#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);