//
// Tools_PickDialogueEvent_Overlay.cpp
//
// Created by Richard Rice - 30/10/2006
// 
// Copyright (C) 2006 Rebellion, All Rights Reserved.
//

#include "Core/Asura.h"
#include "Sound/Tools_PickDialogueEvent_Overlay.h"

#ifdef ASURA_USE_DIALOGUE_SYSTEM

//asura
#include "Core/Asura_NameTree.h"
#include "Core/Asura_UserInput.h"
#include "Interface/Asura_Dialog.h"
#include "Interface/Asura_Overlay.h"
#include "Interface/Asura_Overlay_System.h"
#include "Rendering/Asura_Text_Output.h"
#include "Rendering/Asura_Viewport.h"
#include "Sound/Asura_Dialogue.h"
#include "Sound/Asura_Dialogue_System.h"

//tools
#include "Tools_Overlays.h"
#include "Misc/Tools_Modal_Overlay.h"
#include "Sound/Tools_Dialogue_System.h"
#include "Sound/Tools_DialogueEvent_Dialogs.h"
#include "Sound/Tools_DialogueEvent_Overlay.h"
#include "Sound/Tools_PickDialogueLine_Overlay.h"


Asura_Vector_2 Tools_PickDialogueEvent_Overlay::s_xOverlayPosition(20.0f,2.0f);
Tools_PickDialogueEvent_Overlay* Tools_PickDialogueEvent_Overlay::s_pxThis = 0;

Asura_String Tools_PickDialogueEvent_Overlay::s_xFileFilter;
Asura_String Tools_PickDialogueEvent_Overlay::s_xLastFindEventID;
Asura_Hash_ID Tools_PickDialogueEvent_Overlay::s_uCharacterFilter = 0;

Asura_Hash_ID Tools_PickDialogueEvent_Overlay::s_uSelectedEvent = 0;
List<Asura_Hash_ID> Tools_PickDialogueEvent_Overlay::s_xSelectionList;
bool Tools_PickDialogueEvent_Overlay::s_bCancelled = false;
bool Tools_PickDialogueEvent_Overlay::s_bEventListInvalidated;
bool Tools_PickDialogueEvent_Overlay::s_bAutoPreview = true;

static const char* g_szFilterNone = "*All*";
static const char* g_szEventNone = "*None*";
static const char* g_szEventUnknown = "*Unknown*";

//search types
enum
{
	DIALOGUE_SEARCH_BEGINS,
	DIALOGUE_SEARCH_CONTAINS,
};

static const char* g_aszSearchOptions[] =
{
	"Begins With",
	"Contains",
};


Tools_PickDialogueEvent_Overlay::Tools_PickDialogueEvent_Overlay()
:Asura_Overlay(" ",false,&s_xOverlayPosition)
{
	Asura_Assert(!s_pxThis,"");
	s_pxThis = this;
	SetDefaultTitle();

	m_uFileListSize = 0;
	m_apszFileList = 0;
	m_pxFileStringTree = new Asura_StringTree;

	m_uEventListSize = 0;
	m_apszEventList = 0;
	m_pxEventStringTree = new Asura_StringTree;
	m_pxEventListDialog = 0;

	m_uInitialSelection = 0;
	m_uMostRecentSelectedEvent = 0;
	s_uSelectedEvent = 0;
	m_iEventIndex = 0;

	s_uCharacterFilter = 0;

	m_iSearchOption = 0;

	m_bMultipleSelection = true;

	m_iDialogueHandle = ASURA_INVALID_HANDLE;

	m_bFilterChanged = false;
}

Tools_PickDialogueEvent_Overlay::~Tools_PickDialogueEvent_Overlay()
{
	Asura_Assert(s_pxThis == this,"");

	StopSound();

	DeleteFilterLists();
	DeleteEventList();

	delete m_pxFileStringTree;
	delete m_pxEventStringTree;

	s_pxThis = 0;
}


void Tools_PickDialogueEvent_Overlay::SetDefaultTitle()
{
	SetTitle("Dialogue Event List");	
}

void Tools_PickDialogueEvent_Overlay::CreateOverlay()
{
	//overlay already open?
	if(Asura_Overlay_System::DoesOverlayExist(TOOLS_OVERLAY_PICKDIALOGUEEVENT))
	{
		Asura_Overlay_System::BringOverlayToTop(TOOLS_OVERLAY_PICKDIALOGUEEVENT);
		return;
	}

	//create the overlay then
	Tools_PickDialogueEvent_Overlay* pxOverlay = new Tools_PickDialogueEvent_Overlay();
	
	pxOverlay->InitialiseOverlay();

	pxOverlay->m_uID = TOOLS_OVERLAY_PICKDIALOGUEEVENT;
	Asura_Overlay_System::SubmitNewOverlay( pxOverlay);
}

void Tools_PickDialogueEvent_Overlay::InitialiseOverlay()
{
	//m_uInitialSelection = uInitialSelection;
	//m_uMostRecentSelectedEvent = s_uSelectedEvent = m_uInitialSelection;
	m_pxEventListDialog = 0;


	BuildFilterLists();

	//build temporary list , which will be corrected on the first frame
	m_apszEventList = new const char*[1];
	m_apszEventList[0] = g_szEventNone;
	m_uEventListSize = 1;
	m_bFilterChanged = true;


	//determine the maximum number of lines to use for the various lists
	float fMaxPrintY = Asura_Viewport::GetHeight() / ASURA_TEXT_OUTPUT_FONT_HEIGHT;
	const int iMaxLines = Asura_Maths::FloatToInt_Chop((fMaxPrintY - 24.0f)/1.2f);


	Asura_Dialog* pxDialog;
	Asura_Vector_2 xOffset(1.0f,3.0f);


	Asura_DropDown_List_Dialog* pxDropListDialog;
	
	//add drop down lists for filters
	pxDropListDialog = new Asura_DropDown_List_Dialog(xOffset,m_apszFileList,&m_iSelectedFileFilter,iMaxLines,m_uFileListSize,NULL,&m_bFilterChanged,"File");
	pxDropListDialog->SetHelpText("Filter event list by the file that they belong to.\nAlso used as tne initial file for new events.");
	//pxDropListDialog->SetMinimumWidth(fDropDownListWidth);
	AddDialog(pxDropListDialog);
	xOffset.y += Asura_Dialog::DefaultSpacing();

	//character filter
	pxDropListDialog = new Tools_DialogueCharacter_Dialog(xOffset,iMaxLines,&s_uCharacterFilter,&m_bFilterChanged,"Character");
	pxDropListDialog->SetHelpText("Filter event list to those events containing text spoken by a given character.");
	AddDialog(pxDropListDialog);
	xOffset.y += Asura_Dialog::DefaultSpacing();

	//Search/Search Type
	pxDropListDialog = new Asura_DropDown_List_Dialog(xOffset,g_aszSearchOptions,&m_iSearchOption,iMaxLines,2,NULL,&m_bFilterChanged,"");
	pxDropListDialog->SetHelpText("Determines how the search text should be used for filtering the list.");
	AddDialog(pxDropListDialog);


	xOffset.x = pxDropListDialog->m_xMaxCoord.x + 1.0f;
	pxDialog = new Asura_String_Dialog("",xOffset,&m_xSearchText,30,&m_bFilterChanged);
	((Asura_String_Dialog*)pxDialog)->SetUpdateImmediatelyWhileTyping(true);
	pxDialog->SetHelpText("Filters the event list so that it only shows those beginning with/containing this string");;
	xOffset.x = 1.0f;
	AddDialog(pxDialog);
	xOffset.y += Asura_Dialog::LargeSpacing();

	



	//list of events
	m_bEventChanged = false;
	pxDialog = m_pxEventListDialog = new Asura_List_Dialog(xOffset,m_apszEventList,&m_iEventIndex,iMaxLines,m_uEventListSize,NULL,&m_bEventChanged);
	m_pxEventListDialog->EnableMultipleSelection(m_bMultipleSelection);
	m_pxEventListDialog->SetDoubleClickFunction(OnDoubleClickList,(int)this);
	AddDialog(pxDialog);
	xOffset.y += iMaxLines*1.2f + 1.0f;

	pxDialog = new Asura_Function_Dialog("Preview Dialogue",xOffset,PlaySound,(int)this);
	pxDialog->SetHelpText("Tests the current dialogue event.");
	AddDialog(pxDialog);

	xOffset.x += 12.0f;
	pxDialog = new Asura_Function_Dialog("Stop Preview",xOffset,StopSound,(int)this);
	pxDialog->SetHelpText("Stops the test sound.");
	AddDialog(pxDialog);
	xOffset.x -= 12.0f;

	xOffset.x += 24.0f;
	pxDialog = new Asura_Tickbox_Dialog("Auto Preview",xOffset,&s_bAutoPreview);
	pxDialog->SetHelpText("Automatically previews each sound as it is selected.");
	AddDialog(pxDialog);
	xOffset.x -= 24.0f;
	xOffset.y += Asura_Dialog::LargeSpacing();

	pxDialog = new Asura_Function_Dialog("New Event",xOffset,OnNewEvent,(int)this);
	pxDialog->SetHelpText("Create and select a new event.");
	AddDialog(pxDialog);

	xOffset.x += 12.0f;
	pxDialog = new Asura_Function_Dialog("Edit Event",xOffset,OnEditEvent,(int)this);
	pxDialog->SetHelpText("Selects the current event and opens the overlay for editing it.");
	AddDialog(pxDialog);
	xOffset.x -= 12.0f;


	xOffset.x += 24.0f;
	pxDialog = new Asura_Function_Dialog("Delete",xOffset,DeleteEvents,(int)this);
	pxDialog->SetHelpText("Delete the selected event(s).");
	AddDialog(pxDialog);
	xOffset.x -= 24.0f;

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

//	xOffset.x += 24.0f;
	pxDialog = new Asura_Function_Dialog("Find Event By ID",xOffset,OnFindEventByID,(int)this);
	pxDialog->SetHelpText("Allows you to type in a hash ID and locate the corresponding event. Mainly a debugging aid.");
	AddDialog(pxDialog);
//	xOffset.x -= 24.0f;

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

	pxDialog = new Asura_Function_Dialog("Okay",xOffset,OnOkay,(int)this);
	pxDialog->SetIsEnabledFunction(IsEnabled_OnOkay,(int)this);
	AddDialog(pxDialog);

	xOffset.x += 12.0f;
	pxDialog = new Asura_Function_Dialog("Cancel",xOffset,OnCancel,(int)this);
	pxDialog->SetIsEnabledFunction(IsEnabled_OnCancel,(int)this);
	AddDialog(pxDialog);
	xOffset.x -= 12.0f;

	xOffset.x += 24.0f;
	pxDialog = new Asura_Function_Dialog("View Lines",xOffset,OnViewLines,(int)this);
	pxDialog->SetHelpText("View Lines for selected event.");
	AddDialog(pxDialog);
	xOffset.x -= 24.0f;
	xOffset.y += Asura_Dialog::DefaultSpacing();
}

void Tools_PickDialogueEvent_Overlay::CloseOverlay()
{
	Asura_Overlay_System::CloseOverlays(TOOLS_OVERLAY_PICKDIALOGUEEVENT);	
}

bool Tools_PickDialogueEvent_Overlay::OverlayExists()
{
	//return Asura_Overlay_System::DoesOverlayExist(TOOLS_OVERLAY_PICKDIALOGUEEVENT);
	return s_pxThis != 0;
}

Asura_Hash_ID Tools_PickDialogueEvent_Overlay::PickEvent(const char* szTitle,Asura_Hash_ID uInitialSelection /*= 0*/, bool bMultipleSelect /*= false*/)
{
	//make sure the overlay is open
	bool bOverlayInitiallyOpen = OverlayExists(); 

	if(!bOverlayInitiallyOpen) CreateOverlay();
	
	Asura_Assert(s_pxThis,"Failed to get pick dialogue event overlay");
	if(!s_pxThis) return 0;

	//set the title
	if(szTitle) s_pxThis->SetTitle(szTitle);

	//update selection
	s_pxThis->EnableMultipleSelection(bMultipleSelect);
	s_pxThis->m_uInitialSelection = uInitialSelection;
	s_pxThis->SetInitialSelection(uInitialSelection);

	//run as modal overlay
	s_bCancelled = true;
	Tools_Modal_Overlay::DoModal(s_pxThis);

	//close overlay if it was opened just for this
	if(bOverlayInitiallyOpen && OverlayExists())
	{
		s_pxThis->SetDefaultTitle();
		s_pxThis->EnableMultipleSelection(true);
	}
	else
	{
		CloseOverlay();
	}

	return s_bCancelled ? uInitialSelection : s_uSelectedEvent;
}



void Tools_PickDialogueEvent_Overlay::BuildEventList()
{
	DeleteEventList();
	s_bEventListInvalidated = false;

	char szWildcardSearchString[100];
	if(!m_xSearchText.IsBlank() && m_iSearchOption == DIALOGUE_SEARCH_CONTAINS)
	{
		//prepare search string for wildcard search
		Asura_PrintfToBfr(szWildcardSearchString,"*%s*",sizeof(szWildcardSearchString),true,m_xSearchText.GetString());
	}

	//get a list of all events that meet the current filter requirements
	int iJunkIndex;
	for(u_int i=0;i<Asura_Dialogue_Storage::GetNumberOfEvents();i++)
	{
		const Asura_Dialogue_Event* pxEvent = Asura_Dialogue_Storage::GetEventByIndex(i);

		if(!s_xFileFilter.IsBlank())
		{
			const char* szFilename = pxEvent->GetFilename();
			if(!szFilename || s_xFileFilter.Compare(szFilename))
		 	{
		 		continue;
		 	}
		}

		if(s_uCharacterFilter)
		{
			//does the event involve this character?
			if(!Tools_Dialogue_System::DoesEventContainCharacter(pxEvent,s_uCharacterFilter))
			{
				continue;
			}
		}

		if(!m_xSearchText.IsBlank())
		{
			if(m_iSearchOption == DIALOGUE_SEARCH_BEGINS)
			{
				if(strnicmp(m_xSearchText.GetString(),pxEvent->GetName(),m_xSearchText.GetLength()))
				{
					continue;
				}
			}
			else
			{
				if(!Asura_StringUtil::CompareAgainstWildcardString(pxEvent->GetName(),szWildcardSearchString,true))
				{
					continue;
				}
			}
		}

		m_pxEventStringTree->FindNodeIndexByName(pxEvent->GetName(),true,iJunkIndex);

	}

	//need an entry for 'unknown' ? 
	bool bNeedUnknown = false;
	if(m_uInitialSelection && !Asura_Dialogue_Storage::GetEventByHash(m_uInitialSelection))
	{
		bNeedUnknown = true;
	}

	u_int uSpecialEntries = bNeedUnknown ? 2 : 1;

	//get array of event names , and fill in the special entries that aren't in the tree
	m_uEventListSize = m_pxEventStringTree->GetNumberOfNodes()+uSpecialEntries;
	m_apszEventList = new const char*[m_uEventListSize];
	m_apszEventList[0] = g_szEventNone;
	if(bNeedUnknown) m_apszEventList[1] = g_szEventUnknown;
	m_pxEventStringTree->MakeSortedNameList(m_apszEventList+uSpecialEntries);

	//Update the current selected index to be as close as possible to the previous selection
	if(m_uMostRecentSelectedEvent == 0)
	{
		m_iEventIndex = 0;
	}
	else if(bNeedUnknown && m_uMostRecentSelectedEvent == m_uInitialSelection)
	{
		m_iEventIndex = 1;
	}
	else
	{
		const Asura_Dialogue_Event* pxEvent = Asura_Dialogue_Storage::GetEventByHash(m_uMostRecentSelectedEvent);
		m_iEventIndex = 0;
		if(pxEvent)
		{
			for(u_int i=uSpecialEntries;i<m_uEventListSize;i++)
			{
				if(stricmp(pxEvent->GetName(),m_apszEventList[i])>=0)
				{
					m_iEventIndex = i;
				}
				else
				{
					break;
				}
			}
		}
	}

	//get the hash ID of the event selected
	s_uSelectedEvent = GetEventHash(m_iEventIndex);

	//multiple selection list will be junk after list change
	while(s_xSelectionList.size()) s_xSelectionList.delete_first_entry();

	//update the list dialog if it has been created yet
	if(m_pxEventListDialog)
	{
		m_pxEventListDialog->ReplaceStrings(m_uEventListSize,m_apszEventList);
	}
}

void Tools_PickDialogueEvent_Overlay::DeleteEventList()
{
	delete [] m_apszEventList;
	m_apszEventList = 0;
	m_uEventListSize = 0;
	m_pxEventStringTree->Reset();
}

Asura_Hash_ID Tools_PickDialogueEvent_Overlay::GetEventHash(int iIndex) const
{
	if(!stricmp(m_apszEventList[iIndex],g_szEventNone))
	{
		return 0;
	}
	else if(!stricmp(m_apszEventList[iIndex],g_szEventUnknown))
	{
		return m_uInitialSelection;
	}
	else
	{
		return Asura_GetHashID(m_apszEventList[iIndex]);
	}
}

void Tools_PickDialogueEvent_Overlay::BuildFilterLists()
{
	DeleteFilterLists();

	int iJunkIndex;
	//get a list of all files used by the events
	for(u_int i=0;i<Asura_Dialogue_Storage::GetNumberOfEvents();i++)
	{
		const Asura_Dialogue_Event* pxEvent = Asura_Dialogue_Storage::GetEventByIndex(i);

		const char* szFilename = pxEvent->GetFilename();
		if(szFilename && *szFilename)
		{
			m_pxFileStringTree->FindNodeIndexByName(szFilename,true,iJunkIndex);
		}
	}



	//get lists from the name tree for the list dialogs
	m_uFileListSize = m_pxFileStringTree->GetNumberOfNodes()+1;
	m_apszFileList = new const char*[m_uFileListSize];
	m_apszFileList[0] = g_szFilterNone;
	m_pxFileStringTree->MakeSortedNameList(m_apszFileList+1);


	//determine the index of the initial selections
	m_iSelectedFileFilter = 0;
	if(!s_xFileFilter.IsBlank())
	{
		for(u_int i=1;i<m_uFileListSize;i++)
		{
			if(!s_xFileFilter.Compare(m_apszFileList[i]))
			{
				m_iSelectedFileFilter = i;
				break;
			}
		}
		if(!m_iSelectedFileFilter) s_xFileFilter.MakeNull();
	}
}

void Tools_PickDialogueEvent_Overlay::DeleteFilterLists()
{
	delete [] m_apszFileList;
	m_apszFileList = 0;
	m_uFileListSize = 0;
	m_pxFileStringTree->Reset();
}

void Tools_PickDialogueEvent_Overlay::PerFrameUpdate()
{
	Asura_Overlay::PerFrameUpdate();

	if(m_bFilterChanged || s_bEventListInvalidated)
	{
		if(m_iSelectedFileFilter)
		{
			s_xFileFilter = m_apszFileList[m_iSelectedFileFilter];
		}
		else
		{
			s_xFileFilter.MakeNull();
		}
		
		
		//rebuild the event list
		BuildEventList();
		m_bFilterChanged = false;
	}


	if(m_bEventChanged)
	{
		//get the hash of the new event
		m_uMostRecentSelectedEvent = s_uSelectedEvent = GetEventHash(m_iEventIndex);
		m_bEventChanged = false;

		//If doing multiple selection , get hashes of all in list
		if(m_bMultipleSelection)
		{
			while(s_xSelectionList.size()) s_xSelectionList.delete_first_entry();

			int iNumSelected = m_pxEventListDialog->GetNumSelected();
			for(int i=0;i<iNumSelected;i++)
			{
				int iIndex = m_pxEventListDialog->GetSelection(i);
				Asura_Hash_ID uHash = GetEventHash(iIndex);
				if(uHash) s_xSelectionList.add_entry(uHash);
			}
		}

		if(s_bAutoPreview)
		{
			PlaySound();
		}
	}

	if(IsModal() && !Asura_Overlay_System::OverlaysHaveKeyboardFocus())
	{
		if(Asura_UserInput::DebouncedKeyPressed(ASURA_KEYID_ESCAPE) && IsEnabled_OnCancel())
		{
			OnCancel();
		}
	}

}

bool Tools_PickDialogueEvent_Overlay::IsModal() const
{
	return m_bAlwaysOnTop;
}

void Tools_PickDialogueEvent_Overlay::EndModal()
{
	m_bAlwaysOnTop = false;
}

void Tools_PickDialogueEvent_Overlay::EnableMultipleSelection(bool bMultipleSelect)
{
	m_bMultipleSelection = bMultipleSelect;
	if(m_pxEventListDialog)
	{
		m_pxEventListDialog->EnableMultipleSelection(m_bMultipleSelection);
	}
	if(!bMultipleSelect)
	{
		while(s_xSelectionList.size())
		{
			s_xSelectionList.delete_first_entry();
		}
	}

}

int Tools_PickDialogueEvent_Overlay::GetNumSelected() 
{
	return s_bCancelled ? 0 : s_xSelectionList.size();
}

Asura_Hash_ID Tools_PickDialogueEvent_Overlay::GetSelection(int iIndex)
{
	Asura_Assert(iIndex>=0 && iIndex < s_xSelectionList.size(),"Invalid selection index");
	return s_xSelectionList[iIndex];
}

void Tools_PickDialogueEvent_Overlay::DeleteEvents()
{
	if(!ShowYesNoOverlay("Delete the selected events?")) return;

	if(m_bMultipleSelection)
	{
		while(s_xSelectionList.size())
		{
			Tools_Dialogue_System::DeleteEvent(s_xSelectionList.first_entry(),false);
			s_xSelectionList.delete_first_entry();
		}
	}
	else
	{
		Tools_Dialogue_System::DeleteEvent(s_uSelectedEvent,false);
	}
	//flag the filter as changed so that the deleted entries will be removed.
	m_bFilterChanged = true;
}


void Tools_PickDialogueEvent_Overlay::OnOkay()
{
	s_bCancelled = false;
	EndModal();
}

void Tools_PickDialogueEvent_Overlay::OnCancel()
{
	s_bCancelled = true;
	EndModal();
}

void Tools_PickDialogueEvent_Overlay::OnNewEvent()
{
	Asura_Hash_ID uNewHash = Tools_Dialogue_System::CreateEvent(0);

	if(uNewHash)
	{
		//update the selection
		m_uMostRecentSelectedEvent = uNewHash;
		BuildEventList();
		s_xSelectionList.add_entry(uNewHash);

		s_bCancelled = false;
		EndModal();
	}
}

void Tools_PickDialogueEvent_Overlay::OnEditEvent()
{
	if(m_bMultipleSelection)
	{
		for(LIF<Asura_Hash_ID> xSelectionLIF(&s_xSelectionList);!xSelectionLIF.done();xSelectionLIF.next())
		{
			Tools_DialogueEvent_Overlay::EditEvent(xSelectionLIF());
		}
	}
	else
	{
		if(Asura_Dialogue_Storage::GetEventByHash(s_uSelectedEvent)) Tools_DialogueEvent_Overlay::EditEvent(s_uSelectedEvent);
	}
	s_bCancelled = false;
	EndModal();
}

void Tools_PickDialogueEvent_Overlay::OnDoubleClickList()
{
	if(IsModal())
	{
		OnOkay();
	}
	else
	{
		OnEditEvent();
	}
}

bool Tools_PickDialogueEvent_Overlay::IsEnabled_OnOkay()
{
	return IsModal();
}

bool Tools_PickDialogueEvent_Overlay::IsEnabled_OnCancel()
{
	return IsModal();
}

void Tools_PickDialogueEvent_Overlay::SetInitialSelection(Asura_Hash_ID uSelected)
{
	m_uInitialSelection = uSelected;
	m_uMostRecentSelectedEvent = uSelected;
	
	//make sure the selection will be visible with the current filters.
	const Asura_Dialogue_Event* pxEvent = Asura_Dialogue_Storage::GetEventByHash(uSelected);
	if(pxEvent)
	{
		if(!s_xFileFilter.IsBlank())
		{
			const char* szFilename = pxEvent->GetFilename();
			if(!szFilename || s_xFileFilter.Compare(szFilename))
		 	{
				s_xFileFilter.MakeNull();
				m_bFilterChanged = true;
		 	}
		}

		if(s_uCharacterFilter)
		{
			if(!Tools_Dialogue_System::DoesEventContainCharacter(pxEvent,s_uCharacterFilter))
			{
				s_uCharacterFilter = 0;				
				m_bFilterChanged = true;
			}
		}
		
		if(!m_xSearchText.IsBlank())
		{
			if(m_iSearchOption == DIALOGUE_SEARCH_BEGINS)
			{
				if(strnicmp(m_xSearchText.GetString(),pxEvent->GetName(),m_xSearchText.GetLength()))
				{
					m_xSearchText.MakeNull();
					m_bFilterChanged = true;
				}
			}
			else
			{
				char szWildcardSearchString[100];
				Asura_PrintfToBfr(szWildcardSearchString,"*%s*",sizeof(szWildcardSearchString),true,m_xSearchText.GetString());
				if(!Asura_StringUtil::CompareAgainstWildcardString(pxEvent->GetName(),szWildcardSearchString,true))
				{
					m_xSearchText.MakeNull();
					m_bFilterChanged = true;
				}
			}
		}
	}


	BuildEventList();
} 

void Tools_PickDialogueEvent_Overlay::PlaySound()
{
	StopSound();
	
	const Asura_Dialogue_Event* pxEvent = Asura_Dialogue_Storage::GetEventByHash(s_uSelectedEvent);
	if(!pxEvent) return;

	Asura_Dialogue_CharacterMappingList xMappings;
	Asura_Dialogue_System::PlayEvent(pxEvent,&xMappings,&m_iDialogueHandle);
}

void Tools_PickDialogueEvent_Overlay::StopSound()
{
	Asura_Dialogue_System::Stop(m_iDialogueHandle);
}


void Tools_PickDialogueEvent_Overlay::SetFileFilter(const char* szFileFilter)
{
	s_xFileFilter = szFileFilter;
	if(s_pxThis)
	{
		//get the index of the file in the drop down list
		s_pxThis->m_iSelectedFileFilter = 0;
		if(!s_xFileFilter.IsBlank())
		{
			for(u_int i=1;i<s_pxThis->m_uFileListSize;i++)
			{
				if(!s_xFileFilter.Compare(s_pxThis->m_apszFileList[i]))
				{
					s_pxThis->m_iSelectedFileFilter = i;
					break;
				}
			}
			if(!s_pxThis->m_iSelectedFileFilter) s_xFileFilter.MakeNull();
		}
	}
	InvalidateEventList();
}


void Tools_PickDialogueEvent_Overlay::OnViewLines()
{
	// if there's nothing selected then exit
	if (!s_xSelectionList.size())
	{
		return;
	}

	// get the first selected item (in multiple selection)
	Asura_Hash_ID xEventHash = GetSelection(0);

	const Asura_Dialogue_Event* pxEvent = Asura_Dialogue_Storage::GetEventByHash(xEventHash);

	if (pxEvent)
	{
		//
		// Find first dialogue line in playables list
		//
		for (u_int uPlayIndex = 0; uPlayIndex < pxEvent->GetNumPlayables(); uPlayIndex++)
		{
			// get each playable in the event
			const Asura_Dialogue_Playable* pxPlayable = pxEvent->GetPlayable(uPlayIndex);

			// check if this is a dialogue line
			if (pxPlayable->IsLine())
			{
				// create the overlay if it doesn't exist
				Tools_PickDialogueLine_Overlay::CreateOverlay();
				Tools_PickDialogueLine_Overlay* pxOverlay = static_cast<Tools_PickDialogueLine_Overlay*>(Asura_Overlay_System::GetOverlay(TOOLS_OVERLAY_PICKDIALOGUELINE));

				if (pxOverlay)
				{
					// init the line list box from our line hash
					pxOverlay->SetInitialSelection(pxPlayable->GetHashID());
				}

				break;
			}
		}
	}
}

void Tools_PickDialogueEvent_Overlay::OnFindEventByID()
{
	Asura_Hash_ID uHashID = ASURA_HASH_ID_UNSET;

	// pop up a modal text box
	GetString_Overlay xModalOverlay( "Enter ID", s_xLastFindEventID.GetString() );	

	if( xModalOverlay.DoModal() )
	{
		s_xLastFindEventID = xModalOverlay.GetString();

		// covert text to hash ID
		if( Asura_StringUtil::GetIntValue( xModalOverlay.GetString(), (int*)&uHashID )
			&& (uHashID != ASURA_HASH_ID_UNSET)
			&& Asura_Dialogue_Storage::FindEvent( uHashID ) )
		{
			// Search for event
			for( int i=0; i<(int)s_pxThis->m_uEventListSize; ++i )
			{
				if( GetEventHash(i) == uHashID )
				{
					// found event, set selection
					m_pxEventListDialog->SetSelection(i);
					m_iEventIndex = i;
					m_bEventChanged = true;
					return;
				}
			}
		}	

		Message_Overlay xOverlay( "Event not found" );
		xOverlay.DoModal();
	}
}

#endif //ASURA_USE_DIALOGUE_SYSTEM
