//========= Copyright © 1996-2005, Sander Corporation, All rights reserved. ============//
//
// Purpose: 
//
// $NoKeywords: $
//=============================================================================//

#ifndef CBUILDINGS_H
#define CBUILDINGS_H
#ifdef _WIN32
#pragma once
#endif

#include "hl2wars/rts_mouse_brush.h"
#include "hl2wars/rts_basebuilding.h"
#include "Sprite.h"

// FIXME: Creating an edict as build entry :s?
//class CUnitBuild : public CBaseEntity
struct unit_build_t
{
	//DECLARE_CLASS( CUnitBuild, CBaseEntity );
	//DECLARE_CLASS_NOBASE( CUnitBuild )

	int ability;
	int amount;
	int ai_group;
	//CUtlVector< int > ai_group;

	DECLARE_SIMPLE_DATADESC();

	/*unit_build_t() {}
	unit_build_t(const unit_build_t &)
	{
		ai_group = CUtlVector<int>(0, 0);
	}*/
};

// ##################################################################################
//	>> Building Brush implementation
//
// ##################################################################################
class CBuildingBrush : public CMouseRTSBrush
{
public:
	DECLARE_CLASS( CBuildingBrush, CMouseRTSBrush );

	DECLARE_SERVERCLASS();
	DECLARE_DATADESC();

	CBuildingBrush();
	~CBuildingBrush();

	virtual void Spawn( void );
	virtual void Precache();

	virtual void		OnRestore();

	virtual void OnClickLeft( CBasePlayer *pActivator );
	virtual void OnClickRight( CBasePlayer *pActivator );
	virtual void OnClickLeftDouble( CBasePlayer *pActivator );
	virtual void OnClickRightDouble( CBasePlayer *pActivator );

	virtual int GetBrushType( void ) { return MOUSEBRUSH_BUILDING; };
	virtual int GetOwnerShip( void ) { return m_iOwnerShip; };

	// build functions
	bool AddToQueue( int ability, int ai_group );
	bool RemoveFromQueue( int queue );
	void BuildThink( void );
	void SetRallyPoint( Vector rallypoint );
	virtual void SpawnNPC( unit_build_t buildunit );
	int GetTypeAbility( int i ) { return m_iTypesAbilities.Get( i ); }
	int CountQueue() { return m_pBuildQueue.Count(); }	// doesn't takes amounts of the queue entries in account

	int UpdateTransmitState()	// set transmit filter to transmit always
	{
		return SetTransmitState( FL_EDICT_ALWAYS );
	}
	
private:
	void InputChangeOwnerShip( inputdata_t &inputdata );
	void LoadBuildInfo( KeyValues *pBuildingKeyValues );

protected:
	string_t m_sBuildingData;

	CNetworkVar( int, m_iOwnerShip );	// which team owns this building?

	//CUtlVector< CHandle<CUnitBuild> > m_pBuildQueue;
	CUtlVector< unit_build_t > m_pBuildQueue;
	
	CUtlVector< float > m_pBuildQueueTimes;
	CNetworkArray( int, m_iTypesQueue, QUEUE_MAX );
	CNetworkArray( int, m_iQueueAmount, QUEUE_MAX );

	CNetworkVar( float, m_fBuildTime );
	CNetworkVar( float, m_fBuildTimeMax );
	bool m_bBuilding;		// are we building or can we get a new unit?

	string_t m_sOwnerShipIcon;
	CNetworkVector( m_vOwnerShipIconTarget );

	string_t m_sBuildTarget;
	//EHANDLE m_pBuildTarget;
	Vector m_vBuildTarget;
	QAngle m_vBuildAngle;

	string_t m_sRallyPoint;
	CNetworkVector(m_vRallyPoint);

	CNetworkArray( int, m_iTypesAbilities, MAXABILITIESSLOTS );

	EHANDLE m_hSprite;
};


// ##################################################################################
//	>> Building Model implementation
//
// ##################################################################################
class CBuildingModel : public CBaseBuildingModel
{
public:
	DECLARE_CLASS( CBuildingModel, CBaseBuildingModel );

	DECLARE_SERVERCLASS();
	DECLARE_DATADESC();

	CBuildingModel();
	~CBuildingModel();

	virtual void Spawn( void );
	virtual void Precache();

	void	UpdateOnRemove();

	virtual void		OnRestore();

	virtual bool KeyValue( const char *szKeyName, const char *szValue );

	virtual void OnClickLeft( CBasePlayer *pActivator );
	virtual void OnClickRight( CBasePlayer *pActivator );
	virtual void OnClickLeftDouble( CBasePlayer *pActivator );
	virtual void OnClickRightDouble( CBasePlayer *pActivator );

	// ---------------------------------------------------
	// Model building functions
	// ---------------------------------------------------
	void SetBuildData( string_t building_data );
	void SetBuildTarget( Vector build_target );
	void SetBuildAngle( QAngle build_angle );

	// ---------------------------------------------------
	// Build/recruit functions
	// ---------------------------------------------------
	virtual bool AddToQueue( int ability, int ai_group );
	virtual bool RemoveFromQueue( int queue );
	virtual void BuildThink( void );
	void OnSelectedRightClick( Vector position );
	virtual bool SpawnNPC( unit_build_t buildunit );
	int GetTypeAbility( int i ) { return m_iTypesAbilities.Get( i ); }
	int CountQueue() { return m_pBuildQueue.Count(); }	// doesn't takes amounts of the queue entries in account

	int UpdateTransmitState()	// set transmit filter to transmit always
	{
		return SetTransmitState( FL_EDICT_ALWAYS );
	}
	
private:
	void LoadBuildInfo( KeyValues *pBuildingKeyValues );

// -- Build data
protected:
	string_t m_sBuildingData;

	CUtlVector< unit_build_t > m_pBuildQueue;
	
	CUtlVector< float > m_pBuildQueueTimes;
	CNetworkArray( int, m_iTypesQueue, QUEUE_MAX );
	CNetworkArray( int, m_iQueueAmount, QUEUE_MAX );

	float m_fRetrySpawn;
	CNetworkVar( float, m_fBuildTime );
	CNetworkVar( float, m_fBuildTimeMax );
	bool m_bBuilding;		// are we building or can we get a new unit?

	Vector m_vBuildTarget;
	QAngle m_vBuildAngle;
	CNetworkVector(m_vRallyPoint);

	CNetworkArray( int, m_iTypesAbilities, MAXABILITIESSLOTS );
};

// ##################################################################################
//	>> Building thumper. A placable version of the prop_thumper
//
// ##################################################################################
class CBuildingThumper : public CBaseBuildingModel
{
public:
	DECLARE_CLASS( CBuildingThumper, CBaseBuildingModel );
	DECLARE_DATADESC();

	virtual void Spawn( void );
	virtual void Precache( void );
	//virtual void Think ( void );
	virtual void BuildThink( void );
	virtual void HandleAnimEvent( animevent_t *pEvent );
	virtual void StopLoopingSounds( void );

	//void	InputDisable( inputdata_t &inputdata );
	//void	InputEnable( inputdata_t &inputdata );

	void	InitMotorSound( void );

	void	HandleState( void );

	void	Thump( void );

private:
	
	bool m_bEnabled;
	int m_iHammerAttachment;
	CSoundPatch* m_sndMotor;
	EHANDLE m_hRepellantEnt;
	int m_iDustScale;
};

// ##################################################################################
//	>> Building thumper. A placable version of the prop_thumper
//
// ##################################################################################
class CBuildingAntlionMaker : public CBuildingBrush
{
public:
	DECLARE_CLASS( CBuildingAntlionMaker, CBuildingBrush );

	void SpawnNPC( unit_build_t buildunit );
};

#endif // CBUILDINGS_H