#include <itpp/itmex.h>

#include "estim/arx.h"
#include "stat/datasources.h"
#include "stat/loggers.h"
#include "mex_logger.h"

//#include "mex_datasource.h"

using namespace bdm;

void mexFunction ( int n_output, mxArray *output[], int n_input, const mxArray *input[] ) {
	// Check the number of inputs and output arguments
	string fname;
	if (n_input>0){
		fname=mxArray2string(input[0]);
	} else {
		fname = "UIArxDS_test.cfg";
	}
	// ------------------ 
	
	printf("name: %s", fname.c_str());
	UIFile F ( fname.c_str());

	logger* L = UI::build<logger>( F, "logger");
	ArxDS * DS = UI::build<ArxDS>( F, "system" );
	BM* E = UI::build<BM>( F, "estimator" );
	int Ndat = F.lookupValue ( "experiment.ndat",Ndat );

	DS->log_add ( *L );
	int L_est= L->add ( E->posterior()._rv(), "est" ); // estimate
	int L_lb = L->add ( E->posterior()._rv(), "lb" ); // lower bound
	int L_ub = L->add ( E->posterior()._rv(), "ub" ); // upper bound
	L->init();

	vec dt=zeros ( DS->_drv()._dsize() );   //data variable
	datalink dl ( E->_drv(),DS->_drv() ); //datalink between a datasource and estimator

	for ( int tK=1;tK<Ndat;tK++ ) {
		DS->step();							// simulator step
		DS->getdata ( dt );					// read data
		E->bayes ( dl.pushdown ( dt ) );		// update estimates

		DS->logit ( *L );
		L->logit ( L_est, E->posterior().mean() );
		L->logit ( L_lb,  E->posterior().mean()-2*sqrt ( E->posterior().variance() ) );
		L->logit ( L_ub,  E->posterior().mean() +2*sqrt ( E->posterior().variance() ) );

		L->step();
	}

	L->finalize();

	// ------------------ End of routine -----------------------------
	
	mex_logger* mL=dynamic_cast<mex_logger*>(L);

	if (mL) { // user wants output!!
		if ( n_output<1 ) mexErrMsgTxt ( "Wrong number of output variables!" );
		output[0] = mL->toCell();
	}
	
	///////
	delete L;
	delete DS;
	delete E;
}
