/*
* VGUI ESF Team Menu
* @author: Joseph 'Pcjoe' Florencio
* @date: December 25th, 2005
*/
#include "vgui_int.h"
#include "VGUI_Font.h"
#include "VGUI_ScrollPanel.h"
#include "VGUI_TextImage.h"

#include "hud.h"
#include "cl_util.h"
#include "vgui_TeamFortressViewport.h"

#define VGUI_BLUEBAR_HEIGHT	59
#define VGUI_REDBAR_HEIGHT	36
#define CLASSMENU_BUTTON_BTNSIZE_WIDE	148
#define CLASSMENU_BUTTON_BTNSIZE_TALL	34
// Creation
CESFTeamMenuPanel::CESFTeamMenuPanel(int iTrans, int iRemoveMe, int x,int y,int wide,int tall) : CMenuPanel(iTrans, iRemoveMe, x,y,wide,tall)
{	// We're going to use the wide and tall variables for the size of all the inner elements, take off one unit to account for border
	wide--;
	tall--;

	// Get the scheme used for the Titles
	CSchemeManager *pSchemes = gViewPort->GetSchemeManager();

	// schemes
	SchemeHandle_t hBlueScheme = pSchemes->getSchemeHandle( "ESF Team Select Blue" );
	SchemeHandle_t hRedScheme = pSchemes->getSchemeHandle( "ESF Team Select Red" );
	SchemeHandle_t hTitleScheme = pSchemes->getSchemeHandle( "ESF Map Title" );
	SchemeHandle_t hTeamInfoText = pSchemes->getSchemeHandle( "Team Info Text" );
	Font *pTitleFont = pSchemes->getFont( hTitleScheme );
	int r, g, b, a;

	int iFadeColors = 150;

	// Create the top blue strip
	Label *pBlueLabel = new Label( "", 0, 0, wide, VGUI_BLUEBAR_HEIGHT );
	pBlueLabel->setParent( this );
	pSchemes->getFgColor( hBlueScheme, r, g, b, a );
	pBlueLabel->setBorder( new LineBorder( Color(r, g, b, 0) ) );
	this->setBorder( new LineBorder( Color(r, g, b, 0) ) );
	pBlueLabel->setFgColor( r, g, b, 255 );
	pSchemes->getBgColor( hBlueScheme, r, g, b, a );
	pBlueLabel->setBgColor( r, g, b, iFadeColors );

	// Create images ontop of blue strip
	CImageLabel *pLeftBlueImg = new CImageLabel( "topbar", 0, (VGUI_BLUEBAR_HEIGHT/2)-(16/2), 256, 16 );
	pLeftBlueImg->setParent( pBlueLabel );

	// Create images ontop of blue strip
	CImageLabel *pRightBlueImg = new CImageLabel( "topbar", wide-256, (VGUI_BLUEBAR_HEIGHT/2)-(16/2), 256, 16 );
	pRightBlueImg->setParent( pBlueLabel );

	// Create choose your team image
	CImageLabel *pChooseTeamImg = new CImageLabel( "chooseyourteam", (wide/2)-(482/2), (VGUI_BLUEBAR_HEIGHT/2)-(32/2), 477, 32 );
	pChooseTeamImg->setParent( pBlueLabel );

	// Create red strip
	Label *pRedLabel = new Label( "", 0, VGUI_BLUEBAR_HEIGHT, wide, VGUI_REDBAR_HEIGHT );
	pRedLabel->setParent( this );
	pSchemes->getFgColor( hBlueScheme, r, g, b, a );
	pRedLabel->setBorder( new LineBorder( Color(r, g, b, 0) ) );
	pRedLabel->setFgColor( r, g, b, 255 );
	pSchemes->getBgColor( hRedScheme, r, g, b, a );
	pRedLabel->setBgColor( r, g, b, iFadeColors );

	// Create good image ontop of red strip
	int iRedIconHeight = 34;
	CImageLabel *pGoodImg = new CImageLabel( "good", 0, (VGUI_REDBAR_HEIGHT/2)-(iRedIconHeight/2), 122, 30 );
	pGoodImg->setParent( pRedLabel );

	// Create evil image ontop of red strip
	CImageLabel *pEvilImg = new CImageLabel( "evil", wide-100, (VGUI_REDBAR_HEIGHT/2)-(iRedIconHeight/2), 100, 30 );
	pEvilImg->setParent( pRedLabel );

	// Create spectate image ontop of red strip
	CImageLabel *pSpecmg = new CImageLabel( "spectate", (wide/2)-(206/2), (VGUI_REDBAR_HEIGHT/2)-(iRedIconHeight/2), 206, 30 );
	pSpecmg->setParent( pRedLabel );

	// setup sizes for following boxes
	int iPadding = 45;
	int iTop = VGUI_REDBAR_HEIGHT+VGUI_BLUEBAR_HEIGHT;
	int iContWide = wide-iPadding*2;
	int iContTall = 449;
	int iCurrentY = iTop+iPadding+iContTall;
	int iFreeSpace = tall-iTop-iContTall-iPadding;

	// Box containing map name and briefing
	Label *pContentCont = new Label( "", iPadding, iTop+iPadding, iContWide, iContTall );
	pContentCont->setParent( this );
	pSchemes->getFgColor( hBlueScheme, r, g, b, a );
	pContentCont->setBorder( new LineBorder( Color(r, g, b, 0) ) );
	pContentCont->setFgColor( r, g, b, 255 );
	pContentCont->setBgColor( 255, 255, 255, 255 );

	// Create the Map Name Label
	Label *pMapTitle = new Label( "", 16, 16, iContWide, 32 );
	pMapTitle->setParent( pContentCont );
	pMapTitle->setFont(pTitleFont);
	pSchemes->getFgColor( hTitleScheme, r, g, b, a );
	pMapTitle->setFgColor( r, g, b, 0 );
	pMapTitle->setBgColor( 255, 255, 255, 255 );
	pMapTitle->setContentAlignment( vgui::Label::a_west );
	m_pMapTitle = pMapTitle;

	// Create the Scroll panel
	int iScrollPanelWide = iContWide-33;
	int iScrollPanelTall = iContTall-64;
	CTFScrollPanel *pScrollPanel = new CTFScrollPanel( 32, 64, iScrollPanelWide, iScrollPanelTall );
	pScrollPanel->setParent(pContentCont);
	pScrollPanel->setScrollBarVisible(false, false);
	m_pScrollPanel = pScrollPanel;

	// Create the Map Briefing panel
	TextPanel *pBriefing = new TextPanel("", 0,0, iScrollPanelWide-16, iScrollPanelTall-16 );
	pBriefing->setParent( pScrollPanel->getClient() );
	pSchemes->getFgColor( hTitleScheme, r, g, b, a );
	pBriefing->setFgColor( r, g, b, a );
	pBriefing->setBgColor( 255, 255, 255, 255 );
	pBriefing->setText( gHUD.m_TextMessage.BufferedLocaliseTextString("#Map_Description_not_available") );
	m_pBriefing = pBriefing;
	pScrollPanel->validate();
	
	// Team Menu buttons
	for (int i = 1; i <= 5; i++)
	{
		char sz[256];
		switch(i)
		{
			// Good
		case 1:
			m_pButtons[i] = new CommandButtonNoDraw( "", 0, 0, 124, VGUI_REDBAR_HEIGHT-1, true);
			m_pButtons[i]->setParent( pRedLabel );
			m_pButtons[i]->setBgColor( 0,0,0, 255 );
			m_pButtons[i]->setFgColor( 0,0,0, 255 );
			break;
			// Evil
		case 2:
			m_pButtons[i] = new CommandButtonNoDraw( "", wide-93, 0, 93, VGUI_REDBAR_HEIGHT-1, true);
			m_pButtons[i]->setParent( pRedLabel );
			m_pButtons[i]->setBgColor( 0,0,0, 255 );
			m_pButtons[i]->setFgColor( 0,0,0, 255 );
			break;
			// Auto Assign
		default:
		case 5:
			m_pButtons[i] = new ImageCommandButton( 0, 0, CLASSMENU_BUTTON_BTNSIZE_WIDE, CLASSMENU_BUTTON_BTNSIZE_TALL, "autoassign_btn", "autoassign_mo_btn");
			m_pButtons[i]->setParent( this );
			m_pButtons[i]->setBgColor( 0,0,0, 255 );
			m_pButtons[i]->setFgColor( 0,0,0, 255 );
			m_pButtons[i]->addInputSignal( new CHandler_ButtonHighlight(m_pButtons[i]) );
			break;
		}

		// Team button
		m_pButtons[i]->setContentAlignment( vgui::Label::a_west );
		m_pButtons[i]->setVisible( false );

		// AutoAssign button uses special case
		if (i == 5)
		{	m_pButtons[5]->setBoundKey( '5' );
			m_pButtons[5]->setVisible( true );
		}

		// Create the Signals
		sprintf(sz, "jointeam %d", i);
		m_pButtons[i]->addActionSignal( new CMenuHandler_StringCommandWatch( sz, true ) );
		// Pcjoe: This makes the mouse over image look weird, not required for auto assign
		if(i != 5)
		{	m_pButtons[i]->addInputSignal( new CHandler_MenuButtonOver(this, i) );
		}

		// Create the Team Info panel
		m_pTeamInfoPanel[i] = new TextPanel("", iPadding, iCurrentY, wide-iPadding*2, iFreeSpace );
		m_pTeamInfoPanel[i]->setParent( this );
		m_pTeamInfoPanel[i]->setFont( pSchemes->getFont(hTeamInfoText) );
		m_pTeamInfoPanel[i]->setFgColor(	iTeamColors[i % iNumberOfTeamColors][0],
											iTeamColors[i % iNumberOfTeamColors][1],
											iTeamColors[i % iNumberOfTeamColors][2],
											0 );
		m_pTeamInfoPanel[i]->setBgColor( 0,0,0, 255 );
	}

	// Create the Cancel button
	int iCancelPadding = 15;
	m_pCancelButton = new ImageCommandButton( wide-iCancelPadding-CLASSMENU_BUTTON_BTNSIZE_WIDE, tall-iCancelPadding-CLASSMENU_BUTTON_BTNSIZE_TALL, CLASSMENU_BUTTON_BTNSIZE_WIDE+2, CLASSMENU_BUTTON_BTNSIZE_TALL+2, "cancel_btn", "cancel_mo_btn");
	m_pCancelButton->setParent( this );
	m_pCancelButton->addActionSignal( new CMenuHandler_TextWindow(HIDE_TEXTWINDOW) );
	m_pCancelButton->addInputSignal( new CHandler_ButtonHighlight(m_pCancelButton) );
	pSchemes->getFgColor( hBlueScheme, r, g, b, a );
	m_pCancelButton->setBorder( new LineBorder( Color(r, g, b, 0) ) );
	// set auto assign button right above cancel button
	int iCX,iCY;
	m_pCancelButton->getPos(iCX,iCY);
	m_pButtons[5]->setPos(iCX,iCY-iCancelPadding-CLASSMENU_BUTTON_BTNSIZE_TALL);
	m_pButtons[5]->setSize(CLASSMENU_BUTTON_BTNSIZE_WIDE+2, CLASSMENU_BUTTON_BTNSIZE_TALL+2);
	pSchemes->getFgColor( hBlueScheme, r, g, b, a );
	m_pButtons[5]->setBorder( new LineBorder( Color(r, g, b, 0) ) );
	m_pButtons[5]->setContentAlignment( vgui::Label::a_center );

	// Create the Spectate button
	m_pSpectateButton = new SpectateButtonNoDraw( "", (wide/2)-(206/2)+4, 0, 206, VGUI_REDBAR_HEIGHT-1, true);
	m_pSpectateButton->setParent( pRedLabel );
	m_pSpectateButton->addActionSignal( new CMenuHandler_StringCommand( "spectate", true ) );
	m_pSpectateButton->setBoundKey( '6' );
	m_pSpectateButton->addInputSignal( new CHandler_MenuButtonOver(this, 6) );
	m_pSpectateButton->setBgColor( 0,0,0, 255 );
	m_pSpectateButton->setFgColor( 0,0,0, 255 );
	m_pSpectateButton->setButtonBorderEnabled(false);

	Initialize();
}

//-----------------------------------------------------------------------------
// Purpose: Called each time a new level is started.
//-----------------------------------------------------------------------------
void CESFTeamMenuPanel::Initialize( void )
{
	m_bUpdatedMapName = false;
	m_iCurrentInfo = 0;
	m_pScrollPanel->setScrollValue( 0, 0 );
}

//-----------------------------------------------------------------------------
// Purpose: Called everytime the Team Menu is displayed
//-----------------------------------------------------------------------------
void CESFTeamMenuPanel::Update( void )
{
	// Set the team buttons
	for (int i = 1; i <= 4; i++)
	{
		if (m_pButtons[i])
		{
			if ( i <= gViewPort->GetNumberOfTeams() )
			{	// bound key replacement
				char sz[32]; 
				sprintf( sz, "%d", i );
				m_pButtons[i]->setBoundKey( sz[0] );
				m_pButtons[i]->setVisible( true );

				// Start with the first option up
				if (!m_iCurrentInfo)
					SetActiveInfo( i );

				char szPlayerList[ (MAX_PLAYER_NAME_LENGTH + 3) * 31 ];  // name + ", "
				strcpy(szPlayerList, "\n");
				// Update the Team Info
				// Now count the number of teammembers of this class
				int iTotal = 0;
				for ( int j = 1; j < MAX_PLAYERS; j++ )
				{
					if ( g_PlayerInfoList[j].name == NULL )
						continue; // empty player slot, skip
					if ( g_PlayerInfoList[j].thisplayer )
						continue; // skip this player
					if ( g_PlayerExtraInfo[j].teamnumber != i )
						continue; // skip over players in other teams

					iTotal++;
					if (iTotal > 1)
						strncat( szPlayerList, ", ", sizeof(szPlayerList) - strlen(szPlayerList) );
					strncat( szPlayerList, g_PlayerInfoList[j].name, sizeof(szPlayerList) - strlen(szPlayerList) );
					szPlayerList[ sizeof(szPlayerList) - 1 ] = '\0';
				}

				if (iTotal > 0)
				{
					// Set the text of the info Panel
					char szText[ ((MAX_PLAYER_NAME_LENGTH + 3) * 31) + 256 ]; 
					if (iTotal == 1)
						sprintf(szText, "%s: %d Player (%d points)", gViewPort->GetTeamName(i), iTotal, g_TeamInfo[i].frags );
					else
						sprintf(szText, "%s: %d Players (%d points)", gViewPort->GetTeamName(i), iTotal, g_TeamInfo[i].frags );
					strncat( szText, szPlayerList, sizeof(szText) - strlen(szText) );
					szText[ sizeof(szText) - 1 ] = '\0';

					m_pTeamInfoPanel[i]->setText( szText );
				}
				else
				{
					m_pTeamInfoPanel[i]->setText( "" );
				}
			}
			else
			{
				// Hide the button (may be visible from previous maps)
				m_pButtons[i]->setVisible( false );
			}
		}
	}

	// Spectate button
	if (m_pSpectateButton->IsNotValid())
	{	m_pSpectateButton->setVisible( false );
	}
	else
	{	m_pSpectateButton->setVisible( true );
	}
	
	// If the player is already in a team, make the cancel button visible
	if ( g_iTeamNumber )
	{	m_pCancelButton->setVisible( true );
	}
	else
	{	m_pCancelButton->setVisible( false );
	}

	// Set the Map Title
	if (!m_bUpdatedMapName)
	{
		const char *level = gEngfuncs.pfnGetLevelName();
		if (level && level[0])
		{
			char sz[256]; 
			char szTitle[256]; 
			char *ch;

			// Update the level name
			strcpy( sz, level );
			ch = strchr( sz, '/' );
			if (!ch)
				ch = strchr( sz, '\\' );
			strcpy( szTitle, ch+1 );
			ch = strchr( szTitle, '.' );
			*ch = '\0';
			m_pMapTitle->setText( szTitle );
			*ch = '.';

			// Update the map briefing
			strcpy( sz, level );
			ch = strchr( sz, '.' );
			*ch = '\0';
			strcat( sz, ".txt" );
			char *pfile = (char*)gEngfuncs.COM_LoadFile( sz, 5, NULL );
			if (pfile)
			{
				m_pBriefing->setText( pfile );

				// Get the total size of the Briefing text and resize the text panel
				int iXSize, iYSize;
				m_pBriefing->getTextImage()->getTextSize( iXSize, iYSize );
				m_pBriefing->setSize( iXSize, iYSize );
			}

			m_bUpdatedMapName = true;
		}
	}

	m_pScrollPanel->validate();
}

//=====================================
// Key inputs
bool CESFTeamMenuPanel::SlotInput( int iSlot )
{
	// Check for AutoAssign
	if ( iSlot == 5)
	{
		m_pButtons[5]->fireActionSignal();
		return true;
	}

	// Spectate
	if ( iSlot == 6)
	{
		m_pSpectateButton->fireActionSignal();
		return true;
	}

	// Otherwise, see if a particular team is selectable
	if ( (iSlot < 1) || (iSlot > gViewPort->GetNumberOfTeams()) )
		return false;
	if ( !m_pButtons[ iSlot ] )
		return false;

	// Is the button pushable?
	if ( m_pButtons[ iSlot ]->isVisible() )
	{
		m_pButtons[ iSlot ]->fireActionSignal();
		return true;
	}

	return false;
}

//======================================
// Update the Team menu before opening it
void CESFTeamMenuPanel::Open( void )
{	Update();
	CMenuPanel::Open();
}

void CESFTeamMenuPanel::paintBackground()
{
	// make sure we get the map briefing up
	if ( !m_bUpdatedMapName )
		Update();

	CMenuPanel::paintBackground();
}

//======================================
// Mouse is over a team button, bring up the class info
void CESFTeamMenuPanel::SetActiveInfo( int iInput )
{
	// Remove all the Info panels and bring up the specified one
	m_pSpectateButton->setArmed( false );
	for (int i = 1; i <= 5; i++)
	{
		m_pButtons[i]->setArmed( false );
		m_pTeamInfoPanel[i]->setVisible( false );
	}

	// 6 is Spectate
	if (iInput == 6)
	{
		m_pSpectateButton->setArmed( true );
	}
	else
	{
		m_pButtons[iInput]->setArmed( true );
		m_pTeamInfoPanel[iInput]->setVisible( true );
	}

	m_iCurrentInfo = iInput;

	m_pScrollPanel->validate();
}