/* \file IoModel.h
 * \brief  Header file defining the IoModel structure that will help in processing the input data coming 
 * into ISSM, from Matlab, or through a binary file opened for reading.
 * \sa IoModel.cpp
 */

#ifndef _IOMODEL_H
#define _IOMODEL_H

#include "../include/include.h"
#include "../EnumDefinitions/EnumDefinitions.h"

class Parameters;
class Elements;
class Param;
class Option;

class IoModel {

	private: 
		Parameters *constants;   //this dataset holds all IssmDouble, int, bool and char from input

	public:
		IssmDouble **data;   //this dataset holds temporary data, memory intensive.

		/*This data needs to stay memory resident at all time, even if it's memory intensive: */
		FILE *fid;                               //pointer to input file
		bool *my_elements;
		bool *my_nodes;
		int  *my_vertices;
		int  *singlenodetoelementconnectivity;
		int  *numbernodetoelementconnectivity;

		/*Data to synchronize through low level object drivers: */
		int nodecounter;         //keep track of how many nodes are being created in each analysis type
		int loadcounter;         //keep track of how many loads are being created in each analysis type
		int constraintcounter;   //keep track of how many constraints are being created in each analysis type

		/*for AD mode: to keep track of our independent variables we fetch:*/
		bool* independents;
		DataSet* independent_objects;

		/*Methods*/
		~IoModel();
		IoModel();
		IoModel(FILE* iomodel_handle);

		/*Input/Output*/
		void        CheckEnumSync(void);
		void        Constant(bool *poutput,int constant_enum);
		void        Constant(int *poutput,int constant_enum);
		void        Constant(IssmDouble *poutput,int constant_enum);
		void        Constant(char **poutput,int constant_enum);
		Param      *CopyConstantObject(int constant_enum);
		IssmDouble *Data(int dataenum);
		void        DeleteData(int num,...);
		void        DeleteData(IssmDouble* vector, int dataenum);
		void        FetchConstants(void);
		void        FetchData(bool* pboolean,int data_enum);
		void        FetchData(int* pinteger,int data_enum);
		void        FetchData(IssmDouble* pscalar,int data_enum);
		void        FetchData(char** pstring,int data_enum);
		void        FetchData(int** pmatrix,int* pM,int* pN,int data_enum);
		void        FetchData(IssmDouble**  pscalarmatrix,int* pM,int* pN,int data_enum);
		void        FetchData(char***   pstringarray,int* pnumstrings,int data_enum);
		void        FetchData(IssmDouble*** pmatrixarray,int** pmdims,int** pndims, int* pnumrecords,int data_enum);
		void        FetchData(Option **poption,int data_enum);
		void        FetchData(int num,...);
		void        FetchDataToInput(Elements* elements,int vector_enum,int default_vector_enum=NoneEnum,IssmDouble default_value=0);
		void        LastIndex(int *pindex);
		FILE*       SetFilePointerToData(int* pcode,int* pvector_type, int data_enum);
		void        DeclareIndependents(void);
		void        FetchIndependent(int dependent_enum);
};

#endif  /* _IOMODEL_H */
