/*
 * 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 !!!
 * 
 *
 */
#include "ExManagerModele.h"

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

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

ExManagerModel::ExManagerModel(void)
{
	SetAskForCommand(true);
	SetAskForExclusifCommand(false);
}

ExManagerModel::~ExManagerModel(void)
{
}

void ExManagerModel::Reset(void)
{
	ExManagerObject<ExCModel *>::Reset();
	Init();
}

void ExManagerModel::Init(void)
{
Guard(void ExManagerModel::Init(void))
	ExManagerObject<ExCModel *>::Init();
//	Load("Mur.3ds","MUR");
	
	/*Load("ogre.md2","OGRE");
	SetCurrentObject("OGRE");*/
//	GetCurrentObject()->SetPosition(40.0f,0.0f,0.0f);
/*	
	Load("ogre.md2","OGRE1");
	SetCurrentObject("OGRE1");
	GetCurrentObject()->SetPosition(-40.0f,0.0f,0.0f);
	
	Load("ogre.md2","OGRE2");
	SetCurrentObject("OGRE2");
	GetCurrentObject()->SetPosition(0.0f,0.0f,40.0f);
	
	Load("ogre.md2","OGRE3");
	SetCurrentObject("OGRE3");
	GetCurrentObject()->SetPosition(0.0f,0.0f,-40.0f);

	Load("sara.md2","SARA");
	SetCurrentObject("SARA");
	GetCurrentObject()->SetPosition(20.0f,0.0f,20.0f);
*/
	//Load("pknight.md2","KNIGHT");
	//SetCurrentObject("KNIGHT");

/*	Load("Fleche.3ds","FLECHES");
	SetCurrentObject("FLECHES");
*/
/*	Load("orc.3ds","GENERAL");
	SetCurrentObject("GENERAL");
	//GetCurrentObject()->SetPosition(100,50,0);
	GetCurrentObject()->m_AlwaysDraw=true;
	GetCurrentObject()->SetPosition(1995,95,4154);*/
UnGuard
}

void ExManagerModel::Draw(void)
{
Guard(void ExManagerModel::Draw(void))
	try
	{
		for(m_ItMap=m_Map->begin();m_ItMap!=m_Map->end();m_ItMap++)
		{
			m_ItMap->second->Draw();
		}  
	}catch(...){}
UnGuard
}

void ExManagerModel::List(void)
{
Guard(void ExManagerModel::List(void))
	*Consol<<"---------------List of Model--------------"<<std::endl;
	for(m_ItMap=m_Map->begin();m_ItMap!=m_Map->end();m_ItMap++)
	{
		*Consol<<" Id:"<<m_ItMap->second->GetId()<<" Name :"<<m_ItMap->second->GetName()<<" Type :"<<m_ItMap->second->GetType()<<std::endl;

	}
	*Consol<<"-----------------------------------------------------------------"<<std::endl;
	*Consol<<" Number Total of Object : "<<m_Map->size()<<std::endl;
	*Consol<<" Current Object Id : "<<m_CurrentObjectId<<std::endl;
	*Consol<<"-----------------------------------------------------------------"<<std::endl;

UnGuard
}

ModelType ExManagerModel::FindModelType(std::string FileName)
{
Guard(ModelType ExManagerModel::FindModelType(std::string FileName))
	if(FileName.find(".md2")==(FileName.length()-4))return MODEL_MD2;
	if(FileName.find(".md3")==(FileName.length()-4))return MODEL_MD3;
	if(FileName.find(".asc")==(FileName.length()-4))return MODEL_ASC;
	//if(FileName.find(".ase")==(FileName.length()-4))return MODEL_ASE;
	if(FileName.find(".3ds")==(FileName.length()-4))return MODEL_3DS;
	if(FileName.find(".obj")==(FileName.length()-4))return MODEL_OBJ;
	if(FileName.find(".exm")==(FileName.length()-4))return MODEL_EXM;
	return MODEL_UNKNOW;
UnGuard
}

ExNihilo::ExId ExManagerModel::Load(std::string FileName)
{
Guard(ExNihilo::ExId ExManagerModel::Load(std::string FileName))
	return Load(FileName,FileName);
UnGuard
}

ExNihilo::ExId ExManagerModel::Load(std::string FileName,std::string ObjectName)
{
Guard(ExNihilo::ExId ExManagerModel::Load(std::string FileName,std::string ObjectName))
	//Check if model already loaded
	try
	{
		for(m_ItMap=m_Map->begin();m_ItMap!=m_Map->end();m_ItMap++)
		{
			if(strcmp(m_ItMap->second->GetName().data(),ObjectName.data())==0)
			{
				return m_ItMap->second->GetId();
			}
		}  
	}catch(...){}

	FileName="../Data/Modeles/"+FileName;
	try
	{
		ExCModel *ModelToLoad;
		switch(FindModelType(FileName)) 
		{
			case MODEL_MD2:ModelToLoad = new ExCModelMD2;break;
			case MODEL_MD3:ModelToLoad = new ExCModelMD3;break;
			case MODEL_ASC:ModelToLoad = new ExCModelASC;break;
		//	case MODEL_ASE:ModelToLoad = new ExCModelMD2;break;
			case MODEL_3DS:ModelToLoad = new ExCModel3DS;break;
			case MODEL_OBJ:ModelToLoad = new ExCModelOBJ;break;
			case MODEL_EXM:ModelToLoad = new ExCModelEXM;break;
		}
		ModelToLoad->SetManagerTexture(ManagerTexture);
		ModelToLoad->SetFileName(FileName);
		ModelToLoad->Load(FileName);
		ModelToLoad->SetName(ObjectName);
		ExManagerObject<ExCModel *>::Add(ModelToLoad);
		return ModelToLoad->GetId();
	}
	catch(ExCExpFileNotFound)
	{
		*Consol<<"ExManagerModel::ExCeption =>"<<FileName<<" File not found"<<std::endl;
	}
	catch(ExCExpFileReadError)
	{
		*Consol<<"ExManagerModel::ExCeption =>"<<FileName<<" Read file error"<<std::endl;
	}
	catch(...)
	{
		*Consol<<"ExManagerModel::ExCeption =>"<<FileName<<" Unknow exception"<<std::endl;
	}
	return -1;
UnGuard
}

ExCAction ExManagerModel::InputCommand(ExCCommand Command)
{
Guard(ExCAction ExManagerModel::InputCommand(ExCCommand Command))
	switch(Command.m_Command)
	{
	case KEYBOARD_UP_ARROW_DOWN:
		return NOTHING;
	case KEYBOARD_UP_ARROW_UP:
		return NOTHING;
	case KEYBOARD_UP_ARROW_LEFT:
		return NOTHING;
	case KEYBOARD_UP_ARROW_RIGHT:
		return NOTHING;
	case KEYBOARD_DOWN_ARROW_DOWN:
		return NOTHING;
	case KEYBOARD_DOWN_ARROW_UP:
		return NOTHING;
	case KEYBOARD_DOWN_ARROW_LEFT:
		return NOTHING;
	case KEYBOARD_DOWN_ARROW_RIGHT:
		return NOTHING;
	default :return NOTHING;
	}
UnGuard
}

ExCAction ExManagerModel::InputAction(ExCAction Action)
{
Guard(ExCAction ExManagerModel::InputAction(ExCAction Action))
//std::cout<<"MANAGER MODEL"<<Action;
	try
	{
		switch(Action.m_Action)
		{
		case LIST:
			List();
			break;
		case SET_CURRENT_OBJECT_BY_ID:
			SetCurrentObject(atoi(Action.m_Param.data()));
			break;
		case SET_CURRENT_OBJECT_BY_NAME:
			SetCurrentObject(Action.m_Param);
			break;
		case MODEL_LOAD_WITH_NAME:
			Load(Action.m_Param,Action.m_Param1);
			break;
		case MODEL_LOAD:
			Load(Action.m_Param);
			break;
		case MANAGER_MODEL_RELOAD:
			Reload();
			break;
		default:
			//*Consol<<"Can not file action in MODEL_ACTION_MAP"<<std::endl;
			return GetObject(m_CurrentObjectId)->InputAction(Action);
		}	

		if(Action.m_NextAction){return *Action.m_NextAction;}
		else{return NOTHING;}
	}
	catch(...)
	{
		*Consol<<"ExManagerModel::ExCeption =>> Error input action"<<std::endl;	
		return NOTHING;
	}
UnGuard
}

ExCModel * ExManagerModel::GetObject(ExNihilo::ExId id)
{
Guard(ExCModel *ExManagerModel::GetObject(ExNihilo::ExId id))
	for(m_ItMap=m_Map->begin();m_ItMap!=m_Map->end();m_ItMap++)
	{
		if(m_ItMap->second->GetId()==id)return m_ItMap->second;
	}
	return NULL;
UnGuard
}

ExCModel* ExManagerModel::GetCurrentObject(void)
{
Guard(ExCModel* ExManagerModel::GetCurrentObject(void))
	return GetObject(m_CurrentObjectId);
UnGuard
}

void ExManagerModel::Reload(void)
{
Guard(void ExManagerModel::Reload(void))
	for(m_ItMap=m_Map->begin();m_ItMap!=m_Map->end();m_ItMap++)
	{
		m_ItMap->second->Load(m_ItMap->second->GetFileName());
	}
UnGuard
}



