/***************************************************************
 * 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 = 500000;

   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
