//////////////////////////////////////////////////////////////////////////////
//
// AVP_Knowledge_System_Actor.h
//
// Copyright (C) 2007 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_KNOWLEDGE_SYSTEM_ACTOR_H__
#define __AVP_KNOWLEDGE_SYSTEM_ACTOR_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 "Knowledge/AVP_Knowledge_System.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 AVP_Brain_Actor;
class AVP_Sense_Vision;
class AVP_Sense_Hearing;
class AVP_Sense_MotionTracker;
struct KnowledgeSettings;

//////////////////////////////////////////////////////////////////////////////
//
// AVP_Knowledge_System_Actor
//
//////////////////////////////////////////////////////////////////////////////

class AVP_Knowledge_System_Actor : public AVP_Knowledge_System
{
    typedef AVP_Knowledge_System PARENT;

public:

	// This needs to match the one in AVP_ClientActor_Vertebrate
	enum AVP_AlertLevel
	{
		PASSIVE_ALERTNESS = 0,
		ACTIVE_ALERTNESS,
		AGGRESSIVE_ALERTNESS,
		MAX_ALERT_LEVELS,
	};
    
	AVP_Knowledge_System_Actor( AVP_Brain_Actor* pxBrain );
	~AVP_Knowledge_System_Actor();

#ifndef ASURA_NO_DEBUG_OUTPUT
	virtual bool Verify();
#endif
    virtual void ReadFromChunkStream			( Asura_Chunk_Stream& xStream );
    virtual void WriteToChunkStream				( Asura_Chunk_Stream& xStream ) const;
	virtual void Update							( const float fTimeslice );
	virtual void Initialise						( void );
	virtual void Shutdown						( void );
	virtual void InitialiseFromBlueprint		( const Asura_Blueprint& xBlueprint );
	virtual bool HandleMessage					( const Asura_Message* pxMessage );

	void UpdateBestKnowledge					( const float fTimeslice );
	void UpdateAlertLevel						( const float fTimeslice );
	static bool UpdatePlayerAlienAlertStatus	( void );

	void AddKnowledgeIfNeeded					( const Axon_Knowledge& xNewKnowledge );
	void AddAlertKnowledgeIfNeeded				( const Axon_Knowledge& xNewKnowledge );
	void DeleteCurrentAlertKnowledge			( const Asura_Guid uAlertGuid );
	void AddReconModeKnowledge					( void );
	void ResetReconKnowledge					( void );
	void ResetCorpseKnowledge					( void );


	void SetShootAtScriptedTarget				( bool bVal )	{ m_bShootAtScriptedTarget = bVal; }
	bool ShootAtScriptedTarget					( void )		{ return m_bShootAtScriptedTarget; }
	void SetScriptedTargetIsShootAtPoint		( bool bVal )	{ m_bScriptedTargetIsShootAtPoint = bVal; }
	bool ScriptedTargetIsShootAtPoint			( void )		{ return m_bScriptedTargetIsShootAtPoint; }
	void SetScriptedTarget(Asura_Guid uGuid);
	void UpdateScriptedTargetKnowledge( void );
	void StopAttackingScriptedTarget( void );

	bool EverBeenAggressive()					{ return m_bEverBeenAggressive; }

	float GetVisionRange();

	virtual Axon_Sense_Vision*			CreateVisionSense();
	virtual Axon_Sense_Hearing*			CreateHearingSense();
	virtual AVP_Sense_MotionTracker*	CreateMotionTrackerSense();
	virtual void						DestroyMotionTrackerSense( AVP_Sense_MotionTracker* pxSense );

	AVP_AlertLevel				GetAlertLevel				( void ) const						{ return m_eAlertLevel; }
	void						SetAlertLevel				( AVP_AlertLevel eAlertLevel )		{ m_eAlertLevel = eAlertLevel; }
    
    const Axon_Knowledge&		GetBestThreatKnowledge		( void ) const				        { return m_xBestThreatKnowledge; }
	const Axon_Knowledge&		GetBestAlertKnowledge		( void ) const				        { return m_xBestAlertKnowledge; }

	void						ResetAlertTimer				( void )							{ m_fAlertLevelTimer = 0.0f + Asura_Random::GetFloat(-0.5f, 0.5f); }
	float						GetAlertTimer				( void )							{ return m_fAlertLevelTimer;  }
	static float				GetActiveAlertTimOut		( void )							{ return s_fActiveToPassiveTime;  }
	static float				GetAggressiveAlertTimOut	( void )							{ return s_fAggressiveToActiveTime;  }


	u_int						GetNumSecondaryThreats		( void )							{ return m_uNumSecondaryThreats; }

	const Axon_Knowledge&		GetSecondaryThreatKnowledge	( u_int uThreatId )					{ return m_pxSecondaryThreatKnowledge[uThreatId]; }

	int							GetTargetPriority( Asura_Guid uThreatGuid );
	bool						SquadAlreadyHasThisTarget( u_int uNumThreats, Asura_Guid uThreatGuid );
	void						SetSquadTarget( Asura_Guid uThreatGuid );
	
	void						SetCloakedVisibleRangeSq(float fDistranceSq)					{ s_fVisibleCloakedRngSq = fDistranceSq; }
	float						GetCloakedVisibleRangeSq(void);
	
    AVP_Brain_Actor* GetActorBrain() const;

	void SetVisionFOV( const float fTanHorHalfFOV, const float fTanVertUpHalfFOV, const float fTanVertDownHalfFOV );

	void UpdateKnowledgeSettings( KnowledgeSettings* pxKnowledgeSettings );

	bool DoesHaveReconKnowledge() { return ( m_pxReconKnowledge != NULL ); }

#ifndef ASURA_NO_DEBUG_OUTPUT
	virtual void RenderDebugInfo();
#endif
	
protected:

	void BuildSecondaryThreatArray( u_int uNumEntries );

	// Strictly sounds from the actors enemies
	Axon_Knowledge      m_xBestThreatKnowledge;
	Axon_Knowledge*		m_pxReconKnowledge;
	Axon_Knowledge*		m_pxCorpseKnowledge;
	// store 4 secondary threats
	Axon_Knowledge*		m_pxSecondaryThreatKnowledge;
	u_int				m_uNumSecondaryThreats;
	// Threatening sounds from non-enemies, such as screaming, gunfire, etc
	Axon_Knowledge      m_xBestAlertKnowledge;
	AVP_AlertLevel		m_eAlertLevel;
	float				m_fAlertLevelTimer;
	bool				m_bShootAtScriptedTarget;
	bool				m_bScriptedTargetIsShootAtPoint;
	Axon_Knowledge*		m_pxScriptedTargetKnowledge;
	bool				m_bEverBeenAggressive;
	float				m_fReconResetTimer;
	float				m_fCorpseResetTimer;

	AVP_Sense_MotionTracker* m_pxMotionTracker;

	static float		s_fAggressiveToActiveTime;
	static float		s_fActiveToPassiveTime;
	static float		s_fVisibleCloakedRngSq;

private:

    enum { CURRENT_CHUNK_VERSION = 0 };
};

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

#endif //__AVP_KNOWLEDGE_SYSTEM_ACTOR_H__
