//////////////////////////////////////////////////////////////////////////////
//
// Axon_GS2_AnimPackage.h
//
// Copyright (C) 2009 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_GS2_ANIMPACKAGE_H__
#define __AXON_GS2_ANIMPACKAGE_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_Hash.h"
#include "Core/Asura_LinkList.h"

#ifdef ASURA_TOOLS
#include "Misc/list_tem.hpp"
#endif

// F O R W A R D   D E C L A R A T I O N S ///////////////////////////////////

class Asura_Chunk_Stream;
class Asura_ServerEntity_PhysicalObject;
class Axon_GS2_AnimPackage;

//////////////////////////////////////////////////////////////////////////////
//
// Axon_GS2_AnimMapping
// A mapping contains a number of factors and the animation they map to.
// A factor is a u_int value that is interpreted by the project.
// The number of factors is determined by the project.
// The order of the factors should remain constant.
//
//////////////////////////////////////////////////////////////////////////////

class Axon_GS2_AnimMapping
{
public:
	Axon_GS2_AnimMapping() : m_uAnimHashID( ASURA_HASH_ID_UNSET ), m_uAnimFilenameHashID( ASURA_HASH_ID_UNSET ) {}
	virtual ~Axon_GS2_AnimMapping() {}

	virtual void ReadFromChunkStream( Asura_Chunk_Stream& xStream );
	virtual void WriteToChunkStream( Asura_Chunk_Stream& xStream ) const;

	// True if the mapping matches the mapping data, false otherwise.
	virtual bool Matches( const void* pMappingData ) const = 0;

	Asura_Hash_ID GetAnimHashID()		  const { return m_uAnimHashID; }
	Asura_Hash_ID GetAnimFilenameHashID() const { return m_uAnimFilenameHashID; }

#ifdef ASURA_TOOLS
	void SetAnimHashIDs( Asura_Hash_ID uAnimHashID, Asura_Hash_ID uAnimFilenameHashID )
	{
		m_uAnimHashID = uAnimHashID;
		m_uAnimFilenameHashID = uAnimFilenameHashID;
	}

	virtual void LoadAnims() const;
	virtual void AddFilesToExportList( List< Asura_String >& xNameList ) const;
	virtual bool Verify( const Axon_GS2_AnimPackage& xParentPackage ) const;
#endif

protected:
	void GetAnimHashID( Asura_Hash_ID uHashID )		{ m_uAnimHashID = uHashID; }
	void GetAnimFileHashID( Asura_Hash_ID uHashID ) { m_uAnimFilenameHashID = uHashID; }

private:
	Asura_Hash_ID m_uAnimHashID;
	Asura_Hash_ID m_uAnimFilenameHashID;

	static const u_int uCURRENT_CHUNK_VERSION = 0;
};

//////////////////////////////////////////////////////////////////////////////
//
// Axon_GS2_AnimPackage
// A package contains a number of mappings and any extra data a project requires.
//
//////////////////////////////////////////////////////////////////////////////

class Axon_GS2_AnimPackage
{
public:
	Axon_GS2_AnimPackage();
	virtual ~Axon_GS2_AnimPackage();

	u_int GetUniqueID() const { return m_uUniqueID; }
	// If pMappingData is provided then anim mappings can be correctly evaluated. If not then the default mapping will be applied.
	Asura_Hash_ID GetAnim( const void* pMappingData = NULL, Asura_Hash_ID* puAnimFilenameHashID = NULL );

	virtual void ReadFromChunkStream( Asura_Chunk_Stream& xStream );
#ifdef ASURA_TOOLS
	virtual void WriteToChunkStream( Asura_Chunk_Stream& xStream ) const;

	virtual void LoadAnims() const;
	virtual void AddFilesToExportList( List< Asura_String >& xNameList ) const;
	virtual bool Verify() const;

	void AllocateUniqueID( const Asura_String& xName );

	const Asura_String& GetName() const { return m_xName; }
	void SetName( const Asura_String& xName ) { m_xName = xName; }
	const Asura_String& GetPath() const { return m_xPath; }
	void SetPath( const Asura_String& xPath ) { m_xPath = xPath; }
	bool IsLocalOnlyAndWritable() const { return m_bLocalOnlyAndWritable; }
	void SetLocalOnlyAndWritable( bool bVal ) { m_bLocalOnlyAndWritable = bVal; }

	u_int GetNumMappings() const { return m_xMappings.Size(); }
	Axon_GS2_AnimMapping* GetMapping( u_int u ) { return m_xMappings[ u ]->Data(); }
	Asura_LinkList< Axon_GS2_AnimMapping* >& GetMappings() { return m_xMappings; }
	void AddAnimMapping();
	void DeleteAnimMapping( Axon_GS2_AnimMapping* pxMapping );
#endif

	static const u_int uUNSET_ID = 0;

protected:
	// Set the mapping to contain one of each mapping factor. These should all be initialised to the default/"don't care" value if necessary.
	virtual Axon_GS2_AnimMapping* CreateAnimMapping( bool bSetToDefaults ) = 0;

private:
	u_int									m_uUniqueID;
	Asura_LinkList< Axon_GS2_AnimMapping* > m_xMappings;

#ifdef ASURA_TOOLS
	friend class Tools_AnimTemplates;
	Asura_String m_xName;
	Asura_String m_xPath;
	bool m_bLocalOnlyAndWritable;
#endif

	static const u_int uCURRENT_CHUNK_VERSION = 0;
};

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

#endif //__AXON_GS2_ANIMPACKAGE_H__
