//////////////////////////////////////////////////////////////////////////////
//
// Asura_ServerEntity_DebugWaypointTrigger.cpp
//
// Created by JAT - 02 April 2007
//
// Copyright (c) 2007 Rebellion. All rights reserved.
//
// Description:
//
//////////////////////////////////////////////////////////////////////////////

#include "Core/Asura.h"

#ifdef ASURA_USE_DEBUG_MESSAGE_TRIGGER

#include "Tools_Entity_DebugWaypointTrigger_Object.h"

// Asura
#include "Animation/Asura_Animation.h"
#include "Animation/Asura_Hierarchy.h"
#include "Entity/Triggers/Asura_ServerEntity_DebugWaypointTrigger.h"
#include "Mesh/Asura_Mesh_System.h"
#include "Objects/Tools_Object_System.h"
#include "Load&Save/Tools_SaveAsura.h"
#include "Interface/Asura_Dialog.h"
#include "Interface/Tools_ColourPicker.h"
#include "Network/Asura_Message.h"

// Tools
#include "Hierarchy/Tools_Animation_Files.h"
#include "Entity/Tools_Entity_Trigger_Object.h"
#include "Objects/Tools_Object.h"
#include "Objects/Tools_ObjectSystem_Param.h"
#include "Shapes/Tools_Shapes.h"
#include "Shapes/Asura_Shape_System.h"
#include "Tools_Overlays.h"

#ifdef ASURA_TOOLS
#include "Misc/Tools_Timed_Messages.h"
#endif

TOOLS_DECLARE_SHARED_PARAM(bool,	0xC36E0DF1,	DebugWaypointTrigger_AlwaysShowTitle)
TOOLS_DECLARE_SHARED_PARAM(bool,	0x4F7F2250,	DebugWaypointTrigger_UseLookAtTest)
TOOLS_DECLARE_SHARED_PARAM(bool,	0xCE2A50E9,	DebugWaypointTrigger_UseLOSOcclusion)
TOOLS_DECLARE_SHARED_PARAM(float,	0x35D5824C,	DebugWaypointTrigger_TimeToDisplayText)
TOOLS_DECLARE_SHARED_PARAM(bool,	0x3BC3C1BA,	DebugWaypointTrigger_UseRadiusTrigger)
TOOLS_DECLARE_SHARED_PARAM(float,	0xC4B9DF2F,	DebugWaypointTrigger_TriggerRadius)
TOOLS_DECLARE_SHARED_PARAM(float,	0x794E69B6,	DebugWaypointTrigger_Red)
TOOLS_DECLARE_SHARED_PARAM(float,	0x5EC5CAE8,	DebugWaypointTrigger_Green)
TOOLS_DECLARE_SHARED_PARAM(float,	0xB077A3D5,	DebugWaypointTrigger_Blue)

//////////////////////////////////////////////////////////////////////////////////////////////////
/*--------------------------------------------**
** Tools_Entity_DebugWaypointTrigger_Object **
**--------------------------------------------*/
Tools_Entity_DebugWaypointTrigger_Object::Tools_Entity_DebugWaypointTrigger_Object(Asura_Entity* pxEntity)
:Tools_Entity_Trigger_Object(pxEntity)
{
	Asura_Assert( pxEntity->GetClassification()== AsuraEntityClass_DebugWaypointTrigger, "" );
	Type = TOT_Entity_DebugWaypointTrigger;
	SetMesh("ToolsShape_DebugWaypoint");

	m_bSkin = static_cast<Asura_ServerEntity_DebugWaypointTrigger*>(pxEntity)->m_bSkin;
	m_uShapeID = static_cast<Asura_ServerEntity_DebugWaypointTrigger*>(pxEntity)->m_xClientData.m_uShapeID;
	m_uAnimID  = static_cast<Asura_ServerEntity_DebugWaypointTrigger*>(pxEntity)->m_xClientData.m_uAnimID;

	//Shape only
	if(!m_bSkin)
	{
		// Clear the tools mesh.
		Asura_String xShapeFilename = "NULL";
		Asura_Mesh* pxMesh = NULL;

		const char* szShapeName		= Tools_ShapeTable::LookupObjectMeshName( m_uShapeID );
		const char* szShapeFilename = Tools_ShapeTable::LookupObjectFileName( m_uShapeID );

		if ( !szShapeName || ! szShapeFilename )
		{
			Asura_Assertf(true,("Failed to find shape: Name: %s - File: %s", szShapeName, szShapeFilename));
		}
		else
		{
			pxMesh = 0;
			pxMesh = Asura_Mesh_System::GetMesh(szShapeName);

			if( !pxMesh && Asura_Mesh_System::GetNumberOfMeshes() > 0 )
			{
				Asura_Assertf(Mesh, ("Mesh not found for %s", szShapeName) );
			}
			else
			{
				Mesh = pxMesh;
			}
		}
	}
	else
	{
		//we have a skin & anim
		SetSkinAndAnim(m_uShapeID,m_uAnimID);
	}
}

void Tools_Entity_DebugWaypointTrigger_Object::Create()
{
	Tools_Object* pxObject = Create( false );
	Tools_Object_System::SelectObject( pxObject );
}

Tools_Object* Tools_Entity_DebugWaypointTrigger_Object::Create( Asura_Entity* pxEntity )
{
	return new Tools_Entity_DebugWaypointTrigger_Object( pxEntity );
}

Tools_Entity_DebugWaypointTrigger_Object* Tools_Entity_DebugWaypointTrigger_Object::Create(bool bGenerateName)
{
	//get a name, and the position data
	Asura_Guid uGuid = Asura_Entity_System::GetNextToolsCreatedGuid();
	Tools_Entity_Data* pxToolsData = 0;
	if( bGenerateName )
	{
		pxToolsData = Tools_Entity_Object::CreateToolsDataWithDefaultName( "DebugWaypoint Trigger", "DebugWaypoint Trigger", uGuid, GetNamePrefix() );
	}
	else
	{
		pxToolsData = Tools_Entity_Object::CreateToolsData( "DebugWaypoint Trigger", 0, GetNamePrefix() );
	}
	if ( !pxToolsData ) return 0;

	//create the asura data
	Asura_ServerEntity_DebugWaypointTrigger* pxAsuraEntity = new Asura_ServerEntity_DebugWaypointTrigger();
	pxAsuraEntity->ToolsData = pxToolsData;

	//create the tools object
	Tools_Entity_DebugWaypointTrigger_Object* pxObject = new Tools_Entity_DebugWaypointTrigger_Object( pxAsuraEntity );
	Tools_SaveAsura::SetEntityModified();
	return pxObject;
}

void Tools_Entity_DebugWaypointTrigger_Object::AddOverlayControls( Asura_Overlay* pxNewOverlay, Asura_Vector_2& xOffset )
{
	Asura_Dialog* pxNewDialog;
	Asura_String_Dialog* pxStringDialog;

	Tools_Entity_Trigger_Object::AddOverlayControls( pxNewOverlay,xOffset );
	Asura_ServerEntity_DebugWaypointTrigger* pxAsuraEntity = (Asura_ServerEntity_DebugWaypointTrigger*) Entity;

	pxNewDialog = new Asura_SharedTickbox_Dialog("Use radius trigger", xOffset, &g_xParam_DebugWaypointTrigger_UseRadiusTrigger);
	pxNewDialog->SetHelpText("Only render if within trigger radius");
	pxNewOverlay->AddDialog( pxNewDialog );
	xOffset.x += 15.0f;

	pxNewDialog = new Asura_Numerical_Dialog("Trigger radius", xOffset, &g_xParam_DebugWaypointTrigger_TriggerRadius, 0.0f, 1000.0f, 0.5f, "%3.2f");
	pxNewDialog->SetHelpText("Radius to trigger messages. Also used to decide when to render the text if using the \"Use radius trigger\" or \"Use look-at test\" options.");
	pxNewOverlay->AddDialog( pxNewDialog );
	xOffset.y += Asura_Dialog::DefaultSpacing();
	//reset x
	xOffset.x -= 15.0f; 

	pxNewDialog = new Asura_SharedTickbox_Dialog("Use look-at test", xOffset, &g_xParam_DebugWaypointTrigger_UseLookAtTest);
	pxNewDialog->SetHelpText( "Only show the title and text when the player looks at the bounding sphere of the entity.");
	pxNewOverlay->AddDialog( pxNewDialog );
	xOffset.y += Asura_Dialog::DefaultSpacing();

	pxNewDialog = new Asura_SharedTickbox_Dialog("Use LOS occlusion", xOffset, &g_xParam_DebugWaypointTrigger_UseLOSOcclusion);
	pxNewDialog->SetHelpText( "Only show the title and text when the object is visible from the player's position (i.e. no render polys in-between).");
	pxNewOverlay->AddDialog( pxNewDialog );
	xOffset.y += Asura_Dialog::DefaultSpacing();

	Asura_Tabs_Dialog* pxTabsDialog = new Asura_Tabs_Dialog(xOffset,0,0);
	pxNewOverlay->AddDialog(pxTabsDialog);
	xOffset.y += Asura_Dialog::LargeSpacing();
	pxNewOverlay->SetCurrentParentDialog(pxTabsDialog);

	float fTabsStartY	= xOffset.y;
	float fTabsEndY		= xOffset.y;

	//Shape and anim tab
	pxTabsDialog->AddTab("Shape & Anim");

	pxNewDialog = new Asura_Function_Dialog("Select Skin & Anim",xOffset,ChooseSkin,(int)this);
	pxNewDialog->SetHelpText("Choose a skin and animation for this object");
	((Asura_Function_Dialog*)pxNewDialog)->SetUseSharedDialogColour(true);
	pxNewOverlay->AddDialog(pxNewDialog);
	xOffset.y+=Asura_Dialog::DefaultSpacing();

	pxNewDialog = new Asura_Function_Dialog("Select Anim",xOffset,ChooseAnim,(int)this);
	pxNewDialog->SetHelpText("Choose an animation for this object");
	((Asura_Function_Dialog*)pxNewDialog)->SetUseSharedDialogColour(true);
	pxNewOverlay->AddDialog(pxNewDialog);
	xOffset.y+=Asura_Dialog::DefaultSpacing();

	//_____ This shape selection is being phased out ____
	pxNewDialog = new Asura_Function_Dialog( "Select Shape (Deprecated!)", xOffset, ChooseShape, reinterpret_cast<int>(this));
	pxNewDialog->SetHelpText( "Choose shape for this object. NOTE: This is deprecated, please use skin instead" );
	((Asura_Function_Dialog*)pxNewDialog)->SetUseSharedDialogColour(true);
	pxNewOverlay->AddDialog( pxNewDialog );
	xOffset.y+=Asura_Dialog::DefaultSpacing();
	//___________________________________________________

	if(xOffset.y > fTabsEndY) 
	{
		fTabsEndY = xOffset.y;
	}

	//Text tab
	pxTabsDialog->AddTab("Text");
	xOffset.y = fTabsStartY;

	pxNewDialog = pxStringDialog = new Asura_String_Dialog( "Title Text", xOffset, &pxAsuraEntity->m_xTitleString, eASURA_DEBUGWAYPOINTTRIGGER_TEXTLEN , &Changed );
	pxNewDialog->SetHelpText( "The main text title which will be displayed for this trigger" );
	pxStringDialog->SetMaxStringLength( eASURA_DEBUGWAYPOINTTRIGGER_TEXTLEN - 1 );
	pxNewOverlay->AddDialog( pxNewDialog );
	xOffset.y += Asura_Dialog::DefaultSpacing();

	pxNewDialog = new Asura_SharedTickbox_Dialog("Always Show Title", xOffset, &g_xParam_DebugWaypointTrigger_AlwaysShowTitle);
	pxNewDialog->SetHelpText( "Show the Title regardless of line of sight & triggered considerations");
	pxNewOverlay->AddDialog( pxNewDialog );
	xOffset.y += Asura_Dialog::DefaultSpacing();

	pxNewDialog = pxStringDialog = new Asura_String_Dialog( "Line 1", xOffset, &pxAsuraEntity->m_xStringToDisplay[0], eASURA_DEBUGWAYPOINTTRIGGER_TEXTLEN , &Changed);
	pxStringDialog->SetMaxStringLength( eASURA_DEBUGWAYPOINTTRIGGER_TEXTLEN - 1 );
	pxNewOverlay->AddDialog( pxNewDialog );
	xOffset.y += Asura_Dialog::DefaultSpacing();
	pxNewDialog =pxStringDialog =  new Asura_String_Dialog( "Line 2", xOffset, &pxAsuraEntity->m_xStringToDisplay[1], eASURA_DEBUGWAYPOINTTRIGGER_TEXTLEN , &Changed);
	pxStringDialog->SetMaxStringLength( eASURA_DEBUGWAYPOINTTRIGGER_TEXTLEN - 1 );
	pxNewOverlay->AddDialog( pxNewDialog );
	xOffset.y += Asura_Dialog::DefaultSpacing();
	pxNewDialog = pxStringDialog = new Asura_String_Dialog( "Line 3", xOffset, &pxAsuraEntity->m_xStringToDisplay[2], eASURA_DEBUGWAYPOINTTRIGGER_TEXTLEN , &Changed);
	pxStringDialog->SetMaxStringLength( eASURA_DEBUGWAYPOINTTRIGGER_TEXTLEN - 1 );
	pxNewOverlay->AddDialog( pxNewDialog );
	xOffset.y += Asura_Dialog::DefaultSpacing();
	pxNewDialog = pxStringDialog = new Asura_String_Dialog( "Line 4", xOffset, &pxAsuraEntity->m_xStringToDisplay[3], eASURA_DEBUGWAYPOINTTRIGGER_TEXTLEN , &Changed);
	pxStringDialog->SetMaxStringLength( eASURA_DEBUGWAYPOINTTRIGGER_TEXTLEN - 1 );
	pxNewOverlay->AddDialog( pxNewDialog );
	xOffset.y += Asura_Dialog::DefaultSpacing();
	pxNewDialog = pxStringDialog = new Asura_String_Dialog( "Line 5", xOffset, &pxAsuraEntity->m_xStringToDisplay[4], eASURA_DEBUGWAYPOINTTRIGGER_TEXTLEN , &Changed);
	pxStringDialog->SetMaxStringLength( eASURA_DEBUGWAYPOINTTRIGGER_TEXTLEN - 1 );
	pxNewOverlay->AddDialog( pxNewDialog );
	xOffset.y += Asura_Dialog::DefaultSpacing();
	pxNewDialog = pxStringDialog = new Asura_String_Dialog( "Line 6", xOffset, &pxAsuraEntity->m_xStringToDisplay[5], eASURA_DEBUGWAYPOINTTRIGGER_TEXTLEN , &Changed);
	pxStringDialog->SetMaxStringLength( eASURA_DEBUGWAYPOINTTRIGGER_TEXTLEN - 1 );
	pxNewOverlay->AddDialog( pxNewDialog );
	xOffset.y += Asura_Dialog::DefaultSpacing();
	pxNewDialog = pxStringDialog = new Asura_String_Dialog( "Line 7", xOffset, &pxAsuraEntity->m_xStringToDisplay[6], eASURA_DEBUGWAYPOINTTRIGGER_TEXTLEN , &Changed);
	pxStringDialog->SetMaxStringLength( eASURA_DEBUGWAYPOINTTRIGGER_TEXTLEN - 1 );
	pxNewOverlay->AddDialog( pxNewDialog );
	xOffset.y += Asura_Dialog::DefaultSpacing();
	pxNewDialog = pxStringDialog = new Asura_String_Dialog( "Line 8", xOffset, &pxAsuraEntity->m_xStringToDisplay[7], eASURA_DEBUGWAYPOINTTRIGGER_TEXTLEN , &Changed);
	pxStringDialog->SetMaxStringLength( eASURA_DEBUGWAYPOINTTRIGGER_TEXTLEN - 1 );
	pxNewOverlay->AddDialog( pxNewDialog );
	xOffset.y += Asura_Dialog::DefaultSpacing();

	pxNewDialog = new Tools_ColourPicker_Dialog( "Text Colour", xOffset, Asura_Vector_2( 4.0f, 3.0f ), &g_xParam_DebugWaypointTrigger_Red, &g_xParam_DebugWaypointTrigger_Green, &g_xParam_DebugWaypointTrigger_Blue, 255.0f, NULL);
	pxNewOverlay->AddDialog( pxNewDialog );
	
	xOffset.x += 15.0f;
	pxNewDialog = new Asura_Numerical_Dialog( "Display Duration", xOffset, &g_xParam_DebugWaypointTrigger_TimeToDisplayText, -1.0f, 100.0f, 1.0f, "%.3f");
	pxNewDialog->SetHelpText("Duration of time to display text when triggered (-1 for indefinitely)");
	pxNewOverlay->AddDialog( pxNewDialog );
		
	if(xOffset.y > fTabsEndY) 
	{
		fTabsEndY = xOffset.y;
	}

	xOffset.y = fTabsEndY + 1.0f;
	pxNewOverlay->SetCurrentParentDialog(0);
	pxTabsDialog->SelectTab(0);

	static u_int s_uSelectedTab = 0;
	pxTabsDialog->SetSelectedTabPointer(&s_uSelectedTab);

}

bool Tools_Entity_DebugWaypointTrigger_Object::HandlesThisMessage( int iMessageID )
{
	if ( iMessageID == ASURA_MSG_RESET ) return true;
	return Tools_Entity_Trigger_Object::HandlesThisMessage( iMessageID );
}


void Tools_Entity_DebugWaypointTrigger_Object::PrintInfo( float& fX,float& fY )
{
	Tools_Entity_Trigger_Object::PrintInfo(fX,fY);
}

Tools_Object* Tools_Entity_DebugWaypointTrigger_Object::CreateObjectOfThisType() const
{
	return Create(true);	
}

void Tools_Entity_DebugWaypointTrigger_Object::Copy( const Tools_Object* pxObject )
{
	Tools_Entity_Trigger_Object::Copy( pxObject );

	const Tools_Entity_DebugWaypointTrigger_Object* pxFromObject = (const Tools_Entity_DebugWaypointTrigger_Object*) pxObject;

	Asura_ServerEntity_DebugWaypointTrigger* pxFromEntity = (Asura_ServerEntity_DebugWaypointTrigger*) pxFromObject->Entity;
	Asura_ServerEntity_DebugWaypointTrigger* pxToEntity = (Asura_ServerEntity_DebugWaypointTrigger*) Entity;

	Position = pxFromObject->Position;
	Orientation = pxFromObject->Orientation;

	for( int i = 0; i < 8; i++ )
	{
		pxToEntity->m_xStringToDisplay[i] = pxFromEntity->m_xStringToDisplay[i];
	}

	pxToEntity->m_xTitleString = pxFromEntity->m_xTitleString;
	pxToEntity->m_xClientData.m_fTimeToDisplayString = pxFromEntity->m_xClientData.m_fTimeToDisplayString;
	pxToEntity->m_xClientData.m_fR = pxFromEntity->m_xClientData.m_fR;
	pxToEntity->m_xClientData.m_fG = pxFromEntity->m_xClientData.m_fG;
	pxToEntity->m_xClientData.m_fB = pxFromEntity->m_xClientData.m_fB;
	pxToEntity->m_uChunkedFlags = pxFromEntity->m_uChunkedFlags;
	pxToEntity->m_xClientData.m_xOrientation = pxFromEntity->m_xClientData.m_xOrientation;
	pxToEntity->m_xClientData.m_xPosition = pxFromEntity->m_xClientData.m_xPosition;
	pxToEntity->m_xClientData.m_fTriggerRadius = pxFromEntity->m_xClientData.m_fTriggerRadius;
	pxToEntity->m_xClientData.m_uShapeID = pxFromEntity->m_xClientData.m_uShapeID;
	pxToEntity->m_xClientData.m_uAnimID = pxFromEntity->m_xClientData.m_uAnimID;


	//set the skin/shape in Tools_Object
	if(pxFromEntity->m_bSkin)
	{
		SetSkinAndAnim(pxFromEntity->m_xClientData.m_uShapeID, pxFromEntity->m_xClientData.m_uAnimID);
	}
	else if(pxObject->Mesh)
	{
		SetMesh(pxObject->Mesh);
	}

	if(pxFromEntity->m_bSkin)
	{
		SetInternalSkinAndAnim(pxFromEntity->m_xClientData.m_uShapeID, pxFromEntity->m_xClientData.m_uAnimID);
	}
	else
	{
		SetInternalShape(pxFromEntity->m_xClientData.m_uShapeID);
	}


}

extern void Render_Sphere( const Asura_Vector_3& xCentre, float fRadius, int iColour );
void Tools_Entity_DebugWaypointTrigger_Object::Render()
{
	Tools_Entity_Trigger_Object::Render();

	if ( ( RenderAsSelected() ) && ( Entity ) )
	{
		Render_Sphere( this->Position, static_cast<Asura_ServerEntity_DebugWaypointTrigger*>(Entity)->GetTriggerRadius(), 0xff006000 );
	}
}

bool Tools_Entity_DebugWaypointTrigger_Object::GetParameter(Asura_Hash_ID uParamID,class Tools_Parameter* pxParam) const
{
	Asura_ServerEntity_DebugWaypointTrigger* pxAsuraEntity = (Asura_ServerEntity_DebugWaypointTrigger*) Entity;

	switch(uParamID)
	{
		case g_uHash_DebugWaypointTrigger_AlwaysShowTitle :
			pxParam->SetBool(pxAsuraEntity->m_bAlwaysShowTitle);
			break;

		case g_uHash_DebugWaypointTrigger_UseLookAtTest :
			pxParam->SetBool(pxAsuraEntity->m_bUseLookAtTest);
			break;

		case g_uHash_DebugWaypointTrigger_UseLOSOcclusion :
			pxParam->SetBool(pxAsuraEntity->m_bUseLOSOcclusion);
			break;

		case g_uHash_DebugWaypointTrigger_TimeToDisplayText :
			pxParam->SetFloat(pxAsuraEntity->m_xClientData.m_fTimeToDisplayString);
			break;

		case g_uHash_DebugWaypointTrigger_UseRadiusTrigger :
			pxParam->SetBool(pxAsuraEntity->m_bUseRadiusTriggering);
			break;

		case g_uHash_DebugWaypointTrigger_TriggerRadius :
			pxParam->SetFloat(pxAsuraEntity->m_xClientData.m_fTriggerRadius);
			break;

		case g_uHash_DebugWaypointTrigger_Red :
			pxParam->SetFloat(pxAsuraEntity->m_xClientData.m_fR);
			break;

		case g_uHash_DebugWaypointTrigger_Green :
			pxParam->SetFloat(pxAsuraEntity->m_xClientData.m_fG);
			break;

		case g_uHash_DebugWaypointTrigger_Blue :
			pxParam->SetFloat(pxAsuraEntity->m_xClientData.m_fB);
			break;

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

bool Tools_Entity_DebugWaypointTrigger_Object::SetParameter(Asura_Hash_ID uParamID,const class Tools_Parameter* pxParam)
{
	Asura_ServerEntity_DebugWaypointTrigger* pxAsuraEntity = (Asura_ServerEntity_DebugWaypointTrigger*) Entity;

	switch(uParamID)
	{
		case g_uHash_DebugWaypointTrigger_AlwaysShowTitle :
			pxAsuraEntity->m_bAlwaysShowTitle = pxParam->GetBool();
			break;

		case g_uHash_DebugWaypointTrigger_UseLookAtTest :
			pxAsuraEntity->m_bUseLookAtTest = pxParam->GetBool();
			break;

		case g_uHash_DebugWaypointTrigger_UseLOSOcclusion :
			pxAsuraEntity->m_bUseLOSOcclusion = pxParam->GetBool();
			break;

		case g_uHash_DebugWaypointTrigger_TimeToDisplayText :
			pxAsuraEntity->m_xClientData.m_fTimeToDisplayString = pxParam->GetFloat();
			break;

		case g_uHash_DebugWaypointTrigger_UseRadiusTrigger :
			pxAsuraEntity->m_bUseRadiusTriggering = pxParam->GetBool();
			break;

		case g_uHash_DebugWaypointTrigger_TriggerRadius :
			pxAsuraEntity->m_xClientData.m_fTriggerRadius = pxParam->GetFloat();
			break;

		case g_uHash_DebugWaypointTrigger_Red :
			pxAsuraEntity->m_xClientData.m_fR = pxParam->GetFloat();
			break;

		case g_uHash_DebugWaypointTrigger_Green :
			pxAsuraEntity->m_xClientData.m_fG = pxParam->GetFloat();
			break;

		case g_uHash_DebugWaypointTrigger_Blue :
			pxAsuraEntity->m_xClientData.m_fB = pxParam->GetFloat();
			break;

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

	return true;
}


void Tools_Entity_DebugWaypointTrigger_Object::ChooseSkin()
{
	Asura_Hierarchy_Skin* pxSkin = 0;
	Asura_Hierarchy_Anim* pxAnim = 0;

	//Choose a skin and animation
	if(!Tools_Animation_Files::ChooseSkin((const Asura_Hierarchy_Skin**)&pxSkin)) return;	 
	Tools_Animation_Files::ChooseAnimation(pxSkin,(const Asura_Hierarchy_Anim**)&pxAnim); //Don't care if they don't want to use an anim, can happily use ASURA_HASH_ID_UNSET

	//Apply to each selected object
	List<Tools_Object*> xObjectList;
	Tools_Object_System::ListSelectedObjectsOfType(TOT_Entity_DebugWaypointTrigger, xObjectList);
	for(LIF<Tools_Object*> xObjectLIF(&xObjectList); !xObjectLIF.done(); xObjectLIF.next())
	{
		Tools_Entity_DebugWaypointTrigger_Object* pxObject = (Tools_Entity_DebugWaypointTrigger_Object*) xObjectLIF();

		const Asura_Hash_ID uSkinID = pxSkin ? pxSkin->GetHashID() : ASURA_HASH_ID_UNSET;
		const Asura_Hash_ID uAnimID = pxAnim ? pxAnim->GetHashID() : ASURA_HASH_ID_UNSET;

		pxObject->SetSkinAndAnim(pxSkin,pxAnim);	
		pxObject->SetInternalSkinAndAnim(uSkinID,uAnimID);
		pxObject->SetEntityModified();
	}
}

void Tools_Entity_DebugWaypointTrigger_Object::ChooseAnim()
{
	if(!GetAnimation())
	{
		//have to choose a skin as well
		ChooseSkin();
		return;
	}

	Asura_Hierarchy_Anim* pxAnim = 0;

	if(!Tools_Animation_Files::ChooseAnimation(GetAnimation()->GetSkin(),(const Asura_Hierarchy_Anim**)&pxAnim)) return;

	//Apply to each selected object
	List<Tools_Object*> xObjectList;
	Tools_Object_System::ListSelectedObjectsOfType(TOT_Entity_DebugWaypointTrigger, xObjectList);
	for(LIF<Tools_Object*> xObjectLIF(&xObjectList); !xObjectLIF.done(); xObjectLIF.next())
	{
		Tools_Entity_DebugWaypointTrigger_Object* pxObject = (Tools_Entity_DebugWaypointTrigger_Object*) xObjectLIF();

		//only apply the animation to objects that have get a skin/anim already
		if(pxObject->GetAnimation())
		{
			pxObject->SetAnim(pxAnim);
			pxObject->SetInternalSkinAndAnim(pxObject->m_uShapeID,pxAnim->GetHashID());
			pxObject->SetEntityModified();
		}
	}

}

void Tools_Entity_DebugWaypointTrigger_Object::ChooseShape()
{
	Asura_Hash_ID uShapeID = Tools_ShapeTable::SelectShape(m_uShapeID);

	static_cast<Asura_ServerEntity_DebugWaypointTrigger*>(Entity)->SetShape( uShapeID );

	if(uShapeID == ASURA_HASH_ID_UNSET) return;

	//try to get the Asura_Mesh for the shape selected
	const char* pszMeshName = Tools_ShapeTable::LookupObjectMeshName(uShapeID);
	if(!pszMeshName)
	{
		ShowMessageOverlay("Failed to get mesh name of selected shape.");
		return;
	}

	Asura_Mesh* pxMesh = Asura_Mesh_System::GetMesh(pszMeshName);
	if(!pxMesh)
	{
		ShowMessageOverlay("failed to get mesh for selected shape.");
		return;
	}

	//okay , we have the shape so use it		
	//Apply to each selected object
	List<Tools_Object*> xObjectList;
	Tools_Object_System::ListSelectedObjectsOfType(TOT_Entity_DebugWaypointTrigger, xObjectList);
	for(LIF<Tools_Object*> xObjectLIF(&xObjectList); !xObjectLIF.done(); xObjectLIF.next())
	{
		Tools_Entity_DebugWaypointTrigger_Object* pxObject = (Tools_Entity_DebugWaypointTrigger_Object*) xObjectLIF();

		pxObject->SetMesh(pxMesh);
		pxObject->SetInternalShape(uShapeID);
		pxObject->SetEntityModified();
	}
}

void Tools_Entity_DebugWaypointTrigger_Object::ClearInternalShapeAndAnim()
{
	m_uShapeID = ASURA_HASH_ID_UNSET;
	m_uAnimID  = ASURA_HASH_ID_UNSET;	
	m_bSkin = false;
	UpdateServerEntitySkinAnim();
}

void Tools_Entity_DebugWaypointTrigger_Object::SetInternalSkinAndAnim(u_int uInternalSkin, u_int uInternalAnim)
{
	m_uShapeID = uInternalSkin;
	m_uAnimID  = uInternalAnim;
	m_bSkin = true;	
	UpdateServerEntitySkinAnim();
}

void Tools_Entity_DebugWaypointTrigger_Object::SetInternalShape(u_int uInternalShape)
{
	m_uShapeID = uInternalShape;
	m_uAnimID  = 0;
	m_bSkin = false;	
	UpdateServerEntitySkinAnim();
}


void Tools_Entity_DebugWaypointTrigger_Object::UpdateServerEntitySkinAnim()
{
	//Update the server entity
	if(m_bSkin)
	{
		static_cast<Asura_ServerEntity_DebugWaypointTrigger*>(Entity)->SetSkin(m_uShapeID);
		static_cast<Asura_ServerEntity_DebugWaypointTrigger*>(Entity)->SetAnim(m_uAnimID);
	}
	else
	{
		static_cast<Asura_ServerEntity_DebugWaypointTrigger*>(Entity)->SetShape(m_uShapeID);
	}
}

void Tools_Entity_DebugWaypointTrigger_Object::AddFilesToExportList(List<Asura_String>& xNameList) const
{
	if (Entity && m_uShapeID && m_bSkin)
	{
		//Shape table is automatically exported, we just need to handle skin/anim
		Tools_Level_Export::AddSkinToExportList(m_uShapeID);
		if(m_uAnimID)
		{
			Tools_Level_Export::AddAnimToExportList(m_uAnimID);
		}
	}
	PARENT::AddFilesToExportList(xNameList);
}


void Tools_Entity_DebugWaypointTrigger_Object::UpdatePositionInAsuraData(bool bUpdateLinkedObjects)
{
	Asura_ServerEntity_DebugWaypointTrigger* pxAsuraEntity = static_cast<Asura_ServerEntity_DebugWaypointTrigger*>( Entity );
	pxAsuraEntity->m_xClientData.m_xPosition = Position;
	pxAsuraEntity->m_xClientData.m_xOrientation = Orientation;
	

	PARENT::UpdatePositionInAsuraData(bUpdateLinkedObjects);
}

#endif // #ifdef ASURA_USE_DEBUG_MESSAGE_TRIGGER

//eof
