//========= Copyright © 1996-2005, Sander Corporation, All rights reserved. ============//
//
// Purpose: hud_rts_unitpanel.cpp
//
// $NoKeywords: $
//=============================================================================//

#include "cbase.h"
#include "hl2wars/hud_rts_unitpanel.h"
#include <vgui/ISurface.h>
#include <KeyValues.h>
#include "c_ai_basenpc.h"
#include "c_rts_globalresource.h"
#include "hl2wars/c_hl2wars_player.h"
#include "hl2wars/in_buttons_rts.h"
#include "clientmode.h"
#include "hl2wars/rts_parsedata.h"

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

using namespace vgui;

//-----------------------------------------------------------------------------
// Purpose: Constructor
//-----------------------------------------------------------------------------
CHudRTSUnitPanel::CHudRTSUnitPanel( ) : BaseClass( NULL, "UnitPanel" )
{
	SetProportional( true );
	SetPaintBackgroundEnabled( false );
	SetKeyBoardInputEnabled( false );	
	SetMouseInputEnabled( true );	
	SetScheme("ClientScheme.res");

	SetBounds( 0,0, 256, 256 );
	SetBgColor( Color( 0,0,0,255 ) );  

	for( int i = 0; i < MAXUNITSLOTS; i++) {
		m_iLastUnitTypes[i] = -1;
		m_iLastHighLighted[i] = 1;
		m_pSlot[i] = NULL;
	}

	m_pImageUnits.SetLessFunc( DefLessFunc( int ) );

	m_iScaleLevel = SCALE_18;
}

//-----------------------------------------------------------------------------
// Purpose: Deconstructor
//-----------------------------------------------------------------------------
CHudRTSUnitPanel::~CHudRTSUnitPanel()
{

}

//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CHudRTSUnitPanel::Init( void )
{
	SetCursor( GetParent()->GetCursor() );

	// create slot buttons
	for(int i = 0; i < MAXUNITSLOTS; i++)
	{
		char szbuf[144];
		char szbuf2[144];
		Q_snprintf( szbuf, sizeof(szbuf), "unit_slot%d", i+1 );
		Q_snprintf( szbuf2, sizeof(szbuf2), "unit_double_slot%d", i+1 );
		m_pSlot[i] = new CBitmapButtonRTS( this, szbuf, NULL);
		CreateButtonUnits( m_pSlot[i], szbuf, szbuf2);
	}
}

//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CHudRTSUnitPanel::LevelShutdown( void )
{
	m_pImageUnits.RemoveAll();
}

//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CHudRTSUnitPanel::OnThink( void )
{
	if ( NeedsUpdate() )
	{
		Update();
	}
}

//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CHudRTSUnitPanel::Update()
{
	color32 color;
	color.r = color.g = color.b = color.a = 1.0f;

	// Check if we need to resize
	C_HL2Wars_Player* pPlayer = C_HL2Wars_Player::GetLocalHL2WarsPlayer();
	if( !pPlayer ) 
		return;

	if(pPlayer->m_HLWLocal.m_iNumSelected <= 18 && m_iScaleLevel != SCALE_18)
	{
		m_iScaleLevel = SCALE_18;
		CalculateSizePos();
	}
	else if(pPlayer->m_HLWLocal.m_iNumSelected > 18 && pPlayer->m_HLWLocal.m_iNumSelected <= 32 && m_iScaleLevel != SCALE_32)
	{
		m_iScaleLevel = SCALE_32;
		CalculateSizePos();
	}
	else if(pPlayer->m_HLWLocal.m_iNumSelected > 32 && pPlayer->m_HLWLocal.m_iNumSelected <= 72 && m_iScaleLevel != SCALE_72)
	{
		m_iScaleLevel = SCALE_72;
		CalculateSizePos();
	}

	// we need to find out the images for all buttons
	for( int i = 0; i < MAXUNITSLOTS; i++ ) {
		int unit_index = GetUnitIndex( i );

		UpdateLastHighLighted( i );

		if( unit_index == 0 ) 
		{
			m_pSlot[i]->SetVisible( false );
		}
		else
		{
			m_pSlot[i]->SetVisible( true );
			m_pSlot[i]->SetHealth( GetHealthWeight( i ) );
			// draw the image. GetImage will also check if the image is loaded already or not
			DrawImage( GetImage( GetUnitType( i ) ), i, m_iLastHighLighted[i], color);
		}

		m_iLastUnitTypes[i] = unit_index;
	}
}

//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
float CHudRTSUnitPanel::GetHealthWeight( int selected )
{
	C_HL2Wars_Player* pPlayer = C_HL2Wars_Player::GetLocalHL2WarsPlayer();
	if( !pPlayer ) 
		return 0.0f;

	return ( (float)(pPlayer->m_HLWLocal.m_hSelectedUnits[selected].Get()->GetHealth()) /
		(float)(pPlayer->m_HLWLocal.m_hSelectedUnits[selected].Get()->GetMaxHealth()) );
}

//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CHudRTSUnitPanel::DrawImage( BitmapImage *image, int i, int highlight, color32 color)
{
	m_pSlot[i]->SetImage( CBitmapButtonRTS::BUTTON_ENABLED, image, color);
	if( highlight == 2 )
	{
		m_pSlot[i]->AddButtonFlags( F_SELECTED );
	}
	else 
	{
		m_pSlot[i]->RemoveButtonFlags( F_SELECTED );
	}
	
}

//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CHudRTSUnitPanel::UpdateLastHighLighted( int i )
{
	C_HL2Wars_Player* pPlayer = C_HL2Wars_Player::GetLocalHL2WarsPlayer();
	if( !pPlayer ) 
		return;

	if( i == pPlayer->GetHighLightedUnit() ) {
		m_iLastHighLighted[i] = 2;
	}
	else {
		m_iLastHighLighted[i] = 1;
	}
}

//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
bool CHudRTSUnitPanel::NeedsUpdate( void )
{
	/*C_HL2Wars_Player* pPlayer = C_HL2Wars_Player::GetLocalHL2WarsPlayer();
	if( !pPlayer ) 
		return false;

	for( int i = 0; i < MAXUNITSLOTS; i++ ) {
		// don't change if already setted.
		if( ( m_iLastUnitTypes[i] != GetUnitIndex( i )) || 
				( ( m_iLastHighLighted[i] == 2 ) != ( i == pPlayer->m_iHighLightedUnit ) ) ) {
			return true;
		}
	}
	return false;*/
	return true;
}

//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
BitmapImage *CHudRTSUnitPanel::GetImage( const char *unit_type )
{
	FileUnitInfo_t *pFUI = GetFileUnitInfoFromHandle( LookupUnitInfoSlot( unit_type ) );
	if( !pFUI )
		return NULL;

	return pFUI->m_pImage;
}

//-----------------------------------------------------------------------------
// Purpose: Create button template
//-----------------------------------------------------------------------------
void CHudRTSUnitPanel::CreateButtonUnits( CBitmapButtonRTS *pSlot, const char *command, const char *command2 ) 
{
    pSlot->SetVisible( true );
	pSlot->SetPaintBackgroundEnabled( false );
	pSlot->SetPaintBorderEnabled( false );
	pSlot->SetParent(this);
	pSlot->AddActionSignalTarget(this);
	pSlot->SetCommand(command);
	pSlot->SetCommand2(command2);	// command 2 is double click
	pSlot->SetHighLightImages( "VGUI/button_hover", "VGUI/button_selected" );
	pSlot->SetMouseInputEnabled( true );
	pSlot->AddButtonFlags( F_ONEIMAGE );
	pSlot->AddButtonFlags( F_SHOWHEALTHBAR );
}

//-----------------------------------------------------------------------------
// Purpose: Assumes the unit box size is 2:1
//-----------------------------------------------------------------------------
void CHudRTSUnitPanel::CalculateSizePos( void )
{
	int xmax, ymax;
	int sizex, sizey;
	int x, y;
	GetSize( xmax, ymax );

	// determine size we need
	switch(m_iScaleLevel)
	{
	case SCALE_18:
		{
			x = 6;
			y = 3;
			break;
		}
	case SCALE_32:
		{
			x = 8;
			y = 4;
			break;
		}
	case SCALE_72:
		{
			x = 12;
			y = 6;
			break;
		}
	default:
		{
			x = 6;
			y = 3;
			break;
		}		
	}

	// calculate individual sizes of buttons and apply
	sizex = (int)(xmax / x);
	sizey = (int)(ymax / y);
	for(int i = 0; i < MAXUNITSLOTS; i++)
	{
		m_pSlot[i]->SetSize( sizex, sizey );
	}

	// set position for each button
	for(int j = 0; j < y; j++)
	{
		for(int i = 0; i < x; i++)
		{
			m_pSlot[i+j*x]->SetSize( sizex, sizey );
			m_pSlot[i+j*x]->SetPos( i*sizex, j*sizey );
		}
	}

}

//-----------------------------------------------------------------------------
// Purpose: Handles the button presses of the unit slots
//-----------------------------------------------------------------------------
void CHudRTSUnitPanel::OnCommand(const char *command) 
{ 
	C_HL2Wars_Player* pPlayer = C_HL2Wars_Player::GetLocalHL2WarsPlayer();
	if( !pPlayer ) 
		return;

	char szbuf[144];

	for(int i = 0; i < MAXUNITSLOTS; i++)
	{
		Q_snprintf( szbuf, sizeof(szbuf), "unit_slot%d", i+1 );
		if (!stricmp(command, szbuf)) 
		{ 
			engine->ServerCmd(VarArgs("hl2wars_us%d", i));	
			return;
		} 
	}

	for(int i = 0; i < MAXUNITSLOTS; i++)
	{
		Q_snprintf( szbuf, sizeof(szbuf), "unit_double_slot%d", i+1 );
		if (!stricmp(command, szbuf)) 
		{ 
			engine->ServerCmd(VarArgs("hl2wars_uds%d", i));	
			return;
		} 
	}

	BaseClass::OnCommand(command);   
}

//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
char *CHudRTSUnitPanel::GetUnitType( int i ) 
{  
	if(i < 0 || i >= MAXSELECTED)
		return "UNIT_NONE";

	C_HL2Wars_Player* pPlayer = C_HL2Wars_Player::GetLocalHL2WarsPlayer();
	if( !pPlayer ) 
		return "UNIT_NONE";

	if( pPlayer->m_HLWLocal.m_hSelectedUnits[i].Get() )
	{
		return (char *)g_RTSR->GetUnitType(pPlayer->m_HLWLocal.m_hSelectedUnits[i].Get()->GetUnitIndex());
	}
	else
		return "UNIT_NONE";
}

//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
int CHudRTSUnitPanel::GetUnitIndex( int i )
{
	if(i < 0 || i >= MAXSELECTED)
		return 0;

	C_HL2Wars_Player* pPlayer = C_HL2Wars_Player::GetLocalHL2WarsPlayer();
	if( !pPlayer ) 
		return 0;

	if( pPlayer->m_HLWLocal.m_hSelectedUnits[i] )
		return pPlayer->m_HLWLocal.m_hSelectedUnits[i].Get()->GetUnitIndex();
	else
		return 0;
}

void CHudRTSUnitPanel::OnMousePressed( vgui::MouseCode code)
{
	if( GetParent() )	// let our parent handle this
		GetParent()->OnMousePressed( code );
}

void CHudRTSUnitPanel::OnMouseReleased( vgui::MouseCode code)
{
	if( GetParent() )	// let our parent handle this
		GetParent()->OnMouseReleased( code );
}