/*
 * The X-Log Library, helpping you log what you need to know :)
 * Copyright (C) 2005  Nick Cash   (admin@ew.xidus.net)
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */
 
/*
 * A special thanks to Jack "jollyjeffers" Hoxley and Oli "evolutional" Wilkinson for writing
 * their excellent article on logging posted at Game-Dev. It is the inspiration for this library.
 * The article can be found at: http://www.gamedev.net/reference/programming/features/xmltech/
 */
 
#include "xlog.h" /* also includes stdio for FILE pointers */
#include <stdarg.h>
#include <stdio.h>

#define WIN 1

/* needed for struct stat */
#include <sys/types.h>
#include <sys/stat.h>

#ifdef WIN
#include <windows.h>
#else
#include <time.h>
#endif

char xslt_buf[];
char fname[30];  /* used to open the xml log */

/* local */
int generate_xslt(char *fname);

/*
 * Generate the XSLT template if need be. Fname is the filepath, so you can
 *  save it to any file you wish.
 */
int generate_xslt(char *fname)
{
  if ( fname == NULL || fname[0] == '\0' || (exists_file(fname) == TRUE) )
   return FALSE;
   
  FILE *f = NULL;
  
  if ( (f = fopen(fname,"w")) == NULL )
   return FALSE;

  /* print the file */
  fprintf( f, xslt_buf  );

  fclose(f);
  return TRUE;
}
/* end local */


/*
 * Does a file exist with filen as the file name?
 */
int exists_file( char *filen )
{
  struct stat fst;

  if ( stat( filen, &fst) == -1 )
   return FALSE; /* file doesnt exist! */

  return TRUE;
}

/*
 * Close the log by printing the remaining tags and closing the handle
 */
void end_log( void )
{
  FILE *xml;
  
  if ( (xml = fopen(fname,"a")) == NULL )
    return; /* uh oh */

  /* end log file */
  fprintf( xml, " </Logs>\n" );
  fprintf( xml, "</RunTimeLog>\n" );
  
  /* flush */
  fflush(xml);


  /* close xml log file */
  fclose(xml);
}

/*
 * Initialize the log with the header tags, make sure the XSLT file exists,
 * make sure the log directory exists, or create them.
 */
void init_log( void )
{
#ifdef WIN
  SYSTEMTIME tm;
#else
  time_t rawtime;
  struct tm *t;
#endif
  
  FILE *xml;
  char date[15];
  char time[15];
  static int xlognum = 1;

  /* if the log directory doesnt exist, create it */
  if ( exists_file("log") == FALSE )
   system( "mkdir log" );

  /* if the xslt.xsl file doesnt exist, create it */
  if ( exists_file("log/xslt.xsl") == FALSE )
   generate_xslt("log/xslt.xsl");


  sprintf( fname, "log/%d-xlog.xml", xlognum );

  /* make most recent log */
  for ( ; (exists_file( fname ) == TRUE) ; xlognum++ ) /* increase log num while the file exists */
   sprintf( fname, "log/%d-xlog.xml", xlognum );

  /* create new file */
  if ((xml = fopen(fname, "w")) == NULL)
    return;
    

  /*****************/
  
#ifdef WIN
  GetLocalTime(&tm); /* fill struct with data */

  /* set time and date strings */
  sprintf( time, "%2d:%2d:%2d", tm.wHour, tm.wMinute, tm.wSecond );
  
  sprintf( date, "%s, %s %d, %d", (tm.wDayOfWeek == 0 ? "Sunday" :
                                  (tm.wDayOfWeek == 1 ? "Monday" :
                                  (tm.wDayOfWeek == 2 ? "Tuesday" :
                                  (tm.wDayOfWeek == 3 ? "Wednesday" :
                                  (tm.wDayOfWeek == 4 ? "Thursday" :
                                  (tm.wDayOfWeek == 5 ? "Friday" :
                                  (tm.wDayOfWeek == 6 ? "Saturday" : "Error" ) ) ) ) ) ) ),

                                  (tm.wMonth == 1 ? "January" :
                                  (tm.wMonth == 2 ? "February" :
                                  (tm.wMonth == 3 ? "March" :
                                  (tm.wMonth == 4 ? "April" :
                                  (tm.wMonth == 5 ? "May" :
                                  (tm.wMonth == 6 ? "June" :
                                  (tm.wMonth == 7 ? "July" :
                                  (tm.wMonth == 8 ? "August" :
                                  (tm.wMonth == 9 ? "September" :
                                  (tm.wMonth == 10 ? "October" :
                                  (tm.wMonth == 11 ? "November" :
                                  (tm.wMonth == 12 ? "December" : "Error" ) ) ) ) ) ) ) ) ) ) ) ),
                                   tm.wDay, tm.wYear );
#else
  rawtime = time(NULL);
  t = localtime( &rawtime );

  /* set time and date strings */
  sprintf( time, "%2d:%2d:%2d", t.tm_hour, t.tm_min, t.tm_sec );

  sprintf( date, "%s, %s %d, %d", (t.tm_wday == 0 ? "Sunday" :
                                  (t.tm_wday == 1 ? "Monday" :
                                  (t.tm_wday == 2 ? "Tuesday" :
                                  (t.tm_wday == 3 ? "Wednesday" :
                                  (t.tm_wday == 4 ? "Thursday" :
                                  (t.tm_wday == 5 ? "Friday" :
                                  (t.tm_wday == 6 ? "Saturday" : "Error" ) ) ) ) ) ) ),

                                  (t.tm_mon == 0 ? "January" :
                                  (t.tm_mon == 1 ? "February" :
                                  (t.tm_mon == 2 ? "March" :
                                  (t.tm_mon == 3 ? "April" :
                                  (t.tm_mon == 4 ? "May" :
                                  (t.tm_mon == 5 ? "June" :
                                  (t.tm_mon == 6 ? "July" :
                                  (t.tm_mon == 7 ? "August" :
                                  (t.tm_mon == 8 ? "September" :
                                  (t.tm_mon == 9 ? "October" :
                                  (t.tm_mon == 10 ? "November" :
                                  (t.tm_mon == 11 ? "December" : "Error" ) ) ) ) ) ) ) ) ) ) ) ),
                                   t.tm_mday, t.tm_year );
#endif
  
  fprintf( xml, "<?xml version=\"1.0\" standalone=\"yes\" ?>\n" );
  fprintf( xml, "<?xml-stylesheet type=\"text/xsl\" href=\"xslt.xsl\" ?>\n\n" );
  
  fprintf( xml, "<RunTimeLog>\n" );
  fprintf( xml, " <Header>\n" );
  fprintf( xml, "  <Date>%s</Date>\n", date );
  fprintf( xml, "  <TimeCreated>%s</TimeCreated>\n", time );
  fprintf( xml, " </Header>\n" );
  fprintf( xml, " <Logs>\n" );
  fclose(xml);
  
  end_log();
}

/*
 * Plain text function: creates new line with #, accepts multiple arguments
 */
void log_it(char *Fname, const char *txt, ...)
{
  FILE *fp;
  char buf[3072];
  char file_name[128];
  static int log_num = 0;
  va_list args;

  va_start(args, txt);
  vsprintf(buf, txt, args);
  va_end(args);

  /* if the log directory doesnt exist, create it */
  if ( exists_file("log") == FALSE )
   system( "mkdir log" );

  /* print the fname */
  if ( Fname && Fname[0] != '\0' )
   sprintf( file_name, "log/%s.txt", Fname );
  else
   sprintf( file_name, "log/log.txt" );

  /* try to open logfile */
  if ((fp = fopen(file_name, "a")) == NULL)
    return;

  if ( log_num == 0 )
  {
    fprintf( fp, "\n\n\n\n\n------------------------\n" ); /* give us a few spaces inbetween */
    log_num++;
  }
  else
    log_num++;


  fprintf(fp, "%d.  %s\n", log_num, buf);
  fclose(fp);
}

/*
 * Add XML-style statement to fp, returns FALSE on error, TRUE otherwise
 * embed is the number of spaces before the tag, to keep a nice format
 */
int xml_fprintf( FILE *fp, const char *tag, const char *txt, short embed )
{
  char spacer[51];
  int i = 0;

  if ( fp == NULL )
  {
    glog( "Xml_fprintf: Null file", 0 );
    return FALSE;
  }
  
  if ( (tag == NULL || tag[0] == '\0' ) || (txt == NULL || txt[0] == '\0') )
  {
    glog( "Xml_fprintf: Null string", 0 );
    return FALSE;
  }
  
  if ( embed > 50 )
   embed = 50;

  /* fill the spacer */
  for ( i = 0; i < embed; i++ )
   spacer[i] = ' ';
   
  spacer[i++] = '\0'; /* end string */
  
  /* ok, we have good data, lets print it like we should :P */
  fprintf( fp, "%s<%s>%s</%s>\n", spacer, tag, txt, tag );

  return TRUE;
}

/*
 * Seek to the starting position
 */
void seek_starting(FILE *fp)
{
   if ( fp == NULL )
    return;
    
   short done = FALSE;
   
   fseek( fp, 0, SEEK_SET ); /* go to the start */
   
   while ( done == FALSE )
   {
      char a,b;
      
      for ( ; ; )
        if ( (a = (char)fgetc(fp)) == '<' )
         break;

      if ( (b = (char)fgetc(fp)) == '/' )
      {
          char tmp[5];
          short i;
          
          for ( i = 0; i < 4; i++ )
           tmp[i] = (char)fgetc(fp);
           
          tmp[4] = '\0';

          if ( !stricmp("Logs",tmp) ) /* we found where we need to start */
          {
             done = TRUE;
             fseek( fp, -7, SEEK_CUR ); /* go back */
          }
      }
   }
}

/*
 * Add entry to XML-style log
 */
void log_entry( char *source_file, char *function, int line, const int type, const char *message, ... )
{
  static int num = 0; /* the number */
  char time[16];
  char linen[32];
  FILE *xml;
  
  if ( (xml = fopen(fname,"r+")) == NULL )
   return;

  seek_starting(xml);

  if ( source_file == NULL || source_file[0] == '\0' )
  {
    glog( "Log_entry: Bad source_file string!", 0 );
    return;
  }

  if ( function == NULL || function[0] == '\0' )
  {
    glog( "Log_entry: Bad function name!", 0 );
    return;
  }
  
  if ( message == NULL || message[0] == '\0' )
  {
    glog( "Log_entry: Bad message string!", 0 );
    return;
  }

#ifdef WIN
  SYSTEMTIME tm;
  GetLocalTime(&tm);
  
  sprintf( time, "%2d:%2d:%2d", tm.wHour, tm.wMinute, tm.wSecond );
#else
  time_t rawtime;
  struct tm * t;
  
  time ( &rawtime );
  t = localtime( &rawtime );
  
  sprintf( time, "%2d:%2d:%2d", t.tm_hour, t.tm_min, t.tm_sec );
#endif
  char typen[16];
  char buf[3072];
  va_list args;

  va_start(args, message);
  vsprintf(buf, message, args);
  va_end(args);

  num++;
  
  sprintf( linen, "%d", line );

  sprintf( typen, "%s", type == COMMENT ? "Comment" :
                       (type == ERR     ? "Error"   :
                       (type == WARNING ? "Warning" :
                       (type == EVENT   ? "Event"   :
                       (type == DEBUG   ? "Debug"   :
                       (type == MESSAGE ? "Game Message" : "Unknown" ) ) ) ) ) );
  
  /* 4 spaces before the tag */
  fprintf( xml, "    <LogEvent id=\"%d\">\n", num );
  
  /* print info */
  xml_fprintf( xml, "Type", typen, 8 );
  xml_fprintf( xml, "File", source_file, 8 );
  xml_fprintf( xml, "Function", function, 8 );
  xml_fprintf( xml, "Line", linen, 8 );
  xml_fprintf( xml, "Message", buf, 8 );
  xml_fprintf( xml, "Time", time, 8 );
  fprintf( xml, "    </LogEvent>\n\n" );

  /* flush the file */
  fflush(xml);
  fclose(xml);
  
  end_log();   /* crash-guard */
}

/***************/

/*
 * This is the XSLT template, all held within this string! Feel free to change the colors and stuff
 */
char xslt_buf[] =
{
"\n\
<xsl:stylesheet version=\"1.0\" xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\">\n\n\
\
<!-- This document was originally created by: Jack \"jollyjeffers\" Hoxley and Oli \"evolutional\" Wilkinson -->\n\
<!-- The original article can be found at: http://www.gamedev.net/reference/programming/features/xmltech/ -->\n\
<!-- Modified to fit the X-Log Library by Nick \"Odis\" Cash -->\n\n\
\
<!-- This following section is the entry point for parsing the associated XML        -->\n\
<!-- document. It hands out parsing to the relevent subsections and generally links  -->\n\
	<xsl:template match=\"/\">\n\n\
\
		<html>\n\
			<head>\n\
				<title>Log File Viewer</title>\n\
			</head>\n\
			<body>\n\
				<font face=\"Arial\" size=\"5\" color=\"#2060AA\">\n\
					<b>\n\
						<u>\n\
							Run-Time Log\n\
						</u>\n\
					</b>\n\
				</font>\n\
				<br/>\n\
					<xsl:apply-templates select=\"RunTimeLog/Header\"/>\n\
				<br/>\n\
				<br/>\n\
				<b>\n\
					<font face=\"Arial\" size=\"3\" color=\"#000000\">\n\
						Details of selected log entries:\n\
					</font>\n\
				</b>\n\
				<br/>\n\
				<br/>\n\
				<table border=\"1\" width=\"100%%\" cellspacing=\"0\" cellpadding=\"0\" bordercolorlight=\"#000000\" bordercolordark=\"#ffffff\" bordercolor=\"#000000\">\n\
					<tr>\n\
						<td width=\"3%%\"  bgcolor=\"#000000\"><font size=\"2\" face=\"Arial\" color=\"#FFFFFF\"><b><center>#</center></b></font></td>\n\
						<td width=\"20%%\" bgcolor=\"#000000\"><font size=\"2\" face=\"Arial\" color=\"#FFFFFF\"><b><center>Time</center></b></font></td>\n\
						<td width=\"23%%\" bgcolor=\"#000000\"><font size=\"2\" face=\"Arial\" color=\"#FFFFFF\"><b><center>File</center></b></font></td>\n\
						<td width=\"50%%\" bgcolor=\"#000000\"><font size=\"2\" face=\"Arial\" color=\"#FFFFFF\"><b><center>Function</center></b></font></td>\n\
						<td width=\"4%%\"  bgcolor=\"#000000\"><font size=\"2\" face=\"Arial\" color=\"#FFFFFF\"><b><center>Line</center></b></font></td>\n\
					</tr>\n\
					<xsl:apply-templates select=\"RunTimeLog/Logs/LogEvent\"/>\n\
				</table>\n\
\n\
			</body>\n\
		</html>\n\
\n\
	</xsl:template>\n\
\n\
\n\
\n\
<!-- This next template match is for the log header, that is the general session     -->\n\
<!-- information and run-time system statistics/configuration                        -->\n\
	<xsl:template match=\"Header\">\n\
\n\
		<br/>\n\
		<b>\n\
			<font face=\"Arial\" size=\"3\" color=\"#000000\">\n\
				File information:\n\
			</font>\n\
		</b>\n\
		<br/>\n\
		<font face=\"Arial\" size=\"2\" color=\"#000000\">\n\
			Date:\n\
		</font>\n\
		<i>\n\
			<font face=\"Arial\" size=\"2\" color=\"#808080\">\n\
				<xsl:value-of select=\"Date\"/>\n\
			</font>\n\
		</i>\n\
		<br/>\n\
		<font face=\"Arial\" size=\"2\" color=\"#000000\">\n\
			This log file was created at:\n\
		</font>\n\
		<i>\n\
			<font face=\"Arial\" size=\"2\" color=\"#808080\">\n\
				<xsl:value-of select=\"TimeCreated\"/>\n\
			</font>\n\
		</i>\n\
		<br/>\n\
		<font face=\"Arial\" size=\"2\" color=\"#000000\">\n\
			Total logged events:\n\
		</font>\n\
		<i>\n\
			<font face=\"Arial\" size=\"2\" color=\"#808080\">\n\
				<xsl:copy-of select=\"count(../Logs/LogEvent)\"/>\n\
			</font>\n\
		</i>\n\
\n\
	</xsl:template>\n\
\n\
\n\
\n\
<!-- This template match is for each log entry, filtered according to the selected   -->\n\
<!-- type of event filter. For each log entry we add a row to the table.             -->\n\
        <xsl:template match=\"LogEvent\">\n\
          <xsl:choose>\n\
				<xsl:when test=\"Type=\'Game Message\'\">\n\
							<tr bgcolor=\"#80FF80\" valign=\"middle\" align=\"center\">\n\
\n\
								<td>\n\
									<font size=\"2\" face=\"Arial\" color=\"#202020\">\n\
										<center>\n\
											<xsl:value-of select=\"@id\"/>\n\
										</center>\n\
									</font>\n\
								</td>\n\
\n\
								<xsl:apply-templates select=\"Time\"/>\n\
								<xsl:apply-templates select=\"File\"/>\n\
								<xsl:apply-templates select=\"Function\"/>\n\
								<xsl:apply-templates select=\"Line\"/>\n\
\n\
							</tr>\n\
							<tr bgcolor=\"#AAFFAA\">\n\
								<xsl:apply-templates select=\"Message\"/>\n\
							</tr>\n\
				</xsl:when>\n\
				<xsl:when test=\"Type=\'Unknown\'\">\n\
							<tr bgcolor=\"#EEEEEE\" valign=\"middle\" align=\"center\">\n\
\n\
								<td>\n\
									<font size=\"2\" face=\"Arial\" color=\"#202020\">\n\
										<center>\n\
											<xsl:value-of select=\"@id\"/>\n\
										</center>\n\
									</font>\n\
								</td>\n\
\n\
								<xsl:apply-templates select=\"Time\"/>\n\
								<xsl:apply-templates select=\"File\"/>\n\
								<xsl:apply-templates select=\"Function\"/>\n\
								<xsl:apply-templates select=\"Line\"/>\n\
\n\
							</tr>\n\
							<tr bgcolor=\"#AAAAAA\">\n\
								<xsl:apply-templates select=\"Message\"/>\n\
							</tr>\n\
				</xsl:when>\n\
				<xsl:when test=\"Type=\'Error\'\">\n\
							<tr bgcolor=\"#FF8080\" valign=\"middle\" align=\"center\">\n\
\n\
								<td>\n\
									<font size=\"2\" face=\"Arial\" color=\"#202020\">\n\
										<center>\n\
											<xsl:value-of select=\"@id\"/>\n\
										</center>\n\
									</font>\n\
								</td>\n\
\n\
								<xsl:apply-templates select=\"Time\"/>\n\
								<xsl:apply-templates select=\"File\"/>\n\
								<xsl:apply-templates select=\"Function\"/>\n\
								<xsl:apply-templates select=\"Line\"/>\n\
\n\
							</tr>\n\
							<tr bgcolor=\"#FFAAAA\">\n\
								<xsl:apply-templates select=\"Message\"/>\n\
							</tr>\n\
				</xsl:when>\n\
				<xsl:when test=\"Type='Warning'\">\n\
							<tr bgcolor=\"#FFAA80\" valign=\"middle\" align=\"center\">\n\
\n\
								<td>\n\
									<font size=\"2\" face=\"Arial\" color=\"#202020\">\n\
										<center>\n\
											<xsl:value-of select=\"@id\"/>\n\
										</center>\n\
									</font>\n\
								</td>\n\
\n\
								<xsl:apply-templates select=\"Time\"/>\n\
								<xsl:apply-templates select=\"File\"/>\n\
								<xsl:apply-templates select=\"Function\"/>\n\
								<xsl:apply-templates select=\"Line\"/>\n\
\n\
							</tr>\n\
							<tr bgcolor=\"#FFDDAA\">\n\
								<xsl:apply-templates select=\"Message\"/>\n\
							</tr>\n\
				</xsl:when>\n\
				<xsl:when test=\"Type=\'Event\'\">\n\
							<tr bgcolor=\"#8080FF\" valign=\"middle\" align=\"center\">\n\
\n\
								<td>\n\
									<font size=\"2\" face=\"Arial\" color=\"#202020\">\n\
										<center>\n\
											<xsl:value-of select=\"@id\"/>\n\
										</center>\n\
									</font>\n\
								</td>\n\
\n\
								<xsl:apply-templates select=\"Time\"/>\n\
								<xsl:apply-templates select=\"File\"/>\n\
								<xsl:apply-templates select=\"Function\"/>\n\
								<xsl:apply-templates select=\"Line\"/>\n\
\n\
							</tr>\n\
							<tr bgcolor=\"#AAAAFF\">\n\
								<xsl:apply-templates select=\"Message\"/>\n\
							</tr>\n\
				</xsl:when>\n\
				<xsl:when test=\"Type=\'Debug\'\">\n\
							<tr bgcolor=\"#FFFF80\" valign=\"middle\" align=\"center\">\n\
\n\
								<td>\n\
									<font size=\"2\" face=\"Arial\" color=\"#202020\">\n\
										<center>\n\
											<xsl:value-of select=\"@id\"/>\n\
										</center>\n\
									</font>\n\
								</td>\n\
\n\
								<xsl:apply-templates select=\"Time\"/>\n\
								<xsl:apply-templates select=\"File\"/>\n\
								<xsl:apply-templates select=\"Function\"/>\n\
								<xsl:apply-templates select=\"Line\"/>\n\
\n\
							</tr>\n\
							<tr bgcolor=\"#FFFF99\">\n\
								<xsl:apply-templates select=\"Message\"/>\n\
							</tr>\n\
				</xsl:when>\n\
				<xsl:when test=\"Type=\'Comment\'\">\n\
							<tr bgcolor=\"#FF8020\" valign=\"middle\" align=\"center\">\n\
\n\
								<td>\n\
									<font size=\"2\" face=\"Arial\" color=\"#202020\">\n\
										<center>\n\
											<xsl:value-of select=\"@id\"/>\n\
										</center>\n\
									</font>\n\
								</td>\n\
\n\
								<xsl:apply-templates select=\"Time\"/>\n\
								<xsl:apply-templates select=\"File\"/>\n\
								<xsl:apply-templates select=\"Function\"/>\n\
								<xsl:apply-templates select=\"Line\"/>\n\
\n\
							</tr>\n\
							<tr bgcolor=\"#FFAA80\">\n\
								<xsl:apply-templates select=\"Message\"/>\n\
							</tr>\n\
				</xsl:when>\n\
			</xsl:choose>\n\
\n\
	</xsl:template>\n\
\n\
\n\
\n\
<!-- This match is for the formatted time output associate with each log entry       -->\n\
	<xsl:template match=\"Time\">\n\
		<td>\n\
			<font size=\"2\" face=\"Courier New\" color=\"#404040\">\n\
				<center>\n\
					<xsl:apply-templates/>\n\
				</center>\n\
			</font>\n\
		</td>\n\
	</xsl:template>\n\
\n\
\n\
\n\
<!-- This match is for the source code filename where this entry originated from     -->\n\
	<xsl:template match=\"File\">\n\
		<td>\n\
			<font size=\"2\" face=\"Courier New\" color=\"#404040\">\n\
				<xsl:apply-templates/>\n\
			</font>\n\
		</td>\n\
	</xsl:template>\n\
\n\
\n\
\n\
<!-- This match outputs the qualified function name where the entry was created      -->\n\
	<xsl:template match=\"Function\">\n\
		<td>\n\
			<font size=\"2\" face=\"Courier New\" color=\"#404040\">\n\
				<xsl:apply-templates/>\n\
			</font>\n\
		</td>\n\
	</xsl:template>\n\
\n\
\n\
\n\
<!-- This outputs the line number for the given source code file.                    -->\n\
	<xsl:template match=\"Line\">\n\
		<td>\n\
			<font size=\"2\" face=\"Courier New\" color=\"#404040\">\n\
				<center>\n\
					<xsl:apply-templates/>\n\
				</center>\n\
			</font>\n\
		</td>\n\
	</xsl:template>\n\
\n\
\n\
\n\
<!-- This match outputs the raw 'Message' data that's sttached to this log entry.    -->\n\
	<xsl:template match=\"Message\">\n\
		<td bgcolor=\"#FFFFFF\">\n\
		</td>\n\
			<td colspan=\"4\">\n\
				<font size=\"2\" face=\"Arial\" color=\"#000000\">\n\
					<b>\n\
						<i>\n\
							<xsl:apply-templates/>\n\
						</i>\n\
					</b>\n\
				</font>\n\
			</td>\n\
	</xsl:template>\n\
\n\
\n\
\n\
</xsl:stylesheet>\n\
"
};