//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose: 
//
//=============================================================================//

#include "cbase.h"
#include "hudelement.h"
#include <vgui_controls/Panel.h>
#include <vgui_controls/Label.h>
#include <vgui/ISurface.h>
#include "c_baseplayer.h"
#include <vgui_controls/Panel.h>
#include "dod_gamerules.h"
#include "iclientmode.h"
#include "c_dod_objective_resource.h"
#include "c_dod_playerresource.h"
#include "c_dod_player.h"
#include "VGuiMatSurface/IMatSystemSurface.h"
#include "hud_macros.h"
#include <baseviewport.h>	//for IViewPortPanel
#include "spectatorgui.h"
#include "dod_round_timer.h"
#include "vgui_controls/AnimationController.h"
#include "dod_hud_freezepanel.h"

class CHudObjectiveIcons : public CHudElement, public vgui::Panel
{
public:
	DECLARE_CLASS_SIMPLE( CHudObjectiveIcons, vgui::Panel );

	CHudObjectiveIcons( const char *pName );
	
	virtual void ApplySchemeSettings( IScheme *scheme );
	virtual void Paint();
	virtual void Init();
	virtual void VidInit();
	virtual void Reset();

	virtual void FireGameEvent( IGameEvent *event );

	void DrawBackgroundBox( int xpos, int ypos, int nBoxWidth, int nBoxHeight, bool bCutCorner );

	virtual bool IsVisible( void );

private:

	vgui::Label	*m_pTimer;
	vgui::Label *m_pTimeAdded;

	CHudTexture *m_pIconDefended;

	int m_iCPTextures[8];
	int m_iCPCappingTextures[8];

	int m_iBackgroundTexture;
	Color m_clrBackground;
	Color m_clrBorder;

	int m_iLastCP;	// the index of the area we were last in

	CHudTexture *m_pC4Icon;
	CHudTexture *m_pExplodedIcon;
	CHudTexture *m_pC4PlantedBG;

	int m_iSecondsAdded;		// how many seconds were added in the last time_added event
	bool bInTimerWarningAnim;
	float m_flDrawTimeAddedUntil;

	CPanelAnimationVar( vgui::HFont, m_hTimerFont, "TimerFont", "Default" );
	CPanelAnimationVar( vgui::HFont, m_hTimerFontSmall, "TimerFontSmall", "DefaultSmall" );

	CPanelAnimationVar( vgui::HFont, m_hTextFont, "ChatFont", "Default" );

	CPanelAnimationVarAliasType( int, m_nIconSize, "iconsize", "24", "proportional_int" );
	CPanelAnimationVarAliasType( int, m_nSeparatorWidth, "separator_width", "7", "proportional_int" );
	CPanelAnimationVarAliasType( int, m_nCornerCutSize, "CornerCutSize", "5", "proportional_int" );
	CPanelAnimationVarAliasType( int, m_nBackgroundOverlap, "BackgroundOverlap", "5", "proportional_int" );

	CPanelAnimationVarAliasType( int, m_iIconStartX, "icon_start_x", "10", "proportional_int" );
	CPanelAnimationVarAliasType( int, m_iIconStartY, "icon_start_y", "10", "proportional_int" );
	CPanelAnimationVarAliasType( float, m_flIconExpand, "icon_expand", "0", "proportional_float" );

	CPanelAnimationVar( Color, m_clrTimer, "TimerBG", "255 0 0 128" );

	CPanelAnimationVarAliasType( int, m_nTimeAddedHeight, "time_added_height", "12", "proportional_int" );
	CPanelAnimationVar( float, m_flTimeAddedExpandPercent, "time_added_height_anim", "0.0" );
	CPanelAnimationVar( float, m_flTimeAddedAlpha, "time_added_alpha", "0" );

	CPanelAnimationVar( float, m_flTimeAddedDuration, "time_added_duration", "3.5" );
};

DECLARE_HUDELEMENT( CHudObjectiveIcons );

//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
CHudObjectiveIcons::CHudObjectiveIcons( const char *pName ) : vgui::Panel( NULL, "HudObjectiveIcons" ), CHudElement( pName )
{
	SetParent( g_pClientMode->GetViewport() );
	SetHiddenBits( 0 );

	m_pTimer = new vgui::Label( this, "HudObjectivesRoundTimer", " " );
	if ( m_pTimer )
	{
		m_pTimer->SetContentAlignment( Label::a_center );
	}

	m_pTimeAdded = new vgui::Label( this, "HudObjectivesTimeAdded", " " );
	if ( m_pTimeAdded )
	{
		m_pTimeAdded->SetContentAlignment( Label::a_center );
	}

	m_iBackgroundTexture = vgui::surface()->DrawGetTextureId( "vgui/white" );
	if ( m_iBackgroundTexture == -1 )
	{
		m_iBackgroundTexture = vgui::surface()->CreateNewTextureID();
	}
	vgui::surface()->DrawSetTextureFile( m_iBackgroundTexture, "vgui/white", true, true );

	m_iLastCP = -1;

	m_iSecondsAdded = 0;
	bInTimerWarningAnim = false;

	m_flDrawTimeAddedUntil = -1;
}

//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CHudObjectiveIcons::Init( void )
{
	for( int i = 0 ; i < 8 ; i++ )
	{
		m_iCPTextures[i] = vgui::surface()->CreateNewTextureID();
		m_iCPCappingTextures[i] = vgui::surface()->CreateNewTextureID();
	}

	ListenForGameEvent( "dod_timer_time_added" );
	ListenForGameEvent( "dod_timer_flash" );
}

void CHudObjectiveIcons::VidInit( void )
{
	m_flTimeAddedExpandPercent = 0.0;
	m_flTimeAddedAlpha = 0.0;
	m_flDrawTimeAddedUntil = -1;

	CHudElement::VidInit();
}

//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CHudObjectiveIcons::Reset( void )
{
	m_iLastCP = -1;
	m_flIconExpand = 0;
}

//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
bool CHudObjectiveIcons::IsVisible( void )
{
	if ( IsTakingAFreezecamScreenshot() )
		return false;

	return BaseClass::IsVisible();
}

//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CHudObjectiveIcons::FireGameEvent( IGameEvent *event )
{
	const char *eventname = event->GetName();

	if ( FStrEq( "dod_timer_time_added", eventname ) )
	{
		// show time added under the timer, flash
		m_iSecondsAdded = event->GetInt( "seconds_added" );

		g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( "TimerFlash" ); 

		g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( "ShowTimeAdded" ); 

		if ( !m_pTimeAdded->IsVisible() )
		{
			m_pTimeAdded->SetVisible( true );
		}

		wchar_t wText[12];

		int iSecondsToDraw = abs(m_iSecondsAdded);
		bool bNegative = ( m_iSecondsAdded < 0 );

#ifdef WIN32
		_snwprintf( wText, sizeof(wText)/sizeof(wchar_t), L"%s %d:%02d", bNegative ? L"-" : L"+", iSecondsToDraw / 60, iSecondsToDraw % 60 );
#else
		_snwprintf( wText, sizeof(wText)/sizeof(wchar_t), L"%S %d:%02d", bNegative ? L"-" : L"+", iSecondsToDraw / 60, iSecondsToDraw % 60 );
#endif

		m_pTimeAdded->SetText( wText );

		m_flDrawTimeAddedUntil = gpGlobals->curtime + m_flTimeAddedDuration;

	}
	else if ( FStrEq( "dod_timer_flash", eventname ) )
	{
		// generic flash, used for 5, 2, 1 minute warnings
		g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( "TimerFlash" ); 
	}
}

//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CHudObjectiveIcons::ApplySchemeSettings( IScheme *pScheme )
{
	BaseClass::ApplySchemeSettings( pScheme );

	m_hTextFont = pScheme->GetFont( "ChatFont" );
	m_hTimerFontSmall = pScheme->GetFont( "TimerFontSmall" );

	m_clrBackground = pScheme->GetColor( "HudPanelBackground", GetFgColor() );
	m_clrBorder = pScheme->GetColor( "HudPanelBorder", GetBgColor() );

	m_pC4Icon = gHUD.GetIcon( "icon_c4" );
	m_pExplodedIcon = gHUD.GetIcon( "icon_c4_exploded" );
	m_pC4PlantedBG = gHUD.GetIcon( "icon_c4_planted_bg" );
	m_pIconDefended = gHUD.GetIcon( "icon_defended" );

	m_pTimer->SetFont( m_hTimerFont );
	m_pTimeAdded->SetFont( m_hTimerFontSmall );
}

//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CHudObjectiveIcons::DrawBackgroundBox( int xpos, int ypos, int nBoxWidth, int nBoxHeight, bool bCutCorner )
{
	int nCornerCutSize = bCutCorner ? m_nCornerCutSize : 0;
	vgui::Vertex_t verts[5];

	verts[0].Init( Vector2D( xpos, ypos ) );
	verts[1].Init( Vector2D( xpos + nBoxWidth, ypos ) );
	verts[2].Init( Vector2D( xpos + nBoxWidth + 1, ypos + nBoxHeight - nCornerCutSize + 1 ) );
	verts[3].Init( Vector2D( xpos + nBoxWidth - nCornerCutSize + 1, ypos + nBoxHeight + 1 ) );
	verts[4].Init( Vector2D( xpos, ypos + nBoxHeight ) );

	vgui::surface()->DrawSetTexture( m_iBackgroundTexture );
	vgui::surface()->DrawSetColor( Color( m_clrBackground ) );
	vgui::surface()->DrawTexturedPolygon( 5, verts );

	vgui::Vertex_t borderverts[5];

	borderverts[0].Init( Vector2D( xpos, ypos ) );
	borderverts[1].Init( Vector2D( xpos + nBoxWidth, ypos ) );
	borderverts[2].Init( Vector2D( xpos + nBoxWidth, ypos + nBoxHeight - nCornerCutSize ) );
	borderverts[3].Init( Vector2D( xpos + nBoxWidth - nCornerCutSize, ypos + nBoxHeight ) );
	borderverts[4].Init( Vector2D( xpos, ypos + nBoxHeight ) );

	vgui::surface()->DrawSetColor( Color( m_clrBorder ) );
	vgui::surface()->DrawTexturedPolyLine( borderverts, 5 );
}

//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CHudObjectiveIcons::Paint()
{
	int ypos = m_iIconStartY;
	int xpos = m_iIconStartX;
	static Color clrIcon( 255, 255, 255, 255 );

	if( !g_pObjectiveResource )	// MATTTODO: hasn't been transmited yet .. fix ?
	{
		return;
	}

	// Hide the time added if it is time to do so
	if ( m_flDrawTimeAddedUntil > 0 && m_flDrawTimeAddedUntil < gpGlobals->curtime )
	{
		g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( "HideTimeAdded" ); 

		m_flDrawTimeAddedUntil = -1;
	}

	vgui::surface()->DrawSetTextFont( m_hTextFont );
	vgui::surface()->DrawSetColor( clrIcon );
	
	if ( g_pSpectatorGUI && g_pSpectatorGUI->IsVisible() )
	{
		ypos += g_pSpectatorGUI->GetTopBarHeight();
	}

	int num = g_pObjectiveResource->GetNumControlPoints();
	bool bShowTimer = ( g_DODRoundTimer != NULL );

	if ( num <= 0 && !bShowTimer )
	{
		if ( m_pTimer && m_pTimer->IsVisible() )
		{
			m_pTimer->SetVisible( false );
		}

		if ( m_pTimeAdded && m_pTimeAdded->IsVisible() )
		{
			m_pTimeAdded->SetVisible( false );
		}

		return; // nothing to draw yet
	}

	int iLastVisible = 0;

	int k;

	// let's count how many visible capture points we have (for cutting the corner of the last visible one)
	for( k = 0 ; k < num ; k++ )
	{
		if( g_pObjectiveResource->IsCPVisible( k ) )
		{
			iLastVisible = k;
		}
	}

	// do we have a round timer?
	if( bShowTimer )
	{
		if ( m_pTimer )
		{
			if ( !m_pTimer->IsVisible() )
			{
				m_pTimer->SetVisible( true );
			}

			m_pTimer->SetBounds( xpos, ypos, 2 * m_nIconSize, m_nIconSize );
			m_pTimer->SetBgColor( m_clrTimer );

			m_pTimeAdded->SetBounds( xpos, ypos + m_nIconSize, 2 * m_nIconSize, m_nTimeAddedHeight + m_nBackgroundOverlap );
			m_pTimeAdded->SetBgColor( Color(0,0,0,0) );

			int iRoundTime = (int)g_DODRoundTimer->GetTimeRemaining();

			int minutes = iRoundTime / 60;
			int seconds = iRoundTime % 60;

			if( minutes < 0 ) minutes = 0;
			if( minutes > 99 ) minutes = 99;
			if( seconds < 0 ) seconds = 0;

			// cut the corner if this is all we're drawing

			// figure out the height. will change if we're drawing the +1:00 below it
			int boxHeight = 2*m_nBackgroundOverlap + m_nIconSize + (int)( (float)m_nTimeAddedHeight * m_flTimeAddedExpandPercent );

			DrawBackgroundBox( xpos - m_nBackgroundOverlap, ypos - m_nBackgroundOverlap, m_pTimer->GetWide() + 2 * m_nBackgroundOverlap, boxHeight, ( num <= 0 ) ? true : false );

			// set the time
			char szTime[16];
			Q_snprintf( szTime, sizeof( szTime ), "%02d:%02d", minutes, seconds );
			m_pTimer->SetText( szTime );

			m_pTimeAdded->SetAlpha( (int)m_flTimeAddedAlpha );

			xpos += ( m_pTimer->GetWide() + m_nSeparatorWidth + m_nBackgroundOverlap * 2 );
		}
	}
	else
	{
		if ( m_pTimer && m_pTimer->IsVisible() )
		{
			m_pTimer->SetVisible( false );
		}
	}

	C_DODPlayer *pPlayer = C_DODPlayer::GetLocalDODPlayer();
	int iCurrentCapAreaIndex = pPlayer->GetCPIndex();

	if ( pPlayer->IsAlive() == false )
	{
		m_iLastCP = -1;
	}

	int index;

	for( index = 0 ; index < num ; index++ )
	{
		if( g_pObjectiveResource->IsCPVisible( index ) )
		{
			int iOwnerIcon = g_pObjectiveResource->GetCPCurrentOwnerIcon( index );

			float uv1 = 0.0f;
			float uv2 = 1.0f;

			float flXPos = (float)xpos;
			float flYPos = (float)ypos;
			float flIconSize = (float)m_nIconSize;

			if ( index == iCurrentCapAreaIndex )
			{
				// animate the current cp
				flXPos -= m_flIconExpand;
				flYPos -= m_flIconExpand;
				flIconSize += m_flIconExpand*2;

				m_iLastCP = iCurrentCapAreaIndex;
			}
			else if ( m_iLastCP == index )
			{
				// as a backup, animate out of the one we just left
				flXPos -= m_flIconExpand;
				flYPos -= m_flIconExpand;
				flIconSize += m_flIconExpand*2;
			}


			int iBombsRequired = g_pObjectiveResource->GetBombsRequired( index );

			if ( iBombsRequired > 0 )
			{
				DrawBackgroundBox( flXPos - m_nBackgroundOverlap, flYPos - m_nBackgroundOverlap, flIconSize + 2 * m_nBackgroundOverlap, flIconSize + 2 * m_nBackgroundOverlap + m_nTimeAddedHeight, ( index != iLastVisible ) ? false : true );
			}
			else
			{
				DrawBackgroundBox( flXPos - m_nBackgroundOverlap, flYPos - m_nBackgroundOverlap, flIconSize + 2 * m_nBackgroundOverlap, flIconSize + 2 * m_nBackgroundOverlap, ( index != iLastVisible ) ? false : true );
			}

			// Draw the background for the icon

			// allow for error
			if ( g_pObjectiveResource->IsBombSetAtPoint( index ) )
			{
				// if bomb timer is > 0, draw swipe
				float flBombTime = g_pObjectiveResource->GetBombTimeForPoint( index );	// round up

				// draw the 'white' version underneath
				int iBlankIcon = g_pObjectiveResource->GetCPTimerCapIcon( index );

				if ( iBlankIcon == 0 )
				{	
					iBlankIcon = g_pObjectiveResource->GetIconForTeam( index, TEAM_UNASSIGNED );
				}

				const char *szMatName = GetMaterialNameFromIndex( iBlankIcon );

				vgui::surface()->DrawSetTextureFile( m_iCPTextures[index], szMatName, true, false );

				Vector2D uv11( uv1, uv1 );
				Vector2D uv21( uv2, uv1 );
				Vector2D uv22( uv2, uv2 );
				Vector2D uv12( uv1, uv2 );

				vgui::Vertex_t vert[4];	
				vert[0].Init( Vector2D( flXPos,					flYPos               ), uv11 );
				vert[1].Init( Vector2D( flXPos + flIconSize,	flYPos               ), uv21 );
				vert[2].Init( Vector2D( flXPos + flIconSize,	flYPos + flIconSize ), uv22 );				
				vert[3].Init( Vector2D( flXPos,					flYPos + flIconSize ), uv12 );

				vgui::surface()->DrawSetColor( Color(255,255,255,255) );	
				vgui::surface()->DrawTexturedPolygon( 4, vert );
			
				// draw the real version in a circular swipe
				float flPercentRemaining = ( flBombTime / DOD_BOMB_TIMER_LENGTH );

				float flHalfWide = (float)flIconSize / 2.0f;
				float flHalfTall = (float)flIconSize / 2.0f;

				const float flCompleteCircle = ( 2.0f * M_PI );
				const float fl90degrees = flCompleteCircle * 0.25f;
				const float fl45degrees = fl90degrees * 0.5f;

				float flEndAngle = flCompleteCircle * flPercentRemaining; // clockwise

				typedef struct 
				{
					Vector2D vecTrailing;
					Vector2D vecLeading;
				} icon_quadrant_t;

				/*
				Quadrants are numbered 0 - 7 counter-clockwise
				_________________
				|	  0	| 7		|
				|		|		|
				|  1	|    6  |
				-----------------
				|  2	|	 5  |
				|		|		|
				|	  3	| 4		|
				-----------------
				*/

				// Encode the leading and trailing edge of each quadrant 
				// in the range 0.0 -> 1.0

				icon_quadrant_t quadrants[8];
				quadrants[0].vecTrailing.Init( 0.5, 0.0 );
				quadrants[0].vecLeading.Init( 0.0, 0.0 );

				quadrants[1].vecTrailing.Init( 0.0, 0.0 );
				quadrants[1].vecLeading.Init( 0.0, 0.5 );

				quadrants[2].vecTrailing.Init( 0.0, 0.5 );
				quadrants[2].vecLeading.Init( 0.0, 1.0 );

				quadrants[3].vecTrailing.Init( 0.0, 1.0 );
				quadrants[3].vecLeading.Init( 0.5, 1.0 );

				quadrants[4].vecTrailing.Init( 0.5, 1.0 );
				quadrants[4].vecLeading.Init( 1.0, 1.0 );

				quadrants[5].vecTrailing.Init( 1.0, 1.0 );
				quadrants[5].vecLeading.Init( 1.0, 0.5 );

				quadrants[6].vecTrailing.Init( 1.0, 0.5 );
				quadrants[6].vecLeading.Init( 1.0, 0.0 );

				quadrants[7].vecTrailing.Init( 1.0, 0.0 );
				quadrants[7].vecLeading.Init( 0.5, 0.0 );

				szMatName = GetMaterialNameFromIndex( iOwnerIcon );

				vgui::surface()->DrawSetTextureFile( m_iCPTextures[index], szMatName, true, false );
				vgui::surface()->DrawSetColor( Color(255,255,255,255) );	

				Vector2D uvMid( 0.5, 0.5 );
				Vector2D vecMid( flXPos + flHalfWide, flYPos + flHalfTall );

				int j;
				for ( j=0;j<=7;j++ )
				{
					float flMinAngle = j * fl45degrees;	

					float flAngle = clamp( flEndAngle - flMinAngle, 0, fl45degrees );

					if ( flAngle <= 0 )
					{
						// past our quadrant, draw nothing
						continue;
					}
					else
					{
						// draw our segment
						vgui::Vertex_t vert[3];	

						// vert 0 is mid ( 0.5, 0.5 )
						vert[0].Init( vecMid, uvMid );

						int xdir = 0, ydir = 0;

						switch( j )
						{
						case 0:  
						case 7:
							//right
							xdir = 1;
							ydir = 0;
							break;

						case 1: 
						case 2:
							//up
							xdir = 0;
							ydir = -1;
							break;

						case 3:
						case 4:
							//left
							xdir = -1;
							ydir = 0;
							break;

						case 5:
						case 6:
							//down
							xdir = 0;
							ydir = 1;
							break;
						}

						Vector2D vec1;
						Vector2D uv1;

						// vert 1 is the variable vert based on leading edge
						vec1.x = flXPos + quadrants[j].vecTrailing.x * flIconSize - xdir * tan(flAngle) * flHalfWide;
						vec1.y = flYPos + quadrants[j].vecTrailing.y * flIconSize - ydir * tan(flAngle) * flHalfTall;

						uv1.x = quadrants[j].vecTrailing.x - xdir * abs( quadrants[j].vecLeading.x - quadrants[j].vecTrailing.x ) * tan(flAngle);
						uv1.y = quadrants[j].vecTrailing.y - ydir * abs( quadrants[j].vecLeading.y - quadrants[j].vecTrailing.y ) * tan(flAngle);

						vert[1].Init( vec1, uv1 );

						// vert 2 is our trailing edge
						vert[2].Init( Vector2D( flXPos + quadrants[j].vecTrailing.x * flIconSize,
							flYPos + quadrants[j].vecTrailing.y * flIconSize ),
							quadrants[j].vecTrailing );

						vgui::surface()->DrawTexturedPolygon( 3, vert );					
					}	
				}

				if ( g_pObjectiveResource->IsBombBeingDefused( index ) )
				{
					float flSize = 0.75;
					int iconX = (int)( flXPos + flIconSize * ( ( 1.0 - flSize ) / 2 ) );
					int iconY = (int)( flYPos + flIconSize * ( ( 1.0 - flSize ) / 2 ) );
					int iconW = (int)( flIconSize * flSize );					

					Color c(255,255,255,255);
					m_pIconDefended->DrawSelf( iconX, iconY, iconW, iconW, c );
				}
			}
			else
			{
				// Draw the owner's icon
				if( iOwnerIcon != 0 )
				{
					const char *szMatName = GetMaterialNameFromIndex( iOwnerIcon );

					vgui::surface()->DrawSetTextureFile( m_iCPTextures[index], szMatName, true, false );
					
					/*
					// re-enable if we want to have animating cp icons
					// todo: framerate
					IVguiMatInfo *pMat = vgui::surface()->DrawGetTextureMatInfoFactory( m_iCPTextures[index] );

					if ( !pMat )
						return;

					int iNumFrames = pMat->GetNumAnimationFrames();

					IVguiMatInfoVar *m_pFrameVar;

					bool bFound = false;
					m_pFrameVar = pMat->FindVarFactory( "$frame", &bFound );

					static int frame = 0;

					if ( bFound )
					{
						frame++;
						m_pFrameVar->SetIntValue( frame % iNumFrames );
					}
					*/

					Vector2D uv11( uv1, uv1 );
					Vector2D uv21( uv2, uv1 );
					Vector2D uv22( uv2, uv2 );
					Vector2D uv12( uv1, uv2 );

					vgui::Vertex_t vert[4];	
					vert[0].Init( Vector2D( flXPos,					flYPos              ), uv11 );
					vert[1].Init( Vector2D( flXPos + flIconSize,	flYPos              ), uv21 );
					vert[2].Init( Vector2D( flXPos + flIconSize,	flYPos + flIconSize ), uv22 );				
					vert[3].Init( Vector2D( flXPos,					flYPos + flIconSize ), uv12 );

					vgui::surface()->DrawSetColor( Color(255,255,255,255) );	
					vgui::surface()->DrawTexturedPolygon( 4, vert );
				}		
			}
			
			// see if there are players in the area
			int iNumAllies = g_pObjectiveResource->GetNumPlayersInArea( index, TEAM_ALLIES );
			int iNumAxis = g_pObjectiveResource->GetNumPlayersInArea( index, TEAM_AXIS );

			int iCappingTeam = g_pObjectiveResource->GetCappingTeam( index );

			// Draw bomb icons under cap points
			if ( iBombsRequired > 0 )
			{
				int iBombsRemaining = g_pObjectiveResource->GetBombsRemaining( index );

				bool bBombPlanted = g_pObjectiveResource->IsBombSetAtPoint( index );

				int yIcon = ypos + flIconSize + YRES(2);

				int iIconHalfWidth = XRES(5);
				int iIconWidth = iIconHalfWidth * 2;

				Color c(255,255,255,255);

				switch( iBombsRequired )
				{
				case 1:
					{
						int xMid = xpos + ( flIconSize * 0.50f );

						switch( iBombsRemaining )
						{
						case 0:
							m_pExplodedIcon->DrawSelf( xMid - iIconHalfWidth, yIcon, iIconWidth, iIconWidth, c );
							break;
						case 1:
							if ( bBombPlanted )
							{
								// draw the background behind 1
								int alpha = (float)( abs( sin(2*gpGlobals->curtime) ) * 205.0 + 50.0 );
								m_pC4PlantedBG->DrawSelf( xMid - iIconWidth, yIcon - iIconHalfWidth, iIconWidth*2, iIconWidth*2, Color( 255,255,255,alpha) );
							}
							m_pC4Icon->DrawSelf( xMid - iIconHalfWidth, yIcon, iIconWidth, iIconWidth, c );
							break;
						}
					}
					break;
				case 2:
					{
						int xMid1 = xpos + ( flIconSize * 0.25f );
						int xMid2 = xpos + ( flIconSize * 0.75f );

						switch( iBombsRemaining )
						{
						case 0:
							m_pExplodedIcon->DrawSelf( xMid1 - iIconHalfWidth, yIcon, iIconWidth, iIconWidth, c );
							m_pExplodedIcon->DrawSelf( xMid2 - iIconHalfWidth, yIcon, iIconWidth, iIconWidth, c );
							break;
						case 1:
							if ( bBombPlanted )
							{
								// draw the background behind 1
								int alpha = (float)( abs( sin(2*gpGlobals->curtime) ) * 205.0 + 50.0 );
								m_pC4PlantedBG->DrawSelf( xMid1 - iIconWidth, yIcon - iIconHalfWidth, iIconWidth*2, iIconWidth*2, Color( 255,255,255,alpha) );
							}
							m_pC4Icon->DrawSelf( xMid1 - iIconHalfWidth, yIcon, iIconWidth, iIconWidth, c );
							m_pExplodedIcon->DrawSelf( xMid2 - iIconHalfWidth, yIcon, iIconWidth, iIconWidth, c );
							break;
						case 2:
							if ( bBombPlanted )
							{
								// draw the background behind 2
								int alpha = (float)( abs( sin(2*gpGlobals->curtime) ) * 205.0 + 50.0 );
								m_pC4PlantedBG->DrawSelf( xMid2 - iIconWidth, yIcon - iIconHalfWidth, iIconWidth*2, iIconWidth*2, Color( 255,255,255,alpha) );
							}
							m_pC4Icon->DrawSelf( xMid1 - iIconHalfWidth, yIcon, iIconWidth, iIconWidth, c );
							m_pC4Icon->DrawSelf( xMid2 - iIconHalfWidth, yIcon, iIconWidth, iIconWidth, c );
							break;
						}
					}
					break;
				default:
					{
						// general solution for > 2 bombs

						if ( iBombsRemaining > 0 )
						{
							// draw a bomb icon, then a 'x 3' for how many there are remaining

							if ( bBombPlanted )
							{
								// draw the background behind 2
								int alpha = (float)( abs( sin( 2*gpGlobals->curtime) ) * 205.0 + 50.0 );
								m_pC4PlantedBG->DrawSelf( xpos - iIconHalfWidth, yIcon - iIconHalfWidth, iIconWidth*2, iIconWidth*2, Color( 255,255,255,alpha) );
							}

							m_pC4Icon->DrawSelf( xpos, yIcon, iIconWidth, iIconWidth, c );

							// draw text saying how many bombs there are
							{
								wchar_t wText[6];
								_snwprintf( wText, sizeof(wText)/sizeof(wchar_t), L"x %d", iBombsRemaining );

								vgui::surface()->DrawSetTextColor( g_PR->GetTeamColor( TEAM_SPECTATOR ) );

								// set pos centered under icon
								vgui::surface()->DrawSetTextPos( xpos + ( flIconSize * 0.50f ), yIcon + YRES(2) );

								for ( wchar_t *wch = wText ; *wch != 0 ; wch++ )
								{
									vgui::surface()->DrawUnicodeChar( *wch );
								}
							}

						}
						else
						{
							int xMid = xpos + ( flIconSize * 0.50f );
							m_pExplodedIcon->DrawSelf( xMid - iIconHalfWidth, yIcon, iIconWidth, iIconWidth, c );
						}
					}
					break;
				}
			}

			// see if one team is partially capping,
			// should show a 1/2 under the cap icon
			if ( iCappingTeam == TEAM_UNASSIGNED )
			{
				if ( iNumAllies > 0 && iNumAxis == 0 )
				{
					iCappingTeam = TEAM_ALLIES;
				}
				else if ( iNumAxis > 0 && iNumAllies == 0 )
				{
					iCappingTeam = TEAM_AXIS;
				}

				if ( iCappingTeam == TEAM_UNASSIGNED || iCappingTeam == g_pObjectiveResource->GetOwningTeam( index ) )
				{
					// no team is capping, even partially
					// or the person in the area already owns it
					xpos += ( m_nIconSize + m_nSeparatorWidth + m_nBackgroundOverlap * 2 );
					continue;
				}
			}

			// Draw the number of cappers below the icon
			int numPlayers = g_pObjectiveResource->GetNumPlayersInArea( index, iCappingTeam );
			int requiredPlayers = g_pObjectiveResource->GetRequiredCappers( index, iCappingTeam );

			if ( requiredPlayers > 1 )
			{
				numPlayers = MIN( numPlayers, requiredPlayers );

				wchar_t wText[6];
				_snwprintf( wText, sizeof(wText)/sizeof(wchar_t), L"%d/%d", numPlayers, requiredPlayers );

				vgui::surface()->DrawSetTextColor( g_PR->GetTeamColor( iCappingTeam ) );

				// get string length
				int len = g_pMatSystemSurface->DrawTextLen( m_hTextFont, "2/2" );

				// set pos centered under icon
				vgui::surface()->DrawSetTextPos( xpos + ( m_nIconSize / 2.0f ) - ( len / 2 ), ypos + flIconSize + m_nBackgroundOverlap + YRES( 2 ) ); // + 2 to account for the outlined box

				for ( wchar_t *wch = wText ; *wch != 0 ; wch++ )
				{
					vgui::surface()->DrawUnicodeChar( *wch );
				}
			}

			if ( g_pObjectiveResource->GetCappingTeam( index ) != TEAM_UNASSIGNED )
			{
				int iCapperIcon = g_pObjectiveResource->GetCPCappingIcon( index );

				// Draw the capper's icon
				if( iOwnerIcon != iCapperIcon && iCapperIcon != 0 )
				{
					// axis caps swipe from right to left...allied from left to right
					bool bAxis = ( g_pObjectiveResource->GetCappingTeam(index) == TEAM_AXIS ) ? true : false;

					//swipe!
					float flCapPercentage = g_pObjectiveResource->GetCPCapPercentage(index);
					
					// reversing the direction of the swipe effect
					if ( bAxis )
					{
						flCapPercentage = 1.0f - g_pObjectiveResource->GetCPCapPercentage(index);
					}

					float width = ( flIconSize * flCapPercentage );
					const char *szCappingMatName = GetMaterialNameFromIndex( iCapperIcon );
					
					vgui::surface()->DrawSetTextureFile( m_iCPCappingTextures[index], szCappingMatName, true, false );

					vgui::Vertex_t vert[4];	

					Vector2D uv11( uv1, uv1 );
					Vector2D uv21( flCapPercentage, uv1 );
					Vector2D uv22( flCapPercentage, uv2 );
					Vector2D uv12( uv1, uv2 );

					// reversing the direction of the swipe effect
					if ( bAxis )
					{
						uv11.x = flCapPercentage;
						uv21.x = uv2;
						uv22.x = uv2;
						uv12.x = flCapPercentage;
					}

					Vector2D upperLeft ( flXPos,         flYPos );
					Vector2D upperRight( flXPos + width, flYPos );
					Vector2D lowerRight( flXPos + width, flYPos + flIconSize );
					Vector2D lowerLeft ( flXPos,		 flYPos + flIconSize );

					/// reversing the direction of the swipe effect
					if ( bAxis )
					{
						upperLeft.x  = flXPos + width;
						upperRight.x = flXPos + flIconSize;
						lowerRight.x = flXPos + flIconSize;
						lowerLeft.x  = flXPos + width;
					}
					
					vert[0].Init( upperLeft, uv11 );
					vert[1].Init( upperRight, uv21 );
					vert[2].Init( lowerRight, uv22 );				
					vert[3].Init( lowerLeft, uv12 );
							
					vgui::surface()->DrawSetColor( Color(255,255,255,255) );
					vgui::surface()->DrawTexturedPolygon( 4, vert );
				}
			}
			
			xpos += ( m_nIconSize + m_nSeparatorWidth + m_nBackgroundOverlap * 2 );
		}
	}
}