#ifdef ASURA_USE_NEW_NAV_STUFF

//////////////////////////////////////////////////////////////////////////////
//
// Axon_Behaviour_FollowActor.h
//
// Copyright (C) 2009 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 __AXON_BEHAVIOUR_FOLLOWACTOR_H__
#define __AXON_BEHAVIOUR_FOLLOWACTOR_H__ 1

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

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

// asura
#include "Core/Asura_Maths.h"
#include "Network/Asura_Guid.h"

// axon
#include "Behaviour/Axon_Behaviour.h"

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

class Asura_ServerEntity_PhysicalObject;
class Axon_Brain;
class Axon_Behaviour_Movement;

//////////////////////////////////////////////////////////////////////////////
//
// Axon_Behaviour_FollowActor
//
//////////////////////////////////////////////////////////////////////////////

class Axon_Behaviour_FollowActor : public Axon_Behaviour
{
	typedef Axon_Behaviour PARENT;

public:
	Axon_Behaviour_FollowActor( Axon_Brain* pxBrain );

	virtual void ReadFromChunkStream( Asura_Chunk_Stream& xStream );
	virtual void WriteToChunkStream( Asura_Chunk_Stream& xStream ) const;

	void SetTargetActorGuid( const Asura_Guid uTargetActorGuid );
	Asura_Guid GetTargetActorGuid() const { return m_uTargetActorGuid; }
	void SetRadii( float fInnerRadius, float fOuterRadius );

protected:
	enum State
	{
		WAITING_FOR_TARGET_ACTOR_GUID,
		WAITING_FOR_ERROR_TIMEOUT,
		WAITING,
		MOVING_TOWARDS,
		MOVING_AWAY,
		MOVING_AROUND
	};
	enum Range
	{
		RANGE_TOO_NEAR,
		RANGE_NEAR,
		RANGE_IDEAL,
		RANGE_FAR,
		RANGE_TOO_FAR
	};

	virtual bool Activate();
	virtual void Deactivate();
	virtual void PostLoadInitialise();
	virtual void PerFrameUpdate( const float fTimeslice );

	virtual void OnNewTargetActor();
	virtual void SwitchToState( int iNextState );

	// Override this if you want to look at a different position on an actor.
	virtual void GetTargetLookAtPosition( Asura_Vector_3& xPosition ) const;

	Range GetRange() const { return m_eRange; }

#ifndef ASURA_NO_DEBUG_OUTPUT
	virtual void RenderDebugInfo();
#endif

private:
	bool UpdatePhyObjPointer();
	Range UpdateRange();

private:
	Asura_Guid m_uTargetActorGuid;
	float      m_fInnerRadiusSq;
	float      m_fOuterRadiusSq;
	float      m_fIdealDistance;
	float      m_fIdealDelta;
	int        m_iState;
	float      m_fTimer;

	// This pointer is refreshed every frame to account for objects being destroyed/etc.
	Axon_Behaviour_Movement* m_pxMovementChild;
	Asura_ServerEntity_PhysicalObject* m_pxTargetPhyObj;
	Range m_eRange;
	// Position of the target when the last pathfind was done.
	Asura_Vector_3 m_xPathfindBasePos;

	static const u_int uCURRENT_CHUNK_VERSION = 0;
};

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

#endif //__AXON_BEHAVIOUR_FOLLOWACTOR_H__
#endif // #ifdef ASURA_USE_NEW_NAV_STUFF
