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

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

#ifndef _PrMatlab_h
#define _PrMatlab_h

#include <queue>
#include <stdio.h>

/** \defgroup utility utility
*/

/** \ingroup utility
* \brief Utility class for producing Matlab data files from gathered data.
*
* This class produces a Matlab data file containing a single matrix.  This
* matrix is populated by using the save() function.  Each call to save()
* creates a new row entry in the matrix.  The complete matrix is saved to file
* when the end() function is called.
*/

class PrMatlab {
public:
  /// Return value from start()
  enum PrMatlabStatus { 
    PR_MATLAB_ERROR, 
    PR_MATLAB_OK 
  };

  /// Type of data written to Matlab matrix.
  enum PrMatlabType { 
    PR_MATLAB_DOUBLE = 0,
    PR_MATLAB_FLOAT = 10,
    PR_MATLAB_INT = 20
  };

  PrMatlab();

  ~PrMatlab();

  /**
  * \brief Initializes this class to prepare for creation of a new Matlab
  * data file.
  *
  * This function must be called before doing any save() calls.
  *
  * \param filename New Matlab data file to be created (.mat).
  * \param matrixName Name of the matrix contained in the data file.
  * \param type Type of data written to Matlab matrix.
  * \return PR_MATLAB_OK if successful, PR_MATLAB_ERROR otherwise.
  */

  int start( const char * filename, char * matrixName, PrMatlabType type );

  /**
  * \brief Adds a new row of data to the matrix.
  *
  * Each call to this function will write a new row of data to the matrix.
  * Note that it is compulsory for all calls to pass the same value for \a
  * numCols.
  *
  * \param data Pointer to an array of doubles, floats or ints to be written
  * to the matrix.  The number of elements in the array must be \a numCols
  * and the type is as specified in the call to start().
  * \param numCols Number of columns in the matrix.
  */

  void save( void * data, int numCols );

  /**
  * \brief Writes the gathered matrix to file.
  */

  void end(); 

private:
  enum Endian { BIG, LITTLE };
  static const int BUFFER_SIZE = 250000;

  Endian endian_;
  FILE *filePtr_;
  int numCols;
  char * matrixName;
  PrMatlabType dataType;
  int curRow;
  int rowSize;
  char * buf;
  std::queue<char *> bufQueue;

  // little endian
  //   [0] [1] [2] [3]
  //    1   0   0   0
  // big endian
  //   [0] [1] [2] [3]
  //    0   0   0   1
  Endian getEndian();

  // copy is not allowed.
  PrMatlab(const PrMatlab &) {}
};


#endif // _PrMatlab_h
