///////////////////////////////////////////////////////////////////////////////
/// @file deLogDestiny.cpp
///
/// @brief Error and Logging Class - Destiny Version I
///
/// @author Hootie
///
/// This file is the intellectual property of Novus Delta, LLC.. Usage of the
/// contents of this file is subject to the Destiny3D Member License which
/// can be found at http://www.destiny3d.com.  Any other usage is prohibited.
///
/// This file is distributed "AS IS" without warranty of any kind.  Novus
/// Delta, LLC. does not guarantee the fitness of the contents of this file
/// for any particular purpose.
///
/// Copyright (C) 2001-2003 Novus Delta, LLC. All Rights Reserved.
///
/// <hr>
///                                 Change History
/// <hr>
///
/// @date Dec 2001
/// @author Hootie
/// @remarks Creation
///
///////////////////////////////////////////////////////////////////////////////

//=================================================================================
// Includes
//=================================================================================

#include <cstdio>
#include <windows.h> // for various things in here

#include "deLogDestiny.hpp"



//=================================================================================
// Externs
//=================================================================================

extern char ErrorFileDir[_MAX_PATH + 1];
extern char LogFileDir[_MAX_PATH + 1];
extern char GlobalLogName[120];
extern deTArray<deString*> DestinyErrors;
extern deTArray<deString*> UserErrors;



//=================================================================================
// deLogDestiny::deLogDestiny()
//
// Constructor 
//=================================================================================
deLogDestiny::deLogDestiny(char* /*LogName*/)
{
#pragma fixme(the ConfigFile stuff here needs to be revamped)
#if 0
	FileInfo LogInfo;
	char ErrorFilePath[_MAX_PATH + 1];
	char LogFilePath[_MAX_PATH + 1];
	
	
	CreationResult = deFALSE;
	LogInfo.ThreadID = GetCurrentThreadId();
	LogInfo.ErrorFile = NULL;
	LogInfo.LogFile = NULL;
	ErrorFilePath[0] = NULL;
	LogFilePath[0] = NULL;
	
	if (LogName == NULL)
		strcpy(BaseFileName, GlobalLogName);
	else
		strcpy(BaseFileName, LogName);
	
	strcat(ErrorFilePath, ErrorFileDir);
	strcat(ErrorFilePath, "\\");
	strcat(ErrorFilePath, BaseFileName);
	strcat(ErrorFilePath, ".err");
	
	strcat(LogFilePath, LogFileDir);
	strcat(LogFilePath, "\\");
	strcat(LogFilePath, BaseFileName);
	strcat(LogFilePath, ".log");
	
	LogInfo.ErrorFile = new deWinFile;
	
	if (!LogInfo.ErrorFile)
	{
		// error - deWinFile create failed
		return;
	}
	
	LogInfo.LogFile = new deWinFile;
	
	if (!LogInfo.LogFile)
	{
		// error - deWinFile create failed
		delete LogInfo.ErrorFile;
		return;
	}
	
	if (!LogInfo.ErrorFile->Open(ErrorFilePath, DEWINFILE_WRITEONLY, DEWINFILE_NEW))
	{
		// error - File create failed
		delete LogInfo.ErrorFile;
		delete LogInfo.LogFile;
		return;
	}
	
	if (!LogInfo.LogFile->Open(LogFilePath, DEWINFILE_WRITEONLY, DEWINFILE_NEW))
	{
		// error - File create failed
		delete LogInfo.ErrorFile;
		delete LogInfo.LogFile;
		return;
	}
	
	if (!LogFiles.PushBack(LogInfo))
	{
		// error - SetElement failed
		delete LogInfo.ErrorFile;
		delete LogInfo.LogFile;
		return;
	}
	
	CreationResult = deTRUE;
	return;
#endif
}



//=================================================================================
// deLogDestiny::~deLogDestiny()
//
// Destructor 
//=================================================================================
deLogDestiny::~deLogDestiny()
{
#pragma fixme(the ConfigFile stuff here needs to be revamped)
#if 0
	FileInfo *LogInfo;
	unsigned int ElementCount = 0;
	unsigned int looper = 0;


	ElementCount = LogFiles.Length();

	for (looper = 0; looper < ElementCount; looper++)
	{
		LogInfo = &LogFiles[looper];
		LogInfo->ErrorFile->Close();
		LogInfo->LogFile->Close();
		delete LogInfo->ErrorFile;
		delete LogInfo->LogFile;
	}

	return;
#endif
}



//=================================================================================
// deLogDestiny::Error()
//
// Process a single predefined error message
//=================================================================================
void deLogDestiny::Error(deErrorLevelType /*ErrorLevel*/, unsigned int /*ErrorCode*/)
{
#pragma fixme(the ConfigFile stuff here needs to be revamped)
#if 0
	FileInfo LogInfo;
	deString *ErrorMessage;
	unsigned int ErrorSub = 0;
	char Buffer[1024];
	
	
	Buffer[0] = NULL;
	
	if (!GetThreadFileInfo(&LogInfo))
	{
		// error - GetThreadFileInfo failed
		return;
	}
	
	if (ErrorCode > 99999)
	{
		ErrorSub = ErrorCode - 100000;
		ErrorMessage = (deString *)UserErrors->GetElement(ErrorSub);
	}
	else
		ErrorMessage = (deString *)DestinyErrors->GetElement(ErrorCode);
	
	if (ErrorLevel == DEERROR_WARNING)
		strcat(Buffer, "Warning: ");
	
	if (ErrorLevel == DEERROR_ERROR)
		strcat(Buffer, "Error: ");
	
	if (ErrorLevel == DEERROR_FATAL)
		strcat(Buffer, "Fatal Error: ");
	
	strcat(Buffer, ErrorMessage->const_str());
	strcat(Buffer, "\r\n");
	
	LogInfo.ErrorFile->Write(Buffer, strlen(Buffer));
	
	if (ErrorLevel == DEERROR_FATAL)
	{
		MessageBox(NULL, "A fatal error has occurred.  Check the application's error log for details.", "Destiny3D Fatal Error", MB_OK);
		exit(-1);
	}
	
	return;
#endif
}



//=================================================================================
// deLogDestiny::Error()
//
// Process a single freeform error message
//=================================================================================
void deLogDestiny::Error(deErrorLevelType /*ErrorLevel*/, char* /*Format*/, ...)
{
#pragma fixme(the ConfigFile stuff here needs to be revamped)
#if 0
	va_list args;
	FileInfo LogInfo;
	char ErrorMessage[1024];
	char Buffer[1024];
	
	
	Buffer[0] = NULL;
	ErrorMessage[0] = NULL;
	
	if (!GetThreadFileInfo(&LogInfo))
	{
		// error - GetThreadFileInfo failed
		return;
	}
	
	va_start(args, Format);
	vsprintf(ErrorMessage, Format, args);
	va_end(args);
	
	if (ErrorLevel == DEERROR_WARNING)
		strcat(Buffer, "Warning: ");
	
	if (ErrorLevel == DEERROR_ERROR)
		strcat(Buffer, "Error: ");
	
	if (ErrorLevel == DEERROR_FATAL)
		strcat(Buffer, "Fatal Error: ");
	
	strcat(Buffer, ErrorMessage);
	strcat(Buffer, "\r\n");
	
	LogInfo.ErrorFile->Write(Buffer, strlen(Buffer));
	
	if (ErrorLevel == DEERROR_FATAL)
	{
		MessageBox(NULL, "A fatal error has occurred.  Check the application's error log for details.", "Destiny3D Fatal Error", MB_OK);
		exit(-1);
	}
	
	return;
#endif
}



//=================================================================================
// deLogDestiny::ErrorStart()
//
// Start an error message block
//=================================================================================
void deLogDestiny::ErrorStart(deErrorLevelType /*ErrorLevel*/)
{
#pragma fixme(the ConfigFile stuff here needs to be revamped)
#if 0
	FileInfo LogInfo;
	char Buffer[1024];
	
	
	Buffer[0] = NULL;
	
	if (!GetThreadFileInfo(&LogInfo))
	{
		// error - GetThreadFileInfo failed
		return;
	}
	
	if (ErrorLevel == DEERROR_WARNING)
		strcat(Buffer, "Error Block: Start   Error Level: Warning");
	
	if (ErrorLevel == DEERROR_ERROR)
		strcat(Buffer, "Error Block: Start   Error Level: Error");
	
	if (ErrorLevel == DEERROR_FATAL)
		strcat(Buffer, "Error Block: Start   Error Level: Fatal Error");
	
	strcat(Buffer, "\r\n");
	
	LogInfo.ErrorFile->Write(Buffer, strlen(Buffer));
	
	return;
#endif
}



//=================================================================================
// deLogDestiny::ErrorAddLine()
//
// Add a predefined error message to an error block
//=================================================================================
void deLogDestiny::ErrorAddLine(unsigned int /*ErrorCode*/)
{
#pragma fixme(the ConfigFile stuff here needs to be revamped)
#if 0
	FileInfo LogInfo;
	deString *ErrorMessage;
	unsigned int ErrorSub = 0;
	char Buffer[1024];
	
	
	Buffer[0] = NULL;
	
	if (!GetThreadFileInfo(&LogInfo))
	{
		// error - GetThreadFileInfo failed
		return;
	}
	
	if (ErrorCode > 99999)
	{
		ErrorSub = ErrorCode - 100000;
		ErrorMessage = UserErrors[ErrorSub];
	}
	else
		ErrorMessage = DestinyErrors[ErrorCode];
	
	strcat(Buffer, "Error Block: ");
	strcat(Buffer, ErrorMessage->const_str());
	strcat(Buffer, "\r\n");
	
	LogInfo.ErrorFile->Write(Buffer, strlen(Buffer));
	
	return;
#endif
}



//=================================================================================
// deLogDestiny::ErrorAddLine()
//
// Add a freeform error message to an error block
//=================================================================================
void deLogDestiny::ErrorAddLine(char* /*Format*/, ...)
{
#pragma fixme(the ConfigFile stuff here needs to be revamped)
#if 0
	va_list args;
	FileInfo LogInfo;
	char ErrorMessage[1024];
	char Buffer[1024];
	
	
	Buffer[0] = NULL;
	ErrorMessage[0] = NULL;
	
	if (!GetThreadFileInfo(&LogInfo))
	{
		// error - GetThreadFileInfo failed
		return;
	}
	
	va_start(args, Format);
	vsprintf(ErrorMessage, Format, args);
	va_end(args);
	
	strcat(Buffer, "Error Block: ");
	strcat(Buffer, ErrorMessage);
	strcat(Buffer, "\r\n");
	
	LogInfo.ErrorFile->Write(Buffer, strlen(Buffer));
	
	return;
#endif
}



//=================================================================================
// deLogDestiny::ErrorEnd()
//
// End an error message block
//=================================================================================
void deLogDestiny::ErrorEnd(deErrorLevelType /*ErrorLevel*/)
{
#pragma fixme(the ConfigFile stuff here needs to be revamped)
#if 0
	FileInfo LogInfo;
	char Buffer[1024];
	
	
	Buffer[0] = NULL;
	
	if (!GetThreadFileInfo(&LogInfo))
	{
		// error - GetThreadFileInfo failed
		return;
	}
	
	if (ErrorLevel == DEERROR_WARNING)
		strcat(Buffer, "Error Block: End   Error Level: Warning");
	
	if (ErrorLevel == DEERROR_ERROR)
		strcat(Buffer, "Error Block: End   Error Level: Error");
	
	if (ErrorLevel == DEERROR_FATAL)
		strcat(Buffer, "Error Block: End   Error Level: Fatal Error");
	
	strcat(Buffer, "\r\n");
	
	LogInfo.ErrorFile->Write(Buffer, strlen(Buffer));
	
	if (ErrorLevel == DEERROR_FATAL)
	{
		MessageBox(NULL, "A fatal error has occurred.  Check the application's error log for details.", "Destiny3D Fatal Error", MB_OK);
		exit(-1);
	}
	
	return;
#endif
}



//=================================================================================
// deLogDestiny::Log()
//
// Process a single freeform log message
//=================================================================================
void deLogDestiny::Log(char* /*Format*/, ...)
{
#pragma fixme(the ConfigFile stuff here needs to be revamped)
#if 0
	va_list args;
	FileInfo LogInfo;
	char LogMessage[1024];
	char Buffer[1024];
	
	
	Buffer[0] = NULL;
	LogMessage[0] = NULL;
	
	if (!GetThreadFileInfo(&LogInfo))
	{
		// error - GetThreadFileInfo failed
		return;
	}
	
	va_start(args, Format);
	vsprintf(LogMessage, Format, args);
	va_end(args);
	
	strcat(Buffer, LogMessage);
	strcat(Buffer, "\r\n");
	
	LogInfo.LogFile->Write(Buffer, strlen(Buffer));
	
	return;
#endif
}



//=================================================================================
// deLogDestiny::LogFunctionStart()
//
// Start a function log block
//=================================================================================
void deLogDestiny::LogFunctionStart(const char* /*FunctionName*/)
{
#pragma fixme(the ConfigFile stuff here needs to be revamped)
#if 0
	FileInfo LogInfo;
	char Buffer[1024];
	
	
	Buffer[0] = NULL;
	
	if (!GetThreadFileInfo(&LogInfo))
	{
		// error - GetThreadFileInfo failed
		return;
	}
	
	strcat(Buffer, "Function Log: Start   Function: ");
	strcat(Buffer, FunctionName);
	strcat(Buffer, "\r\n");
	
	LogInfo.LogFile->Write(Buffer, strlen(Buffer));
	
	return;
#endif
}



//=================================================================================
// deLogDestiny::LogParamListStart()
//
// Start a parameter list log block
//=================================================================================
void deLogDestiny::LogParamListStart()
{
#pragma fixme(the ConfigFile stuff here needs to be revamped)
#if 0
	FileInfo LogInfo;
	char Buffer[1024];
	
	
	Buffer[0] = NULL;
	
	if (!GetThreadFileInfo(&LogInfo))
	{
		// error - GetThreadFileInfo failed
		return;
	}
	
	strcat(Buffer, "Function Log: Parameter List Start");
	strcat(Buffer, "\r\n");
	
	LogInfo.LogFile->Write(Buffer, strlen(Buffer));
	
	return;
#endif
}



//=================================================================================
// deLogDestiny::LogParamListEnd()
//
// End a parameter list log block
//=================================================================================
void deLogDestiny::LogParamListEnd()
{
#pragma fixme(the ConfigFile stuff here needs to be revamped)
#if 0
	FileInfo LogInfo;
	char Buffer[1024];
	
	
	Buffer[0] = NULL;
	
	if (!GetThreadFileInfo(&LogInfo))
	{
		// error - GetThreadFileInfo failed
		return;
	}
	
	strcat(Buffer, "Function Log: Parameter List End");
	strcat(Buffer, "\r\n");
	
	LogInfo.LogFile->Write(Buffer, strlen(Buffer));
	
	return;
#endif
}



//=================================================================================
// deLogDestiny::LogFunctionEnd()
//
// End a function log block
//=================================================================================
void deLogDestiny::LogFunctionEnd(const char* /*FunctionName*/)
{
#pragma fixme(the ConfigFile stuff here needs to be revamped)
#if 0
	FileInfo LogInfo;
	char Buffer[1024];
	
	
	Buffer[0] = NULL;
	
	if (!GetThreadFileInfo(&LogInfo))
	{
		// error - GetThreadFileInfo failed
		return;
	}
	
	strcat(Buffer, "Function Log: End   Function: ");
	strcat(Buffer, FunctionName);
	strcat(Buffer, "\r\n");
	
	LogInfo.LogFile->Write(Buffer, strlen(Buffer));
	
	return;
#endif
}



//=================================================================================
// deLogDestiny::LogVariable()
//
// Process a variable value display log message
//=================================================================================
void deLogDestiny::LogVariable(const char* /*VarName*/, char* /*Format*/, ...)
{
#pragma fixme(the ConfigFile stuff here needs to be revamped)
#if 0
	va_list args;
	FileInfo LogInfo;
	char LogMessage[1024];
	char Buffer[1024];
	
	
	Buffer[0] = NULL;
	LogMessage[0] = NULL;
	
	if (!GetThreadFileInfo(&LogInfo))
	{
		// error - GetThreadFileInfo failed
		return;
	}
	
	va_start(args, Format);
	vsprintf(LogMessage, Format, args);
	va_end(args);
	
	strcat(Buffer, "Function Log: Variable: ");
	strcat(Buffer, VarName);
	strcat(Buffer, "  Value: ");
	strcat(Buffer, LogMessage);
	strcat(Buffer, "\r\n");
	
	LogInfo.LogFile->Write(Buffer, strlen(Buffer));
	
	return;
#endif
}



//=================================================================================
// deLogDestiny::GetThreadFileInfo()
//
// Get the files associated with the current thread making a request
//=================================================================================
deBoolean deLogDestiny::GetThreadFileInfo(FileInfo* /*Info*/)
{
#pragma fixme(the ConfigFile stuff here needs to be revamped)
#if 0
	FileInfo *LogInfo = NULL;
	FileInfo NewLogInfo;
	char ErrorFilePath[_MAX_PATH + 1];
	char LogFilePath[_MAX_PATH + 1];
	unsigned int ThreadID = 0;
	char StringThreadID[20];
	unsigned int ElementCount = 0;
	unsigned int looper = 0;
	
	
	ThreadID = GetCurrentThreadId();
	ElementCount = LogFiles.Length();
	
	for (looper = 0; looper < ElementCount; looper++)
	{
		LogInfo = &LogFiles[looper];
		
		if (LogInfo->ThreadID == ThreadID)
			break;
	}
	
	if (looper == ElementCount)
	{
		NewLogInfo.ThreadID = ThreadID;
		NewLogInfo.ErrorFile = NULL;
		NewLogInfo.LogFile = NULL;
		ErrorFilePath[0] = NULL;
		LogFilePath[0] = NULL;
		StringThreadID[0] = NULL;
		
		itoa(ThreadID, StringThreadID, 10);
		
		strcat(ErrorFilePath, ErrorFileDir);
		strcat(ErrorFilePath, "\\");
		strcat(ErrorFilePath, BaseFileName);
		strcat(ErrorFilePath, "_Thread");
		strcat(ErrorFilePath, StringThreadID);
		strcat(ErrorFilePath, ".err");
		
		strcat(LogFilePath, LogFileDir);
		strcat(LogFilePath, "\\");
		strcat(LogFilePath, BaseFileName);
		strcat(LogFilePath, "_Thread");
		strcat(LogFilePath, StringThreadID);
		strcat(LogFilePath, ".log");
		
		NewLogInfo.ErrorFile = new deWinFile;
		
		if (!NewLogInfo.ErrorFile)
		{
			// error - deWinFile create failed
			return deFALSE;
		}
		
		NewLogInfo.LogFile = new deWinFile;
		
		if (!NewLogInfo.LogFile)
		{
			// error - deWinFile create failed
			delete NewLogInfo.ErrorFile;
			return deFALSE;
		}
		
		if (!NewLogInfo.ErrorFile->Open(ErrorFilePath, DEWINFILE_WRITEONLY, DEWINFILE_NEW))
		{
			// error - File create failed
			delete NewLogInfo.ErrorFile;
			delete NewLogInfo.LogFile;
			return deFALSE;
		}
		
		if (!NewLogInfo.LogFile->Open(LogFilePath, DEWINFILE_WRITEONLY, DEWINFILE_NEW))
		{
			// error - File create failed
			delete NewLogInfo.ErrorFile;
			delete NewLogInfo.LogFile;
			return deFALSE;
		}
		
		LogFiles[ElementCount] = NewLogInfo;
			
		*Info = NewLogInfo;
		return deTRUE;
	}
	
	*Info = *LogInfo;
	return deTRUE;
#endif
	return deFALSE;
}
