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

#include "cbase.h"
#include "hud.h"
#include "hudelement.h"
#include "c_tf_player.h"
#include "iclientmode.h"
#include "ienginevgui.h"
#include <vgui/ILocalize.h>
#include <vgui/ISurface.h>
#include <vgui/IVGui.h>
#include <vgui_controls/Label.h>
#include <vgui_controls/EditablePanel.h>
#include "tf_imagepanel.h"
#include "tf_gamerules.h"
#include "c_tf_team.h"
#include "vgui/tf_controls.h"
#include <vgui_controls/TextEntry.h>
#include "vgui_controls/AnimationController.h"
#include "hud_basechat.h"
#include "clientmode_shared.h"
#include "c_playerresource.h"
#include "c_tf_playerresource.h"
#include "tf_hud_objectivestatus.h"
#include "c_team_objectiveresource.h"
#include "c_tf_team.h"
#include "tf_clientscoreboard.h"
#include "tf_playerpanel.h"
#include "tf_hud_tournament.h"
#include "c_tf_objective_resource.h"
#include "tf_time_panel.h"
#include "tf_hud_match_status.h"

#include "tf_gc_client.h"
#include "tf_lobby_server.h"

#include "inputsystem/iinputsystem.h"

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

void AddSubKeyNamed( KeyValues *pKeys, const char *pszName );

using namespace vgui;

#define TOURNAMENT_PANEL_UPDATE_INTERVAL 0.25f

extern ConVar mp_timelimit;
extern ConVar mp_winlimit;
extern ConVar mp_maxrounds;
extern ConVar mp_tournament;

class CHudChat;

DECLARE_HUDELEMENT( CHudTournament );

static const wchar_t* GetSCGlyph( const char* action )
{
	auto origin = g_pInputSystem->GetSteamControllerActionOrigin( action, GAME_ACTION_SET_FPSCONTROLS );
	return g_pInputSystem->GetSteamControllerFontCharacterForActionOrigin( origin );
}

//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
CHudTournament::CHudTournament( const char *pElementName ) : CHudElement( pElementName ), BaseClass( NULL, "HudTournament" )
{
	Panel *pParent = g_pClientMode->GetViewport();
	SetParent( pParent );

	SetHiddenBits( HIDEHUD_MISCSTATUS );

	vgui::ivgui()->AddTickSignal( GetVPanel(), 50 );

	for ( int i = 0; i < MAX_TEAMS; i++ )
	{
		m_bTeamReady[i] = false;
	}

	m_bReadyStatusMode = false;
	m_bCompetitiveMode = false;
	m_bReadyTextBlinking = false;
	m_bCountDownVisible = false;

	m_pPlayerPanelKVs = NULL;
	m_bReapplyPlayerPanelKVs = false;

	m_pScoreboard = NULL;

	m_pCountdownBG = new vgui::ScalableImagePanel( this, "CountdownBG" );
	m_pCountdownLabel = new CExLabel( this, "CountdownLabel", L"" );
	m_pCountdownLabelShadow = new CExLabel( this, "CountdownLabelShadow", L"" );
	m_pModeImage = new vgui::ImagePanel( this, "ModeImage" );
	m_pHudTournamentBG = new vgui::ScalableImagePanel( this, "HudTournamentBG" );
	m_pTournamentConditionLabel = new CExLabel( this, "TournamentConditionLabel", L"" );
}

//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
CHudTournament::~CHudTournament()
{
	if ( m_pPlayerPanelKVs )
	{
		m_pPlayerPanelKVs->deleteThis();
		m_pPlayerPanelKVs = NULL;
	}
}

//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CHudTournament::Init( void )
{
	// listen for events
	ListenForGameEvent( "tournament_stateupdate" );
	ListenForGameEvent( "teams_changed" );
	ListenForGameEvent( "localplayer_respawn" );
	ListenForGameEvent( "restart_timer_time" );
	ListenForGameEvent( "competitive_victory" );

	m_bShouldBeVisible = false;
	SetVisible( false );
	CHudElement::Init();
	m_flNextUpdate = gpGlobals->curtime;
}

//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CHudTournament::PlaySounds( int nTime )
{
	C_TFPlayer *pLocalPlayer = C_TFPlayer::GetLocalTFPlayer();

	if ( !pLocalPlayer )
		return;

	bool bCompetitiveMode = TFGameRules() && TFGameRules()->IsCompetitiveMode();

	switch( nTime )
	{
		case 60:
		{
			if ( bCompetitiveMode )
			{
				pLocalPlayer->EmitSound( "Announcer.CompGame1Begins60Seconds" );
			}
			break;
		}
		case 30:
		{
			if ( bCompetitiveMode )
			{
				pLocalPlayer->EmitSound( "Announcer.CompGame1Begins30Seconds" );
			}
			break;
		}
		case 10:
		{
			if ( TFGameRules() && TFGameRules()->IsMannVsMachineMode() )
			{
				if ( TFObjectiveResource()->GetMannVsMachineWaveCount() >= TFObjectiveResource()->GetMannVsMachineMaxWaveCount() )
				{
					pLocalPlayer->EmitSound( "Announcer.MVM_Final_Wave_Start" );
				}
				else if ( TFObjectiveResource()->GetMannVsMachineWaveCount() <= 1 )
				{
					if ( GTFGCClientSystem()->GetLobby() && IsMannUpGroup( GTFGCClientSystem()->GetLobby()->GetMatchGroup() ) )
					{
						pLocalPlayer->EmitSound( "Announcer.MVM_Manned_Up" );
					}
					else
					{
						pLocalPlayer->EmitSound( "Announcer.MVM_First_Wave_Start" );
					}
				}
				else
				{
					pLocalPlayer->EmitSound( "Announcer.MVM_Wave_Start" );
				}
			}
			else
			{
				pLocalPlayer->EmitSound( bCompetitiveMode ? "Announcer.CompGame1Begins10Seconds" : "Announcer.RoundBegins10Seconds" );
			}
			break;
		}
		case 9:
		{
			if ( TFGameRules() && TFGameRules()->IsMannVsMachineMode() )
			{
				int nMaxWaves = TFObjectiveResource()->GetMannVsMachineMaxWaveCount();
				int nCurWave = TFObjectiveResource()->GetMannVsMachineWaveCount();
				bool bHasTank = false;
				for ( int i = 0; i < MVM_CLASS_TYPES_PER_WAVE_MAX_NEW; ++i )
				{
	// 				int nClassCount = TFObjectiveResource()->GetMannVsMachineWaveClassCount( i );
 					const char *pchClassIconName = TFObjectiveResource()->GetMannVsMachineWaveClassName( i );
					if( V_stristr( pchClassIconName, "tank" ))
					{
						bHasTank = true;
					}
				}
				if( nCurWave == nMaxWaves )
				{
					pLocalPlayer->EmitSound( "music.mvm_start_last_wave" );	
				}
				else if( bHasTank )
				{
					pLocalPlayer->EmitSound( "music.mvm_start_tank_wave" );
				}
				else if( nCurWave > ( nMaxWaves / 2 ) )
				{
					pLocalPlayer->EmitSound( "music.mvm_start_mid_wave" );	
				}
				else
				{
					pLocalPlayer->EmitSound( "music.mvm_start_wave" );
				}
			}
			break;
		}
		case 5:
		{
			pLocalPlayer->EmitSound( bCompetitiveMode ? "Announcer.CompGameBegins05Seconds" : "Announcer.RoundBegins5Seconds" );
			break;
		}
		case 4:
		{
			pLocalPlayer->EmitSound( bCompetitiveMode ? "Announcer.CompGameBegins04Seconds" : "Announcer.RoundBegins4Seconds" );
			break;
		}
		case 3:
		{
			pLocalPlayer->EmitSound( bCompetitiveMode ? "Announcer.CompGameBegins03Seconds" : "Announcer.RoundBegins3Seconds" );
			break;
		}
		case 2:
		{
			pLocalPlayer->EmitSound( bCompetitiveMode ? "Announcer.CompGameBegins02Seconds" : "Announcer.RoundBegins2Seconds" );
			break;
		}
		case 1:
		{
			pLocalPlayer->EmitSound( bCompetitiveMode ? "Announcer.CompGameBegins01Seconds" : "Announcer.RoundBegins1Seconds" );
			break;
		}
	}
}

//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CHudTournament::PreparePanel( void )
{
	if ( m_flNextUpdate > gpGlobals->curtime )
		return;

	if ( !TFGameRules() )
		return;

	bool bSteamController = ::input->IsSteamControllerActive();
	bool bShowReadyHintIcon = false;

	if ( TFGameRules()->IsInPreMatch() )
	{
		bool bCountdownVisible = false;
		bool bAutoReady = false;
		const IMatchGroupDescription* pMatchDesc = GetMatchGroupDescription( TFGameRules()->GetCurrentMatchGroup() );
		if ( pMatchDesc )
		{
			bAutoReady = pMatchDesc->m_params.m_bAutoReady;
		}

		if ( !bAutoReady && ( TFGameRules()->IsWaitingForTeams() || TFGameRules()->GetRoundRestartTime() < 0 ) )
		{
			if ( m_bReadyStatusMode )
			{
				const char *pszLabelText;
				if ( TFGameRules() && TFGameRules()->PlayerReadyStatus_HaveMinPlayersToEnable() )
				{
					if ( bSteamController )
					{
						pszLabelText = "Tournament_Instructions_Ready_NoKeyHintText";
						bShowReadyHintIcon = true;
					}
					else
					{
						pszLabelText = "Tournament_Instructions_Ready";
					}
				}
				else
				{
					pszLabelText = "Tournament_Instructions_Waiting";
				}

				SetDialogVariable( "readylabel", g_pVGuiLocalize->Find( pszLabelText ) );
				SetDialogVariable( "tournamentstatelabel", g_pVGuiLocalize->Find( "Tournament_WaitingForTeam" ) );
				SetPlayerPanelsVisible( true );
				m_pModeImage->SetVisible( m_bCompetitiveMode );
			}
			else
			{
				SetDialogVariable( "readylabel", g_pVGuiLocalize->Find( "Tournament_Instructions" ) );
				SetDialogVariable( "tournamentstatelabel", g_pVGuiLocalize->Find( "Tournament_WaitingForTeams" ) );
				SetPlayerPanelsVisible( false );
				m_pModeImage->SetVisible( false );
			}
		}
		else
		{
			float flTime = TFGameRules()->GetRoundRestartTime() - gpGlobals->curtime;
			int nTime = (int)( ceil( flTime ) );
			
			wchar szCountdown[64];
			wchar_t wzVal[16];

			const char *szCountDown = m_bReadyStatusMode ? "Tournament_CountDownTime" : "Tournament_Countdown";
			const char *szCountDownSec = m_bReadyStatusMode ? "Tournament_CountDownTime" : "Tournament_Countdown_Sec";

			swprintf( wzVal, ARRAYSIZE( wzVal ), L"%d", nTime );
			wchar_t *pFormatString = g_pVGuiLocalize->Find( szCountDown );
			if ( nTime == 1 )
			{
				pFormatString = g_pVGuiLocalize->Find( szCountDownSec );
			}

			if ( pFormatString )
			{
				g_pVGuiLocalize->ConstructString_safe( szCountdown, pFormatString, 1, wzVal );
				SetDialogVariable( "tournamentstatelabel", szCountdown );
			}

			if ( bAutoReady )
			{
				SetDialogVariable( "readylabel", g_pVGuiLocalize->Find( "" ) );
				m_pModeImage->SetVisible( false );
				SetPlayerPanelsVisible( false );
			}
			else if ( nTime <= TOURNAMENT_NOCANCEL_TIME )
			{
				SetDialogVariable( "readylabel", g_pVGuiLocalize->Find( "" ) );
			}
			else
			{
				if ( m_bReadyStatusMode )
				{
					if ( bSteamController )
					{
						SetDialogVariable( "readylabel", g_pVGuiLocalize->Find( "Tournament_Instructions_Ready_NoKeyHintText" ) );
						bShowReadyHintIcon = true;
					}
					else
					{
						SetDialogVariable( "readylabel", g_pVGuiLocalize->Find( "Tournament_Instructions_Ready" ) );
					}
				}
				else
				{
					SetDialogVariable( "readylabel", g_pVGuiLocalize->Find( "" ) );
				}
			}

			if ( m_bReadyStatusMode && nTime >= 0 )
			{
				bCountdownVisible = true;
			}
		}

		// Show the Steam Controller hint icon if need be
		auto pReadyHintIcon = dynamic_cast< CExLabel* >( FindChildByName( "TournamentReadyHintIcon" ) );
		if ( pReadyHintIcon )
		{
			if ( bShowReadyHintIcon && !bAutoReady )
			{
				pReadyHintIcon->SetText( GetSCGlyph( "toggleready" ) );
				pReadyHintIcon->SetVisible( true );
				pReadyHintIcon->SetEnabled( true );
			}
			else
			{
				pReadyHintIcon->SetVisible( false );
				pReadyHintIcon->SetEnabled( false );
			}
		}

		if ( m_bCountDownVisible != bCountdownVisible )
		{
			m_bCountDownVisible = bCountdownVisible;

			if ( m_bCountDownVisible )
			{
				g_pClientMode->GetViewportAnimationController()->StartAnimationSequence(this, m_bCompetitiveMode ? "HudTournament_ShowTimerCompetitive" : "HudTournament_ShowTimerDefault", false);
			}
			else
			{
				g_pClientMode->GetViewportAnimationController()->StartAnimationSequence(this, "HudTournament_HideTimer", false);
			}
		}	
	}
	
#ifdef WIN32
#define STRING_FMT L"%s"
#else
#define STRING_FMT L"%S"	
#endif
	
	C_TFTeam *pBlueTeam = GetGlobalTFTeam( TF_TEAM_BLUE );
	SetDialogVariable( "bluenamelabel", pBlueTeam ? pBlueTeam->Get_Localized_Name() : L"BLU" );

	C_TFTeam *pRedTeam = GetGlobalTFTeam( TF_TEAM_RED );
	SetDialogVariable( "rednamelabel", pRedTeam ? pRedTeam->Get_Localized_Name() : L"RED" );

	SetDialogVariable( "bluestate", TFGameRules()->IsTeamReady( TF_TEAM_BLUE ) ? g_pVGuiLocalize->Find( "Tournament_TeamReady" ) : g_pVGuiLocalize->Find( "Tournament_TeamNotReady" ) );
	SetDialogVariable( "redstate", TFGameRules()->IsTeamReady( TF_TEAM_RED ) ? g_pVGuiLocalize->Find( "Tournament_TeamReady" ) : g_pVGuiLocalize->Find( "Tournament_TeamNotReady" ) );
	
	if ( m_bTeamReady[TF_TEAM_BLUE] != TFGameRules()->IsTeamReady( TF_TEAM_BLUE ) || m_bTeamReady[TF_TEAM_RED] != TFGameRules()->IsTeamReady( TF_TEAM_RED ) )
	{
		C_TFPlayer *pLocalPlayer = C_TFPlayer::GetLocalTFPlayer();

		if ( pLocalPlayer )
		{
			pLocalPlayer->EmitSound( "Hud.Hint" );
		}
	}

	m_bTeamReady[TF_TEAM_BLUE] = TFGameRules()->IsTeamReady( TF_TEAM_BLUE );
	m_bTeamReady[TF_TEAM_RED] = TFGameRules()->IsTeamReady( TF_TEAM_RED );

	wchar_t szWindConditions[1024];
	_snwprintf( szWindConditions, ARRAYSIZE( szWindConditions ), STRING_FMT, g_pVGuiLocalize->Find( "Tournament_WinConditions" ) );
	
	if ( mp_timelimit.GetInt() > 0 || mp_winlimit.GetInt() > 0 || mp_maxrounds.GetInt() )
	{
		bool bPrev = false;

		if ( mp_timelimit.GetInt() > 0 )
		{
			_snwprintf( szWindConditions, ARRAYSIZE( szWindConditions ), STRING_FMT L"%d " STRING_FMT, szWindConditions, mp_timelimit.GetInt(), mp_timelimit.GetInt() == 1 ? g_pVGuiLocalize->Find( "Tournament_WinConditionsMinute" ) : g_pVGuiLocalize->Find( "Tournament_WinConditionsMinutes" ) );
			bPrev = true;
		}

		if ( mp_winlimit.GetInt() > 0 )
		{
			if ( bPrev )
			{
#ifdef WIN32
				_snwprintf( szWindConditions, ARRAYSIZE( szWindConditions ), L"%s, ", szWindConditions );
#else
				_snwprintf( szWindConditions, ARRAYSIZE( szWindConditions ), L"%S, ", szWindConditions );
#endif
			}

			_snwprintf( szWindConditions, ARRAYSIZE( szWindConditions ), STRING_FMT L"%d " STRING_FMT, szWindConditions, mp_winlimit.GetInt(), mp_winlimit.GetInt() == 1 ? g_pVGuiLocalize->Find( "Tournament_WinConditionsWin" ) : g_pVGuiLocalize->Find( "Tournament_WinConditionsWins" ) );
			bPrev = true;
		}

		if ( mp_maxrounds.GetInt() > 0 )
		{
			if ( bPrev )
			{
				_snwprintf( szWindConditions, ARRAYSIZE( szWindConditions ), STRING_FMT L", ", szWindConditions );
			}

			_snwprintf( szWindConditions, ARRAYSIZE( szWindConditions ), STRING_FMT L"%d " STRING_FMT, szWindConditions, mp_maxrounds.GetInt(), mp_maxrounds.GetInt() == 1 ? g_pVGuiLocalize->Find( "Tournament_WinConditionsRound" ) : g_pVGuiLocalize->Find( "Tournament_WinConditionsRounds" ) );
		}
	}
	else
	{
		_snwprintf( szWindConditions, ARRAYSIZE( szWindConditions ), STRING_FMT STRING_FMT, szWindConditions, g_pVGuiLocalize->Find( "Tournament_WinConditionsNone" ) );
	}

	SetDialogVariable( "winconditions", szWindConditions );
}

//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CHudTournament::FireGameEvent( IGameEvent * event )
{
	const char *pEventName = event->GetName();
	CBaseHudChat *pHUDChat = (CBaseHudChat *)GET_HUDELEMENT( CHudChat );

	if ( Q_strcmp( "tournament_stateupdate", pEventName ) == 0 )
	{
		if ( !g_TF_PR )
			return;

		if ( !pHUDChat )
			return;

		wchar_t wszLocalized[100];

		bool bNameChange = event->GetBool( "namechange" );
		int iTeamState = event->GetInt( "readystate", -1 );
		int iIndex = event->GetInt("userid");

		const char *pszName = g_TF_PR->GetPlayerName( iIndex );
	
		wchar_t wszPlayerName[MAX_PLAYER_NAME_LENGTH];
		g_pVGuiLocalize->ConvertANSIToUnicode( pszName, wszPlayerName, sizeof(wszPlayerName) );

		if ( bNameChange )
		{
			wchar_t wszTeam[16];
			g_pVGuiLocalize->ConvertANSIToUnicode( event->GetString( "newname" ), wszTeam, sizeof(wszTeam) );
		
			g_pVGuiLocalize->ConstructString_safe( wszLocalized, g_pVGuiLocalize->Find( "#Tournament_TeamName_Change" ), 2, wszPlayerName, wszTeam );
		}
		else
		{
			g_pVGuiLocalize->ConstructString_safe( wszLocalized, g_pVGuiLocalize->Find( "#Tournament_ReadyState_Change" ), 2, wszPlayerName, iTeamState == 1 ? g_pVGuiLocalize->Find( "#Tournament_TeamReady" ) : g_pVGuiLocalize->Find( "#Tournament_TeamNotReady" ) );
		}

		char szLocalized[100];
		g_pVGuiLocalize->ConvertUnicodeToANSI( wszLocalized, szLocalized, sizeof(szLocalized) );

		pHUDChat->ChatPrintf( iIndex, CHAT_FILTER_NONE, "%s ", szLocalized );
	}
	else if ( Q_strcmp( "localplayer_respawn", pEventName ) == 0 )
	{
		if ( m_bReadyStatusMode )
		{
			if ( m_bReadyTextBlinking )
			{
				g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( "HudReadyPulse" );
			}
		}
	}
	else if ( FStrEq( "restart_timer_time", pEventName ) )
	{
		PlaySounds( event->GetInt( "time" ) );

		if ( TFGameRules()->GetRoundsPlayed() == 0 && m_bCompetitiveMode )
		{
			if ( event->GetInt( "time" ) == 10 )
			{
				g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( this, "HudTournament_MoveTimerDown", false );
				g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( "HudTournament_MoveChatWindow", false );
			}
		}
	}
	else if ( FStrEq( "competitive_victory", pEventName ) )
	{
		g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( this, "HudTournament_DoorsCloseEndRound", false );
	}
}

//-----------------------------------------------------------------------------
// Purpose: 
// Input  :  - 
//-----------------------------------------------------------------------------
void CHudTournament::OnTick( void )
{
	C_TFPlayer *pLocalPlayer = C_TFPlayer::GetLocalTFPlayer();

	if ( !pLocalPlayer )
		return;

	if ( TFGameRules() )
	{
		if ( TFGameRules()->IsInTournamentMode() )
		{
			if ( TFGameRules()->IsInWaitingForPlayers() && TFGameRules()->State_Get() != GR_STATE_GAME_OVER )
			{
				m_bShouldBeVisible = true;
				PreparePanel();

				if ( !TFGameRules()->IsInArenaMode() )
				{
					if ( !pLocalPlayer->IsAlive() )
					{
						m_bShouldBeVisible = false;
					}
				}
			}
			else
			{
				m_bShouldBeVisible = false;
			}

			if ( TFGameRules()->UsePlayerReadyStatusMode() )
			{
				if ( !m_bReadyStatusMode )
				{
					m_bReadyStatusMode = true;
					InvalidateLayout( false, true );
				}
			}
			else if ( m_bReadyStatusMode )
			{
				m_bReadyStatusMode = false;
				InvalidateLayout( false, true );
			}

			if ( TFGameRules()->IsCompetitiveMode() )
			{
				if ( !m_bCompetitiveMode )
				{
					m_bCompetitiveMode = true;
					InvalidateLayout( false, true );
				}
			}
			else if ( m_bCompetitiveMode )
			{
				m_bCompetitiveMode = false;
				InvalidateLayout( false, true );
			}
		}
		else
		{
			m_bShouldBeVisible = false;
		}

		if ( m_bReadyStatusMode )
		{
			const IMatchGroupDescription* pMatchDesc = GetMatchGroupDescription( TFGameRules()->GetCurrentMatchGroup() );
			if ( !pMatchDesc || !pMatchDesc->m_params.m_bAutoReady )
			{
				RecalculatePlayerPanels();

				// Ready text animation
				if ( !TFGameRules()->IsPlayerReady( GetLocalPlayerIndex() ) && !m_bReadyTextBlinking )
				{
					g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( "HudReadyPulse" );
					m_bReadyTextBlinking = true;
				}
				else if ( TFGameRules()->IsPlayerReady( GetLocalPlayerIndex() ) && m_bReadyTextBlinking )
				{
					g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( "HudReadyPulseEnd" );
					m_bReadyTextBlinking = false;
				}
			}

			if ( !m_pScoreboard.Get() && gViewPortInterface )
			{
				m_pScoreboard = (CTFClientScoreBoardDialog *)( gViewPortInterface->FindPanelByName( PANEL_SCOREBOARD ) );
			}

			if ( m_pScoreboard.Get() && m_pScoreboard->IsVisible() )
			{
				m_bShouldBeVisible = false;
			}
		}
	}
}

//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CHudTournament::LevelInit( void )
{
	m_bShouldBeVisible = false;
	SetVisible( false );
	Init();
}

//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CHudTournament::SetVisible( bool state )
{
	// we can only turn on tournament mode if we're in prematch
	if ( state )
	{
		if ( m_bReadyStatusMode )
		{
			if ( m_bReadyTextBlinking )
			{
				g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( "HudReadyPulse" );
			}
		}

		if ( TeamplayRoundBasedRules() && !TeamplayRoundBasedRules()->IsInPreMatch() )
			return;
	}

	BaseClass::SetVisible( state );
}

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

	m_bReapplyPlayerPanelKVs = true;

	KeyValues *pConditions = NULL;
	if ( TFGameRules() && TFGameRules()->IsMannVsMachineMode() )
	{
		pConditions = new KeyValues( "conditions" );
		AddSubKeyNamed( pConditions, "if_mvm" );
	}
	else if ( m_bCompetitiveMode )
	{
		pConditions = new KeyValues( "conditions" );
		AddSubKeyNamed( pConditions, "if_competitive" );
	}
	else if ( m_bReadyStatusMode )
	{
		pConditions = new KeyValues( "conditions" );
		AddSubKeyNamed( pConditions, "if_readymode" );
	}

	// load control settings...
	LoadControlSettings( "resource/UI/HudTournament.res", NULL, NULL, pConditions );

	if ( pConditions )
	{
		pConditions->deleteThis();
	}
}

//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CHudTournament::ApplySettings( KeyValues *inResourceData )
{
	BaseClass::ApplySettings( inResourceData );

	KeyValues *pItemKV = inResourceData->FindKey( "playerpanels_kv" );
	if ( pItemKV )
	{
		if ( m_pPlayerPanelKVs )
		{
			m_pPlayerPanelKVs->deleteThis();
		}
		m_pPlayerPanelKVs = new KeyValues("playerpanels_kv");
		pItemKV->CopySubkeys( m_pPlayerPanelKVs );
	}
}

//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CHudTournament::PerformLayout( void )
{
	BaseClass::PerformLayout();

	if ( m_bReapplyPlayerPanelKVs )
	{
		m_bReapplyPlayerPanelKVs = false;

		if ( m_pPlayerPanelKVs )
		{
			for ( int i = 0; i < m_PlayerPanels.Count(); i++ )
			{
				m_PlayerPanels[i]->ApplySettings( m_pPlayerPanelKVs );
				m_PlayerPanels[i]->InvalidateLayout( false, true );
			}
		}
	}

	bool bShowTournamentConditions = !m_bCompetitiveMode && TFGameRules() && !TFGameRules()->IsMannVsMachineMode();

	// Hide some elements when in competitive mode
	if ( m_pTournamentConditionLabel )
	{
		m_pTournamentConditionLabel->SetVisible( bShowTournamentConditions );
	}

	Panel* pTournamentBG = FindChildByName( "HudTournamentBG" );
	if ( pTournamentBG )
	{
		pTournamentBG->SetVisible( bShowTournamentConditions );
	}

	UpdatePlayerPanels();
}

//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CHudTournament::SetPlayerPanelsVisible( bool bVisible )
{
	for ( int i = 0; i < m_PlayerPanels.Count(); i++ )
	{
		if ( m_PlayerPanels[i] )
		{
			if ( m_PlayerPanels[i]->IsVisible() != bVisible )
			{
				m_PlayerPanels[i]->SetVisible( bVisible );
			}
		}
	}
}

//-----------------------------------------------------------------------------
// Purpose: Create a new panel if necessary
//-----------------------------------------------------------------------------
CTFPlayerPanel *CHudTournament::GetOrAddPanel( int iPanelIndex )
{
	if ( iPanelIndex < m_PlayerPanels.Count() )
	{
		return m_PlayerPanels[ iPanelIndex ];
	}
	Assert( iPanelIndex == m_PlayerPanels.Count() );
	CTFPlayerPanel *pPanel = new CTFPlayerPanel( this, VarArgs("playerpanel%d", iPanelIndex) );
	if ( m_pPlayerPanelKVs )
	{
		pPanel->ApplySettings( m_pPlayerPanelKVs );
		pPanel->InvalidateLayout( false, true );
	}
	m_PlayerPanels.AddToTail( pPanel );
	return pPanel;
}

//-----------------------------------------------------------------------------
// Purpose: Decide which players we will show
//-----------------------------------------------------------------------------
void CHudTournament::RecalculatePlayerPanels( void )
{
	C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer();
	if ( !pPlayer || !g_TF_PR )
		return;

	int iLocalTeam = g_TF_PR->GetTeam( pPlayer->entindex() );

	int iPanel = 0;
	for ( int i = 1; i <= MAX_PLAYERS; i++ )
	{
		if ( !g_TF_PR->IsConnected( i ) )
			continue;

		int iTeam = g_TF_PR->GetTeam( i );
		if ( iTeam == TEAM_UNASSIGNED && !m_bReadyStatusMode )
			continue;
			
		// Spectators see all players, team members only see their team.
		if ( TFGameRules() && TFGameRules()->IsMannVsMachineMode() && iTeam != iLocalTeam && iLocalTeam != TEAM_SPECTATOR )
			continue;

		if ( iTeam != TF_TEAM_RED && iTeam != TF_TEAM_BLUE )
			continue;

		// Add an entry for him
		CTFPlayerPanel *pPanel = GetOrAddPanel( iPanel );
		pPanel->SetPlayerIndex( i );
		++iPanel;
	}

	// Check if we have a lobby, then add in players that have a reservation in the lobby,
	// but aren't in the game yet

	// XXX(JohnS): Once eric's change to mirror the match info to playerresource is in, we should just trust that and
	//             not look at the lobby on our end. Eventually client lobbies shouldn't even have other members in
	//             them.
	CTFGSLobby *pLobby = GTFGCClientSystem()->GetLobby();
	if ( pLobby )
	{
		for ( int i = 0; i < pLobby->GetNumMembers(); ++i )
		{
			CSteamID steamID = pLobby->GetMember( i );

			// Already have a panel for him?
			bool bFound = false;
			for ( int j = 0; j < iPanel; ++j )
			{
				if ( m_PlayerPanels[j]->GetSteamID() == steamID )
				{
					bFound = true;
					break;
				}
			}
			if ( !bFound )
			{
				CTFPlayerPanel *pPanel = GetOrAddPanel( iPanel );
				pPanel->Setup( 0, steamID, pLobby->GetMemberDetails( i )->name().c_str(), pLobby->GetMemberDetails( steamID )->team() );
				++iPanel;
			}
		}
	}

	// Clear out any extra panels
	for ( int i = iPanel; i < m_PlayerPanels.Count(); i++  )
	{
		m_PlayerPanels[i]->SetPlayerIndex( 0 );
	}

	UpdatePlayerPanels();
}

//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CHudTournament::UpdatePlayerPanels( void )
{
	if ( !g_TF_PR )
		return;

	C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer();
	if ( !pPlayer )
		return;

	if ( !TFGameRules() )
		return;

	// Hide panels for players when they're no longer able to stop the countdown
	if ( TFGameRules()->GetRoundRestartTime() >= 0.f && TFGameRules()->GetRoundRestartTime() - gpGlobals->curtime <= TOURNAMENT_NOCANCEL_TIME )
	{
		SetPlayerPanelsVisible( false );
		m_pModeImage->SetVisible( false );

		return;
	}

	bool bNeedsPlayerLayout = false;
	for ( int i = 0; i < m_PlayerPanels.Count(); i++ )
	{
		if ( m_PlayerPanels[i]->Update() )
		{
			bNeedsPlayerLayout = true;
		}
	}

	if ( !bNeedsPlayerLayout || !TFGameRules() )
		return;

	// Try and always put the local player's team on team1, if he's in a team
	int iTeam1 = TF_TEAM_BLUE;
	int iTeam2 = TF_TEAM_RED;
	int iLocalTeam = g_TF_PR->GetTeam( pPlayer->entindex() );
	if ( ( iLocalTeam == TF_TEAM_RED || iLocalTeam == TF_TEAM_BLUE ) && !TFGameRules()->IsCompetitiveMode() )	// Blue always on left in comp
	{
		iTeam1 = iLocalTeam;
		iTeam2 = ( iTeam1 == TF_TEAM_BLUE ) ? TF_TEAM_RED : TF_TEAM_BLUE;
	}

	int iTeam1Count = g_TF_PR->GetNumPlayersForTeam( iTeam1, false );
	if ( GTFGCClientSystem()->GetLobby() )
	{
		// Everyone's on the same team in MvM, and any other lobby-based game is assumed to be two teams.
		iTeam1Count = TFGameRules()->IsMannVsMachineMode() ? 
					  GTFGCClientSystem()->GetLobby()->GetNumMembers() : 
					  GTFGCClientSystem()->GetLobby()->GetNumMembers()>>1;
	}
	int iTeam1Processed = 0;
	int iTeam2Processed = 0;
	int iCenter = GetWide() * 0.5;

	for ( int i = 0; i < m_PlayerPanels.Count(); i++ )
	{
		int iTeam = m_PlayerPanels[i]->GetTeam();

		if ( !m_PlayerPanels[i]->GetPlayerIndex() && iTeam == TEAM_INVALID )
			continue;

		int iXPos = ( m_bCompetitiveMode ) ? -XRES( 30 ) : 0;	// Hack to make space for the season image
		int iYPos = ( m_iTeam1PlayerBaseY + m_iTeam1PlayerDeltaY );
		int nOffset = ( m_bCompetitiveMode ) ? m_iTeamsPlayerDeltaXComp : m_iTeam2PlayerDeltaX;

		if ( iTeam == iTeam1 )
		{
			// Two teams.  First team left of center.
			if ( m_bReadyStatusMode && !TFGameRules()->IsMannVsMachineMode() )
			{
				int iTeam1LeftCorner = iCenter - ( iTeam1Count * nOffset );
				iXPos += ( iTeam1LeftCorner + ( iTeam1Processed * nOffset ) );
			}
			// One team.  Centered.
			else
			{
				int iTeam1LeftCorner = ( iCenter - ( iTeam1Count * nOffset ) * 0.5 );
				iXPos += ( iTeam1LeftCorner + ( iTeam1Processed * nOffset ) );
			}
			m_PlayerPanels[i]->SetSpecIndex( 6 - iTeam1Processed );
			++iTeam1Processed;
		}
		else if ( iTeam == iTeam2 )
		{
			// Two teams.  Second team right of center.
			iXPos = ( iCenter + ( iTeam2Processed * nOffset ) );
			iXPos += ( m_bCompetitiveMode ) ? XRES( 30 ) : 0;	// Hack to make space for the season image
			m_PlayerPanels[i]->SetSpecIndex( 7 + iTeam2Processed );
			++iTeam2Processed;
		}
		
		m_PlayerPanels[i]->SetPos( iXPos, iYPos );
	}
}

DECLARE_HUDELEMENT( CHudTournamentSetup );

bool TournamentHudElementKeyInput( int down, ButtonCode_t keynum, const char *pszCurrentBinding )
{
	CHudTournamentSetup *pTournamentPanel = ( CHudTournamentSetup * )GET_HUDELEMENT( CHudTournamentSetup );

	if ( pTournamentPanel && down == 1 )
	{
		return pTournamentPanel->ToggleState( keynum );
	}

	return false;
}

//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
CHudTournamentSetup::CHudTournamentSetup( const char *pElementName ) : CHudElement( pElementName ), BaseClass( NULL, "HudTournamentSetup" )
{
	Panel *pParent = g_pClientMode->GetViewport();
	SetParent( pParent );

	SetHiddenBits( HIDEHUD_MISCSTATUS );

	vgui::ivgui()->AddTickSignal( GetVPanel(), 100 );

	m_pNameEntry = new TextEntry(this, "TournamentNameEdit" );
	m_pEntryBG = new CTFImagePanel(this, "HudTournamentNameBG" );
	m_pReadyButton = new CExButton(this, "TournamentReadyButton", "" );
	m_pNotReadyButton = new CExButton(this, "TournamentNotReadyButton", "" );

	m_pTeamNameLabel = NULL;
	m_flNextThink = gpGlobals->curtime;
}

//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CHudTournamentSetup::Init( void )
{
	SetVisible( false );
	CHudElement::Init();

	DisableInput();
	
	m_pNameEntry->SetText( g_pVGuiLocalize->Find( "Tournament_TeamNameNotSet" ) );

	m_flNextThink = gpGlobals->curtime;
}

//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CHudTournamentSetup::OnCommand( const char *command )
{
	if ( !Q_strcmp( command, "teamready" ) )
	{
		char szText[64];
		m_pNameEntry->GetText( szText, sizeof( szText ) );

		char szTeamName[64];
		Q_snprintf ( szTeamName, sizeof( szTeamName ), "tournament_teamname %s", szText );
		engine->ClientCmd_Unrestricted( szTeamName );

		engine->ClientCmd_Unrestricted( "tournament_readystate 1" );
		DisableInput();
	}
	else if ( !Q_strcmp( command, "teamnotready" ) )
	{
		engine->ClientCmd_Unrestricted( "tournament_readystate 0" );
		DisableInput();
	}
}

//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
bool CHudTournamentSetup::ToggleState( ButtonCode_t code )
{
	if ( !IsVisible() )
		return false;

	if ( !g_TF_PR )
		return false;

	if ( code == KEY_F4 || code == STEAMCONTROLLER_F4 )
	{
		if ( TFGameRules() && TFGameRules()->UsePlayerReadyStatusMode() )
		{
			int nReady = ( TFGameRules()->IsPlayerReady( GetLocalPlayerIndex() ) ) ? 0 : 1;
			char szCommand[64];
			Q_snprintf( szCommand, sizeof( szCommand ), "tournament_player_readystate %d", nReady );
			engine->ClientCmd_Unrestricted( szCommand );
		}
		else
		{
			if ( IsMouseInputEnabled() )
			{
				DisableInput();
				return true;
			}
			else
			{
				EnableInput();
				return true;
			}
		}
	}

	if ( IsMouseInputEnabled() )
	{
		if ( code == KEY_ESCAPE || code == KEY_ENTER )
		{
			if ( code == KEY_ENTER )
			{
				char szText[64];
				m_pNameEntry->GetText( szText, sizeof( szText ) );

				char szTeamName[64];
				Q_snprintf ( szTeamName, sizeof( szTeamName ), "tournament_teamname %s", szText );
				engine->ClientCmd_Unrestricted( szTeamName );

				m_flNextThink = gpGlobals->curtime + TOURNAMENT_PANEL_UPDATE_INTERVAL;
			}

			DisableInput();
			return true;
		}
	}

	return false;
}

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

	if ( Q_strcmp( "tournament_stateupdate", pEventName ) == 0 )
	{
		if ( TFGameRules()->IsInTournamentMode() && TFGameRules()->IsInWaitingForPlayers() )
		{
			m_flNextThink = gpGlobals->curtime;
		}
	}
}

//-----------------------------------------------------------------------------
// Purpose: 
// Input  :  - 
//-----------------------------------------------------------------------------
void CHudTournamentSetup::OnTick( void )
{
	C_TFPlayer *pLocalPlayer = C_TFPlayer::GetLocalTFPlayer();
	if ( !pLocalPlayer )
		return;

	if ( !g_TF_PR )
		return;

	int iLocalTeam = g_TF_PR->GetTeam( pLocalPlayer->entindex() );
	if ( iLocalTeam <= LAST_SHARED_TEAM || TFGameRules()->State_Get() == GR_STATE_GAME_OVER )
	{
		SetVisible( false );
		return;
	}

	if ( TFGameRules() )
	{
		if ( TFGameRules()->UsePlayerReadyStatusMode() )
		{
			if ( TFGameRules()->IsInTournamentMode() && TFGameRules()->IsInWaitingForPlayers() )
			{
				if ( !IsVisible() )
				{
					SetVisible( true );
				}
				SetPos( 0, YRES( -100 ) ); // make sure the panel is WAY off the screen for MvM mode
			}
			else
			{
				if ( IsVisible() )
				{
					SetVisible( false );
				}
			}
		}
		else if ( TFGameRules()->IsInTournamentMode() && TFGameRules()->IsInWaitingForPlayers() )
		{
			if ( !IsVisible() )
			{
				SetVisible( true );
				g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( "HudTournamentSetupPanelClose" );
			}
		}
		else
		{
			if ( IsVisible() )
			{
				SetVisible( false );
			}
		}
	}

	if ( m_flNextThink <= gpGlobals->curtime )
	{
		if ( !IsMouseInputEnabled() )
		{
			m_pNameEntry->SetText( ( iLocalTeam == TF_TEAM_BLUE ) ? mp_tournament_blueteamname.GetString() : mp_tournament_redteamname.GetString() );
		}

		SetDialogVariable( "tournamentstatelabel", TFGameRules()->IsTeamReady( iLocalTeam ) ? g_pVGuiLocalize->Find( "Tournament_TeamSetupReady" ) : g_pVGuiLocalize->Find( "Tournament_TeamSetupNotReady" ) );

		m_flNextThink = gpGlobals->curtime + TOURNAMENT_PANEL_UPDATE_INTERVAL;
	}
}

//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CHudTournamentSetup::EnableInput( void )
{
	SetVisible( true );
	vgui::SETUP_PANEL( this );
	SetKeyBoardInputEnabled( true );
	SetMouseInputEnabled( true );
	m_pNameEntry->SetVisible( true );
	vgui::surface()->CalculateMouseVisible();
	m_pNameEntry->RequestFocus();
	m_pNameEntry->SetPaintBorderEnabled( true );
	m_pNameEntry->SetMouseInputEnabled( true );
	m_pNameEntry->SetKeyBoardInputEnabled( true );
	MakePopup();

	m_pEntryBG->SetVisible( true );
	m_pReadyButton->SetVisible( true );
	m_pReadyButton->SetMouseInputEnabled( true );
	m_pNotReadyButton->SetVisible( true );
	m_pNotReadyButton->SetMouseInputEnabled( true );

	m_pTeamNameLabel->SetVisible( true );

	engine->ClientCmd_Unrestricted( "gameui_preventescapetoshow\n" );

	g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( "HudTournamentSetupPanelOpen" );
}
//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CHudTournamentSetup::DisableInput( void )
{
	SetKeyBoardInputEnabled( false );
	SetMouseInputEnabled( false );

	m_pNameEntry->SetMouseInputEnabled( false );
	m_pNameEntry->SetKeyBoardInputEnabled( false );
	
	engine->ClientCmd_Unrestricted( "gameui_allowescapetoshow\n" );

	g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( "HudTournamentSetupPanelClose" );
}

//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CHudTournamentSetup::LevelInit( void )
{
	SetVisible( false );
	Init();
}

//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
bool CHudTournamentSetup::ShouldDraw( void )
{
	return ( IsVisible() );
}

//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CHudTournamentSetup::ApplySchemeSettings( IScheme *pScheme )
{
	// load control settings...
	LoadControlSettings( "resource/UI/HudTournamentSetup.res" );

	BaseClass::ApplySchemeSettings( pScheme );

	m_pNameEntry->SetFont( pScheme->GetFont( "HudFontSmallest", IsProportional() ) );
	m_pTeamNameLabel = dynamic_cast<Label *>( FindChildByName( "TournamentTeamNameLabel" ) );
}


DECLARE_HUDELEMENT( CHudStopWatch );

//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
CHudStopWatch::CHudStopWatch( const char *pElementName ) : CHudElement( pElementName ), BaseClass( NULL, "HudStopWatch" )
{
	Panel *pParent = g_pClientMode->GetViewport();
	SetParent( pParent );

	SetHiddenBits( HIDEHUD_MISCSTATUS );

	m_bShouldBeVisible = false;
	vgui::ivgui()->AddTickSignal( GetVPanel(), 100 );

	m_pTimePanel = new CTFHudTimeStatus( this, "ObjectiveStatusTimePanel" );
	m_pStopWatchLabel = new CExLabel( this, "StopWatchLabel", "" );
	m_pStopWatchScore = new CExLabel( this, "StopWatchScoreToBeat", "" );
	m_pStopWatchPointsLabel = new CExLabel( this, "StopWatchPointsLabel", "" );
	m_pStopWatchImage = new ImagePanel( this, "StopWatchImageCaptureTime" );
	m_pStopWatchDescriptionLabel = new CExLabel( this, "StopWatchDescriptionLabel", "" );

	ListenForGameEvent( "competitive_state_changed" );
}

//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
bool CHudStopWatch::ShouldDraw( void )
{ 
	bool bRetVal = m_bShouldBeVisible;
	if ( bRetVal )
	{
		// give the HUD a chance to turn us off when we should be hidden
		bRetVal = CHudElement::ShouldDraw();
	}
	
	return bRetVal; 
}

//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CHudStopWatch::LevelInit( void )
{
	m_bShouldBeVisible = true;
	
	if ( m_pTimePanel )
	{
		m_pTimePanel->SetVisible( true );
		m_pTimePanel->Reset();
	}

	m_pStopWatchLabel->SetVisible( false );
}

//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CHudStopWatch::ApplySchemeSettings( IScheme *pScheme )
{
	KeyValues *pConditions = NULL;
	if ( ShouldUseMatchHUD() )
	{
		pConditions = new KeyValues( "conditions" );
		AddSubKeyNamed( pConditions, "if_comp" );
	}

	// load control settings...
	LoadControlSettings( "resource/UI/HudStopWatch.res", NULL, NULL, pConditions );

	BaseClass::ApplySchemeSettings( pScheme );

	m_pStopWatchDescriptionBG = FindChildByName( "HudStopWatchDescriptionBG" );

	if ( pConditions )
	{
		pConditions->deleteThis();
	}
}

//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CHudStopWatch::OnTick( void )
{
	BaseClass::OnTick();

	if ( !TFGameRules() )
		return;

	C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer();

	if ( !pPlayer )
		return;

	bool bInFreezeCam = ( pPlayer && pPlayer->GetObserverMode() == OBS_MODE_FREEZECAM );

	bool bProperMatch = TFGameRules()->IsInTournamentMode() || TFGameRules()->IsCompetitiveMode();
	if ( !bProperMatch || TFGameRules()->IsInPreMatch() || !TFGameRules()->IsInStopWatch() || bInFreezeCam || TFGameRules()->State_Get() == GR_STATE_GAME_OVER  )
	{
		m_bShouldBeVisible = false;
		return;
	}
	else
	{
		m_bShouldBeVisible = true;
	}

	if ( m_pTimePanel && ObjectiveResource() )
	{
		int iActiveTimer = ObjectiveResource()->GetStopWatchTimer();
		m_pTimePanel->SetTimerIndex( iActiveTimer );

		C_TFTeam *pAttacker = NULL;
		C_TFTeam *pDefender = NULL;

		for ( int i = LAST_SHARED_TEAM+1; i < GetNumberOfTeams(); i++ )
		{
			C_TFTeam *pTeam = GetGlobalTFTeam( i );

			if ( pTeam )
			{
				if ( pTeam->GetRole() == TEAM_ROLE_DEFENDERS )
				{
					pDefender = pTeam;
				}

				if ( pTeam->GetRole() == TEAM_ROLE_ATTACKERS )
				{
					pAttacker = pTeam;
				}
			}
		}

		if ( !pAttacker || !pDefender )
			return;

		if ( TFGameRules()->GetStopWatchState() == STOPWATCH_CAPTURE_TIME_NOT_SET )
		{
			m_pTimePanel->SetVisible( false );
			m_pStopWatchLabel->SetVisible( true );
			m_pStopWatchScore->SetVisible( false );
			m_pStopWatchPointsLabel->SetVisible( false );
			m_pStopWatchDescriptionBG->SetVisible( false );
			m_pStopWatchDescriptionLabel->SetVisible( false );

			m_pStopWatchImage->SetImage( "../hud/ico_time_none" );

			SetDialogVariable( "stopwatchlabel", g_pVGuiLocalize->Find( "Tournament_StopWatchNoCap" ) );
		}
		else if ( TFGameRules()->GetStopWatchState() == STOPWATCH_RUNNING )
		{
			m_pTimePanel->SetVisible( true );
			m_pStopWatchLabel->SetVisible( false );
			m_pStopWatchScore->SetVisible( true );
			m_pStopWatchPointsLabel->SetVisible( true );

			m_pStopWatchImage->SetImage( "../hud/ico_time_10" );

			CTeamRoundTimer *pTimer = dynamic_cast< CTeamRoundTimer* >( ClientEntityList().GetEnt( iActiveTimer ) );

			int iPoints = 0;
		
			if ( pTimer )
			{
				if ( pTimer->IsWatchingTimeStamps() )
				{
					iPoints = pAttacker->Get_Score();
				}
				else
				{
					iPoints = pDefender->Get_Score() - pAttacker->Get_Score();
				}
			}

			wchar_t wzScoreVal[128];
			static wchar_t wzScore[128];
			wchar_t *pszPoints = NULL;
			_snwprintf( wzScoreVal, ARRAYSIZE( wzScoreVal ), L"%i", iPoints );

			if ( 1 == iPoints ) 
			{
				pszPoints = g_pVGuiLocalize->Find( "#Tournament_StopWatch_Point" );
			}
			else
			{
				pszPoints = g_pVGuiLocalize->Find( "#Tournament_StopWatch_Points" );
			}
			
			SetDialogVariable( "pointslabel", pszPoints );
			SetDialogVariable( "scoretobeat", wzScoreVal );

			wchar_t wzHelp[128];

			if ( pPlayer->GetTeam() == pAttacker )
			{
				g_pVGuiLocalize->ConstructString_safe( wzHelp, g_pVGuiLocalize->Find( "Tournament_StopWatch_TimeVictory" ), 1, pDefender->Get_Localized_Name() );
			}
			else
			{
				g_pVGuiLocalize->ConstructString_safe( wzHelp, g_pVGuiLocalize->Find( "Tournament_StopWatch_TimeVictoryDefender" ), 1, pDefender->Get_Localized_Name() );
			}

			SetDialogVariable( "descriptionlabel", wzHelp );

			if ( pTimer && !pTimer->IsWatchingTimeStamps() )
			{
				m_pStopWatchDescriptionBG->SetVisible( true );
				m_pStopWatchDescriptionLabel->SetVisible( true );
			}
			else
			{
				m_pStopWatchDescriptionBG->SetVisible( false );
				m_pStopWatchDescriptionLabel->SetVisible( false );
			}
		}
		else if ( TFGameRules()->GetStopWatchState() == STOPWATCH_OVERTIME )
		{
			m_pTimePanel->SetVisible( false );
			m_pStopWatchLabel->SetVisible( true );
			m_pStopWatchScore->SetVisible( false );
			m_pStopWatchPointsLabel->SetVisible( false );

			m_pStopWatchDescriptionBG->SetVisible( false );
			m_pStopWatchDescriptionLabel->SetVisible( false );

			SetDialogVariable( "descriptionlabel", g_pVGuiLocalize->Find( "#Tournament_StopWatch_CapVictory" ) );

			m_pStopWatchImage->SetImage( "../hud/ico_time_60" );

			wchar_t wzScoreVal[128];

			int iPoints = (pDefender->Get_Score() - pAttacker->Get_Score()) + 1;
			wchar_t wzVal[16];

			swprintf( wzVal, ARRAYSIZE( wzVal ), L"%x", iPoints );
			
			if ( pPlayer->GetTeam() == pAttacker )
			{
				g_pVGuiLocalize->ConstructString_safe( wzScoreVal, g_pVGuiLocalize->Find( "Tournament_StopWatchPointCaptureAttacker" ), 2, wzVal, iPoints == 1 ? g_pVGuiLocalize->Find( "#Tournament_StopWatch_Point" ) : g_pVGuiLocalize->Find( "#Tournament_StopWatch_Points" )  );
			}
			else if ( pPlayer->GetTeam() == pDefender )
			{
				g_pVGuiLocalize->ConstructString_safe( wzScoreVal, g_pVGuiLocalize->Find( "Tournament_StopWatchPointCaptureDefender" ), 2, wzVal, iPoints == 1 ? g_pVGuiLocalize->Find( "#Tournament_StopWatch_Point" ) : g_pVGuiLocalize->Find( "#Tournament_StopWatch_Points" )  );
			}
			else
			{
				g_pVGuiLocalize->ConstructString_safe( wzScoreVal, g_pVGuiLocalize->Find( "Tournament_StopWatchPointCaptureSpectator" ), 2, wzVal, iPoints == 1 ? g_pVGuiLocalize->Find( "#Tournament_StopWatch_Point" ) : g_pVGuiLocalize->Find( "#Tournament_StopWatch_Points" )  );
			}

			SetDialogVariable( "stopwatchlabel", wzScoreVal );	
		}
	}
}

void CHudStopWatch::FireGameEvent( IGameEvent * event )
{
	if ( FStrEq( event->GetName(), "competitive_state_changed" ) )
	{
		InvalidateLayout( false, true );
		return;
	}

	CHudElement::FireGameEvent( event );
}

//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
CON_COMMAND( player_ready_toggle, "Toggle player ready state" )
{
	C_TFPlayer *pPlayer = C_TFPlayer::GetLocalTFPlayer();
	if ( pPlayer )
	{
		CHudTournamentSetup *pTournamentPanel = dynamic_cast< CHudTournamentSetup* >( GET_HUDELEMENT( CHudTournamentSetup ) );
		if ( pTournamentPanel )
		{
			pTournamentPanel->ToggleState( KEY_F4 );
		}
	}
}