#ifndef MXDS_H
#define MXDS_H


#include "../bdm/bdmerror.h"
#include "../bdm/base/datasources.h"
#include "mex_parser.h"

namespace bdm {
/*!
* \brief DataSource reading data columns from a Matlab matrix 

The data are stored in a arbitrary Matlab matrix. Each column of the matrix corresponds to one discrete time observation \f$t\f$. 
The DataSource needs to know the name of the matrix and possibly decription of its contents (via RV)_

*/
class mxArrayDS : public DS {
	protected:
		//! raw pointer to data
		double *data;
		//! maximum length of data
		int max_len;
		//! active column 
		int column;
public:
	
	//!Default constructor
	mxArrayDS () : DS() {};

	/*! \brief Create data source from mxArray

	\code
	class   = 'mxArrayDS';
	varname = 'data_matrix';         // name of a workspace variable
	drv     = {class='RV',...}       // names of data in columns
	\endcode
	
	*/
	void from_setting ( const Setting &set ) {
		string name;
		UI::get(name, set, "varname", UI::compulsory);
		mxArray *mxAr = mexGetVariable ( "base", name.c_str() );
		
		bdm_assert(mxIsNumeric(mxAr),"Matlab variable: "+name +" is not a matrix");
		
		dtsize = mxGetM(mxAr);
		max_len= mxGetN(mxAr);
		data = (double*)mxGetPr(mxAr);
		utsize = 0;

		DS::from_setting(set); //read drv
		
		if (Drv._dsize()!=dtsize){
			RV def ( ( const char* ) set["varname"], dtsize );
			set_drv ( def, Urv );
		}
		column = 0;
	
		if (max_length()>0){
			dt = vec(&data[column*dtsize],dtsize);
		}
	}

	int max_length() {return max_len;}
	
	void step(){
		if (column<max_length()){
			column++;
		
			dt = vec(&data[column*dtsize],dtsize);
		} else {
			bdm_error("DS: trying to read after max_length()");
		}
	}
};

UIREGISTER ( mxArrayDS );
SHAREDPTR ( mxArrayDS );

}
#endif //MXDS_H
