//
// Tools_InterZoneWaypointObject.cpp
//
// Created by Richard Rice - 25/04/2006
// 
// Copyright (C) 2006 Rebellion, All Rights Reserved.
//

#include "Core/Asura.h"
#include "Waypointing/Tools_InterZoneWaypointObject.h"

#ifdef ASURA_USE_STREAMING

//asura
#include "AI/Asura_AI_Navigation.h"
#include "Camera/Asura_Camera.h"
#include "Mesh/Asura_Mesh_System.h"
#include "Rendering/Asura_Render.h"
//tools
#include "Load&Save/Tools_SaveAsura.h"
#include "Misc/Tools_Timed_Messages.h"
#include "Objects/Tools_Object_System.h"



List<Tools_InterZoneWaypointObject*> Tools_InterZoneWaypointObject::s_xObjectList;

Tools_InterZoneWaypointObject::Tools_InterZoneWaypointObject()
:Tools_Object(TOT_InterZoneWaypoint)
{
	m_pxPairedObject = 0;
	m_uIndex = 0xffffffff;
	m_bPlacing = false;
	s_xObjectList.add_entry(this);
}

Tools_InterZoneWaypointObject::~Tools_InterZoneWaypointObject()
{
	s_xObjectList.delete_entry(this);
}

void Tools_InterZoneWaypointObject::Initialise(u_int uIndex,Tools_InterZoneWaypointObject* pxOtherObject,bool bFirstWaypoint)
{
	m_uIndex = uIndex;
	m_pxPairedObject = pxOtherObject;
	m_bFirstWaypoint = bFirstWaypoint;

	//get initial position from nav system
	const Tools_AI_InterZoneWaypointPair& xPair = Asura_AI_Navigation_System::GetInterZoneWaypointPair(uIndex);
	Position = m_bFirstWaypoint ? xPair.m_xThisZonePosition : xPair.m_xOtherZonePosition;

	//pick mesh depending on which half of the pair this is
	const char* pszMeshName = m_bFirstWaypoint ? "ToolsShape_CutsceneTrackPoint" : "ToolsShape_Particle";
	Asura_Mesh* pxMesh = Asura_Mesh_System::GetMesh(pszMeshName);
	if(pxMesh) SetMesh(pxMesh);

	//generate a name
	char szTemp[100];
	Asura_PrintfToBfr(szTemp,"Waypoint %d %s",sizeof(szTemp),true,m_uIndex,m_bFirstWaypoint ? "(This Zone)" : "(Other Zone)");
	m_xName = szTemp;

}


void Tools_InterZoneWaypointObject::CreateAll()
{
	for(u_int i=0;i<Asura_AI_Navigation_System::GetNumInterZoneWaypointPairs();i++)
	{
		Tools_InterZoneWaypointObject* pxObject1 = new Tools_InterZoneWaypointObject;
		Tools_InterZoneWaypointObject* pxObject2 = new Tools_InterZoneWaypointObject;

		pxObject1->Initialise(i,pxObject2,true);
		pxObject2->Initialise(i,pxObject1,false);
	}
}

void Tools_InterZoneWaypointObject::CreateNew()
{
	//create a new default pair , and add to nav system
	Tools_AI_InterZoneWaypointPair xPair;
	xPair.m_xThisZonePosition = *Asura_Camera::GetPosition();
	xPair.m_xOtherZonePosition = *Asura_Camera::GetPosition();

	Asura_AI_Navigation_System::AddInterZoneWaypointPair(xPair);

	//create tools objects for this
	u_int uIndex = Asura_AI_Navigation_System::GetNumInterZoneWaypointPairs()-1;

	Tools_InterZoneWaypointObject* pxObject1 = new Tools_InterZoneWaypointObject;
	Tools_InterZoneWaypointObject* pxObject2 = new Tools_InterZoneWaypointObject;

	pxObject1->Initialise(uIndex,pxObject2,true);
	pxObject2->Initialise(uIndex,pxObject1,false);

	//Select and start placing first object
	pxObject1->StartPlacement();


	Tools_SaveAsura::SetWaypointingModified();
}


void Tools_InterZoneWaypointObject::DeleteAll()
{
	while(s_xObjectList.size())
	{
		Tools_Object_System::DeleteObject(s_xObjectList.first_entry());
	}
}

void Tools_InterZoneWaypointObject::Destroy()
{
	u_int uIndexToDelete = m_uIndex;

	//delete paired object as well
	Tools_Object_System::DeleteObject(m_pxPairedObject);
	Tools_Object::Destroy();

	//delete from nav system
	Asura_AI_Navigation_System::DeleteInterZoneWaypointPair(uIndexToDelete);

	//Change the index of the objects of the last waypoint pair
	u_int uWaypointToReindex = Asura_AI_Navigation_System::GetNumInterZoneWaypointPairs();

	for(LIF<Tools_InterZoneWaypointObject*> xObjectLIF(&s_xObjectList);!xObjectLIF.done();xObjectLIF.next())
	{
		Tools_InterZoneWaypointObject* pxObject = xObjectLIF();
		if(pxObject->m_uIndex != uWaypointToReindex) continue;

		//reinitialise this object to change the index
		pxObject->Initialise(uIndexToDelete,pxObject->m_pxPairedObject,pxObject->m_bFirstWaypoint);
	}

	Tools_SaveAsura::SetWaypointingModified();
}


void Tools_InterZoneWaypointObject::UpdatePositionInAsuraData(bool /*bUpdateLinkedObjects*/)
{
	Tools_AI_InterZoneWaypointPair xPair = Asura_AI_Navigation_System::GetInterZoneWaypointPair(m_uIndex);
	if(m_bFirstWaypoint)
	{
		xPair.m_xThisZonePosition = Position;
	}
	else
	{
		xPair.m_xOtherZonePosition = Position;
	}
	Asura_AI_Navigation_System::SetInterZoneWaypointPair(m_uIndex,xPair);

	Tools_SaveAsura::SetWaypointingModified();
}	

void Tools_InterZoneWaypointObject::OnDeselection()
{
	//abort object placement
	m_bPlacing = false;
}

void Tools_InterZoneWaypointObject::UpdateWhileSelected()
{
	if(m_bPlacing && !Tools_Object_System::IsDoingSnapToVertex())
	{
		if(m_bFirstWaypoint)
		{
			//finished placing first waypoint , so move on to the second
			m_pxPairedObject->StartPlacement();
		}
		m_bPlacing = false;
	}
}

void Tools_InterZoneWaypointObject::StartPlacement()
{
	Tools_Object_System::SelectObject(this);

	m_bPlacing = true;
	Tools_Object_System::StartSnapToVertex();
	Tools_Timed_Message_System::AddMessage( 0xffffffff, "Place waypoint for %s zone", m_bFirstWaypoint ? "this" : "other" );
}

void Tools_InterZoneWaypointObject::Render()
{
	Tools_Object::Render();

	if(IsGroupSelected())
	{
		//draw line to paired object
		Asura_Vector_3 xStart = Position;
		Asura_Vector_3 xEnd = m_pxPairedObject->Position;
		xStart.y -= 0.1f;//raise line slightly to make more visible
		xEnd.y -= 0.1f;
		Asura_Render::RenderLine(xStart,xEnd,0xffffffff);
	}
}

#endif // ASURA_USE_STREAMING