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

#include "cbase.h"
#include "hl2wars/util_hl2wars.h"
#include "ai_basenpc.h"
#include "hl2wars/rts_shareddefs.h"
#include "hl2wars/rts_point_order.h"
//#include "hl2wars/rts_buildings.h"
#include "hl2wars/rts_basebuilding.h"
//#include "hl2wars/rts_placabletank.h"
#include <KeyValues.h>

// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"

typedef CHandle<CAI_BaseNPC> BaseNPCHandle;

void UTIL_HudInfoText( CBasePlayer *pPlayer, const char *pMessageSource, const char *pMessage, float expire_time )
{
	CSingleUserRecipientFilter user( pPlayer );
	user.MakeReliable();
	UserMessageBegin( user, "InfoText" );
		WRITE_BYTE( 2 );	// two strings
		WRITE_STRING( pMessageSource );
		WRITE_STRING( pMessage );
		WRITE_FLOAT( expire_time );
	MessageEnd();
}

void UTIL_HudInfoText( const char *pMessageSource, const char *pMessage, int team_id, float expire_time )
{
	for ( int i = 1; i <= gpGlobals->maxClients; i++ )
	{
		CBasePlayer *pPlayer = (CBasePlayer*)UTIL_PlayerByIndex( i );
		if( !pPlayer )
			continue;

		if( pPlayer->GetTeamRTSID() == team_id )
		{
			UTIL_HudInfoText( pPlayer, pMessageSource, pMessage, expire_time );
		}
	}
}

void UTIL_HudStrategyText( CBasePlayer *pPlayer, const char *pMessage, int type )
{
	if( !pPlayer )
		return;

	CSingleUserRecipientFilter user( pPlayer );
	user.MakeReliable();
	UserMessageBegin( user, "StrategyText" );
		WRITE_BYTE( type );
		WRITE_STRING( pMessage );
	MessageEnd();
}

// --- order utils
bool UTIL_FindSpotForOrderInRadius( Vector *pResult, const Vector &vStartPos, float radius )
{
	QAngle fan;

	fan.x = 0;
	fan.z = 0;

	for( fan.y = 0; fan.y < 360 ; fan.y += 18.0 )
	{
		Vector vecTest;
		Vector vecDir;

		AngleVectors( fan, &vecDir );

		vecTest = vStartPos + vecDir * radius;

		trace_t tr;

		UTIL_TraceLine( vecTest, vecTest - Vector( 0, 0, 8192 ), MASK_SHOT, NULL, COLLISION_GROUP_NONE, &tr );
		if( tr.fraction == 1.0 )
		{
			continue;
		}

		if( !(UTIL_CheckForOrderInSphere( tr.endpos, 16.0f)) )
		{
			*pResult = tr.endpos;
			return true;
		}
	}
	return false;
}

bool UTIL_CheckForOrderInSphere( const Vector &vOrigin, float radius )
{
   	CBaseEntity *pList[512]; 
	int count = 0;

	count = UTIL_EntitiesInSphere( pList, 512, vOrigin, radius, 0 );

	for ( int i = 0; i < count; i++ ) 
    { 
      CBaseEntity *pEntity = dynamic_cast<CBaseEntity *>(pList[ i ]); 
      if( !stricmp(pEntity->GetClassname(), "rts_point_order") ) 
		  return true;
    } 

	return false;
}

CBaseBuildingModel *UTIL_PlaceBuilding( char *building, Vector position, QAngle angle, int teamid, bool constructed  )
{
	return UTIL_PlaceBuilding( LookupAbilityInfoSlot( building ), position, angle, teamid, constructed );
}

CBaseBuildingModel *UTIL_PlaceBuilding( ABILITY_FILE_INFO_HANDLE handle, Vector position, QAngle angle, int teamid, bool constructed )
{
	FileAbilityInfo_t *pFAI = GetFileAbilityInfoFromHandle( handle );
	if( !pFAI )
		return NULL;

	CBaseBuildingModel *pBuilding = dynamic_cast<CBaseBuildingModel *>(CreateEntityByName( pFAI->m_szBuildEntity ));
	if( !pBuilding )
		return NULL;

	pBuilding->SetName(MAKE_STRING(GetFileAbilityName(handle)));
	pBuilding->SetAbsOrigin( position + pFAI->m_vOffSet );
	pBuilding->SetAbsAngles( angle );
	pBuilding->SetModel( pFAI->m_szModel );
	pBuilding->SetOwnership( teamid );
	pBuilding->SetHealth( pFAI->m_flHealth );

	pBuilding->CreateComponents( pFAI->m_pComponentKeyValues );

	for ( KeyValues *sub = pFAI->m_pAbilityKeyValues->GetFirstSubKey(); sub != NULL ; sub = sub->GetNextKey() )
	{
		pBuilding->KeyValue( sub->GetName(), sub->GetString() );
	}

	DispatchSpawn(pBuilding);

	pBuilding->Activate();

	if( constructed )
		pBuilding->SetConstructionState(BS_CONSTRUCTED);
	else
		pBuilding->SetConstructionState( BS_PRECONSTRUCTION );

	return pBuilding;
}