// Author : Chris Tolley
// Date   : 2/28/2004
// logger.cpp contains the class definition for an event/error logger.  It 
// logs stuff into an xml data files.  To use the logger, you only have to 
// include it into your and each file you want to log events from.  All members
// in this class are static so just create the output file stream from your 
// main and then call the logging functions from anywhere in your code.

#include <iostream>
#include <fstream>

using namespace std;

#include "logger.h"

// Initialize some static data
bool logger::loggingOn_ = false;
ofstream logger::out_;
int logger::entryNumber_ = 1;

// Opens an output file stream for log storing. Should be an xml file
void logger::open( const char* file )
{
	// If the output stream was open already, close it
	if( loggingOn_ )
	{
		out_.close();
		loggingOn_ = false;
	}// End if

	// Open the file
	out_.open( file );
	
	// Reset the number of log entry
	entryNumber_ = 1;

	// Turn logging on
	loggingOn_ = true;

	// Write some xml to the file
	out_ << "<?xml version='1.0' encoding='ISO-8859-1' ?>" << endl;
	out_ << "<?xml-stylesheet type='text/xsl' href='event.xsl'?>" << endl;
	out_ << "<report>" << endl << "</report>";
}// End logger::open


// Closes the log file so that no more logging can happen
void logger::close()
{
	// Close the file stream
	out_.close();
	
	// Turn logging off
	loggingOn_ = false;

	// Reset the entry number
	entryNumber_ = 1;
}// End logger::close


// Writes an error to the data file.  function is the name of the functino
// that you are in and msg is a message you want written.
void logger::error( const string& function, const string& msg )
{
	// Make sure that logging is turned on
	if( ! loggingOn_ )
		return;

	// Back up 11 spaces to over the last closing tag
	out_.seekp( -11, ios::end );

	// Write the new error
	out_ << "  <error>" << endl;
	out_ << "    <number> " << entryNumber_ << " </number>" << endl;
	out_ << "    <function> " << function << " </function>" << endl;
	out_ << "    <message> " << msg << " </message>" << endl;
	out_ << "  </error>" << endl;
	out_ << "</report>" << endl;

	// increment the entryNumber;
	++entryNumber_;
}// End logger::error


// The following functions writes an event to the log.  function is
// the name of the function where the event took place and data is a
// piece of data.
void logger::event( const string& function, const string& msg, const string& data )
{	
	// Make sure that logging is turned on
	if( ! loggingOn_ )
		return;

	// Back up 11 spaces to over the last closing tag
	out_.seekp( -11, ios::end );

	// Write the new event
	out_ << "  <event>" << endl;
	out_ << "    <number> " << entryNumber_ << " </number>" << endl;
	out_ << "    <function> " << function << " </function>" << endl;
	out_ << "    <message> " << msg << " </message>" << endl;
	out_ << "    <data> " << data << " </data>" << endl;
	out_ << "  </event>" << endl;
	out_ << "</report>" << endl;

	// increment the entryNumber;
	++entryNumber_;
}// End logger::event(string)


void logger::event( const string& function, const string& msg, const int& data )
{
	// Make sure that logging is turned on
	if( ! loggingOn_ )
		return;

	// Back up 11 spaces to over the last closing tag
	out_.seekp( -11, ios::end );

	// Write the new event
	out_ << "  <event>" << endl;
	out_ << "    <number> " << entryNumber_ << " </number>" << endl;
	out_ << "    <function> " << function << " </function>" << endl;
	out_ << "    <message> " << msg << " </message>" << endl;
	out_ << "    <data> " << data << " </data>" << endl;
	out_ << "  </event>" << endl;
	out_ << "</report>" << endl;

	// increment the entryNumber;
	++entryNumber_;
}// End logger::event(int)


void logger::event( const string& function, const string& msg, const float& data )
{
	// Make sure that logging is turned on
	if( ! loggingOn_ )
		return;

	// Back up 11 spaces to over the last closing tag
	out_.seekp( -11, ios::end );

	// Write the new event
	out_ << "  <event>" << endl;
	out_ << "    <number> " << entryNumber_ << " </number>" << endl;
	out_ << "    <function> " << function << " </function>" << endl;
	out_ << "    <message> " << msg << " </message>" << endl;
	out_ << "    <data> " << data << " </data>" << endl;
	out_ << "  </event>" << endl;
	out_ << "</report>" << endl;

	// increment the entryNumber;
	++entryNumber_;
}// End logger::event(float)


void logger::event( const string& function, const string& msg, const double& data )
{
	// Make sure that logging is turned on
	if( ! loggingOn_ )
		return;

	// Back up 11 spaces to over the last closing tag
	out_.seekp( -11, ios::end );

	// Write the new event
	out_ << "  <event>" << endl;
	out_ << "    <number> " << entryNumber_ << " </number>" << endl;
	out_ << "    <function> " << function << " </function>" << endl;
	out_ << "    <message> " << msg << " </message>" << endl;
	out_ << "    <data> " << data << " </data>" << endl;
	out_ << "  </event>" << endl;
	out_ << "</report>" << endl;

	// increment the entryNumber;
	++entryNumber_;
}// End logger::event(double)


void logger::event( const string& function, const string& msg, const bool& data )
{
	// Make sure that logging is turned on
	if( ! loggingOn_ )
		return;

	// Back up 11 spaces to over the last closing tag
	out_.seekp( -11, ios::end );

	// Write the new event
	out_ << "  <event>" << endl;
	out_ << "    <number> " << entryNumber_ << " </number>" << endl;
	out_ << "    <function> " << function << " </function>" << endl;
	out_ << "    <message> " << msg << " </message>" << endl;
	out_ << "    <data> " << data << " </data>" << endl;
	out_ << "  </event>" << endl;
	out_ << "</report>" << endl;

	// increment the entryNumber;
	++entryNumber_;
}// End logger::event(bool)


void logger::event( const string& function, const string& msg, const unsigned int& data )
{
	// Make sure that logging is turned on
	if( ! loggingOn_ )
		return;

	// Back up 11 spaces to over the last closing tag
	out_.seekp( -11, ios::end );

	// Write the new event
	out_ << "  <event>" << endl;
	out_ << "    <number> " << entryNumber_ << " </number>" << endl;
	out_ << "    <function> " << function << " </function>" << endl;
	out_ << "    <message> " << msg << " </message>" << endl;
	out_ << "    <data> " << data << " </data>" << endl;
	out_ << "  </event>" << endl;
	out_ << "</report>" << endl;

	// increment the entryNumber;
	++entryNumber_;
}// End logger::event(unsigned int)