#include <mex/mex_parser.h>
#include <mex/mex_pdf.h>
class mexBM: public BM{
	protected:
		mxArray *data;
		mexEpdf est;
	public:
		mexBM() {};
		void from_setting(const Setting &S)  {
			Setting &So=S["object"];
			data = (mxArray*)long(So);
		} 
		void validate() {
			mxArray *tmp;
			mexCallMATLAB(1, &tmp, 1, &data,  "validate");
			// new object is in tmp
			data = tmp;
			
			mexCallMATLAB(1, &tmp, 1, &data, "dimensions");
			vec v=mxArray2vec(tmp);
			if (v.length()<3) {bdm_error("Three dimensions are expected in mexBM.dimensions");}
			set_dim(v(0));
			dimy = v(1);
			dimc = v(2);
			
			mexCallMATLAB(1, &tmp, 1, &data, "get_rv");
			UImxArray rvtmp(tmp);
			shared_ptr<RV> r = UI::build<RV>(rvtmp);
			set_rv(*r);
			
			mexCallMATLAB(1, &tmp, 1, &data, "get_rvc");
			UImxArray rvtmpc(tmp);
			shared_ptr<RV> rc = UI::build<RV>(rvtmpc);
			rvtmpc.writeFile("tmpc.cfg");
			rvc=*rc;
			
			mexCallMATLAB(1, &tmp, 1, &data, "get_rvy");
			UImxArray rvtmpy(tmp);
			rvtmpy.writeFile("tmpy.cfg");
			shared_ptr<RV> ry = UI::build<RV>(rvtmpy);
			yrv = *ry;
			
		}
		void bayes(const vec &dt, const vec &cond) {
			mxArray *tmp;
			mxArray *in[3];
			in[0]=data;
			in[1]=mxCreateDoubleMatrix(dt.length(),1,mxREAL);
			vec2mxArray(dt,in[1]);
			in[2]=mxCreateDoubleMatrix(cond.length(),1,mxREAL);
			vec2mxArray(cond,in[2]);
			
			mexCallMATLAB(1, &tmp, 3, in, "bayes");
			data = tmp;
		}
		epdf* predictor(const vec &cond) const {
			mxArray *tmp;
			mxArray *in[3];
			in[0]=data;
			in[1]=mxCreateDoubleMatrix(cond.length(),1,mxREAL);
			vec2mxArray(cond,in[1]);
			
			mexCallMATLAB(1, &tmp, 3, in, "predictor");
			
			UImxArray uitmp(tmp);
			shared_ptr<epdf> pred = UI::build<epdf>(uitmp);
			return pred.get();
			//
		}
		const epdf& posterior() const {
			mxArray *tmp;
			mexCallMATLAB(1, &tmp, 1,(mxArray **) &data,  "posterior");
			const_cast<mexEpdf*>(&est)->set_data(tmp);
			return est;
		}
};
UIREGISTER(mexBM);