//---------------------------------------------------------------------------
// File			: AVP_Behaviour_Marine_SquadMember.h
// Created		: 
// Created By	: Gareth Thomas
// Copyright (C) 2007 Rebellion. All Rights Reserved.
//---------------------------------------------------------------------------

//---------------------------------------------------------------------------
// BEGIN FILE WRAPPER
//---------------------------------------------------------------------------
#ifdef ASURA_USE_PRAGMA_ONCE
#pragma once
#endif
#ifndef __AVP_BEHAVIOUR_MARINE_SQUADMEMBER_H__
#define __AVP_BEHAVIOUR_MARINE_SQUADMEMBER_H__ 1
//---------------------------------------------------------------------------
// END FILE WRAPPER
//---------------------------------------------------------------------------

//---------------------------------------------------------------------------
// INCLUDES
//---------------------------------------------------------------------------
// Asura
#include "Core/Asura_LinkList.h"

// Axon
#include "Behaviour/Axon_Project_Behaviour.h"

// AVP Axon
#include "Core/AVP_PositionEvaluation.h"
#include "Core/BrainTypes/AVP_Brain_Actor_Marine.h"

//---------------------------------------------------------------------------
// FORWARD DECLARATIONS
//---------------------------------------------------------------------------
class AVP_ServerActor_Human;
class AVP_ServerEntity_Squad_Marine;
class AVP_Tactical_System;
class AVP_Knowledge_System_Actor;
struct NavData;

//---------------------------------------------------------------------------
// Class		: AVP_Behaviour_Marine_SquadMember
// Description	: 
//---------------------------------------------------------------------------
class AVP_Behaviour_Marine_SquadMember : public Axon_Project_Behaviour
{
	typedef Axon_Project_Behaviour PARENT;

public:

	// InCover Update State Enum
	enum SMUpdateState
	{
		UNSET,
		CHOOSE,
		WAIT,
		MOVE,
		ATTACK,
		ALERT,
		POST_ALERT,
		HIDE_FROM_CLOAKED_PRED,
		BE_ALERT,
		MAX_STATES
	};

	// Construction / Deconstruction
	AVP_Behaviour_Marine_SquadMember( AVP_Brain_Actor_Marine* pxBrain );
	virtual ~AVP_Behaviour_Marine_SquadMember( void );

	// Public Member Functions...
	SMUpdateState					GetUpdateState( void ) const					{ return m_eUpdateState; }
	AVP_Brain_Actor_Marine*			GetMarineBrain( void )							{ return m_pxMarineBrain; }

protected:

	virtual bool 					Activate( void );
	virtual void 					Deactivate( void );
	virtual void					PerFrameUpdate( const float fTimeslice );
#ifndef ASURA_NO_DEBUG_OUTPUT
	virtual void					RenderDebugInfo( void );
#endif

	void							SetUpdateState( SMUpdateState eState )			{ m_eUpdateState = eState; }
	void							SwitchToState( SMUpdateState eState );
	AVP_ServerActor_Human*			GetOurActor( void ) const						{ return ( m_pxMarineBrain->GetHumanActor() ); }
	AVP_Tactical_System*			GetTacticalSystem( void )						{ return ( m_pxMarineBrain->GetTacticalSystem() ); }
	AVP_Knowledge_System_Actor*		GetKnowledgeSystem( void )						{ return ( m_pxMarineBrain->GetKnowledgeSystem() ); }
	AVP_ServerEntity_Squad_Marine*	GetSquad( void ) const							{ return ( m_pxMarineBrain->GetMarineSquad() ); }
	bool							DoesHaveThreat( void )							{ return ( m_pxMarineBrain->DoesHaveThreat() ); }
	bool							DoesHaveAlert( void )							{ return ( m_pxMarineBrain->DoesHaveAlert() ); }
	AVP_ServerActor_Human*			GetSquadLeader( void ) const;
	bool							AreWeStillInASquad( void ) const;
	bool							AreWeTheSquadLeader( void ) const;
	void							FormationPositionEvaluation( const float fTimeslice );
	void							FindBestWaypoint( AVP_Navigation::PosEvalFunctor* pxPosEval );
	static u_int					GetFormationScoreForWaypoint( AVP_Navigation::AVP_PosEvalParams xPosEvalParams );
	static u_int					GetLeadersDestinationFormationScoreForWaypoint( AVP_Navigation::AVP_PosEvalParams xPosEvalParams );
	void							LookInAGoodDirection( void );
	void							LookAround( const float fTimeslice );
	void							LookScan( const float fTimeslice );
	void							CheckForObjective( bool bHaveThreat, bool bHaveAlert );
	bool							MoveToLeader( const float fTimeslice );
	bool							GetAlertStatus( void );
	bool							ShouldUpdatePositionEvaluation( void );
	u_int							GetAILeadersMoveSpeed( void );
	void							UpdateMovementData( void );

private:

	// Private Member Variables...
	SMUpdateState					m_eUpdateState;
	AVP_Brain_Actor_Marine*			m_pxMarineBrain;
	float							m_fPosEvalUpdateTimer;
	bool							m_bThreatIsCloakedPred;
	Asura_Guid						m_uCloakedPredGuid;
	Asura_Vector_3					m_xCloakedPredLastKnownPosition;
	bool							m_bHaveArrivedAtObjective;
	bool							m_bNewLookSet;
	float							m_fLookTimer;
	float							m_fLookTimeout;
	bool							m_bDirection;
	u_int							m_uLastRouteSegment;
	float							m_fRouteupdateTimer;
	bool							m_bPlayerWasSprintingLastFrame;
	bool							m_bRouteIsToLeader;
	u_short							m_usLeadersRouteIndex;

	float							m_fOurRouteDistance;
	float							m_fLeadersRouteDistance;
	bool							m_bLeaderIsFar;
	float							m_fDistToDestinationSq;
	float							m_fDistToLeaderSq;
	float							m_fRouteDiff;
	Asura_Vector_3					m_xLeaderDestination;

	bool							m_bHasObjective;

	bool							m_bMovingForward;

	float							m_fLeadersLastRouteDist;

	float							m_fTemp;
	float							m_fOurDist;



	enum { CURRENT_CHUNK_VERSION = 0 };

};

#endif //__AVP_BEHAVIOUR_MARINE_SQUADMEMBER_H__

/// End Of File 'AVP_Behaviour_Marine_SquadMember.h'
