
///////////////////////////////////////////////////////////////////////////////
//
// File   : AVP_Sentrygun_AIAnimStateMachine.cpp
// Author : Will Plano
// Date   : 25/06/2008
//
// Copyright (C) 2008 Rebellion, All Rights Reserved.
//
///////////////////////////////////////////////////////////////////////////////

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

#include "Core/Asura.h"

// This file's header...
#include "Actor/Weapons/Sentrygun/AVP_Sentrygun_AIAnimStateMachine.h"

#include "Rendering/Asura_Font_System.h"
#include "Network/Asura_Message.h"

#include "Actor/Weapons/Sentrygun/AVP_Sentrygun_AIAnimStateConnections.h"
#include "Actor/Weapons/Sentrygun/AVP_Sentrygun_AIAnimStateData.h"
#include "Entity/PhysicalObject/Actor/AVP_ServerEntity_Actor.h"
#include "Inventory/AVP_Inventory_Group.h"
#include "Inventory/AVP_Inventory_HashIDs.h"
#include "Inventory/AVP_Inventory_Item.h"
#include "Inventory/AVP_Inventory_System.h"

// relates to names of the blueprint parameters for each anim state. (not just debug decriptions)
static const char* g_aszStates[ AVP_Sentrygun_AIAnimStateMachine::SENTRYGUN_STATE_END - AVP_Sentrygun_AIAnimStateMachine::SENTRYGUN_STATE_BEGIN ] =
{
	"Sweeping",	// SWEEPING
	"Disabled",	// DISABLED
	"Destroyed"	// DESTROYED
};

static bool g_abLoopedState[ AVP_Sentrygun_AIAnimStateMachine::SENTRYGUN_STATE_END - AVP_Sentrygun_AIAnimStateMachine::SENTRYGUN_STATE_BEGIN ] =
{
	true,	// SWEEPING
	true,	// DISABLED
	true,	// DESTROYED
};

////////////////////////////////////////////////////////////////////////////////
// Public functions...
////////////////////////////////////////////////////////////////////////////////

void AVP_Sentrygun_AIAnimStateMachine::Initialise()
{
	// We load the anim data for all our weapons here to avoid long loading sequences in game.
	const AVP_Inventory_System* pxInvSys = m_xServerActor.GetInventorySystem();
	const AVP_Inventory_Group* pxWeaponGroup = pxInvSys != NULL ? pxInvSys->GetGroup( uAVP_INVENTORY_GROUPHASH_WEAPON ) : NULL;
	if ( pxWeaponGroup != NULL )
	{
		Asura_Hash_ID uWeaponItr( pxWeaponGroup->FindLowestPriorityItem() );
		for ( ; uWeaponItr != ASURA_HASH_ID_UNSET; uWeaponItr = pxWeaponGroup->FindNextHighestPriorityItem( uWeaponItr ) )
		{
			const AVP_Inventory_Item* pxItem = pxWeaponGroup->GetItem( uWeaponItr );
			if ( pxItem )
			{
				AVP_Sentrygun_AIAnimStateData::InitialiseWeaponData( m_xServerActor.GetAnimStateBlueprintType(), pxItem->GetBlueprintHash() );
			}
		}
	}

	PARENT::Initialise();
}

const AVP_Actor_AnimStateData* AVP_Sentrygun_AIAnimStateMachine::GetStateAnimData( const u_int uState ) const
{
	const AVP_Inventory_System* pxInvSys = m_xServerActor.GetInventorySystem();
	const AVP_Inventory_Group* pxWeaponGroup = pxInvSys != NULL ? pxInvSys->GetGroup( uAVP_INVENTORY_GROUPHASH_WEAPON ) : NULL;
	Asura_Assert( pxWeaponGroup != NULL, "Unable to get wepaon group" );
	if ( pxWeaponGroup != NULL )
	{
		const AVP_Inventory_Item* pxItem = pxWeaponGroup->GetCurrentInventoryItem();
		if ( pxItem )
		{
			return AVP_Sentrygun_AIAnimStateData::GetAnimStateData( m_xServerActor.GetAnimStateBlueprintType(), pxItem->GetBlueprintHash(), uState );
		}
	}
	// else
	return NULL;
}

#ifndef ASURA_NO_DEBUG_OUTPUT
void AVP_Sentrygun_AIAnimStateMachine::RenderDebugInfo()
{
	PARENT::RenderDebugInfo();

	Asura_Vector_3 xDebugPos( m_xServerActor.GetPosition() );
	if ( Asura_Camera::ProjectWorldCoordsToScreenSpace( xDebugPos, true ) && xDebugPos.z > 0.0f)
	{
		xDebugPos.y -= 20.0f;

		const AVP_Inventory_System* pxInvSys = m_xServerActor.GetInventorySystem();
		const AVP_Inventory_Group* pxWeaponGroup = pxInvSys != NULL ? pxInvSys->GetGroup( uAVP_INVENTORY_GROUPHASH_WEAPON ) : NULL;
		Asura_Assert( pxWeaponGroup != NULL, "Unable to get wepaon group" );
		if ( pxWeaponGroup != NULL )
		{
			xDebugPos.y -= 10.0f;

			Asura_Font_System::Print
			(
				xDebugPos.GetX(),
				xDebugPos.GetY(),
				0.6f,
				0xffffffff,
				ASURA_TEXTFORMAT_CENTREJUSTIFIED | ASURA_TEXTFORMAT_FORMATSTRING, 
				"Weapon: 0x%08x", pxWeaponGroup->GetCurrentItem()
			);
		}
	}
}
#endif

const AVP_Actor_AIAnimStateConnectionData* AVP_Sentrygun_AIAnimStateMachine::GetConnectionData( const u_int uFromState, const u_int uToState ) const
{
	return AVP_Sentrygun_AIAnimStateConnections::GetConnectionData( uFromState, uToState );
}

const char* AVP_Sentrygun_AIAnimStateMachine::GetStateDescriptionStatic( const u_int uState )
{
	if ( uState < SENTRYGUN_STATE_BEGIN )
	{
		return PARENT::GetStateDescriptionStatic( uState );
	}

	Asura_Assert( uState < SENTRYGUN_STATE_END, "Invalid state" );
	return g_aszStates[ uState - SENTRYGUN_STATE_BEGIN ];
}

bool AVP_Sentrygun_AIAnimStateMachine::IsLoopedStateStatic( const u_int uState )
{
	if ( uState < SENTRYGUN_STATE_BEGIN )
	{
		return PARENT::IsLoopedStateStatic( uState );
	}

	Asura_Assert( uState < SENTRYGUN_STATE_END, "Invalid state" );
	return g_abLoopedState[ uState - SENTRYGUN_STATE_BEGIN ];
}

/// End of file. ///
