/*!
  \file
  \brief Loggers for storing results of experiments
  \author Vaclav Smidl.

  -----------------------------------
  BDM++ - C++ library for Bayesian Decision Making under Uncertainty

  Using IT++ for numerical operations
  -----------------------------------
*/

#ifndef LGR_H
#define LGR_H

#include "bdmbase.h"
#include "user_info.h"

namespace bdm{
using std::string;

/*!
* \brief Logging into matrices in data format in memory

* More?...
*/

class memlog : public logger {

protected:
	//! Maximum length of vectors stored in memory
	int maxlen;
	//! Currect record to be written
	int ind;
	//! Storage
	Array<mat> vectors;
	//! name of it file to save results
	string itfilename;
public:
	//!Default constructor
	memlog ( int maxlen0, string itf="" ) : maxlen ( maxlen0 ),ind ( 0 ),vectors ( 0 ),itfilename(itf) {}

	memlog(): ind ( 0 ),vectors ( 0 ) {}

	//! Initialize storage
	void init() {
		int i; int n =entries.length();
		vectors.set_size ( n ); 
		for ( i=0;i<n;i++ ) {vectors(i).set_size (maxlen,entries(i)._dsize() );}
	}
	void step() {if ( ind<maxlen ) ind++; else it_error ( "memlog::ind is too high;" );}
	void logit ( int id, const vec &v ) {
		it_assert_debug(id<vectors.length(),"Logger was not initialized, run init().");
		if(id>=0){ vectors ( id ).set_row ( ind,v );}
	}
	void logit ( int id, const double &d ) {
		it_assert_debug(id<vectors.length(),"Logger was not initialized, run init().");
		it_assert_debug(vectors(id).cols()==1,"Vector expected");
		if(id>=0){ vectors ( id ) ( ind )=d;}
	}
	//! Save values into an itfile named after \c fname.
	void itsave(const char* fname);
	//! 
	void finalize() {if (itfilename.length()>0) itsave(itfilename.c_str());};


	/*! \brief UI for memlog 

	TODO dat tam kam patri, a to celej blok

	\code
	logger = {
		type = "itpplog";
		filename = "file_name.it"; // resulting filename with results in it format
		maxlen = 100;          // size of memory buffer
	}
	\endcode
	 */
	void from_setting( const Setting &set );

	// TODO dodelat void to_setting( Setting &set ) const;
};

UIREGISTER(memlog);

/*!
* \brief Logging into dirfile with buffer in memory

* Dirfile is a special format used by the kst program. See documentation of kst for description.
*
* This format is used to store scalars, hence multivariate RVs must be separated.
*/
class dirfilelog : public memlog {

protected:
	//!name of the directory
	string dirname;
	//! Automatically generated 
	Array<string> scalarnames;
public:
	/*!\brief Default constructor 
	@param dirname0 name of the directory in which to store the results
	@param maxlen0 length of the memory buffers, when full the buffers will be dumped to HDD and returned to the beginning. */
	dirfilelog ( string dirname0, int maxlen0 ) : memlog ( maxlen0 ), dirname ( dirname0 ), scalarnames ( 0 ) {}

	dirfilelog() {}

	//! Initialize storage
	void init();
	void step();
	void finalize();
	/*! \brief Write memory storage to disk. 
	@param Len length of buffer to be written, if 0 the file is truncated at 0.
	*/
	void write_buffers ( int Len );

	// TODO dokumentace - aktualizovat
	/*! \brief UI for dirfilelog (Kst file format) 
	\code
	logger = {
		type = "dirfilelog";
		dirmane = "directory_for_files"; // resulting files will be stored there
		maxlen = 100;                    // size of memory buffer, when full results are written to disk
	}
	\endcode
	*/
	void from_setting( const Setting &set );

	// TODO dodelat void to_setting( Setting &set ) const;
};

UIREGISTER(dirfilelog);

};
#endif // LGR_H
