/*
 * ExNihilo 3D Engine
 * 
 *  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 Library 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 *
 * Please read AUTHORS file !!!
 * 
 * $Id: ExManagerLoad.cpp,v 1.23 2002/11/24 11:58:58 data Exp $
 *
 */

#include "ExManagerLoad.h"

bool ExManagerLoad::m_flag = false; 
ExManagerLoad* ExManagerLoad::m_instance = NULL; 

ExManagerLoad* ExManagerLoad::CreateSingleton(void){
Guard(ExManagerLoad* ExManagerLoad::CreateSingleton(void))
	if(!m_flag)
	{
		m_flag = true; // We are creating the error log now, so set flag to true
		m_instance = new ExManagerLoad; // Create the error log
	}else
	{
		std::cout<<"Error singleton already created"<<std::endl;
	}
	return m_instance; 
UnGuard
}

ExManagerLoad::ExManagerLoad(void)
{
Guard(ExManagerLoad::ExManagerLoad(void))
UnGuard
}

ExManagerLoad::~ExManagerLoad(void)
{
Guard(ExManagerLoad::~ExManagerLoad(void))
UnGuard
}

void ExManagerLoad::Reset(void)
{
Guard(void ExManagerLoad::Reset(void))
	ExManagerObject<ExCLoadingAnimation>::Reset();
	Init();
UnGuard
}

void ExManagerLoad::Init(void)
{
Guard(ExManagerLoad::Init(void))
	ExManagerObject<ExCLoadingAnimation>::Init();
UnGuard
}

void ExManagerLoad::Load(std::string FileName)
{
Guard(ExManagerLoad::Load(std::string FileName))

UnGuard
}

FileType ExManagerLoad::GetFileType(std::string FileName)
{
Guard(FileType ExManagerLoad::GetFileType(std::string FileName))
	std::string Buffext=ExNihilo::GetFileExtension(FileName);

	if(strcmp(Buffext.data(),"csl")==0)
	{
		return FILE_CONSOL;		
	}
	if(strcmp(Buffext.data(),"comd")==0)
	{
		return FILE_COMMAND;
	}
	if(strcmp(Buffext.data(),"wav")==0
		||strcmp(Buffext.data(),"mp3")==0
		||strcmp(Buffext.data(),"mid")==0)
	{
		return FILE_SOUND;
	}
	if(strcmp(Buffext.data(),"asc")==0
		||strcmp(Buffext.data(),"ase")==0
		||strcmp(Buffext.data(),"3ds")==0
		||strcmp(Buffext.data(),"md2")==0
		||strcmp(Buffext.data(),"md3")==0
		||strcmp(Buffext.data(),"exm")==0
		||strcmp(Buffext.data(),"obj")==0)
	{
		return FILE_MODEL;
	}
	if(strcmp(Buffext.data(),"map")==0
		||strcmp(Buffext.data(),"bsp")==0
		||strcmp(Buffext.data(),"hgmp")==0
		||strcmp(Buffext.data(),"skyb")==0)
	{
		return FILE_MAP;
	}
	if(strcmp(Buffext.data(),"int")==0)
	{
		return	 FILE_INTERFACE;
	}
	if(strcmp(Buffext.data(),"set")==0)
	{
		return FILE_SET;
	}
	if(strcmp(Buffext.data(),"exec")==0)
	{
		return FILE_COMMAND;
	}
	if(strcmp(Buffext.data(),"part")==0)
	{
		return FILE_PARTICUL;
	}
	if(strcmp(Buffext.data(),"ExW")==0)
	{
		return FILE_WINDOW;
	}
	if(strcmp(Buffext.data(),"bmp")==0
		||strcmp(Buffext.data(),"tga")==0
		||strcmp(Buffext.data(),"pcx")==0
		||strcmp(Buffext.data(),"jpg")==0
		||strcmp(Buffext.data(),"rgb")==0
		||strcmp(Buffext.data(),"raw")==0
		||strcmp(Buffext.data(),"dds")==0
		||strcmp(Buffext.data(),"ppm")==0)
	{
		return FILE_TEXTURE;
	}
	*Consol<<"ExManagerLoad::ExCeption =>"<<FileName<<" Bad file extension"<<std::endl;	
	DisplayFileType();
	return FILE_UNKNOWN_TYPE;
UnGuard
}




ExCAction ExManagerLoad::InputCommand(ExCCommand Command)
{
Guard(ExCAction ExManagerLoad::InputCommand(ExCCommand Command))
		return NOTHING;
UnGuard
}

ExCAction ExManagerLoad::InputAction(ExCAction Action)
{
Guard(ExCAction ExManagerLoad::InputAction(ExCAction Action))
	switch(Action.m_Action)
	{
	case LOAD_PART_CONFIG_FILE:
		ManagerParticuleSystem->Load(Action.m_Param);
		break;
	case LOAD_SET_OF_FILE:
		LoadSetOfFile(Action.m_Param.data());
		break;
	case LOAD_FILE:
		try
		{
			switch(GetFileType(Action.m_Param)) 
			{
			case FILE_CONSOL:
				ManagerConsole->LoadStringActionFile(Action.m_Param.data());
				break;
			case FILE_SET:
				LoadSetOfFile(Action.m_Param.data());
				break;
			case FILE_SOUND:
				ManagerSound->LoadSound(Action.m_Param);
				break;
			case FILE_MODEL:
				ManagerModel->Load(Action.m_Param);
				break;
			case FILE_MAP:
				ManagerMap->Load(Action.m_Param);
				break;
			case FILE_PARTICUL:
				ManagerParticuleSystem->Load(Action.m_Param);
				break;
			case FILE_WINDOW:
				ManagerObjectWindow->Load(Action.m_Param);
				break;
			case FILE_INTERFACE:
				ManagerInterface->Load(Action.m_Param);
				break;
			case FILE_TEXTURE:
				ManagerTexture->Load(Action.m_Param);
				break;
			case FILE_COMMAND:
				break;
			}
		}
		catch(ExCExpFileNotFound)
		{
			*Consol<<"ExManagerLoad::ExCeption =>"<<Action.m_Param<<" File not found"<<std::endl;
			return false;
		}
		catch(ExCExpFileReadError)
		{
			*Consol<<"ExManagerLoad::ExCeption =>"<<Action.m_Param<<" Read file error"<<std::endl;
			return false;
		}
		catch(...)
		{
			*Consol<<"ExManagerLoad::ExCeption =>"<<Action.m_Param<<" Unknow exception"<<std::endl;
			return false;
		}
		break;
	default:
		*Consol<<"Can not file action in LOAD_ACTION_MAP"<<std::endl;
		break;
	}
	if(Action.m_NextAction){return *Action.m_NextAction;}
	else{return NOTHING;}
UnGuard
}

void ExManagerLoad::LoadSetOfFile(const char *FileName)
{
Guard(void ExManagerLoad::LoadSetOfFile(const char *FileName))
		char			ch;
	int				RetVal;
	int				FileSize;
	FILE			*MyFile;
	bool			endfile=false;
	//int				tmp=0; // not used
	std::string		StBuffer;
	std::string		StType;
	char			buffer[255];

#ifdef UNIX_SRC
	sprintf(buffer, PREFIX "/ExNihilo/Data/%s",FileName);
#else
	sprintf(buffer, "../Data/%s",FileName);
#endif

	MyFile=fopen (buffer,"r");
	if(!MyFile)
	{
		*Consol<<"File not found:"<<buffer<<std::endl;
	}else
	{
		*Consol<<"Loading set File :"<<FileName<<std::endl;

		fseek(MyFile,0,SEEK_END);
		FileSize=ftell(MyFile);
		//Start of file
		fseek(MyFile,0,SEEK_SET);
		do
		{
			RetVal=fread(&ch,sizeof(char),1,MyFile);
		}while(ch!='#');
		//reading file type;
		do
		{
			RetVal=fread(&ch,sizeof(char),1,MyFile);
			StBuffer=StBuffer+ch;	
		}while(ch!='#');
		if(strcmp(StBuffer.data(),"set#")==0)
		{

			do
			{

				StBuffer.erase(StBuffer.begin(),StBuffer.end());
				do
				{
					RetVal=fread(&ch,sizeof(char),1,MyFile);
					StBuffer=StBuffer+ch;
				}while(ch!='#');
				StBuffer.erase(StBuffer.end()-1,StBuffer.end());
				StBuffer.erase(StBuffer.begin(),StBuffer.begin()+1);
				if(StBuffer.find("end of set file") != (unsigned)-1)
				{
					endfile=true;
				}else
				{
					StType=StBuffer;
					StBuffer.erase(StBuffer.begin(),StBuffer.end());
					do
					{
						RetVal=fread(&ch,sizeof(char),1,MyFile);
						StBuffer=StBuffer+ch;
					}while(ch!='#');
					StBuffer.erase(StBuffer.end()-1,StBuffer.end());

					if(strcmp(StType.data(),"command")==0)
					{
						std::cout<<"Load command file :"<<StBuffer.data()<<std::endl;
//						LoadCommandFile(StBuffer.data());
					}
					if(strcmp(StType.data(),"console")==0)
					{
						std::cout<<"Load console file :"<<StBuffer.data()<<std::endl;
						ManagerConsole->LoadStringActionFile(StBuffer.data());	
					}
					if(strcmp(StType.data(),"interface")==0)
					{
						std::cout<<"Load interface file :"<<StBuffer.data()<<std::endl;
						ManagerInterface->Load(StBuffer.data());	
					}
					if(strcmp(StType.data(),"modele")==0)
					{
						std::cout<<"Load asc file :"<<StBuffer.data()<<std::endl;
						ManagerModel->Load(StBuffer);	
					}
					if(strcmp(StType.data(),"sound")==0)
					{
						std::cout<<"Load sound file :"<<StBuffer.data()<<std::endl;
						ManagerSound->LoadSound(StBuffer.data());	
					}
					if(strcmp(StType.data(),"set")==0)
					{
						std::cout<<"Load set file :"<<StBuffer.data()<<std::endl;
						LoadSetOfFile(StBuffer.data());	
					}
					if(strcmp(StType.data(),"exec")==0)
					{
						std::cout<<"Load set file :"<<StBuffer.data()<<std::endl;

						ExCAction action;
						action.SetParam(StBuffer.data());
						//LoadExecFile(&action);	
					}
					if(strcmp(StType.data(),"map")==0
						||strcmp(StType.data(),"bsp")==0
						||strcmp(StType.data(),"hgmp")==0
						||strcmp(StType.data(),"skyb")==0)
					{
						std::cout<<"Load map file :"<<StBuffer.data()<<std::endl;
						ManagerMap->Load(StBuffer);	
					}
					if(strcmp(StType.data(),"ExW")==0)
					{
						std::cout<<"Load Window file :"<<StBuffer.data()<<std::endl;
						ManagerObjectWindow->Load(StBuffer.data());	
					}

				}
			}while(!endfile);
			fclose(MyFile);
		}else
		{
			*Consol<<FileName<<" is not a valide console file"<<std::endl;
		}
	}
UnGuard
}

void ExManagerLoad::DisplayFileType(void)
{
Guard(void ExManagerLoad::DisplayFileType(void))
	*Consol<<"*------------------------------------------------------------------------------------------------*"<<std::endl;
	*Consol<<"|                                Extension file supported by Exnihilo                            |"<<std::endl;
	*Consol<<"|------------------------------------------------------------------------------------------------|"<<std::endl;
	*Consol<<"|Description                 | Extension |  Status  |  Comment                                   |"<<std::endl;
	*Consol<<"|------------------------------------------------------------------------------------------------|"<<std::endl;				
	*Consol<<"|Console configuration file  |  .csl     | Aviable  | Asign consol command to action             |"<<std::endl;
	*Consol<<"|Command configuration file  |  .comd    | Aviable  | Asign input (keyboard,mouse,...)to action  |"<<std::endl;
	*Consol<<"|Window files                |  .ExW     | Aviable  | Load a window from a ressource file        |"<<std::endl;
	*Consol<<"|------------------------------------------------------|-----------------------------------------|"<<std::endl;				
	*Consol<<"|ExNihilo map file           |  .map     | Aviable  | Create map file with AscToMap converter    |"<<std::endl;
	*Consol<<"|Quake map file              |  .bsp     |          |                                            |"<<std::endl;
	*Consol<<"|------------------------------------------------------------------------------------------------|"<<std::endl;				
	*Consol<<"|ASC model  file             |  .asc     | Aviable  | Create a 3d model and export him to *.asc  |"<<std::endl;
	*Consol<<"|MD2 (quake 2) model  file   |  .md2     | Aviable  |                                            |"<<std::endl;
	*Consol<<"|MD3 (quake 3) model  file   |  .md3     |          |                                            |"<<std::endl;
	*Consol<<"|ASE model  file             |  .ase     |          |                                            |"<<std::endl;
	*Consol<<"|3d studio max model  file   |  .3ds     | Aviable  |                                            |"<<std::endl;
	*Consol<<"|OBJ model  file             |  .obj     |          |                                            |"<<std::endl;
	*Consol<<"|------------------------------------------------------------------------------------------------|"<<std::endl;				
	*Consol<<"|Wave sound file             |  .wav     |          |                                            |"<<std::endl;
	*Consol<<"|Midi sound file             |  .mid     |          |                                            |"<<std::endl;
	*Consol<<"|Mp3 sound file              |  .mp3     |          |                                            |"<<std::endl;
	*Consol<<"|------------------------------------------------------------------------------------------------|"<<std::endl;
	*Consol<<"|Particule system  file      |  .part    | Aviable  |  Use SDK partiucle to create *.part file   |"<<std::endl;
	*Consol<<"|Interface file              |  .int     | Aviable  |  Use SDK partiucle to create *.int file    |"<<std::endl;
	*Consol<<"|------------------------------------------------------------------------------------------------|"<<std::endl;				
	*Consol<<"|Groupe of file              |  .set     | Aviable  |                                            |"<<std::endl;
	*Consol<<"|Groupe of action            |  .exec    | Aviable  |                                            |"<<std::endl;
	*Consol<<"*------------------------------------------------------------------------------------------------*"<<std::endl;
UnGuard
}