//////////////////////////////////////////////////////////////////////////////
//
// AVP_Tactical_System.h
//
// Created by NJD - 07 December 2006
//
// Copyright (C) 2006 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_TACTICAL_SYSTEM_H__
#define __AVP_TACTICAL_SYSTEM_H__ 1

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

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

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

#include "Entity/Controller/AVP_ServerEntity_Squad_Marine.h"

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

class Asura_Chunk_Stream;
class Axon_Project_Brain;
class AVP_ServerEntity_GamePlayVolume;
class AVP_ServerNode_CoverpointNode;
class AVP_ServerNode_FormationPoint;
class AVP_ServerEntity_Actor;

//////////////////////////////////////////////////////////////////////////////
//
// AVP_Tactical_System
//
//////////////////////////////////////////////////////////////////////////////

enum AVP_Allegiance
{
    AVP_ALLEGIANCE_NEUTRAL,
    AVP_ALLEGIANCE_FRIEND,
    AVP_ALLEGIANCE_ENEMY,
    AVP_NUM_ALLEGIANCES
};

class AVP_Tactical_System
{
public:
    AVP_Tactical_System(Axon_Project_Brain* pxBrain);
    virtual ~AVP_Tactical_System(void);

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

    static AVP_Allegiance	GetAllegiance(const Asura_Entity& xMe, const Asura_Entity& xThem);

	void					SetDestination				(const Asura_Vector_3& xDest);
	void					SetLookAt					(const Asura_Vector_3& xPos);
	void					SetLookAt					(const Asura_Vector_3& xHead, const Asura_Vector_3& xTorso, const Asura_Vector_3& xFeet);

	bool					HasNewDestinationBeenSet				(void)												{return m_bNewDestinationSet;}
	void					NewDestinationProcessed					(void)												{m_bNewDestinationSet = false;}
	void					ResetLookAtSet							(void)												{m_bLookAtSet = false;}
	bool					HasLookAtBeenSet						(void)												{return m_bLookAtSet;}
	const Asura_Vector_3&	GetDestination							(void)												{return m_xDestination;}
	const Asura_Vector_3&	GetHeadLookAt							(void)												{return m_xHeadLookAt;}
	const Asura_Vector_3&	GetTorsoLookAt							(void)												{return m_xTorsoLookAt;}

	void					SetReloadingWeapon						(bool bVal)											{m_bReloadingWeapon = bVal;}
	bool					IsReloadingWeapon						(void)												{return m_bReloadingWeapon;}
	bool					HasArrivedAtDestination					(void)												{return m_bHasArrivedAtDestination;}
	void					SetHasArrivedAtDestination				(bool bVal)											{m_bHasArrivedAtDestination = bVal;}
	bool					DidRouteFindFail						(void)												{return m_bRouteFindFailed;}
	void					SetRouteFindFail						(bool bVal)											{m_bRouteFindFailed = bVal;}
	void					SetMovementSpeed						(u_int uMoveSpeed)									{m_uMovementSpeed = uMoveSpeed;}
	u_int					GetMovementSpeed						(void)												{return m_uMovementSpeed;}
	void					LetRouteSetLookAt						(bool bVal)											{m_bLetRouteSetLookAt = bVal;}
	bool					DoesRouteSetLookAt						(void)												{return m_bLetRouteSetLookAt;}
	bool					IsInGrapple								(void)												{return m_bIsInGrapple;}
	void					SetIsInGrapple							(bool bVal)											{m_bIsInGrapple = bVal;}
	void					SetCurrentObjectiveGuid					(Asura_Guid uObjectiveGuid)							{m_uCurrentObjectiveGuid = uObjectiveGuid;}
	Asura_Guid				GetCurrentObjectiveGuid					(void)												{return m_uCurrentObjectiveGuid;}
	void					SetCurrentObjectiveType					(u_int uObjectiveType)								{m_uCurrentObjectiveType = uObjectiveType;}
	u_int					GetCurrentObjectiveType					(void)												{return m_uCurrentObjectiveType;}
	void					SetAtDestinationRange					(float fRange)										{m_fAtDestinationRange = fRange;}
	float					GetAtDestinationRange					(void)												{return m_fAtDestinationRange;}
	
	void								SetCurrentGamePlayVolume	(AVP_ServerEntity_GamePlayVolume* pxGPVolume)		{m_pxCurrentGamePlayVolume = pxGPVolume;}
	AVP_ServerEntity_GamePlayVolume*	GetCurrentGamePlayVolume	(void)												{return m_pxCurrentGamePlayVolume;}
	void								SetCoverPoint				(AVP_ServerNode_CoverpointNode* pxCoverpoint)		{m_pxCoverPoint = pxCoverpoint;}
	AVP_ServerNode_CoverpointNode*		GetCoverPoint				(void)												{return m_pxCoverPoint;}

	void								StopMoving					(void)												{m_bStopMovement = true;}
	void								CancelStopMoving			(void)												{m_bStopMovement = false;}
	bool								DoWeNeedToStopMoving		(void)												{return m_bStopMovement;}

	void								StopMovingWithDelay				(void)												{m_bStopMovementWithDelay = true;}
	void								CancelStopMovingWithDelay		(void)												{m_bStopMovementWithDelay = false;}
	bool								DoWeNeedToStopMovingWithDelay	(void)												{return m_bStopMovementWithDelay;}

	void								UseAcurateDistanceCheck			(bool bVal)											{m_bUseAccurateDistanceCheck = bVal;}
	bool								isUsingAcurateDistanceCheck		(void)												{return m_bUseAccurateDistanceCheck;}

	void								SetShouldMoveCrouched		(bool bVal)											{m_bShouldMoveCrouched = bVal;}
	bool								ShouldMoveCrouched			(void)												{return m_bShouldMoveCrouched;}

	bool								GetIsMemberAvailableForManuver(void)											{return m_bMemberAvailableForManuver;}
	void								SetIsMemberAvailableForManuver(bool bVal)										{m_bMemberAvailableForManuver = bVal;}

	bool								IsUsingCover(void)																{return m_bIsUsingCover;}
	void								SetIsUsingCover(bool bVal)														{m_bIsUsingCover = bVal;}

	bool								IsPerformingAction(void)														{return m_bIsPerformingAction;}
	void								SetIsPerformingAction(bool bVal)												{m_bIsPerformingAction = bVal;}

	void								OverrideSlowDownForThisDestination()											{m_bOverrideSlowdown = true;}
	void								DisableSlowdownOverride()														{m_bOverrideSlowdown = false;}
	bool								IsSlowdownOverridden()															{return m_bOverrideSlowdown;}

	void								SetIsOnGameScene(bool bVal)														{m_bIsOnGameScene = bVal;}
	bool								IsOnGameScene(void)																{return m_bIsOnGameScene;}

	void								SetStopShooting(bool bVal)														{m_bStopShooting = bVal;}
	bool								GetStopShooting(void)															{return m_bStopShooting;}

	void								SetAimLerpModifier(float fModifier)												{m_fAimLerpModifier = fModifier;}
	float								GetAimLerpModifier(void)														{return m_fAimLerpModifier;}

	void								UseExternalShooting( bool bVal )												{ m_bUseExternalShooting = bVal; }
	bool								IsUsingExternalShooting( void )													{ return m_bUseExternalShooting; }

	void								UpdateDestination( const Asura_Vector_3& xDest ) { m_xDestination = xDest; }

	bool								IsMoving(void)			{ return m_bIsMoving; }
	void								SetIsMoving(bool bVal)	{ m_bIsMoving = bVal; }

	bool								IsStartMovementDelayOverriden( void )		{ return m_bOverrideStartMovementDelay; }
	void								OverrideStartMovementDelay( void )			{ m_bOverrideStartMovementDelay = true; }
	void								CancelStartMovementDelayOverride( void )	{ m_bOverrideStartMovementDelay = false; }

	bool								GetForceAiming( void )			{ return m_bForceAiming; }
	void								SetForceAiming( bool bVal )		{ m_bForceAiming = bVal; }

	bool								IsWeightAdjustmentOverriden( void )				{ return m_bOverrideWeightAdjustment; }
	void								SetWeightAdjustmentOverride( bool bVal )		{ m_bOverrideWeightAdjustment = bVal; }

	bool								IsSpeedAdjustmentOverriden( void )				{ return m_bOverrideSpeedAdjustment; }
	void								SetSpeedAdjustmentOverride( bool bVal )			{ m_bOverrideSpeedAdjustment = bVal; }

	bool								GetResetShootTimers()							{ return m_uResetShootTimers; }
	void								SetResetShootTimers( bool bVal )				{ m_uResetShootTimers = bVal; }

	bool								IsOnCombatGS2() const							{ return m_bIsOnCombatGS2; }
	void								SetIsOnCombatGS2(bool bVal)						{ m_bIsOnCombatGS2 = bVal; }

	bool								ShouldStopAtDestination()						{ return m_bShouldStopAtDetsination; }
	void								SetShouldStopAtDestination(bool bVal)			{ m_bShouldStopAtDetsination = bVal; }

	bool								IsAllowedToReact( void ) const					{ return m_bIsAllowedToReact; }
	void								SetIsAllowedToReact( bool bVal )				{ m_bIsAllowedToReact = bVal; }

	bool								IsAlert(void)									{ return m_bIsAlert; }
	void								SetIsAlert(bool bVal)							{ m_bIsAlert = bVal; }

	bool								GetMessageForceAiming(void)						{ return m_bMessageForceAiming; }
	void								SetMessageForceAiming(bool bVal)				{ m_bMessageForceAiming = bVal; }

	

#ifndef ASURA_NO_DEBUG_OUTPUT
	virtual bool Verify() { return true; }
#endif

protected:

	Axon_Project_Brain*					m_pxBrain;


	union
	{
		u_int		m_uFlags;
		struct
		{
			u_int	m_bNewDestinationSet			: 1,			// 1
					m_bRouteFindFailed				: 1,			// 2
					m_bHasArrivedAtDestination		: 1,			// 3
					m_bLookAtSet					: 1,			// 4
					m_bReloadingWeapon				: 1,			// 5
					m_bLetRouteSetLookAt			: 1,			// 6
					m_bIsInGrapple					: 1,			// 7
					m_bStopMovement					: 1,			// 8
					m_bStopMovementWithDelay		: 1,			// 9
					m_bUseAccurateDistanceCheck		: 1,			// 10
					m_bShouldMoveCrouched			: 1,			// 11
					m_bIsUsingCover					: 1,			// 12
					m_bIsPerformingAction			: 1,			// 13
					m_bUseExternalShooting			: 1,			// 14
					m_bIsMoving						: 1,			// 15
					m_bOverrideStartMovementDelay	: 1,			// 16
					m_bForceAiming					: 1,			// 17
					m_bOverrideWeightAdjustment		: 1,			// 18
					m_bOverrideSpeedAdjustment		: 1,			// 19
					m_uResetShootTimers				: 1,			// 20
					m_bMemberAvailableForManuver	: 1,			// 21
					m_bOverrideSlowdown				: 1,			// 22
					m_bIsOnGameScene				: 1,			// 23
					m_bStopShooting					: 1,			// 24
					m_bIsOnCombatGS2				: 1,			// 25
					m_bShouldStopAtDetsination		: 1,			// 26
					m_bIsAllowedToReact				: 1,			// 27
					m_bIsAlert						: 1,			// 28
					m_bMessageForceAiming			: 1,			// 29

													: 0;
		};
	};

	float								m_fAtDestinationRange;
	Asura_Vector_3						m_xDestination;
	Asura_Vector_3						m_xTorsoLookAt;
	Asura_Vector_3						m_xHeadLookAt;
	AVP_ServerEntity_GamePlayVolume*	m_pxCurrentGamePlayVolume;
	AVP_ServerNode_CoverpointNode*		m_pxCoverPoint;
	u_int								m_uMovementSpeed;
	u_int								m_uCurrentObjectiveGuid;
	u_int								m_uCurrentObjectiveType;
	float								m_fAimLerpModifier;

private:
    enum { CURRENT_CHUNK_VERSION = 0 };
};

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

#endif //__AVP_TACTICAL_SYSTEM_H__
