/***************************************************************
 * PrMatlab.cpp
 *
 * This class provides methods to save data in matlab format.
 *
 ****************************************************************/

/*
 * modification history
 *----------------------
 *
 * 04/01/98: K.C. Chang: created.
 */

#include "PrMatlab.h"
#include "PrGlobalDefn.h"
#include "PrNetworkDefn.h"
#include <stdio.h>
#include <string.h>

typedef struct 
{
  long	type;
  long	mrows;
  long	ncols;
  long	imagf;
  long	namlen;
} Fmatrix;

PrMatlab::PrMatlab()
{
  filePtr_ = NULL;
  endian_ = Endian();
}

PrMatlab::~PrMatlab()
{
  end();
}

int PrMatlab::start(char *filename)
{
  if (filePtr_ != NULL)
    end();
  
  filePtr_ = fopen(filename,"w");
  if (filePtr_ == NULL) {
    fprintf(stderr,"unable to open outfile %s\n",filename);
    return PR_MATLAB_ERROR;
  }
  return PR_MATLAB_OK;
}

void PrMatlab::end()
{ 
  if (filePtr_ != NULL)
    fclose(filePtr_);
  filePtr_ = NULL;
}

void PrMatlab::save(char *name, PrMatlabType type, void *vp, int row, int col)
{
  int flag;
  int size=0;
  Fmatrix h;

  if (row == 0 || col == 0)
    return;

  if (endian_ == PR_BIG_ENDIAN)
    flag = 1000;
  else
    flag = 0;

  /* undocumented - allows matrix in row format */
  flag += 100;

  flag += type;

  h.type = flag;
  h.mrows = row;
  h.ncols = col;
  h.imagf = 0;
  h.namlen = strlen(name)+1;
  
  fwrite(&h,sizeof(Fmatrix),1,filePtr_);
  fwrite(name,strlen(name)+1,1,filePtr_);

  switch (type) 
    {
    case PR_MATLAB_DOUBLE:
      size = row*col*8;
      break;
    case PR_MATLAB_FLOAT:
      size = row*col*4;
      break;
    case PR_MATLAB_INT:
      size= row*col*4;
      break;
    default:
      fprintf(stderr,"PrMatlab::save(): unknown type\n");
    }

  fwrite(vp,size,1,filePtr_);
}

// little endian
//   [0] [1] [2] [3]
//    1   0   0   0
// big endian
//   [0] [1] [2] [3]
//    0   0   0   1
int PrMatlab::Endian()
{
  int aint=1;
  char *cptr = (char *)&aint;
  if (*cptr == '\0')
    return PR_BIG_ENDIAN; // 1 => big endian
  else
    return PR_LITTLE_ENDIAN;
}
