/*
 * $Id: flexilog.h 4058 2016-04-04 21:03:29Z antonin.misek-skoda-auto.cz $
 *
 * Description  : One line description of file.
 * Author       : Vaclav Kyba <mail/Jabber: vaseo1@gmail.com>  <ICQ: 98576293>
 *
 * Purpose      :
 *     Long description of what the file is for.
 */


#ifndef __FLEXILOG__H__
#define __FLEXILOG__H__
#include <wx/app.h>
#include <wx/log.h>
#include <wx/wfstream.h>
#include <wx/txtstrm.h>
#ifndef VRUT_HPC
#include <wx/textctrl.h>
#endif
#include "VrutApi.h"

#define LOGERROR(a)    VRUT::FlexiLog::LogMessageFlexi((a), wxLOG_Error)
#define LOGWARNING(a)  VRUT::FlexiLog::LogMessageFlexi((a), wxLOG_Warning)
#ifndef NDEBUG
#define LOGDEBUG(a)    VRUT::FlexiLog::LogMessageFlexi((a), wxLOG_Debug)
#define LOGVERBOSE(a)  VRUT::FlexiLog::LogMessageFlexi((a), wxLOG_Info)
#else
#define LOGDEBUG(a)
#define LOGVERBOSE(a)
#endif
#define LOG(a)         VRUT::FlexiLog::LogMessageFlexi((a), wxLOG_Message)

wxULongLong VRUT_CORE_API VRUTGetTime();
// Returns current time (since something stable like system boot) in micro-seconds
inline wxULongLong VRUTGetTimeUS()		{	return VRUTGetTime();				}
// Returns current time (since something stable like system boot) in mili-seconds
inline wxULongLong VRUTGetTimeMS()		{	return VRUTGetTime() / 1000;		}
// Returns current time (since something stable like system boot) in seconds
inline wxULongLong VRUTGetTimeS()		{	return VRUTGetTime() / 1000000;		}

namespace VRUT
{
	class Kernel;

	///Logging class with file and window output
	class VRUT_CORE_API FlexiLog : public
#ifdef VRUT_HPC
		wxLog
#else
		wxLogTextCtrl
#endif
	{
	protected:
#ifndef VRUT_HPC
		///Text control window
		wxTextCtrl * textCtrl;
		///Log to text control window?
		bool logToTextCtrl;
#endif
		///Output file stream
		wxFileOutputStream * dbgout;
		///Output text stream
		wxTextOutputStream * dout;
		///Sync log file after every log message?
		bool syncEveryMsg;

	public:
		///Class constructor
		FlexiLog(
#ifndef VRUT_HPC
			wxTextCtrl * _textCtrl,
#endif
			const wxString &appPath);
		///Class destructor
		virtual ~FlexiLog();

		///Get active log instance only if it is \c FlexiLog, \c NULL otherwise
		static FlexiLog * GetInstance();
		///Log message to active log target only if it is \c FlexiLog (using \c FlexiLog::LogMessage)
		static void LogMessageFlexi(const wxString & msg, wxLogLevel loglevel);
		///Enable or disable logging to text control window
		static void SetTextCtrlLogging(bool enable)
		{
#ifndef VRUT_HPC
			FlexiLog * logInst = GetInstance();
			if (logInst)
				logInst->logToTextCtrl = enable;
#endif
		}
		void SyncEveryMsg(bool enable = true)
		{
			syncEveryMsg = enable;
		}

		///Log message - \c wxLogTextCtrl overload
		///\param[in] level Message importance
		///\param[in] msg Message to log
		///\param[in] timestamp Time information
#if wxCHECK_VERSION(2, 9, 0)
		virtual void DoLogRecord(wxLogLevel level, const wxString& msg, const wxLogRecordInfo& info);
#else
		virtual void DoLog(wxLogLevel level, const wxChar * msg, time_t timestamp);
#endif
		///Log message thread safe - adds log event to be processed later if not main thread
		void LogMessage(const wxString & msg, wxLogLevel loglevel);

		static void SetLogLevel(int logLevel) {
			wxLogLevel logLevels[] = {wxLOG_FatalError, wxLOG_Error, wxLOG_Warning, wxLOG_Message, wxLOG_Max};
			if ((logLevel>=0) && (logLevel<=4))
				wxLog::SetLogLevel(logLevels[logLevel]);
		}

		friend class Kernel;
	};
}


#endif
