
///////////////////////////////////////////////////////////////////////////////
//
// File   : Tools_Entity_Teleporter.cpp
// Author : Andy Tate
// Date   : 28-Feb-2007
//
// Copyright (C) 2007 Rebellion, All Rights Reserved.
//
///////////////////////////////////////////////////////////////////////////////

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

#include "Core/Asura.h"

#if !defined(ASURA_DONT_USE_TELEPORTERS)

// This file's header...
#include "Entity/Tools_Entity_Teleporter.h"

// Asura independent header-files...
#include "Camera/Asura_Camera.h"
#include "Entity/Asura_StaticMessage_System.h"
#include "Entity/Intangible/Asura_ServerEntity_Teleporter.h"
#include "Entity/PhysicalObject/Asura_ServerEntity_PhysicalObject.h"
#include "Entity/Spawners/Asura_ServerEntity_TeleportDestination.h"
#include "Interface/Asura_Dialog.h"
#include "Interface/Asura_Overlay.h"
#include "Network/Asura_Message.h"
#include "Rendering/Asura_Colour.h"
#include "Rendering/Asura_Render.h"
#include "Rendering/Asura_Text_Output.h"
#include "Teleport/Asura_Teleport_Messages.h"

// Tools header-files...
#include "Interface/Tools_ColourPicker.h"
#include "Load&Save/Tools_SaveAsura.h"
#include "Misc/Tools_Timed_Messages.h"
#include "Objects/Tools_Object_System.h"


////////////////////////////////////////////////////////////////////////////////
// Constant declarations...
////////////////////////////////////////////////////////////////////////////////
static Tools_ObjectSystem_SharedValue< bool > g_xParam_Teleport_StartsActive( g_uHash_Entity_StartsActive);
TOOLS_DECLARE_SHARED_PARAM(bool,	0xAAE61249,	Teleport_PerformFade)
TOOLS_DECLARE_SHARED_PARAM(float,	0x3D06C381,	Teleport_FadeRed)
TOOLS_DECLARE_SHARED_PARAM(float,	0x15CEDDF3,	Teleport_FadeGreen)
TOOLS_DECLARE_SHARED_PARAM(float,	0x63CA836A,	Teleport_FadeBlue)
TOOLS_DECLARE_SHARED_PARAM(float,	0xA3012CC9,	Teleport_FadeInDuration)
TOOLS_DECLARE_SHARED_PARAM(float,	0x0183E9D2,	Teleport_FadeOutDuration)


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

Tools_Entity_Teleporter*	Tools_Entity_Teleporter::s_pxSelectedTeleporter		= NULL;
Asura_StaticMessage*		Tools_Entity_Teleporter::s_pxSelectedStaticMessage	= NULL;

static Asura_Dialog*	g_pxTeleportEntityDialogue	= NULL;

ProjectCanBeSelectedFunction* Tools_ChooseObject_EntityToTeleport::s_pfnProjectCanBeSelected = NULL;


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


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

////////////////////////////////////////////////////////////////////////////////
// Function     : Tools_Entity_Teleporter::IsEnabled_PerformFade
// Author       : Andy Tate
// Date         : 28-Feb-2007
////////////////////////////////////////////////////////////////////////////////

bool Tools_Entity_Teleporter::IsEnabled_PerformFade(void)
{
	const Asura_ServerEntity_Teleporter*	pxAsuraEntity	= static_cast<Asura_ServerEntity_Teleporter*>(s_pxSelectedTeleporter->Entity);

	return(pxAsuraEntity->CanPerformFade());
}

/// End of function 'Tools_Entity_Teleporter::IsEnabled_PerformFade'. ///



////////////////////////////////////////////////////////////////////////////////
// Function     : Tools_Entity_Teleporter::SelectTeleportDestination
// Author       : Andy Tate
// Date         : 1-Mar-2007
////////////////////////////////////////////////////////////////////////////////

void Tools_Entity_Teleporter::SelectTeleportDestination(int iIndex)
{
	Asura_ServerEntity_Teleporter*				pxTeleporter		= static_cast<Asura_ServerEntity_Teleporter*>(s_pxSelectedTeleporter->Entity);
	const Asura_Guid							uDestinationGuid	= pxTeleporter->m_auDestinationGuids[iIndex];
	Tools_Object*								pxToolsObject		= Tools_Object_System::GetObjectFromGuid(uDestinationGuid);
	Tools_ChooseObject_TeleporterDestination*	pxChooseObject		= new Tools_ChooseObject_TeleporterDestination (iIndex, s_pxSelectedTeleporter);

	char										szPrompt[256];

	Asura_PrintfToBfr(szPrompt, "Select the destination-entity to use for teleporter entry %d", sizeof(szPrompt), true, iIndex+1);
	Tools_Object_System::ChooseObject(szPrompt, pxChooseObject, pxToolsObject);
}

/// End of function 'Tools_Entity_Teleporter::SelectTeleportDestination'. ///



////////////////////////////////////////////////////////////////////////////////
// Function     : Tools_Entity_Teleporter::SelectGuidToTeleport
// Author       : Andy Tate
// Date         : 2-Mar-2007
////////////////////////////////////////////////////////////////////////////////

void Tools_Entity_Teleporter::SelectGuidToTeleport(void)
{
	Asura_Message_TeleportEntity*			pxData				= static_cast<Asura_Message_TeleportEntity*>(s_pxSelectedStaticMessage->m_pData);
	const Asura_Guid						uGuid				= pxData->GetGuidToTeleport();
	Tools_Object*							pxToolsObject		= Tools_Object_System::GetObjectFromGuid(uGuid);
	Tools_ChooseObject_EntityToTeleport*	pxChooseObject		= new Tools_ChooseObject_EntityToTeleport (s_pxSelectedStaticMessage);

	Tools_Object_System::ChooseObject("Select the entity to be teleported.", pxChooseObject, pxToolsObject);
}

/// End of function 'Tools_Entity_Teleporter::SelectGuidToTeleport'. ///



////////////////////////////////////////////////////////////////////////////////
// Function     : Tools_Entity_Teleporter::UpdateDialogueText
// Author       : Andy Tate
// Date         : 1-Mar-2007
////////////////////////////////////////////////////////////////////////////////

void Tools_Entity_Teleporter::UpdateDialogueText(const int iIndex)
{
	Asura_Dialog*					pxDialogue			= m_apxDestinationDialogues[iIndex];
	Asura_Overlay*					pxOverlay			= pxDialogue->m_pxOverlay;
	Asura_ServerEntity_Teleporter*	pxTeleporter		= static_cast<Asura_ServerEntity_Teleporter*>(Entity);
	const Asura_Guid				uDestinationGuid	= pxTeleporter->m_auDestinationGuids[iIndex];

	char							szText[256];

	if(uDestinationGuid == ASURA_GUID_UNREGISTERED)
	{
		strcpy(szText, "<None>");
	}
	else
	{
		Tools_Object*	pxObject	= Tools_Object_System::GetObjectFromGuid(uDestinationGuid);

		if(pxObject == NULL)
		{
			Asura_PrintfToBfr(szText, "GUID: %d", 256, true, uDestinationGuid);
		}
		else
		{
			Asura_PrintfToBfr(szText, "GUID: %d - \"%s\"", 256, true, uDestinationGuid, pxObject->GetName());
		}
	}

	pxDialogue->UpdateLabel(szText);
	pxOverlay->CalculateOverlaySize();
}

/// End of function 'Tools_Entity_Teleporter::UpdateDialogueText'. ///



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

////////////////////////////////////////////////////////////////////////////////
// Function     : Tools_Entity_Teleporter::Tools_Entity_Teleporter
// Author       : Andy Tate
// Date         : 28-Feb-2007
////////////////////////////////////////////////////////////////////////////////

Tools_Entity_Teleporter::Tools_Entity_Teleporter(Asura_Entity* pxEntity)
: PARENT(pxEntity)
{
	const Asura_ServerEntity_Teleporter*	pxAsuraEntity	= static_cast<Asura_ServerEntity_Teleporter*>(Entity);
	Asura_RGBA								xRGBA;

	// Set the type...
	Type	= TOT_Entity_Teleporter;

	SetMesh("ToolsShape_TeleportEntrance");

	// Initialise the data...
	xRGBA.FromUIntARGB(pxAsuraEntity->m_uFadeColour);

	m_bActive		= pxAsuraEntity->IsActive();
	m_bPerformFade	= pxAsuraEntity->CanPerformFade();

	m_fRed			= xRGBA.m_fR * 255.0f;
	m_fGreen		= xRGBA.m_fG * 255.0f;
	m_fBlue			= xRGBA.m_fB * 255.0f;
}

/// End of function 'Tools_Entity_Teleporter::Tools_Entity_Teleporter'. ///



////////////////////////////////////////////////////////////////////////////////
// Function     : Tools_Entity_Teleporter::SetDestination
// Author       : Andy Tate
// Date         : 1-Mar-2007
////////////////////////////////////////////////////////////////////////////////

void Tools_Entity_Teleporter::SetDestination(const int iIndex,
											 Tools_Object* pxObject)
{
	const Asura_Guid				uDestinationGuid	= (pxObject == NULL) ? ASURA_GUID_UNREGISTERED : pxObject->GetGuid();
	Asura_ServerEntity_Teleporter*	pxAsuraEntity		= static_cast<Asura_ServerEntity_Teleporter*>(Entity);

	pxAsuraEntity->m_auDestinationGuids[iIndex]	= uDestinationGuid;
	UpdateDialogueText(iIndex);
}

/// End of function 'Tools_Entity_Teleporter::SetDestination'. ///



////////////////////////////////////////////////////////////////////////////////
// Function     : Tools_Entity_Teleporter::AddOverlayControls
// Author       : Andy Tate
// Date         : 28-Feb-2007
////////////////////////////////////////////////////////////////////////////////

void Tools_Entity_Teleporter::AddOverlayControls (Asura_Overlay* pxOverlay,
												  Asura_Vector_2& xOffset)
{
	const float						fColourHorOffset	= 15.0f;
	const Asura_Vector_2			xColourSize(4.0f, 3.0f);

	Asura_Dialog*					pxDialog;

	// Add any parent controls...
	PARENT::AddOverlayControls(pxOverlay, xOffset);

	// Add our own controls...
	xOffset.y += Asura_Dialog::SmallSpacing();

	pxDialog = new Asura_SharedTickbox_Dialog("Starts Active", xOffset, &g_xParam_Teleport_StartsActive);
	pxDialog->SetHelpText("This teleporter is active at the start of the level.");
	pxOverlay->AddDialog(pxDialog);
	xOffset.y += Asura_Dialog::LargeSpacing();


	pxDialog = new Asura_SharedTickbox_Dialog("Perform Fade", xOffset, &g_xParam_Teleport_PerformFade);
	pxDialog->SetHelpText("This teleporter fades the screen out during teleporting.");
	pxOverlay->AddDialog(pxDialog);
	xOffset.y += Asura_Dialog::DefaultSpacing();

	xOffset.x += fColourHorOffset;
	pxDialog = new Tools_ColourPicker_Dialog("Fade colour", xOffset, xColourSize, &g_xParam_Teleport_FadeRed, &g_xParam_Teleport_FadeGreen, &g_xParam_Teleport_FadeBlue , 255.0f, &Changed);
	pxDialog->SetHelpText("This is the colour of the fade which occurs when teleporting.");
	pxDialog->SetIsEnabledFunction(IsEnabled_PerformFade);
	pxOverlay->AddDialog(pxDialog);
	xOffset.x -= fColourHorOffset;

	pxDialog = new Asura_Numerical_Dialog("Fade Red",xOffset,&g_xParam_Teleport_FadeRed,0.0f,255.0f,1.0f,"%0.0f");
	pxDialog->SetHelpText("Red colour component (0-255).");
	pxDialog->SetIsEnabledFunction(IsEnabled_PerformFade);
	pxOverlay->AddDialog(pxDialog);
	xOffset.y+=Asura_Dialog::DefaultSpacing();

	pxDialog = new Asura_Numerical_Dialog("Fade Green",xOffset,&g_xParam_Teleport_FadeGreen,0.0f,255.0f,1.0f,"%0.0f");
	pxDialog->SetHelpText("Green colour component (0-255).");
	pxDialog->SetIsEnabledFunction(IsEnabled_PerformFade);
	pxOverlay->AddDialog(pxDialog);
	xOffset.y+=Asura_Dialog::DefaultSpacing();

	pxDialog = new Asura_Numerical_Dialog("Fade Blue",xOffset,&g_xParam_Teleport_FadeBlue,0.0f,255.0f,1.0f,"%0.0f");
	pxDialog->SetHelpText("Blue colour component (0-255).");
	pxDialog->SetIsEnabledFunction(IsEnabled_PerformFade);
	pxOverlay->AddDialog(pxDialog);
	xOffset.y+=Asura_Dialog::DefaultSpacing();

	pxDialog = new Asura_Numerical_Dialog("Fade-out duration", xOffset, &g_xParam_Teleport_FadeOutDuration, 0.000f, 1.0f, 0.100f, "%.3f");
	pxDialog->SetHelpText("This is duration over which the fade-out before teleporting occurs.");
	pxDialog->SetIsEnabledFunction(IsEnabled_PerformFade);
	pxOverlay->AddDialog(pxDialog);
	xOffset.y += Asura_Dialog::DefaultSpacing();

	pxDialog = new Asura_Numerical_Dialog("Fade-in duration", xOffset, &g_xParam_Teleport_FadeInDuration, 0.000f, 1.0f, 0.100f, "%.3f");
	pxDialog->SetHelpText("This is duration over which the fade-in after teleporting occurs.");
	pxDialog->SetIsEnabledFunction(IsEnabled_PerformFade);
	pxOverlay->AddDialog(pxDialog);
	xOffset.y += Asura_Dialog::LargeSpacing();


	for(int i = 0; i < ASURA_TELEPORTER_ENTITY_MAX_DESTINATIONS; i++)
	{
		pxDialog = new Asura_Function_Dialog("", xOffset, SelectTeleportDestination, i, &Changed);
		pxDialog->SetHelpText("Select the destination entity for this teleporter entry.");
		pxOverlay->AddDialog(pxDialog);
		xOffset.y += Asura_Dialog::DefaultSpacing();

		m_apxDestinationDialogues[i]	= pxDialog;
		UpdateDialogueText(i);
	}
}

/// End of function 'Tools_Entity_Teleporter::AddOverlayControls'. ///



////////////////////////////////////////////////////////////////////////////////
// Function     : Tools_Entity_Teleporter::UpdateWhileSelected
// Author       : Andy Tate
// Date         : 6-Dec-2006
////////////////////////////////////////////////////////////////////////////////

void Tools_Entity_Teleporter::UpdateWhileSelected (void)
{
	if(Changed)
	{
		UpdateAsuraEntity();
	}

	// Call the parent...
	PARENT::UpdateWhileSelected();
}

/// End of function 'Tools_Entity_Teleporter::UpdateWhileSelected'. ///

////////////////////////////////////////////////////////////////////////////////
// Function     : Tools_Entity_Teleporter::UpdateAsuraEntity
// Author       : RichardRice
// Date         : 27-Nov-2008
////////////////////////////////////////////////////////////////////////////////

void Tools_Entity_Teleporter::UpdateAsuraEntity (void)
{
	Asura_ServerEntity_Teleporter*	pxAsuraEntity	= static_cast<Asura_ServerEntity_Teleporter*>(Entity);

	
	const Asura_RGBA	xRGBA(m_fRed / 255.0f, m_fGreen / 255.0f, m_fBlue / 255.0f, 1.0f);

	// Initialise our local variables...
	pxAsuraEntity->SetActive(m_bActive);
	pxAsuraEntity->SetPerformFade(m_bPerformFade);

	pxAsuraEntity->m_uFadeColour	= xRGBA.ToUIntARGB();
	
}

/// End of function 'Tools_Entity_Teleporter::UpdateAsuraEntity'. ///


////////////////////////////////////////////////////////////////////////////////
// Function     : Tools_Entity_Teleporter::HandlesThisMessage
// Author       : Andy Tate
// Date         : 6-Dec-2006
////////////////////////////////////////////////////////////////////////////////

bool Tools_Entity_Teleporter::HandlesThisMessage (int iMessageID)
{
	switch(iMessageID)
	{
		case ASURA_MSG_DESTRUCT:
		case ASURA_MSG_ACTIVATE:
		case ASURA_MSG_DEACTIVATE:
		case ASURA_MSG_TRIGGER:
		case ASURA_MSGID_TELEPORT_ENTITY:
		{
			return(true);
		}

		default:
		{
			return(PARENT::HandlesThisMessage(iMessageID));
		}
	}		// End of switch.
}

/// End of function 'Tools_Entity_Teleporter::HandlesThisMessage'. ///



////////////////////////////////////////////////////////////////////////////////
// Function     : Tools_Entity_Teleporter::PrintInfo
// Author       : Andy Tate
// Date         : 6-Dec-2006
////////////////////////////////////////////////////////////////////////////////

void Tools_Entity_Teleporter::PrintInfo (float& fX, float& fY)
{
	const Asura_ServerEntity_Teleporter*	pxAsuraEntity	= static_cast<Asura_ServerEntity_Teleporter*>(Entity);

	// Call the base-function...
	PARENT::PrintInfo(fX, fY);

	// Print our data...
	if(m_bPerformFade)
	{
		Asura_Text_Output::Print(fX, fY++, pxAsuraEntity->m_uFadeColour, 0, "Fade enabled");
		Asura_Text_Output::Print(fX, fY++, 0xFFFFFFFF, 0, "Fade-out duration : %.3fs", pxAsuraEntity->m_fFadeOutDuration);
		Asura_Text_Output::Print(fX, fY++, 0xFFFFFFFF, 0, "Fade-in duration : %.3fs", pxAsuraEntity->m_fFadeInDuration);
	}
	else
	{
		Asura_Text_Output::Print(fX, fY++, 0xFFFFFFFF, 0, "Fade disabled");
	}
}

/// End of function 'Tools_Entity_Teleporter::PrintInfo'. ///



////////////////////////////////////////////////////////////////////////////////
// Function     : Tools_Entity_Teleporter::Copy
// Author       : Andy Tate
// Date         : 6-Dec-2006
////////////////////////////////////////////////////////////////////////////////

void Tools_Entity_Teleporter::Copy (const Tools_Object* pxObject)
{
	const Tools_Entity_Teleporter*			pxTeleporterObject	= static_cast<const Tools_Entity_Teleporter*>(pxObject);
	const Asura_ServerEntity_Teleporter*	pxEntityToCopy		= static_cast<Asura_ServerEntity_Teleporter*>(pxTeleporterObject->Entity);
	Asura_ServerEntity_Teleporter*			pxEntity			= static_cast<Asura_ServerEntity_Teleporter*>(Entity);

	PARENT::Copy(pxObject);

	// Copy our data...
	pxEntity->SetActive(pxEntityToCopy->IsActive());
	pxEntity->SetPerformFade(pxEntityToCopy->CanPerformFade());

	pxEntity->m_fFadeInDuration		= pxEntityToCopy->m_fFadeInDuration;
	pxEntity->m_fFadeOutDuration	= pxEntityToCopy->m_fFadeOutDuration;
	pxEntity->m_uFadeColour			= pxEntityToCopy->m_uFadeColour;

	// Initialise our local variables...
	m_bActive		= pxEntity->IsActive();
	m_bPerformFade	= pxEntity->CanPerformFade();
}

/// End of function 'Tools_Entity_Teleporter::Copy'. ///



////////////////////////////////////////////////////////////////////////////////
// Function     : Tools_Entity_Teleporter::CreateObjectOfThisType
// Author       : Andy Tate
// Date         : 6-Dec-2006
////////////////////////////////////////////////////////////////////////////////

Tools_Object* Tools_Entity_Teleporter::CreateObjectOfThisType (void) const
{
	Create();
	return(Tools_Object_System::SelectedObject);
}

/// End of function 'Tools_Entity_Teleporter::CreateObjectOfThisType'. ///



////////////////////////////////////////////////////////////////////////////////
// Function     : Tools_Entity_Teleporter::OnSelection
// Author       : Andy Tate
// Date         : 28-Feb-2007
////////////////////////////////////////////////////////////////////////////////

void Tools_Entity_Teleporter::OnSelection(void)
{
	PARENT::OnSelection();
	s_pxSelectedTeleporter	= this;
}

/// End of function 'Tools_Entity_Teleporter::OnSelection'. ///



////////////////////////////////////////////////////////////////////////////////
// Function     : Tools_Entity_Teleporter::OnDeselection
// Author       : Andy Tate
// Date         : 28-Feb-2007
////////////////////////////////////////////////////////////////////////////////

void Tools_Entity_Teleporter::OnDeselection(void)
{
	PARENT::OnDeselection();
	s_pxSelectedTeleporter	= NULL;
}

/// End of function 'Tools_Entity_Teleporter::OnDeselection'. ///



////////////////////////////////////////////////////////////////////////////////
// Function     : Tools_Entity_Teleporter::Create
// Author       : Andy Tate
// Date         : 6-Dec-2006
////////////////////////////////////////////////////////////////////////////////

void Tools_Entity_Teleporter::Create (void)
{
	const Asura_Guid	uGuid		= Asura_Entity_System::GetCreatedByToolsGuid();
	Tools_Entity_Data*	pxToolsData	= CreateToolsDataWithDefaultName("Teleporter", "Teleporter", uGuid, GetNamePrefix());

	if(pxToolsData == NULL)
	{
		Asura_Assert(false, "Tools_Entity_Teleporter::Create() - no tools data" );
	}
	else
	{
		Asura_ServerEntity_Teleporter::Create(uGuid);

		Asura_ServerEntity_Teleporter*	pxServer	= Asura_ServerEntity_Teleporter::FindEntity(uGuid);

		if(pxServer == NULL)
		{
			Asura_Assert(false, "Tools_Entity_Teleporter::Create() - no server object");
		}
		else
		{
			pxServer->ToolsData	= pxToolsData;

			Tools_Entity_Teleporter* pxToolsObject = new Tools_Entity_Teleporter(pxServer);

			if(pxToolsObject == NULL)
			{
				Asura_Assert(false, "Tools_Entity_Teleporter::Create() - no Tools object" );
			}
			else
			{
				Tools_Object_System::SelectObject(pxToolsObject);

				pxToolsObject->Position		= *Asura_Camera::GetPosition();
				pxToolsObject->Orientation	= *Asura_Camera::GetOrientation();

				Tools_Timed_Message_System::AddMessage(0xffffff, "Created new Teleporter");
				Tools_SaveAsura::SetEntityModified();
			}
		}
	}
}

/// End of function 'Tools_Entity_Teleporter::Create'. ///



////////////////////////////////////////////////////////////////////////////////
// Function     : Tools_Entity_Teleporter::UpdateTeleportEntityText
// Author       : Andy Tate
// Date         : 2-Mar-2007
////////////////////////////////////////////////////////////////////////////////

void Tools_Entity_Teleporter::UpdateTeleportEntityText(const Asura_StaticMessage& xMessage,
													   Asura_String& xString)
{
	const Asura_Message_TeleportEntity*	pxData	= static_cast<Asura_Message_TeleportEntity*>(xMessage.m_pData);
	const Asura_Guid					uGuid	= pxData->GetGuidToTeleport();

	if(uGuid == ASURA_GUID_UNREGISTERED)
	{
		xString	= "GUID: <None>";
	}
	else
	{
		Tools_Object*	pxObject	= Tools_Object_System::GetObjectFromGuid(uGuid);
		char			szText[256];

		if(pxObject == NULL)
		{
			Asura_PrintfToBfr(szText, "GUID: %d - <Not found>", 256, true, uGuid);
		}
		else
		{
			const char*	szName	= pxObject->GetName();

			Asura_PrintfToBfr(szText, "GUID: %d - \"%s\"", 256, true, uGuid, szName);
		}

		xString	= szText;
	}
}

/// End of function 'Tools_Entity_Teleporter::UpdateTeleportEntityText'. ///



////////////////////////////////////////////////////////////////////////////////
// Function     : Tools_Entity_Teleporter::AddMessageOverlayControls_TeleportEntity
// Author       : Andy Tate
// Date         : 2-Mar-2007
////////////////////////////////////////////////////////////////////////////////

void Tools_Entity_Teleporter::AddMessageOverlayControls_TeleportEntity(Asura_StaticMessage* pxMessage,
																	   Asura_Overlay* pxOverlay,
																	   Asura_Vector_2& xOffset)
{
	Asura_Dialog*	pxDialog;
	Asura_String	xString;

	UpdateTeleportEntityText(*pxMessage, xString);

	pxDialog = new Asura_Function_Dialog(xString.GetString(), xOffset, SelectGuidToTeleport);
	pxDialog->SetHelpText( "Pick the entity to be teleported.");
	pxOverlay->AddDialog(pxDialog);
	xOffset.y += Asura_Dialog::DefaultSpacing();

	s_pxSelectedStaticMessage	= pxMessage;
	g_pxTeleportEntityDialogue	= pxDialog;
}

/// End of function 'Tools_Entity_Teleporter::AddMessageOverlayControls_TeleportEntity'. ///



////////////////////////////////////////////////////////////////////////////////
// Function     : Tools_Entity_Teleporter::Render
// Author       : Andy Tate
// Date         : 12-Mar-2007
////////////////////////////////////////////////////////////////////////////////

void Tools_Entity_Teleporter::Render(void)
{
	// Only render lines for selected teleporters...
	if (IsSelected())
	{
		const Asura_ServerEntity_Teleporter*	pxAsuraEntity	= static_cast<Asura_ServerEntity_Teleporter*>(Entity);

		for(u_int u = 0; u < ASURA_TELEPORTER_ENTITY_MAX_DESTINATIONS; u++)
		{
			const Asura_Guid								uGuid		= pxAsuraEntity->m_auDestinationGuids[u];
			const Asura_ServerEntity_TeleportDestination*	pxServer	= Asura_ServerEntity_TeleportDestination::FindEntity(uGuid);

			if(pxServer)
			{
				Asura_Render::RenderLine(Position,pxServer->GetPosition(),0xFFFF8000);
			}
		}
	}

	// Call the base-function...
	PARENT::Render();
}

/// End of function 'Tools_Entity_Teleporter::Render'. ///

////////////////////////////////////////////////////////////////////////////////
// Function     : Tools_Entity_Teleporter::GetParameter
// Author       : Richard Rice
// Date         : 27-Nov-2008
////////////////////////////////////////////////////////////////////////////////
bool Tools_Entity_Teleporter::GetParameter(Asura_Hash_ID uParamID,class Tools_Parameter* pxParam) const
{
	Asura_ServerEntity_Teleporter*	pxAsuraEntity	= static_cast<Asura_ServerEntity_Teleporter*>(Entity);

	switch(uParamID)
	{
		case g_uHash_Entity_StartsActive :
			pxParam->SetBool(m_bActive);
			break;

		case g_uHash_Teleport_PerformFade :
			pxParam->SetBool(m_bPerformFade);
			break;

		case g_uHash_Teleport_FadeRed :
			pxParam->SetFloat(m_fRed);
			break;

		case g_uHash_Teleport_FadeGreen :
			pxParam->SetFloat(m_fGreen);
			break;

		case g_uHash_Teleport_FadeBlue :
			pxParam->SetFloat(m_fBlue);
			break;

		case g_uHash_Teleport_FadeInDuration :
			pxParam->SetFloat(pxAsuraEntity->m_fFadeInDuration);
			break;

		case g_uHash_Teleport_FadeOutDuration :
			pxParam->SetFloat(pxAsuraEntity->m_fFadeOutDuration);
			break;

		default :
			return Tools_Entity_Object::GetParameter(uParamID,pxParam);
	}
	return true;
}

/// End of function 'Tools_Entity_Teleporter::GetParameter'. ///

////////////////////////////////////////////////////////////////////////////////
// Function     : Tools_Entity_Teleporter::SetParameter
// Author       : Richard Rice
// Date         : 27-Nov-2008
////////////////////////////////////////////////////////////////////////////////

bool Tools_Entity_Teleporter::SetParameter(Asura_Hash_ID uParamID,const class Tools_Parameter* pxParam)
{
	Asura_ServerEntity_Teleporter*	pxAsuraEntity	= static_cast<Asura_ServerEntity_Teleporter*>(Entity);

	switch(uParamID)
	{
		case g_uHash_Entity_StartsActive :
			m_bActive = pxParam->GetBool();
			break;

		case g_uHash_Teleport_PerformFade :
			m_bPerformFade = pxParam->GetBool();
			break;

		case g_uHash_Teleport_FadeRed :
			m_fRed = pxParam->GetFloat();
			break;

		case g_uHash_Teleport_FadeGreen :
			m_fGreen = pxParam->GetFloat();
			break;

		case g_uHash_Teleport_FadeBlue :
			m_fBlue = pxParam->GetFloat();
			break;

		case g_uHash_Teleport_FadeInDuration :
			pxAsuraEntity->m_fFadeInDuration = pxParam->GetFloat();
			break;

		case g_uHash_Teleport_FadeOutDuration :
			pxAsuraEntity->m_fFadeOutDuration = pxParam->GetFloat();
			break;

		default :
			return Tools_Entity_Object::SetParameter(uParamID,pxParam);
	}
	UpdateAsuraEntity();
	SetEntityModified();

	return true;
}


void Tools_Entity_Teleporter::SetSelectedStaticMessage( Asura_StaticMessage* pxMsg )
{
    s_pxSelectedStaticMessage = pxMsg;
}


void Tools_Entity_Teleporter::SetTeleportEntityDialog( Asura_Dialog* pxDialog )
{
    g_pxTeleportEntityDialogue = pxDialog;
}


bool Tools_ChooseObject_TeleporterDestination::CanBeSelected(Tools_Object* pxObject)
{
	return(pxObject->Type == TOT_Entity_TeleportDestination);
}

/// End of function 'Tools_ChooseObject_TeleporterDestination::CanBeSelected'. ///



////////////////////////////////////////////////////////////////////////////////
// Function     : Tools_ChooseObject_TeleporterDestination::ObjectSelected
// Author       : Andy Tate
// Date         : 1-Mar-2007
////////////////////////////////////////////////////////////////////////////////

void Tools_ChooseObject_TeleporterDestination::ObjectSelected(Tools_Object* pxObject)
{
	m_pxTeleporter->SetDestination(m_iIndex, pxObject);
}

/// End of function 'Tools_ChooseObject_TeleporterDestination::ObjectSelected'. ///



////////////////////////////////////////////////////////////////////////////////
// Function     : Tools_ChooseObject_EntityToTeleport::CanBeSelected
// Author       : Andy Tate
// Date         : 2-Mar-2007
////////////////////////////////////////////////////////////////////////////////

bool Tools_ChooseObject_EntityToTeleport::CanBeSelected(Tools_Object* pxObject)
{
	const Asura_Guid							uGuid				= pxObject->GetGuid();
	const Asura_ServerEntity_PhysicalObject*	pxPhysicalObject	= Asura_ServerEntity_PhysicalObject::FindEntity(uGuid);


	if(pxPhysicalObject)
	{
		return true;
	}
	
	if(s_pfnProjectCanBeSelected)
	{
		return s_pfnProjectCanBeSelected(pxObject);
	}

	return false;
}

/// End of function 'Tools_ChooseObject_EntityToTeleport::CanBeSelected'. ///



////////////////////////////////////////////////////////////////////////////////
// Function     : Tools_ChooseObject_EntityToTeleport::ObjectSelected
// Author       : Andy Tate
// Date         : 2-Mar-2007
////////////////////////////////////////////////////////////////////////////////

void Tools_ChooseObject_EntityToTeleport::ObjectSelected(Tools_Object* pxObject)
{
	const Asura_Guid				uGuid		= (pxObject == NULL) ? ASURA_GUID_UNREGISTERED : pxObject->GetGuid();
	Asura_Message_TeleportEntity*	pxData		= static_cast<Asura_Message_TeleportEntity*>(m_pxStaticMessage->m_pData);
	Asura_Dialog*					pxDialogue	= g_pxTeleportEntityDialogue;
	Asura_Overlay*					pxOverlay	= pxDialogue->m_pxOverlay;

	Asura_String					xString;

	pxData->SetGuidToTeleport(uGuid);

	Tools_Entity_Teleporter::UpdateTeleportEntityText(*m_pxStaticMessage, xString);
	pxDialogue->UpdateLabel(xString.GetString());
	pxOverlay->CalculateOverlaySize();
}


#endif	// !defined(ASURA_DONT_USE_TELEPORTERS)
