#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() {};

    /*! Create object from the following structure

    \code
    class   = 'mxArrayDS';
    varname = 'data_matrix';                   % name of a Matlab workspace variable
    -- inherited fields ---
    bdm::DS::from_setting
    drv     = RV({'names',...},[sizes,...]);   % names of data redords 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) {
            Drv=RV( ( const char* ) set["varname"], dtsize );
        }
        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
