#ifndef QRFETRACE_H_
#define QRFETRACE_H_

#include <QObject>
#include <QChar>
#include <QTime>
#include <QThread>
#include <QMutex>

#include <QrfeRingFile>

#define QRFE_TRACE_FILE_COUNT 				4
#define QRFE_TRACE_MAX_FILE_SIZE 			1048576 // 1MB
#define QRFE_TRACE_MAX_MODULE_NAME_SIZE 	25

class QrfeTrace: public QObject
{
	Q_OBJECT

public:
	/*!
	 * @brief Enum with the different trace modes.
	 */
	typedef enum {
		Trace2Stdout 			= 0x00000001,		/*!< @brief Traces to the stdout file */
		Trace2File				= 0x00000002,		/*!< @brief Traces to trace files, the location of these files is in the applications dir */
		Trace2Signal			= 0x00000004,		/*!< @brief Traces to a signal */
		Trace2HTMLSignal		= 0x00000008,		/*!< @brief Traces to a signal in the HTML format */
	} QrfeTraceMode;

private:
	/*!
	 * @brief Constructs the QrfeTrace class
	 * The constructor of the class is private, because the class implements the
	 * singleton pattern.
	 */
	QrfeTrace()	;
public	:
	/*!
	 * @brief Destructs the QrfeTrace class
	 */
	~QrfeTrace();

	/*!
	 * @brief Static function to get the pointer to the singleton instance.
	 */
	static QrfeTrace* getInstance();

	/*!
	 * @brief Static function to change the line delimiter.
	 * Call this function to specify the line delimiter that is appended to each trace to stdout and file.
	 * @param	del				The line delimiter
	 */
	static void setLineDelimiter ( QString del );

	/*!
	 * @brief Static function to change the path, where the trace files are stored.
	 * Call this function to specify a custom trace file location. The default trace file location is in the
	 * application dir. Call this function before you call init, otherwise the first file be created in the
	 * default location.
	 * @param	path			The path where the trace files should be stored
	 */
	static bool setTraceFilePath ( QString path );

	/*!
	 * @brief Static function to set the prefix of the trace files.
	 * Call this function to specify a custom prefix for all trace files. The pattern will be prefixX.txt
	 * @param	prefix			The desired prefix of the files
	 */
	static bool setTraceFilePrefix ( QString prefix );

	/*!
	 * @brief Function to init the trace class.
	 * Call this function to set the trace level for the desired mode. The level is assigned to all given modes.
	 * By calling the function several times it is possible to set different levels for different modes.
	 * @param	trcLevel		The desired trace level
	 * @param 	mode 			The mode(s) to which the level should be assigned
	 */
	static void init( int trcLevel = -1, quint32 mode = 0);

	/*!
	 * @brief Function to set the trace level of the class.
	 * Call this function to set the trace level for the desired mode. The level is assigned to all given modes.
	 * By calling the function several times it is possible to set different levels for different modes.
	 * @param	trcLevel		The desired trace level
	 * @param 	mode 			The mode(s) to which the level should be assigned
	 */
	static void setTrcLevel( int trcLevel, quint32 mode );

	/*!
	 * @brief Static function to trace a message.
	 * The message is traced out in all set modes, if trcLevel is <= the mode specific trace level.
	 * @param 	trcLevel	The trace level of the message
	 * @param	msg			Trace message
	 */
	static void trc (const int trcLevel, const QString& msg );

	/*!
	 * @brief Static function to trace a warning message to stderr and to warningSignal.
	 * The message is traced out to stderr and the warningSignal.
	 * @param	msg			Trace message
	 */
	static void trcWarning (const QString& msg );

	/*!
	 * @brief Static function to trace an error message to stderr and to the error signal.
	 * The message is traced out to stderr and the errorSignal.
	 * @param	msg			Trace message
	 */
	static void trcError (const QString& msg );

private:
	/*!
	 * @brief Function to trace the given message.
	 * The message is traced out in all set modes, if trcLevel is <= the mode specific trace level.
	 * @param 	trcLevel	The trace level of the message
	 * @param	msg			Trace message
	 */
	void trace ( const int trcLevel, const QString& msg );

	/*!
	 * @brief Function to trace the given message.
	 * The message is traced out to stderr and to the warningSignal.
	 * @param	msg			Trace message
	 */
	void warning ( const QString& msg );

	/*!
	 * @brief Function to trace the given message.
	 * The message is traced out to stderr and to errorSignal.
	 * @param	msg			Trace message
	 */
	void error ( const QString& msg );

signals:
	/*!
	 * @brief Trace signal with plain text
	 * The signal is emitted if the Trace2Signal mode is enabled and a message is traced with an appropriate
	 * trace level.
	 * @param 	str			Trace message in plain text
	 */
	void traceSignal( const QString& str );

	/*!
	 * @brief Trace signal with HTML text
	 * The signal is emitted if the Trace2HTMLSignal mode is enabled and a message is traced with an appropriate
	 * trace level.
	 * @param 	str			Trace message in HTML text
	 */
	void traceSignalHTML( const QString& str );

	/*!
	 * @brief Error-Trace signal with plain text
	 * The signal is emitted every time an warning was written out.
	 * @param 	str			Error message in plain text
	 */
	void warningSignal( const QString& str );

	/*!
	 * @brief Error-Trace signal with plain text
	 * The signal is emitted every time an error was written out.
	 * @param 	str			Error message in plain text
	 */
	void errorSignal( const QString& str );


private:
	/*!
	 * @brief Private helper function to transfer the given string to the HTML format.
	 * @returns HTML specific string
	 */
	static QString makeHTML ( const QString& trc );

	/*!
	 * @brief Static singleton instance.
	 */
	static QrfeTrace m_theInstance;

	/*! @brief Helper variable if any trace mode is enabled. */
	static bool 	m_trcOn;

	/*! @brief Trace level for the stdout trace */
	static int 	m_Stdout_trcLevel;
	/*! @brief Trace level for the file trace */
	static int 	m_File_trcLevel;
	/*! @brief Trace level for the signal trace */
	static int 	m_Signal_trcLevel;
	/*! @brief Trace level for the HTML signal trace */
	static int 	m_HTMLSignal_trcLevel;

	/*! @brief Mutex to secure tracing*/
	static QMutex	m_trcMutex;

	/*! @brief Current activated trace modes */
	static quint32	m_trcMode;

	/*! @brief The line delimiter, that is added to each trace */
	static QString	m_trcLineDelimiter;

	/*! @brief Current used file */
	static QrfeRingFile	m_trcFile;

	friend class QrfeTraceModule;
};



#endif /*QRFETRACE_H_*/
