//
// Tools_PFX_Overlay.cpp
//
// Created by KOR - 21 February 2008
//
// Copyright (C) 2008 Rebellion, All Rights Reserved.
//

#include "Core/Asura.h"

// This file's header.
#include "Particles/Tools_PFX_Overlay.h"

// Asura
#include "Core/Asura_UserInput.h"
#include "SpecialFX/PFX/Asura_PFX_System.h"
#include "Rendering/Asura_Text_Output.h"
#include "Rendering/Asura_Render.h"
#include "Rendering/Asura_Direct3D.h"
#include "Rendering/Asura_Viewport.h"

#include "Interface/Asura_Overlay.h"

static bool s_bMinimised;
static Asura_Vector_2 s_xPosition;

static int TreeSort_Func(const Asura_TreeDialog_Item& xOne, const Asura_TreeDialog_Item& xTwo)
{
	switch((xOne.GetUserData() == ASURA_HASH_ID_UNSET) * 2 + (xTwo.GetUserData() == ASURA_HASH_ID_UNSET))
	{
	case 0:
	case 3:
		return stricmp(xOne.GetName(), xTwo.GetName());
	case 1:
		return 1;
	case 2:
		return -1;
	}
	return 0;
}

// Tools_PFXSelect_Overlay ////////////////////////////////////////////////////////////////////////
Tools_PFXSelect_Overlay::Tools_PFXSelect_Overlay(const char* pszTitleString, Mode eMode, const Asura_String &xFilter)
: PARENT(Asura_String(pszTitleString)), m_eMode(eMode)
{
	switch(eMode)
	{
		case MODE_EFFECTS:
		{
			const Asura_TemplateHashTree<Asura_String>&			xNameTree	= Asura_PFX_System::GetEffectTempNames();
			Asura_TemplateHashTree_ConstIterator<Asura_String>	xIterator(xNameTree);

			while(!xIterator.Done())
			{
				const Asura_String*	pxFullTemplateName	= xIterator.GetCurrent();

				if(pxFullTemplateName != NULL)
				{
					AddToTree(*pxFullTemplateName, xFilter);
				}
				xIterator.Next();
			}
			break;
		}

		case MODE_SOURCES:
		{
			const Asura_TemplateHashTree<Asura_String>&			xNameTree	= Asura_PFX_System::GetSourceTempNames();
			Asura_TemplateHashTree_ConstIterator<Asura_String>	xIterator(xNameTree);

			while(!xIterator.Done())
			{
				const Asura_String*	pxFullTemplateName	= xIterator.GetCurrent();

				if(pxFullTemplateName != NULL)
				{
					AddToTree(*pxFullTemplateName, xFilter);
				}
				xIterator.Next();
			}
			break;
		}

		case MODE_PARTICLES:
		{
			const Asura_TemplateHashTree<Asura_String>&			xNameTree	= Asura_PFX_System::GetParticleTempNames();
			Asura_TemplateHashTree_ConstIterator<Asura_String>	xIterator(xNameTree);

			while(!xIterator.Done())
			{
				const Asura_String*	pxFullTemplateName	= xIterator.GetCurrent();

				if(pxFullTemplateName != NULL)
				{
					AddToTree(*pxFullTemplateName, xFilter);
				}
				xIterator.Next();
			}
			break;
		}
	}		// End of switch.

	m_xTree.AddItem(m_xTree.GetRoot(), "[NONE]", ASURA_HASH_ID_UNSET);
}

bool Tools_PFXSelect_Overlay::DoModal()
{
	ShowOverlay();
	return m_bReturnValue;
}

static void GeneratePathName(Asura_TreeDialog_Item* pxCurrentItem, Asura_String &xBuf)
{
	if (pxCurrentItem->GetParent() != NULL && pxCurrentItem->GetParent()->GetName())
	{
		GeneratePathName(pxCurrentItem->GetParent(), xBuf);
		xBuf += "\\";
	}
	xBuf += pxCurrentItem->GetName();
}
static Asura_TreeDialog_Item* FindItem(Asura_TreeDialog_Item* pRoot, const char *pName)
{
	const char* pDir;
	if (!pName)
	{
		return NULL;
	}
	do
	{
		pDir = strchr(pName, '\\');

		if (pDir)
		{
			Asura_String xSubFolder(pName, pDir - pName);

			Asura_TreeDialog_Item* pxCurrChild;
			for( pxCurrChild = pRoot->GetChild(); pxCurrChild ; pxCurrChild = pxCurrChild->GetSibling() )
			{
				if (!stricmp(pxCurrChild->GetName(), xSubFolder.GetString()))
				{
					pRoot = pxCurrChild;
					pName = pDir + 1;
					break;
				}
			}
			if (!pxCurrChild)
			{
				return NULL;
			}
		} 
	} while (pDir);

	for( Asura_TreeDialog_Item* pxCurrChild = pRoot->GetChild(); pxCurrChild ; pxCurrChild = pxCurrChild->GetSibling() )
	{
		if (!stricmp(pxCurrChild->GetName(), pName))
		{
			return pxCurrChild;
		}
	}
	return NULL;
}

void Tools_PFXSelect_Overlay::SetSelected(const char* pName)
{
	Asura_TreeDialog_Item *pxItem = FindItem(m_xTree.GetRoot(), pName);
	m_xTree.SetSelectedItem(pxItem ? pxItem : FindItem(m_xTree.GetRoot(), "[NONE]"));
}

void Tools_PFXSelect_Overlay::SetSelected(Asura_Hash_ID uHash)
{
	const Asura_String *pName = NULL;
	switch (m_eMode)
	{
	case MODE_EFFECTS:
		pName = Asura_PFX_System::GetEffectTempNameByHash(uHash);
		break;
	case MODE_SOURCES:
		pName = Asura_PFX_System::GetSourceTempNameByHash(uHash);
		break;
	case MODE_PARTICLES:
		pName = Asura_PFX_System::GetParticleTempNameByHash(uHash);
		break;
	}
	SetSelected(pName ? pName->GetString() : "[NONE]");

}


void Tools_PFXSelect_Overlay::OkaySelected( int iUserData )   
{
	Tools_PFXSelect_Overlay *pxThis = (Tools_PFXSelect_Overlay *)iUserData;

	if (pxThis)
	{
		Asura_TreeDialog_Item *pItem = pxThis->m_xTree.GetSelectedItem();

		if (pItem && pItem->GetNumChildren() == 0)
		{
			pxThis->m_bReturnValue = true;
			pxThis->GetOverlay()->m_bShouldClose = true;

			if (pxThis->m_bReturnValue)
			{
				pxThis->m_uHash	= pxThis->m_xTree.GetSelectedItem()->GetUserData();
				GeneratePathName(pxThis->m_xTree.GetSelectedItem(), pxThis->m_xTemplateName);
			}
		} 
	}
}

void Tools_PFXSelect_Overlay::CancelSelected( int iUserData )   
{
	Tools_PFXSelect_Overlay *pxThis = (Tools_PFXSelect_Overlay *)iUserData;

	if (pxThis)
	{
		pxThis->m_bReturnValue = false;
	}
}

void Tools_PFXSelect_Overlay::AddToTree(const Asura_String& xName, const Asura_String& xFilter)
{
	const Asura_Char* pxTemplateName = xName.GetString();
	Asura_TreeDialog_Item* pxCurrItem = m_xTree.GetRoot();

	if (!xFilter.IsBlank())
	{
		if (strnicmp(xFilter.GetString(), pxTemplateName, xFilter.GetLength()))
			return;
	}

	const char *pDir;
	do
	{

		pDir = strchr(pxTemplateName, '\\');

		if (pDir)
		{
			Asura_String xSubFolder(pxTemplateName, pDir - pxTemplateName);
			Asura_TreeDialog_Item* pxCurrChild;
			for( pxCurrChild = pxCurrItem->GetChild(); pxCurrChild; pxCurrChild = pxCurrChild->GetSibling() )
			{
				if( xSubFolder.Compare(pxCurrChild->GetName(), true) == 0 )
				{
					pxCurrItem = pxCurrChild;
					break;
				}
			}
			if (!pxCurrChild)
			{
				pxCurrItem = m_xTree.InsertItem( TreeSort_Func, pxCurrItem, xSubFolder.GetString(), ASURA_HASH_ID_UNSET );
			}

			pxTemplateName = pDir + 1;
		}
	}
	while (pDir);

	m_xTree.InsertItem(TreeSort_Func, pxCurrItem, pxTemplateName, xName.GetHash());
}

void Tools_PFXSelect_Overlay::InitialiseOverlay(class Asura_Overlay* pxOverlay)
{
	Asura_Vector_2 xOffset(1,3);

	Asura_Tree_Dialog* pxNewTreeDialogue = new Asura_Tree_Dialog( xOffset, &m_xTree, 30, 20 );
	pxNewTreeDialogue->SetDoubleClickedFunction( TreeDoubleClicked, (int)this );
	pxOverlay->AddDialog( pxNewTreeDialogue );
	xOffset.y += pxNewTreeDialogue->GetMaxCoords().y + 1.0f;

	Asura_Dialog* pxOKDialog = new Asura_FunctionWithKeybinding_Dialog( "OK", xOffset, OkaySelected, (int)this, ASURA_KEYID_ENTER, NULL );
	pxOverlay->AddDialog( pxOKDialog );
	xOffset.x += 10.0f;

	Asura_Dialog* pxCancelDialog = new Asura_FunctionWithKeybinding_Dialog( "Cancel", xOffset, CancelSelected, (int)this, ASURA_KEYID_ESCAPE, &pxOverlay->m_bShouldClose );
	pxOverlay->AddDialog( pxCancelDialog );
	xOffset.x -= 10.0f;

}

void Tools_PFXSelect_Overlay::TreeDoubleClicked(int iUserData)
{

	Tools_PFXSelect_Overlay *pxThis =(Tools_PFXSelect_Overlay *)iUserData;

	if (pxThis)
	{
		Asura_TreeDialog_Item* pxCurrentItem = pxThis->m_xTree.GetSelectedItem();

		if (pxCurrentItem && pxCurrentItem->GetNumChildren() == 0)
		{
			OkaySelected(iUserData);
		}
	}
}


Tools_PFXSelect_Overlay::~Tools_PFXSelect_Overlay()
{
}

