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

#include "vgui_baseui_interface.h"
#include "vgui/IVGui.h"
#include "vgui_controls/Frame.h"
#include "vgui_controls/Label.h"
#include "vgui_controls/AnimationController.h"
#include "vgui/ILocalize.h"
#include "mathlib/mathlib.h"
#include "inputsystem/ButtonCode.h"
#include "vgui_askconnectpanel.h"
#include "keys.h"
#include "cl_pluginhelpers.h"


using namespace vgui;


class CAskConnectPanel : public EditablePanel
{
	DECLARE_CLASS_SIMPLE( CAskConnectPanel, vgui::EditablePanel );

public:
	CAskConnectPanel( VPANEL parent );
	~CAskConnectPanel();

	void GetHostName( char *pOut, int maxOutBytes );
	void SetHostName( const char *pHostName );
	void StartSlideAnimation( float flDuration );
	void UpdateCurrentPosition();
	void Hide();

	virtual void ApplySchemeSettings( vgui::IScheme *pScheme );
	virtual void ApplySettings(KeyValues *inResourceData);
	virtual void OnTick();

public:
	static CAskConnectPanel *s_pAskConnectPanel;

private:
	char m_HostName[256];
	Color m_bgColor;
	int m_OriginalWidth;					// Don't get less than this wide.
	
	double m_flAnimationEndTime;				// -1 if not playing

	Label *m_pInfoLabel;
	
	Label *m_pHostNameLabel;
	int m_HostNameLabelRightSidePadding;	// Grow the whole panel to make sure there's this much padding on the right of the hostname label.
	
	Label *m_pAcceptLabel;
	AnimationController *m_pAnimationController;
};

CAskConnectPanel *CAskConnectPanel::s_pAskConnectPanel = NULL;


CAskConnectPanel::CAskConnectPanel( VPANEL parent ) 
	: BaseClass( NULL, "AskConnectPanel" ), m_bgColor( 0, 0, 0, 192 )
{
	SetParent( parent );
	Assert( s_pAskConnectPanel == NULL );
	s_pAskConnectPanel = this;
	m_flAnimationEndTime = -1;

	SetKeyBoardInputEnabled( false );
	SetMouseInputEnabled( false );
	SetVisible( false );

	m_pHostNameLabel = new Label( this, "HostNameLabel", "" );
	m_pAcceptLabel = new Label( this, "AcceptLabel", "" );
	m_pInfoLabel = new Label( this, "InfoLabel", "" );
	
	m_HostName[0] = 0;
	vgui::ivgui()->AddTickSignal( GetVPanel() );
	SetAutoDelete( true );

	m_pAnimationController = new vgui::AnimationController( NULL );
	m_pAnimationController->SetParent( parent );
	m_pAnimationController->SetScriptFile( parent, "scripts/plugin_animations.txt" );
	m_pAnimationController->SetProportional( false );

	LoadControlSettings( "resource\\askconnectpanel.res" );
	InvalidateLayout( true );
	
	m_OriginalWidth = GetWide();
	int x, y, wide, tall;
	m_pHostNameLabel->GetBounds( x, y, wide, tall );
	m_HostNameLabelRightSidePadding = GetWide() - (x+wide);
}

CAskConnectPanel::~CAskConnectPanel()
{
	s_pAskConnectPanel = NULL;
}

void CAskConnectPanel::GetHostName( char *pOut, int maxOutBytes )
{
	V_strncpy( pOut, m_HostName, maxOutBytes );
}

void CAskConnectPanel::SetHostName( const char *pHostName )
{
	V_strncpy( m_HostName, pHostName, sizeof( m_HostName ) );
	m_pHostNameLabel->SetText( pHostName );
	
	// Update our width.
	int x, y, wide, tall;
	m_pHostNameLabel->SizeToContents();
	m_pHostNameLabel->GetBounds( x, y, wide, tall );	

	int x2, y2, wide2, tall2;
	wchar_t wcMessage[512];
	g_pVGuiLocalize->ConstructString_safe( wcMessage, g_pVGuiLocalize->Find("#Valve_ServerOfferingToConnect"), 0 );
	m_pInfoLabel->SetText( wcMessage );
	m_pInfoLabel->SizeToContents();
	m_pInfoLabel->GetBounds( x2, y2, wide2, tall2 );	

	int desiredWidth = max(x+wide,x2+wide2) + m_HostNameLabelRightSidePadding;
	if ( desiredWidth < m_OriginalWidth )
		desiredWidth = m_OriginalWidth;
	
	SetWide( desiredWidth );
}

void CAskConnectPanel::ApplySettings(KeyValues *inResourceData)
{
	BaseClass::ApplySettings(inResourceData);
	
	const char *pStr = inResourceData->GetString( "BgColor", NULL );
	if ( pStr )
	{
		int r = 0, g = 0, b = 0, a = 0;
		if ( sscanf( pStr, "%d %d %d %d", &r, &g, &b, &a ) == 4 )
		{
			m_bgColor = Color( r, g, b, a );
			SetBgColor( m_bgColor );
		}
	}
}

void CAskConnectPanel::StartSlideAnimation( float flDuration )
{
	m_flAnimationEndTime = Plat_FloatTime() + flDuration;
	
	// Figure out what key they have bound...
	const char *pKeyName = Key_NameForBinding( "askconnect_accept" );
	if ( pKeyName )
	{
		wchar_t wcKeyName[64], wcMessage[512];
		g_pVGuiLocalize->ConvertANSIToUnicode( pKeyName, wcKeyName, sizeof( wcKeyName ) );
		g_pVGuiLocalize->ConstructString_safe( wcMessage, g_pVGuiLocalize->Find("#Valve_PressKeyToAccept"), 1, wcKeyName );
		m_pAcceptLabel->SetText( wcMessage );
	}
	else
	{
		m_pAcceptLabel->SetText( "#Valve_BindKeyToAccept" );
	}

	m_pAnimationController->StartAnimationSequence( "AskConnectShow" ); 
	SetVisible( true );
	InvalidateLayout();
	UpdateCurrentPosition();
}

void CAskConnectPanel::Hide()
{
	m_flAnimationEndTime = -1;
	SetVisible( false );
}

void CAskConnectPanel::OnTick()
{
	// Do the hide animation?
	if ( m_flAnimationEndTime != -1 )
	{
		if ( Plat_FloatTime() > m_flAnimationEndTime )
		{
			m_flAnimationEndTime = -1;
			m_pAnimationController->StartAnimationSequence( "AskConnectHide" ); 
		}
	}

	m_pAnimationController->UpdateAnimations( Sys_FloatTime() );

	// Make sure vgui doesn't call Paint() on us after we're hidden.
	if ( GetAlpha() == 0 )
		SetVisible( false );

	if ( IsVisible() )
	{
		UpdateCurrentPosition();
	}

	BaseClass::OnTick();
}

void CAskConnectPanel::UpdateCurrentPosition()
{
	int x=0, y=0, wide=0, tall=0;
	if ( g_PluginManager )
		g_PluginManager->GetHudMessagePosition( x, y, wide, tall );
	
	SetPos( x, y+tall );
}

void CAskConnectPanel::ApplySchemeSettings( vgui::IScheme *pScheme )
{
	BaseClass::ApplySchemeSettings( pScheme );

	SetBgColor( m_bgColor );
	SetPaintBackgroundType( 2 );
}


void SetupDefaultAskConnectAcceptKey()
{
	// If they don't have a binding for askconnect_accept, set one up.
	if ( !Key_NameForBinding( "askconnect_accept" ) )
	{
		// .. but only if they don't already have something setup for F3.
		if ( !Key_BindingForKey( KEY_F3 ) )
		{
			Key_SetBinding( KEY_F3, "askconnect_accept" );
		}
	}
}


vgui::Panel* CreateAskConnectPanel( VPANEL parent )
{
	return new CAskConnectPanel( parent );
}


void ShowAskConnectPanel( const char *pHostName, float flDuration )
{
	const int cubHostName = V_strlen( pHostName );
	if ( cubHostName <= 0 )
		return;

	// Hostname is not allowed to contain semicolon, whitespace, or control characters
	for ( int i = 0; i < cubHostName; i++ )
	{
		if ( pHostName[i] == ';' || V_isspace( pHostName[i] ) || pHostName[i] < 0x20 )
		{
			return;
		}
	}

	CAskConnectPanel *pPanel = CAskConnectPanel::s_pAskConnectPanel;
	if ( pPanel )
	{
		pPanel->SetHostName( pHostName );
		pPanel->StartSlideAnimation( flDuration );
		pPanel->MoveToFront();
	}
}


void HideAskConnectPanel()
{
	CAskConnectPanel *pPanel = CAskConnectPanel::s_pAskConnectPanel;
	if ( pPanel )
		pPanel->Hide();
}

bool IsAskConnectPanelActive( char *pHostName, int maxHostNameBytes )
{
	CAskConnectPanel *pPanel = CAskConnectPanel::s_pAskConnectPanel;
	if ( pPanel && pPanel->IsVisible() && pPanel->GetAlpha() > 0 )
	{
		pPanel->GetHostName( pHostName, maxHostNameBytes );
		return true;
	}
	else
	{
		return false;
	}
}