//////////////////////////////////////////////////////////////////////////////
//
// AVP_ServerEntity_Team_Alien.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_SERVERENTITY_TEAM_ALIEN_H__
#define __AVP_SERVERENTITY_TEAM_ALIEN_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 "Core/Asura_List.h"

#include "Entity/Controller/AVP_ServerEntity_Team.h"

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

class Asura_Message;
struct AVP_AlienTeam_Knowledge;
class AVP_Brain_Team_Alien;
class AVP_Knowledge_System_AlienTeam;
class AVP_ServerEntity_AlienSpawnPoint;
class AVP_ServerEntity_GamePlayVolume;
class AVP_ServerEntity_Actor;

//////////////////////////////////////////////////////////////////////////////
//
// AVP_ServerEntity_AlienTeam
//
//////////////////////////////////////////////////////////////////////////////

class AVP_ServerEntity_Team_Alien : public AVP_ServerEntity_Team
{
    typedef AVP_ServerEntity_Team PARENT;

public:

	struct  LightInfo
	{
		Asura_Vector_3 m_xPosition;
		Asura_Vector_3 m_xSourcePosition;
		float m_fRadius;
		float m_fDistance;
		float m_fCutoffDistance;
		float m_fIntensity;
		enum { TORCH, MOVING_FLARE, IDLE_FLARE } m_eType;
	};


    AVP_ServerEntity_Team_Alien( Asura_Guid uGuid );
    virtual ~AVP_ServerEntity_Team_Alien();

    virtual void ReadFromChunkStream( Asura_Chunk_Stream& xStream );
    virtual void WriteToChunkStream( Asura_Chunk_Stream& xStream ) const;
	virtual void PostLoadInitialise();
    virtual bool HandleMessage( const Asura_Message* pxMessage );
	virtual void Update();

	AVP_Brain_Team_Alien* GetAlienTeamBrain() const;
	AVP_Knowledge_System_AlienTeam* GetKnowledgeSystem() const;

	// Send event message AVP_ENTITY_EVENT_ONALIENKILLED
	void OnAlienKilled();

	bool CanAttack( Asura_Guid uTargetGuid ) const;
	void AddAttacker( Asura_Guid uAttackerGuid, const Asura_Guid uTargetGuid );
	void RemoveAttacker( Asura_Guid uAttackerGuid, const Asura_Guid uTargetGuid );
	void AddTargeter( Asura_Guid uTargeterGuid, const Asura_Guid uTargetGuid );
	void RemoveTargeter( Asura_Guid uTargeterGuid, const Asura_Guid uTargetGuid );

	void AddAttackGrapple( Asura_Guid uTargetGuid );
	void AddAttackStand( Asura_Guid uTargetGuid );
	void AddAttackJump( Asura_Guid uTargetGuid );
	void RemoveAttackGrapple( Asura_Guid uTargetGuid );
	void RemoveAttackStand( Asura_Guid uTargetGuid );
	void RemoveAttackJump( Asura_Guid uTargetGuid );
	bool GetNumAttackers( Asura_Guid uTargetGuid, u_int& uAttackGrapple, u_int& uAttackStand, u_int& uAttackJump) const;
	bool DidTargetMovedRecently(Asura_Guid uTargetGuid) const;
	float TimeSinceLastGrapple(Asura_Guid uTargetGuid) const;


	bool CanBurstCrawl() const { return ( m_fBurstCrawlTimer <= 0.0f ); }
	void HaveBurstCrawled();
	bool CanHaltCrawl() const { return ( m_fHaltCrawlTimer <= 0.0f ); }
	void HaveHaltCrawled();

	u_int GetNumLights() const { return m_uNumLights; }
	const LightInfo& GetLightInfo( const u_int uIndex ) const { return m_axLightInfo[ uIndex ]; }

	u_int GetNumberOfChargers( const Asura_Guid uTargetGuid ) const;
	void AddCharger( const Asura_Guid uTargetGuid );
	void RemoveCharger( const Asura_Guid uTargetGuid );

	// FP threats are forward-predicted threats - threats that have their future position estimated so we can avoid them better.
	// This is done centrally here to avoid each separate Alien from re-doing the calculations.
	u_int GetNumFPThreats() const { return m_uNumFPThreats; }
	bool GetFPThreatData( const u_int uIndex, Asura_Vector_3& xInitialPosition, Asura_Vector_3& xFinalPosition ) const;

	// light change interface
	u_int GetLightGeneration() const { return m_uLightGeneration; }
	void LightChanged() { ++m_uLightGeneration; }	

	static AVP_ServerEntity_Team_Alien* Create( const Asura_Guid uGuid );
    static AVP_ServerEntity_Team_Alien* FindEntity( const Asura_Guid uGuid );
    static AVP_ServerEntity_Team_Alien* GetInstance() { return s_pxAlienTeam; }

private:
	void UpdateLights( const float fTimeslice );
	void UpdateFPThreats();

	// List of lights for the Aliens to avoid.
	enum { MAX_LIGHTS = 16 };
	float m_fFlareCheckTimer;
	u_int m_uNumLights;
	LightInfo m_axLightInfo[ MAX_LIGHTS ];
	u_int m_uLightGeneration;

	// List of FP threats for the Aliens to avoid.
	enum { MAX_FP_THREATS = 8 };
	u_int m_uNumFPThreats;
	struct FPThreatData
	{
		Asura_Guid m_uGuid;
		mutable u_int m_uLastFrameUpdated;
		// Position now.
		mutable Asura_Vector_3 m_xPosT;
		// Position in one second's time.
		mutable Asura_Vector_3 m_xPosTPlusOne;
	} m_axFPThreats[ MAX_FP_THREATS ];

	// Limit the frequency at which Aliens can attack.
	float m_fAttackTimer;
	float m_fAttackPeriod;

	float m_fBurstCrawlTimer;
	float m_fHaltCrawlTimer;

private:
    // Only one of these per level currently.
    static AVP_ServerEntity_Team_Alien* s_pxAlienTeam;

    enum { CURRENT_CHUNK_VERSION = 1 };
};

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

#endif //__AVP_SERVERENTITY_TEAM_ALIEN_H__
