//////////////////////////////////////////////////////////////////////////////
//
// Axon_Gamescene_AnimTemplate_System.cpp
//
// Copyright (c) 2006 Rebellion. All rights reserved.
//
//////////////////////////////////////////////////////////////////////////////

// I N C L U D E S ///////////////////////////////////////////////////////////

#include "Core/Asura.h"

#ifdef ASURA_USE_AXON

// This file's header.
#include "Axon_Gamescene_AnimTemplate_System.h"

//Asura
#include "Network/Asura_Network.h"
#include "Core/Asura_Timers.h"

//Axon
#include "AnimTemplates/Axon_Gamescene_AnimTemplates.h"

#ifdef ASURA_TOOLS
#include "AnimTemplates/Tools_Mode_AnimTemplates.h"
#endif

//////////////////////////////////////////////////////////////////////////////
//
// Axon_Gamescene_AnimTemplate_System
//
//////////////////////////////////////////////////////////////////////////////

Axon_Gamescene_AnimTemplate_System* Axon_Gamescene_AnimTemplate_System::s_pxThis = NULL;

Asura_TemplateHashTree< Axon_Gamescene_AnimTemplate* > Axon_Gamescene_AnimTemplate_System::s_xAnimTemplatePtrTree;
Asura_TemplateHashTree< Axon_GS2_AnimPackage* >		   Axon_Gamescene_AnimTemplate_System::s_xAnimPackagePtrTree;

void Axon_Gamescene_AnimTemplate_System::Initialise()
{
	s_pxThis = Project_CreateAnimTemplateSystem();

#ifdef ASURA_TOOLS
	Tools_AnimTemplates::LoadAnimTemplatesAndPackages();
#endif
}

void Axon_Gamescene_AnimTemplate_System::Shutdown()
{
	s_xAnimTemplatePtrTree.Traverse( DeleteAnimTemplate );
	s_xAnimTemplatePtrTree.Reset();

	s_xAnimPackagePtrTree.Traverse( DeleteAnimPackage );
	s_xAnimPackagePtrTree.Reset();

	delete s_pxThis;
	s_pxThis = NULL;
}

float Axon_Gamescene_AnimTemplate_System::GetTimeForAnimSequence()
{
	if ( Asura_Network::IsExternalNetworkActive() )
	{
		return Asura_Timers::GetServerAbsoluteTime();
	}
	else
	{
		return Asura_Timers::GetLocalScaledTime();
	}
}

Axon_Gamescene_AnimTemplate* Axon_Gamescene_AnimTemplate_System::GetAnimTemplateByID( const u_int uUniqueID )
{
	if ( uUniqueID == uAXON_ANIMATION_SEQUENCE_ID_NONE )
	{
		return NULL;
	}
	Axon_Gamescene_AnimTemplate** ppxTemplate = s_xAnimTemplatePtrTree.GetDataByHash( uUniqueID );
	return ( ppxTemplate ? *ppxTemplate : NULL );
}

Axon_GS2_AnimPackage* Axon_Gamescene_AnimTemplate_System::GetAnimPackageByID( const u_int uUniqueID )
{
	if ( uUniqueID == Axon_GS2_AnimPackage::uUNSET_ID )
	{
		return NULL;
	}
	Axon_GS2_AnimPackage** ppxPackage = s_xAnimPackagePtrTree.GetDataByHash( uUniqueID );
	return ( ppxPackage ? *ppxPackage : NULL );
}

#ifdef ASURA_TOOLS
void Axon_Gamescene_AnimTemplate_System::AddAnimTemplate( Axon_Gamescene_AnimTemplate* pxTemplate )
{
	s_xAnimTemplatePtrTree.AddNode( pxTemplate->GetUniqueID(), pxTemplate );
}

void Axon_Gamescene_AnimTemplate_System::RemoveAnimTemplate( const Axon_Gamescene_AnimTemplate* pxTemplate )
{
	const u_int uUniqueID = pxTemplate->GetUniqueID();
	Axon_Gamescene_AnimTemplate** ppxTemplate = s_xAnimTemplatePtrTree.GetDataByHash( uUniqueID );
	if ( ppxTemplate )
	{
		delete *ppxTemplate;
		*ppxTemplate = NULL;
	}
	s_xAnimTemplatePtrTree.DeleteNodeByHash( uUniqueID );
}

Axon_Gamescene_AnimTemplate* Axon_Gamescene_AnimTemplate_System::GetAnimTemplateByIndex( const u_int uIndex )
{
	Axon_Gamescene_AnimTemplate** ppxTemplate = s_xAnimTemplatePtrTree.GetDataByIndex( uIndex );
	return ppxTemplate ? *ppxTemplate : NULL;
}

Axon_Gamescene_AnimTemplate* Axon_Gamescene_AnimTemplate_System::GetAnimTemplateByName( const Asura_String& xName )
{
	if ( xName.IsBlank() )
	{
		return NULL;
	}

	for ( Axon_GS2_AnimTemplate_Iterator xTemplateIter; !xTemplateIter.Done(); xTemplateIter.Next() )
	{
		if ( xTemplateIter.GetCurrent()->GetName() == xName )
		{
			return xTemplateIter.GetCurrent();
		}
	}

	return NULL;
}

void Axon_Gamescene_AnimTemplate_System::AddAnimPackage( Axon_GS2_AnimPackage* pxPackage )
{
	s_xAnimPackagePtrTree.AddNode( pxPackage->GetUniqueID(), pxPackage );
}

void Axon_Gamescene_AnimTemplate_System::RemoveAnimPackage( const Axon_GS2_AnimPackage* pxPackage )
{
	const u_int uUniqueID = pxPackage->GetUniqueID();
	Axon_GS2_AnimPackage** ppxPackage = s_xAnimPackagePtrTree.GetDataByHash( uUniqueID );
	if ( ppxPackage )
	{
		s_pxThis->DestroyAnimPackage( *ppxPackage );
	}
	s_xAnimPackagePtrTree.DeleteNodeByHash( uUniqueID );
}

Axon_GS2_AnimPackage* Axon_Gamescene_AnimTemplate_System::GetAnimPackageByIndex( const u_int uIndex )
{
	Axon_GS2_AnimPackage** ppxTemplate = s_xAnimPackagePtrTree.GetDataByIndex( uIndex );
	return ppxTemplate ? *ppxTemplate : NULL;
}

Axon_GS2_AnimPackage* Axon_Gamescene_AnimTemplate_System::GetAnimPackageByName( const Asura_String& xName )
{
	if ( xName.IsBlank() )
	{
		return NULL;
	}

	for ( Axon_GS2_AnimPackage_Iterator xPackageIter; !xPackageIter.Done(); xPackageIter.Next() )
	{
		if ( xPackageIter.GetCurrent()->GetName() == xName )
		{
			return xPackageIter.GetCurrent();
		}
	}

	return NULL;
}
#endif // ASURA_TOOLS

void Axon_Gamescene_AnimTemplate_System::DeleteAnimTemplate( u_int uUniqueID, Axon_Gamescene_AnimTemplate** ppxTemplate )
{
	delete *ppxTemplate;
	*ppxTemplate = NULL;
}

void Axon_Gamescene_AnimTemplate_System::DeleteAnimPackage( u_int uUniqueID, Axon_GS2_AnimPackage** ppxPackage )
{
	s_pxThis->DestroyAnimPackage( *ppxPackage );
	*ppxPackage = NULL;
}

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

#endif // ASURA_USE_AXON
