#include <Stuff\StuffHeaders.hpp>
#include <MLR\MLRTexturePool.hpp>
#include <DLLPlatform\DLLPlatform.hpp>

#include <ElementRenderer\ElementRenderer.hpp>
#include <ElementRenderer\GroupElement.hpp>
#include <ElementRenderer\ListElement.hpp>
#include <ElementRenderer\SwitchElement.hpp>
#include <ElementRenderer\ShapeElement.hpp>
#include <ElementRenderer\GridElement.hpp>
#include <ElementRenderer\StateChange.hpp>
#include <MLR\MLRHeaders.hpp>
#include <gosFX\gosFX.hpp>

#include "ImageLib\image.h"

#include <GameOS\ToolOS.hpp>

//#define NON_DEBUG_BUG 1

char theName[1024];

char contentPath[1024];
char inputPath[1024];

char texturePath[1024];
char outputPath[1024];

void FileExportMaster(int, int, Scalar, Scalar, Scalar, Scalar, const char *fname);
void ImportMegabasetexture(Page *page);
void ImportExportCulturalMeshs(Page *map_to_convert, const char*, const 
char*, Scalar, Scalar, Scalar, Scalar);

FILE *analyzeFile;

void __stdcall InitializeGameEngine()
{
	//
	//---------------------
	// Initialize libraries
	//---------------------
	//
	Stuff::InitializeClasses();
	MidLevelRenderer::InitializeClasses(NULL, 32768*16);
	gosFX::InitializeClasses();
	ElementRenderer::InitializeClasses();

	Stuff::ArmorLevel=1;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void __stdcall DoGameLogic()
{
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void __stdcall UpdateDisplay()
{
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void __stdcall TerminateGameEngine()
{
	//
	//-------------------
	// Turn off libraries
	//-------------------
	//
	ElementRenderer::TerminateClasses();
	gosFX::TerminateClasses();
	MidLevelRenderer::TerminateClasses();
	Stuff::TerminateClasses();
}

//
// Setup the GameOS structure
//
void __stdcall GetGameOSEnvironment( char* CommandLine )
{
	CommandLine = CommandLine;
	Environment.applicationName			= "PMeshHunter";
	Environment.directoryPath			=	"\\Tools\\PMeshHunter";
	Environment.screenWidth				= 640;
	Environment.screenHeight			= 480;
	Environment.fullScreen				= FALSE;
	Environment.bitDepth				= 16;
	Environment.debugLog				= "PMeshHunterLog.txt";
	Environment.spew					= "";			//"GameOS*";

	Environment.UpdateRenderers			= UpdateDisplay;
	Environment.DoGameLogic				= DoGameLogic;
	Environment.InitializeGameEngine	= InitializeGameEngine;
	Environment.TerminateGameEngine		= TerminateGameEngine;

	Environment.Renderer				= 0;
	Environment.FullScreenDevice		= 0;

	Environment.AntiAlias				= 0;			// true/false - Enable full screen antialiasing

	//
	// Texture infomation
	//
	Environment.Texture_S_256			= 13;
	Environment.Texture_S_128			= 12;
	Environment.Texture_S_64			= 1;
	Environment.Texture_S_32			= 1;
	Environment.Texture_S_16			= 1;

	Environment.Texture_K_256			= 1;
	Environment.Texture_K_128			= 1;
	Environment.Texture_K_64			= 1;
	Environment.Texture_K_32			= 1;
	Environment.Texture_K_16			= 1;

	Environment.Texture_A_256			= 1;
	Environment.Texture_A_128			= 1;
	Environment.Texture_A_64			= 1;
	Environment.Texture_A_32			= 1;
	Environment.Texture_A_16			= 1;
}

void
	CheckFiles(const char *dir)
{
	char file_name[1024];
	char long_file_name[1024];

	sprintf(file_name, "%s\\*.erf", dir);

	const char *fname = gos_FindFiles(file_name);

	while(fname!=NULL)
	{
		sprintf(long_file_name, "%s\\%s", dir, fname);
		if(gos_DoesFileExist((const char *)long_file_name))
		{
			FileStream fs;

			fs.Open(long_file_name);

			if(fs.IsFileOpened()==true)
			{
				SPEWALWAYS((0, "%s", long_file_name));
				gos_PushCurrentHeap(ElementRenderer::g_Heap);
				ElementRenderer::Element *element = ElementRenderer::Element::Create(&fs, ElementRenderer::ReadERFVersion(&fs));
				gos_PopCurrentHeap();

				Check_Object(element);
				delete element;
			}

		}

		fname = gos_FindFilesNext();
	}
	gos_FindFilesClose();

	sprintf(file_name, "%s\\*.mlr", dir);

	fname = gos_FindFiles(file_name);

	while(fname!=NULL)
	{
		sprintf(long_file_name, "%s\\%s", dir, fname);
		if(gos_DoesFileExist((const char *)long_file_name))
		{
			FileStream fs;

			fs.Open(long_file_name);

			if(fs.IsFileOpened()==true)
			{
				SPEWALWAYS((0, "%s", long_file_name));
				int version = MidLevelRenderer::ReadMLRVersion(&fs);
				OBB obb;

				fs >> obb;

				MLRShape *shape;
				if(version<14)
				{
					shape = MidLevelRenderer::MLRShape::Make(&fs, version);
				}
				else
				{
					RegisteredClass::ClassID class_id;
					fs >> class_id;

					switch(class_id)
					{
						case MidLevelRenderer::MLRShapeClassID:
							shape = MidLevelRenderer::MLRShape::Make(&fs, version);
						break;
						case MidLevelRenderer::MLRCulturShapeClassID:
							shape = MidLevelRenderer::MLRCulturShape::Make(&fs, version);
						break;
					}
				}

				Check_Object(shape);
				shape->DetachReference();
			}
		}

		fname = gos_FindFilesNext();
	}
	gos_FindFilesClose();

	sprintf(file_name, "%s\\*.ebf", dir);

	fname = gos_FindFiles(file_name);

	while(fname!=NULL)
	{
		sprintf(long_file_name, "%s\\%s", dir, fname);
		if(gos_DoesFileExist((const char *)long_file_name))
		{
			FileStream fs;

			fs.Open(long_file_name);

			if(fs.IsFileOpened()==true)
			{
				SPEWALWAYS((0, "%s", long_file_name));

				gosFX::ReadGFXVersion(&fs);
	
				int mlr_version = MidLevelRenderer::ReadMLRVersion(&fs);
				unsigned debris_count;
				fs >> debris_count;
	
				unsigned i;
				Point3D pos, center;
				Scalar radius;
				for(i=0;i<debris_count;i++)
				{
					fs >> pos;
					fs >> center;
					fs >> radius;

					//
					//---------------
					// Load the shape
					//---------------
					//

					MLRShape *piece = NULL;
					if(mlr_version<14)
					{
						piece = MidLevelRenderer::MLRShape::Make(&fs, mlr_version);
					}
					else
					{
						RegisteredClass::ClassID class_id;
						fs >> class_id;

						switch(class_id)
						{
							case MidLevelRenderer::MLRShapeClassID:
								piece = MidLevelRenderer::MLRShape::Make(&fs, mlr_version);
							break;
							case MidLevelRenderer::MLRCulturShapeClassID:
								piece = MidLevelRenderer::MLRCulturShape::Make(&fs, mlr_version);
							break;
						}
					}

					Check_Object(piece);
					piece->DetachReference();
				}
			}
		}

		fname = gos_FindFilesNext();
	}
	gos_FindFilesClose();
}

extern WIN32_FIND_DATA		FindDirectoryData;
extern HANDLE				FindDirectoryHandle;

void
	CheckDirectory(const char *dir)
{
	char dir_name[1024];
	char long_dir_name[1024];

	fprintf(stdout, "%s\n", dir);
	sprintf(dir_name, "%s\\*.*", dir);

	const char *dname = gos_FindDirectories(dir_name);

	while(dname!=NULL)
	{
		sprintf(long_dir_name, "%s\\%s", dir, dname);
		
		WIN32_FIND_DATA		rememberFindDirectoryData = FindDirectoryData;
		HANDLE				rememberFindDirectoryHandle = FindDirectoryHandle;
		CheckDirectory(long_dir_name);

		FindDirectoryData = rememberFindDirectoryData;
		FindDirectoryHandle = rememberFindDirectoryHandle;

		dname = gos_FindDirectoriesNext();
	}
	gos_FindDirectoriesClose();

	CheckFiles(dir);
}

int
	__cdecl main(int argc, char *argv[])
{
	InitGameOS(NULL, NULL, "blabla");
	InitializeGameEngine();

	for(int i=1;i<argc;i++)
	{
		if(NULL!=strstr(argv[i], "-h") || NULL!=strstr(argv[i], "/h"))
		{
			fprintf(stdout, "%s - Polygon Mesh Hunter\n", argv[0]);
			fprintf(stdout, "No Help available\n");
			exit(0);
		}
	}

	gos_PushCurrentHeap(MidLevelRenderer::TexturePoolHeap);
	MidLevelRenderer::TGAFilePool *pool = new MidLevelRenderer::TGAFilePool("textures\\");
	Check_Object(pool);
	MidLevelRenderer::MLRTexturePool::Instance =
		new MidLevelRenderer::MLRTexturePool(pool);
	Check_Object(MidLevelRenderer::MLRTexturePool::Instance);
	gos_PopCurrentHeap();

#if 1
	CheckDirectory("content");
#else
	{
		MString fname("test.erf");

		if(gos_DoesFileExist((const char *)fname))
		{
			FileStream fs;

			fs.Open(fname);

			if(fs.IsFileOpened()==true)
			{
				gos_PushCurrentHeap(ElementRenderer::g_Heap);
				ElementRenderer::Element *element = ElementRenderer::Element::Create(&fs, ElementRenderer::ReadERFVersion(&fs));
				gos_PopCurrentHeap();

				Check_Object(element);
				delete element;
			}

		}

		fname = "test.mlr";

		if(gos_DoesFileExist((const char *)fname))
		{
			FileStream fs;

			fs.Open(fname);

			if(fs.IsFileOpened()==true)
			{
				int version = MidLevelRenderer::ReadMLRVersion(&fs);
				OBB obb;

				fs >> obb;

				MLRShape *shape;
				if(version<14)
				{
					shape = MidLevelRenderer::MLRShape::Make(&fs, version);
				}
				else
				{
					RegisteredClass::ClassID class_id;
					fs >> class_id;

					switch(class_id)
					{
						case MidLevelRenderer::MLRShapeClassID:
							shape = MidLevelRenderer::MLRShape::Make(&fs, version);
						break;
						case MidLevelRenderer::MLRCulturShapeClassID:
							shape = MidLevelRenderer::MLRCulturShape::Make(&fs, version);
						break;
					}
				}

				Check_Object(shape);
				shape->DetachReference();
			}
		}

		fname = "test.ebf";

		if(gos_DoesFileExist((const char *)fname))
		{
			FileStream fs;

			fs.Open(fname);

			if(fs.IsFileOpened()==true)
			{
//				fs.LoadData();

				gosFX::ReadGFXVersion(&fs);
	
				int mlr_version = MidLevelRenderer::ReadMLRVersion(&fs);
				unsigned debris_count;
				fs >> debris_count;
	
				unsigned i;
				Point3D pos, center;
				Scalar radius;
				for(i=0;i<debris_count;i++)
				{
					fs >> pos;
					fs >> center;
					fs >> radius;

					//
					//---------------
					// Load the shape
					//---------------
					//

					MLRShape *piece = NULL;
					if(mlr_version<14)
					{
						piece = MidLevelRenderer::MLRShape::Make(&fs, mlr_version);
					}
					else
					{
						RegisteredClass::ClassID class_id;
						fs >> class_id;

						switch(class_id)
						{
							case MidLevelRenderer::MLRShapeClassID:
								piece = MidLevelRenderer::MLRShape::Make(&fs, mlr_version);
							break;
							case MidLevelRenderer::MLRCulturShapeClassID:
								piece = MidLevelRenderer::MLRCulturShape::Make(&fs, mlr_version);
							break;
						}
					}

					Check_Object(piece);
					piece->DetachReference();
				}
			}
		}
	}
#endif

	TerminateGameEngine();
	ExitGameOS();
	return 0;
}

