#include "mag_vector.h"
#include "mfhdf.h"
#include "df.h"

static int32 vdata_id_r, vdata_id_w;
static int32 sds_id_r1, sds_id_w1;

/*     init write function    */

int32 init_wr_mag_vec(int32 hdf_fp, int32 sd_id, char *classname)
{
  int32 retval=0;
  int32 dim_sizes[3];
  int32 rank;

  void mag_vec_error();

  if ((vdata_id_w = VSattach(hdf_fp, -1, "w"))==FAIL) {
    fprintf(stderr,"VSattach: Could not attach hdf_fp\n");
    retval=-1;
  }
  VSsetname(vdata_id_w, "mag_vec");
  VSsetclass(vdata_id_w, classname);

   if (VSfdefine(vdata_id_w, "mag_vec_sctime", DFNT_UINT32, (1) )) {
     mag_vec_error("VSfdefine mag_vec_sctime error");
     retval = -1;
   }
   if (VSfdefine(vdata_id_w, "mag_vec_QAC", DFNT_UINT32, (1) )) {
     mag_vec_error("VSfdefine mag_vec_QAC error");
     retval = -1;
   }

  if (VSsetfields(vdata_id_w,"mag_vec_sctime, mag_vec_QAC")){
    mag_vec_error("VSsetfields error");
    retval = -1;
  }
  dim_sizes[0] = SD_UNLIMITED;
  rank = 3;
  dim_sizes[1] = MAGVECDIM;
  dim_sizes[2] = MAGNUMVCT;
  if((sds_id_w1=SDcreate(sd_id, "mag_vec_vector", DFNT_INT16, rank, dim_sizes)) == FAIL)
    fprintf(stderr,"SDcreate: Could not create mag_vec_vector \n");

  return(retval);
}

/****** write function ******/

int32 write_mag_vec(struct MagVectorSet MagVectorSet_struk)
{
int32 start[3], edges[3];
int32 retval = 0;
uint8 *odata;
static int32 recnum_wr=0;

void pack_mag_vec();

  odata = (uint8 *) malloc(sizeof(struct MagVectorSet));
  pack_mag_vec(odata, &MagVectorSet_struk);

  if( VSwrite(vdata_id_w, (uint8 *)odata, 1, FULL_INTERLACE) == -1) {
    fprintf(stderr,"VSwrite: Problem writing MAG VEC data\n");
  } 
  start[0] = recnum_wr++;
  start[1] = 0;
  start[2] = 0;
  edges[0] = 1;

  edges[1] = MAGVECDIM;
  edges[2] = MAGNUMVCT;
  if (SDwritedata(sds_id_w1,start,NULL,edges,(VOIDP) (MagVectorSet_struk.vector ))==FAIL) {
    fprintf(stderr,"SDwritedata: Problem writing vector data.\n");
  }
  memset(&MagVectorSet_struk, 0, sizeof(struct MagVectorSet));
  free(odata);
  return(retval);
}

void close_wr_mag_vec() {
  VSdetach(vdata_id_w);
  SDendaccess(sds_id_w1);
}

/*     init read function    */

int32 init_rd_mag_vec(int32 hdf_fp, int32 sd_id)
{
  static int32 sds_index1;
  int32 vdata_ref;
  int32 retval=0;

  void mag_vec_error();

    if((sds_index1=SDnametoindex(sd_id, "mag_vec_vector" ))==FAIL) {
      fprintf(stderr,"SDnametoindex: Could not find mag_vec_vector\n");
      retval = -1;
    }
    if((sds_id_r1=SDselect(sd_id, sds_index1))==FAIL) {
      fprintf(stderr,"SDselect: Could not select sds_index1\n");
      retval = -1;
    }

  if ((vdata_ref = VSfind(hdf_fp, "mag_vec"))==FAIL) {
    fprintf(stderr,"VSfind: Could not get vdata_ref\n");
    retval=-1;
  }
  if ((vdata_id_r = VSattach(hdf_fp, vdata_ref, "r"))==FAIL) {
    fprintf(stderr,"VSattach: Could not attach hdf_fp\n");
    retval=-1;
  }

  if (VSsetfields(vdata_id_r,"mag_vec_sctime, mag_vec_QAC")) {
    mag_vec_error("VSsetfields error");
  }
  return(retval);
}

/****** read function ******/

int32 read_mag_vec(struct MagVectorSet *MagVectorSet_struk, int32 recnum_rd)
{
int32 start[3], edges[3];
static int32 last_recnum = -1;
int32 maxrec;
int32 retval = 0;
uint8 *odata;

void unpack_mag_vec();

  start[0] = recnum_rd;
  start[1] = 0;
  start[2] = 0;
  edges[0] = 1;

  odata = (uint8 *) malloc(sizeof(struct MagVectorSet));
  VSinquire(vdata_id_r, &maxrec, NULL, NULL, NULL, NULL);
  if (recnum_rd >= maxrec || last_recnum>=maxrec-1) return(-1);
  if (recnum_rd >= 0) {
    last_recnum = recnum_rd;
    if (VSseek(vdata_id_r, recnum_rd)==FAIL) {
      fprintf(stderr,"VSseek unsuccessful\n");
      retval = -1;
    }
  } else {
    recnum_rd = ++last_recnum;
  }
  edges[1] = MAGVECDIM;
  edges[2] = MAGNUMVCT;
  if(SDreaddata(sds_id_r1,start,NULL,edges, (VOIDP)(MagVectorSet_struk->vector ))==FAIL) {
    fprintf(stderr,"SDreaddata: Could not read vector\n");
    retval = -1;
  }
  if(VSread(vdata_id_r, (uint8 *)odata, 1, FULL_INTERLACE)==FAIL) {
    fprintf(stderr,"VSread: Could not read\n");
    retval = -1;
  }
  unpack_mag_vec(odata, MagVectorSet_struk);
  return(retval);
}

void mag_vec_error(int8 *mess)
  { fprintf(stderr,"MAG VEC INIT: %s\n",mess); }

void close_rd_mag_vec() {
  VSdetach(vdata_id_r);
  SDendaccess(sds_id_r1);
}
/*   pack function    */

void pack_mag_vec(uint8 *data, struct MagVectorSet *MagVectorSet_ptr)
{
int32 ptr=0;

   memcpy(data+ptr, &MagVectorSet_ptr->sctime, ((4)*(1)) );
   ptr+= ((4)*(1));
   memcpy(data+ptr, &MagVectorSet_ptr->QAC, ((4)*(1)) );
   ptr+= ((4)*(1));
}

/*   unpack function    */

void unpack_mag_vec(uint8 *data, struct MagVectorSet *MagVectorSet_ptr)
{
int32 ptr=0;

   memcpy(&MagVectorSet_ptr->sctime, data+ptr,  ((4)*(1)) );
   ptr+= ((4)*(1));
   memcpy(&MagVectorSet_ptr->QAC, data+ptr,  ((4)*(1)) );
   ptr+= ((4)*(1));
}
