
#include "datasources.h"

using namespace bdm;

void MemDS::getdata ( vec &dt ) {
	int i;

	bdm_assert_debug ( dt.length() == rowid.length(), "MemDS:getdata incompatible dt" );
	for ( i = 0; i < rowid.length(); i++ ) {
		dt ( i ) = Data ( rowid ( i ), time );
	}
}

void MemDS::getdata ( vec &dt, const ivec &indeces ) {
	int j, i;
	bdm_assert_debug ( dt.length() == indeces.length(), "MemDS:getdata incompatible dt" );
	for ( i = 0; i < indeces.length(); i++ ) {
		j = indeces ( i );
		dt ( i ) = Data ( rowid ( j ), time  );
	}
}

void MemDS::step() {
	if ( time < Data.cols() ) {
		time++;
	}
}

void MemDS::set_rvs ( RV &drv, RV &urv ) {
	bdm_assert_debug ( drv._dsize() == rowid.length(), "MemDS::set_rvs incompatible drv" );
	bdm_assert_debug ( urv._dsize() == 0, "MemDS does not support urv." );

	Drv = drv;
}

MemDS::MemDS ( mat &Dat, ivec &rowid0) : rowid ( rowid0 ) {
	bdm_assert_debug ( max ( rowid ) <= Dat.rows(), "MemDS rowid is too high for given Dat." );

	time = 0;
	Data = Dat;
}

void ArxDS::step() {
	//shift history
	H.shift_right ( 0, dt_size );

	H.set_subvector ( dt_size - utsize, U ); // write U after Drv

	//get regressor
	rgr = rgrlnk.pushdown ( H );
	// Eval Y
	H.set_subvector ( 0, model.samplecond ( rgr ) );

}

void ArxDS::from_setting ( const Setting &set ) {
	shared_ptr<RV> yrv = UI::build<RV> ( set, "y" , UI::compulsory );
	shared_ptr<RV> urv = UI::build<RV> ( set, "u" , UI::compulsory );
	shared_ptr<RV> rrv = UI::build<RV> ( set, "rgr" , UI::compulsory );

	mat Th;
	UI::get ( Th, set, "theta", UI::compulsory );

	vec mu0;
	if ( !UI::get ( mu0, set, "offset" ) )
		mu0 = zeros ( yrv->_dsize() );

	mat sqR;
	UI::get ( sqR, set, "r", UI::compulsory );
	set_parameters ( Th, mu0, sqR );
	set_drv ( *yrv, *urv, *rrv );

	if ( set.exists ( "opt" ) )
		set_options ( set["opt"] );
}

CsvFileDS::CsvFileDS ( const string& fname, const string& orientation ) : FileDS() {
	time = 0;

	vec data_line;
	string line;

	ifstream fs;
	fs.open ( fname.c_str() );
	if ( fs.is_open() ) {
		while ( getline ( fs, line ) ) {
			data_line.set ( line );
			Data.append_row ( data_line );
		}
	}

	if ( orientation == "BY_ROW" ) {
		transpose ( Data, Data );
	}


}

//! Auxiliary function building full history of rv0
RV fullrgr ( const RV &drv0, const RV &urv0, const RV &rrv0 ) {
	RV T ( urv0 );
	RV pom = concat ( drv0, urv0 );
	int mint = rrv0.mint();
	for ( int i = 0; i > mint; i-- ) {
		pom.t_plus ( -1 );
		T.add ( pom );
	}
	return T;
}

void ITppFileDS::from_setting ( const Setting &set ) {
	shared_ptr<RV> rvtmp = UI::build<RV> ( set, "rv" , UI::compulsory );

	it_file it ( set["filename"] );
	it << Name ( set["varname"] );
	it >> Data;
	time = 0;
	//rowid and delays are ignored

	set_drv ( *rvtmp, RV() );
}

void stateDS::from_setting ( const Setting &set ) {
	IM = UI::build<mpdf> ( set, "IM", UI::compulsory );
	OM = UI::build<mpdf> ( set, "OM", UI::compulsory );

	dt.set_length ( OM->dimension() );
	xt.set_length ( IM->dimension() );
	ut.set_length ( 0 );

#if 0
	RV* rvtmp = UI::build<RV> ( set["IM"], "rvu", UI::compulsory );
	//set_drv(rvtmp);
#endif
}
