/**
 * @file Logger.h
 * Defines the Logger class
 * @author Tomas Urban
 * @version 0.2
 * @date 23/07/2009
 */
#ifndef LOGGER_H
#define LOGGER_H

#include <boost/thread/mutex.hpp>
#include "Helper/Singleton.h"

/** 
 * Singleton class for logging. The class uses std::clog as the output channel. All logging
 * operations are thread safe.
 */
class Logger : public Singleton<Logger>
{
private:
	friend class Singleton<Logger>;
	Logger(void);
	int m_nLogMode; // Logging mode
	boost::mutex m_mutex; // Logging lock
	void LogLine(const std::string sText);
public:	
	~Logger(void);	

	/**
	 * No logging operations are with exeption allowed when this mode is set. It should not be combined
	 * with other modes.
	 */
	static const int LOG_NOTHING = 0x00;
	/**
	  * Important information statements are allowed to be printed to the log when this 
	  * mode is active. This mode can be combined with other modes. It is one of the default 
	  * modes.
	 */
	static const int LOG_INFO = 0x01;
	/**
	  * Critical errors are allowed to be printed to the log when this mode is active. This
	  * mode can be combined with other modes. It is one of the default modes.
	 */
	static const int LOG_ERRORS = 0x02;
	/**
	  * Minor warnings are allowed to be printed to the log when this mode is active. This
	  * mode can be combined with other modes.
	 */
	static const int LOG_WARNINGS = 0x04;
	/**
	  * Hexa dump of captured messages is allowed to be printed to the log when this mode 
	  * is active. This mode can be combined with other modes.
	 */
	static const int LOG_CAPTURE = 0x08;
	/**
	  * Debugging statements are allowed to be printed to the log when this mode is active. This
	  * mode can be combined with other modes.
	 */
	static const int LOG_DEBUG = 0x10;
	/**
	 * All logging operations are allowed with this mode. It should not be combined with other
	 * modes.
	 */
	static const int LOG_ALL = LOG_INFO | LOG_ERRORS | LOG_WARNINGS | LOG_CAPTURE | LOG_DEBUG;
	/**
	 * Sets the logging mode. Individual logging methods are allowed to write to the logging output
	 * only if the particular logging mode is active.
     *
	 * @param nMode Logging mode to be activated. Several modes can be combined using the bitwise or 
	 *        operator. The following modes are provided:\n
	 *        #LOG_INFO\n
	 *        #LOG_ERRORS\n
	 *        #LOG_WARNINGS\n
	 *        #LOG_CAPTURE\n
	 *        #LOG_DEBUG\n
	 *        #LOG_NOTHING\n
	 *        #LOG_ALL
	 */
	void SetLoggingMode(int nMode) { m_nLogMode = nMode; }
	/**
	 * Returns the active logging mode. Individual logging methods are allowed to write to the
	 * logging output only if the particular logging mode is active.
	 *
	 * @return active logging mode
	 */
	int GetLoggingMode() const { return m_nLogMode; }
	/**
	 * Adds an informative statement to the log. #LOG_INFO mode has to be active, otherwise the
	 * method is not executed.
	 *
	 * @param sInfo information to be logged
	 */
	void LogInfo(const std::string sInfo);
	/**
	 * Adds an error statement to the log. #LOG_ERRORS mode has to be active, otherwise the
	 * method is not executed.
	 *
	 * @param sError error to be logged
	 */
	void LogError(const std::string sError);
	/**
	 * Adds a warning to the log. #LOG_WARNINGS mode has to be active, otherwise the
	 * method is not executed.
	 *
	 * @param sWarning warning to be logged
	 */
	void LogWarning(const std::string sWarning);
	/**
	 * Writes binary dump of captured data to the log. #LOG_CAPTURE mode has to be active, 
	 * otherwise the method is not executed.
	 *
	 * @param sData captured data to be logged
	 */
	void LogCapture(const std::string sData);
	/**
	 * Adds a debugging statement to the log. #LOG_DEBUG mode has to be active, otherwise the
	 * method is not executed.
	 *
	 * @param sDebugData information to be logged
	 */
	void LogDebug(const std::string sDebugData);
};

#endif
