#include "StdAfx.h"

#include "AnimationInfoLoader.h"
#include "ICryXML.h"
#include "IXMLSerializer.h"


CAnimationInfoLoader::CAnimationInfoLoader(ICryXML * pXML) : m_pXML(pXML)
{
}

CAnimationInfoLoader::~CAnimationInfoLoader(void)
{
}


int GetIntFromStringBOOL(const std::string& val)
{
	if (!val.c_str())
		return -1;

	int ret = 0;
	if ((stricmp(val.c_str(), "1") == 0) || (stricmp(val.c_str(), "yes") == 0))
		ret = 1;

	return ret;

}

EMoveDirection GetMoveDirectionFromString(const std::string& val)
{
	EMoveDirection res(EMD_Ignore);

	if (stricmp(val.c_str(), "forward") == 0)
	{
		res =  eMD_Forward;
	}
	else
		if (stricmp(val.c_str(), "back") == 0)
		{

			res = eMD_Back;
		}
		else
			if (stricmp(val.c_str(), "left") == 0)
			{

				res = eMD_Left;
			}
			else
				if (stricmp(val.c_str(), "right") == 0)
				{

					res = eMD_Right;
				}


				return res;
}

void SkipSpaces(std::string& str)
{
	std::size_t i =str.find(' ') ;
	while ( i!= str.npos)
	{
		str.erase(i);
		i =str.find(' ') ;
	}
}

float GetDirectionFromString(const std::string& val)
{
	//EDirection res(ED_Ignore);
	if (stricmp(val.c_str(), "identity") == 0)
	{
		return 0.0f;
	}
	//else
	//	if (stricmp(val.c_str(), "l90") == 0)
	//	{
	//		res =  ED_L90;
	//	}
	//	else
	//		if (stricmp(val.c_str(), "r90") == 0)
	//		{
	//			res =  ED_R90;
	//		}
	//		else
	//			if (stricmp(val.c_str(), "l180") == 0)
	//			{
	//				res =  ED_180;
	//			}
	//			else
	//				if (stricmp(val.c_str(), "r180") == 0)
	//				{
	//					res =  ED_180;
	//				}
	//				else
	//					if (stricmp(val.c_str(), "180") == 0)
	//					{
	//						res =  ED_180;
	//					}
	//					return res;
	
	std::string str(val);

	SkipSpaces(str);

	float sign = 1.0f;  

	if (str[0] == 'r' || str[0] == 'R')
	{
		str.erase(0,1);
		sign = -1.0f;
	}
	else
		if (str[0] == 'l' || str[0] == 'L')
		{
			str.erase(0,1);
			sign = 1.0f;
		}


	float q = atof(str.c_str());
	if (q == 180.0f)
		q -= 0.0001f;

	float degree = sign * atof(str.c_str());

	return DEG2RAD(degree);
		//
}

bool GetBodyDirection(const std::string& val, std::vector<SDirection>& vec)
{
	//
	std::string src(val);
	std::size_t oldpath = src.find('[');
	if (oldpath == string::npos)
	{
		float oldangle = GetDirectionFromString(val);
		vec.push_back(SDirection(0.0f, IDENTITY));
		vec.push_back(SDirection(1.0f, IDENTITY - oldangle));
		return true;
	}

	// new path
	std::size_t last = src.find(']');

	while(last != string::npos)
	{
		std::string str;
		str.append(src, oldpath + 1, last - oldpath -1);

		std::size_t delim = str.find(';');
		std::string angle, time;

		angle.append(str, 0, delim);
		time.append(str, delim + 1, str.length() - delim - 1);

		vec.push_back(SDirection(atof(time.c_str()), IDENTITY - GetDirectionFromString(angle)));

		src.erase(0, last + 1);
		oldpath = src.find('[');
		last = src.find(']');
	}

	return true;
}

int GetNodeIDFromName(const char * name, const XmlNodeRef& node)
{
	uint32 numChildren= node->getChildCount();

	for (uint32 chield = 0; chield < numChildren; ++ chield )
	{
		if (stricmp(name, node->getChild(chield)->getTag()) == 0)
		{
			return chield;
		}
	}

	return -1;
}




bool CAnimationInfoLoader::LoadDescription(const std::string& name, IAnimationLoaderListener * pListener)//, IAnimationLoaderListener * pListener)
{
	// fill structures
	char error[4096];

	XmlNodeRef root =  m_pXML->GetXMLSerializer()->Read(name.c_str(), sizeof(error), error);
	if (!root)
	{
		ReportError(pListener, "Cannot read file \"%s\": %s\n", name.c_str(), error);
	}


	// temporary storage for the presets
	struct  PresetFinder
	{
		static bool FillPreset(std::vector<CompressionPreset>& presets, const char * name, CompressionPreset& newpreset)
		{
			uint32 end = presets.size();
			for (uint32 i = 0; i < end; ++i)
			{
				if (stricmp(presets[i].m_Name.c_str(), name) == 0)
				{
					newpreset = presets[i];
					return true;
				}
			}

			return false;
		}
	};

	std::vector<CompressionPreset> presets;

	uint32 numDefinitions = root->getChildCount();

	for (uint32 nDefinitionNode=0; nDefinitionNode<numDefinitions; ++nDefinitionNode)
	{
		XmlNodeRef pRoot = root->getChild(nDefinitionNode);
		if(!pRoot)
		{
			ReportError(pListener, "Node not found");
			continue;
		}

		if (stricmp(pRoot->getTag(), "preset") == 0)
		{

			// this is preset for compression
			CompressionPreset preset;
			uint32 numBonesInfo = pRoot->getChildCount();
			std::string presetName = pRoot->getAttr("Name");
			preset.m_Name = presetName;


			for (uint32 nBone = 0; nBone < numBonesInfo; ++nBone )
			{
				CompressionPreset::BonePreset bone;

				XmlNodeRef pBone = pRoot->getChild(nBone);
				//<Bone id="12345" error="0.00001" rotformat="auto" posformat="auto"/>
				uint32 boneId;

				pBone->getAttr("id", boneId);
				pBone->getAttr("poserror", bone.m_fPosError);
				pBone->getAttr("roterror", bone.m_fRotError);
				pBone->getAttr("rotformat", bone.m_RotCompressionFormat);
				pBone->getAttr("posformat", bone.m_PosCompressionFormat);

				preset.m_BoneInfoMap[boneId] = bone;
			}

			presets.push_back(preset);
		}
	}


	for (uint32 nDefinitionNode=0; nDefinitionNode<numDefinitions; ++nDefinitionNode)
	{
		XmlNodeRef pRoot = root->getChild(nDefinitionNode);
		if(!pRoot)
		{
			ReportError(pListener, "Node not found");
			continue;
		}

		if (stricmp(pRoot->getTag(), "preset") == 0)
		{
			continue;
		}

		SAnimationDefinition def;

		uint32 numAttribs = pRoot->getChildCount();

		{
			uint32 model = GetNodeIDFromName("model", pRoot);
			if (model == -1)
			{
				ReportInfo(pListener, "Model name not found in \"%s\" node", pRoot->getTag());
			}
			else
			{
				def.m_Model = pRoot->getChild(model)->getAttr("File");
				if (def.m_Model.empty())
				{
					ReportError(pListener, "Model name not found in \"%s\" node", pRoot->getTag());
				}
			}

		}


		{
			uint32 path = GetNodeIDFromName("animation", pRoot);
			if (path == -1)
			{
				ReportInfo(pListener, "Path not found in \"%s\" node \"%s\"", pRoot->getTag(), def.m_Model.c_str());
			}
			else
			{
				const char * pChar = pRoot->getChild(path)->getAttr("Path");
				if (!pChar)
				{
					ReportError(pListener, "Path not found in \"%s\" node \"%s\"", pRoot->getTag(), def.m_Model.c_str());
				}

				def.SetAnimationPath(std::string(pChar));
			}
		}

		{
			uint32 path = GetNodeIDFromName("database", pRoot);
			if (path == -1)
			{
				ReportInfo(pListener, "Database not found in \"%s\" node \"%s\"", pRoot->getTag(), def.m_Model.c_str());
			}
			else
			{
				const char * pChar = pRoot->getChild(path)->getAttr("Path");
				if (!pChar)
				{
					ReportError(pListener, "Path not found in \"%s\" node \"%s\"", pRoot->getTag(), def.m_Model.c_str());
				}

				def.m_DBName = std::string(pChar);
			}
		}



		{
			uint32 compression = GetNodeIDFromName("compression", pRoot);
			if (compression == -1)
			{
				ReportInfo(pListener, "Compression value not found in \"%s\" node \"%s\"", pRoot->getTag(), def.m_Model.c_str());
			}
			else
			{

				if (!pRoot->getChild(compression)->getAttr("value", def.m_MainDesc.m_CompressionQuality))
				{
					ReportInfo(pListener, "Compression value not found in \"%s\" node \"%s\"", pRoot->getTag(), def.m_Model.c_str());
				};
			}
		}

		{
			uint32 rootquality = GetNodeIDFromName("rootquality", pRoot);
			if (rootquality == -1)
			{
				ReportInfo(pListener, "RootQuality value not found in \"%s\" node \"%s\"", pRoot->getTag(), def.m_Model.c_str());
			}
			else
			{

				if (!pRoot->getChild(rootquality)->getAttr("value", def.m_MainDesc.m_fRootQuality))
				{
					ReportInfo(pListener, "RootQuality value not found in \"%s\" node \"%s\"", pRoot->getTag(), def.m_Model.c_str());
				};
			}
		}


		{
			uint32 floordist = GetNodeIDFromName("FloorDist", pRoot);
			if (floordist == -1)
			{
				//ReportInfo(pListener, "FloorDist value not found in \"%s\" node \"%s\"", pRoot->getTag(), def.m_Model.c_str());
			}
			else
			{

				if (!pRoot->getChild(floordist)->getAttr("value", def.m_MainDesc.m_fFloorDist))
				{
					ReportInfo(pListener, "FloorDist value not found in \"%s\" node \"%s\"", pRoot->getTag(), def.m_Model.c_str());
				};
			}
		}

		{
			uint32 SpeedXY = GetNodeIDFromName("SpeedXY", pRoot);
			if (SpeedXY == -1)
			{
				//ReportInfo(pListener, "RootQuality value not found in \"%s\" node \"%s\"", pRoot->getTag(), def.m_Model.c_str());
			}
			else
			{

				if (!pRoot->getChild(SpeedXY)->getAttr("value", def.m_MainDesc.m_fSpeedXY))
				{
					ReportInfo(pListener, "SpeedXY value not found in \"%s\" node \"%s\"", pRoot->getTag(), def.m_Model.c_str());
				};
			}
		}




	
		{
			uint32 compression = GetNodeIDFromName("autocompression", pRoot);
			if (compression == -1)
			{
				ReportInfo(pListener, "Compression value not found in \"%s\" node \"%s\"", pRoot->getTag(), def.m_Model.c_str());
			}
			else
			{

				if (!pRoot->getChild(compression)->getAttr("value", def.m_MainDesc.m_FixedToFoots))
				{
					ReportInfo(pListener, "Compression value not found in \"%s\" node \"%s\"", pRoot->getTag(), def.m_Model.c_str());
				};
			}
		}

		{
			uint32 preset = GetNodeIDFromName("preset", pRoot);
			if (preset == -1)
			{
				//ReportInfo(pListener, "Preset not found in \"%s\" node \"%s\"", pRoot->getTag(), def.m_Model.c_str());
			}
			else
			{
				const char * pChar = pRoot->getChild(preset)->getAttr("name");
				if (!pChar)
				{
					ReportInfo(pListener, "Preset not found in \"%s\" node \"%s\"", pRoot->getTag(), def.m_Model.c_str());
				}

				//def.SetAnimationPath(std::string(pChar));

				PresetFinder::FillPreset(presets, pChar, def.m_MainDesc.m_Preset);
			}
		}

		//int m_RootToHeels;

		{
			uint32 rootToHeels = GetNodeIDFromName("RootToHeels", pRoot);
			if (rootToHeels == -1)
			{
				//ReportInfo(pListener, "SkipSaveToDatabase value not found in \"%s\" node \"%s\"", pRoot->getTag(), def.m_Model.c_str());
			}
			else
			{
				std::string val = pRoot->getChild(rootToHeels)->getAttr("value");
				if (val.empty())
				{
					ReportInfo(pListener, "RootToHeels value not found in \"%s\" node \"%s\"", pRoot->getTag(), def.m_Model.c_str());
				}

				def.m_MainDesc.m_RootToHeels = GetIntFromStringBOOL(val);
			}
		}

		{
			uint32 skipSaveToDB = GetNodeIDFromName("SkipSaveToDatabase", pRoot);
			if (skipSaveToDB == -1)
			{
				//ReportInfo(pListener, "SkipSaveToDatabase value not found in \"%s\" node \"%s\"", pRoot->getTag(), def.m_Model.c_str());
			}
			else
			{
				std::string val = pRoot->getChild(skipSaveToDB)->getAttr("value");
				if (val.empty())
				{
					ReportInfo(pListener, "SkipSaveToDatabase value not found in \"%s\" node \"%s\"", pRoot->getTag(), def.m_Model.c_str());
				}

				def.m_MainDesc.m_SkipSaveToDatabase = GetIntFromStringBOOL(val);
			}
		}

		{
			uint32 footplant = GetNodeIDFromName("footplants", pRoot);
			if (footplant == -1)
			{
				ReportInfo(pListener, "Footplants value not found in \"%s\" node \"%s\"", pRoot->getTag(), def.m_Model.c_str());
			}
			else
			{
				std::string val = pRoot->getChild(footplant)->getAttr("value");
				if (val.empty())
				{
					ReportInfo(pListener, "Footplants value not found in \"%s\" node \"%s\"", pRoot->getTag(), def.m_Model.c_str());
				}

				def.m_MainDesc.m_FootPlant = GetIntFromStringBOOL(val);
			}
		}

		{
			uint32 deletepos = GetNodeIDFromName("DeletePosController", pRoot);
			if (deletepos != -1)
			{
				std::string val = pRoot->getChild(deletepos)->getAttr("value");
				if (val.empty())
				{
					ReportInfo(pListener, "DeletePosController value not found in \"%s\" node \"%s\"", pRoot->getTag(), def.m_Model.c_str());
				}

				def.m_MainDesc.m_DeletePosController = GetIntFromStringBOOL(val);
			}
		}

		{
			uint32 deleterot = GetNodeIDFromName("DeleteRotController", pRoot);
			if (deleterot != -1)
			{
				std::string val = pRoot->getChild(deleterot)->getAttr("value");
				if (val.empty())
				{
					ReportInfo(pListener, "DeletePosController value not found in \"%s\" node \"%s\"", pRoot->getTag(), def.m_Model.c_str());
				}

				def.m_MainDesc.m_DeleteRotController = GetIntFromStringBOOL(val);
			}
		}

		{
			uint32 human = GetNodeIDFromName("human", pRoot);
			if (human == -1)
			{
				ReportInfo(pListener, "Human value not found in \"%s\" node \"%s\"", pRoot->getTag(), def.m_Model.c_str());
			}
			else
			{
				std::string val = pRoot->getChild(human)->getAttr("value");
				if (val.empty())
				{
					ReportInfo(pListener, "Human value not found in \"%s\" node \"%s\"", pRoot->getTag(), def.m_Model.c_str());
				}
				def.m_MainDesc.m_Human = GetIntFromStringBOOL(val);
			}
		}

		{
			uint32 skip = GetNodeIDFromName("SkipSaveToDatabase", pRoot);
			if (skip == -1)
			{
				//ReportInfo(pListener, "SkipSaveToDatabase value not found in \"%s\" node \"%s\"", pRoot->getTag(), def.m_Model.c_str());
			}
			else
			{
				std::string val = pRoot->getChild(skip)->getAttr("value");
				if (val.empty())
				{
					ReportInfo(pListener, "SkipSaveToDatabase value not found in \"%s\" node \"%s\"", pRoot->getTag(), def.m_Model.c_str());
				}
				def.m_MainDesc.m_SkipSaveToDatabase = GetIntFromStringBOOL(val);
			}
		}

		{
			uint32 reverse = GetNodeIDFromName("ReverseDirection", pRoot);
			if (reverse == -1)
			{
				//ReportInfo(pListener, "ReverseDirection value not found in \"%s\" node \"%s\"", pRoot->getTag(), def.m_Model.c_str());
			}
			else
			{
				std::string val = pRoot->getChild(reverse)->getAttr("value");
				if (val.empty())
				{
					ReportInfo(pListener, "ReverseDirection value not found in \"%s\" node \"%s\"", pRoot->getTag(), def.m_Model.c_str());
				}
				def.m_MainDesc.m_ReverseDirection = GetIntFromStringBOOL(val);
			}
		}

		{
			uint32 weapon = GetNodeIDFromName("weapon", pRoot);
			if (weapon == -1)
			{
				ReportInfo(pListener, "Human value not found in \"%s\" node \"%s\"", pRoot->getTag(), def.m_Model.c_str());
			}
			else
			{
				std::string val = pRoot->getChild(weapon)->getAttr("value");
				if (val.empty())
				{
					ReportInfo(pListener, "Weapon value not found in \"%s\" node \"%s\"", pRoot->getTag(), def.m_Model.c_str());
				}
				def.m_MainDesc.m_Weapon = GetIntFromStringBOOL(val);
			}
		}

		{
			uint32 move = GetNodeIDFromName("movedirection", pRoot);
			if (move != -1)
			{

				std::string val = pRoot->getChild(move)->getAttr("value");
				if (val.empty())
				{
					ReportInfo(pListener, "MoveDirection value not found in \"%s\" node \"%s\"", pRoot->getTag(), def.m_Model.c_str());
				}
				else
					def.m_MainDesc.m_MoveDirection = GetMoveDirectionFromString(val);
			}
		}


		{
			uint32 dir = GetNodeIDFromName("bodydirection", pRoot);
			if (dir != -1)
			{

				std::string val = pRoot->getChild(dir)->getAttr("value");
				if (val.empty())
				{
					ReportInfo(pListener, "MoveDirection value not found in \"%s\" node \"%s\"", pRoot->getTag(), def.m_Model.c_str());
				}

			//	def.m_MainDesc.m_fDirection = GetDirectionFromString(val);
				GetBodyDirection(val, def.m_MainDesc.m_Directions);
			}
		}

		{
			uint32 dir = GetNodeIDFromName("RotatePosRoot", pRoot);
			if (dir != -1)
			{

				std::string val = pRoot->getChild(dir)->getAttr("value");
				if (val.empty())
				{
					ReportInfo(pListener, "RotatePosRoot value not found in \"%s\" node \"%s\"", pRoot->getTag(), def.m_Model.c_str());
				}

				def.m_MainDesc.m_RotatePosRoot = GetDirectionFromString(val);
			}
		}

		{
			uint32 dir = GetNodeIDFromName("RotateQuatRoot", pRoot);
			if (dir != -1)
			{

				std::string val = pRoot->getChild(dir)->getAttr("value");
				if (val.empty())
				{
					ReportInfo(pListener, "RotateQuatRoot value not found in \"%s\" node \"%s\"", pRoot->getTag(), def.m_Model.c_str());
				}

				def.m_MainDesc.m_RotateQuatRoot = GetDirectionFromString(val);
			}
		}

		{
			uint32 dir = GetNodeIDFromName("RotatePosChild", pRoot);
			if (dir != -1)
			{

				std::string val = pRoot->getChild(dir)->getAttr("value");
				if (val.empty())
				{
					ReportInfo(pListener, "RotatePosChild value not found in \"%s\" node \"%s\"", pRoot->getTag(), def.m_Model.c_str());
				}

				def.m_MainDesc.m_RotatePosChild = GetDirectionFromString(val);
			}
		}

		{
			uint32 dir = GetNodeIDFromName("RotateQuatChild", pRoot);
			if (dir != -1)
			{

				std::string val = pRoot->getChild(dir)->getAttr("value");
				if (val.empty())
				{
					ReportInfo(pListener, "RotateQuatChild value not found in \"%s\" node \"%s\"", pRoot->getTag(), def.m_Model.c_str());
				}

				def.m_MainDesc.m_RotateQuatChild = GetDirectionFromString(val);
			}
		}



		XmlNodeRef pAttrib;

		uint32 details = GetNodeIDFromName("SpecialAnimsList", pRoot);
		if (details != -1)
		{
			pAttrib = pRoot->getChild(details);

			uint32 numAnims = pAttrib->getChildCount();

			for (uint32 nAnims = 0; nAnims < numAnims; ++nAnims )
			{


				SAnimationDesc desc(def.m_MainDesc);
				XmlNodeRef pAnim = pAttrib->getChild(nAnims);

				if(!pAnim)
				{
					ReportInfo(pListener, "Node not found");
				}
				else
				{
					const char *pPath = pAnim->getAttr("APath");

					if (!pPath)
					{
						ReportInfo(pListener, "Animation name not found in \"%s\" node \"subnode\" \"%s\"", pRoot->getTag(), pAnim->getTag(), def.m_Model.c_str());
						continue;
					}
					desc.SetAnimationName(std::string(pPath));

					std::string val;

					val = pAnim->getAttr("RootToHeels");
					if (!val.empty())
					{
						desc.m_RootToHeels = GetIntFromStringBOOL(val);
					}

					val = pAnim->getAttr("ReverseDirection");
					if (!val.empty())
					{
						desc.m_ReverseDirection = GetIntFromStringBOOL(val);
					}

					val = pAnim->getAttr("SkipSaveToDatabase");
					if (!val.empty())
					{
						desc.m_SkipSaveToDatabase = GetIntFromStringBOOL(val);
					}

					val = pAnim->getAttr("DeletePosController");
					if (!val.empty())
					{
						desc.m_DeletePosController = GetIntFromStringBOOL(val);
					}

					val = pAnim->getAttr("DeleteRotController");
					if (!val.empty())
					{
						desc.m_DeleteRotController = GetIntFromStringBOOL(val);
					}

					val = pAnim->getAttr("compression");
					if (!val.empty())
					{
						pAnim->getAttr("compression", desc.m_CompressionQuality);
					}

					val = pAnim->getAttr("rootquality");
					if (!val.empty())
					{
						pAnim->getAttr("rootquality", desc.m_fRootQuality);
					}

					val = pAnim->getAttr("FloorDist");
					if (!val.empty())
					{
						pAnim->getAttr("FloorDist", desc.m_fFloorDist);
					}

					val = pAnim->getAttr("SpeedXY");
					if (!val.empty())
					{
						pAnim->getAttr("SpeedXY", desc.m_fSpeedXY);
					}

					val = pAnim->getAttr("autocompression");
					if (!val.empty())
					{
						pAnim->getAttr("autocompression", desc.m_FixedToFoots);
					}

					val = pAnim->getAttr("footplants");
					if (!val.empty())
					{
						desc.m_FootPlant = GetIntFromStringBOOL(val);
					}


					val = pAnim->getAttr("movedirection");
					if (!val.empty())
					{
						desc.m_MoveDirection = GetMoveDirectionFromString(val);
					}

					val = pAnim->getAttr("RotatePosRoot");
					if (!val.empty())
					{
						desc.m_RotatePosRoot = GetDirectionFromString(val);
					}

					val = pAnim->getAttr("RotateQuatRoot");
					if (!val.empty())
					{
						desc.m_RotateQuatRoot = GetDirectionFromString(val);
					}

					val = pAnim->getAttr("RotatePosChild");
					if (!val.empty())
					{
						desc.m_RotatePosChild = GetDirectionFromString(val);
					}

					val = pAnim->getAttr("RotateQuatChild");
					if (!val.empty())
					{
						desc.m_RotateQuatChild = GetDirectionFromString(val);
					}

					val = pAnim->getAttr("bodydirection");
					if (!val.empty())
					{
						//desc.m_fDirection = GetDirectionFromString(val);
						GetBodyDirection(val, desc.m_Directions);
					}

					val = pAnim->getAttr("human");
					if (!val.empty())
					{
						desc.m_Human = GetIntFromStringBOOL(val);
					}

					val = pAnim->getAttr("preset");
					if (!val.empty())
					{
						PresetFinder::FillPreset(presets, val.c_str(), desc.m_Preset);
					}

					size_t num = def.m_OverrideAnimations.size();


					if (def.FindIdentical(std::string(pPath), true))
					{
						ReportInfo(pListener, "Duplicate  \"%s\" \"%s\"", pPath,  def.m_Model.c_str());
					}
					else
					{
						def.m_OverrideAnimations.push_back(desc);
					}
				}
			}
		}

		size_t num = m_Definitions.size();
		m_Definitions.push_back(def);
	}

	return true;
}



const SAnimationDesc& SAnimationDefinition::GetAnimationDesc(const std::string& name ) const
{

	std::string searchname(name);
	FixString(searchname);


	for (uint32 i = 0; i < m_OverrideAnimations.size(); ++i)
	{
		std::string mapname(m_OverrideAnimations[i].GetAnimationName());


		if ((strstr(mapname.c_str(), searchname.c_str()) != 0) || (strstr(searchname.c_str(), mapname.c_str()) != 0))
		{
			return m_OverrideAnimations[i];
		}
	}

	return m_MainDesc;
}

bool SAnimationDefinition::FindIdentical(const std::string& name, bool checkLen )
{
	std::string searchname(name);
	FixString(searchname);

	for (uint32 i = 0; i < m_OverrideAnimations.size(); ++i)
	{
		std::string mapname(m_OverrideAnimations[i].GetAnimationName());

		if ((strstr(mapname.c_str(), searchname.c_str()) != 0) || (strstr(searchname.c_str(), mapname.c_str()) != 0))
		{
			if (checkLen)
			{
				if (mapname.length() == searchname.length())
					return true;
			}
			else
				return true;
		}
	}

	return false;
}

const SAnimationDefinition * CAnimationInfoLoader::GetAnimationDefinition(const std::string& name ) const
{
	std::string searchname(name);
	FixString(searchname);

	for (uint32 i = 0; i < m_Definitions.size(); ++i )
	{
		std::string mapname(m_Definitions[i].GetAnimationPath());

		if ((strstr(mapname.c_str(), searchname.c_str()) != 0) || (strstr(searchname.c_str(), mapname.c_str()) != 0))
		{
			return &m_Definitions[i];
		}
	}

	return 0;
}


void ReportWarning(IAnimationLoaderListener* pListener, const char* szFormat, ...)
{

	va_list args;
	va_start(args, szFormat);
	char szBuffer[1024];
	vsprintf(szBuffer, szFormat, args);
	pListener->OnAnimationLoaderMessage(IAnimationLoaderListener::MESSAGE_WARNING, szBuffer);
	va_end(args);
}

void ReportInfo(IAnimationLoaderListener* pListener, const char* szFormat, ...)
{
	va_list args;
	va_start(args, szFormat);
	char szBuffer[1024];
	vsprintf(szBuffer, szFormat, args);
	pListener->OnAnimationLoaderMessage(IAnimationLoaderListener::MESSAGE_INFO, szBuffer);
	va_end(args);
}

void ReportError(IAnimationLoaderListener* pListener, const char* szFormat, ...)
{
	va_list args;
	va_start(args, szFormat);
	char szBuffer[1024];
	vsprintf(szBuffer, szFormat, args);
	pListener->OnAnimationLoaderMessage(IAnimationLoaderListener::MESSAGE_ERROR, szBuffer);
	va_end(args);
}

