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

#include "hud.h"
#include "cl_util.h"
#include "camera.h"
#include "kbutton.h"
#include "cvardef.h"
#include "usercmd.h"
#include "const.h"
#include "camera.h"
#include "in_defs.h"
#include "parsemsg.h"
#include "ref_params.h"

#include "vgui_int.h"
#include "vgui_TeamFortressViewport.h"
#include "vgui_ServerBrowser.h"
#include "vgui_esfclassmenu.h"

#include "mdlcontrol.h"
#include "modelvgui.h"

#define VGUI_BLUEBAR_HEIGHT	59
#define VGUI_REDBAR_HEIGHT	36

// Class Menu Dimensions
#define CLASSMENU_BUTTON_INIT_PADDING	13
#define CLASSMENU_BUTTON_BTNSIZE_WIDE	148
#define CLASSMENU_BUTTON_BTNSIZE_TALL	34
#define CLASSMENU_BUTTON_BTN_PADDING	7
#define VGUI_MODEL_PANEL_HEIGHT	480

// Mouse pressed
void CBulletInputSignal::mousePressed(MouseCode code,Panel* panel) 
{	// If we can unselect, leave the current button alone and let us turn it off and on
	if(m_pBulletedList->canUnselect())
	{	m_pBulletedList->Reset(m_pButton);
	}
	else
	{	m_pBulletedList->Reset();
	}
	m_pButton->flipArmed();
	// Call update function on master panel
//	m_pBulletedList->printCallback();
	m_pBulletedList->getMasterPanel()->Update();
}


// Destructor
CESFClassMenuPanel::~CESFClassMenuPanel()
{	for(int i=0; i<PC_LASTCLASS; i++)
	{	delete m_pCharacterPortrait[i];
		delete m_pFormBulletList[i];
		delete m_pCustomModelBulletList[i];
		std::map<std::string,CBulletedList*>::iterator iterDel;
		ForEachIn(iterDel, m_AttacksBulletedList[i])
		{	delete iterDel->second;
		}
		m_AttacksBulletedList[i].clear();
		m_StatPanels[i].clear();
	}
}
// CUSTOM SCROLLPANEL
CESFClassScrollButton::CESFClassScrollButton( std::string strArrow, const char* text,int x,int y,int wide,int tall) : CommandButton(text,x,y,wide,tall)
{
	// Set text color to orange
	setFgColor(Scheme::sc_primary1);

	// Load in the arrow
	m_pTGA = LoadTGAForRes( strArrow.c_str() );
	setImage( m_pTGA );

	// Highlight signal
	InputSignal *pISignal = new CHandler_CommandButtonHighlight(this);
	addInputSignal(pISignal);
}

void CESFClassScrollButton::paint( void )
{
	if (!m_pTGA)
		return;

	// draw armed button text in white
	if ( isArmed() )
	{
		m_pTGA->setColor( Color(255,255,255, 0) );
	}
	else
	{
		m_pTGA->setColor( Color(255,255,255, 128) );
	}

	m_pTGA->doPaint(this);
}

void CESFClassScrollButton::paintBackground( void )
{
}

void CESFClassSlider::paintBackground( void )
{
	int r,g,b,a;
	// Get the scheme used for the Titles
	CSchemeManager *pSchemes = gViewPort->GetSchemeManager();
	SchemeHandle_t hBlueScheme = pSchemes->getSchemeHandle( "ESF Team Select Blue" );
	pSchemes->getFgColor( hBlueScheme, r, g, b, a );

	int wide,tall,nobx,noby;
	getPaintSize(wide,tall);
	getNobPos(nobx,noby);

	// Border
	drawSetColor(r,g,b,128);
	drawOutlinedRect( 0,0,wide,tall );

	if( isVertical() )
	{	// Nob Outline
		drawSetColor(r,g,b,0);
		drawOutlinedRect( 0,nobx,wide,noby );
	}
	// Pcjoe: No horizontal bars
}

CESFClassScrollPanel::CESFClassScrollPanel(int x,int y,int wide,int tall) : ScrollPanel(x,y,wide,tall)
{
	ScrollBar *pScrollBar = getVerticalScrollBar();
	pScrollBar->setButton( new CESFClassScrollButton( "esf_arrowup", "", 0,0,16,16 ), 0 );
	pScrollBar->setButton( new CESFClassScrollButton( "esf_arrowdown", "", 0,0,16,16 ), 1 );
	pScrollBar->setSlider( new CESFClassSlider(0,wide-1,wide,(tall-(wide*2))+2,true) ); 
	pScrollBar->setPaintBorderEnabled(false);
	pScrollBar->setPaintBackgroundEnabled(false);
	pScrollBar->setPaintEnabled(false);

	pScrollBar = getHorizontalScrollBar();
	pScrollBar->setButton( new CESFClassScrollButton( "esf_arrowup", "", 0,0,16,16 ), 0 );
	pScrollBar->setButton( new CESFClassScrollButton( "esf_arrowdown", "", 0,0,16,16 ), 1 );
	pScrollBar->setSlider( new CESFClassSlider(tall,0,wide-(tall*2),tall,false) );
	pScrollBar->setPaintBorderEnabled(false);
	pScrollBar->setPaintBackgroundEnabled(false);
	pScrollBar->setPaintEnabled(false);

	//force the scrollbars on, so after the validate clientClip will be smaller
	setScrollBarAutoVisible(false, false);
	setScrollBarVisible(false, true);
}

void CESFClassScrollPanel::validate()
{	ScrollPanel::validate();

	// Set Position
	ScrollBar *pScrollBar = getVerticalScrollBar();
	pScrollBar->setPos(1,0);
	getClient()->setPos(0,0);
	int wide,tall;
	getSize(wide,tall);
	getClient()->setSize(wide,tall);
	getClientClip()->setSize(wide-16,tall);
	getClientClip()->setPos(17,0);
}

// Color scroll
CESFColorScrollButton::CESFColorScrollButton(std::string strArrow, const char* text,int x,int y,int wide,int tall, Color fg) : CommandButton(text,x,y,wide,tall)
{
	// Set color
	setFgColor(fg[0],fg[1],fg[2],fg[3]);

	// Load in the arrow
	m_pTGA = LoadTGAForRes( strArrow.c_str() );
	setImage( m_pTGA );

	// Highlight signal
	InputSignal *pISignal = new CHandler_CommandButtonHighlight(this);
	addInputSignal(pISignal);
}

void CESFColorScrollButton::paint( void )
{
	if (!m_pTGA)
		return;

	// draw armed button text in white
	if ( isArmed() )
	{
		m_pTGA->setColor( Color(255,255,255, 0) );
	}
	else
	{
		m_pTGA->setColor( Color(255,255,255, 128) );
	}

	m_pTGA->doPaint(this);
}

void CESFColorScrollButton::paintBackground( void )
{
/*
	if ( isArmed() )
	{
		// Orange highlight background
		drawSetColor( Scheme::sc_primary2 );
		drawFilledRect(0,0,_size[0],_size[1]);
	}

	// Orange Border
	drawSetColor( Scheme::sc_secondary1 );
	drawOutlinedRect(0,0,_size[0]-1,_size[1]);
*/
}

void CESFColorSlider::paintBackground( void )
{
	int wide,tall,nobx,noby;
	getPaintSize(wide,tall);
	getNobPos(nobx,noby);

	int iFGr, iFGg, iFGb, iFGa;
	int iBGr, iBGg, iBGb, iBGa;
	getFgColor(iFGr, iFGg, iFGb, iFGa);
	getBgColor(iBGr, iBGg, iBGb, iBGa);
	// Border
	drawSetColor(iFGr, iFGg, iFGb, iFGa);
	drawOutlinedRect( 0,0,wide,tall );

	if( isVertical() )
	{
		// Nob Fill
		drawSetColor(iBGr, iBGg, iBGb, iBGa);
		drawFilledRect( 0,nobx,wide,noby );

		// Nob Outline
		drawSetColor(iFGr, iFGg, iFGb, iFGa);
		drawOutlinedRect( 0,nobx,wide,noby );
	}
	else
	{
		// Nob Fill
		drawSetColor(iBGr, iBGg, iBGb, iBGa);
		drawFilledRect( nobx,0,noby,tall );

		// Nob Outline
		drawSetColor(iFGr, iFGg, iFGb, iFGa);
		drawOutlinedRect( nobx,0,noby,tall );
	}
}

CESFColorScrollPanel::CESFColorScrollPanel(int x,int y,int wide,int tall, Color fg, Color bg) : ScrollPanel(x,y,wide,tall)
{
	ScrollBar *pScrollBar = getVerticalScrollBar();
	pScrollBar->setButton( new CESFColorScrollButton( "esf_arrowup", "", 0,0,16,16, fg ), 0 );
	pScrollBar->setButton( new CESFColorScrollButton( "esf_arrowdown", "", 0,0,16,16, fg ), 1 );
	pScrollBar->setSlider( new CESFColorSlider(0,wide-1,wide,(tall-(wide*2))+2,true, fg, bg) ); 
	pScrollBar->setPaintBorderEnabled(false);
	pScrollBar->setPaintBackgroundEnabled(false);
	pScrollBar->setPaintEnabled(false);

	pScrollBar = getHorizontalScrollBar();
	pScrollBar->setButton( new CESFColorScrollButton( "esf_arrowup", "", 0,0,16,16, fg ), 0 );
	pScrollBar->setButton( new CESFColorScrollButton( "esf_arrowdown", "", 0,0,16,16, fg ), 1 );
	pScrollBar->setSlider( new CESFColorSlider(tall,0,wide-(tall*2),tall,false, fg, bg) );
	pScrollBar->setPaintBorderEnabled(false);
	pScrollBar->setPaintBackgroundEnabled(false);
	pScrollBar->setPaintEnabled(false);
}



struct maxstat_info_s
{	std::map<std::string,float> data;
};

int lower_case ( int c )
{	return tolower ( c );
}

int g_iModelPosX=0,g_iModelPosY=0;
// Creation
CESFClassMenuPanel::CESFClassMenuPanel(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--;

	// clear
	setCurrentForm("");
	setCustomModel("");
	setRotate(0);
	setCurrentlyRotating( false );
	setMouseXPrev(-1);
	setDrawCycle(0);

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

	// schemes
	SchemeHandle_t hTitleScheme = pSchemes->getSchemeHandle( "Title Font" );
	SchemeHandle_t hClassWindowText = pSchemes->getSchemeHandle( "Briefing Text" );
	SchemeHandle_t hBlueScheme = pSchemes->getSchemeHandle( "ESF Team Select Blue" );
	SchemeHandle_t hRedScheme = pSchemes->getSchemeHandle( "ESF Team Select Red" );
	SchemeHandle_t hTextScheme = pSchemes->getSchemeHandle( "ESF Team Select Text" );

	// Before everything, create 4 transparent panesl we're going to use to cut a dark fade around the model portrait
	int iFadeAmt = 100;
	CTransparentPanel *pFadePanel1 = new CTransparentPanel(iFadeAmt,0,0,0,0);
	pFadePanel1->setParent(this);
	CTransparentPanel *pFadePanel2 = new CTransparentPanel(iFadeAmt,0,0,0,0);
	pFadePanel2->setParent(this);
	CTransparentPanel *pFadePanel3 = new CTransparentPanel(iFadeAmt,0,0,0,0);
	pFadePanel3->setParent(this);
	CTransparentPanel *pFadePanel4 = new CTransparentPanel(iFadeAmt,0,0,0,0);
	pFadePanel4->setParent(this);

	// color schemes
	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 *pChooseClassImg = new CImageLabel( "selectyourclass", (wide/2)-(486/2), (VGUI_BLUEBAR_HEIGHT/2)-(32/2), 477, 32 );
	pChooseClassImg->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 class image ontop of red strip
	int iRedIconHeight = 34;
	CImageLabel *pClassImg = new CImageLabel( "class", 0, (VGUI_REDBAR_HEIGHT/2)-(iRedIconHeight/2), 128, 30 );
	pClassImg->setParent( pRedLabel );

	// Create side panel container for class buttons
	int iTop = VGUI_BLUEBAR_HEIGHT+VGUI_REDBAR_HEIGHT;
	int iLeft = 182;
	Label *pClassButtonLabel = new Label( "", 0, iTop, iLeft, tall-iTop );
	pClassButtonLabel->setParent( this );
	pSchemes->getFgColor( hBlueScheme, r, g, b, a );
	pClassButtonLabel->setBorder( new LineBorder( Color(r, g, b, 0) ) );
	pClassButtonLabel->setFgColor( r, g, b, 255 );
	pSchemes->getBgColor( hBlueScheme, r, g, b, a );
	pClassButtonLabel->setBgColor( r, g, b, iFadeColors );

	// Create panel that holds 3d model, form data, and custom model data
	m_pModelLabel = new Label( "", iLeft+27, iTop+16, 405, 607 );
	pSchemes->getFgColor( hBlueScheme, r, g, b, a );
	m_pModelLabel->setBorder( new LineBorder( Color(r, g, b, 0) ) );
	m_pModelLabel->setBgColor( r, g, b, 255 );
	m_pModelLabel->setParent( this );
	// Set screen model position
	g_iModelPosX=x+iLeft+27;
	g_iModelPosY=y+iTop+16;

	// Set invisible panel over model select for rotation
	CommandButtonNoDraw *pRotBtn = new CommandButtonNoDraw( "", iLeft+27, iTop+16, 405, VGUI_MODEL_PANEL_HEIGHT, true);
	pRotBtn->setParent(this);
	pRotBtn->addInputSignal( new CRotateInputSignal() );

	// Setup reset button
	int iCenterXReset = 405/2 - 80/2;
	ImageCommandButton *pResetRot = new ImageCommandButton( iCenterXReset, VGUI_MODEL_PANEL_HEIGHT-22, 80+2, 20+2, "reset_btn", "reset_mo_btn");
	pResetRot->addInputSignal( new CRotateResetInputSignal() );
	pResetRot->addInputSignal( new CHandler_ButtonHighlight(pResetRot) );
	pSchemes->getFgColor( hBlueScheme, r, g, b, a );
	pResetRot->setBorder( new LineBorder( Color(r, g, b, 0) ) );
	pResetRot->setParent( pRotBtn );

	// We know the dimentions and pos of the model label, set sizes of the fade panels
	pFadePanel1->setPos(0,0);
	pFadePanel1->setSize(iLeft+27, tall);
	pFadePanel2->setPos(iLeft+27,0);
	pFadePanel2->setSize(wide-(iLeft-27), 16+iTop);
	pFadePanel3->setPos(iLeft+27,iTop+16+VGUI_MODEL_PANEL_HEIGHT);
	pFadePanel3->setSize(wide-(iLeft-27), tall-(iTop+16+VGUI_MODEL_PANEL_HEIGHT));
	pFadePanel4->setPos(iLeft+27+405,iTop+16);
	pFadePanel4->setSize(wide-(iLeft+27+405),VGUI_MODEL_PANEL_HEIGHT);

	// Character form and custom model image frame
	Label *pCfCmFrame = new Label( "", -1, VGUI_MODEL_PANEL_HEIGHT, 405, 26 );
	pCfCmFrame->setParent( m_pModelLabel );
	pSchemes->getFgColor( hBlueScheme, r, g, b, a );
	pCfCmFrame->setBorder( new LineBorder( Color(r, g, b, 0) ) );
	pCfCmFrame->setFgColor( r, g, b, 255 );
	pCfCmFrame->setBgColor( r, g, b, 255 );

	// Character Form Img
	CImageLabel *pCharacterFormImg = new CImageLabel( "characterform", 3, 1, 191, 20);
	pCharacterFormImg->setParent( pCfCmFrame );

	// Custom Model Img
	CImageLabel *pCustomModelImg = new CImageLabel( "custommodel", 405-200, 1, 190, 20);
	pCustomModelImg->setParent( pCfCmFrame );
		
	// Create the Scroll panel
	int iScrollWidth = 185;
	m_pCMScrollPanel = new CESFClassScrollPanel( 405-iScrollWidth-8, VGUI_MODEL_PANEL_HEIGHT+27+7,iScrollWidth,84 );
	m_pCMScrollPanel->setParent(m_pModelLabel);
	pSchemes->getFgColor( hBlueScheme, r, g, b, a );
	m_pCMScrollPanel->setBorder( new LineBorder( Color(r,g,b,0) ) );
	m_pCMScrollPanel->validate();
	int clientWide=iScrollWidth-17;

	// Create attack label (for moving attack icons all at the same time)
	m_pAttackPanel = new CTransparentPanel(255,iLeft+434,iTop+280,393,1024);
	m_pAttackPanel->setParent(this);
	// Create Image for attacks
	int iAtkCenterX = (393/2)-(140/2);
	CImageLabel *pAttackImg = new CImageLabel( "attacks", iAtkCenterX, 0, 140, 20 );
	pAttackImg->setParent(m_pAttackPanel);

	// Create statistics panel
	int iStatPanelPadding = 16;
	int iStatPanelWide = wide-(iLeft+27+405+iStatPanelPadding*2);
	m_pStatPanel = new Label( "", iLeft+27+405+iStatPanelPadding, iTop+16, iStatPanelWide, 200 );
	m_pStatPanel->setParent(this);
	pSchemes->getFgColor( hBlueScheme, r, g, b, a );
	m_pStatPanel->setBorder( new LineBorder( Color(r, g, b, 0) ) );
	m_pStatPanel->setFgColor( r, g, b, 255 );
	m_pStatPanel->setBgColor( r, g, b, 255 );

	// Create stats image label
	CImageLabel *pStatsImg = new CImageLabel( "statistics", 2, 4, 180, 20 );
	pStatsImg->setParent(m_pStatPanel);

	// Create character bio
	int charBioTall = 130;
	m_pCharacterBio = new Label( "", iLeft+27+405+iStatPanelPadding, iTop+16+200+16, iStatPanelWide, charBioTall );
	m_pCharacterBio->setParent(this);
	pSchemes->getFgColor( hBlueScheme, r, g, b, a );
	m_pCharacterBio->setBorder( new LineBorder( Color(r, g, b, 0) ) );
	m_pCharacterBio->setFgColor( r, g, b, 255 );
	m_pCharacterBio->setBgColor( r, g, b, 255 );

	// Create character bio image label
	CImageLabel *pCharBioImg = new CImageLabel( "characterbio", 2, 4, 180, 20 );
	pCharBioImg->setParent(m_pCharacterBio);
	
	// Create the Scroll panel
	int iBioPanelPad = 20;
	int iBioPanelWide = iStatPanelWide-iBioPanelPad*2;
	int iBioPanelTall = charBioTall-(20+32);
	m_pCharacterBioSP = new CESFColorScrollPanel( iBioPanelPad, 20+iBioPanelPad, iBioPanelWide, charBioTall-(20+32), Color(r,g,b,0), Color(0,0,0,255) );
	m_pCharacterBioSP->setParent(m_pCharacterBio);
	pSchemes->getFgColor( hBlueScheme, r, g, b, a );
	m_pCharacterBioSP->setBorder( new LineBorder( Color(r, g, b, 0) ) );

	// enable scrollbars
	m_pCharacterBioSP->setScrollBarAutoVisible(false, false);
	m_pCharacterBioSP->setScrollBarVisible(false, true);
	m_pCharacterBioSP->validate();

	int clientBioWide=m_pCharacterBioSP->getClientClip()->getWide();

	// Create attack info panel
	int charAtkInfoTall = 140;
	m_pAttackInfo = new Label( "", iLeft+27+405+iStatPanelPadding, iTop+16+200+16+charBioTall+16, iStatPanelWide, charAtkInfoTall );
	m_pAttackInfo->setParent(this);
	pSchemes->getFgColor( hBlueScheme, r, g, b, a );
	m_pAttackInfo->setBorder( new LineBorder( Color(r, g, b, 0) ) );
	m_pAttackInfo->setFgColor( r, g, b, 255 );
	m_pAttackInfo->setBgColor( r, g, b, 255 );

	// Create character bio image label
	CImageLabel *pAttackInfoImg = new CImageLabel( "attackinfo", 2, 4, 180, 20 );
	pAttackInfoImg->setParent(m_pAttackInfo);
	
	// Create the Scroll panel (use bio panel info)
	int iAtkInfoPanelTall = charAtkInfoTall-(20+32);
	m_pAttackInfoSP = new CESFColorScrollPanel( iBioPanelPad, 20+iBioPanelPad, iBioPanelWide, iAtkInfoPanelTall, Color(r,g,b,0), Color(0,0,0,255) );
	m_pAttackInfoSP->setParent(m_pAttackInfo);
	pSchemes->getFgColor( hBlueScheme, r, g, b, a );
	m_pAttackInfoSP->setBorder( new LineBorder( Color(r, g, b, 0) ) );

	// enable scrollbars
	m_pAttackInfoSP->setScrollBarAutoVisible(false, false);
	m_pAttackInfoSP->setScrollBarVisible(false, true);
	m_pAttackInfoSP->validate();

	int clientAtkInfoWide=m_pAttackInfoSP->getClientClip()->getWide();


	/*
	* NOTE - Pcjoe: The random +2 for the sizes are so the border is visible. Elsewise, the images will cut off the borders
	*/
	// Loop through all of the classes and parse the character portrait information first
	int cp;
	for(cp = 0; cp < PC_LASTCLASS; cp++ )
	{	// Create 3d VGUI portraits
		m_pCharacterPortrait[cp] = new CCharacterVgui(sTFClassSelection[cp]);
	}

	// Loop through a second time to find the max values for all of the stats
	std::vector<maxstat_info_s> max_stat_info;
	for(int iTransLevel=0; true; iTransLevel++)
	{	bool bFoundResult = false;
		for( cp = 0; cp < PC_LASTCLASS; cp++ )
		{	std::list<CCharacterFormVgui> forms = (*m_pCharacterPortrait[cp]->getForms());
			std::list<CCharacterFormVgui>::iterator iterForm;
			int iCount = 0;
			ForEachIn(iterForm, forms)
			{	if(iCount == iTransLevel)
				{	bFoundResult = true;
					maxstat_info_s infolevel;
					// Get data
					if(signed(max_stat_info.size()) > iTransLevel)
					{	infolevel = max_stat_info[iTransLevel];
					}

					// Calc max stat
					std::map<std::string,float> statList = iterForm->getStatistics();
					std::map<std::string,float>::iterator iterStat;
					ForEachIn(iterStat, statList)
					{	std::map<std::string,float>::iterator iterFind = infolevel.data.find(iterStat->first);
						// We have a previous entry, only overwrite if we're larger
						if(iterFind != infolevel.data.end())
						{	if(iterFind->second < iterStat->second)
							{	iterFind->second = iterStat->second;
							}
						}
						// First entry with name
						else
						{	infolevel.data[iterStat->first] = iterStat->second;
						}
					}

					// Save result
					if(signed(max_stat_info.size()) > iTransLevel)
					{	max_stat_info[iTransLevel] = infolevel;
					}
					else
					{	max_stat_info.push_back(infolevel);
					}
					break;
				}
				iCount++;
			}
		}

		if(!bFoundResult)
		{	break;
		}
	}

	// Create the Class buttons
	for (int i = 0; i < PC_LASTCLASS; i++)
	{	int iYPos = CLASSMENU_BUTTON_INIT_PADDING + ( (CLASSMENU_BUTTON_BTNSIZE_TALL + CLASSMENU_BUTTON_BTN_PADDING) * i );
		ActionSignal *pASignal = new CMenuHandler_StringCommandClassSelect( sTFClassSelection[i], true );

		// Class button
		char szClassBtnImg[256];
		char szClassBtnImgMo[256];
		sprintf(szClassBtnImg,"%s_btn", sTFClassSelection[i]);
		sprintf(szClassBtnImgMo,"%s_mo_btn", sTFClassSelection[i]);

		m_pButtons[i] = new ImageClassButton( i, CLASSMENU_BUTTON_INIT_PADDING, iYPos, CLASSMENU_BUTTON_BTNSIZE_WIDE+2, CLASSMENU_BUTTON_BTNSIZE_TALL+2, szClassBtnImg, szClassBtnImgMo);
		m_pButtons[i]->addActionSignal( pASignal );
		m_pButtons[i]->addInputSignal( new CHandler_MenuButtonOver(this, i) );
		m_pButtons[i]->setParent( pClassButtonLabel );
		pSchemes->getFgColor( hBlueScheme, r, g, b, a );
		m_pButtons[i]->setBorder( new LineBorder( Color(r, g, b, 0) ) );

		// Create upper right hand corner class name images
		char szImgClassText[256];
		sprintf(szImgClassText,"%stitle",sTFClassSelection[i]);
		m_pClassTextImg[i] = new CImageLabel( szImgClassText, wide-128-10, (VGUI_REDBAR_HEIGHT/2)-(iRedIconHeight/2), 128, 32 );
		m_pClassTextImg[i]->setParent( pRedLabel );
		m_pClassTextImg[i]->setVisible(false);

		// Set data for form bulleted list
		m_pFormBulletList[i] = new CBulletedList(this, m_pModelLabel, 4, VGUI_MODEL_PANEL_HEIGHT+27,195);
		std::list<CCharacterFormVgui> forms = (*m_pCharacterPortrait[i]->getForms());
		std::list<CCharacterFormVgui>::iterator iterForm;
		int iFormCount = 0;
		int iStatInfoPad = 20;
		int iStatInfoWide = iStatPanelWide-iStatInfoPad*2;
			Label *pStatInfoBox = new Label( "", iStatInfoPad, 24+iStatInfoPad, iStatPanelWide-iStatInfoPad*2, 145 );
		ForEachIn(iterForm, forms)
		{	m_pFormBulletList[i]->addBullet(iterForm->getName(), iterForm->getName());
			// * Add data for attacks bulleted list as well
			// Get attack list
			std::map<std::string,std::string> atkList = iterForm->getAttacks();
			std::map<std::string,std::string>::iterator iterAtk;

			// Add bullets
			m_AttacksBulletedList[i][iterForm->getName()] = new CBulletedList(this, m_pAttackPanel, 0, 34, 393,Label::a_center);
			ForEachIn(iterAtk, atkList)
			{	m_AttacksBulletedList[i][iterForm->getName()]->addBullet(iterAtk->first, iterAtk->second);

				// * Add attack info data
				// First see if this attack already has attack info data
				std::map<std::string,CTransparentPanel*>::iterator iterFindAtkInfo = m_AttackInfoPanels.find(iterAtk->second);
				// No results found, add it!
				if(iterFindAtkInfo == m_AttackInfoPanels.end())
				{	// Make Panel
					CTransparentPanel *pNewAtkPanel = new CTransparentPanel( 255, 0, 0, clientAtkInfoWide, iAtkInfoPanelTall );
					pNewAtkPanel->setParent( m_pAttackInfoSP->getClient() );

					// Create text window
					char szAtkInfoSearch[256];
					sprintf(szAtkInfoSearch,"#%s_info",iterAtk->second.c_str());
					TextPanel *pTextWindow = new TextPanel(gHUD.m_TextMessage.BufferedLocaliseTextString(szAtkInfoSearch)
															, 0, 0, clientAtkInfoWide, iAtkInfoPanelTall);
					pTextWindow->setParent( pNewAtkPanel );
					pTextWindow->setFont( pSchemes->getFont(hClassWindowText) );
					pSchemes->getFgColor( hTextScheme, r, g, b, a );
					pTextWindow->setFgColor( r, g, b, a );
					pTextWindow->setBgColor( r, g, b, 255 );
					
					// Resize the Info panel to fit it all
					int wideTW,tallTW;
					pTextWindow->getTextImage()->getTextSizeWrapped(wideTW,tallTW);
					pTextWindow->setSize(wideTW,tallTW);
					pNewAtkPanel->setSize(wideTW,tallTW);
					pNewAtkPanel->setVisible(false);

					// Set in list
					m_AttackInfoPanels[iterAtk->second] = pNewAtkPanel;
				}
			}
			m_AttacksBulletedList[i][iterForm->getName()]->setVisible(false);


			// * Create stat boxes
			// Create content box for stat info
			Label *pStatInfoBox = new Label( "", iStatInfoPad, 24+iStatInfoPad, iStatPanelWide-iStatInfoPad*2, 145 );
			m_StatPanels[i][iterForm->getName()] = pStatInfoBox;	// Add to list
			pStatInfoBox->setParent(m_pStatPanel);
			pSchemes->getFgColor( hBlueScheme, r, g, b, a );
			pStatInfoBox->setBorder( new LineBorder( Color(r, g, b, 0) ) );
			pStatInfoBox->setFgColor( r, g, b, 255 );
			pStatInfoBox->setBgColor( r, g, b, 255 );

			// Create padding and size variables
			std::map<std::string,float> statList = iterForm->getStatistics();
			std::map<std::string,float>::iterator iterStat;
			int iStatCount = 0;
			int iStatHeight = 22;
			int iTextStatWide = 110;
			int iStatBarPad = 5;
			// Loop through all stats and add
			ForEachIn(iterStat, statList)
			{	float flValue = iterStat->second;
				float flMax = 100;
				// Get max size
				if(signed(max_stat_info.size()) > iFormCount)
				{	flMax = max_stat_info[iFormCount].data[iterStat->first];
				}
				r=255, g=0, b=0;
				//Get scheme for color
				std::string strSchemeNameTemp = iterStat->first;
				std::string strSchemeName;
				// to lowercase, and delete all spaces				
				/*remove by harSens: does not compile
				transform ( strSchemeNameTemp.begin(), strSchemeNameTemp.end(), strSchemeNameTemp.begin(), lower_case );
				*/
				for(int charl=0; charl < signed(strSchemeNameTemp.size()); charl++)
				{	if(strSchemeNameTemp.at(charl) != ' ')
					{	strSchemeName.push_back(strSchemeNameTemp.at(charl));
					}
				}
				// Get scheme and set color
				SchemeHandle_t hBarScheme = pSchemes->getSchemeHandle( strSchemeName.c_str() );
				if(hBarScheme)
				{	pSchemes->getBgColor( hBarScheme, r, g, b, a );
				}

				std::string strStatName = iterStat->first + ":";
				CStatInfo *pStatBar = new CStatInfo((char*)strStatName.c_str(), iStatBarPad, iStatBarPad+iStatHeight*iStatCount, iStatInfoWide-iStatBarPad*2, iStatHeight, iTextStatWide, flValue, flMax, r, g, b);
				pStatBar->setParent(pStatInfoBox);
				iStatCount++;
			}
			// set new size
			int iNewTallStatInfo = iStatBarPad+iStatHeight*iStatCount+iStatBarPad;
			pStatInfoBox->setSize(pStatInfoBox->getWide(), iNewTallStatInfo);

			iFormCount++;
		}
		m_pFormBulletList[i]->setVisible(true);
		m_pFormBulletList[i]->setUnselect(false);

		// Create character bio info
		m_pCharacterBioPanels[i] = new CTransparentPanel( 255, 0, 0, clientBioWide, iBioPanelTall );
		m_pCharacterBioPanels[i]->setParent( m_pCharacterBioSP->getClient() );		
		
		// Create the Text info window
		char szBioSearch[256];
		sprintf(szBioSearch,"#%s_bio",sTFClassSelection[i]);
		TextPanel *pTextWindow = new TextPanel(gHUD.m_TextMessage.BufferedLocaliseTextString(szBioSearch)
												, 0, 0, clientBioWide, iBioPanelTall);
		pTextWindow->setParent( m_pCharacterBioPanels[i] );
		pTextWindow->setFont( pSchemes->getFont(hClassWindowText) );
		pSchemes->getFgColor( hTextScheme, r, g, b, a );
		pTextWindow->setFgColor( r, g, b, a );
		pTextWindow->setBgColor( r, g, b, 255 );

		// Resize the Info panel to fit it all
		int wideTW,tallTW;
		pTextWindow->getTextImage()->getTextSizeWrapped(wideTW,tallTW);
		pTextWindow->setSize(wideTW,tallTW);
		m_pCharacterBioPanels[i]->setSize(wideTW,tallTW);
		m_pCharacterBioPanels[i]->setVisible(false);

		// Set data for custom models
		m_pCustomModelBulletList[i] = new CBulletedList(this, m_pCMScrollPanel->getClient(),0,0,clientWide, Label::a_east);
		// add default
		m_pCustomModelBulletList[i]->addBullet("Default","");
		// Add custom models for each class
		int iTotalMdls = gHUD.m_CustomModel.getCustomModelNum(i);
		for(int n = 0; n < iTotalMdls; n++)
		{	CCustomModel *pMdl = gHUD.m_CustomModel.getCustomModel(i,n);
			if(pMdl)
			{	m_pCustomModelBulletList[i]->addBullet(pMdl->getName(),pMdl->getDirectoryName());
			}
		}
		m_pCustomModelBulletList[i]->setVisible(true);
		m_pCustomModelBulletList[i]->setUnselect(false);
		m_pCMScrollPanel->validate();

		// Create the Player count string
		gHUD.m_TextMessage.LocaliseTextString( "#Title_CurrentlyOnYourTeam", m_sPlayersOnTeamString, STRLENMAX_PLAYERSONTEAM );
/*		m_pPlayers[i] = new Label( "", CLASSMENU_WINDOW_NAME_X, CLASSMENU_WINDOW_PLAYERS_Y );
		m_pPlayers[i]->setParent( this );
		m_pPlayers[i]->setBgColor( 0, 0, 0, 255 );
		m_pPlayers[i]->setContentAlignment( vgui::Label::a_west );
		m_pPlayers[i]->setFont( pSchemes->getFont(hClassWindowText) );*/
	}
	m_pCharacterBioSP->validate();

	// Create the Cancel button
	m_pCancelButton = new ImageCommandButton( 0, 0, CLASSMENU_BUTTON_BTNSIZE_WIDE+2, CLASSMENU_BUTTON_BTNSIZE_TALL+2, "cancel_btn", "cancel_mo_btn");
	m_pCancelButton->setParent( pClassButtonLabel );
	m_pCancelButton->addInputSignal( new CHandler_ButtonHighlight(m_pCancelButton) );
	m_pCancelButton->addActionSignal( new CMenuHandler_TextWindow(HIDE_TEXTWINDOW) );
	pSchemes->getFgColor( hBlueScheme, r, g, b, a );
	m_pCancelButton->setBorder( new LineBorder( Color(r, g, b, 0) ) );


	// Create the Spectate button
	m_pSpectateButton = new ImageSpectateButton( 0, 0, CLASSMENU_BUTTON_BTNSIZE_WIDE+2, CLASSMENU_BUTTON_BTNSIZE_TALL+2, "spectate_btn", "spectate_mo_btn");
	m_pSpectateButton->setParent( pClassButtonLabel );
	m_pSpectateButton->addInputSignal( new CHandler_ButtonHighlight(m_pSpectateButton) );
	m_pSpectateButton->addActionSignal( new CMenuHandler_StringCommand( "spectate", true ) );
	pSchemes->getFgColor( hBlueScheme, r, g, b, a );
	m_pCancelButton->setBorder( new LineBorder( Color(r, g, b, 0) ) );
	
	m_iCurrentInfo = 0;	
}

// Update
void CESFClassMenuPanel::Update()
{
	int	 iYPos = CLASSMENU_BUTTON_INIT_PADDING;

	// Cycle through the rest of the buttons
	for (int i = 0; i < PC_LASTCLASS; i++)
	{	
		if (/* m_pButtons[i]->IsNotValid() || */i == 0 )
		{	//maybe throwing in a dende here?
			m_pButtons[i]->setVisible( false );
		}
		else
		{	m_pButtons[i]->setVisible( true );
			m_pButtons[i]->setPos( CLASSMENU_BUTTON_INIT_PADDING, iYPos );
			iYPos += CLASSMENU_BUTTON_BTNSIZE_TALL + CLASSMENU_BUTTON_BTN_PADDING;

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

	
	// If the player already has a class, make the cancel button visible
	if ( g_iPlayerClass!=PC_UNDEFINED )	
	{
		m_pCancelButton->setPos( CLASSMENU_BUTTON_INIT_PADDING, iYPos );
		m_pCancelButton->setVisible( true );
		iYPos += CLASSMENU_BUTTON_BTNSIZE_TALL + CLASSMENU_BUTTON_BTN_PADDING;
	}
	else
	{
		m_pCancelButton->setVisible( false );
	}

	// If we're not in teamplay, show spectate button
	if (m_pSpectateButton->IsNotValid() || g_iTeamNumber)
	{
		m_pSpectateButton->setVisible( false );
	}
	else
	{
		m_pSpectateButton->setPos( CLASSMENU_BUTTON_INIT_PADDING, iYPos );
		m_pSpectateButton->setVisible( true );
	}
	// Pcjoe: Set Form
	std::string strSelForm = m_pFormBulletList[m_iCurrentInfo]->getSelectedCallback();
	// Form not currently selected, change forms and reset anim
	if(strSelForm != "")
	{	bool bNewForm = false;
		if(strSelForm != getCurrentForm())
		{	bNewForm = true;
			setCurrentForm(strSelForm);
		}
		CCharacterVgui *pCharPortrait = getCharacterPortrait(m_iCurrentInfo);
		if(pCharPortrait)
		{	CCharacterFormVgui *pForm = pCharPortrait->getForm(getCurrentForm());
			if(pForm)
			{	// * Update attack and stat list as well
				// Disable all visability
				if(bNewForm)
				{	std::map<std::string,CBulletedList*>::iterator iterAtk;
					ForEachIn(iterAtk, m_AttacksBulletedList[m_iCurrentInfo])
					{	iterAtk->second->setVisible(false);
						iterAtk->second->Reset();
					}
					std::map<std::string,Label*>::iterator iterStat;
					ForEachIn(iterStat, m_StatPanels[m_iCurrentInfo])
					{	iterStat->second->setVisible(false);
					}
					std::map<std::string,CTransparentPanel*>::iterator iterAtkInfo;
					ForEachIn(iterAtkInfo, m_AttackInfoPanels)
					{	iterAtkInfo->second->setVisible(false);
					}
				}
				// Set current group as visible
				std::map<std::string,CBulletedList*>::iterator iterFind = m_AttacksBulletedList[m_iCurrentInfo].find(getCurrentForm());
				if(iterFind != m_AttacksBulletedList[m_iCurrentInfo].end())
				{	iterFind->second->setVisible(true);
					// Set Animation
					if(pForm->getModel())
					{	// Just changed forms
						if(bNewForm)
						{	// Reset animation
							pForm->getModel()->playSequence("idle");
							// Reset Interpolation
							pForm->getModel()->getModelControl()->setInterpolSequence("");
						}
						// Changing animations
						else
						{	std::string strCallback = iterFind->second->getSelectedCallback();
							if(strCallback == "")
							{	strCallback = "idle";
								// Hide attack panel
								m_pAttackInfo->setVisible(false);
							}
							if(strCallback != pForm->getModel()->getCurrentSequence())
							{	// Set animation
								pForm->getModel()->playSequence(strCallback);
								if(strCallback != "idle")
								{	// Reset all entries
									std::map<std::string,CTransparentPanel*>::iterator iterAtkInfo;
									ForEachIn(iterAtkInfo, m_AttackInfoPanels)
									{	iterAtkInfo->second->setVisible(false);
									}
									// set to visible and set content
									m_pAttackInfo->setVisible(true);
									std::map<std::string,CTransparentPanel*>::iterator iterFindAtk = m_AttackInfoPanels.find(strCallback);
									if(iterFindAtk != m_AttackInfoPanels.end())
									{	iterFindAtk->second->setVisible(true);
										m_pAttackInfoSP->setScrollValue( 0, 0 );
									}
								}
							}
							m_pAttackInfoSP->validate();
						}
					}
				}
				// Set stat panel to visible
				std::map<std::string,Label*>::iterator iterFindStat = m_StatPanels[m_iCurrentInfo].find(getCurrentForm());
				if(iterFindStat != m_StatPanels[m_iCurrentInfo].end())
				{	iterFindStat->second->setVisible(true);
					// Resize main stat panel
					m_pStatPanel->setSize(m_pStatPanel->getWide(), 4+20+iterFindStat->second->getTall()+32);
					// Reset character bio panel
					int x, y;
					m_pStatPanel->getPos(x,y);
					m_pCharacterBio->setPos(x, y+m_pStatPanel->getTall()+16);
					// Reset attack panel pos
					m_pCharacterBio->getPos(x,y);
					m_pAttackPanel->setPos(x,y+m_pCharacterBio->getTall()+16);
					// Reset attack info panel pos and size
					std::map<std::string,CBulletedList*>::iterator iterFind = m_AttacksBulletedList[m_iCurrentInfo].find(getCurrentForm());
					if(iterFind != m_AttacksBulletedList[m_iCurrentInfo].end())
					{	m_pAttackPanel->getPos(x,y);
						int iAtkInfoY = y+iterFind->second->getHeight()+16;
						int iAtkInfoTall = getTall()-iAtkInfoY-27;
						m_pAttackInfo->setPos(x,iAtkInfoY);
						m_pAttackInfo->setSize(m_pAttackInfo->getWide(),iAtkInfoTall);

						((CESFColorScrollPanel*)m_pAttackInfoSP)->setSize( m_pAttackInfoSP->getWide(), iAtkInfoTall-(20+32) );
						m_pAttackInfoSP->setScrollValue( 0, 0 );
						m_pAttackInfoSP->validate();
					}
				}
			}
		}
	}

	// Pcjoe: set custom model
	std::string strSelCustom = m_pCustomModelBulletList[m_iCurrentInfo]->getSelectedCallback();
	if(getCustomModel() != strSelCustom)
	{	setCustomModel(strSelCustom);
		m_pCMScrollPanel->validate();
	}
}

//======================================
// Key inputs for the Class Menu
bool CESFClassMenuPanel::SlotInput( int iSlot )
{
	if ( (iSlot < 0) || (iSlot >= PC_LASTCLASS) )
		return false;
	if ( !m_pButtons[ iSlot ] )
		return false;
	if (m_pButtons[ iSlot ]->IsNotValid())
		return false;
	
	//no dende yet :)
	if (iSlot==0)
	{	iSlot=PC_RANDOM;
	}

	m_pButtons[ iSlot ]->fireActionSignal();
	return true;	
}

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

//-----------------------------------------------------------------------------
// Purpose: Called each time a new level is started.
//-----------------------------------------------------------------------------
void CESFClassMenuPanel::Initialize( void )
{	setVisible( false );
}

//======================================
// Mouse is over a class button, bring up the class info
void CESFClassMenuPanel::SetActiveInfo( int iInput )
{
	// Don't set new active info if we're rotating (it's easy to rotate into a menu button, ANNOYING)
	if(getCurrentlyRotating() || iInput == m_iCurrentInfo)
	{	return;
	}

	// Remove all the Info panels and bring up the specified one
	for (int i = 0; i < PC_LASTCLASS; i++)
	{
		m_pButtons[i]->setArmed( false );
		// added by Pcjoe
		m_pClassTextImg[i]->setVisible(false);
		m_pFormBulletList[i]->setVisible(false);
		m_pCustomModelBulletList[i]->setVisible(false);
		m_pFormBulletList[i]->Reset();
		m_pCustomModelBulletList[i]->Reset();
		// Disable all visability
		std::map<std::string,CBulletedList*>::iterator iterAtk;
		ForEachIn(iterAtk, m_AttacksBulletedList[i])
		{	iterAtk->second->setVisible(false);
			iterAtk->second->Reset();
		}
		std::map<std::string,Label*>::iterator iterStat;
		ForEachIn(iterStat, m_StatPanels[i])
		{	iterStat->second->setVisible(false);
		}
		// Reset rotate
		setRotate(0);
		setCurrentlyRotating( false );
		m_pCharacterBioPanels[i]->setVisible(false);
		// Reset scroll bar position(s)
		m_pCMScrollPanel->setScrollValue( 0, 0 );
		m_pCharacterBioSP->setScrollValue( 0, 0 );
		m_pAttackInfoSP->setScrollValue( 0, 0 );
	}

	if ( iInput > PC_RANDOM || iInput < 0 )
		iInput = 0;

	m_pButtons[iInput]->setArmed( true );
	// Added by Pcjoe
	m_pClassTextImg[iInput]->setVisible( true );
	m_pFormBulletList[iInput]->setVisible( true );
	m_pCustomModelBulletList[iInput]->setVisible( true );
	// Pcjoe: Reset Form with first selection
	m_pFormBulletList[iInput]->armFirst();
	setCurrentForm(m_pFormBulletList[iInput]->getSelectedCallback());
	CCharacterVgui *pCharPortrait = getCharacterPortrait(iInput);
	if(pCharPortrait)
	{	CCharacterFormVgui *pForm = pCharPortrait->getForm(getCurrentForm());
		if(pForm)
		{	if(pForm->getModel())
			{	// Reset animation
				pForm->getModel()->playSequence("idle");
				// Reset Interpolation
				pForm->getModel()->getModelControl()->setInterpolSequence("");
				// Hide attack panel
				m_pAttackInfo->setVisible(false);
			}

			// * Update attack list as well
			// Set current group as visible
			std::map<std::string,CBulletedList*>::iterator iterFind = m_AttacksBulletedList[iInput].find(getCurrentForm());
			if(iterFind != m_AttacksBulletedList[iInput].end())
			{	iterFind->second->setVisible(true);
			}
			// Update stat window
			std::map<std::string,Label*>::iterator iterFindStat = m_StatPanels[iInput].find(getCurrentForm());
			if(iterFindStat != m_StatPanels[iInput].end())
			{	iterFindStat->second->setVisible(true);
				// Resize main stat panel
				m_pStatPanel->setSize(m_pStatPanel->getWide(), 4+20+iterFindStat->second->getTall()+32);
				// Reset character bio panel
				int x, y;
				m_pStatPanel->getPos(x,y);
				m_pCharacterBio->setPos(x, y+m_pStatPanel->getTall()+16);
				// Reset attack panel pos
				m_pCharacterBio->getPos(x,y);
				m_pAttackPanel->setPos(x,y+m_pCharacterBio->getTall()+16);
				// Reset attack info panel pos and size
				std::map<std::string,CBulletedList*>::iterator iterFind = m_AttacksBulletedList[m_iCurrentInfo].find(getCurrentForm());
				if(iterFind != m_AttacksBulletedList[m_iCurrentInfo].end())
				{	m_pAttackPanel->getPos(x,y);
					int iAtkInfoY = y+iterFind->second->getHeight()+16;
					int iAtkInfoTall = getTall()-iAtkInfoY-27;
					m_pAttackInfo->setPos(x,iAtkInfoY);
					m_pAttackInfo->setSize(m_pAttackInfo->getWide(),iAtkInfoTall);

					((CESFColorScrollPanel*)m_pAttackInfoSP)->setSize( m_pAttackInfoSP->getWide(), iAtkInfoTall-(20+32) );
					m_pAttackInfoSP->setScrollValue( 0, 0 );
					m_pAttackInfoSP->validate();
				}
			}
		}
	}
	// Pcjoe: reset custom model with first selection
	m_pCustomModelBulletList[iInput]->armFirst();
	setCustomModel(m_pCustomModelBulletList[iInput]->getSelectedCallback());
	m_pCMScrollPanel->validate();

	// Pcjoe: update character bio
	m_pCharacterBioPanels[iInput]->setVisible(true);
	// set size of scroll panel and validate
	m_pCharacterBioSP->validate();

	m_iCurrentInfo = iInput;
}

// Pcjoe: Setup inset window
void CESFClassMenuPanel::setupInsetWindow(struct ref_params_s *pparams)
{	if(!pparams)
	{	return;
	}
	// set inset parameters
	int wide,tall;
	// Get position in screen coords, and size
	m_pModelLabel->getSize(wide,tall);

	// Set data in viewport
	pparams->viewport[0] = g_iModelPosX+2;
	pparams->viewport[1] = g_iModelPosY+2;
	pparams->viewport[2] = wide-2;
	pparams->viewport[3] = VGUI_MODEL_PANEL_HEIGHT;
	pparams->nextView	 = 0;
	pparams->onlyClientDraw = 1;

	setDrawCycle(1);

	for(int i = 0; i < 3; i++)
	{	pparams->vieworg[i] = 0;
		pparams->viewangles[i] = 0;
	}

	// get camera data from xml character form
	CCharacterVgui *pModel = getCharacterPortrait(getCurrentInfo());
	if(pModel)
	{	CCharacterFormVgui *pForm = pModel->getForm(getCurrentForm());
		if(pForm)
		{	vec3_t vecCam = pForm->getCameraPosition();
			pparams->vieworg[0] = vecCam.x;
			pparams->vieworg[1] = vecCam.y;
			pparams->vieworg[2] = vecCam.z;
			for(int n = 0; n < 3; n++)
			{	pparams->viewangles[n] = pForm->getCameraAngle()[n];
			}
		}
	}
}

void reloadCharXML()
{	for(int i = 0; i < PC_LASTCLASS; i++)
	{	delete gViewPort->m_pESFClassMenu->m_pCharacterPortrait[i];
		gViewPort->m_pESFClassMenu->m_pCharacterPortrait[i] = new CCharacterVgui();	
		char szDir[512];
		sprintf(szDir, "%s/classes/%s.xml", gEngfuncs.pfnGetGameDirectory(), sTFClassSelection[i]);
		// Parse XML
		gViewPort->m_pESFClassMenu->m_pCharacterPortrait[i]->parseXML(szDir);
	}
	gViewPort->m_pESFClassMenu->setCurrentForm("normal");
	gViewPort->m_pESFClassMenu->setCustomModel("");
}