//
// Asura_PFX_System_Templates.cpp
//
// Created by KOR - 15/07/2004
//
// Contains all template store functions from Asura_PFX_System
//
// Copyright (C) 2004 Rebellion, All Rights Reserved.
//

#include "Core/Asura.h"

// This file's header.
#include "SpecialFX/PFX/Asura_PFX_System.h"

// Asura headers
#include "Core/Asura_HashTree.h"
#include "Core/Asura_SortAndSearch.h"
#include "SpecialFX/PFX/Asura_PFX_Templates.h"

#ifdef ASURA_TOOLS
#include "ChunkSystem/Asura_Chunk_Loaders.h"
#endif


void Asura_PFX_System::ClearAllTemplates()
{
	s_xParticleTemplateResourceSet.Reset();
 	s_xSourceTemplateResourceSet.Reset();
 	s_xEffectTemplateResourceSet.Reset();

#ifdef ASURA_TOOLS
	s_xParticleTempNames.Reset();
	s_xSourceTempNames.Reset();
	s_xEffectTempNames.Reset();
#endif 
}

/// Helper functions for add template methods /////////////////////////////////////////////////////

bool Asura_PFX_System::CanParticleTemplateBeAdded(Asura_Hash_ID uNameHash)
{
	Asura_PFX_Particle_Template*	pxParticleTemplate	= s_xParticleTemplateResourceSet.GetResourceWithoutOverride(uNameHash);
	const bool						bFound				= (pxParticleTemplate != NULL);

	// Check if it's already there
	// AJG - 14/11/07 - Outside of tools builds it's probably reasonable for a template to appear twice, as if you have separate level and character exports there's a chance that there'll be crossovers.
#ifdef ASURA_TOOLS
	Asura_Assert(!bFound, "A particle template with this name has been added already. Keeping old one.");
#endif //#ifdef ASURA_TOOLS
	return(!bFound);
}

bool Asura_PFX_System::CanSourceTemplateBeAdded(Asura_Hash_ID uNameHash)
{
	Asura_PFX_Source_Template*	pxSourceTemplate	= s_xSourceTemplateResourceSet.GetResourceWithoutOverride(uNameHash);
	const bool					bFound				= (pxSourceTemplate != NULL);

	// Check if it's already there
	// AJG - 14/11/07 - Outside of tools builds it's probably reasonable for a template to appear twice, as if you have separate level and character exports there's a chance that there'll be crossovers.
#ifdef ASURA_TOOLS
	Asura_Assert(!bFound, "A source template with this name has been added already. Keeping old one.");
#endif //#ifdef ASURA_TOOLS
	return(!bFound);
}

bool Asura_PFX_System::CanEffectTemplateBeAdded(Asura_Hash_ID uNameHash)
{
	Asura_PFX_Effect_Template*	pxEffectTemplate	= s_xEffectTemplateResourceSet.GetResourceWithoutOverride(uNameHash);
	const bool					bFound				= (pxEffectTemplate != NULL);

	// Check if it's already there
	// AJG - 14/11/07 - Outside of tools builds it's probably reasonable for a template to appear twice, as if you have separate level and character exports there's a chance that there'll be crossovers.
#ifdef ASURA_TOOLS
	Asura_Assert(!bFound, "An effect template with this name has been added already. Keeping old one.");
#endif //#ifdef ASURA_TOOLS
	return(!bFound);
}

/// Add template methods //////////////////////////////////////////////////////////////////////////


bool Asura_PFX_System::AddExistingSourceTemplateToCurrentBank(Asura_Hash_ID uNameHash)
{
	//see if the template exists
	Asura_PFX_Source_Template* pxTemplate = s_xSourceTemplateResourceSet.GetResourceWithoutOverride(uNameHash);
	if(pxTemplate)
	{
		//Add a reference to the current resource bank
		s_xSourceTemplateResourceSet.AddResource( uNameHash, *pxTemplate, false);
		return true;
	}
	else
	{
		return false;
	}
}

bool Asura_PFX_System::AddExistingEffectTemplateToCurrentBank(Asura_Hash_ID uNameHash)
{
	//see if the template exists
	Asura_PFX_Effect_Template* pxTemplate = s_xEffectTemplateResourceSet.GetResourceWithoutOverride(uNameHash);
	if(pxTemplate)
	{
		//Add a reference to the current resource bank
		s_xEffectTemplateResourceSet.AddResource( uNameHash, *pxTemplate, false);
		return true;
	}
	else
	{
		return false;
	}
}



bool Asura_PFX_System::AddParticleTemplate(Asura_Hash_ID uNameHash, Asura_PFX_Particle_Template* pxTemplate)
{
	/*
	Idealy this should be handled more like the source and effect templates to avoid creating unwanted templates
	when they already exist in the system.
	Leaving it like this at the moment , to allow the workaround for fixing the texture index to continue working.
	RAR 17/03/2009
	*/

	//search for an existing particle template
	Asura_PFX_Particle_Template* pxOldTemplate = s_xParticleTemplateResourceSet.GetResourceWithoutOverride(uNameHash); 
	if(pxOldTemplate)
	{
		//add a reference to the old template to the current bank
		s_xParticleTemplateResourceSet.AddResource(uNameHash, *pxOldTemplate);
		pxOldTemplate->m_iTextureHandle = pxTemplate->m_iTextureHandle; //on PS3 the handle can change, so set it to the new one.

		return false;//returns false to indicate that the new template can be binned
	}
	else
	{
		//add the new template
		return(s_xParticleTemplateResourceSet.AddResource(uNameHash, *pxTemplate));
	}
}

bool Asura_PFX_System::AddSourceTemplate(Asura_Hash_ID uNameHash, Asura_PFX_Source_Template* pxTemplate)
{
 	return(s_xSourceTemplateResourceSet.AddResource(uNameHash, *pxTemplate));
}

bool Asura_PFX_System::AddEffectTemplate(Asura_Hash_ID uNameHash, Asura_PFX_Effect_Template* pxTemplate)
{
	return(s_xEffectTemplateResourceSet.AddResource(uNameHash, *pxTemplate));
}

#ifdef ASURA_TOOLS
bool Asura_PFX_System::AddParticleTemplate(const char* szName, Asura_PFX_Particle_Template* pxTemplate)
{
	const Asura_Hash_ID				uHash				= Asura_GetHashID(szName);
	Asura_PFX_Particle_Template*	pxExistingTemplate	= s_xParticleTemplateResourceSet.GetResourceWithoutOverride(uHash);

	//Note that pxTemplate may be NULL if the PFX system is just adding the name
	//for loading on demand.
	if(pxExistingTemplate == NULL)
	{
		s_xParticleTempNames.AddNode(uHash, Asura_String(szName));
	}
	else
	{
		if(s_bAllowTemplateReload)
		{
			if(Asura_PFX_System::GetNumEffects())
			{
				Asura_PFX_System::ClearAllEffects();
			}

			s_xParticleTemplateResourceSet.DeleteResource(uHash);
		}
		else
		{
			//Don't allow templates to be reloaded , except when we are expecting them to be
			delete(pxTemplate);
			return(true);
		}
	}

	if(pxTemplate != NULL)
	{
		s_xParticleTemplateResourceSet.AddResource(uHash, *pxTemplate);
	}

	return(true);
}

bool Asura_PFX_System::AddSourceTemplate(const char* szName, Asura_PFX_Source_Template* pxTemplate)
{
	const Asura_Hash_ID			uHash				= Asura_GetHashID(szName);
	Asura_PFX_Source_Template*	pxExistingTemplate	= s_xSourceTemplateResourceSet.GetResourceWithoutOverride(uHash);

	//Note that pxTemplate may be NULL if the PFX system is just adding the name
	//for loading on demand.
	if(pxExistingTemplate == NULL)
	{
		s_xSourceTempNames.AddNode(uHash, Asura_String(szName));
	}
	else
	{
		// We now support reloading of templates in tools, so get rid of the old one
		if(s_bAllowTemplateReload)
		{
			s_xSourceTemplateResourceSet.DeleteResource(uHash);
			if(Asura_PFX_System::GetNumEffects())
			{
				Asura_PFX_System::ClearAllEffects();
			}
		}
		else
		{
			//Don't allow templates to be reloaded , except when we are expecting them to be
			delete(pxTemplate);
			return(true);
		}
	}

	if(pxTemplate != NULL)
	{
		s_xSourceTemplateResourceSet.AddResource(uHash, *pxTemplate);
		pxTemplate->m_xName = szName;
	}

	return(true);
}

bool Asura_PFX_System::AddEffectTemplate(const char* szName, Asura_PFX_Effect_Template* pxTemplate)
{
	const Asura_Hash_ID			uHash				= Asura_GetHashID(szName);
	Asura_PFX_Effect_Template*	pxExistingTemplate	= s_xEffectTemplateResourceSet.GetResourceWithoutOverride(uHash);

	//Note that pxTemplate may be NULL if the PFX system is just adding the name
	//for loading on demand.
	if(pxExistingTemplate == NULL)
	{
		s_xEffectTempNames.AddNode(uHash, Asura_String(szName));
	}
	else
	{
		// We now support reloading of templates in tools, so get rid of the old one
		if(s_bAllowTemplateReload)
		{
			s_xEffectTemplateResourceSet.DeleteResource(uHash);
			if(Asura_PFX_System::GetNumEffects())
			{
				Asura_PFX_System::ClearAllEffects();
			}
		}
		else
		{
			//Don't allow templates to be reloaded , except when we are expecting them to be
			//This shouldn't be happening for effect templates at all (unlike the particle and source templates)
			//RAR 19/01/2007
			Asura_Assert(false, "Reloading an effect template at an unexpected time.");
			delete(pxTemplate);
			return(true);
		}
	}

	if(pxTemplate != NULL)
	{
		s_xEffectTemplateResourceSet.AddResource(uHash, *pxTemplate);
		pxTemplate->m_xName	= szName;
	}

	return(true);
}
#endif // ASURA_TOOLS

/// Get template methods //////////////////////////////////////////////////////////////////////////

#ifdef ASURA_TOOLS
Asura_PFX_Effect_Template* Asura_PFX_System::LoadEffectTemplateByOverrideName( const Asura_String& xOverrideName )
{
	u_int uStart, uLength;
	if (Asura_StringUtil::FindStringPartByIndex( xOverrideName.GetString(), ':', 0, uStart, uLength ))
	{
		Asura_String xEffectName( xOverrideName.GetString(), uLength );
		Asura_PFX_Effect_Template* pxEffectTemplate = LoadTemplate(xEffectName);
		if (!pxEffectTemplate && !xEffectName.EndsWith("_E"))
		{
			xEffectName += Asura_String("_E");
			pxEffectTemplate = LoadTemplate(xEffectName);
		}

		Asura_Assertf( pxEffectTemplate, ("Unable to retrieve PFX Effect Template %s.\n", xEffectName.GetString()) );
		return pxEffectTemplate;
	}

	return NULL;
}
#endif

Asura_PFX_Particle_Template* Asura_PFX_System::GetParticleTempByHash(Asura_Hash_ID uHash, bool bIgnoreOverrides/* = false*/)
{
	Asura_PFX_Particle_Template*	pxTemplate	= bIgnoreOverrides ? s_xParticleTemplateResourceSet.GetResourceWithoutOverride(uHash) : s_xParticleTemplateResourceSet.GetResource(uHash);

#if defined(ASURA_TOOLS)
	if ( pxTemplate == NULL )
	{
		if (!bIgnoreOverrides)
		{
			// Need to get the name from the override map as the template name tree is only populated when the source has been loaded...
			Asura_String xName;
			if (s_xParticleTemplateResourceSet.GetOverrideNewName(uHash, xName))
			{
				(void)LoadEffectTemplateByOverrideName(xName);
				pxTemplate = bIgnoreOverrides ? s_xParticleTemplateResourceSet.GetResourceWithoutOverride(uHash) : s_xParticleTemplateResourceSet.GetResource(uHash);
				Asura_Assert( pxTemplate, "Unable to retrieve PFX Particle Template.\n" );
			}
		}
	}
#endif

#if defined(ASURA_TOOLS)
	if(pxTemplate == NULL)
	{
		const Asura_String*	pxName	= s_xParticleTempNames.GetDataByHash(uHash);

		if(pxName != NULL)
		{
			pxTemplate	= LoadParticleTemplateByHash(uHash);
		}
	}
#endif	// defined(ASURA_TOOLS)
	return(pxTemplate);
}

Asura_PFX_Source_Template* Asura_PFX_System::GetSourceTempByHash(Asura_Hash_ID uHash, bool bIgnoreOverrides/* = false*/)
{
	Asura_PFX_Source_Template*	pxTemplate	= bIgnoreOverrides ? s_xSourceTemplateResourceSet.GetResourceWithoutOverride(uHash) : s_xSourceTemplateResourceSet.GetResource(uHash);

#if defined(ASURA_TOOLS)
	if ( pxTemplate == NULL )
	{
		if (!bIgnoreOverrides)
		{
			// Need to get the name from the override map as the template name tree is only populated when the source has been loaded...
			Asura_String xName;
			if (s_xSourceTemplateResourceSet.GetOverrideNewName(uHash, xName))
			{
				(void)LoadEffectTemplateByOverrideName(xName);
				pxTemplate = bIgnoreOverrides ? s_xSourceTemplateResourceSet.GetResourceWithoutOverride(uHash) : s_xSourceTemplateResourceSet.GetResource(uHash);
				Asura_Assert( pxTemplate, "Unable to retrieve PFX Source Template.\n" );
			}
		}
	}
#endif

#if defined(ASURA_TOOLS)
	if(pxTemplate == NULL)
	{
		const Asura_String*	pxName	= s_xSourceTempNames.GetDataByHash(uHash);

		if(pxName != NULL)
		{
			pxTemplate	= LoadSourceTemplateByHash(uHash);
		}
	}
#endif	//defined(ASURA_TOOLS)
	return(pxTemplate);
}

Asura_PFX_Effect_Template* Asura_PFX_System::GetEffectTempByHash(Asura_Hash_ID uHash, bool bIgnoreOverrides/* = false*/)
{

	Asura_PFX_Effect_Template*	pxTemplate	= bIgnoreOverrides ? s_xEffectTemplateResourceSet.GetResourceWithoutOverride(uHash) : s_xEffectTemplateResourceSet.GetResource(uHash);


#if defined(ASURA_TOOLS)
	if ( pxTemplate == NULL )
	{
		if (!bIgnoreOverrides)
		{
			// Need to get the name from the override map as the template name tree is only populated when the source has been loaded...
			Asura_String xName;
			if (s_xEffectTemplateResourceSet.GetOverrideNewName(uHash, xName))
			{
					pxTemplate = LoadEffectTemplateByOverrideName(xName);
					Asura_Assert( pxTemplate, "Unable to retrieve PFX Effect Template.\n" );
			}
		}
	}
#endif

#if defined(ASURA_TOOLS)
	if(pxTemplate == NULL)
	{
		const Asura_String*	pxName	= s_xEffectTempNames.GetDataByHash(uHash);

		if(pxName != NULL)
		{
			pxTemplate	= LoadTemplateByHash(uHash);
		}
	}
#endif	//defined(ASURA_TOOLS)
	return(pxTemplate);
}

bool Asura_PFX_System::DoesParticleHashExist(Asura_Hash_ID uHash)
{
	Asura_PFX_Particle_Template*	pxTemplate	= s_xParticleTemplateResourceSet.GetResource(uHash);

	return(pxTemplate != NULL);
}

bool Asura_PFX_System::DoesSourceHashExist(Asura_Hash_ID uHash)
{
	Asura_PFX_Source_Template*	pxTemplate	= s_xSourceTemplateResourceSet.GetResource(uHash);

	return(pxTemplate != NULL);
}

bool Asura_PFX_System::DoesEffectHashExist(Asura_Hash_ID uHash)
{
	Asura_PFX_Effect_Template*	pxTemplate	= s_xEffectTemplateResourceSet.GetResource(uHash);

	return(pxTemplate != NULL);
}



#ifdef ASURA_TOOLS
const Asura_String* Asura_PFX_System::GetParticleTempNameByHash(Asura_Hash_ID uHash)
{
	return s_xParticleTempNames.GetDataByHash( uHash );
}

const Asura_String* Asura_PFX_System::GetSourceTempNameByHash(Asura_Hash_ID uHash)
{
	return s_xSourceTempNames.GetDataByHash( uHash );
}

const Asura_String* Asura_PFX_System::GetEffectTempNameByHash(Asura_Hash_ID uHash)
{
	return s_xEffectTempNames.GetDataByHash( uHash );
}

/// Delete template methods ///////////////////////////////////////////////////////////////////////

void Asura_PFX_System::DeleteParticleTemplate(Asura_Hash_ID uHashID)
{
	// Delete template
	s_xParticleTemplateResourceSet.DeleteResource(uHashID);

	// Delete name
	s_xParticleTempNames.DeleteNodeByHash( uHashID );
}

void Asura_PFX_System::DeleteSourceTemplate(Asura_Hash_ID uHashID)
{
	// Delete template
	s_xSourceTemplateResourceSet.DeleteResource(uHashID);
		
	// Delete name
	s_xSourceTempNames.DeleteNodeByHash( uHashID );
}

void Asura_PFX_System::DeleteEffectTemplate(Asura_Hash_ID uHashID)
{
	// Delete template
	s_xEffectTemplateResourceSet.DeleteResource(uHashID);
		
	// Delete name
	s_xEffectTempNames.DeleteNodeByHash( uHashID );
}

bool Asura_PFX_System::IsParticleTempLoadedByHash(Asura_Hash_ID uHash)
{
	Asura_PFX_Particle_Template*	pxTemplate	= s_xParticleTemplateResourceSet.GetResource(uHash);

	return(pxTemplate != NULL);
}

bool Asura_PFX_System::IsSourceTempLoadedByHash(Asura_Hash_ID uHash)
{
	Asura_PFX_Source_Template*	pxTemplate	= s_xSourceTemplateResourceSet.GetResource(uHash);

	return(pxTemplate != NULL);
}

bool Asura_PFX_System::IsEffectTempLoadedByHash(Asura_Hash_ID uHash)
{
	Asura_PFX_Effect_Template*	pxTemplate	= s_xEffectTemplateResourceSet.GetResource(uHash);

	return(pxTemplate != NULL);
}

bool Asura_PFX_System::RenameParticleTemplate(const char* szOldName,const char* szNewName)
{
	Asura_Hash_ID uOldHash = Asura_GetHashID(szOldName);
	Asura_Hash_ID uNewHash = Asura_GetHashID(szNewName);

	Asura_PFX_Particle_Template* pxParticleTemp = GetParticleTempByHash(uOldHash);
	if(!pxParticleTemp)
	{
		Asura_Assert(0,"Failed to get the template being renamed");
		return false;
	}

	//update the 'ID' hash tree
	bool bOkay = s_xParticleTemplateResourceSet.RelocateResource(uOldHash, uNewHash);
	if(!bOkay)
	{
		Asura_Assert(0,"Failed to update template hash ID in hash tree");
		return false;
	}

	//and the name hash tree
	bOkay = s_xParticleTempNames.ReplaceHash(uOldHash, uNewHash);
	if(!bOkay)
	{
		Asura_Assert(0,"Failed to update template hash ID in hash tree");
		return false;
	}

	//update the name in the name hash tree
	Asura_String* pxName = s_xParticleTempNames.GetDataByHash(uNewHash);
	Asura_Assert(pxName,"");
	*pxName = szNewName;

	//update the name inside the template itself
	//or rather don't.. since the particle template doesn't store its own name at the moment
	//pxParticleTemp->m_xName = szNewName;
	
	return true;	
}

bool Asura_PFX_System::RenameSourceTemplate(const char* szOldName,const char* szNewName)
{
	Asura_Hash_ID uOldHash = Asura_GetHashID(szOldName);
	Asura_Hash_ID uNewHash = Asura_GetHashID(szNewName);

	Asura_PFX_Source_Template* pxSourceTemp = GetSourceTempByHash(uOldHash);
	if(!pxSourceTemp)
	{
		Asura_Assert(0,"Failed to get the template being renamed");
		return false;
	}

	//update the 'ID' hash tree
	bool bOkay = s_xSourceTemplateResourceSet.RelocateResource(uOldHash, uNewHash);
	if(!bOkay)
	{
		Asura_Assert(0,"Failed to update template hash ID in hash tree");
		return false;
	}

	//and the name hash tree
	bOkay = s_xSourceTempNames.ReplaceHash(uOldHash, uNewHash);
	if(!bOkay)
	{
		Asura_Assert(0,"Failed to update template hash ID in hash tree");
		return false;
	}

	//update the name in the name hash tree
	Asura_String* pxName = s_xSourceTempNames.GetDataByHash(uNewHash);
	Asura_Assert(pxName,"");
	*pxName = szNewName;

	//update the name inside the template itself
	pxSourceTemp->m_xName = szNewName;
	
	return true;	
}

bool Asura_PFX_System::RenameEffectTemplate(const char* szOldName,const char* szNewName)
{
	Asura_Hash_ID uOldHash = Asura_GetHashID(szOldName);
	Asura_Hash_ID uNewHash = Asura_GetHashID(szNewName);

	Asura_PFX_Effect_Template* pxEffectTemp = GetEffectTempByHash(uOldHash);
	if(!pxEffectTemp)
	{
		Asura_Assert(0,"Failed to get the template being renamed");
		return false;
	}

	//update the 'ID' hash tree
	bool bOkay = s_xEffectTemplateResourceSet.RelocateResource(uOldHash, uNewHash);
	if(!bOkay)
	{
		Asura_Assert(0,"Failed to update template hash ID in hash tree");
		return false;
	}

	//and the name hash tree
	bOkay = s_xEffectTempNames.ReplaceHash(uOldHash, uNewHash);
	if(!bOkay)
	{
		Asura_Assert(0,"Failed to update template hash ID in hash tree");
		return false;
	}

	//update the name in the name hash tree
	Asura_String* pxName = s_xEffectTempNames.GetDataByHash(uNewHash);
	Asura_Assert(pxName,"");
	*pxName = szNewName;

	//update the name inside the template itself
	pxEffectTemp->m_xName = szNewName;
	
	return true;	
}
#endif // ASURA_TOOLS


#ifdef ASURA_TOOLS
const Asura_PFX_Effect_Template* Asura_PFX_Effect_Template::GetTemplateForPlatform(int iPlatform) const
{
	//check for override for the platform
	for(u_int u=0;u<m_uNumPlatformOverrides;u++)
	{
		if(m_pxPlatformOverrides[u].m_iPlatform == iPlatform)
		{
			if(m_pxPlatformOverrides[u].m_uEffect)
			{
				Asura_PFX_Effect_Template* pxEffect = Asura_PFX_System::GetEffectTempByHash(m_pxPlatformOverrides[u].m_uEffect);
				return pxEffect ? pxEffect : this;
			}
			break;
		}
	}
	return this;
}

Asura_PFX_Effect_Template* Asura_PFX_Effect_Template::GetTemplateForPlatform(int iPlatform)
{
	//check for override for the platform
	for(u_int u=0;u<m_uNumPlatformOverrides;u++)
	{
		if(m_pxPlatformOverrides[u].m_iPlatform == iPlatform)
		{
			if(m_pxPlatformOverrides[u].m_uEffect)
			{
				Asura_PFX_Effect_Template* pxEffect = Asura_PFX_System::GetEffectTempByHash(m_pxPlatformOverrides[u].m_uEffect);
				return pxEffect ? pxEffect : this;
			}
			break;
		}
	}
	return this;
}

Asura_Hash_ID Asura_PFX_Effect_Template::GetTemplateHash() const
{
	if(m_xName.IsBlank()) return ASURA_HASH_ID_UNSET;
	return Asura_GetHashID(m_xName.GetString());
}

Asura_Hash_ID Asura_PFX_Source_Template::GetTemplateHash() const
{
	if(m_xName.IsBlank()) return ASURA_HASH_ID_UNSET;
	return Asura_GetHashID(m_xName.GetString());
}


Asura_PFX_Particle_Template* Asura_PFX_System::LoadParticleTemplateByHash(Asura_Hash_ID uHash)
{
	const Asura_String*	pxName	= GetParticleTempNameByHash(uHash);

	if(pxName == NULL)
	{
		Asura_Assert(false, "No template name");
		return(NULL);
	}
	else
	{
		Asura_PFX_Particle_Template*	pxTemplate;
		char							szFilename[MAX_PATH];

		//build the filename
		Asura_PrintfToBfr(szFilename, "PFXTemps\\Particle\\%s.pcl", MAX_PATH, true, pxName->GetString());

		//and load the template
		LoadAsuraFile(szFilename);

		pxTemplate	= s_xParticleTemplateResourceSet.GetResource(uHash);

		Asura_Assertf((pxTemplate != NULL), ("Failed to load particle template '%s'", pxName->GetString()));
		return(pxTemplate);
	}
}

Asura_PFX_Source_Template* Asura_PFX_System::LoadSourceTemplateByHash(Asura_Hash_ID uHash)
{
	const Asura_String*	pxName	= GetSourceTempNameByHash(uHash);

	if(pxName == NULL)
	{
		Asura_Assert(false, "No template name");
		return(NULL);
	}
	else
	{
		Asura_PFX_Source_Template*	pxTemplate;
		char						szFilename[MAX_PATH];

		//build the filename
		Asura_PrintfToBfr(szFilename, "PFXTemps\\Source\\%s.src", MAX_PATH, true, pxName->GetString());

		//and load the template
		LoadAsuraFile(szFilename);

		pxTemplate	= s_xSourceTemplateResourceSet.GetResource(uHash);

		Asura_Assertf((pxTemplate != NULL), ("Failed to load source template '%s'", pxName->GetString()));
		return(pxTemplate);
	}
}

Asura_PFX_Effect_Template* Asura_PFX_System::LoadEffectTemplateByHash(Asura_Hash_ID uHash)
{
	const Asura_String*	pxName	= GetEffectTempNameByHash(uHash);

	if(pxName == NULL)
	{
		Asura_Assert(false, "No template name");
		return(NULL);
	}
	else
	{
		Asura_PFX_Effect_Template*	pxTemplate;
		char						szFilename[MAX_PATH];

		//build the filename
		Asura_PrintfToBfr(szFilename, "PFXTemps\\Effect\\%s.fct", MAX_PATH, true, pxName->GetString());

		//and load the template
		LoadAsuraFile(szFilename);

		pxTemplate	= s_xEffectTemplateResourceSet.GetResource(uHash);

		Asura_Assertf((pxTemplate != NULL), ("Failed to load effect template '%s'", pxName->GetString()));
		return(pxTemplate);
	}
}

Asura_PFX_Effect_Template* Asura_PFX_System::LoadTemplateByHash(Asura_Hash_ID uEffectHash)
{
	const Asura_String*	pxName	= GetEffectTempNameByHash(uEffectHash);

	if(pxName == NULL)
	{
		Asura_Assert(false, "No template name");
		return(NULL);
	}
	else
	{
		Asura_PFX_Effect_Template* pxTemplate = LoadTemplate( *pxName );
		Asura_Assertf(pxTemplate, ("Failed to load template '%s'\n", pxName->GetString()));
		return pxTemplate;
	}
}

Asura_PFX_Effect_Template* Asura_PFX_System::LoadTemplate( const Asura_String& xTemplateName )
{
	if (xTemplateName.IsBlank())
	{
		Asura_Assert( false, "No template name" );
		return (NULL);
	}
	else
	{
		Asura_PFX_Effect_Template*	pxTemplate;
		char						szFilename[MAX_PATH];

		//build the filename
		Asura_PrintfToBfr(szFilename, "PFXTemps\\%s.pfx", MAX_PATH, true, xTemplateName.GetString());

		//and load the template
		LoadAsuraFile(szFilename);

		pxTemplate	= s_xEffectTemplateResourceSet.GetResource(xTemplateName.GetHash());

		return(pxTemplate);
	}
}
#endif //ASURA_TOOLS



/// End of file. ///
