//////////////////////////////////////////////////////////////////////////////
//
// ToolsAVP_Node_GS2Node.cpp
//
// Copyright (C) 2008 Rebellion. All Rights Reserved.
//
//////////////////////////////////////////////////////////////////////////////

// I N C L U D E S ///////////////////////////////////////////////////////////

// core
#include "Core/Asura.h"

// header
#include "Entity/Locations/OrientedNode/GamesceneNode/ToolsAVP_Node_GS2Node.h"

// asura
#include "AI/Asura_AI_Navigation.h"
#include "Rendering/Asura_Text_Output.h"

// axon
#include "Behaviour/BehaviourTypes/Axon_Behaviour_Types.h"

// avp
#include "Behaviour/AVP_BehaviourParams.h"
#include "Entity/Locations/OrientedNode/GamesceneNode/AVP_ServerNode_GS2Node.h"

// tools
#include "Entity/Locations/OrientedNode/GamesceneNode/ToolsAVP_Node_GS2Node.h"
#include "Entity/Locations/Spline/GamesceneSpline/ToolsAVP_Node_GS2Spline.h"
#include "Load&Save/Tools_SaveAsura.h"
#include "Misc/Tools_Timed_Messages.h"
#include "Objects/ToolsAVP_Object_Type.h"
#include "Objects/Axon/Tools_Object_Axon_Interface.h"

#include "Entity/AVP_Messages.h"

//////////////////////////////////////////////////////////////////////////////
//
// ToolsAVP_Node_GS2Node
//
//////////////////////////////////////////////////////////////////////////////

TOOLS_DECLARE_SHARED_PARAM( bool,         0x09afca68, AVPGS2Node_IntegrateWithNavData );	// Asura_GetHashID( "AVPGS2Node_IntegrateWithNavData" )
TOOLS_DECLARE_SHARED_PARAM( bool,         0x83af21ec, AVPGS2Node_LeaveOnThreatInfo );		// Asura_GetHashID( "AVPGS2Node_LeaveOnThreatInfo" )

Asura_Hashed_List< ToolsAVP_Node_GS2Node > ToolsAVP_Node_GS2Node::s_xList;

ToolsAVP_Node_GS2Node::ToolsAVP_Node_GS2Node( Asura_Entity* pxEntity )
: PARENT( pxEntity )
{
	Type = TOT_Entity_AVPGS2Node;
	s_xList.AddToList( this );
}

ToolsAVP_Node_GS2Node::~ToolsAVP_Node_GS2Node()
{
	s_xList.RemoveFromList( this );
}

bool ToolsAVP_Node_GS2Node::IsBaseOrDerivativeOf( int iToolsObjectType ) const
{
	if ( iToolsObjectType == TOT_Entity_AVPGS2Node )
	{
		return true;
	}
	else
	{
		return PARENT::IsBaseOrDerivativeOf( iToolsObjectType );
	}
}

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

	PARENT::Render();

	const AVP_ServerNode_GS2Node* pxGameNode = GetAVPGameNode();
	if ( IsSelected() && pxGameNode->ShouldIntegrateWithNavData() )
	{
		if ( pxGameNode->GetWaypointID() < Asura_AI_Navigation_System::GetNumberOfWaypoints() )
		{
			const Asura_AI_NavVertex* pxWP = Asura_AI_Navigation_System::GetWaypoint( pxGameNode->GetWaypointID() );
			if ( pxWP )
			{
				Render_Sphere( pxWP->m_xPosition, pxWP->GetRadius(), 0xff0000ff );
			}
		}
	}
}

void ToolsAVP_Node_GS2Node::PrintInfo( float& fX, float& fY )
{
	PARENT::PrintInfo( fX, fY );

	if ( GetAVPGameNode()->ShouldIntegrateWithNavData() )
	{
		Asura_Text_Output::Print( fX, fY++, 0xffffffff, 0, "Associated Waypoint ID : %u", GetAVPGameNode()->GetWaypointID() );
	}
}

bool ToolsAVP_Node_GS2Node::HandlesThisMessage( int iMessageID )
{
	if ( iMessageID == AVP_MSGID_DEACTIVATE_OCCUPIER ||
		iMessageID == AVP_MSGID_DESTROY_OCCUPIER ||
		iMessageID == AVP_MSGID_SET_HEALTH )
	{
		return true;
	}
	else
	{
		return PARENT::HandlesThisMessage( iMessageID );
	}
}

void ToolsAVP_Node_GS2Node::Copy( const Tools_Object* pxObject )
{
	// Copy parent data.
	PARENT::Copy( pxObject );

	// Copy our data.
	const ToolsAVP_Node_GS2Node* pxFromObject = ToolsAVP_Node_GS2Node::FindEntity( pxObject->GetGuid() );
	// No extra data.

	// Copy the engine entity's data across.
	AVP_ServerNode_GS2Node* pxToEntity			= AVP_ServerNode_GS2Node::FindEntity( Entity->GetGuid() );
	AVP_ServerNode_GS2Node* pxFromEntity		= AVP_ServerNode_GS2Node::FindEntity( pxFromObject->Entity->GetGuid() );
	pxToEntity->m_bIntegrateWithNavData			= pxFromEntity->m_bIntegrateWithNavData;
	pxToEntity->m_bLeaveGamesceneOnKnowledge	= pxFromEntity->m_bLeaveGamesceneOnKnowledge;
}

Tools_Object* ToolsAVP_Node_GS2Node::CreateObjectOfThisType() const
{
	return CreateAndReturn();
}

void ToolsAVP_Node_GS2Node::Create()
{
	CreateAndReturn();
}

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

ToolsAVP_Node_GS2Node* ToolsAVP_Node_GS2Node::CreateAndReturn()
{
	// Get a new GUID
	const Asura_Guid uGuid = Asura_Entity_System::GetCreatedByToolsGuid();

	// Set up tools data and auto-create a unique name (prompt for new name if there is a clash).
	Tools_Entity_Data* pxToolsData = CreateToolsDataWithDefaultName( "AVP GS2 Node", "AVP GS2 Node", uGuid );
	if ( !pxToolsData ) { return NULL; }

	// Create the game specfic server object and set its data.
	AVP_ServerNode_GS2Node* pxGameNode = new AVP_ServerNode_GS2Node( uGuid );
	if ( !pxGameNode ) { return NULL; }

	pxGameNode->ToolsData = pxToolsData;

	// Create the game specific tools object and select it.
	ToolsAVP_Node_GS2Node* pxToolsNode = new ToolsAVP_Node_GS2Node( pxGameNode );
	if ( !pxToolsNode ) { return NULL; }

	// Set everything to the default values.
	pxToolsNode->SetThisToDefaults();

	Tools_Object_System::SelectObject( pxToolsNode );

	pxToolsNode->Position = *Asura_Camera::GetPosition();
	// Set the orient to the camera heading but vertical.
	Asura_Euler_3 xHeading = *Asura_Camera::GetOriEuler();
	xHeading.x = xHeading.z = 0.0f;
	xHeading.ToMatrix( pxToolsNode->Orientation );

	pxGameNode->SetPosition( pxToolsNode->Position );
	pxGameNode->SetOrientation( pxToolsNode->Orientation );

	Tools_Timed_Message_System::AddMessage( Tools_Timed_Message_System::COLOUR_DEFAULT, "Created new AVP GS2 node." );
	Tools_SaveAsura::SetEntityModified();

	return pxToolsNode;
}

void ToolsAVP_Node_GS2Node::AddPropertiesTabControls( Asura_Tabs_Dialog* pxTabsDialogue, Asura_Vector_2& xOffset )
{
	AddStructureTypeDialogue( pxTabsDialogue, xOffset );
	AddSmoothOverNodeOverlayControls( pxTabsDialogue, xOffset );
	AddFollowSurfaceDialogue( pxTabsDialogue, xOffset );
	AddCollisionsDialogues( pxTabsDialogue, xOffset );

	Asura_Dialog* pxNewDialog = new Asura_SharedTickbox_Dialog( "Integrate With Nav Data", xOffset, &g_xParam_AVPGS2Node_IntegrateWithNavData );
	pxNewDialog->SetHelpText( "Determines whether this node should integrate into the navigation data." );
	pxTabsDialogue->AddDialog( pxNewDialog );
	xOffset.y += Asura_Dialog::DefaultSpacing();

	if ( !GetAVPGameNode()->GetBehaviourParams() || GetAVPGameNode()->GetBehaviourParams()->GetParamsType() != AVP_BP_TYPE_MARINE_COMBAT )
	{
		pxNewDialog = new Asura_SharedTickbox_Dialog( "Leave Gamescene on Threat Information", xOffset, &g_xParam_AVPGS2Node_LeaveOnThreatInfo );
		pxNewDialog->SetHelpText( "If the actor gains threat or alert knowledge and this is selected the actor will leave gamescene." );
		pxTabsDialogue->AddDialog( pxNewDialog );
		xOffset.y += Asura_Dialog::DefaultSpacing();
	}

	xOffset.y += Asura_Dialog::LargeSpacing() - Asura_Dialog::DefaultSpacing();
	AddLinkWeightsDialogue( pxTabsDialogue, xOffset );
}

void ToolsAVP_Node_GS2Node::AddUnderTabsControls( Asura_Overlay* pxNewOverlay, Asura_Vector_2& xOffset )
{
	AddLinkControls( pxNewOverlay, xOffset );
	xOffset.y += Asura_Dialog::LargeSpacing() - Asura_Dialog::DefaultSpacing();

	AddMainDefaultsOverlayControls( pxNewOverlay, xOffset );
	Tools_Object_Axon_Interface::AddPreviewControls( pxNewOverlay, xOffset );
}

AVP_ServerNode_GS2Node* ToolsAVP_Node_GS2Node::GetAVPGameNode() const
{
	return AVP_ServerNode_GS2Node::FindEntity( GetGuid() );
}

bool ToolsAVP_Node_GS2Node::GetParameter( Asura_Hash_ID uParamID, Tools_Parameter* pxParam ) const
{
	switch ( uParamID )
	{
		case g_uHash_AVPGS2Node_IntegrateWithNavData:
		{
			pxParam->SetBool( GetAVPGameNode()->m_bIntegrateWithNavData );
			return true;
		}

		case g_uHash_AVPGS2Node_LeaveOnThreatInfo:
		{
			pxParam->SetBool( GetAVPGameNode()->m_bLeaveGamesceneOnKnowledge );
			return true;
		}

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

bool ToolsAVP_Node_GS2Node::SetParameter( Asura_Hash_ID uParamID, const Tools_Parameter* pxParam )
{
	switch ( uParamID )
	{
		case g_uHash_AVPGS2Node_IntegrateWithNavData:
		{
			GetAVPGameNode()->m_bIntegrateWithNavData = pxParam->GetBool();
			Tools_SaveAsura::SetEntityModified();
			return true;
		}

		case g_uHash_AVPGS2Node_LeaveOnThreatInfo:
		{
			GetAVPGameNode()->m_bLeaveGamesceneOnKnowledge = pxParam->GetBool();
			Tools_SaveAsura::SetEntityModified();
			return true;
		}

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

//////////////////////////////////////////////////////////////////////////////
//
// 
//
//////////////////////////////////////////////////////////////////////////////
