
///////////////////////////////////////////////////////////////////////////////
//
// File   : Tools_Overlay_FacialAnimation.cpp
// Author : Andy Tate
// Date   : 8-May-2008
//
// Copyright (C) 2008 Rebellion, All Rights Reserved.
//
///////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////
// Include files...
////////////////////////////////////////////////////////////////////////////////

#include "Core/Asura.h"

#if defined(ASURA_USE_FACIAL_ANIMATION_SYSTEM)

// This file's header...
#include "FacialAnimation/Overlays/Tools_Overlay_FacialAnimation.h"

// Asura independent header-files...
#include "ChunkSystem/Asura_Chunk_Loaders.h"
#include "Interface/Asura_Overlay_System.h"

// Tools header-files...
#include "Tools_Overlays.h"
#include "FacialAnimation/Tools_FacialAnimation_System.h"
#include "FacialAnimation/Overlays/Tools_Overlay_FacialAnimation_EditFace.h"
#include "FacialAnimation/Overlays/Tools_Overlay_FacialAnimation_EditFaceType.h"
#include "Misc/Tools_Modal_Overlay.h"
#include "PC/FileSystem/Tools_FileSystem.h"


////////////////////////////////////////////////////////////////////////////////
// Constant declarations...
////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////
// Static variable declarations...
////////////////////////////////////////////////////////////////////////////////

Tools_Overlay_FacialAnimation*	Tools_Overlay_FacialAnimation::s_pxThis	= NULL;


////////////////////////////////////////////////////////////////////////////////
// Private functions...
////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////
// Protected functions...
////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////
// Function     : Tools_Overlay_FacialAnimation::AddOverlayItems
// Author       : Andy Tate
// Date         : 8-May-2008
////////////////////////////////////////////////////////////////////////////////

void Tools_Overlay_FacialAnimation::AddOverlayItems(Asura_Vector_2& xOffset)
{
	Asura_Tabs_Dialog*	pxTabsDialogue	= new Asura_Tabs_Dialog (xOffset);
	Asura_Dialog*		pxNewDialogue	= pxTabsDialogue;

	// Create our tabs...
	AddDialog(pxNewDialogue);
	xOffset.y	+= Asura_Dialog::LargeSpacing();

	// Create the face-types tab...
	pxTabsDialogue->AddTab("Types");
	{
		Asura_Vector_2		xLocalOffset(xOffset);

		const float			fTreeWidth			= 30.0f;
		const float			fTreeHeight			= 30.0f;
		Asura_Tree_Dialog*	pxNewTreeDialogue	= new Asura_Tree_Dialog(xLocalOffset, &m_xTypeTree, fTreeWidth, fTreeHeight);

		pxNewTreeDialogue->SetDoubleClickedFunction(OnEditCurrentTypeSelected);
		pxTabsDialogue->AddDialog(pxNewTreeDialogue);

		xLocalOffset.y += fTreeHeight + 1.0f;
		pxNewDialogue	= new Asura_Function_Dialog("Create Face-type In Any Directory", xLocalOffset, OnCreateNewTypeSelected);
		pxTabsDialogue->AddDialog(pxNewDialogue);

		xLocalOffset.y += Asura_Dialog::DefaultSpacing();
		pxNewDialogue	= new Asura_Function_Dialog("Create Face-type In Current Directory", xLocalOffset, OnCreateNewTypeInCurrentDirectorySelected, NULL, IsTypeTreeItemADirectory);
		pxTabsDialogue->AddDialog(pxNewDialogue);

		xLocalOffset.y += Asura_Dialog::DefaultSpacing();
		pxNewDialogue	= new Asura_Function_Dialog("Edit Current Face-type", xLocalOffset, OnEditCurrentTypeSelected, NULL, IsTypeTreeItemAFile);
		pxTabsDialogue->AddDialog(pxNewDialogue);
	}

	// Create the face tab...
	pxTabsDialogue->AddTab("Faces");
	{
		Asura_Vector_2		xLocalOffset(xOffset);

		const float			fTreeWidth			= 30.0f;
		const float			fTreeHeight			= 30.0f;
		Asura_Tree_Dialog*	pxNewTreeDialogue	= new Asura_Tree_Dialog(xLocalOffset, &m_xFaceTree, fTreeWidth, fTreeHeight);

		pxNewTreeDialogue->SetDoubleClickedFunction(OnEditCurrentFaceSelected);
		pxTabsDialogue->AddDialog(pxNewTreeDialogue);

		xLocalOffset.y += fTreeHeight + 1.0f;
		pxNewDialogue	= new Asura_Function_Dialog("Create Face In Any Directory", xLocalOffset, OnCreateNewFaceSelected);
		pxTabsDialogue->AddDialog(pxNewDialogue);

		xLocalOffset.y += Asura_Dialog::DefaultSpacing();
		pxNewDialogue	= new Asura_Function_Dialog("Create Face In Current Directory", xLocalOffset, OnCreateNewFaceInCurrentDirectorySelected, NULL, IsFaceTreeItemADirectory);
		pxTabsDialogue->AddDialog(pxNewDialogue);

		xLocalOffset.y += Asura_Dialog::DefaultSpacing();
		pxNewDialogue	= new Asura_Function_Dialog("Edit Current Face", xLocalOffset, OnEditCurrentFaceSelected, NULL, IsFaceTreeItemAFile);
		pxTabsDialogue->AddDialog(pxNewDialogue);
	}

	// Create the face-animations tab...
	pxTabsDialogue->AddTab("Animations");
	{
		Asura_Vector_2		xLocalOffset(xOffset);

		const float			fTreeWidth			= 30.0f;
		const float			fTreeHeight			= 30.0f;
		Asura_Tree_Dialog*	pxNewTreeDialogue	= new Asura_Tree_Dialog(xLocalOffset, &m_xAnimationTree, fTreeWidth, fTreeHeight);

		pxTabsDialogue->AddDialog(pxNewTreeDialogue);
	}

	// Create the face-animations tab...
	pxTabsDialogue->AddTab("Poses");
	{
		Asura_Vector_2		xLocalOffset(xOffset);

		const float			fTreeWidth			= 30.0f;
		const float			fTreeHeight			= 30.0f;
		Asura_Tree_Dialog*	pxNewTreeDialogue	= new Asura_Tree_Dialog(xLocalOffset, &m_xPoseTree, fTreeWidth, fTreeHeight);

		pxTabsDialogue->AddDialog(pxNewTreeDialogue);
	}

	// Start with the first tab being open...
	pxTabsDialogue->SelectTab(0);
}

/// End of function 'Tools_Overlay_FacialAnimation::AddOverlayItems'. ///



////////////////////////////////////////////////////////////////////////////////
// Function     : Tools_Overlay_FacialAnimation::Tools_Overlay_FacialAnimation
// Author       : Andy Tate
// Date         : 8-May-2008
////////////////////////////////////////////////////////////////////////////////

Tools_Overlay_FacialAnimation::Tools_Overlay_FacialAnimation(void)
: PARENT("Facial Animation", false)
, m_xTypeTree(Tools_FacialAnimation_System::GetTypeDirectoryName(), Tools_FacialAnimation_System::GetTypeFileExtension(), false)
, m_xFaceTree(Tools_FacialAnimation_System::GetFaceDirectoryName(), Tools_FacialAnimation_System::GetFaceFileExtension(), false)
, m_xAnimationTree(Tools_FacialAnimation_System::GetAnimationDirectoryName(), Tools_FacialAnimation_System::GetAnimationFileExtension(), false)
, m_xPoseTree(Tools_FacialAnimation_System::GetPoseDirectoryName(), Tools_FacialAnimation_System::GetPoseFileExtension(), false)
{
	Asura_Vector_2	xOffset(1.0f, 3.0f);

	// Initialise the variables...
	m_uID		= TOOLS_OVERLAY_FACIALANIMATION;
	s_pxThis	= this;

	// Finally, update the overlays...
	AddOverlayItems(xOffset);
}

/// End of function 'Tools_Overlay_FacialAnimation::Tools_Overlay_FacialAnimation'. ///



////////////////////////////////////////////////////////////////////////////////
// Function     : Tools_Overlay_FacialAnimation::~Tools_Overlay_FacialAnimation
// Author       : Andy Tate
// Date         : 8-May-2008
////////////////////////////////////////////////////////////////////////////////

Tools_Overlay_FacialAnimation::~Tools_Overlay_FacialAnimation()
{
	// Reset our pointer...
	s_pxThis	= NULL;
}

/// End of function 'Tools_Overlay_FacialAnimation::~Tools_Overlay_FacialAnimation'. ///



////////////////////////////////////////////////////////////////////////////////
// Function     : Tools_Overlay_FacialAnimation::OnCreateNewTypeSelected
// Author       : Andy Tate
// Date         : 9-May-2008
////////////////////////////////////////////////////////////////////////////////

void Tools_Overlay_FacialAnimation::OnCreateNewTypeSelected(void)
{
	char	szWorkingDirectory[MAX_PATH];

	GetCurrentDirectory(MAX_PATH, szWorkingDirectory);

	const Asura_String					xRootDirectory(Asura_String(szWorkingDirectory) + "\\" + Tools_FacialAnimation_System::GetTypeDirectoryName());
	const int							iRootDirectoryLength	= xRootDirectory.GetLength() + 1;	// +1 for '\\'

	Tools_FileSystem_SelectFolderInfo	xSelectFolderInfo(xRootDirectory.GetString(), "Select Directory for Face-Type", "");

	if(Tools_FileSystem::SelectFolder(xSelectFolderInfo))
	{
		Asura_String	xLocalDirectory(xSelectFolderInfo.SelectedFolder);
		const int		iLocalDirectoryLength	= xLocalDirectory.GetLength();

		xLocalDirectory	= xLocalDirectory.SubString(iRootDirectoryLength, iLocalDirectoryLength - iRootDirectoryLength);
		CreateNewType(xLocalDirectory.GetString());
	}
}

/// End of function 'Tools_Overlay_FacialAnimation::OnCreateNewTypeSelected'. ///



////////////////////////////////////////////////////////////////////////////////
// Function     : Tools_Overlay_FacialAnimation::OnCreateNewTypeInCurrentDirectorySelected
// Author       : Andy Tate
// Date         : 12-May-2008
////////////////////////////////////////////////////////////////////////////////

void Tools_Overlay_FacialAnimation::OnCreateNewTypeInCurrentDirectorySelected(void)
{
	const Asura_TreeDialog_Tree&	xTree			= s_pxThis->m_xTypeTree;
	const Asura_TreeDialog_Item*	pxCurrentItem	= xTree.GetSelectedItem();

	if(pxCurrentItem != NULL)
	{
		Asura_String	xDirectory;

		pxCurrentItem->ConcatenatePath( xDirectory );
		CreateNewType(xDirectory.GetString());
	}
}

/// End of function 'Tools_Overlay_FacialAnimation::OnCreateNewTypeInCurrentDirectorySelected'. ///



////////////////////////////////////////////////////////////////////////////////
// Function     : Tools_Overlay_FacialAnimation::OnEditCurrentTypeSelected
// Author       : Andy Tate
// Date         : 9-May-2008
////////////////////////////////////////////////////////////////////////////////

void Tools_Overlay_FacialAnimation::OnEditCurrentTypeSelected(void)
{
	const Asura_TreeDialog_FileTree&	xFileTree	= s_pxThis->m_xTypeTree;

	if(xFileTree.IsCurrentItemAFile())
	{
		Asura_String					xPath;

		const Asura_TreeDialog_Item*	pxCurrentItem	= xFileTree.GetSelectedItem();
		Tools_FacialAnimation_FaceType*	pxType			= Tools_FacialAnimation_System::FindOrLoadTypeFromTreeItem(*pxCurrentItem, xPath);

		// Did we manage to create a new face?
		if(pxType == NULL)
		{
			ShowMessageOverlay("Failed to find the specified face \"%s\".", xPath.GetString());
		}
		else
		{
			// Attempt to bring up the dialogue...
			if(Tools_Overlay_FacialAnimation_EditFaceType::OverlayExists())
			{
				Tools_Overlay_FacialAnimation_EditFaceType::CloseOverlay();
			}

			Tools_Overlay_FacialAnimation_EditFaceType::CreateOverlay(false, xPath, *pxType);
		}
	}
}

/// End of function 'Tools_Overlay_FacialAnimation::OnEditCurrentTypeSelected'. ///



////////////////////////////////////////////////////////////////////////////////
// Function     : Tools_Overlay_FacialAnimation::IsTypeTreeItemADirectory
// Author       : Andy Tate
// Date         : 12-May-2008
////////////////////////////////////////////////////////////////////////////////

bool Tools_Overlay_FacialAnimation::IsTypeTreeItemADirectory(void)
{
	const Asura_TreeDialog_FileTree&	xFileTree	= s_pxThis->m_xTypeTree;

	return(xFileTree.IsCurrentItemADirectory());
}

/// End of function 'Tools_Overlay_FacialAnimation::IsTypeTreeItemADirectory'. ///



////////////////////////////////////////////////////////////////////////////////
// Function     : Tools_Overlay_FacialAnimation::IsTypeTreeItemAFile
// Author       : Andy Tate
// Date         : 12-May-2008
////////////////////////////////////////////////////////////////////////////////

bool Tools_Overlay_FacialAnimation::IsTypeTreeItemAFile(void)
{
	const Asura_TreeDialog_FileTree&	xFileTree	= s_pxThis->m_xTypeTree;

	return(xFileTree.IsCurrentItemAFile());
}

/// End of function 'Tools_Overlay_FacialAnimation::IsTypeTreeItemAFile'. ///



////////////////////////////////////////////////////////////////////////////////
// Function     : Tools_Overlay_FacialAnimation::CreateNewType
// Author       : Andy Tate
// Date         : 12-May-2008
////////////////////////////////////////////////////////////////////////////////

void Tools_Overlay_FacialAnimation::CreateNewType(const char* szDirectory)
{
	GetString_Overlay	xGetNameOverlay("Enter name for new face-type", "Type");

	if(xGetNameOverlay.DoModal())
	{
		const char*						szName	= xGetNameOverlay.GetString();
		Tools_FacialAnimation_FaceType*	pxType	= Tools_FacialAnimation_System::FindType(szName);

		if(pxType == NULL)
		{
			pxType	= Tools_FacialAnimation_System::CreateType(szName);

			if(pxType == NULL)
			{
				ShowMessageOverlay("Failed to create a new face-type named \"%s\".", szName);
			}
			else
			{
				const Asura_String		xPath(Asura_String(szDirectory) + "\\" + szName);

				Asura_TreeDialog_FileTree&	xFileTree	= s_pxThis->m_xTypeTree;
				Asura_TreeDialog_Item*		pxNewItem	= xFileTree.AddItem(xPath);

				// Update the tree-dialogue accordingly...
				xFileTree.SetSelectedItem(pxNewItem);

				// Open the appropriate overlay...
				if(Tools_Overlay_FacialAnimation_EditFaceType::OverlayExists())
				{
					Tools_Overlay_FacialAnimation_EditFaceType::CloseOverlay();
				}

				Tools_Overlay_FacialAnimation_EditFaceType::CreateOverlay(true, xPath, *pxType);
			}
		}
		else
		{
			ShowMessageOverlay("Already have a face-type named \"%s\", try a different name.", szName);
		}
	}
}

/// End of function 'Tools_Overlay_FacialAnimation::CreateNewType'. ///



////////////////////////////////////////////////////////////////////////////////
// Function     : Tools_Overlay_FacialAnimation::CreateNewFace
// Author       : Andy Tate
// Date         : 12-May-2008
////////////////////////////////////////////////////////////////////////////////

void Tools_Overlay_FacialAnimation::CreateNewFace(const char* szDirectory)
{
	GetString_Overlay	xGetNameOverlay("Enter name for new face", "Face");

	if(xGetNameOverlay.DoModal())
	{
		const char*					szName	= xGetNameOverlay.GetString();
		Tools_FacialAnimation_Face*	pxFace	= Tools_FacialAnimation_System::FindFace(szName);

		if(pxFace == NULL)
		{
			pxFace	= Tools_FacialAnimation_System::CreateFace(szName);

			if(pxFace == NULL)
			{
				ShowMessageOverlay("Failed to create a new face named \"%s\".", szName);
			}
			else
			{
				const Asura_String		xPath(Asura_String(szDirectory) + "\\" + szName);

				Asura_TreeDialog_FileTree&	xFileTree	= s_pxThis->m_xFaceTree;
				Asura_TreeDialog_Item*		pxNewItem	= xFileTree.AddItem(xPath);

				// Update the tree-dialogue accordingly...
				xFileTree.SetSelectedItem(pxNewItem);

				// Open the appropriate overlay...
				if(Tools_Overlay_FacialAnimation_EditFace::OverlayExists())
				{
					Tools_Overlay_FacialAnimation_EditFace::CloseOverlay();
				}

				Tools_Overlay_FacialAnimation_EditFace::CreateOverlay(true, xPath, *pxFace);
			}
		}
		else
		{
			ShowMessageOverlay("Already have a face named \"%s\", try a different name.", szName);
		}
	}
}

/// End of function 'Tools_Overlay_FacialAnimation::CreateNewFace'. ///



////////////////////////////////////////////////////////////////////////////////
// Function     : Tools_Overlay_FacialAnimation::OnCreateNewFaceSelected
// Author       : Andy Tate
// Date         : 9-May-2008
////////////////////////////////////////////////////////////////////////////////

void Tools_Overlay_FacialAnimation::OnCreateNewFaceSelected(void)
{
	char	szWorkingDirectory[MAX_PATH];

	GetCurrentDirectory(MAX_PATH, szWorkingDirectory);

	const Asura_String					xRootDirectory(Asura_String(szWorkingDirectory) + "\\" + Tools_FacialAnimation_System::GetFaceDirectoryName());
	const int							iRootDirectoryLength	= xRootDirectory.GetLength() + 1;	// +1 for '\\'

	Tools_FileSystem_SelectFolderInfo	xSelectFolderInfo(xRootDirectory.GetString(), "Select Directory for Face", "");

	if(Tools_FileSystem::SelectFolder(xSelectFolderInfo))
	{
		Asura_String	xLocalDirectory(xSelectFolderInfo.SelectedFolder);
		const int		iLocalDirectoryLength	= xLocalDirectory.GetLength();

		xLocalDirectory	= xLocalDirectory.SubString(iRootDirectoryLength, iLocalDirectoryLength - iRootDirectoryLength);
		CreateNewFace(xLocalDirectory.GetString());
	}
}

/// End of function 'Tools_Overlay_FacialAnimation::OnCreateNewFaceSelected'. ///



////////////////////////////////////////////////////////////////////////////////
// Function     : Tools_Overlay_FacialAnimation::OnCreateNewFaceInCurrentDirectorySelected
// Author       : Andy Tate
// Date         : 12-May-2008
////////////////////////////////////////////////////////////////////////////////

void Tools_Overlay_FacialAnimation::OnCreateNewFaceInCurrentDirectorySelected(void)
{
	const Asura_TreeDialog_Tree&	xTree			= s_pxThis->m_xFaceTree;
	const Asura_TreeDialog_Item*	pxCurrentItem	= xTree.GetSelectedItem();

	if(pxCurrentItem != NULL)
	{
		Asura_String	xDirectory;

		pxCurrentItem->ConcatenatePath( xDirectory );
		CreateNewFace(xDirectory.GetString());
	}
}

/// End of function 'Tools_Overlay_FacialAnimation::OnCreateNewFaceInCurrentDirectorySelected'. ///



////////////////////////////////////////////////////////////////////////////////
// Function     : Tools_Overlay_FacialAnimation::OnEditCurrentFaceSelected
// Author       : Andy Tate
// Date         : 9-May-2008
////////////////////////////////////////////////////////////////////////////////

void Tools_Overlay_FacialAnimation::OnEditCurrentFaceSelected(void)
{
	const Asura_TreeDialog_FileTree&	xFileTree	= s_pxThis->m_xFaceTree;

	if(xFileTree.IsCurrentItemAFile())
	{
		Asura_String					xPath;

		const Asura_TreeDialog_Item*	pxCurrentItem	= xFileTree.GetSelectedItem();
		Tools_FacialAnimation_Face*		pxFace			= Tools_FacialAnimation_System::FindOrLoadFaceFromTreeItem(*pxCurrentItem, xPath);

		// Did we manage to create a new face?
		if(pxFace == NULL)
		{
			ShowMessageOverlay("Failed to find the specified face \"%s\".", xPath.GetString());
		}
		else
		{
			// Attempt to bring up the dialogue...
			if(Tools_Overlay_FacialAnimation_EditFace::OverlayExists())
			{
				Tools_Overlay_FacialAnimation_EditFace::CloseOverlay();
			}

			Tools_Overlay_FacialAnimation_EditFace::CreateOverlay(false, xPath, *pxFace);
		}
	}
}

/// End of function 'Tools_Overlay_FacialAnimation::OnEditCurrentFaceSelected'. ///



////////////////////////////////////////////////////////////////////////////////
// Function     : Tools_Overlay_FacialAnimation::IsFaceTreeItemADirectory
// Author       : Andy Tate
// Date         : 12-May-2008
////////////////////////////////////////////////////////////////////////////////

bool Tools_Overlay_FacialAnimation::IsFaceTreeItemADirectory(void)
{
	const Asura_TreeDialog_FileTree&	xFileTree	= s_pxThis->m_xFaceTree;

	return(xFileTree.IsCurrentItemADirectory());
}

/// End of function 'Tools_Overlay_FacialAnimation::IsFaceTreeItemADirectory'. ///



////////////////////////////////////////////////////////////////////////////////
// Function     : Tools_Overlay_FacialAnimation::IsFaceTreeItemAFile
// Author       : Andy Tate
// Date         : 12-May-2008
////////////////////////////////////////////////////////////////////////////////

bool Tools_Overlay_FacialAnimation::IsFaceTreeItemAFile(void)
{
	const Asura_TreeDialog_FileTree&	xFileTree	= s_pxThis->m_xFaceTree;

	return(xFileTree.IsCurrentItemAFile());
}

/// End of function 'Tools_Overlay_FacialAnimation::IsFaceTreeItemAFile'. ///



////////////////////////////////////////////////////////////////////////////////
// Public functions...
////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////
// Function     : Tools_Overlay_FacialAnimation::CreateOverlay
// Author       : Andy Tate
// Date         : 8-May-2008
////////////////////////////////////////////////////////////////////////////////

void Tools_Overlay_FacialAnimation::CreateOverlay(void)
{
	if(Asura_Overlay_System::DoesOverlayExist(TOOLS_OVERLAY_FACIALANIMATION))
	{
		Asura_Overlay_System::BringOverlayToTop(TOOLS_OVERLAY_FACIALANIMATION);
	}
	else
	{
		Tools_Overlay_FacialAnimation*	pxOverlay	= new Tools_Overlay_FacialAnimation;

		Asura_Overlay_System::SubmitNewOverlay(pxOverlay);
	}
}

/// End of function 'Tools_Overlay_FacialAnimation::CreateOverlay'. ///



////////////////////////////////////////////////////////////////////////////////
// Function     : Tools_Overlay_FacialAnimation::CloseOverlay
// Author       : Andy Tate
// Date         : 8-May-2008
////////////////////////////////////////////////////////////////////////////////

void Tools_Overlay_FacialAnimation::CloseOverlay(void)
{
	Asura_Overlay_System::CloseOverlays(TOOLS_OVERLAY_FACIALANIMATION);	
}

/// End of function 'Tools_Overlay_FacialAnimation::CloseOverlay'. ///

#endif	//defined(ASURA_USE_FACIAL_ANIMATION_SYSTEM)


/// End of file. ///
