/*
 * 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: ExManagerId.cpp,v 1.12 2002/11/24 11:58:57 data Exp $
 *
 */

#include "ExManagerId.h"

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

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

ExManagerId::ExManagerId()
{
Guard(ExManagerId::ExManagerId())
	m_ExIdCounter=0;
UnGuard
}

ExManagerId::~ExManagerId()
{
Guard(ExManagerId::~ExManagerId())
UnGuard
}

//////////////////////////////////////////////////////////////////////

void ExManagerId::Reset(void)
{
Guard(ExManagerId::Reset(void))
	m_MapObjectInfo->clear();
	delete m_MapObjectInfo;
	m_ExIdCounter=0;
	Init();
UnGuard
}

void ExManagerId::Init(void)
{
Guard(ExManagerId::Init(void))
	m_MapObjectInfo=new std::map<  ExNihilo::ExId   , ExNihilo::ExObjectInfo , std::less <ExNihilo::ExId  >  >;	
UnGuard
}

std::string ExManagerId::GetAviableName(std::string Name,std::string Type,int occu)
{
Guard(std::string ExManagerId::GetAviableName(std::string Name,std::string Type,int occu))
	if(GetObjectId(Name,Type)==-1)//new name
	{
		return Name;
	}
	
	//here code to change name
	if(occu>0)
	{
		Name.erase(Name.end()-1,Name.end());
	}
	if(occu>10)
	{
		Name.erase(Name.end()-1,Name.end());
	}
	if(occu>100)
	{
		Name.erase(Name.end()-1,Name.end());
	}
	if(occu>1000)
	{
		Name.erase(Name.end()-1,Name.end());
	}
	if(occu>10000)
	{
		Name.erase(Name.end()-1,Name.end());
	}
	char buffer[255];
	memset(buffer,0,255);
	sprintf(buffer,"%s%d",Name.data(),occu);

	return GetAviableName(buffer,Type,occu+1);
	
UnGuard
}

ExNihilo::ExId ExManagerId::RecordObject(ExCObject &object)
{
Guard(ExNihilo::ExId ExManagerId::RecordObject(ExCObject &object))
	try
	{	
		object.SetId(m_ExIdCounter);m_ExIdCounter++;
		std::string name(object.GetType());
		if(name.find(" *")<name.length())
		{
			name.erase(name.find(" *"),name.length()-name.find(" *"));
		}
		object.SetName(GetAviableName(object.GetName(),object.GetType(),0));
		object.SetType(name);
		object.SetFlux(Consol,FluxAction);
		

		ExNihilo::ExObjectInfo Info;
		Info.m_Id	= object.GetId();
		Info.m_Name	= object.GetName();
		Info.m_Type = object.GetType();
		
		std::pair<ExNihilo::ExId,ExNihilo::ExObjectInfo>  obj;
		obj.first=object.GetId();
		obj.second=Info;
		m_MapObjectInfo->insert(obj);

		

		*Consol<<"ExManagerId:: New Id :"<<Info.m_Id<<"  For name:"<<Info.m_Name<<" Type:"<<Info.m_Type<<std::endl;
		return Info.m_Id;
	}catch(...)
	{
		throw ExCExpRecordObject();
	}
UnGuard
}

ExNihilo::ExId ExManagerId::RecordObject(ExCObject *object)
{
Guard(ExNihilo::ExId ExManagerId::RecordObject(ExCObject *object))
	object->SetId(m_ExIdCounter);m_ExIdCounter++;
	std::string name(object->GetType());
	if(name.find(" *")<name.length())
	{
		name.erase(name.find(" *"),name.length()-name.find(" *"));
	}
	object->SetName(GetAviableName(object->GetName(),object->GetType(),0));
	object->SetType(name);

	ExNihilo::ExObjectInfo Info;
	Info.m_Id	= object->GetId();
	Info.m_Name	= object->GetName();
	Info.m_Type = object->GetType();
	
	std::pair<ExNihilo::ExId,ExNihilo::ExObjectInfo>  obj;
	obj.first=object->GetId();
	obj.second=Info;
	m_MapObjectInfo->insert(obj);

	*Consol<<"ExManagerId:: New Id :"<<Info.m_Id<<"  For name:"<<Info.m_Name<<" Type:"<<Info.m_Type<<std::endl;
	return Info.m_Id;
UnGuard
}

ExNihilo::ExId	ExManagerId::GetObjectId(std::string Name,std::string Type)
{
Guard(ExNihilo::ExId	ExManagerId::GetObjectId(std::string Name,std::string Type))
	for(m_ItMapObjectInfo=m_MapObjectInfo->begin();m_ItMapObjectInfo!=m_MapObjectInfo->end();m_ItMapObjectInfo++)
	{
		if(Name==m_ItMapObjectInfo->second.m_Name)//||Type==m_ItMapObjectInfo->second.m_Type)
			return	m_ItMapObjectInfo->second.m_Id;
	}
	return -1;
UnGuard
}

std::string		ExManagerId::GetObjectName(ExNihilo::ExId id)
{
Guard(std::string		ExManagerId::GetObjectName(ExNihilo::ExId id))
	try
	{
		return m_MapObjectInfo->find(id)->second.m_Name;	
	}
	catch(...)
	{
		return "NoName";
	}
UnGuard
}

std::string		ExManagerId::GetObjectType(ExNihilo::ExId id)
{
Guard(std::string		ExManagerId::GetObjectType(ExNihilo::ExId id))
	try
	{
		return m_MapObjectInfo->find(id)->second.m_Type;	
	}
	catch(...)
	{
		return "NoName";
	}
UnGuard
}

void ExManagerId::List(void)
{
Guard(void ExManagerId::List(void))
	for(m_ItMapObjectInfo=m_MapObjectInfo->begin();m_ItMapObjectInfo!=m_MapObjectInfo->end();m_ItMapObjectInfo++)
	{
		*Consol<<"Id :"<<m_ItMapObjectInfo->second.m_Id<<"  For name:"<<m_ItMapObjectInfo->second.m_Name<<" Type:"<<m_ItMapObjectInfo->second.m_Type<<std::endl;
	}	
UnGuard
}

ExCAction ExManagerId::InputAction(ExCAction Action)
{
Guard(ExCAction ExManagerId::InputAction(ExCAction Action))
	switch(Action.m_Action)
	{
	case ID_LIST:
		List();
		break;
	}
	if(Action.m_NextAction){return *Action.m_NextAction;}
	else{return NOTHING;}
UnGuard
}

std::string		ExManagerId::GetObjectManagerType(std::string ObjectType)
{
Guard(std::string		ExManagerId::GetObjectManagerType(std::string ObjectType))
	//std::cout<<"Type:"<<ObjectType<<std::endl;
	try
	{
		//Entity manager
		if(strcmpi(ObjectType.data(),"ExCEntity")==0)return "ExManagerEntity";
		//Camera manager
		if(strcmpi(ObjectType.data(),"ExCCamera")==0)return "ExManagerCamera";
		if(strcmpi(ObjectType.data(),"ExCCameraFree")==0)return "ExManagerCamera";
		if(strcmpi(ObjectType.data(),"ExCCameraChase")==0)return "ExManagerCamera";
		if(strcmpi(ObjectType.data(),"ExCCameraFirst")==0)return "ExManagerCamera";
		if(strcmpi(ObjectType.data(),"ExCCameraFlight")==0)return "ExManagerCamera";
		//Model Manager
		if(strcmpi(ObjectType.data(),"ExCModel")==0)return "ExManagerModel";
		if(strcmpi(ObjectType.data(),"ExCModelASC")==0)return "ExManagerModel";
		if(strcmpi(ObjectType.data(),"ExCModelASE")==0)return "ExManagerModel";
		if(strcmpi(ObjectType.data(),"ExCModelEXM")==0)return "ExManagerModel";
		if(strcmpi(ObjectType.data(),"ExCModelMD")==0)return "ExManagerModel";
		if(strcmpi(ObjectType.data(),"ExCModelMD2")==0)return "ExManagerModel";
		if(strcmpi(ObjectType.data(),"ExCModelMD3")==0)return "ExManagerModel";
		if(strcmpi(ObjectType.data(),"ExCModel3DS")==0)return "ExManagerModel";
		if(strcmpi(ObjectType.data(),"ExCModelOBJ")==0)return "ExManagerModel";
		//MEsh Manager
		if(strcmpi(ObjectType.data(),"ExCMesh")==0)return "ExManagerMesh";
		if(strcmpi(ObjectType.data(),"ExCMeshFireEffect")==0)return "ExManagerMesh";
		if(strcmpi(ObjectType.data(),"ExCMeshWaterEffect")==0)return "ExManagerMesh";
		if(strcmpi(ObjectType.data(),"ExCMeshSummonCylenderEffect")==0)return "ExManagerMesh";
		if(strcmpi(ObjectType.data(),"ExCMeshSmogEffect")==0)return "ExManagerMesh";
		if(strcmpi(ObjectType.data(),"ExCMeshWaterDisqueEffect")==0)return "ExManagerMesh";
		if(strcmpi(ObjectType.data(),"ExCMeshLOD3ds")==0)return "ExManagerMesh";
		if(strcmpi(ObjectType.data(),"ExCMeshSauronEffect")==0)return "ExManagerMesh";
		if(strcmpi(ObjectType.data(),"ExCMesh3ds")==0)return "ExManagerMesh";
	}
	catch(...)
	{
		return "Unknow manager";
	}
UnGuard
}


