//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose: MapOverview.cpp: implementation of the CHudOverview class.
//
// $NoKeywords: $
//=============================================================================//

#include "cbase.h"
#include "hl2wars/hud_rts_radar.h"
#include <vgui/isurface.h>
#include <vgui/ILocalize.h>
#include <filesystem.h>
#include <keyvalues.h>
#include <convar.h>
#include <mathlib/mathlib.h>
#include <game/client/iviewport.h>
#include <igameresources.h>
#include "gamevars_shared.h"
#include "spectatorgui.h"
#include "c_playerresource.h"
#include "Sprite.h"
#include "SpriteTrail.h"
#include "clientmode.h"
#include <vgui_controls/AnimationController.h>

#include "hl2wars/rts_shareddefs.h"
#include "hl2wars/c_hl2wars_player.h"
#include "hl2wars/hud_iconsvisuals.h"
#include "hl2wars/c_rts_buildings.h"
#include "hl2wars/c_rts_globalresource.h"

#include "hl2wars/map_bounderies.h"
#include "collisionutils.h"
#include "c_ai_basenpc.h"

class C_EnvRTSObjective;

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


using namespace vgui;

static ConVar radar("minimap", "1", 0, "toggles radar map image and icons...");
extern ConVar sv_fogofwar;

//add some lists
extern C_EnvRTSObjective *GetEnvRTSObjectiveList();
extern C_CapturePoint *GetCapturePointList();
extern C_BuildingBrush *GetBuildingBrushList();
extern C_BaseBuildingModel *GetBuildingModelList();
extern CMapBounderies *GetMapBounderiesList();

CHudMiniMap::CHudMiniMap( const char *pElementName ) : BaseClass( NULL, "Minimap" )
{
	Panel *pParent = g_pClientMode->GetViewport(); 

    SetParent( pParent );    
    
	SetProportional( true );
    SetVisible( true );//initially set our radar to visible even as a spectator 
	
	SetBounds( 0,0, 256, 256 );
	SetBgColor( Color( 0,0,0,128 ) );
	SetPaintBackgroundEnabled( false );
	ShowPanel( true );

	// Make sure we actually have the font...
	//vgui::IScheme *pScheme = vgui::scheme()->GetIScheme( GetScheme() );
	
	//m_hIconFont = pScheme->GetFont( "DefaultSmall" );
	
	m_nBackgroundTextureID = -1;
	m_nMapTextureID = -1;
	m_MapKeyValues = NULL;

	m_MapOrigin = Vector( 0, 0, 0 );
	m_fMapScale = 1.0f;
	m_bFollowAngle = false;
    SetMode( MAP_MODE_FULL );

	m_fZoom = 1.0f;
	m_MapCenter = Vector2D( 512, 512 );
	m_ViewOrigin = Vector2D( 512, 512 );
	m_fViewAngle = 0;

	m_flChangeSpeed = 1000;
	//m_flIconSize = 264.0f;

	//m_ObjectCounterID = 1;

	Reset();

	SetKeyBoardInputEnabled( false );	
	SetMouseInputEnabled( true );	

	SetScheme("ClientScheme.res");

	//m_nIcon = surface()->CreateNewTextureID(); 

	SetCursor( GetParent()->GetCursor() );
	
	//Q_memset( m_Players, 0, sizeof(m_Players) );

	//g_pMapOverview = this;  // for cvars access etc

	left_mouse_pressed = false;
	right_mouse_pressed = false;

	pObjectiveIcon = NULL;
	pBuildingIcon = NULL;

	SetZPos( -1 );

	Init();
}

void CHudMiniMap::ApplySchemeSettings(vgui::IScheme *scheme)
{
	BaseClass::ApplySchemeSettings( scheme );

	SetBgColor( Color( 0,0,0,128 ) );
	SetPaintBackgroundEnabled( false );

	//pObjectiveIcon = new CHudTexture();
	pObjectiveIcon = gHUD.GetIcon( "objective_icon" );
	m_clrObjectiveIcon = Color( 255, 255, 255, 255 );

	//pBuildingIcon = new CHudTexture();
	pBuildingIcon = gHUD.GetIcon( "building_icon" );
	//m_clrBuildingIcon = Color( 255, 255, 255, 255 );

	//pResourceIcon = new CHudTexture();
	pResourceIcon = gHUD.GetIcon( "resource_icon" );

	// load fow texture
	m_iFogOfWar = vgui::surface()->CreateNewTextureID(); 
	vgui::surface()->DrawSetTextureFile( m_iFogOfWar, "fow/fow" , true, false);
	m_iFOWSize = FOW_SIZE / FOW_TILESIZE;
	m_iFOWSizeWorldH = FOW_SIZE / 2;

	// load background texture
	m_nBackgroundTextureID = vgui::surface()->CreateNewTextureID(); 
	vgui::surface()->DrawSetTextureFile( m_nBackgroundTextureID, "VGUI/radar" , true, false);
}


void CHudMiniMap::Reset( void )
{
	m_fNextUpdateTime = 0;
}

void CHudMiniMap::Init( void )
{
	gameeventmanager->AddListener( this, "game_newmap", false );
}

/*bool CHudMiniMap::ShouldDraw( void )
{
	return CHudElement::ShouldDraw();
}*/

CHudMiniMap::~CHudMiniMap()
{
	if ( m_MapKeyValues )
		m_MapKeyValues->deleteThis();

	gameeventmanager->RemoveListener( this);
	//g_pMapOverview = NULL;

	//TODO release Textures ? clear lists
}

//-----------------------------------------------------------------------------
// Purpose: Game events
//-----------------------------------------------------------------------------
void CHudMiniMap::FireGameEvent( IGameEvent *event )
{
	const char * type = event->GetName();

	if ( Q_strcmp(type, "game_newmap") == 0 )
	{
		SetMap( event->GetString("mapname") );
		Reset();		// reset next update
	}
}

//finds our overview file we created earlier and loads it
void CHudMiniMap::SetMap(const char * levelname)
{	
	// Reset players and objects, even if the map is the same as the previous one
	m_MapUnits.RemoveAll();
	m_MapBounderies.RemoveAll();
	m_MapObjects.RemoveAll();

	// load new KeyValues
	if ( m_MapKeyValues && Q_strcmp( levelname, m_MapKeyValues->GetName() ) == 0 )
	{
		return;	// map didn't change
	}

	if ( m_MapKeyValues )
		m_MapKeyValues->deleteThis();

	m_MapKeyValues = new KeyValues( levelname );

	char tempfile[MAX_PATH];
	Q_snprintf( tempfile, sizeof( tempfile ), "resource/maps/%s.txt", levelname );
	
	if ( !m_MapKeyValues->LoadFromFile( filesystem, tempfile, "GAME" ) )
	{
		DevMsg( 1, "Error! CHudMinMap::SetMap: couldn't load file %s.\n", tempfile );
		m_nMapTextureID = -1;
		return;
	}

	// TODO release old texture ?

	m_nMapTextureID = surface()->CreateNewTextureID();

	//if we have not uploaded yet, lets go ahead and do so
	surface()->DrawSetTextureFile( m_nMapTextureID, m_MapKeyValues->GetString("material"), true, false);

	int wide, tall;

	surface()->DrawGetTextureSize( m_nMapTextureID, wide, tall );

	if ( wide != tall )
	{
		DevMsg( 1, "Error! CHudOverview::SetMap: map image must be a square.\n" );
		m_nMapTextureID = -1;
		return;
	}

	m_MapOrigin.x	= m_MapKeyValues->GetInt("pos_x");
	m_MapOrigin.y	= m_MapKeyValues->GetInt("pos_y");
	m_fMapScale		= m_MapKeyValues->GetFloat("scale",1.0f);
	m_bRotateMap	= m_MapKeyValues->GetInt("rotate")!=0;
	m_fFullZoom = m_fZoom = m_MapKeyValues->GetFloat("zoom", 1.0f );
}
void CHudMiniMap::ShowPanel(bool bShow)
{
	SetVisible( bShow );
}

void CHudMiniMap::OnThink( void )
{
	// in case the player wants to move to a position on the map
	GoToPanelPos();

	togglePrint(); 
 
	if ( NeedsUpdate() )
	{
		Update();
		m_fNextUpdateTime = gpGlobals->curtime + 0.2f; // update 5 times a second
	}
	
}

bool CHudMiniMap::NeedsUpdate( void )
{
	return m_fNextUpdateTime < gpGlobals->curtime;
}
void CHudMiniMap::Update( void )
{
	// update settings
	m_fWorldTime = gpGlobals->curtime;

	UpdateUnits();
	UpdateMapBounderies();
	UpdateMapObjects();
}

void CHudMiniMap::UpdateUnits()
{
	C_HL2Wars_Player *pPlayer = C_HL2Wars_Player::GetLocalHL2WarsPlayer();
	if ( !pPlayer )
		return;

	m_MapUnits.RemoveAll();
	for( int i = DEFAULT_TEAMS; i < MAX_TEAMS_ID_RTS + DEFAULT_TEAMS; i++ )
	{
		Vector colorvec = g_RTSR->GetColor255( i );
		Color color( colorvec.x, colorvec.y, colorvec.z );
		for( int j = 0; j <  g_RTSR->GetSize( i ); j++ )
		{
			C_AI_BaseNPC *pNPC = g_RTSR->GetUnit( i, j );
			if( !pNPC )
				continue;

			if( pNPC->IsVisibleFOW() ) 
			{
				MapUnit_t unit;
				unit.color = color;
				Vector2D pos2D = MapToPanel( WorldToMap( pNPC->GetAbsOrigin() ), false );
				unit.position = Vector( pos2D.x, pos2D.y, 0.0f);
				m_MapUnits.AddToTail(unit);
			}
			
		}
	}
}

void CHudMiniMap::UpdateMapBounderies()
{
	m_MapBounderies.RemoveAll();
	for( CMapBounderies *pEnt = GetMapBounderiesList(); pEnt != NULL; pEnt = pEnt->m_pNext )
	{
		Vector point1, point2, point3, point4;
		MapBounderies_t bounderies;
		Vector mins, maxs;
		pEnt->CollisionProp()->WorldSpaceAABB( &mins, &maxs );

		point1[2] = point2[2] = point3[2] = point4[2] = (pEnt->GetAbsOrigin())[2];

		point1[0] = mins[0];
		point1[1] = mins[1];
		point2[0] = mins[0];
		point2[1] = maxs[1];
		point3[0] = maxs[0];
		point3[1] = maxs[1];
		point4[0] = maxs[0];
		point4[1] = mins[1];

		Vector2D pos2D = MapToPanel( WorldToMap( point1 ), false );
		bounderies.points[0] = Vector( pos2D.x, pos2D.y, 0.0f);
		pos2D = MapToPanel( WorldToMap( point2 ), false );
		bounderies.points[1] = Vector( pos2D.x, pos2D.y, 0.0f);
		pos2D = MapToPanel( WorldToMap( point3 ), false );
		bounderies.points[2] = Vector( pos2D.x, pos2D.y, 0.0f);
		pos2D = MapToPanel( WorldToMap( point4 ), false );
		bounderies.points[3] = Vector( pos2D.x, pos2D.y, 0.0f);

		m_MapBounderies.AddToTail( bounderies );
	}
}

void CHudMiniMap::UpdateMapObjects()
{
	m_MapObjects.RemoveAll();

	for( C_BuildingBrush *pEnt = GetBuildingBrushList(); pEnt != NULL; pEnt = pEnt->m_pNext )
	{
		if( pEnt )
		{
			Vector color = g_RTSR->GetColor255( pEnt->GetOwnerShip() );

			MapObjects_t object;
			Vector2D pos2D = MapToPanel( WorldToMap( pEnt->GetAbsOrigin() ), false );
			object.position = Vector( pos2D.x, pos2D.y, 0.0f);
			object.color = Color( color.x, color.y, color.z, 255 );
			object.hsize = 8;
			object.type = OBJECT_BUILDING;
			m_MapObjects.AddToTail( object );
		}	
	}

	for( C_BaseBuildingModel *pEnt = GetBuildingModelList(); pEnt != NULL; pEnt = pEnt->m_pNext )
	{
		if( pEnt )
		{
			Vector color = g_RTSR->GetColor255( pEnt->GetOwnerShip() );

			MapObjects_t object;
			Vector2D pos2D = MapToPanel( WorldToMap( pEnt->GetAbsOrigin() ), false );
			object.position = Vector( pos2D.x, pos2D.y, 0.0f);
			object.color = Color( color.x, color.y, color.z, 255 );
			object.hsize = 8;
			object.type = OBJECT_BUILDING;
			//object.icon = STRING(pEnt->geticon)
			m_MapObjects.AddToTail( object );
		}	
	}

	for( C_CapturePoint *pEnt = GetCapturePointList(); pEnt != NULL; pEnt = pEnt->m_pNext )
	{
		if( pEnt )
		{
			Vector color = g_RTSR->GetColor255( pEnt->GetOwnerShip() );

			MapObjects_t object;
			Vector2D pos2D = MapToPanel( WorldToMap( pEnt->GetAbsOrigin() ), false );
			object.position = Vector( pos2D.x, pos2D.y, 0.0f);
			object.color = Color( color.x, color.y, color.z, 255 );
			object.hsize = 8;
			object.type = OBJECT_CP;
			m_MapObjects.AddToTail( object );
		}	
	}

	for( C_EnvRTSObjective *pEnt = GetEnvRTSObjectiveList(); pEnt != NULL; pEnt = pEnt->m_pNext )
	{
		if( pEnt )
		{
			MapObjects_t object;
			Vector2D pos2D = MapToPanel( WorldToMap( pEnt->GetAbsOrigin() ), false );
			object.position = Vector( pos2D.x, pos2D.y, 0.0f);
			object.color = Color( 255, 255, 255, 255 );
			object.hsize = 16;
			object.type = OBJECT_OBJ;
			m_MapObjects.AddToTail( object );
		}
	}
}

/*void CHudMiniMap::SetFollowEntity(int entindex)
{
	m_nFollowEntity = entindex;
}*/

void CHudMiniMap::SetMode(int mode)
{
	m_flChangeSpeed = 0; // change size instantly

	if ( mode == MAP_MODE_OFF )
	{
		ShowPanel( false );

		g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( "MapOff" );
	}
	
	else if ( mode == MAP_MODE_FULL )
	{
		if ( m_nMode != MAP_MODE_OFF )
			m_flChangeSpeed = 1000; // zoom effect

		/*C_BasePlayer *pPlayer = CBasePlayer::GetLocalPlayer();

		if ( pPlayer )  {//always follow the local player
            SetFollowEntity( pPlayer->entindex() );
		}*/

		ShowPanel( true );

		if ( mode != m_nMode )
		{
			g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( "MapZoomToLarge" );
		}

	}

	// finally set mode
	m_nMode = mode;
}

void CHudMiniMap::DrawBackground()
{
	if ( m_nBackgroundTextureID < 0 )
		return;

	surface()->DrawSetColor( 255,255,255, 255 );
	surface()->DrawSetTexture( m_nBackgroundTextureID );
	surface()->DrawTexturedRect( 0, 0, GetWide(), GetTall() );
}

void CHudMiniMap::DrawMapTexture( Vector2D *pointsvec )
{
	if ( m_nMapTextureID < 0 )
		return;
	
	Vertex_t points[4] =
	{
		//upper left 0,0
		Vertex_t( pointsvec[0], Vector2D(0,0) ),

		//UPPER RIGHT 1023, 0
		Vertex_t( pointsvec[1], Vector2D(1,0) ),

		//LOWER LEFT 1023, 1
		Vertex_t( pointsvec[2], Vector2D(1,1) ),

		Vertex_t( pointsvec[3], Vector2D(0,1) )
	};

	int alpha = 255.0f * .8; clamp( alpha, 1, 255 );
	
	surface()->DrawSetColor( 255,255,255, alpha );
	surface()->DrawSetTexture( m_nMapTextureID );
	surface()->DrawTexturedPolygon( 4, points );
}

void CHudMiniMap::DrawFOWTexture( Vector2D *pointsvec )
{
	if( !sv_fogofwar.GetBool() )
		return;

	if ( m_iFogOfWar < 0 )
		return;

	vgui::surface()->DrawSetTexture( m_iFogOfWar );
	vgui::surface()->DrawSetColor( 255, 255, 255, 255 );

	Vertex_t points[4] =
	{
		//upper left 0,0
		Vertex_t( pointsvec[0], Vector2D( 
				((MapToWorld( Vector2D( 0,0 ) ).x + m_iFOWSizeWorldH ) / FOW_TILESIZE) / m_iFOWSize, 
				((MapToWorld( Vector2D( 0,0 ) ).y + m_iFOWSizeWorldH ) / FOW_TILESIZE) / m_iFOWSize
				) ),

		//UPPER RIGHT 1023, 0
		Vertex_t( pointsvec[1], Vector2D(  
				((MapToWorld( Vector2D(OVERVIEW_MAP_SIZE-1,0) ).x + m_iFOWSizeWorldH ) / FOW_TILESIZE) / m_iFOWSize,
				((MapToWorld( Vector2D(OVERVIEW_MAP_SIZE-1,0) ).y + m_iFOWSizeWorldH ) / FOW_TILESIZE) / m_iFOWSize 
				) ),

		//LOWER LEFT 1023, 1
		Vertex_t( pointsvec[2], Vector2D(  
				((MapToWorld( Vector2D(OVERVIEW_MAP_SIZE-1,OVERVIEW_MAP_SIZE-1) ).x + m_iFOWSizeWorldH ) / FOW_TILESIZE) / m_iFOWSize,
				((MapToWorld( Vector2D(OVERVIEW_MAP_SIZE-1,OVERVIEW_MAP_SIZE-1) ).y + m_iFOWSizeWorldH ) / FOW_TILESIZE) / m_iFOWSize 
				) ), 

		Vertex_t( pointsvec[3], Vector2D(  
				((MapToWorld( Vector2D(0,OVERVIEW_MAP_SIZE-1) ).x + m_iFOWSizeWorldH ) / FOW_TILESIZE) / m_iFOWSize,
				((MapToWorld( Vector2D(0,OVERVIEW_MAP_SIZE-1) ).y + m_iFOWSizeWorldH ) / FOW_TILESIZE) / m_iFOWSize 
				) ), 
	};

	vgui::surface()->DrawTexturedPolygon( 4, points );
}

float CHudMiniMap::GetViewAngle( void )
{
	C_BasePlayer* pPlayer = C_BasePlayer::GetLocalPlayer();
	if( !pPlayer ) 
		return m_fLastViewAngle;

	m_fLastViewAngle = pPlayer->GetAbsAngles()[YAW] - 90.0f;
	return m_fLastViewAngle;
}

Vector2D CHudMiniMap::MapToPanel( const Vector2D &mappos, bool rotate )
{
	int pwidth, pheight; 
	Vector2D panelpos;
	float viewAngle = GetViewAngle();

	GetSize(pwidth, pheight);

	Vector offset;
	offset.x = mappos.x - m_MapCenter.x;
	offset.y = mappos.y - m_MapCenter.y;
	offset.z = 0;

	if( rotate )
		VectorYawRotate( offset, viewAngle, offset );

	// find the actual zoom from the animationvar m_fZoom and the map zoom scale
	float fScale = m_fZoom / OVERVIEW_MAP_SIZE;

	offset.x *= fScale;
	offset.y *= fScale;

	panelpos.x = (pwidth * 0.5f) + (pheight * offset.x);
	panelpos.y = (pheight * 0.5f) + (pheight * offset.y);

	return panelpos;
}

Vector2D CHudMiniMap::PanelToMap( Vector2D &panelpos )
{
	int pwidth, pheight; 
	Vector2D mappos;
	float viewAngle = -1.0f * GetViewAngle();

	GetSize(pwidth, pheight);

	Vector offset;

	offset.x = ( panelpos.x - ( pwidth * 0.5f ) ) / ( pheight );
	offset.y = ( panelpos.y - ( pheight * 0.5f ) ) / ( pheight );
	offset.z = 0.0f;

	float fScale = m_fZoom / OVERVIEW_MAP_SIZE;
	offset.x /= fScale;
	offset.y /= fScale;

	VectorYawRotate( offset, viewAngle, offset );

	mappos.x = offset.x + m_MapCenter.x;
	mappos.y = offset.y + m_MapCenter.y;

	return mappos;
}

void CHudMiniMap::Paint()
{
	Vector2D pointsvec[4];
	pointsvec[0] = MapToPanel ( Vector2D(0,0), true );
	pointsvec[1] = MapToPanel ( Vector2D(OVERVIEW_MAP_SIZE-1,0), true );
	pointsvec[2] = MapToPanel ( Vector2D(OVERVIEW_MAP_SIZE-1,OVERVIEW_MAP_SIZE-1), true );
	pointsvec[3] = MapToPanel ( Vector2D(0,OVERVIEW_MAP_SIZE-1), true ); 

	DrawBackground();
	DrawMapTexture( pointsvec );
	DrawFOWTexture( pointsvec );
	DrawPosPlayer();
	DrawUnits();
	DrawMapObjects();
	DrawMapBounderies();

	BaseClass::Paint();
	
}

float CHudMiniMap::GetZoom( void )
{
	return m_fZoom;
}

int CHudMiniMap::GetMode( void )
{
	return m_nMode;
}

void CHudMiniMap::SetData(KeyValues *data)
{
	m_fZoom = 1.00f;
	//m_nFollowEntity =  data->GetInt( "entity", m_nFollowEntity );
}

void CHudMiniMap::SetAngle(float angle)
{
	m_fViewAngle = angle;
}

Vector2D CHudMiniMap::WorldToMap( const Vector &worldpos )
{
	Vector2D offset( worldpos.x - m_MapOrigin.x, worldpos.y - m_MapOrigin.y);

	offset.x /=  m_fMapScale;
	offset.y /= -m_fMapScale;

	return offset;
}

Vector2D CHudMiniMap::MapToWorld( Vector2D &offset )
{
	offset.x *=  m_fMapScale;
	offset.y *= -m_fMapScale;

	Vector2D worldpos( offset.x + m_MapOrigin.x, offset.y + m_MapOrigin.y);

	return worldpos;
}

void CHudMiniMap::DrawPosPlayer( void ) 
{
	C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer();
	if ( !pPlayer )
		return;

	surface()->DrawSetColor( 255,0,0,255 );
	Vector2D center = MapToPanel( WorldToMap( pPlayer->GetAbsOrigin() ), true );
	surface()->DrawFilledRect( center.x-2, center.y-2, center.x+2, center.y+2);

}

void CHudMiniMap::DrawUnits( void )
{
	for( int i = 0; i < m_MapUnits.Count(); i++ )
	{
		Vector position;
		ApplyRotation(  &m_MapUnits.Element( i ).position, &position );
		surface()->DrawSetColor( m_MapUnits.Element( i ).color.r(), m_MapUnits.Element( i ).color.g(), 
			m_MapUnits.Element( i ).color.b(), 255 );
		surface()->DrawFilledRect( position.x-1, 
			position.y-1, 
			position.x+1, 
			position.y+1
		);
	}
}

void  CHudMiniMap::DrawMapObjects()
{
	for( int i = 0; i < m_MapObjects.Count(); i++ )
	{
		CHudTexture *pTex = NULL; 
		switch( m_MapObjects.Element( i ).type )
		{
		case OBJECT_BUILDING:
			pTex = pBuildingIcon;
			break;
		case OBJECT_CP:
			pTex = pResourceIcon;
			break;
		case OBJECT_OBJ:
			pTex = pObjectiveIcon;
			break;
		default:
			break;
		}

		if( !pTex )
			continue;

		Vector position;
		ApplyRotation(  &m_MapObjects.Element( i ).position, &position );

		pTex->DrawSelf( 
			position.x - m_MapObjects.Element( i ).hsize, 
			position.y - m_MapObjects.Element( i ).hsize, 
			m_MapObjects.Element( i ).hsize * 2, 
			m_MapObjects.Element( i ).hsize * 2, 
			m_MapObjects.Element( i ).color 
		);
	}
}

void CHudMiniMap::DrawMapBounderies()
{
	surface()->DrawSetColor( 0,0,255,200 );
	for( int i = 0; i < m_MapBounderies.Count(); i++ )
	{	
		Vector points[4];
		ApplyRotation( &m_MapBounderies.Element(i).points[0], &points[0] );
		ApplyRotation( &m_MapBounderies.Element(i).points[1], &points[1] );
		ApplyRotation( &m_MapBounderies.Element(i).points[2], &points[2] );
		ApplyRotation( &m_MapBounderies.Element(i).points[3], &points[3] );

		surface()->DrawLine( points[0].x, points[0].y, 
			points[1].x, points[1].y );
		surface()->DrawLine( points[1].x, points[1].y,
			points[2].x, points[2].y );
		surface()->DrawLine( points[2].x, points[2].y, 
			points[3].x, points[3].y );
		surface()->DrawLine( points[3].x, points[3].y, 
			points[0].x, points[0].y );
	}
}

void CHudMiniMap::ApplyRotation( Vector *in, Vector *out )
{
	Vector center = Vector( GetWide() / 2, GetTall() / 2, 0.0f );
	float viewAngle = GetViewAngle();
	VectorYawRotate( *in - center, viewAngle, *out );
	*out += center;
}

bool CHudMiniMap::IsInPanel(Vector2D &pos)
{
	int x,y,w,t;

	GetBounds( x,y,w,t );

	return ( pos.x >= 0 && pos.x < w && pos.y >= 0 && pos.y < t );
}

int CHudMiniMap::GetPixelOffset( float height )
{
	Vector2D pos2 = WorldToMap( Vector( height,0,0) );
	pos2 = MapToPanel( pos2, true );

	Vector2D pos3 = WorldToMap( Vector(0,0,0) );
	pos3 = MapToPanel( pos3, true  );

	int a = pos2.y-pos3.y; 
	int b = pos2.x-pos3.x;

	return (int)sqrt((float)(a*a+b*b)); // number of panel pixels for "scale" units in world
}
void CHudMiniMap::togglePrint() 
{ 
   if (!radar.GetBool()) 
      this->SetVisible(false); 
   else 
      this->SetVisible(true); 
}

// mouse listeners for the panel
void CHudMiniMap::OnCursorMoved(int x, int y)
{
	mouse_x_move = x;
	mouse_y_move = y;
}


//-----------------------------------------------------------------------------
// Purpose: Receive mouse input so we can set a new position for the player
//-----------------------------------------------------------------------------
void CHudMiniMap::OnMousePressed( MouseCode code )
{
	C_HL2Wars_Player *pPlayer = C_HL2Wars_Player::GetLocalHL2WarsPlayer();
	if( !pPlayer )
		return;

	switch( code ) {
		case MOUSE_LEFT:
			left_mouse_pressed = true;
			break;
		case MOUSE_RIGHT:
			right_mouse_pressed = true;
			break;
	}

	pPlayer->SetActivePanel( this );
}

//-----------------------------------------------------------------------------
// Purpose:  
//-----------------------------------------------------------------------------
void CHudMiniMap::OnMouseReleased(MouseCode code)
{
	C_HL2Wars_Player *pPlayer = C_HL2Wars_Player::GetLocalHL2WarsPlayer();
	if( !pPlayer )
		return;

	switch( code ) {
		case MOUSE_LEFT:
			left_mouse_pressed = false;
			break;
		case MOUSE_RIGHT:
			right_mouse_pressed = false;
			break;
	}

	pPlayer->SetActivePanel( NULL );
}

//-----------------------------------------------------------------------------
// Purpose:  
//-----------------------------------------------------------------------------
void CHudMiniMap::GoToPanelPos( )
{
	C_HL2Wars_Player *pPlayer = C_HL2Wars_Player::GetLocalHL2WarsPlayer();
	if( !pPlayer )
		return;

	if( left_mouse_pressed ) {
		Assert( mouse_x_move >= 0 && mouse_y_move >= 0 );
		Vector2D click = Vector2D( mouse_x_move, mouse_y_move );
		Vector2D world2d = MapToWorld( PanelToMap( click ) );
		Vector destination;
		destination[0] = world2d[0];
		destination[1] = world2d[1];
		destination[2] = pPlayer->GetAbsOrigin().z;

		if( IsValidPosition( destination ) )
		{
			//engine->ServerCmd( VarArgs( "hl2wars_newposition %f %f %f", destination.x, destination.y, destination.z ) );
			pPlayer->SetDirectMove(destination);
		}	
	}
}

bool CHudMiniMap::IsValidPosition( Vector position )
{
	bool valid = false;
	int counter = 0;
	for( CMapBounderies *pEnt = GetMapBounderiesList(); pEnt != NULL; pEnt = pEnt->m_pNext )
	{
		Vector vAbsMins, vAbsMaxs;
		pEnt->CollisionProp()->WorldSpaceAABB( &vAbsMins, &vAbsMaxs );
		//vAbsMins -= Vector( 1, 1, 1 );
		//vAbsMaxs += Vector( 1, 1, 1 );

		if( IsPointInBox( position, vAbsMins, vAbsMaxs ) )
			valid = true;

		counter++;
	}

	if( counter == 0 )
		return true;

	return valid;
}

/*void CHudMiniMap::UpdateFollowEntity()
{
	if ( m_nFollowEntity != 0 )
	{
		C_BaseEntity *ent = ClientEntityList().GetEnt( m_nFollowEntity );

		if ( ent )
		{
			//Vector position = MainViewOrigin();	// Use MainViewOrigin so SourceTV works in 3rd person
			QAngle angle = ent->EyeAngles();
			//Msg("Yaw %f \n", angle[YAW] );

			//if ( m_nFollowEntity <= MAX_PLAYERS )
			//{
			//	SetPlayerPositions( m_nFollowEntity-1, position, angle );
			//}

			SetAngle( angle[YAW] );
		}
	}
	else
	{
		SetAngle( 0 );
	}
}*/

