//========= Copyright © 1996-2003, Valve LLC, All rights reserved. ============
//
// Purpose: 
//
//=============================================================================

#include "cbase.h"
#include "weapon_selection.h"
#include "iclientmode.h"
#include "basetfcombatweapon_shared.h"
#include "weapon_objectselection.h"
#include <KeyValues.h>
#include <vgui/IScheme.h>
#include <vgui/ISurface.h>
#include <vgui/ISystem.h>
#include <vgui_controls/AnimationController.h>
#include <vgui_controls/Panel.h>
#include "keydefs.h"

#include <vgui/IVGui.h>

#include "weapon_twohandedcontainer.h"
#ifdef CLIENT_DLL
#include "c_weapon_builder.h"
#include "iinput.h"
#else
#include "weapon_builder.h"
#endif

using namespace vgui;

class CHudWeaponSelection;

typedef enum 
{
	IMAGE_BACKGROUND = 0,
	IMAGE_CURRENT,
	IMAGE_INVALID
} WeaponBoxType_t;

enum
{
	HUMAN_WEAPON_SELECTION = 0,
	ALIEN_WEAPON_SELECTION,
};

struct CSlotInfo
{
	bool	active;
	bool	valid;
	CHudTexture const *icon;
	bool	drawAmmo;
	float	ammoPerc;
	bool	ammoCaution;
	char	printname[ 128 ];
	CHandle< C_BaseCombatWeapon > weapon;
};

struct CWeaponMenuItem
{
	// If true, it's a dummy item
	bool							buildslot;
	int								priority;
	int								hotkey;
	int								openbuildmenu;
	bool							isvalidmenuitem;
	CHandle< C_BaseCombatWeapon >	weapon;
};

class WeaponMenu
{
public:
	WeaponMenu() : items( 0, 0, WeaponLessFunc )
	{
		m_bIsBuildMenu = false;
		m_nActiveItem = 0;
	}

	void	SetActiveItem( int item )
	{
		bool changed = ( m_nActiveItem != item );

		m_nActiveItem = item;

		if ( !changed )
			return;

		const char *prefix = m_bIsBuildMenu ? "WeaponHiliteBuildMenu" : "WeaponHiliteWeaponMenu";

		if ( m_nActiveItem >= 1 )
		{
			char slotSequence[ 128 ];
			Q_snprintf( slotSequence, sizeof( slotSequence ), "%s%i", prefix, m_nActiveItem );

			g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( slotSequence );
		}
	}

	int		GetActiveItem()
	{
		return m_nActiveItem;
	}

	static bool WeaponLessFunc( const CWeaponMenuItem& w1, const CWeaponMenuItem& w2 )
	{
		return w1.priority < w2.priority;
	}

	CUtlRBTree< CWeaponMenuItem, int >	items;
	int			m_nActiveItem;
	bool		m_bIsBuildMenu;
};

class CHudWeaponItemPanel : public vgui::Panel
{
	DECLARE_CLASS_SIMPLE( CHudWeaponItemPanel, vgui::Panel );

public:
	CHudWeaponItemPanel( vgui::Panel *parent, const char *panelName );

	CPanelAnimationVarAliasType( float, m_flIconWidth, "IconWidth", "60", "proportional_float" );
	CPanelAnimationVarAliasType( float, m_flIconHeight, "IconHeight", "30", "proportional_float" );
	CPanelAnimationVarAliasType( float, m_flIconXPos, "IconXPos", "10", "proportional_float" );
	CPanelAnimationVarAliasType( float, m_flIconYPos, "IconYPos", "4", "proportional_float" );
	CPanelAnimationVarAliasType( float, m_flTextXPos, "TextXPos", "10", "proportional_float" );
	CPanelAnimationVarAliasType( float, m_flTextYPos, "TextYPos", "35", "proportional_float" );
	CPanelAnimationVarAliasType( float, m_flAmmoBarX, "AmmoBarX", "75", "proportional_float" );
	CPanelAnimationVarAliasType( float, m_flAmmoBarWide, "AmmoBarWide", "4", "proportional_float" );
	CPanelAnimationVarAliasType( float, m_flSelectionNumberXPos, "SelectionNumberXPos", "4", "proportional_float" );
	CPanelAnimationVarAliasType( float, m_flSelectionNumberYPos, "SelectionNumberYPos", "4", "proportional_float" );

	CPanelAnimationVarAliasType( float, m_flPriceXEndPos,	"PriceXEndPos", "4", "proportional_float" );
	CPanelAnimationVarAliasType( float, m_flPriceYEndPos,	"PriceYEndPos", "4", "proportional_float" );

	CPanelAnimationVar( float, m_flGrowFraction, "GrowFraction", "1.0" );

	bool				m_bInUse;

	bool				m_bDrawNumbers;
	int					m_nSlotNumber;
	bool				m_bBuildMenu;

	// Copies of data
	CSlotInfo			info;
	CWeaponMenuItem		menuItem;

	virtual void		Paint();

	virtual void		ApplySchemeSettings( vgui::IScheme *scheme );

	void				SetupIcons();

	enum
	{
		NUM_SLOT_TEAMS = 2,
		NUM_MENU_TYPES = 3,
	};

	CHudTexture			*m_BackgroundIcons[ NUM_SLOT_TEAMS ][ NUM_MENU_TYPES ];

private:
	void TranslateColor( float percent, Color& clr );
	void DrawBox( bool isbuildmenu, int x, int y, int wide, int tall, bool isactive, bool isvalid, float normalizedAlpha, int number );
	int GetTeamIndex();
	void OnWeaponSelectionDrawn( CHudWeaponSelection *selection, C_WeaponObjectSelection *weapon, bool bCurrentlySelected, 
		int wide, int tall, Color& clr );
};

//-----------------------------------------------------------------------------
// Purpose: tf2 weapon selection hud element
//-----------------------------------------------------------------------------
class CHudWeaponSelection : public CBaseHudWeaponSelection, public vgui::Panel
{
	DECLARE_CLASS_SIMPLE( CHudWeaponSelection, vgui::Panel );

public:

	CHudWeaponSelection(const char *pElementName );

	virtual bool ShouldDraw( void );
	
	virtual void VidInit(void);

	virtual void CycleToNextWeapon( void );
	virtual void CycleToPrevWeapon( void );
	virtual void SwitchToLastWeapon( void );

	virtual C_BaseCombatWeapon *GetWeaponInSlot( int iSlot, int iSlotPos );
	virtual void SelectWeaponSlot( int iSlot );

	virtual void OnWeaponPickup( C_BaseCombatWeapon *pWeapon );

	virtual void SelectWeapon( void );
	
	virtual C_BaseCombatWeapon	*GetSelectedWeapon( void );

	virtual void OpenSelection( void );

	virtual int	KeyInput( int down, int keynum, const char *pszCurrentBinding );

	virtual void HideSelection( void );

protected:
	virtual void OnTick();
	virtual void ApplySchemeSettings(vgui::IScheme *pScheme);
	virtual void ApplySettings( KeyValues *resourceData );
private:

	// Offensive
	// Defensive
	// General Purpose
	enum
	{
		BUILD_OFFENSIVE = 0,
		BUILD_DEFENSIVE,
		BUILD_GENERAL_PURPOSE,

		NUM_BUILD_MENUS,
	};

	enum
	{
		MAX_WEAPON_MENU_ITEMS = 7,
		MAX_BUILD_MENU_ITEMS = 6,
	};

	void SetupWeaponMenu( WeaponMenu& menu, C_BaseCombatWeapon *activeItem, bool drawNumbers );
	void SetupBuildMenu( WeaponMenu& menu, C_BaseCombatWeapon *activeItem );

	void DrawBox( bool isbuildmenu, int x, int y, int wide, int tall, bool current, bool isvalid, float normalizedAlpha, int number );

	void TranslateColor( float percent, Color& clr );

	void	ShowBuildMenu( int buildmenu );
	void ShowBuildMenu( WeaponMenu& buildMenu );
	void	HideBuildMenu( void );
	WeaponMenu&	GetActiveMenu();
	int GetLowIndex( WeaponMenu& menu );
	void WrapIndexToRange( int& index, int low, int high );
	int FindSlotForHotKey( WeaponMenu& menu, int hotkey );
	int FindNextSelectableWeaponInMenu( WeaponMenu& menu, int startindex, int direction );
	int CountSelectableItems( WeaponMenu& menu );
	CWeaponMenuItem *GetFirstSelectableWeapon( WeaponMenu& menu );
	const char *GetBuildMenuName( int slot );
	const char *GetBuildMenuMaterial( int slot );

	void	SelectBuildMenuSlot( WeaponMenu& buildMenu );

	void	CreateWeaponItemPanels();

	void	ClearBuildMenu();
	void	RebuildMenus();
	void	AssignSlots( WeaponMenu& menu, int firstindex );
	void	CollapseSingleItemBuildMenus();
	
	void	GetSlotInfo( const CWeaponMenuItem *w, C_BaseCombatWeapon *active, CSlotInfo& info );

	int GetTeamIndex();

	void	SetupIcons();

	CPanelAnimationVar( float, m_flAlphaOverride, "Alpha", "255.0" );
	CPanelAnimationVar( float, m_flSelectionAlphaOverride, "SelectionAlpha", "255.0" );

	CPanelAnimationVar( Color, m_TextColor, "TextColor", "SelectionTextFg" );
	CPanelAnimationVar( Color, m_InvalidActiveColor, "InvalidActiveColor", "InvalidActiveSlotFg" );
	CPanelAnimationVar( Color, m_InvalidActiveTextColor, "InvalidActiveTextColor", "InvalidActiveSlotText" );
	CPanelAnimationVar( Color, m_InvalidColor, "InvalidColor", "InvalidSlotFg" );
	CPanelAnimationVar( Color, m_InvalidTextColor, "InvalidTextColor", "InvalidSlotText" );
	CPanelAnimationVar( Color, m_OtherColor, "OtherColor", "OtherSlotFg" );
	CPanelAnimationVar( Color, m_OtherTextColor, "OtherTextColor", "OtherSlotText" );
	CPanelAnimationVar( Color, m_AmmoNormalColor, "AmmoNormalColor", "AmmoNormal" );
	CPanelAnimationVar( Color, m_AmmoCautionColor, "AmmoCautionColor", "AmmoCaution" );

	CPanelAnimationVar( vgui::HFont, m_hNumberFont, "NumberFont", "HudSelectionNumbers" );
	CPanelAnimationVar( vgui::HFont, m_hTextFont, "TextFont", "HudSelectionText" );
	CPanelAnimationVar( vgui::HFont, m_hTextFontSmall, "TextFontSmall", "HudSelectionTextSmall" );
	CPanelAnimationVar( vgui::HFont, m_hPriceFont, "PriceFont", "HudSelectionTextSmall" );

	CPanelAnimationVar( float, m_flGrowFraction, "GrowFraction", "0.0" );

	CHandle<C_BaseCombatWeapon> m_hLastPickedUpWeapon;
	bool		m_bInSelectionMode;
	int			m_nLastBuildTick;
	bool		m_bInBuildMenu;
	int			m_nActiveBuildMenu;

	WeaponMenu	*m_PreviousBuildMenu;

	WeaponMenu m_Weapons;
	WeaponMenu m_BuildObjects[ NUM_BUILD_MENUS ];

	CHudWeaponItemPanel *m_pWeaponPanels[ MAX_WEAPON_MENU_ITEMS ];
	CHudWeaponItemPanel *m_pBuildPanels[ MAX_BUILD_MENU_ITEMS ];

	CWeaponMenuItem *FindWeapon( WeaponMenu& menu, int hotkey );

	friend class CHudWeaponItemPanel;
};

DECLARE_HUDELEMENT( CHudWeaponSelection );

void CHudWeaponSelection::VidInit(void)
{
	CBaseHudWeaponSelection::VidInit();

	SetupIcons();
}

void CHudWeaponSelection::SetupIcons()
{
	int i;

	for ( i = 0; i < MAX_WEAPON_MENU_ITEMS; i++ )
	{
		m_pWeaponPanels[ i ]->SetupIcons();
	}

	for ( i = 0; i < MAX_BUILD_MENU_ITEMS; i++ )
	{
		m_pBuildPanels[ i ]->SetupIcons();
	}
}


void CHudWeaponSelection::AssignSlots( WeaponMenu& menu, int firstindex )
{
	int slot = firstindex;

	for ( int i = menu.items.FirstInorder(); i != menu.items.InvalidIndex(); i = menu.items.NextInorder( i ) )
	{
		CWeaponMenuItem *w = &menu.items[ i ];
		w->hotkey = slot++;
	}
}

//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CHudWeaponSelection::CreateWeaponItemPanels()
{
	int i;
	char sz[ 128 ];
	for ( i = 0; i < MAX_WEAPON_MENU_ITEMS; i++ )
	{
		Q_snprintf( sz, sizeof( sz ), "WeaponMenu%i", i + 1 );
		m_pWeaponPanels[ i ] = new CHudWeaponItemPanel( this, sz );
		m_pWeaponPanels[ i ]->m_nSlotNumber = i;
		m_pWeaponPanels[ i ]->m_bBuildMenu = false;
	}

	for ( i = 0; i < MAX_BUILD_MENU_ITEMS; i++ )
	{
		Q_snprintf( sz, sizeof( sz ), "BuildMenu%i", i + 1 );
		m_pBuildPanels[ i ] = new CHudWeaponItemPanel( this, sz );
		m_pBuildPanels[ i ]->m_nSlotNumber = i;
		m_pBuildPanels[ i ]->m_bBuildMenu = true;
	}
}

//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CHudWeaponSelection::RebuildMenus()
{
	int i;
	
	if ( gpGlobals->tickcount == m_nLastBuildTick )
		return;

	m_nLastBuildTick =  gpGlobals->tickcount;


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

	m_Weapons.items.RemoveAll();
	for ( i = 0; i < NUM_BUILD_MENUS; i++ )
	{
		m_BuildObjects[ i ].items.RemoveAll();
	}

	CWeaponMenuItem item;

	int c = MAX_WEAPONS;
	for ( i = 0; i < c; i++ )
	{
		C_BaseCombatWeapon *pWeapon = player->GetWeapon(  i );
		if ( !pWeapon )
		{
			continue;
		}

		if ( !pWeapon->VisibleInWeaponSelection() )
		{
			continue;
		}

		item.priority = pWeapon->GetSlot() * 10 + pWeapon->GetPosition();
		item.buildslot = false;
		item.openbuildmenu = -1;
		item.weapon = pWeapon;
		item.isvalidmenuitem = true;

		if ( dynamic_cast< C_WeaponObjectSelection * >( pWeapon ) )
		{
			// HACK
			int firstbuildslot = 4;
			int whichBuildMenu = clamp( pWeapon->GetSlot() - firstbuildslot, 0, NUM_BUILD_MENUS - 1 );

			m_BuildObjects[ whichBuildMenu ].items.Insert( item );
		}
		else
		{
			m_Weapons.items.Insert( item );
		}
	}

	while ( m_Weapons.items.Count() < 3 )
	{
		// Add build item menus
		item.priority = 999;
		item.buildslot = false;
		item.openbuildmenu = -1;
		item.weapon = NULL;
		item.isvalidmenuitem = false;
		m_Weapons.items.Insert( item );

		m_Weapons.m_bIsBuildMenu = false;
	}

	for ( i = 0; i < NUM_BUILD_MENUS; i++ )
	{
		// Add build item menus
		item.priority = 999;
		item.buildslot = true;
		item.openbuildmenu = i;
		item.weapon = NULL;
		item.isvalidmenuitem = CountSelectableItems( m_BuildObjects[ i ] ) > 0 ? true : false;
		m_Weapons.items.Insert( item );
	
		// Assign build menu slots
		AssignSlots( m_BuildObjects[ i ], 0 );
	
		m_BuildObjects[ i ].m_bIsBuildMenu = true;
	}

	// Now walk in order and assign hotkeys
	AssignSlots( m_Weapons, 1 );

	// Merge single item build menus into main menu
	CollapseSingleItemBuildMenus();
}

//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CHudWeaponSelection::CollapseSingleItemBuildMenus()
{
	for ( int i = 0; i < NUM_BUILD_MENUS; i++ )
	{
		int count = m_BuildObjects[ i ].items.Count();

		// Not an issue
		if ( count > 1 )
			continue;

		CWeaponMenuItem *mainItem = FindWeapon( m_Weapons, 4 + i );
		if ( !mainItem )
			continue;

		// It's empty, need to make main item a disabled slot
		if ( count == 0 )
		{
			// Add build item menus
			mainItem->isvalidmenuitem = false;
		}
		else
		{
			// Only one item in sub menu, copy it over
			CWeaponMenuItem *buildItem = &m_BuildObjects[ i ].items[ 0 ];
			mainItem->buildslot = false;
			mainItem->openbuildmenu = -1;
			mainItem->isvalidmenuitem = true;
			mainItem->weapon = buildItem->weapon;
		}
	}
}

//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CHudWeaponSelection::ClearBuildMenu()
{
	for ( int i = 0; i < MAX_BUILD_MENU_ITEMS; i++ )
	{
		m_pBuildPanels[ i ]->m_bInUse = false;
	}
}

//-----------------------------------------------------------------------------
// Purpose: Constructor
//-----------------------------------------------------------------------------
CHudWeaponSelection::CHudWeaponSelection(const char *pElementName ) : 
	CBaseHudWeaponSelection(pElementName), BaseClass(NULL, "HudWeaponSelection")
{
	vgui::Panel *pParent = g_pClientMode->GetViewport();
	SetParent( pParent );

	m_nLastBuildTick = -1;

	m_hNumberFont = NULL;
	m_bInSelectionMode = false;

	CreateWeaponItemPanels();

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

void CHudWeaponSelection::ShowBuildMenu( int buildmenu )
{
	bool wasinbuild = m_bInBuildMenu;

	int mainItem = buildmenu + 4;
	m_Weapons.SetActiveItem( mainItem );

	m_bInBuildMenu = true;
	m_nActiveBuildMenu = buildmenu;
	GetActiveMenu().SetActiveItem( GetLowIndex( GetActiveMenu() ) );

	if ( !wasinbuild )
	{
		g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("WeaponOpenBuildSubMenu");

		switch ( buildmenu )
		{
		default:
		case BUILD_OFFENSIVE:
			g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("WeaponOpenBuildOffensive");
			break;
		case BUILD_DEFENSIVE:
			g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("WeaponOpenBuildDefensive");
			break;
		case BUILD_GENERAL_PURPOSE:
			g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("WeaponOpenBuildGeneral");
			break;
		}
	}
}

void CHudWeaponSelection::ShowBuildMenu( WeaponMenu& buildMenu )
{
	int c = m_Weapons.items.Count();
	for ( int i = 0; i < c; i++ )
	{
		CWeaponMenuItem *item = &m_Weapons.items[ i ];
		if ( !item || !item->buildslot )
			continue;

		WeaponMenu &menu = m_BuildObjects[ item->openbuildmenu ];
		if ( &menu == &buildMenu )
		{
			ShowBuildMenu( item->openbuildmenu );
			return;
		}
	}

	Assert( 0 );
}

void CHudWeaponSelection::HideBuildMenu( void )
{
	bool wasinbuild = m_bInBuildMenu;

	GetActiveMenu().SetActiveItem( GetLowIndex( GetActiveMenu() ) );
	m_bInBuildMenu = false;

	if ( wasinbuild )
	{
		g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("WeaponCloseBuildSubMenu");
	}

	m_nActiveBuildMenu = -1;
}

WeaponMenu&	CHudWeaponSelection::GetActiveMenu()
{
	return m_bInBuildMenu ? m_BuildObjects[ m_nActiveBuildMenu ] : m_Weapons;
}

int CHudWeaponSelection::GetLowIndex( WeaponMenu& menu )
{
	if ( menu.items.Count() == 0 )
		return 1;

	int lowindex =  menu.items[  menu.items.FirstInorder() ].hotkey;
	return lowindex;
}

void CHudWeaponSelection::WrapIndexToRange( int& index, int low, int high )
{
	int delta = ( high - low ) + 1;
	while ( index < low )
	{
		index += delta;
	}
	
	while ( index > high )
	{
		index -= delta;
	}
}

int CHudWeaponSelection::FindSlotForHotKey( WeaponMenu& menu, int hotkey )
{
	int count		= menu.items.Count();
	for ( int i = 0; i < count;i++ )
	{
		if ( menu.items[ i ].hotkey == hotkey )
			return i;
	}

	return 0;
}

int CHudWeaponSelection::FindNextSelectableWeaponInMenu( WeaponMenu& menu, int startindex, int direction )
{
	direction = direction > 0 ? 1 : -1;

	int count		= menu.items.Count();
	int lowindex	= GetLowIndex( menu );
	int highindex	= lowindex + count - 1;

	for ( int offset = 1; offset <= count; offset++ )
	{
		int current = startindex + offset * direction;
		
		WrapIndexToRange( current, lowindex, highindex );

		//int slot = FindSlotForHotKey( menu, current );

		//C_BaseCombatWeapon *w = menu.items[ slot ].weapon;
		//if ( w && !w->CanBeSelected() )
		//	continue;

		return current;
	}

	return startindex;
}

int CHudWeaponSelection::CountSelectableItems( WeaponMenu& menu )
{
	int count = 0;
	int c = menu.items.Count();
	for ( int i = 0; i < c; i++ )
	{
		C_BaseCombatWeapon *w = menu.items[ i ].weapon;
		if ( w && w->CanBeSelected() )
		{
			count++;
		}
	}
	return count;
}

CWeaponMenuItem *CHudWeaponSelection::GetFirstSelectableWeapon( WeaponMenu& menu )
{
	int c = menu.items.Count();
	for ( int i = 0; i < c; i++ )
	{
		C_BaseCombatWeapon *w = menu.items[ i ].weapon;
		if ( w && w->CanBeSelected() )
		{
			return &menu.items[ i ];
		}
	}
	return NULL;
}

const char *CHudWeaponSelection::GetBuildMenuName( int slot )
{
	switch ( slot )
	{
	default:
	case BUILD_OFFENSIVE:
		return "Offensive Object";
	case BUILD_DEFENSIVE:
		return "Defensive Object";
	case BUILD_GENERAL_PURPOSE:
		return "General Purpose";
	}

	return "General Purpose";
}

const char *CHudWeaponSelection::GetBuildMenuMaterial( int slot )
{
	switch ( slot )
	{
	default:
	case BUILD_OFFENSIVE:
		return "weapon_selection_offensive";
	case BUILD_DEFENSIVE:
		return "weapon_selection_defensive";
	case BUILD_GENERAL_PURPOSE:
		return "weapon_selection_general";
	}

	return "hud/menu/weapon_selection_general";
}

//-----------------------------------------------------------------------------
// Purpose: sets up display for showing weapon pickup
//-----------------------------------------------------------------------------
void CHudWeaponSelection::OnWeaponPickup( C_BaseCombatWeapon *pWeapon )
{
	// Nothing in TF2
}

//-----------------------------------------------------------------------------
// Purpose: returns true if the panel should draw
//-----------------------------------------------------------------------------
bool CHudWeaponSelection::ShouldDraw()
{
	C_BaseTFPlayer *pPlayer = C_BaseTFPlayer::GetLocalPlayer();
	if ( !pPlayer || pPlayer->GetPlayerClass() == NULL )
	{
		if ( IsInSelectionMode() )
		{
			HideSelection();
		}
		return false;
	}
	
	bool bret = CBaseHudWeaponSelection::ShouldDraw();
	
	if ( !bret )
		return false;

	return ( m_bSelectionVisible || ( m_flGrowFraction > 0.0f ) ) ? true : false;
}

void CHudWeaponSelection::TranslateColor( float percent, Color& clr )
{
	if ( percent >= 1.0f )
		return;

	if ( percent <= 0.75f )
	{
		clr = Color( 0, 0, 0, 0 );
	}
	else
	{
		float frac = ( percent - 0.75f ) / 0.25f;

		clr = Color( clr[0] * frac,
			clr[1] * frac,
			clr[2] * frac,
			clr[3] * frac );
	}
}

void CHudWeaponSelection::GetSlotInfo( const CWeaponMenuItem *w, C_BaseCombatWeapon *active, CSlotInfo& info )
{
	if ( w->buildslot )
	{
		info.active = !m_bInBuildMenu && ( GetActiveMenu().GetActiveItem() == w->hotkey );
		info.valid = w->isvalidmenuitem;
		info.icon = gHUD.GetIcon( GetBuildMenuMaterial( w->openbuildmenu ) );
		info.drawAmmo = false;
		info.ammoCaution = false;
		Q_snprintf( info.printname, sizeof( info.printname ), GetBuildMenuName( w->openbuildmenu ) );
		info.weapon = NULL;
	}
	else if ( !w->weapon )
	{
		info.active =false;
		info.valid = false;
		info.icon = NULL;
		info.drawAmmo = false;
		info.ammoCaution = false;
		Q_snprintf( info.printname, sizeof( info.printname ), "" );
		info.weapon = NULL;
	}
	else
	{
		C_BaseCombatWeapon *pWeapon = w->weapon;
		Assert( pWeapon );

		info.active = active == pWeapon;
		info.valid = pWeapon->CanBeSelected();
		info.icon = info.active ? pWeapon->GetSpriteActive() : pWeapon->GetSpriteInactive();

		info.drawAmmo = false;
		info.ammoPerc = 1.0f;
		// Don't know the max ammo, so if I don't use clips, just go red on no ammo left
		if ( pWeapon->UsesClipsForAmmo1() || pWeapon->HasAmmo() )
		{
			info.ammoPerc = 1.0f - ( (float) pWeapon->Clip1() ) / ( (float)pWeapon->GetMaxClip1() );
			info.drawAmmo = true;
		}
		info.ammoCaution = ( info.ammoPerc >= CLIP_PERC_THRESHOLD ) ? true : false;

		Q_snprintf( info.printname, sizeof( info.printname ), "%s", pWeapon->GetPrintName() );
		info.weapon = pWeapon;
	}

	strupr(info.printname);
}

void CHudWeaponSelection::SetupWeaponMenu( WeaponMenu& menu, C_BaseCombatWeapon *activeItem, bool drawNumbers )
{
	int panelPosition = 0;
	for ( int item = menu.items.FirstInorder(); item != menu.items.InvalidIndex() && panelPosition < MAX_WEAPON_MENU_ITEMS; item = menu.items.NextInorder( item ) )
	{
		CWeaponMenuItem *w = &menu.items[ item ];
		Assert( w );

		CSlotInfo info;
		GetSlotInfo( w, activeItem, info );

		CHudWeaponItemPanel *panel = m_pWeaponPanels[ panelPosition++ ];
		if ( !panel )
		{
			Assert( 0 );
			continue;
		}

		panel->m_bInUse		= true;
		panel->info			= info;
		panel->menuItem		= *w;
		panel->m_bDrawNumbers = drawNumbers;
	}

	for ( ; panelPosition < MAX_WEAPON_MENU_ITEMS; )
	{
		CHudWeaponItemPanel *panel = m_pWeaponPanels[ panelPosition++ ];
		panel->m_bInUse = false;
	}
}

void CHudWeaponSelection::SetupBuildMenu( WeaponMenu& menu, C_BaseCombatWeapon *activeItem )
{
	int panelPosition = 0;
	for ( int item = menu.items.FirstInorder(); item != menu.items.InvalidIndex() && panelPosition < MAX_BUILD_MENU_ITEMS; item = menu.items.NextInorder( item ) )
	{
		CWeaponMenuItem *w = &menu.items[ item ];
		Assert( w );

		CSlotInfo info;
		GetSlotInfo( w, activeItem, info );

		CHudWeaponItemPanel *panel = m_pBuildPanels[ panelPosition++ ];
		if ( !panel )
		{
			Assert( 0 );
			continue;
		}

		panel->m_bInUse		= true;
		panel->info			= info;
		panel->menuItem		= *w;
		panel->m_bDrawNumbers = false;
	}

	for ( ; panelPosition < MAX_BUILD_MENU_ITEMS; )
	{
		CHudWeaponItemPanel *panel = m_pBuildPanels[ panelPosition++ ];
		panel->m_bInUse = false;
	}
}

void CHudWeaponSelection::OnTick()
{
	C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer();
	if ( !pPlayer )
		return;

	RebuildMenus();

	int x, y;
	GetPos(x, y);

	C_BaseCombatWeapon *wpn = GetSelectedWeapon();

	// Draw main menu
	SetupWeaponMenu( m_Weapons, wpn, true );
	
	CWeaponMenuItem *item = FindWeapon( GetActiveMenu(), GetActiveMenu().GetActiveItem() );

	WeaponMenu* otherMenu = NULL;
	int buildMenuNumber=  0;

	// Drawing build menu
	if ( m_bInBuildMenu )
	{
		otherMenu = &m_BuildObjects[ m_nActiveBuildMenu ];
		buildMenuNumber = m_nActiveBuildMenu;
	}
	else if ( item && item->buildslot && item->hotkey == GetActiveMenu().GetActiveItem() )
	{
		otherMenu = &m_BuildObjects[ item->openbuildmenu ];
		buildMenuNumber = item->openbuildmenu;
	}
	else if ( m_nActiveBuildMenu >= 0 )
	{
		otherMenu = &m_BuildObjects[ m_nActiveBuildMenu ];
		buildMenuNumber = m_nActiveBuildMenu;
	}

	if ( otherMenu )
	{
		SetupBuildMenu( *otherMenu, wpn );
	}
	else
	{
		ClearBuildMenu();
	}

	if ( otherMenu != m_PreviousBuildMenu )
	{
		m_PreviousBuildMenu = otherMenu;

		if ( otherMenu )
		{
			switch ( buildMenuNumber )
			{
			default:
			case BUILD_OFFENSIVE:
				g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("WeaponOpenBuildOffensive");
				break;
			case BUILD_DEFENSIVE:
				g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("WeaponOpenBuildDefensive");
				break;
			case BUILD_GENERAL_PURPOSE:
				g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("WeaponOpenBuildGeneral");
				break;
			}
		}
	}
}

//-----------------------------------------------------------------------------
// Purpose: hud scheme settings
//-----------------------------------------------------------------------------
void CHudWeaponSelection::ApplySchemeSettings(vgui::IScheme *pScheme)
{
	BaseClass::ApplySchemeSettings(pScheme);
	SetPaintBackgroundEnabled(false);
}

//-----------------------------------------------------------------------------
// Purpose: Select the next item in the weapon list
//-----------------------------------------------------------------------------
void CHudWeaponSelection::CycleToNextWeapon( void )
{
	// Get the local player.
	C_BaseTFPlayer *pPlayer = C_BaseTFPlayer::GetLocalPlayer();
	if ( !pPlayer || !pPlayer->GetPlayerClass() )
		return;

	// Make it active
	bool justopened = false;
	if ( !IsInSelectionMode() )
	{
		OpenSelection();
		justopened = true;
	}

	RebuildMenus();

	WeaponMenu& menu = GetActiveMenu();
	int c = menu.items.Count();
	if ( c != 0 && !justopened )
	{
		GetActiveMenu().SetActiveItem( FindNextSelectableWeaponInMenu( menu, GetActiveMenu().GetActiveItem(), +1 ) );
	}

	// Play the "cycle to next weapon" sound
	pPlayer->EmitSound( "Player.WeaponSelectionMoveSlot" );
}

//-----------------------------------------------------------------------------
// Purpose: Selects the previous item in the menu
//-----------------------------------------------------------------------------
void CHudWeaponSelection::CycleToPrevWeapon( void )
{
	C_BaseTFPlayer *pPlayer = C_BaseTFPlayer::GetLocalPlayer();
	if ( !pPlayer || !pPlayer->GetPlayerClass() )
		return;

	// Make it active
	bool justopened = false;
	if ( !IsInSelectionMode() )
	{
		OpenSelection();
		justopened = true;
	}

	RebuildMenus();

	WeaponMenu& menu = GetActiveMenu();
	int c = menu.items.Count();
	if ( c != 0 && !justopened )
	{
		GetActiveMenu().SetActiveItem( FindNextSelectableWeaponInMenu( menu, GetActiveMenu().GetActiveItem(), -1 ) );
	}

	// Play the "cycle to next weapon" sound
	pPlayer->EmitSound( "Player.WeaponSelectionMoveSlot" );
}

//-----------------------------------------------------------------------------
// Purpose: Switches the last weapon the player was using
//-----------------------------------------------------------------------------
void CHudWeaponSelection::SwitchToLastWeapon( void )
{
	// Get the player's last weapon
	C_BaseTFPlayer *pPlayer = C_BaseTFPlayer::GetLocalPlayer();
	if ( !pPlayer )
		return;

	// If we're currently using the builder weapon, switch to the weapon we were
	// using before we started using it.
	C_BaseCombatWeapon *pActiveWeapon = pPlayer->GetActiveWeapon();
	// Handle the twohanded weapon container
	CWeaponTwoHandedContainer *pContainer = dynamic_cast< CWeaponTwoHandedContainer * >( pActiveWeapon );
	if ( pContainer )
	{
		pActiveWeapon = pContainer->GetLeftWeapon();
	}

	if ( dynamic_cast< C_WeaponBuilder* >( pActiveWeapon ) )
	{
		::input->MakeWeaponSelection( pPlayer->GetLastWeaponBeforeObject() );
		return;
	}

	// Switch to previous weapon normally
	::input->MakeWeaponSelection( pPlayer->GetLastWeapon() );
}

//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
CWeaponMenuItem *CHudWeaponSelection::FindWeapon( WeaponMenu& menu, int hotkey )
{
	RebuildMenus();

	int c = menu.items.Count();

	for ( int i = 0; i < c; i++ )
	{
		CWeaponMenuItem *item = &menu.items[ i ];
		if ( item->hotkey == hotkey )
			return item;
	}

	return NULL;
}


//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
C_BaseCombatWeapon *CHudWeaponSelection::GetWeaponInSlot( int iSlot, int iSlotPos )
{
	CWeaponMenuItem *item = FindWeapon( GetActiveMenu(), iSlot );
	if ( item )
	{
		return item->weapon;
	}

	return NULL;
}

C_BaseCombatWeapon *CHudWeaponSelection::GetSelectedWeapon( void )
{
	RebuildMenus();

	return GetWeaponInSlot( GetActiveMenu().GetActiveItem(), 0 );
}

void CHudWeaponSelection::SelectBuildMenuSlot( WeaponMenu& buildMenu )
{
	// Get the local player.
	C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer();
	if ( !pPlayer )
		return;

	int numSelectable = CountSelectableItems( buildMenu );

	if ( numSelectable >= 1 )
	{
		// Single item, just fast switch to it
		CWeaponMenuItem *fastSwitchItem = GetFirstSelectableWeapon( buildMenu );
		C_BaseCombatWeapon *w = fastSwitchItem ? fastSwitchItem->weapon : NULL;

		Assert( w && w->CanBeSelected() );
		if ( 0 && numSelectable == 1 && w && w->CanBeSelected() )
		{
			ShowBuildMenu( buildMenu );

			m_hSelectedWeapon = w;
			GetActiveMenu().SetActiveItem( fastSwitchItem->hotkey );

			// There's only one active item in bucket, so change directly to weapon
			SetWeaponSelected();
			CancelWeaponSelection();
		}
		else
		{
			// Play the "open weapon selection" sound
			pPlayer->EmitSound( "Player.WeaponSelectionOpen" );

			ShowBuildMenu( buildMenu );
		}
	}
	else
	{
		pPlayer->EmitSound( "Player.DenyWeaponSelection" );
	}
}

//-----------------------------------------------------------------------------
// Purpose: Weapon selection code
//-----------------------------------------------------------------------------
void CHudWeaponSelection::SelectWeaponSlot( int iSlot )
{
	// Get the local player.
	C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer();
	if ( !pPlayer )
		return;

	// Make sure the player's allowed to switch weapons
	if ( pPlayer->IsAllowedToSwitchWeapons() == false )
		return;

	// Make it active
	if ( !IsInSelectionMode() )
	{
		OpenSelection();
	}

	RebuildMenus();
	CWeaponMenuItem *item = FindWeapon( GetActiveMenu(), iSlot );

	C_BaseCombatWeapon *weapon = item ? item->weapon : NULL;

	if ( item && item->buildslot )
	{
		SelectBuildMenuSlot( m_BuildObjects[ item->openbuildmenu ] );
		return;
	}

	if ( m_bInBuildMenu )
	{
		CWeaponMenuItem *mainItem = FindWeapon( m_Weapons, iSlot );
		if ( mainItem )
		{
			if ( mainItem->buildslot )
			{
				if ( mainItem->openbuildmenu == m_nActiveBuildMenu )
				{
					CycleToNextWeapon();
				}
				else
				{
					SelectBuildMenuSlot(  m_BuildObjects[ mainItem->openbuildmenu ] );
				}
			}
			else if ( mainItem->weapon )
			{
				// Play the "open weapon selection" sound
				pPlayer->EmitSound( "Player.WeaponSelectionOpen" );

				m_bInBuildMenu = false;
				m_hSelectedWeapon = mainItem->weapon;
				GetActiveMenu().SetActiveItem( mainItem->hotkey );

				// Check for fast weapon switch mode
				if ( GetSelectedWeapon() && GetSelectedWeapon()->CanBeSelected() )
				{	
					// There's only one active item in bucket, so change directly to weapon
					SetWeaponSelected();
					CancelWeaponSelection();
					return;
				}
			}
		}
		return;
	}

	if ( item && weapon )
	{
		// Play the "open weapon selection" sound
		pPlayer->EmitSound( "Player.WeaponSelectionOpen" );

		if ( !weapon->CanBeSelected() )
		{
			if ( GetActiveMenu().GetActiveItem() == item->hotkey )
			{
				pPlayer->EmitSound( "Player.DenyWeaponSelection" );
			}
		}

		m_hSelectedWeapon = weapon;
		GetActiveMenu().SetActiveItem( item->hotkey );

		// Check for fast weapon switch mode
		if ( GetSelectedWeapon() && GetSelectedWeapon()->CanBeSelected() )
		{	
			// There's only one active item in bucket, so change directly to weapon
			SetWeaponSelected();
			CancelWeaponSelection();
			return;
		}
	}
	else
	{
		pPlayer->EmitSound( "Player.DenyWeaponSelection" );
	}
}

//-----------------------------------------------------------------------------
// Purpose: Player has chosen to draw the currently selected weapon
//-----------------------------------------------------------------------------
void CHudWeaponSelection::SelectWeapon( void )
{
	C_BasePlayer *player = C_BasePlayer::GetLocalPlayer();
	if ( !player )
		return;

	CWeaponMenuItem *item = FindWeapon( GetActiveMenu(), GetActiveMenu().GetActiveItem() );
	if ( !item )
	{
		CancelWeaponSelection();
		return;
	}

	if ( item->buildslot )
	{
		SelectBuildMenuSlot(  m_BuildObjects[ item->openbuildmenu ] );
		return;
	}

	CBaseHudWeaponSelection::SelectWeapon();
}

//-----------------------------------------------------------------------------
// Purpose: 
// Input  : down - 
//			keynum - 
//			*pszCurrentBinding - 
//-----------------------------------------------------------------------------
int	CHudWeaponSelection::KeyInput( int down, int keynum, const char *pszCurrentBinding )
{
	if ( !down )
		return 1;

	if ( keynum != K_ESCAPE )
		return 1;

	C_BasePlayer *player = C_BasePlayer::GetLocalPlayer();
	if ( !player )
		return 1;

	if ( !IsInSelectionMode() )
		return 1;

	if ( !m_bInBuildMenu )
	{
		CancelWeaponSelection();
		return 0;
	}

	// Play the "open weapon selection" sound
	player->EmitSound( "Player.WeaponSelectionOpen" );

	HideBuildMenu();

	// Swallow the key
	return 0;
}

void CHudWeaponSelection::OpenSelection( void )
{
	HideBuildMenu();
	m_nActiveBuildMenu = -1;
	
	CBaseHudWeaponSelection::OpenSelection();
	
	g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("WeaponOpenWeaponMenu");
}

void CHudWeaponSelection::HideSelection( void )
{
	CBaseHudWeaponSelection::HideSelection();
	
	if ( m_bInBuildMenu )
	{
		HideBuildMenu();
	}

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

int CHudWeaponSelection::GetTeamIndex()
{
	C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer();
	if(!pPlayer)
		return HUMAN_WEAPON_SELECTION;
	int team = pPlayer->GetTeamNumber();
	if ( !team )
		return HUMAN_WEAPON_SELECTION;

	bool human = ( team == TEAM_HUMANS ) ? true : false;
	return human ? HUMAN_WEAPON_SELECTION : ALIEN_WEAPON_SELECTION;
}

//-----------------------------------------------------------------------------
// Purpose: serializes settings from a resource data container
//-----------------------------------------------------------------------------
void CHudWeaponSelection::ApplySettings( KeyValues *resourceData )
{
	BaseClass::ApplySettings( resourceData );

	// loop through all the keys, applying them wherever
	for (KeyValues *controlKeys = resourceData->GetFirstSubKey(); controlKeys != NULL; controlKeys = controlKeys->GetNextKey())
	{
		// Skip keys that are atomic..
		if (controlKeys->GetDataType() != KeyValues::TYPE_NONE)
			continue;

		Panel *panel = FindChildByName( controlKeys->GetName() );
		if ( !panel )
			continue;

		// apply the settings
		panel->ApplySettings(controlKeys);
	}
}









//-----------------------------------------------------------------------------
// Purpose: 
// Input  : *parent - 
//			*panelName - 
//-----------------------------------------------------------------------------
CHudWeaponItemPanel::CHudWeaponItemPanel( vgui::Panel *parent, const char *panelName )
	: BaseClass( parent, panelName )
{
	m_bInUse = false;
	m_bDrawNumbers = false;
	m_nSlotNumber = 0;

	// Copies of data
	memset( &info, 0, sizeof( info ) );
	memset( &menuItem, 0, sizeof( menuItem ) );

	memset( m_BackgroundIcons, 0, sizeof( m_BackgroundIcons ) );
}

//-----------------------------------------------------------------------------
// Purpose: 
// Input  : *scheme - 
//-----------------------------------------------------------------------------
void CHudWeaponItemPanel::ApplySchemeSettings( vgui::IScheme *scheme )
{
	BaseClass::ApplySchemeSettings( scheme );
	SetPaintBackgroundEnabled( false );
}

//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CHudWeaponItemPanel::Paint()
{
	if ( !m_bInUse )
		return;

	CHudWeaponSelection *selection = static_cast< CHudWeaponSelection * >( GetParent() );
	if ( !selection )
		return;

	int wide, tall;
	GetSize( wide, tall );

	float transparencyfrac = m_flGrowFraction;

	float sizefracw = m_flGrowFraction;
	float sizefrach = m_flGrowFraction;
	float sizefrac = m_flGrowFraction;

	bool buildMenu = m_bBuildMenu;

	bool isactive = info.active;
	bool isvalid = 	info.valid;

	Color iconColor = selection->GetFgColor();
	Color textColor  = selection->m_TextColor;
	if ( isactive )
	{
		if ( !isvalid )
		{
			iconColor = selection->m_InvalidActiveColor;
			textColor = selection->m_InvalidActiveTextColor;
		}
	}
	else
	{
		if ( isvalid )
		{
			iconColor = selection->m_OtherColor;
			textColor = selection->m_OtherTextColor;
		}
		else
		{
			iconColor = selection->m_InvalidColor;
			textColor = selection->m_InvalidTextColor;
		}
	}

	Color ammoColor = info.ammoCaution ? selection->m_AmmoCautionColor : selection->m_AmmoNormalColor;

	TranslateColor( transparencyfrac, iconColor );
	TranslateColor( transparencyfrac, textColor );
	TranslateColor( transparencyfrac, ammoColor );

	// Draw box
	DrawBox( buildMenu, 0, 0, wide, tall, isactive, isvalid, m_flGrowFraction * 255, m_bDrawNumbers ? menuItem.hotkey : -1 );

	// icons use old system, drawing in screen space
	int iconXPos = m_flIconXPos;
	int iconYPos = m_flIconYPos;
	int iconWide = m_flIconWidth;
	int iconTall = m_flIconHeight;

	if ( info.icon )
	{
		info.icon->DrawSelf( sizefracw * iconXPos, sizefrach * iconYPos, sizefracw * iconWide, sizefrach * iconTall,
			iconColor ); 
	}

	surface()->DrawSetTextColor( textColor );
	HFont textFont = sizefrac < 1.0 ? selection->m_hTextFontSmall : selection->m_hTextFont;
	surface()->DrawSetTextFont( textFont );
	//int slen = UTIL_ComputeStringWidth( textFont, info.printname ); 
	int charCount = Q_strlen( info.printname );

	int textYPos = m_flTextYPos;
	int textXPos = m_flTextXPos;

	surface()->DrawSetTextPos( sizefracw * textXPos, sizefrach * textYPos );
	for (char *pch = info.printname; charCount > 0; pch++, charCount--)
	{
		surface()->DrawUnicodeChar(*pch);
	}

	if ( info.drawAmmo )
	{
		int ammoBarX = m_flAmmoBarX;
		int ammoBarWide = m_flAmmoBarWide;

		// Draw the clip ratio bar
		gHUD.DrawProgressBar( 
			sizefracw * ammoBarX, sizefrach * iconYPos, 
			sizefracw * ammoBarWide, sizefrach * iconTall, info.ammoPerc, 
			ammoColor, CHud::HUDPB_VERTICAL );
	}

	// Let the weapon draw stuff too
	if ( info.weapon )
	{
		C_WeaponObjectSelection *selectionWeapon = dynamic_cast< C_WeaponObjectSelection * >( info.weapon.Get() );
		if ( selectionWeapon )
		{
			OnWeaponSelectionDrawn( selection, selectionWeapon, isactive, wide, tall, textColor );
		}
	}
}

//-----------------------------------------------------------------------------
// Purpose: We've just been drawn in the weapon selection
//-----------------------------------------------------------------------------
void CHudWeaponItemPanel::OnWeaponSelectionDrawn( CHudWeaponSelection *selection, C_WeaponObjectSelection *weapon, 
	bool bCurrentlySelected, int wide, int tall, Color& clr )
{
	CBaseTFPlayer *pOwner = ToBaseTFPlayer( weapon->GetOwner() );
	if ( !pOwner )
		return;

	// Draw our resource cost
	int	fontHeight = vgui::surface()->GetFontTall( selection->m_hPriceFont );
	int iCost = CalculateObjectCost( weapon->GetSubType(),  pOwner->GetNumObjects(weapon->GetSubType()), pOwner->GetTeamNumber() );

	int x = wide - m_flPriceXEndPos;
	int y = tall - m_flPriceYEndPos - fontHeight;

	char text[ 32 ];
	Q_snprintf( text, sizeof( text ), "%i", iCost );

	// Compute pixels needed so we can right justify it
	int pixels = 0;
	char *pch;
	for (pch = text; *pch != 0; pch++)
	{
		pixels += vgui::surface()->GetCharacterWidth( selection->m_hPriceFont, *pch );
	}

	vgui::surface()->DrawSetTextFont( selection->m_hPriceFont );
	vgui::surface()->DrawSetTextPos( x - pixels, y );
	vgui::surface()->DrawSetTextColor( clr );
	for ( pch = text; *pch; pch++ )
	{
		vgui::surface()->DrawUnicodeChar(*pch);
	}
}

//-----------------------------------------------------------------------------
// Purpose: 
// Input  : percent - 
//			clr - 
//-----------------------------------------------------------------------------
void CHudWeaponItemPanel::TranslateColor( float percent, Color& clr )
{
	if ( percent >= 1.0f )
		return;

	if ( percent <= 0.75f )
	{
		clr = Color( 0, 0, 0, 0 );
	}
	else
	{
		float frac = ( percent - 0.75f ) / 0.25f;

		clr = Color( clr[0] * frac,
			clr[1] * frac,
			clr[2] * frac,
			clr[3] * frac );
	}
}

//-----------------------------------------------------------------------------
// Purpose: draws a selection box
//-----------------------------------------------------------------------------
void CHudWeaponItemPanel::DrawBox( bool isbuildmenu, int x, int y, int wide, int tall, bool isactive, bool isvalid, float normalizedAlpha, int number )
{
	CHudWeaponSelection *selection = static_cast< CHudWeaponSelection * >( GetParent() );
	if ( !selection )
	{
		Assert( 0 );
		return;
	}

	int team = GetTeamIndex();

	Color boxColor = Color( 255, 255, 255, 255 );
	boxColor[3] *= ( normalizedAlpha / 255.0f );

	Color numberColor = selection->m_TextColor;

	CHudTexture *texture;
	
	texture = m_BackgroundIcons[ team ][ (int)IMAGE_BACKGROUND ];
	if ( texture )
	{
		texture->DrawSelf( x, y, wide, tall, boxColor );
	}

	if ( isactive )
	{
		if ( !isvalid )
		{
			texture = m_BackgroundIcons[ team ][ (int)IMAGE_INVALID ];
			if ( texture )
			{
				texture->DrawSelf( x, y, wide, tall, boxColor );
			}

			numberColor = selection->m_InvalidActiveColor;
		}
		else
		{
			texture = m_BackgroundIcons[ team ][ (int)IMAGE_CURRENT ];
			if ( texture )
			{
				texture->DrawSelf( x, y, wide, tall, boxColor );
			}

			numberColor = selection->m_OtherColor;
		}
	}
	else
	{
		if ( !isvalid )
		{
			numberColor = selection->m_InvalidColor;
		}
		else
		{
			numberColor = selection->m_OtherColor;
		}
	}

	// draw the number
	if (number >= 0)
	{
		numberColor[3] *= ( normalizedAlpha / 255.0f );
		surface()->DrawSetTextColor(numberColor);
		surface()->DrawSetTextFont(selection->m_hNumberFont);
		wchar_t wch = '0' + number;
		surface()->DrawSetTextPos(x + m_flSelectionNumberXPos, y + m_flSelectionNumberYPos);
		surface()->DrawUnicodeChar(wch);
	}
}


//-----------------------------------------------------------------------------
// Purpose: 
// Output : int
//-----------------------------------------------------------------------------
int CHudWeaponItemPanel::GetTeamIndex()
{
	C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer();
	if(!pPlayer)
		return HUMAN_WEAPON_SELECTION;
	int team = pPlayer->GetTeamNumber();
	if ( !team )
		return HUMAN_WEAPON_SELECTION;

	bool human = ( team == TEAM_HUMANS ) ? true : false;
	return human ? HUMAN_WEAPON_SELECTION : ALIEN_WEAPON_SELECTION;
}


//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CHudWeaponItemPanel::SetupIcons()
{
	memset( m_BackgroundIcons, 0, sizeof( m_BackgroundIcons ) );

	const char *menutypestr = m_bBuildMenu ? "build" : "selection";

	for ( int team = 0; team < NUM_SLOT_TEAMS; team++ )
	{
		const char *teamtype = team == 0 ? "human" : "alien";

		for ( int type = 0; type < NUM_MENU_TYPES; type++ )
		{
			const char *slottype = type == 0 ? "background" : type == 1 ? "current" : "invalid";

			char sz[ 256 ];
			Q_snprintf( sz, sizeof( sz ), "%s_weapon_%s_%s_%i",
				teamtype, menutypestr, slottype, m_nSlotNumber + 1 );

			m_BackgroundIcons[ team ][ type ] = gHUD.GetIcon( sz );;
		}
	}
}
