#include "datasources.h"

using namespace bdm;

MemDS::MemDS ( mat &Dat ) : Data( Dat ) {
}

void MemDS::step( ) {
    if ( time < max_length() ) {
        time++;
    }
}

void MemDS::getdata ( vec &dt ) const {
    bdm_assert_debug ( dt.length() == Data.rows(), "MemDS:getdata incompatible dt" );
    dt = Data.get_col ( time );
}

void MemDS::getdata ( vec &dt, const ivec &indices ) {
    bdm_assert_debug ( dt.length() == indices.length(), "MemDS:getdata incompatible dt" );
    vec tmp = Data.get_col ( time );
    dt = tmp ( indices );
}

void MemDS::from_setting ( const Setting &set ) {
    DS::from_setting ( set );

    UI::get ( Data, set, "Data", UI::compulsory );

    if ( !UI::get ( time, set, "time", UI::optional ) ) {
        time = 0;
    }
}

void MemDS::validate()
{
    if (Urv._dsize()>0) {
        bdm_error ( "MemDS::urv is not supported" );
    }
    dtsize = Data.rows();
    utsize = 0;
    // DS::validate() has to be called after the dtsize attribute is set to proper value
    DS::validate();
    log_level[logut]=0;
}

void FileDS::from_setting ( const Setting & set ) {
    // here we do not call MemDS::from_setting intentionally as we can not load any Data matrix directly
    DS::from_setting ( set );

    UI::get ( filename, set, "filename", UI::compulsory );

    time = 0;
}

void CsvFileDS::from_setting ( const Setting & set ) {
    FileDS::from_setting ( set );

    vec data_line;
    string line;

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

    string orientation;
    if( UI::get ( orientation, set, "orientation", UI::optional ) & (orientation == "BY_ROW") )
        transpose ( Data, Data );
}

void ITppFileDS::from_setting ( const Setting & set ) {
    FileDS::from_setting ( set );

    string varname;
    UI::get ( varname, set, "varname", UI::compulsory );

    it_file it ( filename );
    it << Name ( varname );
    it >> Data;
}

void PdfDS::step() {
    yt2rgr.store_data ( yt ); // y is now history
    ut2rgr.filldown ( ut, rgr );
    yt2rgr.filldown ( yt, rgr );
    yt = ipdf->samplecond ( rgr );
    ut2rgr.store_data ( ut ); //u is now history
}

void PdfDS::getdata ( vec & dt_out ) const {
    bdm_assert_debug ( dt_out.length() >= dtsize, "Short output vector" );
    dt_out.set_subvector ( 0, yt );
    dt_out.set_subvector ( yt.length(), ut );
}

