//////////////////////////////////////////////////////////////////////////////
//
// Tools_Object_GamesceneSplinePoint.cpp
//
// Created by NJD - 16 October 2006
//
// Copyright (C) 2006 Rebellion, All Rights Reserved.
//
//////////////////////////////////////////////////////////////////////////////

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

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

#ifdef ASURA_USE_AXON

// header
#include "Entity/Locations/Spline/GamesceneSpline/Tools_Object_GamesceneSplinePoint.h"

// asura
#include "Entity/Locations/OrientedNode/GamesceneNode/Asura_ServerNode_GS2Node.h"
#include "Entity/Locations/Spline/GamesceneSpline/Asura_ServerNode_GS2Spline.h"
#include "Mesh/Asura_Mesh.h"

// tools
#include "Entity/Locations/Spline/GamesceneSpline/Tools_EntityNode_GS2Spline.h"

//////////////////////////////////////////////////////////////////////////////
//
// Tools_Object_GS2Point
//
//////////////////////////////////////////////////////////////////////////////

Tools_Object_GS2Point* Tools_Object_GS2Point::s_pxThisGamesceneSplinePoint = NULL;

Tools_Object_GS2Point::Tools_Object_GS2Point(
	Asura_ServerNode_GS2Spline* pxParentNode,
	Tools_EntityNode_GS2Spline* pxParentTools,
	int iIndex,
	bool bIsEndPoint)
: PARENT(pxParentNode, pxParentTools, iIndex, bIsEndPoint)
{
	Type = TOT_Entity_GS2SplinePoint;

	m_pxGSParentNode  = pxParentNode;
	m_pxGSParentTools = pxParentTools;
	m_pxGSParentNode->GetPointOrientation(m_iIndex - 1).ToMatrix(Orientation);
	if (m_pxGSParentNode->ShouldUsePointOrientation())
	{
		SetMesh( "ToolsShape_CutsceneTrackPoint" );
	}
	else
	{
		SetMesh( "ToolsShape_SplineNode" );
	}
}

void Tools_Object_GS2Point::UpdatePositionInAsuraData(bool /*updateLinkedObjects*/)
{
	Asura_Quat xQuatOri;
	xQuatOri.FromMatrix(Orientation);
	// Note that the control points do not have an orientation, so there are NumPoints-2 orientations,
	// hence the m_iIndex-1 in all of the point orientation code.
	m_pxGSParentNode->SetPointOrientation(m_iIndex - 1, xQuatOri);

	PARENT::UpdatePositionInAsuraData(true);
}

void Tools_Object_GS2Point::UpdatePositionFromAsuraData()
{
	m_pxGSParentNode->GetPointOrientation(m_iIndex - 1).ToMatrix(Orientation);

	PARENT::UpdatePositionFromAsuraData();
}

void Tools_Object_GS2Point::OnDeselection()
{
	s_pxThisGamesceneSplinePoint = NULL;
	PARENT::OnDeselection();
}

void Tools_Object_GS2Point::OnSelection()
{
	PARENT::OnSelection();
	s_pxThisGamesceneSplinePoint = this;
}

void Tools_Object_GS2Point::Render()
{
	if ( m_pxGSParentNode->ShouldUsePointOrientation() )
	{
		if ( !Mesh || strcmp( Mesh->Name.GetString(), "ToolsShape_CutsceneTrackPoint" ) != 0 )
		{
			SetMesh( "ToolsShape_CutsceneTrackPoint" );
		}
	}
	else
	{
		if ( !Mesh || strcmp( Mesh->Name.GetString(), "ToolsShape_SplineNode" ) != 0 )
		{
			SetMesh( "ToolsShape_SplineNode" );
		}
	}

	PARENT::Render();
}

void Tools_Object_GS2Point::Update()
{
	PARENT::Update();

	if ( m_pxGSParentNode->ShouldUsePointOrientation() )
	{
		// If we're an end point we must make sure we orientate with the corresponding node.
		if ( m_bIsEndPoint )
		{
			const Asura_Guid uGuidWeMustRemainWith = (m_iIndex == 1) ? m_pxGSParentNode->GetSourceGuid() : m_pxGSParentNode->GetTargetGuid();
			Asura_ServerNode_GS2Node* pxNode = Asura_ServerNode_GS2Node::FindEntity( uGuidWeMustRemainWith );
			if ( pxNode )
			{
				Asura_Quat xNodeOrientQ;
				pxNode->GetOrientation( xNodeOrientQ );
				if ( !m_pxGSParentNode->GetPointOrientation( m_iIndex - 1 ).ApproximatelyEquals( xNodeOrientQ ) )
				{
					xNodeOrientQ.ToMatrix( Orientation );
					UpdatePositionInAsuraData( true );
				}
			}
		}
	}
}

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

#endif // ASURA_USE_AXON
