#ifdef ASURA_USE_AXON
//////////////////////////////////////////////////////////////////////////////
//
// Axon_Gamescene_AnimTemplate_System.h
//
// Created by Tamir Ibrahim (27.09.06)
// Was the old <project>_AnimationTemplate_System made by Andrew Weinkove - 22/07/2005
// Class that manages animation templates.
//
// Copyright (c) 2006 Rebellion. All rights reserved.
//
//////////////////////////////////////////////////////////////////////////////

// B E G I N   F I L E   W R A P P E R ///////////////////////////////////////

#ifdef ASURA_USE_PRAGMA_ONCE
    #pragma once
#endif

#ifndef AXON_GAMESCENE_ANIMTEMPLATE_SYSTEM_H___
#define AXON_GAMESCENE_ANIMTEMPLATE_SYSTEM_H___ 1

// E N D   F I L E   W R A P P E R ///////////////////////////////////////////

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

// Asura
#include "Core/Asura_HashTree.h"

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

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

class Axon_Gamescene_AnimTemplate_System
{
public:
	virtual ~Axon_Gamescene_AnimTemplate_System() {}

	static Axon_Gamescene_AnimTemplate* GetAnimTemplateByID( const u_int uUniqueID );
	static float GetTimeForAnimSequence();

	static Axon_GS2_AnimPackage* GetAnimPackageByID( const u_int uUniqueID );

	static void Initialise();
	static Axon_Gamescene_AnimTemplate_System* Project_CreateAnimTemplateSystem();
	static Axon_Gamescene_AnimTemplate_System* GetInstance() { return s_pxThis; }
	static void Shutdown();

#ifdef ASURA_TOOLS
	static void AddAnimTemplate( Axon_Gamescene_AnimTemplate* pxTemplate );
	static void RemoveAnimTemplate( const Axon_Gamescene_AnimTemplate* pxTemplate );
	static u_int GetNumAnimTemplates() { return s_xAnimTemplatePtrTree.GetNumberOfNodes(); }
	static Axon_Gamescene_AnimTemplate* GetAnimTemplateByIndex( const u_int uIndex );
	static Axon_Gamescene_AnimTemplate* GetAnimTemplateByName( const Asura_String& xName );

	static void AddAnimPackage( Axon_GS2_AnimPackage* pxPackage );
	static void RemoveAnimPackage( const Axon_GS2_AnimPackage* pxPackage );
	static u_int GetNumAnimPackages() { return s_xAnimPackagePtrTree.GetNumberOfNodes(); }
	static Axon_GS2_AnimPackage* GetAnimPackageByIndex( const u_int uIndex );
	static Axon_GS2_AnimPackage* GetAnimPackageByName( const Asura_String& xName );
#endif

private:
	static void DeleteAnimTemplate( u_int uUniqueID, Axon_Gamescene_AnimTemplate** ppxTemplate );
	static void DeleteAnimPackage( u_int uUniqueID, Axon_GS2_AnimPackage** ppxPackage );

	virtual Axon_GS2_AnimPackage* CreateAnimPackage() = 0;
	virtual void				  DestroyAnimPackage( Axon_GS2_AnimPackage* pxPackage ) = 0;

private:
	friend class Axon_Chunk_AnimTemplates;
	friend class Axon_GS2_AnimPackage_Iterator;
	friend class Axon_GS2_AnimTemplate_Iterator;
	friend class Tools_AnimTemplates;

	static Axon_Gamescene_AnimTemplate_System* s_pxThis;

	static Asura_TemplateHashTree< Axon_Gamescene_AnimTemplate* > s_xAnimTemplatePtrTree;
	static Asura_TemplateHashTree< Axon_GS2_AnimPackage* >		  s_xAnimPackagePtrTree;
};

//////////////////////////////////////////////////////////////////////////////
//
// Axon_GS2_AnimTemplate_Iterator
//
//////////////////////////////////////////////////////////////////////////////

class Axon_GS2_AnimTemplate_Iterator
{
public:
	Axon_GS2_AnimTemplate_Iterator()
	: m_xHashTreeIter( Axon_Gamescene_AnimTemplate_System::s_xAnimTemplatePtrTree )
	{
		Restart();
	}

	void Restart() { m_xHashTreeIter.Restart(); }
	Axon_Gamescene_AnimTemplate* GetCurrent() const { return *m_xHashTreeIter.GetCurrent(); }
	bool Done() const { return m_xHashTreeIter.Done(); }
	void Next() { m_xHashTreeIter.Next(); }

	u_int GetCurrentUniqueID() const { return m_xHashTreeIter.GetCurrentHash(); }

private:
	Asura_TemplateHashTree_Iterator< Axon_Gamescene_AnimTemplate* > m_xHashTreeIter;
};

//////////////////////////////////////////////////////////////////////////////
//
// Axon_GS2_AnimPackage_Iterator
//
//////////////////////////////////////////////////////////////////////////////

class Axon_GS2_AnimPackage_Iterator
{
public:
	Axon_GS2_AnimPackage_Iterator()
	: m_xHashTreeIter( Axon_Gamescene_AnimTemplate_System::s_xAnimPackagePtrTree )
	{
		Restart();
	}

	void Restart() { m_xHashTreeIter.Restart(); }
	Axon_GS2_AnimPackage* GetCurrent() const { return *m_xHashTreeIter.GetCurrent(); }
	bool Done() const { return m_xHashTreeIter.Done(); }
	void Next() { m_xHashTreeIter.Next(); }

	u_int GetCurrentUniqueID() const { return m_xHashTreeIter.GetCurrentHash(); }

private:
	Asura_TemplateHashTree_Iterator< Axon_GS2_AnimPackage* > m_xHashTreeIter;
};

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

#endif // #ifndef AXON_GAMESCENE_ANIMTEMPLATE_SYSTEM_H___
#endif // ASURA_USE_AXON
