#include "../inc/QrfeTrace.h"
#include <QtDebug>
#include <QDir>
#include <QCoreApplication>
#include <QMutexLocker>

QrfeTrace 		QrfeTrace::m_theInstance;
bool 			QrfeTrace::m_trcOn 					= false;
int 			QrfeTrace::m_Stdout_trcLevel		= -1;
int 			QrfeTrace::m_File_trcLevel			= -1;
int 			QrfeTrace::m_Signal_trcLevel		= -1;
int 			QrfeTrace::m_HTMLSignal_trcLevel	= -1;
quint32 		QrfeTrace::m_trcMode				= 0;
QString			QrfeTrace::m_trcLineDelimiter		= "\r\n";
QrfeRingFile 	QrfeTrace::m_trcFile("", "trcFile", "txt", QRFE_TRACE_FILE_COUNT, QRFE_TRACE_MAX_FILE_SIZE);
QMutex			QrfeTrace::m_trcMutex;


QrfeTrace::QrfeTrace()
{
}


QrfeTrace::~QrfeTrace()
{
}

QrfeTrace* QrfeTrace::getInstance()
{
	return &m_theInstance;
}

bool QrfeTrace::setTraceFilePath ( QString path )
{
	QMutexLocker lock(&m_trcMutex);
	return m_trcFile.setPath(path);
}

bool QrfeTrace::setTraceFilePrefix( QString prefix )
{
	QMutexLocker lock(&m_trcMutex);
	return m_trcFile.setPrefix(prefix);
}

void QrfeTrace::setLineDelimiter ( QString del )
{
	m_trcLineDelimiter = del;
}

void QrfeTrace::init(int trcLevel, quint32 mode)
{
	setTrcLevel(trcLevel, mode);
}

void QrfeTrace::setTrcLevel( int trcLevel, quint32 mode )
{
	QMutexLocker lock(&m_trcMutex);

	m_trcMode = mode;
	if ((mode & Trace2Stdout) != 0)
	{
		m_Stdout_trcLevel = trcLevel;
	}
	if ((mode & Trace2File) != 0)
	{
		m_File_trcLevel = trcLevel;
		if(trcLevel > -1)
		{
			m_trcFile.setAppend(false);
			m_trcFile.setRisingNumber(false);
			if(m_trcFile.path() == "")
				m_trcFile.setPath(QCoreApplication::applicationDirPath());
			m_trcFile.open(QIODevice::WriteOnly);
		}
	}
	if ((mode & Trace2Signal) != 0)
	{
		m_Signal_trcLevel = trcLevel;
	}
	if ((mode & Trace2HTMLSignal) != 0)
	{
		m_HTMLSignal_trcLevel = trcLevel;
	}

	if(m_Stdout_trcLevel > 0 ||
		m_File_trcLevel > 0 ||
		m_Signal_trcLevel > 0 ||
		m_HTMLSignal_trcLevel > 0 )
	{
		m_trcOn = true;
	}
	else
	{
		m_trcOn = false;
	}
}

void QrfeTrace::trc(const int trcLevel, const QString& msg)
{
	m_theInstance.trace(trcLevel, msg);
}

void QrfeTrace::trcWarning(const QString& msg)
{
	m_theInstance.warning(msg);
}

void QrfeTrace::trcError(const QString& msg)
{
	m_theInstance.error(msg);
}


#ifndef QRFE_TRACE_ON

void QrfeTrace::trace(const int /*trcLevel*/, const QString& /*msg*/){}
void QrfeTrace::warning(const QString& /*msg*/){}
void QrfeTrace::error(const QString& /*msg*/){}

#else

void QrfeTrace::trace(const int trcLevel, const QString& msg)
{
	QMutexLocker lock(&m_trcMutex);

	if (!m_theInstance.m_trcOn || trcLevel < 0)
		return;

	if (trcLevel <= m_Signal_trcLevel)
		emit traceSignal(msg);

	if (trcLevel <= m_HTMLSignal_trcLevel)
		emit traceSignalHTML(makeHTML(msg));

	if (trcLevel <= m_File_trcLevel)
	{
        m_trcFile.write(msg.toLatin1() + m_trcLineDelimiter.toLatin1());
	}

	if (trcLevel <= m_Stdout_trcLevel){
        fprintf(stdout, "%s%s", msg.toLatin1().data(), m_trcLineDelimiter.toLatin1().data());
		fflush(stdout);
	}
}

void QrfeTrace::warning(const QString& msg)
{
	QMutexLocker lock(&m_trcMutex);
#if !defined (Q_OS_WINCE) && !defined (Q_OS_WINCE_STD)
    fprintf(stderr, "%s%s", msg.toLatin1().data(), m_trcLineDelimiter.toLatin1().data());
	fflush(stderr);
#endif
	emit warningSignal(msg);
}


void QrfeTrace::error(const QString& msg)
{
	QMutexLocker lock(&m_trcMutex);
#if !defined (Q_OS_WINCE) && !defined (Q_OS_WINCE_STD)
    fprintf(stderr, "%s%s", msg.toLatin1().data(), m_trcLineDelimiter.toLatin1().data());
	fflush(stderr);
#endif
	emit errorSignal(msg);
}
#endif

QString QrfeTrace::makeHTML(const QString& trc)
{
	QString trcHTML = trc;
	//trcHTML.replace(" ", "&nbsp;");
	trcHTML.replace("\"", "&quot;");
	trcHTML.replace("&", "&amp;");
	trcHTML.replace("<", "&lt;");
	trcHTML.replace(">", "&gt;");
	return "<html>" + trcHTML + "</html>";
}

