
/*!
  \file
  \brief Bayesian Models (bm) that use Bayes rule to learn from observations
  \author Vaclav Smidl.

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

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

#ifndef root_H
#define root_H

#include <string>

#include "itpp_ext.h"
#include "base/libconfig/lib/libconfig.h++"
#include "bdmerror.h"

using namespace libconfig;
using namespace itpp;
using namespace std;

namespace bdm {

	
	//! auxiliary function for debugging
	void UI_DBG (const Setting &S, const string &spc, ostream &out );
	
//forward declaration
class logger;

//! information about connection to a logger
class log_record {
public:
	//!remember which logger is registered
	logger &L;
	//! vector of log IDs - one element for each entry
	ivec ids;

	//!default constructor
	log_record ( logger &L0 ) : L ( L0 ), ids ( 0 ) {}
};

//! Root class of BDM objects
class root {
protected:
	//! record of connections to the logger
	log_record* logrec;
	//! level of details that will be logged to a logger
	int log_level;

	//! It is necessary to allow calling of from_setting and to_setting within the user_info class
	friend class UI;

	//! Read instance properties according the data stored in the Setting structure
	//! 
	//! It has to be called only through user_info class, therefore it is protected 
	virtual void from_setting ( const Setting &set ) {
	}

	//! Save all the instance properties into the Setting structure
	//!
	//! It has to be called only through user_info class, therefore it is protected 
	virtual void to_setting ( Setting &set ) const {
	}

public:
	//!default constructor
	root() : logrec ( NULL ), log_level ( 0 ) {};

	//! make sure this is a virtual object
	virtual ~root() {
		if ( logrec ) delete logrec;
	}

	//! Returns basic textual info about the current instance
	virtual string to_string() const {
		Config C;
		Setting &set=C.getRoot();
		this->to_setting(set);
		ostringstream os;
		UI_DBG(set, "", os);
		return os.str();
	}
	//! Register itself in a logger, i.e. allocate space for data from this class
	//! The level of details (parameter \c level ) is individual for each class.
	virtual void log_register ( logger &L, const string &prefix ) {
		logrec = new log_record ( L );
	}

	//! Write current information into the given logger
	virtual void log_write() const {
	}
	//! set level of details to be logged - needs to be called before log_register!
	virtual void set_log_level ( int level ) {
		log_level = level;
	}

	//! Check that all internal structures has been correctly set-up. Called at the end of from_setting.
	virtual void validate() {
	}

	//! Virtual method providing deep copy of instances
	virtual root* _copy() const NOT_IMPLEMENTED(NULL);
	

	//! access function
	int _log_level() const {
		return log_level;
	}

};

}; //namespace
#endif // root_H
