//////////////////////////////////////////////////////////////////////////////
//
// AVP_Behaviour_Human_Movement.h
//
// Copyright (C) 2008 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 __AVP_BEHAVIOUR_HUMAN_MOVEMENT_H__
#define __AVP_BEHAVIOUR_HUMAN_MOVEMENT_H__ 1

// E N D   F I L E   W R A P P E R ///////////////////////////////////////////

// I N C L U D E S ///////////////////////////////////////////////////////////

// avp axon
#include "Behaviour/Axon_Project_Behaviour.h"
#include "Core/AVP_Navigation.h"

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

class AVP_Brain_Actor;
using namespace AVP_Navigation;

//////////////////////////////////////////////////////////////////////////////
//
// AVP_Behaviour_Predator_Movement
//
//////////////////////////////////////////////////////////////////////////////

class AVP_Behaviour_Human_Movement : public Axon_Project_Behaviour
{
	typedef Axon_Project_Behaviour PARENT;

public:
	AVP_Behaviour_Human_Movement( AVP_Brain_Actor* pxBrain );

	void SetDestinationGS2NodeGuid( Asura_Guid uGS2NodeGuid );
	bool GetToPosition(const Asura_Vector_3& xDestination, MovementMode m_eMovementMode = AVP_Navigation::MM_MEDIUM, bool bOverrideMovementMode = false);

	void SetStopAtEnd( bool bVal ) { m_bStopAtEnd = bVal; }
	
	

protected:
	virtual bool HandleMessage( const Asura_Message* pxMessage );
	virtual bool Activate();
	virtual void Deactivate();
	virtual void ReadFromChunkStream( Asura_Chunk_Stream& xStream );
	virtual void WriteToChunkStream( Asura_Chunk_Stream& xStream ) const;
	virtual void PostLoadInitialise();
	virtual void Update( const float fTimeslice );
	virtual void PerFrameUpdate( const float fTimeslice );

	void SetMovementMode( void );

#ifndef ASURA_NO_DEBUG_OUTPUT
	virtual void RenderDebugInfo();
#endif

	AVP_Brain_Actor*	GetActorBrain() const;

private:
	enum State
	{
		UNSET,
		TRAVERSING_STANDARD_LINK,
		MOVING_TO_DESTINATION,
		MOUNT_GAMESCENE,
		FINISHED,
		NUM_STATES
	};

	void			SwitchToState( const State eNextState );
	bool			UpdateFollowPoint();
	void			UpdatePositionOnRoute();
	void			UpdateStuckDetection( const float fTimeslice );
	bool			SendMountGamesceneMessage( void );
	Asura_Hash_ID	GetMountGamesceneAnimBlendTemplateBlueprintHash( void );
	void			CalculateAvoidanceSteering( const Asura_Vector_3& xFollowPointSteering, Asura_Vector_3& xSteering );


private:
	State          m_eCurrentState;
	float          m_fTimeInState;
	float          m_fArrivalRange;
	// Used for detecting if we get stuck.
	// If our follow point stops moving we're obviously making no headway along the route.
	Asura_Vector_3 m_xPrevPositionOnRoute;
	float          m_fSmoothedPORVelocity;

	Asura_Vector_3 m_xPositionOnRoute;
	Asura_Vector_3 m_xFollowPoint;

	bool		   m_bFirstTime;
	Asura_Guid	   m_uGS2NodeGuid;
	Asura_Vector_3 m_xPostGS2Direction;
	Asura_Vector_3 m_xEndGS2Position;
	bool		   m_bNeedToEnterNode;
	bool		   m_bStopAtEnd;
	bool		   m_bMoveModeOverriden;

	static const u_int uCURRENT_CHUNK_VERSION = 2;
};

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

#endif //__AVP_BEHAVIOUR_HUMAN_MOVEMENT_H__
