//
// Tools_GUIMenu_Element_StatusText.cpp
//
// Created by Richard Rice - 26/04/2007
// 
// Copyright (C) 2006 Rebellion, All Rights Reserved.
//

#include "Core/Asura.h"
#include "GUIMenu/Tools_GUIMenu_Element_StatusText.h"

#ifdef ASURA_USE_GUI_MENU_SYSTEM
// Asura
#include "Core/Asura_HashedLocalisedText.h"
#include "Interface/Asura_CommandConsole.h"
#include "Interface/Asura_Dialog.h"
#include "Interface/Asura_Overlay.h"

#include "GUIMenu/Asura_GUIMenu_Modifier.h"
#include "GUIMenu/Asura_GUIMenu_System.h"
#include "Rendering/Asura_Font_System.h"

// Tools
#include "GUIMenu/Tools_GUIMenu_CommandConsole.h"
#include "GUIMenu/Tools_GUIMenu_PreviewOverlay.h"
#include "Interface/Tools_ColourPicker.h"
//#include "Misc/Tools_Dialog.h"
#include "Misc/Tools_Modal_Overlay.h"

// --------------------------------------------------------------------------------------

DEBUGVAR float dbg_fTextInfoSubwindowWidth = 35.f;
DEBUGVAR float dbg_fTextInfoSubwindowHeight = 20.f;

struct TextElementFormatingRenderFlag
{
	const Asura_Char* m_szName;
	u_int m_uValue;
};

static TextElementFormatingRenderFlag g_axHorzFormatFlags[] =
{
	{"None", 0},
	{"Left - Justify", ASURA_GUIMENU_STATUSTEXT_JUSTIFY_LEFT},
	{"Centre - Justify", ASURA_GUIMENU_STATUSTEXT_JUSTIFY_CENTRE},
	{"Right - Justify", ASURA_GUIMENU_STATUSTEXT_JUSTIFY_RIGHT},
};

static const Asura_Char* g_apcHorzFormatFlagNames[] =
{
	g_axHorzFormatFlags[0].m_szName,
	g_axHorzFormatFlags[1].m_szName,
	g_axHorzFormatFlags[2].m_szName,
	g_axHorzFormatFlags[3].m_szName
};

static const u_int g_uNumHorzRenderFlags = sizeof(g_axHorzFormatFlags) / sizeof(TextElementFormatingRenderFlag);

static TextElementFormatingRenderFlag g_axVertFormatFlags[] =
{
	{"None", 0},
	{"Centre - Justify", ASURA_GUIMENU_STATUSTEXT_JUSTIFY_VERTICAL_CENTRE},
	{"Bottom - Justify", ASURA_GUIMENU_STATUSTEXT_JUSTIFY_VERTICAL_BOTTOM},
};

static const Asura_Char* g_apcVertFormatFlagNames[] =
{
	g_axVertFormatFlags[0].m_szName,
	g_axVertFormatFlags[1].m_szName,
	g_axVertFormatFlags[2].m_szName
};

static TextElementFormatingRenderFlag g_axShadowFlags[] =
{
	{"None", 0},
	{"Shadow - Light", ASURA_GUIMENU_STATUSTEXT_DROPSHADOW_LIGHT},
	{"Shadow - Hard", ASURA_GUIMENU_STATUSTEXT_DROPSHADOW}
};

static const Asura_Char* g_apcShadowFlagNames[] =
{
	g_axShadowFlags[0].m_szName,
	g_axShadowFlags[1].m_szName,
	g_axShadowFlags[2].m_szName
};

static const u_int g_uNumShadowFlags = sizeof(g_axShadowFlags) / sizeof(TextElementFormatingRenderFlag);

static const u_int g_uNumVertRenderFlags = sizeof(g_axVertFormatFlags) / sizeof(TextElementFormatingRenderFlag);
static ListSelection_Overlay g_xTextElementTextIDOverlay("Select Text");

typedef TextElementFormatingRenderFlag ConditionInfo;

static ConditionInfo g_axConditionInfo[NUM_ASURA_GUIMENU_CONDITIONS] =
{
	{"None ", ASURA_GUIMENU_CONDITION_NONE},
	{"  =  ", ASURA_GUIMENU_CONDITION_EQUAL},
	{"  >  ", ASURA_GUIMENU_CONDITION_GREATER},
	{" >=  ", ASURA_GUIMENU_CONDITION_GREATER_EQUAL},
	{"  <  ", ASURA_GUIMENU_CONDITION_LESS},
	{" <=  ", ASURA_GUIMENU_CONDITION_LESS_EQUAL},
	{" !=  ", ASURA_GUIMENU_CONDITION_NOT_EQUAL	}
};

static const Asura_Char* g_apcConditionInfoNames[NUM_ASURA_GUIMENU_CONDITIONS] =
{
	g_axConditionInfo[0].m_szName,
	g_axConditionInfo[1].m_szName,
	g_axConditionInfo[2].m_szName,
	g_axConditionInfo[3].m_szName,
	g_axConditionInfo[4].m_szName,
	g_axConditionInfo[5].m_szName,
	g_axConditionInfo[6].m_szName
};

static const u_int g_uNumConditionInfo = sizeof(g_axConditionInfo) / sizeof(ConditionInfo);

// --------------------------------------------------------------------------------------

int Tools_GUIMenu_Element_StatusText::s_iMostRecentSelectedFont = 0;
Tools_GUIMenu_Element_StatusText* Tools_GUIMenu_Element_StatusText:: s_pxThis = NULL;

Tools_GUIMenu_Element_StatusText::Tools_GUIMenu_Element_StatusText(Asura_GUIMenu_Element_StatusText* pxAsuraStatusText,Tools_GUIMenu_Root* pxToolsParent)
:Tools_GUIMenu_Element_Base(pxAsuraStatusText,pxToolsParent)
{
	m_pxAsuraStatusText = pxAsuraStatusText;

	m_iCurrentHorzJustifyIndex		= 0;
	m_bHorzJustifyChanged			= false;
	m_iCurrentVertJustifyIndex		= 0;
	m_bVertJustifyChanged			= false;

	m_uHorzRenderFlag				= 0;
	m_uVertRenderFlag				= 0;

	m_bListChanged					= false;

	m_bShadowChanged				= false;
	m_uShadowFlag					= 0;
	m_iCurrentShadowIndex			= 0;
	m_bAutoScale = pxAsuraStatusText->GetTextRenderFlag(ASURA_GUIMENU_STATUSTEXT_SCALE_ON_PARENT_RESIZE);

	m_xToolsSpecialEffects.Initialise();
}

void Tools_GUIMenu_Element_StatusText::InitialiseNewItem()
{
	PARENT::InitialiseNewItem();

	//set an initial font
	const Asura_Font* pxFont = Asura_Font_System::GetFont(s_iMostRecentSelectedFont);
	if(pxFont)
	{
		m_pxAsuraStatusText->SetFontByName(pxFont->m_szFileName);
	}
	
}

void Tools_GUIMenu_Element_StatusText::Update()
{	
	PARENT::Update();

	if( m_bHorzJustifyChanged)
	{
		if( m_iCurrentHorzJustifyIndex < g_uNumHorzRenderFlags)
		{
			m_uHorzRenderFlag = g_axHorzFormatFlags[m_iCurrentHorzJustifyIndex].m_uValue;
			m_pxAsuraStatusText->SetTextRenderFlags( m_uHorzRenderFlag | m_uVertRenderFlag);
		}

		SetModified();
		m_bChanged = true;
		m_bHorzJustifyChanged = false;
	}

	if( m_bVertJustifyChanged)
	{
		if( m_iCurrentVertJustifyIndex < g_uNumVertRenderFlags)
		{
			m_uVertRenderFlag = g_axVertFormatFlags[m_iCurrentVertJustifyIndex].m_uValue;
			m_pxAsuraStatusText->SetTextRenderFlags( m_uHorzRenderFlag | m_uVertRenderFlag);
		}

		SetModified();
		m_bChanged = true;

		m_bVertJustifyChanged = false;
	}

	if( m_bListChanged == true)
	{
		Tools_GUIMenu_Root::DeleteOverlay();
		Tools_GUIMenu_Root::CreateOverlay();

		m_bListChanged = false;
		m_bChanged = true;
		SetModified();
	}

	if( m_bShadowChanged)
	{
		if( m_iCurrentShadowIndex < g_uNumShadowFlags)
		{
			m_uShadowFlag = g_axShadowFlags[m_iCurrentShadowIndex].m_uValue;
			m_pxAsuraStatusText->SetTextRenderFlag(ASURA_GUIMENU_STATUSTEXT_DROPSHADOW | ASURA_GUIMENU_STATUSTEXT_DROPSHADOW_LIGHT, false);
			m_pxAsuraStatusText->SetTextRenderFlag( m_uShadowFlag, true);
		}

		SetModified();
		m_bChanged = true;

		m_bShadowChanged = false;
	}

	if ( m_pxAsuraStatusText->GetStyleObjectHash() != ASURA_HASH_ID_UNSET )
	{
		m_xToolsSpecialEffects.DisableEditing(true);
	}
	else
	{
		m_xToolsSpecialEffects.DisableEditing(false);
	}
}

void Tools_GUIMenu_Element_StatusText::AddOverlayControls(Asura_Overlay* pxOverlay,Asura_Vector_2& xOffset)
{
	int i;

	s_pxThis = this;

	PARENT::AddOverlayControls(pxOverlay,xOffset);

	Asura_Dialog* pxDialog;

	xOffset.y += Asura_Dialog::SmallSpacing();

	pxDialog = new Asura_Function_Dialog("Font",xOffset,ChooseFont,(int)this);
	pxDialog->SetIsEnabledFunction(CanEditFontName,(int)this);
	pxDialog->SetHelpText("Select the font for this text item");
	pxDialog->m_iControlID = Asura_GetHashID("SelectFont");
	pxOverlay->AddDialog(pxDialog);
	xOffset.y += Asura_Dialog::DefaultSpacing();

	pxDialog = new Asura_Numerical_Dialog("Font Scale", xOffset, m_pxAsuraStatusText->GetFontScalePointer(), 0.0f, 9999.0f, 0.001f, "%3.3f", &m_bChanged);
	pxDialog->SetIsEnabledFunction(CanEditFontScale,(int)this);
	pxDialog->SetHelpText("Set the font scale for this text item");
	pxOverlay->AddDialog(pxDialog);
	xOffset.y += Asura_Dialog::DefaultSpacing();

	pxDialog = new Asura_Tickbox_Dialog("Scale on resize", xOffset, &m_bAutoScale, &m_bChanged);
	pxDialog->SetIsEnabledFunction(CanEditRenderFlags,(int)this);
	pxDialog->SetHelpText("Enables font to rescale when element is scaled");
	pxOverlay->AddDialog(pxDialog);
	xOffset.y += Asura_Dialog::DefaultSpacing();

	//pxDialog = new Asura_StringDisplay_Dialog( ".:: Text Justify - Horizontal ::.", xOffset);
	//pxOverlay->AddDialog(pxDialog);
	//xOffset.y += Asura_Dialog::DefaultSpacing();

	m_uHorzRenderFlag = 0;

	if( m_pxAsuraStatusText->GetTextRenderFlag( ASURA_GUIMENU_STATUSTEXT_JUSTIFY_LEFT))
	{
		m_uHorzRenderFlag = ASURA_GUIMENU_STATUSTEXT_JUSTIFY_LEFT;
	}
	else if( m_pxAsuraStatusText->GetTextRenderFlag( ASURA_GUIMENU_STATUSTEXT_JUSTIFY_CENTRE))
	{
		m_uHorzRenderFlag = ASURA_GUIMENU_STATUSTEXT_JUSTIFY_CENTRE;
	}
	else if( m_pxAsuraStatusText->GetTextRenderFlag( ASURA_GUIMENU_STATUSTEXT_JUSTIFY_RIGHT))
	{
		m_uHorzRenderFlag = ASURA_GUIMENU_STATUSTEXT_JUSTIFY_RIGHT;
	}

	for( i=0; i<g_uNumHorzRenderFlags; i++)
	{
		if( g_axHorzFormatFlags[i].m_uValue == m_uHorzRenderFlag)
		{
			m_iCurrentHorzJustifyIndex = i;
			break;
		}
	}

	pxDialog = new Asura_DropDown_List_Dialog( xOffset,
												&g_apcHorzFormatFlagNames[0],
												&m_iCurrentHorzJustifyIndex,
												g_uNumHorzRenderFlags, 
												g_uNumHorzRenderFlags,
												NULL, &m_bHorzJustifyChanged, "Text Justify - Horizontal");

	pxDialog->SetIsEnabledFunction(CanEditXOffset,(int)this);
	pxOverlay->AddDialog( pxDialog);
	xOffset.y += Asura_Dialog::DefaultSpacing();

	m_uVertRenderFlag = 0;

	if( m_pxAsuraStatusText->GetTextRenderFlag( ASURA_GUIMENU_STATUSTEXT_JUSTIFY_VERTICAL_BOTTOM))
	{
		m_uVertRenderFlag = ASURA_GUIMENU_STATUSTEXT_JUSTIFY_VERTICAL_BOTTOM;
	}
	else if( m_pxAsuraStatusText->GetTextRenderFlag( ASURA_GUIMENU_STATUSTEXT_JUSTIFY_VERTICAL_CENTRE))
	{
		m_uVertRenderFlag = ASURA_GUIMENU_STATUSTEXT_JUSTIFY_VERTICAL_CENTRE;
	}

	for( i=0; i<g_uNumVertRenderFlags; i++)
	{
		if( g_axVertFormatFlags[i].m_uValue == m_uVertRenderFlag)
		{
			m_iCurrentVertJustifyIndex = i;
			break;
		}
	}


	pxDialog = new Asura_DropDown_List_Dialog( xOffset,
												&g_apcVertFormatFlagNames[0],
												&m_iCurrentVertJustifyIndex,
												g_uNumVertRenderFlags, 
												g_uNumVertRenderFlags,
												NULL,
												&m_bVertJustifyChanged, "Text Justify - Vertical");

	pxDialog->SetIsEnabledFunction(CanEditYOffset,(int)this);
	pxOverlay->AddDialog( pxDialog);
	xOffset.y += Asura_Dialog::DefaultSpacing();

	m_uShadowFlag = 0;

	if( m_pxAsuraStatusText->GetTextRenderFlag( ASURA_GUIMENU_STATUSTEXT_DROPSHADOW_LIGHT))
	{
		m_uShadowFlag = ASURA_GUIMENU_STATUSTEXT_DROPSHADOW_LIGHT;
	}
	else if( m_pxAsuraStatusText->GetTextRenderFlag( ASURA_GUIMENU_STATUSTEXT_DROPSHADOW))
	{
		m_uShadowFlag = ASURA_GUIMENU_STATUSTEXT_DROPSHADOW;
	}

	m_iCurrentShadowIndex = 0;

	for( i=0; i<g_uNumShadowFlags; i++)
	{
		if( g_axShadowFlags[i].m_uValue == m_uShadowFlag)
		{
			m_iCurrentShadowIndex = i;
			break;
		}
	}

	pxDialog = new Asura_DropDown_List_Dialog( xOffset,
												&g_apcShadowFlagNames[0],
												&m_iCurrentShadowIndex,
												g_uNumShadowFlags, 
												g_uNumShadowFlags,
												NULL, &m_bShadowChanged, "Drop Shadow");

	pxDialog->SetIsEnabledFunction(CanEditRenderFlags,(int)this);
	pxOverlay->AddDialog( pxDialog);
	xOffset.y += Asura_Dialog::LargeSpacing();


	m_pxAsuraStatusText->m_xConsoleVar.AddOverlayControls( pxOverlay, xOffset, "Status Variable", "Console Variable (int) to match against", Asura_CommandConsole_VarRepository::Var::TYPE_INT, &m_bChanged);

	pxDialog = new Asura_Function_Dialog( "Add New Text Info", xOffset, AddNewTextInfo, (int)this, &m_bListChanged);
	pxDialog->SetHelpText("Adds a new 'Text Info' Entry");
//	pxDialog->ControlID = Asura_GetHashID("SelectFont");
	pxOverlay->AddDialog(pxDialog);
	xOffset.y += Asura_Dialog::DefaultSpacing();

	Asura_Vector_2 xSub( xOffset);
	xSub.x += Asura_Dialog::SmallSpacing();
	
	Asura_Subwindow_Dialog* pxSubWindow = new Asura_Subwindow_Dialog( xSub, dbg_fTextInfoSubwindowWidth, dbg_fTextInfoSubwindowHeight, true);
	pxOverlay->AddDialog(pxSubWindow);
	
	Asura_Vector_2 xPos( 0.0f, 0.0f);

	for( u_int u=0; u<m_pxAsuraStatusText->GetTextEntryCount(); u++)
	{
		AddTextInfoToDialog( u, pxSubWindow, xPos);
	}
	xOffset.y = pxSubWindow->m_xMaxCoord.y;
}

void Tools_GUIMenu_Element_StatusText::AddExtraOverlayControls(Asura_Overlay* pxOverlay, Asura_Tabs_Dialog* pxTabs, Asura_Vector_2& xOffset)
{
	m_xToolsSpecialEffects.CopyFromAsura(m_pxAsuraStatusText->GetSpecialEffectsSettings());
	m_xToolsSpecialEffects.AddEffectsOverlayControls(pxOverlay,pxTabs,xOffset,&m_bChanged);
}

void Tools_GUIMenu_Element_StatusText::UpdateOverlayControls(Asura_Overlay* pxOverlay)
{
	PARENT::UpdateOverlayControls(pxOverlay);

	//update font control
	char szText[100];
	Asura_PrintfToBfr(szText,"Font : %s",sizeof(szText),true,m_pxAsuraStatusText->GetFontName());

	pxOverlay->UpdateDialogLabel(Asura_GetHashID("SelectFont"),szText);

	//update modifier font control
	if(pxOverlay->GetDialog(Asura_GetHashID("SelectModifierFont")))
	{
		Asura_PrintfToBfr(szText,"Font : %s",sizeof(szText),true,m_xModifierData_String);
		pxOverlay->UpdateDialogLabel(Asura_GetHashID("SelectModifierFont"),szText);
	}
}

// -------------------------------------------------------------------------------------------------

void Tools_GUIMenu_Element_StatusText::AddTextInfoToDialog( u_int uIndex, Asura_Subwindow_Dialog* pxSubWindow, Asura_Vector_2& xOffset)
{
	Asura_Dialog* pxDialog;
	Asura_Vector_2 xVecPos( xOffset);
	Asura_Char cBuffer[256];
	int i;

	Asura_String xString;
	Asura_GUIMenu_StatusText_Info* pxInfo = m_pxAsuraStatusText->GetTextEntry( uIndex);
	if( pxInfo)
	{
		const Asura_HashedLocalisedText_Page* pxPage = Asura_HashedLocalisedText::GetPage(pxInfo->m_uTextPage);

		if(pxPage && pxPage->HasTextIDStrings())
		{
			Asura_Icon_Dialog* pxIcon = new Asura_Icon_Dialog( xVecPos,Tools_Dialog::GetIconTexture(), TOOLS_ICON_ARROW_UP);
			pxIcon->SetClickedFunction(_MoveUp, uIndex);
			pxIcon->SetClickedFlag(&m_bListChanged);
			pxIcon->SetHelpText("Move Up");
			pxSubWindow->AddDialog( pxIcon);

			xVecPos.x = pxIcon->m_xMaxCoord.x + 0.2f;

			pxIcon = new Asura_Icon_Dialog( xVecPos,Tools_Dialog::GetIconTexture(), TOOLS_ICON_ARROW_DOWN);
			pxIcon->SetClickedFunction(_MoveDown, uIndex);
			pxIcon->SetClickedFlag(&m_bListChanged);
			pxIcon->SetHelpText("Move Down");
			pxSubWindow->AddDialog( pxIcon);

			xVecPos.x = pxIcon->m_xMaxCoord.x + 0.2f;

			pxIcon = new Asura_Icon_Dialog( xVecPos,Tools_Dialog::GetIconTexture(),TOOLS_ICON_DELETE);
			pxIcon->SetClickedFunction(_Delete, uIndex);
			pxIcon->SetClickedFlag(&m_bListChanged);
			pxIcon->SetHelpText("Delete");
			pxSubWindow->AddDialog( pxIcon);

			xVecPos.x = pxIcon->m_xMaxCoord.x + 0.2f;

			Tools_ColourPicker_Dialog* pxColourDialog = new Tools_ColourPicker_Dialog("Colour",xVecPos,Asura_Vector_2(1.5f,1.0f),&pxInfo->m_xColour.m_fR,&pxInfo->m_xColour.m_fG,&pxInfo->m_xColour.m_fB,1.0f,&m_bChanged);
			pxColourDialog->EnableAlphaEditing(&pxInfo->m_xColour.m_fA);
			pxSubWindow->AddDialog(pxColourDialog);

			xVecPos.x = pxColourDialog->m_xMaxCoord.x + 0.2f;

			int iCompIndex = 0;		
			// first match compare condition
			for( i=0; i<g_uNumConditionInfo; i++)
			{
				if( g_axConditionInfo[i].m_uValue == (u_int)pxInfo->m_xDisplayParams.m_eConditionCompare)
				{
					iCompIndex = i;
					break;
				}
			}
				
			Asura_PrintfToBfr( cBuffer, "%s %d : ", 256, true, g_apcConditionInfoNames[iCompIndex], pxInfo->m_xDisplayParams.m_iDisplayConditionThreshold);
			xString = cBuffer;
			xString += 	pxPage->GetTextIDString( pxInfo->m_uTextID);

			pxDialog = new Asura_Function_Dialog( xString.GetString(), xVecPos, _EditTextInfoDetails, (int)uIndex, &m_bListChanged);
			pxDialog->SetHelpText("Edit Details");
			pxSubWindow->AddDialog(pxDialog);

			xOffset.y += Asura_Dialog::DefaultSpacing();
		}
	}
}

// -------------------------------------------------------------------------------------------------

void Tools_GUIMenu_Element_StatusText::_EditTextInfoDetails( int iValue)
{
	StatusTextInfoOverlay xOverlay;

	Asura_GUIMenu_Element_StatusText* pxText = s_pxThis->GetAsuraData();
	if( pxText)
	{
		Asura_GUIMenu_StatusText_Info* pxInfo = pxText->GetTextEntry( iValue);

		xOverlay.SetData( *pxInfo);

		if( xOverlay.DoModal() == true)
		{
			Asura_GUIMenu_StatusText_Info xInfo = xOverlay.GetData();
			pxInfo->m_uTextPage = xInfo.m_uTextPage;
			pxInfo->m_uTextID = xInfo.m_uTextID;
			pxInfo->m_xColour = xInfo.m_xColour;
			pxInfo->m_xDisplayParams = xInfo.m_xDisplayParams;
		}
	}
}

// -------------------------------------------------------------------------------------------------

void Tools_GUIMenu_Element_StatusText::_MoveUp(int iIndex)
{
	if( iIndex > 0)
	{
		Asura_GUIMenu_Element_StatusText* pxText = s_pxThis->GetAsuraData();
		if( pxText)
		{
			pxText->SwapTextEntries( iIndex, iIndex-1);
		}

	}
}

// -------------------------------------------------------------------------------------------------

void Tools_GUIMenu_Element_StatusText::_MoveDown(int iIndex)
{
	Asura_GUIMenu_Element_StatusText* pxText = s_pxThis->GetAsuraData();
	if( pxText)
	{
		u_int uCount = pxText->GetTextEntryCount();

		if( (iIndex >= 0) && (iIndex < (int)uCount-1))
		{
			pxText->SwapTextEntries( iIndex, iIndex+1);
		}
	}
}

// -------------------------------------------------------------------------------------------------

void Tools_GUIMenu_Element_StatusText::_Delete(int iIndex)
{
	Asura_GUIMenu_Element_StatusText* pxText = s_pxThis->GetAsuraData();
	if( pxText)
	{
		pxText->RemoveTextInfo( iIndex);
	}

}

// -------------------------------------------------------------------------------------------------

void Tools_GUIMenu_Element_StatusText::ChooseFont()
{
	Asura_String xCurrentFont = m_pxAsuraStatusText->GetFontName();

	ListSelection_Overlay xOverlay("Select Font");	

	//get a list of all loaded fonts
	for(int i=0;i<ASURA_MAX_FONTS;i++)	
	{
		const Asura_Font* pxFont = Asura_Font_System::GetFont(i);
		if(!pxFont) continue;

		bool bInitialSelection = !stricmp(xCurrentFont.GetString(),pxFont->m_szFileName);
		xOverlay.AddItem(pxFont->m_szFileName,i,bInitialSelection);
	}

	if(!xOverlay.GetNumItems())
	{
		//no fonts... means there won't be a tools font either , so the user is unlikely to have got this far.
		Asura_Assert(0,"Failed to find any loaded fonts");
		return;
	}

	if(!xOverlay.DoModal()) return;

	//update the asura data
	m_pxAsuraStatusText->SetFontByName(xOverlay.GetSelectionString());
	s_iMostRecentSelectedFont = xOverlay.GetSelectionData();

	//and the overlay
	UpdateOverlay();

	SetModified();
}

void Tools_GUIMenu_Element_StatusText::ChooseModifierFont()
{
	ListSelection_Overlay xOverlay("Select Font");	

	//get a list of all loaded fonts
	for(int i=0;i<ASURA_MAX_FONTS;i++)	
	{
		const Asura_Font* pxFont = Asura_Font_System::GetFont(i);
		if(!pxFont) continue;

		bool bInitialSelection = !stricmp(m_xModifierData_String.GetString(),pxFont->m_szFileName);
		xOverlay.AddItem(pxFont->m_szFileName,i,bInitialSelection);
	}

	if(!xOverlay.GetNumItems())
	{
		//no fonts... means there won't be a tools font either , so the user is unlikely to have got this far.
		Asura_Assert(0,"Failed to find any loaded fonts");
		return;
	}

	if(!xOverlay.DoModal()) return;

	m_xModifierData_String = xOverlay.GetSelectionString();
	m_bModifierChanged = true;

	UpdateOverlay();
}

void Tools_GUIMenu_Element_StatusText::SetFont(const char* szFontName)
{
	PARENT::SetFont(szFontName);

	if(CanEditFontName())
	{
		m_pxAsuraStatusText->SetFontByName(szFontName);
		SetModified();

		if(IsSelected()) UpdateOverlay();
	}
}


void Tools_GUIMenu_Element_StatusText::Copy(const Tools_GUIMenu_Root* pxSource)
{
	PARENT::Copy(pxSource);
	const Tools_GUIMenu_Element_StatusText* pxSourceStatusText = (const Tools_GUIMenu_Element_StatusText*) pxSource;
	m_bAutoScale = pxSourceStatusText->m_bAutoScale;

	m_xToolsSpecialEffects.Copy(&pxSourceStatusText->m_xToolsSpecialEffects);

	// Once tools settings have been copied make sure Asura object is correctly updated
	m_xToolsSpecialEffects.CopyToAsura(m_pxAsuraStatusText->GetSpecialEffectsSettings());
}

void Tools_GUIMenu_Element_StatusText::CopyToAsura()
{
	PARENT::CopyToAsura();
	m_pxAsuraStatusText->SetTextRenderFlag(ASURA_GUIMENU_STATUSTEXT_SCALE_ON_PARENT_RESIZE, m_bAutoScale);

	m_pxAsuraStatusText->SetEnableSpecialEffects(m_xToolsSpecialEffects.GetEnabledFlag());
	m_xToolsSpecialEffects.CopyToAsura(m_pxAsuraStatusText->GetSpecialEffectsSettings());
}

void Tools_GUIMenu_Element_StatusText::CopyFromAsura()
{
	m_xToolsSpecialEffects.CopyFromAsura(m_pxAsuraStatusText->GetSpecialEffectsSettings());
}

void Tools_GUIMenu_Element_StatusText::ChooseModifierText()
{
	//Asura_Hash_ID uTextID = m_uModifierData;
	//if(!ChooseText(uTextID)) return;

	//m_uModifierData = uTextID;

	//UpdateOverlay();
	//m_bModifierChanged = true;
}

// -------------------------------------------------------------------------------------------

void Tools_GUIMenu_Element_StatusText::AddNewTextInfo( void)
{
	Asura_RGBA xColour( 1.0f, 1.0f, 1.f, 1.0f);

	m_pxAsuraStatusText->AddTextInfo( uASURA_HASHEDTEXTPAGE_MENU, ASURA_HASH_ID_UNSET, 
									  ASURA_GUIMENU_CONDITION_NONE,
									  0,
									  xColour);

}

// -------------------------------------------------------------------------------------------

const char* Tools_GUIMenu_Element_StatusText::GetLocalDataFlagName(u_int uFlagValue) const
{
	switch(uFlagValue)
	{
		case Asura_GUIMenu_Element_StatusText::ASURA_GUIMENU_ELEMENT_STATUSTEXT_LOCAL_FLAG_FONT_SCALE :
			return "Font Scale";

		case Asura_GUIMenu_Element_StatusText::ASURA_GUIMENU_ELEMENT_STATUSTEXT_LOCAL_FLAG_FONT_NAME :
			return "Font Name";

		case Asura_GUIMenu_Element_StatusText::ASURA_GUIMENU_ELEMENT_STATUSTEXT_LOCAL_FLAG_OFFSET_X :
			return "X Offset";

		case Asura_GUIMenu_Element_StatusText::ASURA_GUIMENU_ELEMENT_STATUSTEXT_LOCAL_FLAG_OFFSET_Y:
			return "Y Offset";

		case Asura_GUIMenu_Element_StatusText::ASURA_GUIMENU_ELEMENT_STATUSTEXT_LOCAL_FLAG_RENDER_FLAGS :
			return "Render Flags";

		default :
			return PARENT::GetLocalDataFlagName(uFlagValue);

	}
}

// returns whether this object supports e.g. position, or UVs etc.
bool Tools_GUIMenu_Element_StatusText::IsModifierTypeSupported( ASURA_GUIMENU_MODIFY_TYPE eType ) const
{
	switch (eType)
	{
		case ASURA_GUIMENU_MODIFY_TEXT_STRING:
		case ASURA_GUIMENU_MODIFY_TEXT_OFFSET_X:
		case ASURA_GUIMENU_MODIFY_TEXT_OFFSET_Y:
		case ASURA_GUIMENU_MODIFY_TEXT_RENDER_FLAGS:
		case ASURA_GUIMENU_MODIFY_TEXT_ID:
		case ASURA_GUIMENU_MODIFY_FONT_SCALE:
		case ASURA_GUIMENU_MODIFY_FONT_NAME:
			return true;
		default:
			return PARENT::IsModifierTypeSupported(eType);
	}
}


bool Tools_GUIMenu_Element_StatusText::CanEditFontScale()
{
	return ShouldStyleUseLocalDataFor(Asura_GUIMenu_Element_StatusText::ASURA_GUIMENU_ELEMENT_STATUSTEXT_LOCAL_FLAG_FONT_SCALE);
}

bool Tools_GUIMenu_Element_StatusText::CanEditFontName()
{
	return ShouldStyleUseLocalDataFor(Asura_GUIMenu_Element_StatusText::ASURA_GUIMENU_ELEMENT_STATUSTEXT_LOCAL_FLAG_FONT_NAME);
}

//bool Tools_GUIMenu_Element_StatusText::CanEditTextID()
//{
//	return ShouldStyleUseLocalDataFor(Asura_GUIMenu_Element_StatusText::ASURA_GUIMENU_ELEMENT_STATUSTEXT_LOCAL_FLAG_TEXT_ID);
//}

bool Tools_GUIMenu_Element_StatusText::CanEditXOffset()
{
	return ShouldStyleUseLocalDataFor(Asura_GUIMenu_Element_StatusText::ASURA_GUIMENU_ELEMENT_STATUSTEXT_LOCAL_FLAG_OFFSET_X);
}

bool Tools_GUIMenu_Element_StatusText::CanEditYOffset()
{
	return ShouldStyleUseLocalDataFor(Asura_GUIMenu_Element_StatusText::ASURA_GUIMENU_ELEMENT_STATUSTEXT_LOCAL_FLAG_OFFSET_Y);
}

bool Tools_GUIMenu_Element_StatusText::CanEditRenderFlags()
{
	return ShouldStyleUseLocalDataFor(Asura_GUIMenu_Element_StatusText::ASURA_GUIMENU_ELEMENT_STATUSTEXT_LOCAL_FLAG_RENDER_FLAGS);
}


void Tools_GUIMenu_Element_StatusText::AddModifierOverlayControls(Asura_GUIMenu_Modifier* pxModifier, Asura_Vector_2& xOffset )
{
	Asura_Dialog* pxDialog;

	switch(pxModifier->GetModifyType())
	{
		case ASURA_GUIMENU_MODIFY_TEXT_STRING:
		{
			//get the existing text and convert from unicode
			char szText[200] = "";
			Asura_PrintfToBfr(szText,"%S",sizeof(szText),true,pxModifier->GetUnicodeCharStringData());
			m_xModifierData_String = szText;

			pxDialog = new Asura_String_Dialog("Text",xOffset,&m_xModifierData_String,30,&m_bModifierChanged);
			pxDialog->SetHelpText("The text to use when the modifier is active");
			((Asura_String_Dialog*)pxDialog)->SetMaxStringLength(200);
			AddModifierDialog(pxDialog);
			xOffset.y += Asura_Dialog::DefaultSpacing();
			
		}
		break;

		case ASURA_GUIMENU_MODIFY_TEXT_OFFSET_X:
		{
			m_fModifierData = pxModifier->GetFloatData();

			pxDialog = new Asura_Numerical_Dialog("Text X Offset", xOffset, &m_fModifierData, -9999.0f, 9999.0f, 1.0f, "%.0f", &m_bModifierChanged);
			pxDialog->SetHelpText("The text offset to use when the modifier is active");
			AddModifierDialog(pxDialog);
			xOffset.y += Asura_Dialog::DefaultSpacing();
		
		}
		break;

		case ASURA_GUIMENU_MODIFY_TEXT_OFFSET_Y:
		{
			m_fModifierData = pxModifier->GetFloatData();

			pxDialog = new Asura_Numerical_Dialog("Text Y Offset", xOffset, &m_fModifierData, -9999.0f, 9999.0f, 1.0f, "%.0f", &m_bModifierChanged);
			pxDialog->SetHelpText("The text offset to use when the modifier is active");
			AddModifierDialog(pxDialog);
			xOffset.y += Asura_Dialog::DefaultSpacing();
		}
		break;

		case ASURA_GUIMENU_MODIFY_TEXT_RENDER_FLAGS:
		{
			m_uModifierData = pxModifier->GetUIntData();

			int iHorizontalGroupID = Asura_GetHashID("ModifierHorizontalJustify");
			int iVerticalGroupID = Asura_GetHashID("ModifierVerticalJustify");

			pxDialog = new Asura_Dialog("Horizontal Justification :",xOffset);
			AddModifierDialog(pxDialog);
			xOffset.y += Asura_Dialog::DefaultSpacing();
			
			pxDialog = new Asura_FlagTickbox_Dialog("Left",xOffset,&m_uModifierData, ASURA_GUIMENU_STATUSTEXT_JUSTIFY_LEFT, &m_bModifierChanged);
			pxDialog->SetRadioButtonGroup(iHorizontalGroupID,false);
			AddModifierDialog(pxDialog);
			xOffset.x = pxDialog->m_xMaxCoord.x + 1.0f;

			pxDialog = new Asura_FlagTickbox_Dialog("Centre",xOffset,&m_uModifierData, ASURA_GUIMENU_STATUSTEXT_JUSTIFY_CENTRE, &m_bModifierChanged);
			pxDialog->SetRadioButtonGroup(iHorizontalGroupID,false);
			AddModifierDialog(pxDialog);
			xOffset.x = pxDialog->m_xMaxCoord.x + 1.0f;

			pxDialog = new Asura_FlagTickbox_Dialog("Right",xOffset,&m_uModifierData, ASURA_GUIMENU_STATUSTEXT_JUSTIFY_RIGHT, &m_bModifierChanged);
			pxDialog->SetRadioButtonGroup(iHorizontalGroupID,false);
			AddModifierDialog(pxDialog);
			xOffset.x = 1.0f;
			xOffset.y += Asura_Dialog::DefaultSpacing();

			pxDialog = new Asura_Dialog("Vertical Justification :",xOffset);
			AddModifierDialog(pxDialog);
			xOffset.y += Asura_Dialog::DefaultSpacing();

			pxDialog = new Asura_FlagTickbox_Dialog("Centre",xOffset,&m_uModifierData, ASURA_GUIMENU_STATUSTEXT_JUSTIFY_VERTICAL_CENTRE, &m_bModifierChanged);
			pxDialog->SetRadioButtonGroup(iVerticalGroupID,false);
			AddModifierDialog(pxDialog);
			xOffset.x = pxDialog->m_xMaxCoord.x + 1.0f;

			pxDialog = new Asura_FlagTickbox_Dialog("Right",xOffset,&m_uModifierData, ASURA_GUIMENU_STATUSTEXT_JUSTIFY_VERTICAL_BOTTOM, &m_bModifierChanged);
			pxDialog->SetRadioButtonGroup(iVerticalGroupID,false);
			AddModifierDialog(pxDialog);
			xOffset.x = 1.0f;
			xOffset.y += Asura_Dialog::DefaultSpacing();

		}
		break;

		case ASURA_GUIMENU_MODIFY_FONT_SCALE:
		{
			m_fModifierData = pxModifier->GetFloatData();

			pxDialog = new Asura_Numerical_Dialog("Font Scale", xOffset, &m_fModifierData, 0.0f, 9999.0f, 0.001f, "%3.3f", &m_bModifierChanged);
			pxDialog->SetHelpText("The font scale to use when the modifier is active");
			AddModifierDialog(pxDialog);
			xOffset.y += Asura_Dialog::DefaultSpacing();
		}
		break;

		case ASURA_GUIMENU_MODIFY_TEXT_ID:
		{
			m_uModifierData = pxModifier->GetUIntData();

			pxDialog = new Asura_Function_Dialog("Text",xOffset,ChooseModifierText,(int)this);
			pxDialog->SetHelpText("Select the text to use when the modifier is active.");
			pxDialog->m_iControlID = Asura_GetHashID("SelectModifierText");
			AddModifierDialog(pxDialog);
			xOffset.y += Asura_Dialog::DefaultSpacing();
			
		}
		break;

		case ASURA_GUIMENU_MODIFY_FONT_NAME:
		{
			m_xModifierData_String = pxModifier->GetCharStringData();

			pxDialog = new Asura_Function_Dialog("Font",xOffset,ChooseModifierFont,(int)this);
			pxDialog->SetIsEnabledFunction(CanEditFontName,(int)this);
			pxDialog->SetHelpText("Select the font to use when the modifier is active");
			pxDialog->m_iControlID = Asura_GetHashID("SelectModifierFont");
			AddModifierDialog(pxDialog);
			xOffset.y += Asura_Dialog::DefaultSpacing();
		}
		break;

		default :
			PARENT::AddModifierOverlayControls(pxModifier,xOffset);
			break;
	}
}

void Tools_GUIMenu_Element_StatusText::InitialiseModifier(Asura_GUIMenu_Modifier* pxModifier)
{
	switch(pxModifier->GetModifyType())
	{
		case ASURA_GUIMENU_MODIFY_TEXT_STRING:
			pxModifier->SetData(L"");
			break;

		case ASURA_GUIMENU_MODIFY_TEXT_OFFSET_X:
			pxModifier->SetData(m_pxAsuraStatusText->GetOffsetX());
			break;

		case ASURA_GUIMENU_MODIFY_TEXT_OFFSET_Y:
			pxModifier->SetData(m_pxAsuraStatusText->GetOffsetY());
			break;

		case ASURA_GUIMENU_MODIFY_TEXT_RENDER_FLAGS:
			pxModifier->SetData(m_pxAsuraStatusText->GetTextRenderFlags());
			break;

		case ASURA_GUIMENU_MODIFY_FONT_SCALE:
			pxModifier->SetData(m_pxAsuraStatusText->GetFontScale());
			break;

		case ASURA_GUIMENU_MODIFY_TEXT_ID:
			pxModifier->SetData( ASURA_HASH_ID_UNSET);
			break;

		case ASURA_GUIMENU_MODIFY_FONT_NAME:
			pxModifier->SetData(m_pxAsuraStatusText->GetFontName());
			break;

		default :
			PARENT::InitialiseModifier(pxModifier);
			break;
	}
}

// static function
void Tools_GUIMenu_Element_StatusText::TextUpdated()
{
	g_xTextElementTextIDOverlay.Reset();
}

void Tools_GUIMenu_Element_StatusText::AddToPreviewOverlay() const
{
	PARENT::AddToPreviewOverlay();

	const Asura_String xConsoleVarName = m_pxAsuraStatusText->m_xConsoleVar.GetName();
	if(xConsoleVarName != "*None*")
	{
		Tools_GUIMenu_PreviewOverlay::RegisterConsoleVariable(xConsoleVarName.GetString(),Asura_CommandConsole_VarRepository::Var::TYPE_INT);
	}
}


/*----------------**
** StatusTextInfo **
**----------------*/

StatusTextInfoOverlay::StatusTextInfoOverlay()
:Tools_Modal_Overlay("Edit Status Text Info")
{
	m_bTextChanged	= false;
	m_bChanged		= false;
	m_bCondTypeChanged = false;

	//m_fScaleU = 1.0f;
	//m_fScaleV = 1.0f;
	//m_bUniformScale = true;
	//m_bUChanged = false;
	//m_bVChanged = false;
}

bool StatusTextInfoOverlay::DoModal()
{
	m_bReturnValue = false;
	ShowOverlay();
	return m_bReturnValue;
}

void StatusTextInfoOverlay::OkaySelected(int iData)
{
	Asura_Assert(iData,"");
	*(bool*)iData = true;
}

void StatusTextInfoOverlay::CancelSelected(int iData)
{
	Asura_Assert(iData,"");
	*(bool*)iData = false;
}

void StatusTextInfoOverlay::InitialiseOverlay(class Asura_Overlay* pxOverlay)
{
	//setup the controls on the overlay
	Asura_Vector_2 xOffset = Asura_Vector_2(1.0f,3.0f);
	Asura_Dialog* pxDialog;
	u_int u;

	char szText[100];

	const Asura_String* pxTextPageName = Asura_GUIMenu_System::GetMenuTextFilenameFromHash(m_xInfo.m_uTextPage);
	Asura_Assert(pxTextPageName, "Could not find text page name");
	Asura_PrintfToBfr(szText,"Text Page : %s",sizeof(szText),true, pxTextPageName ? pxTextPageName->GetString() : "*Unknown*");	

	pxDialog = new Asura_Function_Dialog( szText, xOffset, ChooseTextPage, (int)this, &m_bTextChanged);
	pxDialog->SetHelpText("Select the text page to use.");
	pxDialog->m_iControlID = Asura_GetHashID("SelectTextPage");
	pxOverlay->AddDialog(pxDialog);
	xOffset.y += Asura_Dialog::DefaultSpacing();

	const Asura_HashedLocalisedText_Page* pxPage = Asura_HashedLocalisedText::GetPage(m_xInfo.m_uTextPage);
	const char* szID = pxPage ? pxPage->GetTextIDString( m_xInfo.m_uTextID) : NULL;
	Asura_PrintfToBfr(szText,"Text : %s", sizeof(szText), true, szID ? szID : "*None*");

	pxDialog = new Asura_Function_Dialog( szText, xOffset, ChooseText, (int)this, &m_bTextChanged);
	pxDialog->SetHelpText("Select the text to use.");
	pxDialog->m_iControlID = Asura_GetHashID("SelectText");
	pxOverlay->AddDialog(pxDialog);
	xOffset.y += Asura_Dialog::DefaultSpacing();


	pxDialog = new Asura_Numerical_Dialog("Compare Value", xOffset, &m_xInfo.m_xDisplayParams.m_iDisplayConditionThreshold, -2147483617, 2147483617, 1, "%d", &m_bChanged);
	pxDialog->SetHelpText("Compare Value.");
	pxOverlay->AddDialog(pxDialog);
	xOffset.y+=Asura_Dialog::DefaultSpacing();

	m_iCurrentConditionIndex = 0;

	for( u=0; u<g_uNumConditionInfo; u++)
	{
		if( g_axConditionInfo[u].m_uValue == (u_int)m_xInfo.m_xDisplayParams.m_eConditionCompare)
		{
			m_iCurrentConditionIndex = u;
			break;
		}
	}

	pxDialog = new Asura_DropDown_List_Dialog( xOffset,
												&g_apcConditionInfoNames[0],
												&m_iCurrentConditionIndex,
												g_uNumConditionInfo, 
												g_uNumConditionInfo,
												NULL,
												&m_bCondTypeChanged, "Compare Type");


	pxOverlay->AddDialog( pxDialog);
	xOffset.y += Asura_Dialog::LargeSpacing();

	pxDialog = new Asura_Function_Dialog("Okay",xOffset,OkaySelected,(int)&m_bReturnValue,&pxOverlay->m_bShouldClose);
	pxOverlay->AddDialog(pxDialog);
	xOffset.x+=7.0f;

	pxDialog = new Asura_Function_Dialog("Cancel",xOffset,CancelSelected,(int)&m_bReturnValue,&pxOverlay->m_bShouldClose);
	pxOverlay->AddDialog(pxDialog);
}

void StatusTextInfoOverlay::Update()
{
	if( m_bTextChanged)
	{
		char szText[100];
		Asura_Overlay* pxOverlay = GetOverlay();

		const Asura_HashedLocalisedText_Page* pxPage = Asura_HashedLocalisedText::GetPage(m_xInfo.m_uTextPage);
		const char* szID = pxPage ? pxPage->GetTextIDString( m_xInfo.m_uTextID) : NULL;
		Asura_PrintfToBfr(szText,"Text : %s", sizeof(szText), true, szID ? szID : "*None*");
		
		pxOverlay->UpdateDialogLabel(Asura_GetHashID("SelectText"),szText);

		const Asura_String* pxTextPageName = Asura_GUIMenu_System::GetMenuTextFilenameFromHash(m_xInfo.m_uTextPage);
		Asura_Assert(pxTextPageName, "Could not find text page name");
		Asura_PrintfToBfr(szText,"Text Page : %s",sizeof(szText),true, pxTextPageName ? pxTextPageName->GetString() : "*Unknown*");	
		pxOverlay->UpdateDialogLabel(Asura_GetHashID("SelectTextPage"),szText);

		m_bChanged = true;
		m_bTextChanged = false;
	}

	if( m_bCondTypeChanged)
	{
		m_xInfo.m_xDisplayParams.m_eConditionCompare = (Asura_GUIMenu_Display_Condition)g_axConditionInfo[m_iCurrentConditionIndex].m_uValue;

		m_bChanged = true;
		m_bCondTypeChanged = false;
	}
}

// ---------------------------------------------------------------------------------

void StatusTextInfoOverlay::ChooseTextPage( void)
{
	Asura_Hash_ID uTextPage = m_xInfo.m_uTextPage;

	if(!Tools_Mode_GUIMenu::ChooseTextPage(uTextPage)) { return; }
	
	if(uTextPage != m_xInfo.m_uTextPage)
	{
		m_xInfo.m_uTextPage = uTextPage;
		m_xInfo.m_uTextID = ASURA_HASH_ID_UNSET;
	}
}

void StatusTextInfoOverlay::ChooseText( void)
{
	Asura_Hash_ID uTextID = m_xInfo.m_uTextID;

	if(!Tools_Mode_GUIMenu::ChooseText(m_xInfo.m_uTextPage, uTextID)) { return; }

	m_xInfo.m_uTextID = uTextID;
}

#endif //ASURA_USE_GUI_MENU_SYSTEM
