// Tools_GUIMenu_Widget_TextListBox.cpp
//
// Created by Richard Rice - 05/12/2006
// 
// Copyright (C) 2006 Rebellion, All Rights Reserved.
//

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

#ifdef ASURA_USE_GUI_MENU_SYSTEM
#include "Interface/Asura_CommandConsole.h"
#include "Interface/Asura_Dialog.h"
#include "Interface/Asura_Overlay.h"
#include "Interface/Tools_ColourPicker.h"

#include "GUIMenu/Asura_GUIMenu_Element_Image.h"
#include "GUIMenu/Asura_GUIMenu_Element_Path.h"
#include "GUIMenu/Asura_GUIMenu_Element_StatusText.h"
#include "GUIMenu/Asura_GUIMenu_Widget_TextListBox.h"

#include "Rendering/Asura_Font_System.h"

#include "GUIMenu/Tools_GUIMenu_System.h"
#include "Misc/Tools_Modal_Overlay.h"

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

static const Asura_Char* const g_aszHorzTextJustificationNames [] =
{
	"None",     // HORZ_JUSTIFY_NONE,
	"Left",		// HORZ_JUSTIFY_LEFT,
	"Center",	// HORZ_JUSTIFY_CENTER,
	"Right",	// HORZ_JUSTIFY_RIGHT,
	
	NULL
};

static const Asura_Char* const g_aszVertTextJustificationNames [] =
{
	"None",		// VERT_JUSTIFY_NONE,
	"Center",	// VERT_JUSTIFY_CENTER,
	"Bottom",	// VERT_JUSTIFY_BOTTOM,
	
	NULL
};

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

int Tools_GUIMenu_Widget_TextListBox::s_iMostRecentSelectedFont = 0;

Tools_GUIMenu_Widget_TextListBox::Tools_GUIMenu_Widget_TextListBox(Asura_GUIMenu_Widget_TextListBox* pxAsuraListBox,Tools_GUIMenu_Root* pxToolsParent)
:Tools_GUIMenu_Widget_Base(pxAsuraListBox,pxToolsParent)
{
	m_pxAsuraListBox = pxAsuraListBox;

	m_uMaxAllowedEntries = m_pxAsuraListBox->GetMaxAllowedEntries();
	m_uMaxDisplayedEntries = m_pxAsuraListBox->GetMaxDisplayedEntries();
	m_fFontScale = m_pxAsuraListBox->GetFontScale();

	m_iCurrentHorzJustifyIndex		= 0;
	m_iCurrentVertJustifyIndex		= 0;
	m_bJustifyChanged				= false;

	m_bMaxActionsChanged			= false;

	m_pszImageNames					= 0;
	m_bDecImageChanged				= false;
	m_iCurrentDecImageIndex			= 0;
	m_bIncImageChanged				= false;
	m_iCurrentIncImageIndex			= 0;
	m_pszPathNames					= 0;
	m_bScrollBarChanged				= false;
	m_iCurrentScrollBarIndex		= 0;

	m_xFlashColour.Set( 1.0f, 0.0f, 0.0f, 1.0f);
	m_bFlashColourChanged			= 0;

	m_fFlashTime					= fASURA_GUIMENU_WIDGET_TEXTLISTBOX_FLASH_TIME_DEFAULT;
	m_bFlashTimeChanged				= false;
	
	m_fInitialRepeatDelay			= fASURA_GUIMENU_WIDGET_TEXTLISTBOX_CONTROL_INITIAL_REPEAT_DELAY;;
	m_fSecondaryRepeatDelay			= fASURA_GUIMENU_WIDGET_TEXTLISTBOX_CONTROL_SECONDARY_REPEAT_DELAY;
	m_bInputDelayChanged			= false;

	m_fScrollRate					= 0.0f;
	m_bWordWrap						= false;
	m_bResizeFont					= false;

	CopyFromAsura();
}

Tools_GUIMenu_Widget_TextListBox::~Tools_GUIMenu_Widget_TextListBox()
{
	delete [] m_pszImageNames;
	delete [] m_pszPathNames;
}

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

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

	//should have allow for at least one entry
	m_uMaxAllowedEntries = 1;
	m_uMaxDisplayedEntries = 1;
	m_pxAsuraListBox->SetMaxAllowedEntries(m_uMaxAllowedEntries);
	m_pxAsuraListBox->SetMaxDisplayedEntries(m_uMaxDisplayedEntries);
}

void Tools_GUIMenu_Widget_TextListBox::Update()
{
	PARENT::Update();
	
	if( m_bJustifyChanged)
	{
		m_bJustifyChanged = false;
		m_bChanged = true;
		SetModified();
	}

	if( m_bMaxActionsChanged)
	{
		Tools_GUIMenu_Root::DeleteOverlay();
		Tools_GUIMenu_Root::CreateOverlay();
		m_bMaxActionsChanged = false;
		m_bChanged = true;
		SetModified();
	}

	if( m_bDecImageChanged)
	{
		Asura_GUIMenu_Root* pxItem;
		Asura_Hash_ID uHashItem;
		Asura_Hash_ID uHashName;
		int iCount;
		u_int u;
		const Asura_Char** ppszList = Tools_GUIMenu_System::GetAllWidgetElementNames( m_pxAsuraListBox->GetID(), &iCount, Tools_GUIMenu_System::ELEMENT_FILTER_ALLOW_IMAGES);

		m_pxAsuraListBox->SetDecImage( NULL);

		uHashName = Asura_GetHashID( ppszList[m_iCurrentDecImageIndex]);
		for( u=0; u<m_pxAsuraListBox->GetContainerCount(); u++)
		{
			pxItem = m_pxAsuraListBox->GetContainerItem( u);
			uHashItem = Asura_GetHashID( pxItem->GetNameAsChar());
		
			if( uHashName == uHashItem)
			{
				m_pxAsuraListBox->SetDecImage( static_cast<Asura_GUIMenu_Element_Image*>(pxItem));
				break;
			}
		}

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

	if( m_bIncImageChanged)
	{
		Asura_GUIMenu_Root* pxItem;
		Asura_Hash_ID uHashItem;
		Asura_Hash_ID uHashName;
		int iCount;
		u_int u;
		const Asura_Char** ppszList = Tools_GUIMenu_System::GetAllWidgetElementNames( m_pxAsuraListBox->GetID(), &iCount, Tools_GUIMenu_System::ELEMENT_FILTER_ALLOW_IMAGES);

		m_pxAsuraListBox->SetIncImage( NULL);

		uHashName = Asura_GetHashID( ppszList[m_iCurrentIncImageIndex]);
		for( u=0; u<m_pxAsuraListBox->GetContainerCount(); u++)
		{
			pxItem = m_pxAsuraListBox->GetContainerItem( u);
			uHashItem = Asura_GetHashID( pxItem->GetNameAsChar());

			if( uHashName == uHashItem)
			{
				m_pxAsuraListBox->SetIncImage( static_cast<Asura_GUIMenu_Element_Image*>(pxItem));
				break;
			}
		}


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

	if( m_bScrollBarChanged)
	{
		Asura_GUIMenu_Root* pxItem;
		Asura_Hash_ID uHashItem;
		Asura_Hash_ID uHashName;
		int iCount;
		u_int u;
		const Asura_Char** ppszList = Tools_GUIMenu_System::GetAllWidgetElementNames( m_pxAsuraListBox->GetID(), &iCount, Tools_GUIMenu_System::ELEMENT_FILTER_ALLOW_PATH);

		m_pxAsuraListBox->SetScrollBar( NULL);

		uHashName = Asura_GetHashID( ppszList[m_iCurrentScrollBarIndex]);
		for( u=0; u<m_pxAsuraListBox->GetContainerCount(); u++)
		{
			pxItem = m_pxAsuraListBox->GetContainerItem( u);
			uHashItem = Asura_GetHashID( pxItem->GetNameAsChar());

			if( uHashName == uHashItem)
			{
				m_pxAsuraListBox->SetScrollBar( static_cast<Asura_GUIMenu_Element_Path*>(pxItem));
				break;
			}
		}


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

	if(m_bFlashColourChanged)
	{
		m_pxAsuraListBox->SetFlashColour( m_xFlashColour.m_fR, m_xFlashColour.m_fG, m_xFlashColour.m_fB, m_xFlashColour.m_fA);
		m_bFlashColourChanged = false;
		m_bChanged = true;
		SetModified();
	}

	if( m_bFlashTimeChanged)
	{
		m_pxAsuraListBox->SetFlashTime( m_fFlashTime);
		m_bFlashTimeChanged = false;
		m_bChanged = true;
		SetModified();
	}

	if( m_bInputDelayChanged)
	{
		m_pxAsuraListBox->SetInitialControlRepeatDelay( m_fInitialRepeatDelay);
		m_pxAsuraListBox->SetSecondaryControlRepeatDelay( m_fSecondaryRepeatDelay);
		m_bInputDelayChanged = false;
		m_bChanged = true;
		SetModified();
	}

	if( m_bChanged )
	{	
		CopyToAsura();
	}
}

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

	PARENT::AddOverlayControls(pxOverlay,xOffset);

	Asura_Dialog* pxDialog;

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

	pxDialog = new Asura_StringDisplay_Dialog( ".:: Button Press Repeat Settings ::.", xOffset);
	pxOverlay->AddDialog(pxDialog);
	xOffset.y += Asura_Dialog::DefaultSpacing();

	m_fInitialRepeatDelay = m_pxAsuraListBox->GetInitialControlRepeatDelay();
	m_fSecondaryRepeatDelay = m_pxAsuraListBox->GetSecondaryControlRepeatDelay();

	pxDialog = new Asura_Numerical_Dialog("Initial Repeat Delay", xOffset, &m_fInitialRepeatDelay, 0.0f, 10.0f, 0.1f, "%2.2f", &m_bInputDelayChanged);
	pxDialog->SetIsEnabledFunction(CanEditInputRepeat,(int)this);
	pxDialog->SetHelpText("Sets the initial repeat delay of a button press");
	pxOverlay->AddDialog( pxDialog );
	xOffset.y += Asura_Dialog::DefaultSpacing();

	pxDialog = new Asura_Numerical_Dialog("Secondary Repeat Delay", xOffset, &m_fSecondaryRepeatDelay, 0.0f, 10.0f, 0.1f, "%2.2f", &m_bInputDelayChanged);
	pxDialog->SetIsEnabledFunction(CanEditInputRepeat,(int)this);
	pxDialog->SetHelpText("Sets the secondary repeat delay of a button press");
	pxOverlay->AddDialog( pxDialog );
	xOffset.y += Asura_Dialog::DefaultSpacing();
	xOffset.y += Asura_Dialog::SmallSpacing();

	pxDialog = new Asura_Numerical_Dialog("Max Entries",xOffset,&m_uMaxAllowedEntries,1,9999,1,"%d",&m_bChanged);
	pxDialog->SetIsEnabledFunction(CanEditMaxEntries,(int)this);
	pxDialog->SetHelpText("Maximum number of entries allowed in the list box");
	pxOverlay->AddDialog(pxDialog);
	xOffset.y += Asura_Dialog::DefaultSpacing();

	pxDialog = new Asura_Numerical_Dialog("Max Displayed",xOffset,&m_uMaxDisplayedEntries,1,9999,1,"%d",&m_bChanged);
	pxDialog->SetIsEnabledFunction(CanEditMaxDisplayed,(int)this);
	pxDialog->SetHelpText("Maximum number of entries to display at once");
	pxOverlay->AddDialog(pxDialog);
	xOffset.y += Asura_Dialog::DefaultSpacing();

	pxDialog = new Asura_Function_Dialog("Font",xOffset,ChooseFont,(int)this);
	pxDialog->SetIsEnabledFunction(CanEditFont,(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_fFontScale, 0.0f, 9999.0f, 0.001f, "%3.3f", &m_bChanged);
	pxDialog->SetIsEnabledFunction(CanEditFont,(int)this);
	pxDialog->SetHelpText("Set the font scale for this text item");
	pxOverlay->AddDialog(pxDialog);
	xOffset.y += Asura_Dialog::LargeSpacing();

	pxDialog = new Asura_Numerical_Dialog("Scroll Rate", xOffset, &m_fScrollRate, 0.0f, 999.0f, 0.1f, "%.1f", &m_bChanged);
	pxDialog->SetIsEnabledFunction(CanEditFont,(int)this);
	pxDialog->SetHelpText("Scroll rate in pixels/second to use if the text is too long to fit in the box.");
	pxOverlay->AddDialog(pxDialog);
	xOffset.y += Asura_Dialog::DefaultSpacing();

	pxDialog = new Asura_Tickbox_Dialog("Word Wrap", xOffset, &m_bWordWrap, &m_bChanged);
	pxDialog->SetIsEnabledFunction(CanEditTextRenderFlags,(int)this);
	pxDialog->SetHelpText("Enables word wrapping if the string is too wide to fit.\nIgnored if using x offset , or scrolling");
	pxOverlay->AddDialog(pxDialog);
	xOffset.y += Asura_Dialog::DefaultSpacing();

	pxDialog = new Asura_Tickbox_Dialog("Resize Font", xOffset, &m_bResizeFont, &m_bChanged);
	pxDialog->SetIsEnabledFunction(CanEditTextRenderFlags,(int)this);
	pxDialog->SetHelpText("Multiplies the font scale by the scale applied to this objects\ndimensions when resized. This means that fonts will become smaller\non smaller screens etc.");
	pxOverlay->AddDialog(pxDialog);
	xOffset.y += Asura_Dialog::DefaultSpacing();

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

	pxDialog = new Asura_DropDown_List_Dialog(  xOffset,
												g_aszHorzTextJustificationNames,
												&m_iCurrentHorzJustifyIndex,
												HORZ_JUSTIFY_MAX, 
												HORZ_JUSTIFY_MAX,
												NULL, 
												&m_bJustifyChanged);

	pxOverlay->AddDialog( pxDialog);
	pxDialog->SetIsEnabledFunction(CanEditTextRenderFlags,(int)this);
	
	pxDialog = new Asura_StringDisplay_Dialog( "Horizontal", Asura_Vector_2(xOffset.x + 8,xOffset.y) );
	pxOverlay->AddDialog(pxDialog);
	
	xOffset.y += Asura_Dialog::DefaultSpacing();

	// Verticle justification
	pxDialog = new Asura_DropDown_List_Dialog(  xOffset,
												g_aszVertTextJustificationNames,
												&m_iCurrentVertJustifyIndex,
												VERT_JUSTIFY_MAX, 
												VERT_JUSTIFY_MAX,
												NULL, 
												&m_bJustifyChanged);

	pxOverlay->AddDialog( pxDialog);
	pxDialog->SetIsEnabledFunction(CanEditTextRenderFlags,(int)this);
	
	pxDialog = new Asura_StringDisplay_Dialog( "Vertical", Asura_Vector_2(xOffset.x + 8,xOffset.y) );
	pxOverlay->AddDialog(pxDialog);
		
	xOffset.y += Asura_Dialog::DefaultSpacing();


	// -- these allow you to specify which image elements will flash or disappear etc.
	// -- used as icons for either end of the list --
	int iCount = 0;

	delete [] m_pszImageNames;
	const char** pszName = Tools_GUIMenu_System::GetAllWidgetElementNames( m_pxAsuraListBox->GetID(), &iCount, Tools_GUIMenu_System::ELEMENT_FILTER_ALLOW_IMAGES);
	m_pszImageNames = new const char*[iCount];
	for(int i = 0; i < iCount; ++i)
	{
		m_pszImageNames[i] = pszName[i];
	}

	m_iCurrentDecImageIndex = 0;
	m_iCurrentIncImageIndex = 0;
	m_iCurrentScrollBarIndex = 0;

	const Asura_GUIMenu_Element_Image* pxDecImage = m_pxAsuraListBox->GetDecImage();
	Asura_Hash_ID uHashItem;
	Asura_Hash_ID uHashName;
	const Asura_Char* pcName;

	if( pxDecImage)
	{
		pcName = pxDecImage->GetNameAsChar();
		uHashName = Asura_GetHashID( pcName);

		for( i=0; i<iCount; i++)
		{
			uHashItem = Asura_GetHashID( m_pszImageNames[i]);

			if( uHashName == uHashItem)
			{
				m_iCurrentDecImageIndex = i;
				break;
			}
		}
	}

	pxDialog = new Asura_DropDown_List_Dialog( xOffset,
												m_pszImageNames,
												&m_iCurrentDecImageIndex,
												iCount, 
												iCount,
												NULL, &m_bDecImageChanged, ".:: Decrement Icon - Image Element ::.");

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


	const Asura_GUIMenu_Element_Image* pxIncImage = m_pxAsuraListBox->GetIncImage();

	if( pxIncImage)
	{
		pcName = pxIncImage->GetNameAsChar();
		uHashName = Asura_GetHashID( pcName);

		for( i=0; i<iCount; i++)
		{
			uHashItem = Asura_GetHashID( m_pszImageNames[i]);

			if( uHashName == uHashItem)
			{
				m_iCurrentIncImageIndex = i;
				break;
			}
		}
	}

	pxDialog = new Asura_DropDown_List_Dialog( xOffset,
												m_pszImageNames,
												&m_iCurrentIncImageIndex,
												iCount, 
												iCount,
												NULL, &m_bIncImageChanged, ".:: Increment Icon - Image Element ::.");

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


	int iPathCount = 0;
	delete [] m_pszPathNames;
	pszName = Tools_GUIMenu_System::GetAllWidgetElementNames( m_pxAsuraListBox->GetID(), &iPathCount, Tools_GUIMenu_System::ELEMENT_FILTER_ALLOW_PATH);
	m_pszPathNames = new const char*[iPathCount];
	for(int i = 0; i < iPathCount; ++i)
	{
		m_pszPathNames[i] = pszName[i];
	}

	const Asura_GUIMenu_Element_Path* pxScrollBar = m_pxAsuraListBox->GetScrollBar();

	if( pxScrollBar)
	{
		pcName = pxScrollBar->GetNameAsChar();
		uHashName = Asura_GetHashID( pcName);

		for( i=0; i<iPathCount; i++)
		{
			uHashItem = Asura_GetHashID( m_pszPathNames[i]);

			if( uHashName == uHashItem)
			{
				m_iCurrentScrollBarIndex = i;
				break;
			}
		}
	}

	pxDialog = new Asura_DropDown_List_Dialog( xOffset,
												m_pszPathNames,
												&m_iCurrentScrollBarIndex,
												iPathCount, 
												iPathCount,
												NULL, &m_bScrollBarChanged, ".:: Scroll Bar - Path Element ::.");
	pxDialog->SetHelpText("Adding a scrollbar causes the increment and decrement icons to act as scroll down and up.");

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

	Asura_Vector_2 xPos = xOffset;

	m_xFlashColour = m_pxAsuraListBox->GetFlashColour();

	Tools_ColourPicker_Dialog* pxColourDialog = new Tools_ColourPicker_Dialog( "Flash Colour",
																				xOffset,
																				Asura_Vector_2(1.5f,1.0f),
																				&m_xFlashColour.m_fR,
																				&m_xFlashColour.m_fG,
																				&m_xFlashColour.m_fB,
																				1.0f,
																				&m_bFlashColourChanged);
	pxColourDialog->EnableAlphaEditing(&m_xFlashColour.m_fA);
	pxColourDialog->SetIsEnabledFunction(CanEditFlash,(int)this);
	pxOverlay->AddDialog(pxColourDialog);
	xOffset.y += Asura_Dialog::DefaultSpacing();

	Asura_Vector_2 xDims = pxColourDialog->GetMaxCoords();
	xPos.x += xDims.x;

	m_fFlashTime = m_pxAsuraListBox->GetFlashTime();

	pxDialog = new Asura_Numerical_Dialog("Flash Time", xPos, &m_fFlashTime, 0.0f, 30.0f, 0.01f, "%3.2f", &m_bFlashTimeChanged);
	pxDialog->SetIsEnabledFunction(CanEditFlash,(int)this);
	pxDialog->SetHelpText("Specifies the length of time the flash stays active");
	pxOverlay->AddDialog( pxDialog );


	// don't allow arguments to be edited as they must be the index of the selected listbox item
	m_pxAsuraListBox->m_xCommandManager.AddOverlayControls( pxOverlay, xOffset, false, false, &m_bChanged, &m_bMaxActionsChanged);
	m_pxAsuraListBox->m_xPopulationFunction.AddOverlayControls( pxOverlay, xOffset, "Population function", 
		"This is a console command which takes the index of a listbox element and outputs the text to display in that widget.", 
		false, &m_bChanged);

	m_pxAsuraListBox->m_xInitValueVar.AddOverlayControls( pxOverlay,  
													   xOffset,
													   "Console Var",
													   "The console variable to take the initial value from (optional)",
													   Asura_CommandConsole_VarRepository::Var::TYPE_INT,
													   &m_bChanged);
}

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

	char szText[100];
	Asura_PrintfToBfr(szText,"Font : %s",sizeof(szText),true,m_pxAsuraListBox->GetFontName().GetString());

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


void Tools_GUIMenu_Widget_TextListBox::CopyToAsura()
{
	PARENT::CopyToAsura();

	m_pxAsuraListBox->SetMaxAllowedEntries(m_uMaxAllowedEntries);
	m_pxAsuraListBox->SetMaxDisplayedEntries(m_uMaxDisplayedEntries);
	m_pxAsuraListBox->SetTextScrollRate(m_fScrollRate);
	m_pxAsuraListBox->SetTextRenderFlag(ASURA_GUIMENU_TEXT_WORDWRAP,m_bWordWrap);
	m_pxAsuraListBox->SetTextRenderFlag(ASURA_GUIMENU_TEXTLISTBOX_SCALE_ON_PARENT_RESIZE,m_bResizeFont);
	m_pxAsuraListBox->SetFontScale( m_fFontScale );

	// set text justification flags in ausra data
	u_int uTextJustificationFlags( m_pxAsuraListBox->GetTextRenderFlags() );
	CopyTextJustificationToFlags( uTextJustificationFlags );

	m_pxAsuraListBox->SetTextRenderFlags(  uTextJustificationFlags );
}

void Tools_GUIMenu_Widget_TextListBox::CopyFromAsura()
{
	PARENT::CopyFromAsura();

	m_uMaxAllowedEntries   = m_pxAsuraListBox->GetMaxAllowedEntries();
	m_uMaxDisplayedEntries = m_pxAsuraListBox->GetMaxDisplayedEntries();
	m_fScrollRate		   = m_pxAsuraListBox->GetTextScrollRate();
	m_bWordWrap			   = m_pxAsuraListBox->GetTextRenderFlag(ASURA_GUIMENU_TEXT_WORDWRAP);
	m_bResizeFont		   = m_pxAsuraListBox->GetTextRenderFlag(ASURA_GUIMENU_TEXTLISTBOX_SCALE_ON_PARENT_RESIZE);
	m_fFontScale		   = m_pxAsuraListBox->GetFontScale();

	CopyTextJustificationFromFlags( m_pxAsuraListBox->GetTextRenderFlags() ); 
}

void Tools_GUIMenu_Widget_TextListBox::SetRectangle(const Asura_Bounding_Rectangle& xRect)
{
	PARENT::SetRectangle(xRect);

	//update the max displayed entries so that the entry height is recalculated
	m_pxAsuraListBox->SetMaxDisplayedEntries(m_uMaxDisplayedEntries);
}

void Tools_GUIMenu_Widget_TextListBox::Copy(const Tools_GUIMenu_Root* pxSource)
{
	PARENT::Copy(pxSource);

	const Tools_GUIMenu_Widget_TextListBox* pxSourceTextListBox = (const Tools_GUIMenu_Widget_TextListBox*) pxSource;
	const Asura_GUIMenu_Widget_TextListBox* pxSourceAsuraTextListBox = (const Asura_GUIMenu_Widget_TextListBox*) pxSourceTextListBox->m_pxAsuraListBox;

	//copy tools data
	m_uMaxAllowedEntries = pxSourceTextListBox->m_pxAsuraListBox->m_uMaxAllowedEntries;
	m_uMaxDisplayedEntries = pxSourceTextListBox->m_pxAsuraListBox->m_uMaxDisplayedEntries;
	m_iCurrentHorzJustifyIndex = pxSourceTextListBox->m_iCurrentHorzJustifyIndex;
	m_iCurrentVertJustifyIndex = pxSourceTextListBox->m_iCurrentVertJustifyIndex;
	m_fInitialRepeatDelay = pxSourceTextListBox->m_fInitialRepeatDelay;
	m_fSecondaryRepeatDelay = pxSourceTextListBox->m_fSecondaryRepeatDelay;
	m_fFontScale = pxSourceTextListBox->m_fFontScale;
	m_fScrollRate = pxSourceTextListBox->m_fScrollRate;
	m_bWordWrap = pxSourceTextListBox->m_bWordWrap;
	m_bResizeFont = pxSourceTextListBox->m_bResizeFont;


	
	//Determine the child elements that should be the increment/decrement images
	//get the names of the increment/decrement images
	const char* szDecName = 0;
	const char* szIncName = 0;
	if(	pxSourceAsuraTextListBox->m_pxDecImage != NULL)
	{
		szDecName = pxSourceAsuraTextListBox->m_pxDecImage->GetNameAsChar();
	}
	if(	pxSourceAsuraTextListBox->m_pxIncImage != NULL)
	{
		szIncName = pxSourceAsuraTextListBox->m_pxIncImage->GetNameAsChar();
	}

	//search for image elements with the same name in this copy
	for( u_int i=0; i<m_pxAsuraListBox->GetContainerCount(); i++)
	{
		Asura_GUIMenu_Root* pxItem = m_pxAsuraListBox->GetContainerItem(i);
		if(pxItem->GetType() == Asura_GUIMenu_Root::ASURA_GUIMENU_TYPEID_ELEMENT_IMAGE)
		{
			if( szDecName && !stricmp(pxItem->GetNameAsChar(), szDecName))
			{
				m_pxAsuraListBox->SetDecImage( static_cast<Asura_GUIMenu_Element_Image*>(pxItem));
			}
			if( szIncName && !stricmp(pxItem->GetNameAsChar(), szIncName))
			{
				m_pxAsuraListBox->SetIncImage( static_cast<Asura_GUIMenu_Element_Image*>(pxItem));
			}
		}
	}
		
	//determine the chld element that should be the path
	if(	pxSourceAsuraTextListBox->m_pxScrollBar != NULL)
	{
		const char* szScrName = pxSourceAsuraTextListBox->m_pxScrollBar->GetNameAsChar();

		for( u_int i=0; i<m_pxAsuraListBox->GetContainerCount(); i++)
		{
			Asura_GUIMenu_Root* pxItem = m_pxAsuraListBox->GetContainerItem(i);
			if(pxItem->GetType() == Asura_GUIMenu_Root::ASURA_GUIMENU_TYPEID_ELEMENT_PATH)
			{
				if( szScrName && !stricmp( pxItem->GetNameAsChar(), szScrName))
				{
					m_pxAsuraListBox->SetScrollBar( static_cast<Asura_GUIMenu_Element_Path*>(pxItem));
				}
			}
		}
	}
}

void Tools_GUIMenu_Widget_TextListBox::ChooseFont()
{
	Asura_String xCurrentFont = m_pxAsuraListBox->GetFontName().GetString();

	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_pxAsuraListBox->SetFontByName(xOverlay.GetSelectionString());
	s_iMostRecentSelectedFont = xOverlay.GetSelectionData();

	//and the overlay
	UpdateOverlay();

	SetModified();
}

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

	if(CanEditFont())
	{
		m_pxAsuraListBox->SetFontByName(szFontName);
		SetModified();

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


void Tools_GUIMenu_Widget_TextListBox::CopyTextJustificationFromFlags( const u_int uFlags )
{
	m_iCurrentHorzJustifyIndex = HORZ_JUSTIFY_NONE;
	m_iCurrentVertJustifyIndex = VERT_JUSTIFY_NONE;

	if( uFlags & ASURA_TEXTFORMAT_DEFAULT )				{ m_iCurrentHorzJustifyIndex = HORZ_JUSTIFY_NONE; }
	else if( uFlags & ASURA_TEXTFORMAT_LEFTJUSTIFIED)	{ m_iCurrentHorzJustifyIndex = HORZ_JUSTIFY_LEFT; }
	else if( uFlags & ASURA_TEXTFORMAT_CENTREJUSTIFIED)	{ m_iCurrentHorzJustifyIndex = HORZ_JUSTIFY_CENTER; }
	else if( uFlags & ASURA_TEXTFORMAT_RIGHTJUSTIFIED)	{ m_iCurrentHorzJustifyIndex = HORZ_JUSTIFY_RIGHT; }

	if( uFlags & ASURA_TEXTFORMAT_VERTICALCENTREJUSTIFIED)		{ m_iCurrentVertJustifyIndex = VERT_JUSTIFY_CENTER; }
	else if( uFlags & ASURA_TEXTFORMAT_VERTICALBOTTOMJUSTIFIED)	{ m_iCurrentVertJustifyIndex = VERT_JUSTIFY_BOTTOM; }
}

const u_int Tools_GUIMenu_Widget_TextListBox::CopyTextJustificationToFlags( u_int& uFlags )
{
		// clear justification flags
		uFlags &= ~(ASURA_TEXTFORMAT_DEFAULT|ASURA_TEXTFORMAT_LEFTJUSTIFIED|ASURA_TEXTFORMAT_CENTREJUSTIFIED|ASURA_TEXTFORMAT_RIGHTJUSTIFIED|		ASURA_TEXTFORMAT_VERTICALCENTREJUSTIFIED|ASURA_TEXTFORMAT_VERTICALBOTTOMJUSTIFIED);

	if( m_iCurrentHorzJustifyIndex < HORZ_JUSTIFY_MAX)
	{
		// set flags using current justify index (from drop down box dialog)
		switch( m_iCurrentHorzJustifyIndex )
		{
			case HORZ_JUSTIFY_NONE:
				uFlags |= ASURA_TEXTFORMAT_DEFAULT;
				break;

			case HORZ_JUSTIFY_LEFT:
				uFlags |= ASURA_TEXTFORMAT_LEFTJUSTIFIED;
				break;

			case HORZ_JUSTIFY_CENTER:
				uFlags |= ASURA_TEXTFORMAT_CENTREJUSTIFIED;
				break;
			
			case HORZ_JUSTIFY_RIGHT:
				uFlags |= ASURA_TEXTFORMAT_RIGHTJUSTIFIED;
				break;

			default:
				break;
		}
	}

	if( m_iCurrentVertJustifyIndex < VERT_JUSTIFY_MAX)
	{
		// set flags using current justify index (from drop down box dialog)
		switch( m_iCurrentVertJustifyIndex )
		{
			case VERT_JUSTIFY_CENTER:
				uFlags |= ASURA_TEXTFORMAT_VERTICALCENTREJUSTIFIED;
				break;

			case VERT_JUSTIFY_BOTTOM:
				uFlags |= ASURA_TEXTFORMAT_VERTICALBOTTOMJUSTIFIED;
				break;

			default:
				break;
		};
	}

	return uFlags;
}

bool Tools_GUIMenu_Widget_TextListBox::IsNavExitSupported(int iLink) const
{
	//The list box can only have left and right exits
	return (iLink == ASURA_GUIMENU_UI_NAV_EXIT_LEFT) || (iLink == ASURA_GUIMENU_UI_NAV_EXIT_RIGHT);
}

u_int Tools_GUIMenu_Widget_TextListBox::GetFlagsToEdit() const
{
	return PARENT::GetFlagsToEdit() | ASURA_GUIMENU_ACTION_FLAG_NOTIFY_DATA_CHANGE_IMMEDIATE | ASURA_GUIMENU_ACTION_FLAG_NOTIFY_DATA_CHANGE_ON_EXIT;
}

const char* Tools_GUIMenu_Widget_TextListBox::GetLocalDataFlagName(u_int uFlagValue) const
{
	switch(uFlagValue)
	{
		case Asura_GUIMenu_Widget_TextListBox::ASURA_GUIMENU_WIDGET_TEXTLISTBOX_LOCAL_FLAG_WIDTH :
			return "Width";
			break;

		case Asura_GUIMenu_Widget_TextListBox::ASURA_GUIMENU_WIDGET_TEXTLISTBOX_LOCAL_FLAG_HEIGHT :
			return "Height";
			break;

		case Asura_GUIMenu_Widget_TextListBox::ASURA_GUIMENU_WIDGET_TEXTLISTBOX_LOCAL_FLAG_MAX_ALLOWED_ENTRIES :
			return "Max Entries";
			break;

		case Asura_GUIMenu_Widget_TextListBox::ASURA_GUIMENU_WIDGET_TEXTLISTBOX_LOCAL_FLAG_MAX_DISPLAY_ENTRIES :
			return "Max Displayed Entries";
			break;

		case Asura_GUIMenu_Widget_TextListBox::ASURA_GUIMENU_WIDGET_TEXTLISTBOX_LOCAL_FLAG_RENDER_FLAGS :
			return "Word Wrap, Font Resize and Justification";
			break;

		case Asura_GUIMenu_Widget_TextListBox::ASURA_GUIMENU_WIDGET_TEXTLISTBOX_LOCAL_FLAG_FLASH_DETAILS :
			return "Flash Details";
			break;

		case Asura_GUIMenu_Widget_TextListBox::ASURA_GUIMENU_WIDGET_TEXTLISTBOX_LOCAL_FLAG_CONTROL_REPEAT :
			return "Control Repeat";
			break;

		case Asura_GUIMenu_Widget_TextListBox::ASURA_GUIMENU_WIDGET_TEXTLISTBOX_LOCAL_FLAG_FONT :
			return "Font";
			break;

		case Asura_GUIMenu_Widget_TextListBox::ASURA_GUIMENU_WIDGET_TEXTLISTBOX_LOCAL_FLAG_POPULATION_FUNCTION :
			return "Population Function";
			break;

		case Asura_GUIMenu_Widget_TextListBox::ASURA_GUIMENU_WIDGET_TEXTLISTBOX_LOCAL_FLAG_COMMAND_MANAGER :
			return "Command Manager";
			break;

		default :
			return PARENT::GetLocalDataFlagName(uFlagValue);

	}
}

bool Tools_GUIMenu_Widget_TextListBox::CanEditMaxEntries()
{
	return ShouldStyleUseLocalDataFor(Asura_GUIMenu_Widget_TextListBox::ASURA_GUIMENU_WIDGET_TEXTLISTBOX_LOCAL_FLAG_MAX_ALLOWED_ENTRIES);
}

bool Tools_GUIMenu_Widget_TextListBox::CanEditMaxDisplayed()
{
	return ShouldStyleUseLocalDataFor(Asura_GUIMenu_Widget_TextListBox::ASURA_GUIMENU_WIDGET_TEXTLISTBOX_LOCAL_FLAG_MAX_DISPLAY_ENTRIES);
}

bool Tools_GUIMenu_Widget_TextListBox::CanEditWidth()
{
	return ShouldStyleUseLocalDataFor(Asura_GUIMenu_Widget_TextListBox::ASURA_GUIMENU_WIDGET_TEXTLISTBOX_LOCAL_FLAG_WIDTH);
}

bool Tools_GUIMenu_Widget_TextListBox::CanEditHeight()
{
	return ShouldStyleUseLocalDataFor(Asura_GUIMenu_Widget_TextListBox::ASURA_GUIMENU_WIDGET_TEXTLISTBOX_LOCAL_FLAG_HEIGHT);
}

bool Tools_GUIMenu_Widget_TextListBox::CanEditFlash()
{
	return ShouldStyleUseLocalDataFor(Asura_GUIMenu_Widget_TextListBox::ASURA_GUIMENU_WIDGET_TEXTLISTBOX_LOCAL_FLAG_FLASH_DETAILS);
}

bool Tools_GUIMenu_Widget_TextListBox::CanEditTextRenderFlags()
{
	return ShouldStyleUseLocalDataFor(Asura_GUIMenu_Widget_TextListBox::ASURA_GUIMENU_WIDGET_TEXTLISTBOX_LOCAL_FLAG_RENDER_FLAGS);
}

bool Tools_GUIMenu_Widget_TextListBox::CanEditInputRepeat()
{
	return ShouldStyleUseLocalDataFor(Asura_GUIMenu_Widget_TextListBox::ASURA_GUIMENU_WIDGET_TEXTLISTBOX_LOCAL_FLAG_CONTROL_REPEAT);
}

bool Tools_GUIMenu_Widget_TextListBox::CanEditFont()
{
	return ShouldStyleUseLocalDataFor(Asura_GUIMenu_Widget_TextListBox::ASURA_GUIMENU_WIDGET_TEXTLISTBOX_LOCAL_FLAG_FONT);
}

bool Tools_GUIMenu_Widget_TextListBox::CanEditPopulationFunction()
{
	return ShouldStyleUseLocalDataFor(Asura_GUIMenu_Widget_TextListBox::ASURA_GUIMENU_WIDGET_TEXTLISTBOX_LOCAL_FLAG_POPULATION_FUNCTION);
}

bool Tools_GUIMenu_Widget_TextListBox::CanEditCommandManager()
{
	return ShouldStyleUseLocalDataFor(Asura_GUIMenu_Widget_TextListBox::ASURA_GUIMENU_WIDGET_TEXTLISTBOX_LOCAL_FLAG_COMMAND_MANAGER);
}

#endif //ASURA_USE_GUI_MENU_SYSTEM
