
///////////////////////////////////////////////////////////////////////////////
//
// File   : AVP_FaceHugger_AnimationHandler.cpp
// Author : Andy Tate
// Date   : 18-Oct-2006
//
// Copyright (C) 2006 Rebellion, All Rights Reserved.
//
///////////////////////////////////////////////////////////////////////////////

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

#include "Core/Asura.h"

// This file's header...
#include "Actor/Vertebrates/FaceHugger/AVP_FaceHugger_AnimationHandler.h"

// Asura independent header-files...
#include "Animation/Asura_Animation.h"
#include "Animation/Asura_AnimationBlend.h"
#include "Animation/Asura_AnimationController_Animation.h"
#include "Actor/Vertebrates/FaceHugger/AVP_FaceHugger_Description.h"

// Asura platform header-files...

// Game independent header-files...
#include "Animation/AVP_AnimFlags.h"
#include "Entity/PhysicalObject/Actor/Vertebrates/FaceHugger/AVP_ClientActor_FaceHugger.h"
#include "Entity/PhysicalObject/Actor/Vertebrates/FaceHugger/AVP_ClientActor_FaceHugger.h"
#include "Entity/PhysicalObject/Actor/AVP_Actor_Messages.h"

////////////////////////////////////////////////////////////////////////////////
// Constant declarations...
////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////
// Static variable declarations...
////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////
// Private functions...
////////////////////////////////////////////////////////////////////////////////

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

////////////////////////////////////////////////////////////////////////////////
// Function     : AVP_FaceHugger_AnimationHandler::AVP_FaceHugger_AnimationHandler
// Author       : Andy Tate
// Date         : 18-Oct-2006
////////////////////////////////////////////////////////////////////////////////

AVP_FaceHugger_AnimationHandler::AVP_FaceHugger_AnimationHandler(AVP_ClientActor_FaceHugger& xOwner)
: PARENT(xOwner)
, m_xOwnerFaceHugger(xOwner)
{
}

void AVP_FaceHugger_AnimationHandler::Initialise( void )
{
	PARENT::Initialise();

	InitialiseIKSolver();
}

void AVP_FaceHugger_AnimationHandler::HandleAnimationRequest(const AVP_Message_Actor_RequestAnimation& xAnimRequestData)
{
#if 0
	if ( m_xCurrentAnimSequenceData.IsValid() || m_xPendingAnimSequenceData.IsValid() )
	{
		return;
	}

	u_int uAnimFlags = AAC_FLAG_ACTIVE | AAC_FLAG_DESTROY_WHEN_FINISHED | AAC_FLAG_ENSURE_UNIQUE_HASH | AACA_FLAG_CALCULATE_VELOCITY;

	// Work out if we should add the loop flag.
	if ( xAnimRequestData.m_eLoopStatus == AVP_Message_Actor_RequestAnimation::LOOP_ON )
	{
		uAnimFlags |= AACA_FLAG_LOOPED;
	}
	else if ( xAnimRequestData.m_eLoopStatus == AVP_Message_Actor_RequestAnimation::LOOP_STATUS_UNSET )
	{
		const bool bAnimLoopsByDefault =
			( 
				xAnimRequestData.m_uAnimation == AVP_FaceHugger_Description::FACEHUGGER_ANIM_IDLE	||
				xAnimRequestData.m_uAnimation == AVP_FaceHugger_Description::FACEHUGGER_ANIM_WALK	||
				xAnimRequestData.m_uAnimation == AVP_FaceHugger_Description::FACEHUGGER_ANIM_RUN
			);
		
		uAnimFlags |= bAnimLoopsByDefault ? AACA_FLAG_LOOPED : 0;
	}

	u_int uHashId = AVP_FaceHugger_Description::GetAnimationHashID(static_cast<AVP_FaceHugger_Description::AnimationType>(xAnimRequestData.m_uAnimation));

	CreateRequestedAnimation(uHashId, uAnimFlags); 		
#endif
}

void AVP_FaceHugger_AnimationHandler::Update()
{
	PARENT::Update();

	const u_int uAnimFlags = GetAnimation()->GetFlagsForAllAnimsLastFrame();

	m_xTailIKChain.SetAnimVeto( ( uAnimFlags & AVP_ANIMFLAG_NOT_IK_HANDS_AND_TAIL ) != 0 );
}

void AVP_FaceHugger_AnimationHandler::CreateRequestedAnimation( const Asura_Hash_ID uAnimHashID, const u_int uAnimFlags )
{
	Asura_AnimationBlend*					pxAnimBlend = new Asura_AnimationBlend_AnimatedTween(0.1f, 0.1f, false);
	m_uCurrentRequestedAnimControllerHash = PlayAnimation( uAnimFlags, AVP_AAPC_REQUEST_ANIM, uAnimHashID, pxAnimBlend );
}

void AVP_FaceHugger_AnimationHandler::InitialiseIKSolver()
{
	Asura_Assert( m_xIKSolver.GetFirstChain() == NULL, "IK Solver already initialised, clearing it..." );
	if ( m_xIKSolver.GetFirstChain() )
	{
		m_xIKSolver.Clear();
	}

	m_xTailIKChain.SetBonesArrays( AVP_FaceHugger_Description::GetTailChainArray(), NULL );
	m_xTailIKChain.SetDoJointConstraints();
	m_xTailIKChain.SetDoCollisionConstraints();
	m_xTailIKChain.SetBoneCollisionRadius( 0.05f );
	m_xIKSolver.AddChain( m_xTailIKChain );

	EnableIKSolver();
}

/// End of file. ///
