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

#include "cbase.h"

#include "hud.h"
#include "tf_match_summary.h"
#include "tf_hud_statpanel.h"
#include "tf_spectatorgui.h"
#include "vgui_controls/AnimationController.h"
#include "iclientmode.h"
#include "engine/IEngineSound.h"
#include "c_tf_playerresource.h"
#include "c_team.h"
#include "tf_clientscoreboard.h"
#include <vgui_controls/Label.h>
#include <vgui_controls/ImagePanel.h>
#include <vgui/ILocalize.h>
#include <vgui/ISurface.h>
#include "vgui_avatarimage.h"
#include "fmtstr.h"
#include "teamplayroundbased_gamerules.h"
#include "tf_gamerules.h"
#include "tf_logic_halloween_2014.h"
#include "tf_playermodelpanel.h"
#include "tf_mapinfo.h"
#include "c_tf_team.h"
#include "tf_pvp_rank_panel.h"
#include "tf_badge_panel.h"
#include "tf_survey_questions.h"

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

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

#define MAX_PLAYER_MODELS	6

#define MS_STATE_TRANSITION_TO_STATS					17.0f
#define MS_STATE_TRANSITION_TO_MEDALS					3.0f
#define MS_STATE_TIME_BETWEEN_MEDALS					0.1f
#define MS_STATE_TIME_BETWEEN_MEDALS_CATEGORIES			0.1f

extern ConVar tf_scoreboard_alt_class_icons;

DECLARE_BUILD_FACTORY( TFSectionedListPanel );

DECLARE_HUDELEMENT( CTFMatchSummary );

#ifdef STAGING_ONLY
static void cc_tf_restart_match_summary()
{
	CTFMatchSummary *pMatchSummary = GET_HUDELEMENT( CTFMatchSummary );
	if (pMatchSummary)
	{
		pMatchSummary->InvalidateLayout(true, true);
		pMatchSummary->SetVisible( false );
		pMatchSummary->SetVisible( true );
	}
}
ConCommand tf_restart_match_summary("tf_restart_match_summary", cc_tf_restart_match_summary);
#endif

//-----------------------------------------------------------------------------
// Purpose: Constructor
//-----------------------------------------------------------------------------
CTFMatchSummary::CTFMatchSummary( const char *pElementName ) 
	: CHudElement( pElementName )
	, EditablePanel( NULL, "MatchSummary" )
	, m_bXPShown( false )
{
	vgui::Panel *pParent = g_pClientMode->GetViewport();
	SetParent( pParent );

	m_pMainStatsContainer = new EditablePanel( this, "MainStatsContainer" );
	m_pDrawingPanel = new CDrawingPanel( this, "DrawingPanel" );
	m_pStatsBgPanel = new EditablePanel( this, "StatsBgPanel" );

	m_pTeamScoresPanel = new EditablePanel( m_pMainStatsContainer, "TeamScoresPanel" );
	m_pParticlePanel = new CTFParticlePanel( m_pMainStatsContainer, "ParticlePanel" );
	m_pStatsLabelPanel = new EditablePanel( m_pMainStatsContainer, "StatsLabelPanel" );

	m_pBlueTeamPanel = new EditablePanel( m_pTeamScoresPanel, "BlueTeamPanel" );
	m_pRedTeamPanel = new EditablePanel( m_pTeamScoresPanel, "RedTeamPanel" );

	m_pPlayerListBlueParent = new EditablePanel( m_pBlueTeamPanel, "BluePlayerListParent" );
	m_pPlayerListBlue = new TFSectionedListPanel( m_pPlayerListBlueParent, "BluePlayerList" );
	m_pPlayerListRedParent = new EditablePanel( m_pRedTeamPanel, "RedPlayerListParent" );
	m_pPlayerListRed = new TFSectionedListPanel( m_pPlayerListRedParent, "RedPlayerList" );

	m_pBlueTeamScore = new CExLabel( m_pBlueTeamPanel, "BlueTeamScore", "" );
	m_pBlueTeamScoreDropshadow = new CExLabel( m_pBlueTeamPanel, "BlueTeamScoreDropshadow", "" );
	m_pBlueTeamScoreBG = new EditablePanel( m_pBlueTeamPanel, "BlueTeamScoreBG" );
	m_pBluePlayerListBG = new EditablePanel( m_pBlueTeamPanel, "BluePlayerListBG" );
	m_pRedTeamScore = new CExLabel( m_pRedTeamPanel, "RedTeamScore", "" );
	m_pRedTeamScoreDropshadow = new CExLabel( m_pRedTeamPanel, "RedTeamScoreDropshadow", "" );
	m_pRedTeamScoreBG = new EditablePanel( m_pRedTeamPanel, "RedTeamScoreBG" );
	m_pRedPlayerListBG = new EditablePanel( m_pRedTeamPanel, "RedPlayerListBG" );
	m_pBlueMedalsPanel = new EditablePanel( m_pTeamScoresPanel, "BlueMedals" );
	m_pRedMedalsPanel = new EditablePanel( m_pTeamScoresPanel, "RedMedals" );
	m_pRedTeamImage = new vgui::ImagePanel( m_pRedTeamPanel, "RedTeamImage" );
	m_pBlueTeamImage = new vgui::ImagePanel( m_pBlueTeamPanel, "BlueTeamImage" );
	m_pRedLeaderAvatarImage = new CAvatarImagePanel( m_pRedTeamPanel, "RedLeaderAvatar" );
	m_pBlueLeaderAvatarImage = new CAvatarImagePanel( m_pBlueTeamPanel, "BlueLeaderAvatar" );
	m_pRedLeaderAvatarBG = new EditablePanel( m_pRedTeamPanel, "RedLeaderAvatarBG" );
	m_pBlueLeaderAvatarBG = new EditablePanel( m_pBlueTeamPanel, "BlueLeaderAvatarBG" );
	m_pStatsAndMedals = new CExLabel( m_pStatsLabelPanel, "StatsAndMedals", "" );
	m_pStatsAndMedalsShadow = new CExLabel( m_pStatsLabelPanel, "StatsAndMedalsShadow", "" );
	m_pRedTeamName = new CExLabel( m_pRedTeamPanel, "RedTeamLabel", "" );
	m_pBlueTeamName = new CExLabel( m_pBlueTeamPanel, "BlueTeamLabel", "" );
	m_pRedTeamWinner = new CExLabel( m_pRedTeamPanel, "RedTeamWinner", "" );
	m_pRedTeamWinnerDropshadow = new CExLabel( m_pRedTeamPanel, "RedTeamWinnerDropshadow", "" );
	m_pBlueTeamWinner = new CExLabel( m_pBlueTeamPanel, "BlueTeamWinner", "" );
	m_pBlueTeamWinnerDropshadow = new CExLabel( m_pBlueTeamPanel, "BlueTeamWinnerDropshadow", "" );

	m_pImageList = NULL;

	m_mapAvatarsToImageList.SetLessFunc( DefLessFunc( CSteamID ) );
	m_mapAvatarsToImageList.RemoveAll();

	Q_memset( m_SkillRatings, 0, sizeof( m_SkillRatings ) );

	m_iCurrentState = MS_STATE_INITIAL;
	m_flNextActionTime = -1;

	m_nMedalsToAward_Bronze_Blue = 0;
	m_nMedalsToAward_Silver_Blue = 0;
	m_nMedalsToAward_Gold_Blue = 0;
	m_nMedalsToAward_Bronze_Red = 0;
	m_nMedalsToAward_Silver_Red = 0;
	m_nMedalsToAward_Gold_Red = 0;
	
	m_nMedalsRevealed = 0;
	m_nNumMedalsThisUpdate = 0;

	m_bBlueGoldValueRevealed = false;
	m_bBlueSilverValueRevealed = false;
	m_bBlueBronzeValueRevealed = false;
	m_bRedGoldValueRevealed = false;
	m_bRedSilverValueRevealed = false;
	m_bRedBronzeValueRevealed = false;
	m_bPlayerAbandoned = false;

	m_flMedalSoundTime = -1.f;

	m_bLargeMatchGroup = false;

	Q_memset( m_iImageClass, NULL, sizeof( m_iImageClass ) );
	Q_memset( m_iImageClassAlt, NULL, sizeof( m_iImageClassAlt ) );

	ListenForGameEvent( "competitive_victory" );
	ListenForGameEvent( "competitive_stats_update" );
	ListenForGameEvent( "player_abandoned_match" );
	ListenForGameEvent( "client_disconnect" );
	ListenForGameEvent( "show_match_summary" );

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

//-----------------------------------------------------------------------------
// Purpose: Constructor
//-----------------------------------------------------------------------------
CTFMatchSummary::~CTFMatchSummary()
{
	if ( NULL != m_pImageList )
	{
		delete m_pImageList;
		m_pImageList = NULL;
	}
}

//-----------------------------------------------------------------------------
// Purpose: Applies scheme settings
//-----------------------------------------------------------------------------
void CTFMatchSummary::ApplySchemeSettings( vgui::IScheme *pScheme )
{
	BaseClass::ApplySchemeSettings( pScheme );

	m_bLargeMatchGroup = false;

	KeyValues *pConditions = NULL;
	if ( TFGameRules() )
	{
		const IMatchGroupDescription* pMatch = GetMatchGroupDescription( TFGameRules()->GetCurrentMatchGroup() );
		if ( pMatch )
		{
			if ( pMatch->m_params.m_pmm_match_group_size->GetInt() > 12 )
			{
				pConditions = new KeyValues( "conditions" );
				AddSubKeyNamed( pConditions, "if_large" );

				m_bLargeMatchGroup = true;
			}
		}
	}

	LoadControlSettings( "resource/UI/HudMatchSummary.res", NULL, NULL, pConditions );

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

	if ( m_pDrawingPanel )
	{
		m_pDrawingPanel->ClearAllLines();
		m_pDrawingPanel->SetType( DRAWING_PANEL_TYPE_MATCH_SUMMARY );
		m_pDrawingPanel->MakePopup();
	}


	if ( m_pImageList )
		delete m_pImageList;
	m_pImageList = new ImageList( false );

	m_mapAvatarsToImageList.RemoveAll();

	for ( int i = 1; i < (int)StatMedal_Max; i++ )
	{
		m_iImageMedals[i] = m_pImageList->AddImage( scheme()->GetImage( g_pszCompetitiveMedalImages[i], true ) );
	}

	for ( int i = 1; i < SCOREBOARD_CLASS_ICONS; i++ )
	{
		m_iImageClass[i] = m_pImageList->AddImage( scheme()->GetImage( g_pszClassIcons[i], true ) );
		m_iImageClassAlt[i] = m_pImageList->AddImage( scheme()->GetImage( g_pszClassIconsAlt[i], true ) );
	}

	int iCurrentCount = m_pImageList->GetImageCount();

	// resize the images to our resolution
	for ( int i = 0; i < iCurrentCount; i++ )
	{
		int wide = 13, tall = 13;
		m_pImageList->GetImage( i )->SetSize( scheme()->GetProportionalScaledValueEx( GetScheme(), wide ), scheme()->GetProportionalScaledValueEx( GetScheme(), tall ) );
	}

	// resize the images to our resolution
	for ( int i = iCurrentCount; i < m_pImageList->GetImageCount(); i++ )
	{
		int wide = 26, tall = 26;
		m_pImageList->GetImage( i )->SetSize( scheme()->GetProportionalScaledValueEx( GetScheme(), wide ), scheme()->GetProportionalScaledValueEx( GetScheme(), tall ) );
	}

	SetPaintBackgroundEnabled( false );
	m_pTeamScoresPanel->SetPaintBackgroundEnabled( false );
	m_pPlayerListBlueParent->SetPaintBackgroundEnabled( false );
	m_pPlayerListRedParent->SetPaintBackgroundEnabled( false );
	m_pPlayerListBlue->SetPaintBackgroundEnabled( false );
	m_pPlayerListRed->SetPaintBackgroundEnabled( false );

	m_pPlayerListBlue->SetImageList( m_pImageList, false );
	m_pPlayerListBlue->SetVisible( true );

	m_pPlayerListRed->SetImageList( m_pImageList, false );
	m_pPlayerListRed->SetVisible( true );

	InitPlayerList( m_pPlayerListBlue, TF_TEAM_BLUE );
	InitPlayerList( m_pPlayerListRed, TF_TEAM_RED );

	m_hFont = pScheme->GetFont( "ScoreboardVerySmall", true );

	m_iCurrentState = MS_STATE_INITIAL;
	m_flNextActionTime = -1;

	RecalculateMedalCounts();

	m_nMedalsRevealed = 0;

	m_bBlueGoldValueRevealed = false;
	m_bBlueSilverValueRevealed = false;
	m_bBlueBronzeValueRevealed = false;
	m_bRedGoldValueRevealed = false;
	m_bRedSilverValueRevealed = false;
	m_bRedBronzeValueRevealed = false;

	m_flMedalSoundTime = -1.f;
	m_flDrawingPanelTime = -1.f;

	m_pBlueMedalsPanel->SetDialogVariable( "blueteammedals_gold", "?" );
	m_pBlueMedalsPanel->SetDialogVariable( "blueteammedals_silver", "?" );
	m_pBlueMedalsPanel->SetDialogVariable( "blueteammedals_bronze", "?" );
	m_pRedMedalsPanel->SetDialogVariable( "redteammedals_gold", "?" );
	m_pRedMedalsPanel->SetDialogVariable( "redteammedals_silver", "?" );
	m_pRedMedalsPanel->SetDialogVariable( "redteammedals_bronze", "?" );

	Update();
}

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

	EditablePanel* pStatsContainer = FindControl< EditablePanel >( "MainStatsContainer" );
	if ( pStatsContainer && m_bLargeMatchGroup )
	{
		pStatsContainer->SetPos( pStatsContainer->GetXPos(), m_iAnimStatsContainer12v12YPos );
	}
}

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

//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CTFMatchSummary::SetVisible( bool state )
{
	int iRenderGroup = gHUD.LookupRenderGroupIndexByName( "mid" );

	if ( state )
	{
		gHUD.LockRenderGroup( iRenderGroup );

		InvalidateLayout( true, true );

		m_iCurrentState = MS_STATE_INITIAL;

		m_flDrawingPanelTime = gpGlobals->curtime + 4.5f;

		CPvPRankPanel* pPvPRankPanel = FindControl< CPvPRankPanel >( "RankPanel" );
		if ( pPvPRankPanel )
		{
			pPvPRankPanel->SetMatchGroup( TFGameRules()->GetCurrentMatchGroup() );
		}

		g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( "CompetitiveGame_LowerChatWindow", false );
	}
	else
	{
		gHUD.UnlockRenderGroup( iRenderGroup );
	}

	BaseClass::SetVisible( state );
}

//-----------------------------------------------------------------------------
// Purpose: Used for sorting players
//-----------------------------------------------------------------------------
bool CTFMatchSummary::TFPlayerSortFunc( vgui::SectionedListPanel *list, int itemID1, int itemID2 )
{
	KeyValues *it1 = list->GetItemData( itemID1 );
	KeyValues *it2 = list->GetItemData( itemID2 );
	Assert( it1 && it2 );

	// first compare score
	int v1 = it1->GetInt( "score" );
	int v2 = it2->GetInt( "score" );
	if ( v1 > v2 )
		return true;
	else if ( v1 < v2 )
		return false;

	// if score is the same, use player index to get deterministic sort
	int iPlayerIndex1 = it1->GetInt( "playerIndex" );
	int iPlayerIndex2 = it2->GetInt( "playerIndex" );
	return ( iPlayerIndex1 > iPlayerIndex2 );
}

//-----------------------------------------------------------------------------
// Purpose: Inits the player list in a list panel
//-----------------------------------------------------------------------------
void CTFMatchSummary::InitPlayerList( TFSectionedListPanel *pPlayerList, int nTeam )
{
	float flAspectRatio = engine->GetScreenAspectRatio();
	bool bStandard = flAspectRatio < 1.6f;

	pPlayerList->SetVerticalScrollbar( false );
	pPlayerList->RemoveAll();
	pPlayerList->RemoveAllSections();
	pPlayerList->AddSection( 0, "Players", TFPlayerSortFunc );
	pPlayerList->SetSectionAlwaysVisible( 0, true );
	pPlayerList->SetSectionDrawDividerBar( 0, false );
	pPlayerList->SetBorder( NULL );
	pPlayerList->SetMouseInputEnabled( false );
	pPlayerList->SetClickable( false );

	pPlayerList->AddColumnToSection( 0, "medal", "", SectionedListPanel::COLUMN_IMAGE | SectionedListPanel::COLUMN_CENTER, pPlayerList->m_iMedalWidth );
	pPlayerList->AddColumnToSection( 0, "avatar", "", SectionedListPanel::COLUMN_IMAGE | SectionedListPanel::COLUMN_RIGHT, pPlayerList->m_iAvatarWidth );
	pPlayerList->AddColumnToSection( 0, "spacer", "", 0, pPlayerList->m_iSpacerWidth );
	pPlayerList->AddColumnToSection( 0, "name", "", 0, pPlayerList->m_iNameWidth );
	pPlayerList->AddColumnToSection( 0, "class", "", SectionedListPanel::COLUMN_IMAGE | SectionedListPanel::COLUMN_RIGHT, pPlayerList->m_iClassWidth );
	pPlayerList->AddColumnToSection( 0, "score", bStandard ? "#TF_Comp_Scoreboard_Score_Standard" : "#TF_Comp_Scoreboard_Score", SectionedListPanel::COLUMN_RIGHT, pPlayerList->m_iStatsWidth );
	pPlayerList->AddColumnToSection( 0, "score_medal", "", SectionedListPanel::COLUMN_IMAGE | SectionedListPanel::COLUMN_RIGHT, pPlayerList->m_iAwardWidth );
	pPlayerList->AddColumnToSection( 0, "kills", bStandard ? "#TF_Comp_Scoreboard_Kills_Standard" : "#TF_Comp_Scoreboard_Kills", SectionedListPanel::COLUMN_RIGHT, pPlayerList->m_iStatsWidth );
	pPlayerList->AddColumnToSection( 0, "kills_medal", "", SectionedListPanel::COLUMN_IMAGE | SectionedListPanel::COLUMN_RIGHT, pPlayerList->m_iAwardWidth );
	pPlayerList->AddColumnToSection( 0, "damage", bStandard ? "#TF_Comp_Scoreboard_Damage_Standard" : "#TF_Comp_Scoreboard_Damage", SectionedListPanel::COLUMN_RIGHT, pPlayerList->m_iStatsWidth );
	pPlayerList->AddColumnToSection( 0, "damage_medal", "", SectionedListPanel::COLUMN_IMAGE | SectionedListPanel::COLUMN_RIGHT, pPlayerList->m_iAwardWidth );
	pPlayerList->AddColumnToSection( 0, "healing", bStandard ? "#TF_Comp_Scoreboard_Healing_Standard" : "#TF_Comp_Scoreboard_Healing", SectionedListPanel::COLUMN_RIGHT, pPlayerList->m_iStatsWidth );
	pPlayerList->AddColumnToSection( 0, "healing_medal", "", SectionedListPanel::COLUMN_IMAGE | SectionedListPanel::COLUMN_RIGHT, pPlayerList->m_iAwardWidth );
	pPlayerList->AddColumnToSection( 0, "support", bStandard ? "#TF_Comp_Scoreboard_Support_Standard" : "#TF_Comp_Scoreboard_Support", SectionedListPanel::COLUMN_RIGHT, pPlayerList->m_iStatsWidth );
	pPlayerList->AddColumnToSection( 0, "support_medal", "", SectionedListPanel::COLUMN_IMAGE | SectionedListPanel::COLUMN_RIGHT, pPlayerList->m_iAwardWidth );
}

//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CTFMatchSummary::Update( void )
{
	UpdateTeamInfo();
	UpdatePlayerList();
	UpdateBadgePanels( m_pRedBadgePanels, m_pPlayerListRed );
	UpdateBadgePanels( m_pBlueBadgePanels, m_pPlayerListBlue );
}

//-----------------------------------------------------------------------------
// Purpose: Updates information about teams
//-----------------------------------------------------------------------------
void CTFMatchSummary::UpdateTeamInfo()
{
	bool bUseWinnerLabel = false;
	if ( GetGlobalTFTeam( TF_TEAM_RED ) && GetGlobalTFTeam( TF_TEAM_BLUE ) )
	{
		if ( GetGlobalTFTeam( TF_TEAM_RED )->Get_Score() == GetGlobalTFTeam( TF_TEAM_BLUE )->Get_Score() )
		{
			bUseWinnerLabel = true;
		}
	}

	int nWinningTeam = TEAM_INVALID;
	if ( TFGameRules() )
	{
		nWinningTeam = TFGameRules()->GetWinningTeam();
	}

	for ( int teamIndex = TF_TEAM_RED; teamIndex <= TF_TEAM_BLUE; teamIndex++ )
	{
		C_TFTeam *team = GetGlobalTFTeam( teamIndex );
		if ( team )
		{
			// choose dialog variables to set depending on team
			const char *pDialogVarTeamName = "";
			const char *pDialogVarTeamScore = "";
			const char *pDialogVarWinner = "";
			vgui::EditablePanel *pOwner = NULL;

			switch ( teamIndex )
			{
			case TF_TEAM_RED:
				pDialogVarTeamName = "redteamname";
				pDialogVarTeamScore = "redteamscore";
				pDialogVarWinner = "redteamwinner";
				pOwner = m_pRedTeamPanel;
				break;
			case TF_TEAM_BLUE:
				pDialogVarTeamName = "blueteamname";
				pDialogVarTeamScore = "blueteamscore";
				pDialogVarWinner = "blueteamwinner";
				pOwner = m_pBlueTeamPanel;
				break;
			default:
				Assert( false );
				break;
			}

			if ( !pOwner )
				return;

			// set the team name
			pOwner->SetDialogVariable( pDialogVarTeamName, team->Get_Localized_Name() );

			if ( bUseWinnerLabel )
			{
				const char *pszLabel = "";
				if ( teamIndex == nWinningTeam ) 
				{
					if ( team->GetNumPlayers() > 1 )
					{
						pszLabel = "#TF_Winners";
					}
					else
					{
						pszLabel = "#TF_Winner";
					}
				}

				pOwner->SetDialogVariable( pDialogVarTeamScore, "" );
				pOwner->SetDialogVariable( pDialogVarWinner, g_pVGuiLocalize->Find( pszLabel ) );
			}
			else
			{
				pOwner->SetDialogVariable( pDialogVarTeamScore, team->Get_Score() );
				pOwner->SetDialogVariable( pDialogVarWinner, "" );
			}
		}
	}

	bool bShowAvatars = g_TF_PR && g_TF_PR->HasPremadeParties();

	if ( bShowAvatars )
	{
		m_pRedLeaderAvatarImage->SetPlayer( GetSteamIDForPlayerIndex( g_TF_PR->GetPartyLeaderRedTeamIndex() ), k_EAvatarSize64x64 );
		m_pRedLeaderAvatarImage->SetShouldDrawFriendIcon( false );
		m_pBlueLeaderAvatarImage->SetPlayer( GetSteamIDForPlayerIndex( g_TF_PR->GetPartyLeaderBlueTeamIndex() ), k_EAvatarSize64x64 );
		m_pBlueLeaderAvatarImage->SetShouldDrawFriendIcon( false );
	}

	m_pRedLeaderAvatarImage->SetVisible( bShowAvatars );
	m_pRedLeaderAvatarBG->SetVisible( bShowAvatars );
	m_pRedTeamName->SetVisible( bShowAvatars );
	m_pRedTeamImage->SetVisible( !bShowAvatars );

	m_pBlueLeaderAvatarImage->SetVisible( bShowAvatars );
	m_pBlueLeaderAvatarBG->SetVisible( bShowAvatars );
	m_pBlueTeamName->SetVisible( bShowAvatars );
	m_pBlueTeamImage->SetVisible( !bShowAvatars );
}

//-----------------------------------------------------------------------------
// Purpose: Returns the last medal (column) added so we can display some effects
//-----------------------------------------------------------------------------
matchsummary_columns_t CTFMatchSummary::InternalAddMedalKeyValues( int iIndex, StatMedal_t eMedal, KeyValues *pKeyValues, int nTotalMedals /*= -1*/ )
{
	int nMedal = (int)eMedal;
	matchsummary_columns_t retVal = MS_COLUMN_INVALID;

	if ( ( nTotalMedals < 0 ) || ( m_nNumMedalsThisUpdate <= nTotalMedals ) )
	{
		if ( m_SkillRatings[iIndex].nScoreRank == nMedal )
		{
			pKeyValues->SetInt( "score_medal", m_iImageMedals[nMedal] );
			if ( nTotalMedals >= 0 )
			{
				m_nNumMedalsThisUpdate++;
			}

			if ( ( nTotalMedals >= 0 ) && ( m_nNumMedalsThisUpdate > nTotalMedals ) )
			{
				retVal = MS_COLUMN_SCORE_MEDAL;
			}
		}
	}

	if ( ( nTotalMedals < 0 ) || ( m_nNumMedalsThisUpdate <= nTotalMedals ) )
	{
		if ( m_SkillRatings[iIndex].nKillsRank == nMedal )
		{
			pKeyValues->SetInt( "kills_medal", m_iImageMedals[nMedal] );
			if ( nTotalMedals >= 0 )
			{
				m_nNumMedalsThisUpdate++;
			}

			if ( ( nTotalMedals >= 0 ) && ( m_nNumMedalsThisUpdate > nTotalMedals ) )
			{
				retVal = MS_COLUMN_KILLS_MEDAL;
			}
		}
	}

	if ( ( nTotalMedals < 0 ) || ( m_nNumMedalsThisUpdate <= nTotalMedals ) )
	{
		if ( m_SkillRatings[iIndex].nDamageRank == nMedal )
		{
			pKeyValues->SetInt( "damage_medal", m_iImageMedals[nMedal] );
			if ( nTotalMedals >= 0 )
			{
				m_nNumMedalsThisUpdate++;
			}

			if ( ( nTotalMedals >= 0 ) && ( m_nNumMedalsThisUpdate > nTotalMedals ) )
			{
				retVal = MS_COLUMN_DAMAGE_MEDAL;
			}
		}
	}

	if ( ( nTotalMedals < 0 ) || ( m_nNumMedalsThisUpdate <= nTotalMedals ) )
	{
		if ( m_SkillRatings[iIndex].nHealingRank == nMedal )
		{
			pKeyValues->SetInt( "healing_medal", m_iImageMedals[nMedal] );
			if ( nTotalMedals >= 0 )
			{
				m_nNumMedalsThisUpdate++;
			}

			if ( ( nTotalMedals >= 0 ) && ( m_nNumMedalsThisUpdate > nTotalMedals ) )
			{
				retVal = MS_COLUMN_HEALING_MEDAL;
			}
		}
	}

	if ( ( nTotalMedals < 0 ) || ( m_nNumMedalsThisUpdate <= nTotalMedals ) )
	{
		if ( m_SkillRatings[iIndex].nSupportRank == nMedal )
		{
			pKeyValues->SetInt( "support_medal", m_iImageMedals[nMedal] );
			if ( nTotalMedals >= 0 )
			{
				m_nNumMedalsThisUpdate++;
			}

			if ( ( nTotalMedals >= 0 ) && ( m_nNumMedalsThisUpdate > nTotalMedals ) )
			{
				retVal = MS_COLUMN_SUPPORT_MEDAL;
			}
		}
	}

	return retVal;
}

//-----------------------------------------------------------------------------
// Purpose: Updates the player list
//-----------------------------------------------------------------------------
void CTFMatchSummary::UpdatePlayerList()
{
	m_pPlayerListRed->RemoveAll();
	m_pPlayerListRed->ClearAllColorOverrideForCell();

	m_pPlayerListBlue->RemoveAll();
	m_pPlayerListBlue->ClearAllColorOverrideForCell();

	if ( !g_TF_PR )
		return;

	m_nNumMedalsThisUpdate = 0;

	for ( int playerIndex = 1; playerIndex <= MAX_PLAYERS; playerIndex++ )
	{
		if ( g_PR->IsConnected( playerIndex ) || g_PR->IsValid( playerIndex ) )
		{
			TFSectionedListPanel *pPlayerList = NULL;
			int nTeam = g_PR->GetTeam( playerIndex );
			switch ( nTeam )
			{
			case TF_TEAM_BLUE:
				pPlayerList = m_pPlayerListBlue;
				break;
			case TF_TEAM_RED:
				pPlayerList = m_pPlayerListRed;
				break;
			}
			if ( null == pPlayerList )
				continue;

			KeyValues *pKeyValues = new KeyValues( "data" );
			pKeyValues->SetInt( "playerIndex", playerIndex );

			// this is just a placeholder in the sectioned list panel
			pKeyValues->SetInt( "medal", 0 ); 

			pKeyValues->SetString( "name", g_TF_PR->GetPlayerName( playerIndex ) );
			pKeyValues->SetInt( "score", g_TF_PR->GetTotalScore( playerIndex ) );

			int iClass = g_TF_PR->GetPlayerClass( playerIndex );
			if ( iClass >= TF_FIRST_NORMAL_CLASS && iClass <= TF_LAST_NORMAL_CLASS )
			{
				pKeyValues->SetInt( "class", tf_scoreboard_alt_class_icons.GetBool() ? m_iImageClassAlt[iClass] : m_iImageClass[iClass] );
			}
			else
			{
				pKeyValues->SetInt( "class", 0 );
			}

			pKeyValues->SetInt( "kills", g_TF_PR->GetPlayerScore( playerIndex ) );
			pKeyValues->SetInt( "damage", g_TF_PR->GetDamage( playerIndex ) );
			pKeyValues->SetInt( "healing", g_TF_PR->GetHealing( playerIndex ) );

			int nSupport = g_TF_PR->GetDamageAssist( playerIndex ) +
				g_TF_PR->GetHealingAssist( playerIndex ) +
				g_TF_PR->GetDamageBlocked( playerIndex ) +
				( g_TF_PR->GetBonusPoints( playerIndex ) * 25 );
			pKeyValues->SetInt( "support", nSupport );

			matchsummary_columns_t eParticleColumn = MS_COLUMN_INVALID;
			StatMedal_t eParticleMedal = StatMedal_None;

			if ( m_iCurrentState == MS_STATE_GOLD_MEDALS )
			{
				// we can add the bronze and silver since we've already processed those
				InternalAddMedalKeyValues( playerIndex, StatMedal_Bronze, pKeyValues );
				InternalAddMedalKeyValues( playerIndex, StatMedal_Silver, pKeyValues );
				eParticleColumn = InternalAddMedalKeyValues( playerIndex, StatMedal_Gold, pKeyValues, m_nMedalsRevealed );
				eParticleMedal = StatMedal_Gold;
			}
			else if ( m_iCurrentState == MS_STATE_SILVER_MEDALS )
			{
				// we can add the bronze since we've already processed those
				InternalAddMedalKeyValues( playerIndex, StatMedal_Bronze, pKeyValues );
				eParticleColumn = InternalAddMedalKeyValues( playerIndex, StatMedal_Silver, pKeyValues, m_nMedalsRevealed );
				eParticleMedal = StatMedal_Silver;
			}
			else if ( m_iCurrentState == MS_STATE_BRONZE_MEDALS )
			{
				eParticleColumn = InternalAddMedalKeyValues( playerIndex, StatMedal_Bronze, pKeyValues, m_nMedalsRevealed );
				eParticleMedal = StatMedal_Bronze;
			}

			UpdatePlayerAvatar( playerIndex, pKeyValues );

			int itemID = pPlayerList->AddItem( 0, pKeyValues );
			pPlayerList->SetItemFgColor( itemID, g_PR->GetTeamColor( nTeam ) );
			// Green background for rematch folks
			pPlayerList->SetItemBgColor( itemID, Color( 80, 80, 80, 80 ) );
			pPlayerList->SetItemBgHorizFillInset( itemID, pPlayerList->m_iHorizFillInset );
			pPlayerList->SetItemFont( itemID, m_hFont );

			// This highlights the local player in grey
			if ( playerIndex == GetLocalPlayerIndex() )
			{
				pPlayerList->SetSelectedItem( itemID );
			}

			// loop through and setup our medal color overrides
			KeyValues *pKey = pKeyValues->FindKey( "score_medal" );
			if ( pKey && pKey->GetInt() )
			{
				int nMedal = pKey->GetInt();
				pPlayerList->SetColorOverrideForCell( 0, itemID, MS_COLUMN_SCORE, ( nMedal == (int)StatMedal_Bronze ) ? m_clrBronzeMedal : ( nMedal == (int)StatMedal_Silver ) ?  m_clrSilverMedal : m_clrGoldMedal );
			}
			pKey = pKeyValues->FindKey( "kills_medal" );
			if ( pKey && pKey->GetInt() )
			{
				int nMedal = pKey->GetInt();
				pPlayerList->SetColorOverrideForCell( 0, itemID, MS_COLUMN_KILLS, ( nMedal == (int)StatMedal_Bronze ) ? m_clrBronzeMedal : ( nMedal == (int)StatMedal_Silver ) ? m_clrSilverMedal : m_clrGoldMedal );
			}
			pKey = pKeyValues->FindKey( "damage_medal" );
			if ( pKey && pKey->GetInt() )
			{
				int nMedal = pKey->GetInt();
				pPlayerList->SetColorOverrideForCell( 0, itemID, MS_COLUMN_DAMAGE, ( nMedal == (int)StatMedal_Bronze ) ? m_clrBronzeMedal : ( nMedal == (int)StatMedal_Silver ) ? m_clrSilverMedal : m_clrGoldMedal );
			}
			pKey = pKeyValues->FindKey( "healing_medal" );
			if ( pKey && pKey->GetInt() )
			{
				int nMedal = pKey->GetInt();
				pPlayerList->SetColorOverrideForCell( 0, itemID, MS_COLUMN_HEALING, ( nMedal == (int)StatMedal_Bronze ) ? m_clrBronzeMedal : ( nMedal == (int)StatMedal_Silver ) ? m_clrSilverMedal : m_clrGoldMedal );
			}
			pKey = pKeyValues->FindKey( "support_medal" );
			if ( pKey && pKey->GetInt() )
			{
				int nMedal = pKey->GetInt();
				pPlayerList->SetColorOverrideForCell( 0, itemID, MS_COLUMN_SUPPORT, ( nMedal == (int)StatMedal_Bronze ) ? m_clrBronzeMedal : ( nMedal == (int)StatMedal_Silver ) ? m_clrSilverMedal : m_clrGoldMedal );
			}

			pKeyValues->deleteThis();

			if ( ( eParticleColumn > MS_COLUMN_INVALID ) && ( eParticleMedal > StatMedal_None ) )
			{
				int nPanelXPos, nPanelYPos, nPanelWide, nPanelTall;
				pPlayerList->GetMaxCellBounds( itemID, eParticleColumn, nPanelXPos, nPanelYPos, nPanelWide, nPanelTall );

				FireMedalEffects( pPlayerList, nPanelXPos, nPanelYPos, nPanelWide, nPanelTall, eParticleMedal );
			}
		}
	}

	m_pPlayerListRed->SetSectionFgColor( 0, g_PR->GetTeamColor( TF_TEAM_RED ) );
	m_pPlayerListBlue->SetSectionFgColor( 0, g_PR->GetTeamColor( TF_TEAM_BLUE ) );

	// force the lists to PerformLayout() now so we can update our rank images after we return
	m_pPlayerListRed->InvalidateLayout( true );
	m_pPlayerListBlue->InvalidateLayout( true );
}

//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CTFMatchSummary::FireMedalEffects( Panel *pPanel, int nPanelXPos, int nPanelYPos, int nPanelWide, int nPanelTall, StatMedal_t eParticleMedal )
{
	if ( !pPanel )
		return;

	int nPanelCenterX = nPanelXPos + ( nPanelWide / 2 );
	int nPanelCenterY = nPanelYPos + ( nPanelTall / 2 );

	int iItemAbsX, iItemAbsY;
	vgui::ipanel()->GetAbsPos( pPanel->GetParent()->GetVPanel(), iItemAbsX, iItemAbsY );

	int x = iItemAbsX + nPanelCenterX;
	int y = iItemAbsY + nPanelCenterY;

	const char *pszSoundEffect = "MatchMaking.None";
	const char *pszParticleEffect = "mvm_loot_smoke";
	if ( eParticleMedal == StatMedal_Bronze )
	{
		pszSoundEffect = "MatchMaking.Bronze";
		pszParticleEffect = "mvm_loot_explosion";
	}
	else if ( eParticleMedal == StatMedal_Silver )
	{
		pszSoundEffect = "MatchMaking.Silver";
		pszParticleEffect = "mvm_loot_explosion";
	}
	else if ( eParticleMedal == StatMedal_Gold )
	{
		pszSoundEffect = "MatchMaking.Gold";
		pszParticleEffect = "mvm_pow_gold_seq_firework_mid";
	}

	m_pParticlePanel->FireParticleEffect( pszParticleEffect, x, y, 0.2f, false );

	C_BasePlayer *pLocalPlayer = C_BasePlayer::GetLocalPlayer();
	if ( pLocalPlayer )
	{
		pLocalPlayer->EmitSound( pszSoundEffect );
	}
}

//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CTFMatchSummary::UpdateBadgePanels( CUtlVector<CTFBadgePanel*> &pBadgePanels, TFSectionedListPanel *pPlayerList )
{
	if ( !TFGameRules() )
		return;

	const IMatchGroupDescription *pMatchDesc = GetMatchGroupDescription( TFGameRules()->GetCurrentMatchGroup() );
	const IProgressionDesc *pProgressionDesc = pMatchDesc ? pMatchDesc->m_pProgressionDesc : NULL; 
	if ( pProgressionDesc )
	{
		if ( pPlayerList )
		{
			int iNumPanels = 0;
			int parentTall = pPlayerList->GetTall();
			CTFBadgePanel *pPanel = NULL;

			for ( int i = 0; i < pPlayerList->GetItemCount(); i++ )
			{
				KeyValues *pKeyValues = pPlayerList->GetItemData( i );
				if ( !pKeyValues )
					continue;

				const CSteamID steamID = GetSteamIDForPlayerIndex( pKeyValues->GetInt( "playerIndex" ) );
#ifdef STAGING_ONLY
				if ( steamID.IsValid() || tf_test_match_summary.GetBool() )
#else
				if ( steamID.IsValid() )
#endif // STAGING_ONLY
				{
					if ( iNumPanels >= pBadgePanels.Count() )
					{
						pPanel = new CTFBadgePanel( m_pMainStatsContainer, "BadgePanel" );
						pPanel->MakeReadyForUse();
						pPanel->SetVisible( true );
						pPanel->SetZPos( 9999 );
						pBadgePanels.AddToTail( pPanel );
					}
					else
					{
						pPanel = pBadgePanels[iNumPanels];
					}

					int x, y, wide, tall;
					pPlayerList->GetMaxCellBounds( i, 0, x, y, wide, tall );

					if ( y + tall > parentTall )
						continue;

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

					int xParent = 0, yParent = 0;
					if ( pPlayerList->GetParent() )
					{
						pPlayerList->GetParent()->GetPos( xParent, yParent );
					}

					int xGrandParent = 0, yGrandParent = 0;
					if ( pPlayerList->GetParent()->GetParent() )
					{
						pPlayerList->GetParent()->GetParent()->GetPos( xGrandParent, yGrandParent );
					}

					int nPanelXPos, nPanelYPos, nPanelWide, nPanelTall;
					pPanel->GetBounds( nPanelXPos, nPanelYPos, nPanelWide, nPanelTall );

					if ( ( nPanelXPos != xGrandParent + xParent + x )
						|| ( nPanelYPos != yGrandParent + yParent + y )
						|| ( nPanelWide != wide )
						|| ( nPanelTall != tall ) )
					{
						pPanel->SetBounds( xGrandParent + xParent + x, yGrandParent + yParent + y, wide, tall );
						pPanel->InvalidateLayout( true, true );
					}

					pPanel->SetupBadge( pProgressionDesc, steamID );
					iNumPanels++;
				}
			}

			// hide any unused images
			for ( int i = iNumPanels; i < pBadgePanels.Count(); i++ )
			{
				if ( pBadgePanels[i]->IsVisible() )
				{
					pBadgePanels[i]->SetVisible( false );
				}
			}
		}
	}
}

//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CTFMatchSummary::UpdatePlayerAvatar( int playerIndex, KeyValues *kv )
{
	if ( !g_PR )
		return;

	uint32 iAccountID = g_PR->GetAccountID( playerIndex );
	if ( iAccountID > 0 )
	{
		// Update their avatar
		if ( kv && steamapicontext->SteamFriends() && steamapicontext->SteamUtils() )
		{
			CSteamID steamIDForPlayer( iAccountID, 1, GetUniverse(), k_EAccountTypeIndividual );

			// See if we already have that avatar in our list
			int iMapIndex = m_mapAvatarsToImageList.Find( steamIDForPlayer );
			int iImageIndex;
			if ( iMapIndex == m_mapAvatarsToImageList.InvalidIndex() )
			{
				CAvatarImage *pImage = new CAvatarImage();
				pImage->SetAvatarSteamID( steamIDForPlayer );
				pImage->SetAvatarSize( 32, 32 );	// Deliberately non scaling
				iImageIndex = m_pImageList->AddImage( pImage );

				m_mapAvatarsToImageList.Insert( steamIDForPlayer, iImageIndex );
			}
			else
			{
				iImageIndex = m_mapAvatarsToImageList[iMapIndex];
			}

			kv->SetInt( "avatar", iImageIndex );

			CAvatarImage *pAvIm = (CAvatarImage *)m_pImageList->GetImage( iImageIndex );
			pAvIm->UpdateFriendStatus();
		}
	}
}

//-----------------------------------------------------------------------------
// Purpose: Event handler
//-----------------------------------------------------------------------------
void CTFMatchSummary::FireGameEvent( IGameEvent *event )
{
	const char *type = event->GetName();

	if ( FStrEq( type, "competitive_victory" ) )
	{
		Q_memset( m_SkillRatings, 0, sizeof( m_SkillRatings ) );
		Leaderboards_LadderRefresh();
	}
	else if ( FStrEq( type, "competitive_stats_update" ) )
	{
		int iIndex = event->GetInt( "index" );
		Assert( iIndex > 0 && iIndex <= MAX_PLAYERS );
		if ( iIndex > 0 && iIndex <= MAX_PLAYERS )
		{
			m_SkillRatings[iIndex].unRating = event->GetInt( "rating" );			// Rank
			m_SkillRatings[iIndex].nDelta = event->GetInt( "delta" );
			m_SkillRatings[iIndex].nScoreRank = event->GetInt( "score_rank" );		// Medal for Score (Gold, Silver, Bronze, or nothing)		
			m_SkillRatings[iIndex].nKillsRank = event->GetInt( "kills_rank" );		// Medal for Kills
			m_SkillRatings[iIndex].nDamageRank = event->GetInt( "damage_rank" );	// Medal for Damage
			m_SkillRatings[iIndex].nHealingRank = event->GetInt( "healing_rank" );	// Medal for Healing
			m_SkillRatings[iIndex].nSupportRank = event->GetInt( "support_rank" );	// Medal for Rank

			RecalculateMedalCounts();
		}
	}
	else if ( FStrEq( type, "player_abandoned_match" ) )
	{
		m_bPlayerAbandoned = true;
	}
	else if ( FStrEq( type, "client_disconnect" ) )
	{
		m_bPlayerAbandoned = false;
	}
	else if ( FStrEq( type, "show_match_summary" ) )
	{
		SetVisible( true );

		if ( m_pPlayerListRedParent->GetParent() )
		{
			int nRedBadgeOffset = m_pPlayerListRedParent->GetParent()->GetXPos();
			FOR_EACH_VEC( m_pRedBadgePanels, i )
			{
				g_pClientMode->GetViewportAnimationController()->RunAnimationCommand( m_pRedBadgePanels[i], "xpos", m_pRedBadgePanels[i]->GetXPos() - nRedBadgeOffset, 0.25, 0.25, vgui::AnimationController::INTERPOLATOR_ACCEL );
			}
		}

		if ( m_pPlayerListBlueParent->GetParent() )
		{
			int nBlueBadgeOffset = m_pPlayerListBlueParent->GetParent()->GetXPos();
			FOR_EACH_VEC( m_pBlueBadgePanels, i )
			{
				g_pClientMode->GetViewportAnimationController()->RunAnimationCommand( m_pBlueBadgePanels[i], "xpos", m_pBlueBadgePanels[i]->GetXPos() - nBlueBadgeOffset, 0.25, 0.25, vgui::AnimationController::INTERPOLATOR_ACCEL );
			}
		}

		g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( m_pTeamScoresPanel, "HudMatchSummary_SlideInPanels", false );
	}
}

//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CTFMatchSummary::InternalUpdateMedalCountForType( int iTeam, StatMedal_t eMedal )
{
	switch ( eMedal )
	{
	case StatMedal_Bronze:
		if ( iTeam == TF_TEAM_RED )
		{
			m_nMedalsToAward_Bronze_Red++;
		}
		else if ( iTeam == TF_TEAM_BLUE )
		{
			m_nMedalsToAward_Bronze_Blue++;
		}
		break;
	case StatMedal_Silver:
		if ( iTeam == TF_TEAM_RED )
		{
			m_nMedalsToAward_Silver_Red++;
		}
		else if ( iTeam == TF_TEAM_BLUE )
		{
			m_nMedalsToAward_Silver_Blue++;
		}
		break;
	case StatMedal_Gold:
		if ( iTeam == TF_TEAM_RED )
		{
			m_nMedalsToAward_Gold_Red++;
		}
		else if ( iTeam == TF_TEAM_BLUE )
		{
			m_nMedalsToAward_Gold_Blue++;
		}
		break;
	case StatMedal_None:
	default:
		break;
	}
}

//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CTFMatchSummary::RecalculateMedalCounts()
{
	m_nMedalsToAward_Bronze_Blue = 0;
	m_nMedalsToAward_Silver_Blue = 0;
	m_nMedalsToAward_Gold_Blue = 0;
	m_nMedalsToAward_Bronze_Red = 0;
	m_nMedalsToAward_Silver_Red = 0;
	m_nMedalsToAward_Gold_Red = 0;

	if ( !g_PR )
		return;

	for ( int playerIndex = 1; playerIndex <= MAX_PLAYERS; playerIndex++ )
	{
		if ( g_PR->IsConnected( playerIndex ) || g_PR->IsValid( playerIndex ) )
		{
			int nTeam = g_PR->GetTeam( playerIndex );
			if ( nTeam >= FIRST_GAME_TEAM )
			{
				InternalUpdateMedalCountForType( nTeam, (StatMedal_t)( m_SkillRatings[playerIndex].nScoreRank ) );
				InternalUpdateMedalCountForType( nTeam, (StatMedal_t)( m_SkillRatings[playerIndex].nKillsRank ) );
				InternalUpdateMedalCountForType( nTeam, (StatMedal_t)( m_SkillRatings[playerIndex].nDamageRank ) );
				InternalUpdateMedalCountForType( nTeam, (StatMedal_t)( m_SkillRatings[playerIndex].nHealingRank ) );
				InternalUpdateMedalCountForType( nTeam, (StatMedal_t)( m_SkillRatings[playerIndex].nSupportRank ) );
			}
		}
	}
}

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

	C_TFPlayer *pLocalPlayer = C_TFPlayer::GetLocalTFPlayer();

	if ( !IsVisible() || !pLocalPlayer )
		return;

	const IMatchGroupDescription* pMatchDesc = GetMatchGroupDescription( TFGameRules()->GetCurrentMatchGroup() );
	if ( !pMatchDesc )
		return;

	if ( pMatchDesc->m_params.m_bAllowDrawingAtMatchSummary 
	     && m_pDrawingPanel 
	     && ( m_flDrawingPanelTime > 0 ) 
	     && ( m_flDrawingPanelTime < gpGlobals->curtime ) )
	{
		m_pDrawingPanel->SetVisible( true );
		m_pDrawingPanel->SetKeyBoardInputEnabled( false );
		m_flDrawingPanelTime = -1.f;

		if ( pLocalPlayer )
		{
			pLocalPlayer->EmitSound( "Announcer.SummaryScreenWinners" );
		}
	}

	int nMedalsToAward_Bronze_Total = m_nMedalsToAward_Bronze_Blue + m_nMedalsToAward_Bronze_Red;
	int nMedalsToAward_Silver_Total = m_nMedalsToAward_Silver_Blue + m_nMedalsToAward_Silver_Red;
	int nMedalsToAward_Gold_Total = m_nMedalsToAward_Gold_Blue + m_nMedalsToAward_Gold_Red;

	bool bShowPerformanceMedals = ShowPerformanceMedals();
	bool bMapHasMatchSummaryStage = ( TFGameRules() && TFGameRules()->MapHasMatchSummaryStage() );

	
#ifdef STAGING_ONLY
	bool bUseMatchSummaryStage = tf_test_match_summary.GetBool() || ( pMatchDesc && pMatchDesc->m_params.m_bUseMatchSummaryStage );
#else
	bool bUseMatchSummaryStage = ( pMatchDesc && pMatchDesc->m_params.m_bUseMatchSummaryStage );
#endif

	switch ( m_iCurrentState )
	{
	case MS_STATE_INITIAL:
	{
		bool bUseStage = ( bMapHasMatchSummaryStage && bUseMatchSummaryStage );

		if ( GTFGCClientSystem()->GetSurveyRequest().has_match_id() )
		{
			Panel* pSurveyPanel = CreateSurveyQuestionPanel( this, GTFGCClientSystem()->GetSurveyRequest() );
			pSurveyPanel->MakePopup();
		}

		m_iCurrentState = MS_STATE_DRAWING;
		m_flNextActionTime = bUseStage ? gpGlobals->curtime + MS_STATE_TRANSITION_TO_STATS : gpGlobals->curtime + 2.f;
		m_bXPShown = false;

		if ( !bUseStage )
		{
			// if we're not using the stage we'll just show the doors and then skip to stats with no drawing
			if ( m_pDrawingPanel )
			{
				m_pDrawingPanel->SetVisible( false );
			}
		}
		break;
	}
	case MS_STATE_DRAWING:
		{
			if ( gpGlobals->curtime > m_flNextActionTime )
			{
				if ( m_pDrawingPanel )
				{
					m_pDrawingPanel->SetVisible( false );
				}

				if ( m_pStatsBgPanel )
				{
					m_pStatsBgPanel->SetVisible( true );
				}

				if ( m_pStatsLabelPanel )
				{
					m_pStatsLabelPanel->SetVisible( true );
				}

				g_pClientMode->GetViewportAnimationController()->RunAnimationCommand( m_pStatsLabelPanel, "ypos", m_bLargeMatchGroup ? m_iAnimStatsLabelPanel12v12YPos : m_iAnimStatsLabelPanel6v6YPos, 0.0, 0.1, vgui::AnimationController::INTERPOLATOR_ACCEL );
				g_pClientMode->GetViewportAnimationController()->RunAnimationCommand( m_pBlueMedalsPanel, "ypos", m_iAnimBlueMedalsYPos, 0.0, 0.1, vgui::AnimationController::INTERPOLATOR_ACCEL );
				g_pClientMode->GetViewportAnimationController()->RunAnimationCommand( m_pRedMedalsPanel, "ypos", m_iAnimRedMedalsYPos, 0.0, 0.1, vgui::AnimationController::INTERPOLATOR_ACCEL );
				g_pClientMode->GetViewportAnimationController()->RunAnimationCommand( m_pBlueTeamName, "ypos", m_bLargeMatchGroup ? m_iAnimBlueTeamLabel12v12YPos : m_iAnimBlueTeamLabel6v6YPos, 0.0, 0.1, vgui::AnimationController::INTERPOLATOR_ACCEL );
				g_pClientMode->GetViewportAnimationController()->RunAnimationCommand( m_pRedTeamName, "ypos", m_bLargeMatchGroup ? m_iAnimRedTeamLabel12v12YPos : m_iAnimRedTeamLabel6v6YPos, 0.0, 0.1, vgui::AnimationController::INTERPOLATOR_ACCEL );
				g_pClientMode->GetViewportAnimationController()->RunAnimationCommand( m_pPlayerListBlueParent, "wide", m_iAnimBluePlayerListParent, 0.0, 0.1, vgui::AnimationController::INTERPOLATOR_ACCEL );
				g_pClientMode->GetViewportAnimationController()->RunAnimationCommand( m_pBlueTeamScore, "wide", m_iAnimBlueTeamScore, 0.0, 0.1, vgui::AnimationController::INTERPOLATOR_ACCEL );
				g_pClientMode->GetViewportAnimationController()->RunAnimationCommand( m_pBlueTeamScoreDropshadow, "wide", m_iAnimBlueTeamScoreDropshadow, 0.0, 0.1, vgui::AnimationController::INTERPOLATOR_ACCEL );
				g_pClientMode->GetViewportAnimationController()->RunAnimationCommand( m_pBlueTeamScoreBG, "wide", m_iAnimBlueTeamScoreBG, 0.0, 0.1, vgui::AnimationController::INTERPOLATOR_ACCEL );
				g_pClientMode->GetViewportAnimationController()->RunAnimationCommand( m_pBluePlayerListBG, "wide",  m_iAnimBluePlayerListBG, 0.0, 0.1, vgui::AnimationController::INTERPOLATOR_ACCEL );
				g_pClientMode->GetViewportAnimationController()->RunAnimationCommand( m_pRedTeamScore, "wide", m_iAnimRedTeamScoreWide, 0.0, 0.1, vgui::AnimationController::INTERPOLATOR_ACCEL );
				g_pClientMode->GetViewportAnimationController()->RunAnimationCommand( m_pRedTeamScore, "xpos", m_iAnimRedTeamScoreXPos, 0.0, 0.1, vgui::AnimationController::INTERPOLATOR_ACCEL );
				g_pClientMode->GetViewportAnimationController()->RunAnimationCommand( m_pRedTeamScoreDropshadow, "wide", m_iAnimRedTeamScoreDropshadowWide, 0.0, 0.1, vgui::AnimationController::INTERPOLATOR_ACCEL );
				g_pClientMode->GetViewportAnimationController()->RunAnimationCommand( m_pRedTeamScoreDropshadow, "xpos", m_iAnimRedTeamScoreDropshadowXPos, 0.0, 0.1, vgui::AnimationController::INTERPOLATOR_ACCEL );
				g_pClientMode->GetViewportAnimationController()->RunAnimationCommand( m_pRedTeamScoreBG, "wide", m_iAnimRedTeamScoreBGWide, 0.0, 0.1, vgui::AnimationController::INTERPOLATOR_ACCEL );
				g_pClientMode->GetViewportAnimationController()->RunAnimationCommand( m_pRedTeamScoreBG, "xpos", m_iAnimRedTeamScoreBGXPos, 0.0, 0.1, vgui::AnimationController::INTERPOLATOR_ACCEL );
				g_pClientMode->GetViewportAnimationController()->RunAnimationCommand( m_pPlayerListRedParent, "wide", m_iAnimRedPlayerListParentWide, 0.0, 0.1, vgui::AnimationController::INTERPOLATOR_ACCEL );
				g_pClientMode->GetViewportAnimationController()->RunAnimationCommand( m_pPlayerListRedParent, "xpos", m_iAnimRedPlayerListParentXPos, 0.0, 0.1, vgui::AnimationController::INTERPOLATOR_ACCEL );
				g_pClientMode->GetViewportAnimationController()->RunAnimationCommand( m_pRedPlayerListBG, "wide", m_iAnimRedPlayerListBGWide, 0.0, 0.1, vgui::AnimationController::INTERPOLATOR_ACCEL );
				g_pClientMode->GetViewportAnimationController()->RunAnimationCommand( m_pRedPlayerListBG, "xpos", m_iAnimRedPlayerListBGXPos, 0.0, 0.1, vgui::AnimationController::INTERPOLATOR_ACCEL );
				g_pClientMode->GetViewportAnimationController()->RunAnimationCommand( m_pBlueTeamWinner, "wide", m_iAnimBlueTeamScore, 0.0, 0.1, vgui::AnimationController::INTERPOLATOR_ACCEL );
				g_pClientMode->GetViewportAnimationController()->RunAnimationCommand( m_pBlueTeamWinnerDropshadow, "wide", m_iAnimBlueTeamScoreDropshadow, 0.0, 0.1, vgui::AnimationController::INTERPOLATOR_ACCEL );
				g_pClientMode->GetViewportAnimationController()->RunAnimationCommand( m_pRedTeamWinner, "wide", m_iAnimRedTeamScoreWide, 0.0, 0.1, vgui::AnimationController::INTERPOLATOR_ACCEL );
				g_pClientMode->GetViewportAnimationController()->RunAnimationCommand( m_pRedTeamWinner, "xpos", m_iAnimRedTeamScoreXPos, 0.0, 0.1, vgui::AnimationController::INTERPOLATOR_ACCEL );
				g_pClientMode->GetViewportAnimationController()->RunAnimationCommand( m_pRedTeamWinnerDropshadow, "wide", m_iAnimRedTeamScoreDropshadowWide, 0.0, 0.1, vgui::AnimationController::INTERPOLATOR_ACCEL );
				g_pClientMode->GetViewportAnimationController()->RunAnimationCommand( m_pRedTeamWinnerDropshadow, "xpos", m_iAnimRedTeamScoreDropshadowXPos, 0.0, 0.1, vgui::AnimationController::INTERPOLATOR_ACCEL );

				int nRedBadgeOffset = m_pPlayerListRedParent->GetXPos() - m_iAnimRedPlayerListParentXPos;
				FOR_EACH_VEC( m_pRedBadgePanels, i )
				{
					g_pClientMode->GetViewportAnimationController()->RunAnimationCommand( m_pRedBadgePanels[i], "xpos", m_pRedBadgePanels[i]->GetXPos() - nRedBadgeOffset, 0.0, 0.1, vgui::AnimationController::INTERPOLATOR_ACCEL );

				}

				float flDelay = MS_STATE_TRANSITION_TO_MEDALS;
					
				if ( pLocalPlayer )
				{
					if ( bShowPerformanceMedals )
					{
						const char *pszEntryName = UTIL_GetRandomSoundFromEntry( "Announcer.CompSummaryScreenOutlierQuestion" );
						if ( pszEntryName && pszEntryName[0] )
						{
							flDelay = enginesound->GetSoundDuration( pszEntryName );
							pLocalPlayer->EmitSound( pszEntryName );
						}
					}
					pLocalPlayer->EmitSound( "MatchMaking.ScoreboardPanelSlide" );
				}

				m_iCurrentState = MS_STATE_STATS;
				m_flNextActionTime = gpGlobals->curtime + flDelay;

				m_pRedMedalsPanel->SetVisible( bShowPerformanceMedals );
				m_pBlueMedalsPanel->SetVisible( bShowPerformanceMedals );

				m_pStatsAndMedals->SetText( bShowPerformanceMedals ? g_pVGuiLocalize->Find( "#TF_CompSummary_StatsAndMedals" ) : L"" );
				m_pStatsAndMedalsShadow->SetText( bShowPerformanceMedals ? g_pVGuiLocalize->Find( "#TF_CompSummary_StatsAndMedals" ) : L"" );
			}
			break;
		}
	case MS_STATE_STATS:
		{
			if ( gpGlobals->curtime > m_flNextActionTime )
			{
				m_iCurrentState = bShowPerformanceMedals ? MS_STATE_BRONZE_MEDALS : MS_STATE_FINAL;
				m_nMedalsRevealed = 0;
				m_flNextActionTime = -1;
			}
			break;
		}
	case MS_STATE_BRONZE_MEDALS:
		{
			if ( gpGlobals->curtime > m_flNextActionTime )
			{
				if ( !m_bBlueBronzeValueRevealed && !m_bRedBronzeValueRevealed )
				{
					m_pBlueMedalsPanel->SetDialogVariable( "blueteammedals_bronze", m_nMedalsToAward_Bronze_Blue );
					m_bBlueBronzeValueRevealed = true;
					Panel *pChild = m_pBlueMedalsPanel->FindChildByName( "BlueBronzeMedalValue" );
					if ( pChild )
					{
						int nXPos, nYPos, nWide, nTall;
						pChild->GetBounds( nXPos, nYPos, nWide, nTall );
						FireMedalEffects( pChild, nXPos, nYPos, nWide, nTall, ( m_nMedalsToAward_Bronze_Blue > 0 ) ? StatMedal_Bronze : StatMedal_None );
					}

					m_pRedMedalsPanel->SetDialogVariable( "redteammedals_bronze", m_nMedalsToAward_Bronze_Red );
					m_bRedBronzeValueRevealed = true;
					pChild = m_pRedMedalsPanel->FindChildByName( "RedBronzeMedalValue" );
					if ( pChild )
					{
						int nXPos, nYPos, nWide, nTall;
						pChild->GetBounds( nXPos, nYPos, nWide, nTall );
						FireMedalEffects( pChild, nXPos, nYPos, nWide, nTall, ( m_nMedalsToAward_Bronze_Red > 0 ) ? StatMedal_Bronze : StatMedal_None );
					}

					m_flNextActionTime = gpGlobals->curtime + MS_STATE_TIME_BETWEEN_MEDALS_CATEGORIES;
				}
				else
				{
					if ( ( nMedalsToAward_Bronze_Total > 0 ) && ( m_nMedalsRevealed < nMedalsToAward_Bronze_Total ) )
					{
						Update();
						m_nMedalsRevealed++;
						m_flNextActionTime = gpGlobals->curtime + MS_STATE_TIME_BETWEEN_MEDALS;
					}
					else
					{
						m_iCurrentState = MS_STATE_SILVER_MEDALS;
						m_nMedalsRevealed = 0;
						m_flNextActionTime = MS_STATE_TIME_BETWEEN_MEDALS_CATEGORIES;
					}
				}
			}
			break;
		}
	case MS_STATE_SILVER_MEDALS:
		{
			if ( gpGlobals->curtime > m_flNextActionTime )
			{
				if ( !m_bBlueSilverValueRevealed && !m_bRedSilverValueRevealed )
				{
					m_pBlueMedalsPanel->SetDialogVariable( "blueteammedals_silver", m_nMedalsToAward_Silver_Blue );
					m_bBlueSilverValueRevealed = true;
					Panel *pChild = m_pBlueMedalsPanel->FindChildByName( "BlueSilverMedalValue" );
					if ( pChild )
					{
						int nXPos, nYPos, nWide, nTall;
						pChild->GetBounds( nXPos, nYPos, nWide, nTall );
						FireMedalEffects( pChild, nXPos, nYPos, nWide, nTall, ( m_nMedalsToAward_Silver_Blue > 0 ) ? StatMedal_Silver : StatMedal_None );
					}

					m_pRedMedalsPanel->SetDialogVariable( "redteammedals_silver", m_nMedalsToAward_Silver_Red );
					m_bRedSilverValueRevealed = true;
					pChild = m_pRedMedalsPanel->FindChildByName( "RedSilverMedalValue" );
					if ( pChild )
					{
						int nXPos, nYPos, nWide, nTall;
						pChild->GetBounds( nXPos, nYPos, nWide, nTall );
						FireMedalEffects( pChild, nXPos, nYPos, nWide, nTall, ( m_nMedalsToAward_Silver_Red > 0 ) ? StatMedal_Silver : StatMedal_None );
					}

					m_flNextActionTime = gpGlobals->curtime + MS_STATE_TIME_BETWEEN_MEDALS_CATEGORIES;
				}
				else
				{
					if ( ( nMedalsToAward_Silver_Total > 0 ) && ( m_nMedalsRevealed < nMedalsToAward_Silver_Total ) )
					{
						Update();
						m_nMedalsRevealed++;
						m_flNextActionTime = gpGlobals->curtime + MS_STATE_TIME_BETWEEN_MEDALS;
					}
					else
					{
						m_iCurrentState = MS_STATE_GOLD_MEDALS;
						m_nMedalsRevealed = 0;
						m_flNextActionTime = MS_STATE_TIME_BETWEEN_MEDALS_CATEGORIES;
					}
				}
			}
			break;
		}
	case MS_STATE_GOLD_MEDALS:
		{
			if ( gpGlobals->curtime > m_flNextActionTime )
			{
				if ( !m_bBlueGoldValueRevealed && !m_bRedGoldValueRevealed )
				{
					m_pBlueMedalsPanel->SetDialogVariable( "blueteammedals_gold", m_nMedalsToAward_Gold_Blue );
					m_bBlueGoldValueRevealed = true;
					Panel *pChild = m_pBlueMedalsPanel->FindChildByName( "BlueGoldMedalValue" );
					if ( pChild )
					{
						int nXPos, nYPos, nWide, nTall;
						pChild->GetBounds( nXPos, nYPos, nWide, nTall );
						FireMedalEffects( pChild, nXPos, nYPos, nWide, nTall, ( m_nMedalsToAward_Gold_Blue > 0 ) ? StatMedal_Gold : StatMedal_None );
					}

					m_pRedMedalsPanel->SetDialogVariable( "redteammedals_gold", m_nMedalsToAward_Gold_Red );
					m_bRedGoldValueRevealed = true;
					pChild = m_pRedMedalsPanel->FindChildByName( "RedGoldMedalValue" );
					if ( pChild )
					{
						int nXPos, nYPos, nWide, nTall;
						pChild->GetBounds( nXPos, nYPos, nWide, nTall );
						FireMedalEffects( pChild, nXPos, nYPos, nWide, nTall, ( m_nMedalsToAward_Gold_Red > 0 ) ? StatMedal_Gold : StatMedal_None );
					}

					m_flNextActionTime = gpGlobals->curtime + MS_STATE_TIME_BETWEEN_MEDALS_CATEGORIES;
				}
				else
				{
					if ( ( nMedalsToAward_Gold_Total > 0 ) && ( m_nMedalsRevealed < nMedalsToAward_Gold_Total ) )
					{
						Update();
						m_nMedalsRevealed++;
						m_flNextActionTime = gpGlobals->curtime + MS_STATE_TIME_BETWEEN_MEDALS;
					}
					else
					{
						m_iCurrentState = MS_STATE_FINAL;
						m_nMedalsRevealed = 0;
						m_flNextActionTime = -1;

						if ( pLocalPlayer )
						{
							const char *pszSoundScriptEntry = "Announcer.CompSummaryScreenOutlierNo"; 
							if ( nMedalsToAward_Bronze_Total || nMedalsToAward_Silver_Total || nMedalsToAward_Gold_Total )
							{
								pszSoundScriptEntry = "Announcer.CompSummaryScreenOutlierYes";
							}

							const char *pszSoundName = UTIL_GetRandomSoundFromEntry( pszSoundScriptEntry );
							m_flMedalSoundTime = gpGlobals->curtime + enginesound->GetSoundDuration( pszSoundName ) + 0.5f;
							pLocalPlayer->EmitSound( pszSoundName );

							IGameEvent *event = gameeventmanager->CreateEvent( "ds_screenshot" );
							if ( event )
							{
								event->SetFloat( "delay", 0.5f );
								gameeventmanager->FireEventClientSide( event );
							}
						}
					}
				}
			}
			break;
		}
	default:
	case MS_STATE_FINAL:
		{
			bool bMedalSoundTimeComplete = ( m_flMedalSoundTime > 0 ) && ( m_flMedalSoundTime < gpGlobals->curtime );

			if ( !m_bXPShown /*&& ( !bShowMedals || bMedalSoundTimeComplete ) */)
			{
				g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( "CompetitiveGame_ShowPvPRankPanel", false );	
				m_bXPShown = true;
			}

			if ( bShowPerformanceMedals )
			{
				if ( bMedalSoundTimeComplete )
				{
					m_flMedalSoundTime = -1.f;
					int iLocalPlayerIndex = GetLocalPlayerIndex();

					if ( ( m_SkillRatings[iLocalPlayerIndex].nScoreRank != StatMedal_None ) ||
						 ( m_SkillRatings[iLocalPlayerIndex].nKillsRank != StatMedal_None ) ||
						 ( m_SkillRatings[iLocalPlayerIndex].nDamageRank != StatMedal_None ) ||
						 ( m_SkillRatings[iLocalPlayerIndex].nHealingRank != StatMedal_None ) ||
						 ( m_SkillRatings[iLocalPlayerIndex].nSupportRank != StatMedal_None ) )
					{
						if ( pLocalPlayer )
						{
							int iClass = RandomInt( TF_CLASS_SCOUT, TF_CLASS_ENGINEER );
							if ( pLocalPlayer->GetPlayerClass() && ( pLocalPlayer->GetPlayerClass()->GetClassIndex() > TF_CLASS_UNDEFINED ) )
							{
								iClass = pLocalPlayer->GetPlayerClass()->GetClassIndex();
							}

							pLocalPlayer->EmitSound( VarArgs( "%s.CompSummaryScreenOutlier", g_aPlayerClassNames_NonLocalized[iClass] ) );
						}
					}
				}
			}

			break;
		}
	}
}

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

void CTFMatchSummary::LevelShutdown( void )
{
	SetVisible( false );
}

//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
bool CTFMatchSummary::ShowPerformanceMedals( void )
{
	bool bDistributePerformanceMedals = false;

	const IMatchGroupDescription* pMatchDesc = GetMatchGroupDescription( TFGameRules()->GetCurrentMatchGroup() );
	if ( pMatchDesc )
	{
		bDistributePerformanceMedals = pMatchDesc->m_params.m_bDistributePerformanceMedals;
	}

	return ( bDistributePerformanceMedals && !m_bPlayerAbandoned );
}
