#include <cstdio>
#include <cstdarg>

#include "dexibuild.hpp"
#include "deConsole.hpp"

#ifdef _DEBUG
#include <crtdbg.h>
#endif

static int s_VersionMajor = 0;
static int s_VersionMinor = 1;
static int LogLevelThreshold = Log_Info;

void LogExportMsg(int level, const char* format, ...)
{
	if (level < LogLevelThreshold)
		return;
	va_list Marker;
	static char Buffer[2048];
	
	// Write text to string
	// and append to edit control
	va_start(Marker, format);
	// print to screen
	//	vprintf(format, Marker);
	// print to string
	_vsnprintf(Buffer, 2048, format, Marker);
	va_end(Marker);
	Buffer[2047] = '\0';
	
	// print to screen
	deConsoleOut("%s", Buffer);
	
	// < possibly output to log file >
}

void printusage(const char* exename)
{
	deString2 name2(exename);
	int slash = name2.Find('\\', 0, deString2::search_backwards);
	if (slash < 0)
		slash = name2.Find('/', 0, deString2::search_backwards);
	if (slash >= 0)
		name2 = name2.SubString(slash+1, name2.size());
	LogExportMsg(Log_Info, "Usage:\n");
	LogExportMsg(Log_Info, "%s [-finput.dexi] [-ooutput] [-bbatchdir] [-s1]\n", name2.const_str());
	LogExportMsg(Log_Info, "\t-f specifies a single input filename\n");
	LogExportMsg(Log_Info, "\t-o specifies a single output filename (with -f)\n");
	LogExportMsg(Log_Info, "\t-b specifies a batch-processing directory\n");
	LogExportMsg(Log_Info, "\t-s indicates whether to recurse subdirectories (with -b)\n");
	LogExportMsg(Log_Info, "Defaults: output = input.dworld\n\n");
}

int main(int argc, char* argv[])
{
	int result;
	try
	{
		/*
		double mean,var;
		double dbl_list[] = {1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 100000};
		int num_elems = sizeof(dbl_list)/sizeof(double);
		calc_mean_variance(dbl_list, num_elems, mean, var);
		double std_dev = sqrt(var);
		*/
		deConsole_MakeConsole();
		LogExportMsg(Log_Info, "Destiny3D Tool: DEXI builder, version %d.%d\n\n", 
			s_VersionMajor, s_VersionMinor);
		if (argc <= 1)
		{
			printusage(argv[0]);
			result = 1;
			goto exit_main;
		}

		if (!Destiny3D_Init("dexibuild"))
		{
			throw dexiException("Error initializing Destiny3D\n");
		}
		
		DexiBuilder theBuilder;
		
		int k;
		bool doBatch = false;
		bool doSubDir = false;
		deDouble Scale = 1.0/64;
		deString2 inputFileName;
		deString2 outputFileName;
		deString2 batchDirName;
		for (k = 1; k < argc; ++k)
		{
			deString2 arg = argv[k];
			deString2 decision = arg.SubString(0,2);
			// -o = output option
			if (decision == "-f")
			{
				inputFileName = arg.SubString(2, arg.size());
				if (inputFileName.size() <= 0)
				{
					deString error;
					error.Format("invalid input option: '%s'", arg.const_str());
					throw dexiException(error);
				}
			}
			// -s = scale option
			else if (decision == "-o")
			{
				outputFileName = arg.SubString(2, arg.size());
				if (outputFileName.size() <= 0)
				{
					deString error;
					error.Format("invalid output option: '%s'", arg.const_str());
					throw dexiException(error);
				}
			}
			else if (decision == "-b")
			{
				doBatch = true;
				batchDirName = arg.SubString(2, arg.size());
				if (batchDirName.size() == 0)
				{
					batchDirName = "./";
				}
				deString2::deString_char endchar = batchDirName.get_at(batchDirName.size()-1);
				if (endchar != '/' && endchar != '\\')
				{
					batchDirName += "/";
				}
			}
			else if (decision == "-s")
			{
				arg = arg.SubString(2, arg.size());
				doSubDir= !!atoi(arg.const_str());
			}
			else
			{
				deString error;
				error.Format("invalid input option: '%s'", arg.const_str());
				throw dexiException(error);
			}
		}

		if (!doBatch)
		{
			if (inputFileName == "")
			{
				printusage(argv[0]);
				result = 1;
				goto exit_main;
			}
			theBuilder.loadFile(inputFileName);
		}
		else
		{
			if (batchDirName == "")
			{
				printusage(argv[0]);
				result = 1;
				goto exit_main;
			}
			theBuilder.loadBatch(batchDirName, doSubDir);
		}
	}
	catch (dexiException e)
	{
		LogExportMsg(Log_Error, "============================\n");
		LogExportMsg(Log_Error, "Error: %s\n", e.what.const_str());
		LogExportMsg(Log_Error, "============================\n");
		result = 1;
	}
#ifdef NDEBUG
	catch(...)
	{
		LogExportMsg(Log_Error, "============================\n");
		LogExportMsg(Log_Error, "unknown exception!\n");
		LogExportMsg(Log_Error, "============================\n");
		result = 1;
	}
#endif

exit_main:
	LogExportMsg(Log_Message, "\nDestiny3D_ShutDown\n");
	Destiny3D_ShutDown();
	return result;
}

