/*\file matlabio.h
 *\brief: I/O for ISSM in matlab mode
 */

#ifndef _MATLAB_IO_H_
#define _MATLAB_IO_H_

#ifdef HAVE_CONFIG_H
#include <config.h>
#else
#error "Cannot compile with HAVE_CONFIG_H symbol! run configure first!"
#endif 

#include "../include/matlabincludes.h"
#include "../../c/classes/classes.h"
#include "../../c/Container/Container.h"
#include "../../c/include/include.h"

void WriteData(mxArray** pdataref,SeqMat<int>* matrix);
void WriteData(mxArray** pdataref,SeqMat<double>* matrix);
void WriteData(mxArray** pdataref,double* matrix, int M,int N);
void WriteData(mxArray** pdataref,int*    matrix, int M,int N);
void WriteData(mxArray** pdataref,SeqVec<int>* vector);
void WriteData(mxArray** pdataref,SeqVec<double>* vector);
void WriteData(mxArray** pdataref,double* vector, int M);
void WriteData(mxArray** pdataref,int integer);
void WriteData(mxArray** pdataref,bool boolean);
void WriteData(mxArray** pdataref,double scalar);
void WriteData(mxArray** pdataref,char* string);
void WriteData(mxArray** pdataref);
void WriteData(mxArray** pdataref,BamgGeom* bamggeom);
void WriteData(mxArray** pdataref,BamgMesh* bamgmesh);
void WriteData(mxArray** pdataref,RiftStruct* riftstruct);

void FetchData(double** pmatrix,int* pM,int *pN,const mxArray* dataref);
void FetchData(double** pmatrix,int* pnumel,int* pndims,int** psize,const mxArray* dataref);
void FetchData(int** pmatrix,int* pM,int *pN,const mxArray* dataref);
void FetchData(bool** pmatrix,int* pM,int *pN,const mxArray* dataref);
void FetchData(bool** pmatrix,int* pnumel,int* pndims,int** psize,const mxArray* dataref);
void FetchData(Matrix<double>** pmatrix,const mxArray* dataref);
void FetchData(int** pvector,int* pM,const mxArray* dataref);
void FetchData(float** pvector,int* pM,const mxArray* dataref);
void FetchData(double** pvector,int* pM,const mxArray* dataref);
void FetchData(bool** pvector,int* pM,const mxArray* dataref);
void FetchData(Vector<double>** pvector,const mxArray* dataref);
void FetchData(char** pstring,const mxArray* dataref);
void FetchData(char** pmatrix,int* pnumel,int* pndims,int** psize,const mxArray* dataref);
void FetchData(double* pscalar,const mxArray* dataref);
void FetchData(int* pinteger,const mxArray* dataref);
void FetchData(bool* pbool,const mxArray* dataref);
void FetchData(BamgGeom** bamggeom,const mxArray* dataref);
void FetchData(BamgMesh** bamgmesh,const mxArray* dataref);
void FetchData(BamgOpts** bamgopts,const mxArray* dataref);
void FetchData(Options** poptions,int istart, int nrhs,const mxArray** pdataref);
void FetchData(DataSet** pcontours,const mxArray* dataref);

Option* OptionParse(char* name, const mxArray* prhs[]);
GenericOption<double>*    OptionDoubleParse( char* name, const mxArray* prhs[]);
GenericOption<double*>*   OptionDoubleArrayParse( char* name, const mxArray* prhs[]);
GenericOption<bool*>*     OptionLogicalParse( char* name, const mxArray* prhs[]);
GenericOption<char*>*     OptionCharParse( char* name, const mxArray* prhs[]);
GenericOption<Options**>* OptionStructParse( char* name, const mxArray* prhs[]);
GenericOption<Options*>*  OptionCellParse( char* name, const mxArray* prhs[]);

mxArray* mxGetAssignedField(const mxArray* pmxa_array,int number, const char* field);
void SetStructureField(mxArray* dataref,const char* fieldname,int fieldrows,int fieldcols,double* fieldpointer);
void SetStructureFieldi(mxArray* dataref,int i,const char* fieldname,int fieldrows,int fieldcols,double* fieldpointer);
void SetStructureFieldi(mxArray* dataref,int i,const char* fieldname,int fieldrows,int fieldcols,int*    fieldpointer);
void SetStructureFieldi(mxArray* dataref,int i,const char* fieldname,int field);
void SetStructureFieldi(mxArray* dataref,int i,const char* fieldname,double field);
int CheckNumMatlabArguments(int nlhs,int NLHS, int nrhs,int NRHS, const char* THISFUNCTION, void (*function)( void ));

/*Matlab to Matrix routines: */
Matrix<double>* MatlabMatrixToMatrix(const mxArray* mxmatrix);
Vector<double>* MatlabVectorToVector(const mxArray* mxvector);

/*Matlab to double* routines: */
int MatlabVectorToDoubleVector(double** pvector,int* pvector_rows,const mxArray* mxvector);
int MatlabMatrixToDoubleMatrix(double** pmatrix,int* pmatrix_rows,int* pmatrix_cols,const mxArray* mxmatrix);
int MatlabNArrayToNArray(double** pmatrix,int* pmatrix_numel,int* pmatrix_ndims,int** pmatrix_size,const mxArray* mxmatrix);
int MatlabNArrayToNArray(bool** pmatrix,int* pmatrix_numel,int* pmatrix_ndims,int** pmatrix_size,const mxArray* mxmatrix);
int MatlabNArrayToNArray(char** pmatrix,int* pmatrix_numel,int* pmatrix_ndims,int** pmatrix_size,const mxArray* mxmatrix);

/*Matlab to SeqMat routines: */
SeqMat<double>* MatlabMatrixToSeqMat(const mxArray* dataref);
SeqVec<double>* MatlabVectorToSeqVec(const mxArray* dataref);

/*Matlab to Petsc routines: */
#ifdef _HAVE_PETSC_
int MatlabMatrixToPetscMat(Mat* matrix,int* prows,int* pcols, const mxArray* mxmatrix);
PetscMat* MatlabMatrixToPetscMat(const mxArray* mxmatrix);
int MatlabVectorToPetscVec(Vec* pvector,int* pvector_rows,const mxArray* mxvector);
PetscVec* MatlabVectorToPetscVec(const mxArray* mxvector);
#endif

#endif	/* _IO_H_ */
