
///////////////////////////////////////////////////////////////////////////////
//
// File   : AVP_Vertebrate_AnimationHandler.h
// Author : Chris Wallace
// Date   : 18-Apr-2007
//
// Copyright (C) 2007 Rebellion, All Rights Reserved.
//
///////////////////////////////////////////////////////////////////////////////

#ifdef ASURA_USE_PRAGMA_ONCE
	#pragma once
#endif   // ifdef ASURA_USE_PRAGMA_ONCE

#ifndef __AVP_VERTEBRATE_ANIMATIONHANDLER_H__
#define __AVP_VERTEBRATE_ANIMATIONHANDLER_H__


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

#include "Actor/AVP_Actor_AnimationHandler.h"

// asura
#include "Animation/IK/Asura_Animation_IK_Solver.h"
#include "Core/Asura_Handle.h"
#include "Core/Asura_Hash.h"
#include "Network/Asura_Guid.h"

// axon
#include "AnimTemplates/Axon_Gamescene_AnimSequenceData.h"

////////////////////////////////////////////////////////////////////////////////
// Defines
////////////////////////////////////////////////////////////////////////////////

#define MAX_MARKER_POINTS 2

////////////////////////////////////////////////////////////////////////////////
// Forward class declarations...
////////////////////////////////////////////////////////////////////////////////

class Asura_AnimationController_Group;
class Asura_Ragdoll_Wrapper;
class Asura_Physics_Ragdoll_Description;
class AVP_Actor_AnimationSet;
class AVP_ClientActor_Vertebrate;

////////////////////////////////////////////////////////////////////////////////
// Class declaration...
////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////
// Class        : AVP_Vertebrate_AnimationHandler
// Author       : Andy Tate
// Date         : 18-Oct-2006
//
// Description  : Class to handle the animation of a vertebrate.
////////////////////////////////////////////////////////////////////////////////

class AVP_Vertebrate_AnimationHandler : public AVP_Actor_AnimationHandler
{
	friend class AVP_Behaviour_Alien_Thrown;

public:
	// Public functions...
	AVP_Vertebrate_AnimationHandler          (AVP_ClientActor_Vertebrate& xOwner);
	virtual ~AVP_Vertebrate_AnimationHandler ();

	virtual void Initialise( void );
	virtual void Shutdown( void );

	virtual void	UpdateSkin(void);

    virtual void Update();
 	virtual void Render( void ) const;
 
	bool MakeRagdoll(const Asura_Vector_3& xPosition, const Asura_Matrix_3x3& xOrientation);
	bool DestroyRagdoll(bool bDestroyEntity = false);

	Asura_Handle			GetRagdollHandle	(void) const	{ return(m_iRagdollHandle); }
 	virtual bool			IsRagdoll			(void) const;
	virtual bool			IsRagdollFadingOut() const;

	void	EnableIKSolver();
	void	DisableIKSolver();

	virtual void	UpdateAnimStateData( const AVP_Actor_AnimStateData* pxAnimDataLBSlow, const AVP_Actor_AnimStateData* pxAnimDataLBFast, const AVP_Actor_AnimStateData* pxAnimDataUBSlow, const AVP_Actor_AnimStateData* pxAnimDataUBFast, const bool bLoop, const float fBlendLBSpeed, const float fBlendUBSpeed, const float fOSMoveDirAngle, const float fTweenTime, const bool bSynch );
	virtual void	PauseCurrentAnimState();
	virtual void	PlayCurrentAnimState();
	// these are only needed by the AI but should work for players too should the need arise
	virtual bool	IsCurrentAnimStateFinished() const;
	virtual void	SetCurrentAnimStateLooped( const bool bSet );

	virtual u_int GetFootStepFlags() const;

	virtual const AVP_Actor_AnimStateData* GetCurrentAnimStateData() const;

	void	SetRagDollAsleep() const;
	bool    IsADeadBody()	   const;
	bool    IsRagDollAsleep()  const;
	void    WakeUpRagDoll()    const;

	static void CreateConsoleVars();
	static float GetUpperBodyAnimTweenTime();

protected:
    bool	CreateRagdoll	(const Asura_Physics_Ragdoll_Description& xDescription, const Asura_Vector_3& xPosition, const Asura_Matrix_3x3& xOrientation);
	bool	DestroyRagdollKeepRendering(void);

	virtual void UpdateRagdollFading( Asura_Ragdoll_Wrapper* pxRagdollrapper );
	virtual float GetRagdollStartFadingOutTime() const { return -1.0f; }
	virtual int GetRagdollPriority() const { return 10; }

	bool	AttachWeaponToMarkerPoint( u_int uWeaponGuid, Asura_Hash_ID uMarkerPointHashID );
	bool	DetachWeaponFromHand( u_int uWeaponGuid );
	bool	GetHandleWeaponAttachmentLocally() const;

	AVP_ClientActor_Vertebrate&			m_xOwnerVertebrate;
	Asura_Handle						m_iRagdollHandle;					// The handle used when this actor becomes a ragdoll.

	const AVP_Actor_AnimStateData*		m_pxCurrentLBSlowAnimData;
	const AVP_Actor_AnimStateData*		m_pxCurrentLBFastAnimData;
	const AVP_Actor_AnimStateData*		m_pxCurrentUBSlowAnimData;
	const AVP_Actor_AnimStateData*		m_pxCurrentUBFastAnimData;

	Asura_Hash_ID						m_uLowerBodyGroupHash;
	Asura_Hash_ID						m_uUpperBodyGroupHash;

	Asura_Hash_ID						m_auLBSpeedAACGHash[ 2 ];
	Asura_Hash_ID						m_auUBSpeedAACGHash[ 2 ];
	Asura_Hash_ID						m_aauLBAACAHash[ 2 ][ 2 ];
	Asura_Hash_ID						m_aauUBAACAHash[ 2 ][ 2 ];

	Asura_Hash_ID						m_uFootstepsAACAHash;
	Asura_Hash_ID						m_uSecondaryTimerAACAHash;

	float								m_fCurrentLBBlendSpeed;
	float								m_afCurrentLBBlendDir[ 2 ];
	u_int								m_auCurrentLBAnimBlendRegion[ 2 ];
	u_int								m_auCurrentLBACWAnimIndex[ 2 ];
	u_int								m_auLastLBAnimBlendRegion[ 2 ];

	float								m_fCurrentUBBlendSpeed;
	float								m_afCurrentUBBlendDir[ 2 ];
	u_int								m_auCurrentUBAnimBlendRegion[ 2 ];
	u_int								m_auCurrentUBACWAnimIndex[ 2 ];
	u_int								m_auLastUBAnimBlendRegion[ 2 ];

	Asura_Animation_IK_Solver			m_xIKSolver;

	Asura_Hash_ID						m_auSkinHashes[ASURA_ANIMATION_SKIN_COUNT];

 private:
	// Private typedefs...
	typedef AVP_Actor_AnimationHandler PARENT;

	// Private functions...
	void	UpdateAnimBlends( const bool bLoop, const float fOSMoveDirAngle, const float fNewStateTweenTime, const bool bNewStateSync );
	void	TweenToNewLBDirectionalAnimGroup( const AVP_Actor_AnimStateData* pxAnimDataACW, const AVP_Actor_AnimStateData* pxAnimDataCW, const u_int uSpeedItr, const float fDirBlendWeight, const bool bLoop, const float fTweenTime );
	void	TweenToNewUBDirectionalAnimGroup( const AVP_Actor_AnimStateData* pxAnimDataACW, const AVP_Actor_AnimStateData* pxAnimDataCW, const u_int uSpeedItr, const float fDirBlendWeight, const bool bLoop, const float fTweenTime );
	void	ShutdownIKSolver();

	float								m_fLastFadeParametric;
	float								m_fBoneDataUpdateTweenTimer;

	AVP_Vertebrate_AnimationHandler(void);
 	AVP_Vertebrate_AnimationHandler(const AVP_Vertebrate_AnimationHandler& xOther);
  	AVP_Vertebrate_AnimationHandler& operator=(const AVP_Vertebrate_AnimationHandler& xOther);
};   // End of class 'AVP_Vertebrate_AnimationHandler'.


#endif   // ifndef __AVP_VERTEBRATE_ANIMATIONHANDLER_H__


/// End of file. ///
