
///////////////////////////////////////////////////////////////////////////////
//
// File   : AVP_Alien_AIAnimStateData.cpp
// Author : Will Plano
// Date   : 27/09/2007
//
// Copyright (C) 2007 Rebellion, All Rights Reserved.
//
///////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////
// Include files...
////////////////////////////////////////////////////////////////////////////////

#include "Core/Asura.h"

// This file's header...
#include "Actor/Vertebrates/Alien/AVP_Alien_AIAnimStateData.h"

// Asura
#include "Blueprint/Asura_Blueprint_System.h"
#include "Core/Asura_Hash.h"
#include "Dynamics/Asura_Collision_Object.h"

// AVP
#include "Blueprint/AVP_Blueprint_HashIDs.h"
#include "Physics/AVP_Collision_Descriptor.h"

#ifdef ASURA_TOOLS
#include "Blueprint/ToolsAVP_Blueprint_AnimSpreadsheetExporter.h"
#endif

AVP_Actor_AnimStateData*** AVP_Alien_AIAnimStateData::s_apppxAnimStateData[ AVP_Alien_AIAnimStateMachine::GROUNDTYPE_END ];

bool AVP_Alien_AIAnimStateData::s_bInitialised = false;

const AVP_Actor_AnimStateData* AVP_Alien_AIAnimStateData::GetAnimStateData( const Asura_Hash_ID uAnimStateBlueprintType, u_int uState, u_int uGroundType /*= AVP_Actor_PhysicsObjectHandler::ON_FLOOR*/, AVP_Alien_AIAnimStateMachine::LimbDamage eLimbDamage /*= AVP_Alien_AIAnimStateMachine::LIMBDMG_NONE*/ )
{
	if ( !s_bInitialised )
	{
		Initialise( uAnimStateBlueprintType );
	}
	AVP_Alien_AIAnimStateMachine::GroundType eAnimGroundType = uGroundType == AVP_Actor_PhysicsObjectHandler::ON_FLOOR ? AVP_Alien_AIAnimStateMachine::GROUNDTYPE_ON_FLOOR: AVP_Alien_AIAnimStateMachine::GROUNDTYPE_NON_FLOOR;
	Asura_Assert( uState < AVP_Alien_AIAnimStateMachine::ALIEN_STATE_END, "Invalid state" );
	if ( uState < AVP_Alien_AIAnimStateMachine::ALIEN_STATE_END )
	{
		if ( eLimbDamage != AVP_Alien_AIAnimStateMachine::LIMBDMG_NONE )
		{
			eAnimGroundType = AVP_Alien_AIAnimStateMachine::GROUNDTYPE_ON_FLOOR;
		}

		if ( s_apppxAnimStateData[ eAnimGroundType ] &&
			 s_apppxAnimStateData[ eAnimGroundType ][ eLimbDamage ] )
		{
			return s_apppxAnimStateData[ eAnimGroundType ][ eLimbDamage ][ uState ];
		}
	}
	return NULL;
}

void AVP_Alien_AIAnimStateData::Initialise( const Asura_Hash_ID uAnimStateBlueprintType )
{
	if ( s_bInitialised )
	{
		return;
	}

	s_bInitialised = true;

	for ( u_int uGroundItr = 0; uGroundItr < AVP_Alien_AIAnimStateMachine::GROUNDTYPE_END; ++uGroundItr )
	{
		s_apppxAnimStateData[ uGroundItr ] = NULL;

		bool bHasLimbDamage = uGroundItr == AVP_Alien_AIAnimStateMachine::GROUNDTYPE_ON_FLOOR;
		u_int uNumLimDamage = bHasLimbDamage ? AVP_Alien_AIAnimStateMachine::LIMBDMG_END : 1;
		s_apppxAnimStateData[ uGroundItr ] = new AVP_Actor_AnimStateData**[ uNumLimDamage ];
		for ( u_int uLimbDmgItr = 0; uLimbDmgItr < uNumLimDamage; ++uLimbDmgItr )
		{
			s_apppxAnimStateData[ uGroundItr ][ uLimbDmgItr ] = new AVP_Actor_AnimStateData*[ AVP_Alien_AIAnimStateMachine::ALIEN_STATE_END ];

			Asura_String xStateBPName("AI_");
			xStateBPName += AVP_Alien_AIAnimStateMachine::GetGroundTypeDescription( uGroundItr );
			if ( bHasLimbDamage )
			{
				xStateBPName += '_';
				xStateBPName += AVP_Alien_AIAnimStateMachine::GetLimbDamageDescription( uLimbDmgItr );
			}
#ifdef ASURA_TOOLS
			if ( ToolsAVP_Blueprint_AnimSpreadsheetExporter::IsActive() )
			{
				ToolsAVP_Blueprint_AnimSpreadsheetExporter::CreateFile( ( Asura_String( "Alien_" ) + xStateBPName + ".csv" ).GetString() );
			}
#endif
			u_int uStateItr = 0;
			for ( ; uStateItr < AVP_Alien_AIAnimStateMachine::ACTOR_STATE_IDLE; ++uStateItr )
			{
				s_apppxAnimStateData[ uGroundItr ][ uLimbDmgItr ][ uStateItr ] = NULL;
			}
			for ( ; uStateItr < AVP_Alien_AIAnimStateMachine::ALIEN_STATE_END; ++uStateItr )
			{
				s_apppxAnimStateData[ uGroundItr ][ uLimbDmgItr ][ uStateItr ] = NULL;
				const Asura_Blueprint* pxStateBlueprint = Asura_Blueprint_System::GetBlueprintByHashID( uAnimStateBlueprintType, xStateBPName.GetHash() );
				Asura_Assertf( pxStateBlueprint, ( "Unable to get state blueprint 0x%08x", xStateBPName.GetHash() ) );
				if ( pxStateBlueprint )
				{
					if ( AVP_Alien_AIAnimStateMachine::IsDirectionalState( uStateItr ) )
					{
						s_apppxAnimStateData[ uGroundItr ][ uLimbDmgItr ][ uStateItr ] = new AVP_Actor_AnimStateData_Directional();
						s_apppxAnimStateData[ uGroundItr ][ uLimbDmgItr ][ uStateItr ]->InitialiseFromBlueprint( uAnimStateBlueprintType, *pxStateBlueprint, AVP_Alien_AIAnimStateMachine::GetStateDescriptionStatic( uStateItr ), AVP_Vertebrate_AIAnimStateMachine::IsStateRequired( uStateItr ) );
					}
					else
					{
						s_apppxAnimStateData[ uGroundItr ][ uLimbDmgItr ][ uStateItr ] = new AVP_Actor_AnimStateData_NonDirectional();
						s_apppxAnimStateData[ uGroundItr ][ uLimbDmgItr ][ uStateItr ]->InitialiseFromBlueprint( uAnimStateBlueprintType, *pxStateBlueprint, AVP_Alien_AIAnimStateMachine::GetStateDescriptionStatic( uStateItr ), AVP_Vertebrate_AIAnimStateMachine::IsStateRequired( uStateItr ) );
					}
#ifdef ASURA_TOOLS
					if ( ToolsAVP_Blueprint_AnimSpreadsheetExporter::IsActive() )
					{
						ToolsAVP_Blueprint_AnimSpreadsheetExporter::WriteState( AVP_Alien_AIAnimStateMachine::GetStateDescriptionStatic( uStateItr ), s_apppxAnimStateData[ uGroundItr ][ uLimbDmgItr ][ uStateItr ], pxStateBlueprint, uAnimStateBlueprintType );
					}
#endif
				}
			} // end state loop
		} // end limb damage loop
	} // end ground loop
}

void AVP_Alien_AIAnimStateData::ResetStorage()
{
	if ( s_bInitialised )
	{
		s_bInitialised = false;
		for ( u_int uGroundItr = 0; uGroundItr < AVP_Alien_AIAnimStateMachine::GROUNDTYPE_END; ++uGroundItr )
		{
			if ( s_apppxAnimStateData[ uGroundItr ] != NULL )
			{
				bool bHasLimbDamage = uGroundItr == AVP_Alien_AIAnimStateMachine::GROUNDTYPE_ON_FLOOR;
				u_int uNumLimDamage = bHasLimbDamage ? AVP_Alien_AIAnimStateMachine::LIMBDMG_END : 1;
				for ( u_int uLimbDmgItr = 0; uLimbDmgItr < uNumLimDamage; ++uLimbDmgItr )
				{
					if ( s_apppxAnimStateData[ uGroundItr ][ uLimbDmgItr ] != NULL )
					{
						for ( u_int uStateItr = 0; uStateItr < AVP_Alien_AIAnimStateMachine::ALIEN_STATE_END; ++uStateItr )
						{
							delete s_apppxAnimStateData[ uGroundItr ][ uLimbDmgItr ][ uStateItr ];
						}
						delete[] s_apppxAnimStateData[ uGroundItr ][ uLimbDmgItr ];
						s_apppxAnimStateData[ uGroundItr ][ uLimbDmgItr ] = NULL;
					}
				}
				delete[] s_apppxAnimStateData[ uGroundItr ];
				s_apppxAnimStateData[ uGroundItr ] = NULL;
			}
		}
	}
}
/// End of file. ///
