#include "Core/Asura.h"
#include "Debugging/Asura_Assert.h"

#include "ChunkSystem/Asura_Chunk_StartPosition.h"
#include "Mesh/Asura_Env_System.h"
#include "Mesh/Asura_Env.h"
#include "Mesh/Asura_Mesh_System.h"
#include "Camera/Asura_Camera.h"
#include "Interface/Asura_Overlay_System.h"
#include "Interface/Asura_Overlay.h"
#include "Interface/Asura_Dialog.h"

#include "Load&Save/Tools_SaveAsura.h"
#include "Objects/Tools_StartPosition_Object.h"
#include "Objects/Tools_Object_System.h"
#include "Misc/Tools_Timed_Messages.h"
#include "Tools_Overlays.h"

Tools_StartPosition_Object* Tools_StartPosition_Object::s_pxThisStartPos = 0;
Asura_Vector_2				Tools_StartPosition_Object::s_xOverlayPosition;

Tools_StartPosition_Object::Tools_StartPosition_Object(int index)
:Tools_Object(TOT_StartPosition)
{
	Index = index;
	m_bChanged = true;
	UpdatePositionFromAsuraData();

	//generate the name
	char buffer[30];
#ifdef ASURA_USE_BOTH_START_POSITION_TYPES
	sprintf(buffer,"Start Pos (multiplayer) %d",index);
#else
	sprintf(buffer,"Start Position %d",index);
#endif
	Name = buffer;

	Asura_String mesh_name = "ToolsShape_CutsceneActor";
	Mesh = Asura_Mesh_System::GetMesh(mesh_name);

}


void Tools_StartPosition_Object::CreateAllObjects()
{
	//create all the tools objects from the asura data
	Asura_Environment* env = Asura_Environment_System::GetEnvironment();
	if(!env) return;

	for(int i=0;i<env->NumberOfStartPositions;i++)
	{
		Project_CreateStartPositionObject(i);
	}
}

void Tools_StartPosition_Object::UpdatePositionFromAsuraData()
{
	Asura_Environment* env = Asura_Environment_System::GetEnvironment();
	Asura_Assert(env,"");

	Position = env->GetStartPosition(Index);
	Orientation = env->GetStartOrientation(Index);
}

void Tools_StartPosition_Object::UpdatePositionInAsuraData(bool /*updateLinkedObjects*/)
{
	Asura_Environment* env = Asura_Environment_System::GetEnvironment();
	Asura_Assert(env,"");

	env->GetStartPosition(Index) = Position;
	env->GetStartOrientation(Index) = Orientation;

	SetFileModified();
}

void Tools_StartPosition_Object::UpdateWhileSelected()
{
	if(m_bChanged)
	{
		//update the asura data
		m_bChanged = false;
		UpdatePositionInAsuraData(false);
	}

	Tools_Object::UpdateWhileSelected();
}

const char* Tools_StartPosition_Object::GetName()
{
	return Name.GetString();
}

void Tools_StartPosition_Object::Destroy()
{
	Asura_Environment* env = Asura_Environment_System::GetEnvironment();
	Asura_Assert(env,"");
	env->NumberOfStartPositions--;

	//search for any start positions with a higher index , and shuffle them down
	for(LIF<Tools_Object*> olif(&Tools_Object_System::ObjectList);!olif.done();olif.next())
	{
		if(olif()->Type !=TOT_StartPosition) continue;
		Tools_StartPosition_Object* start = (Tools_StartPosition_Object*) olif();

		if(start->Index > Index)
		{
			start->Index--;
			//update the asura data in the new slot
			start->UpdatePositionInAsuraData(false);
			//update the name
			char buffer[30];
#ifdef ASURA_USE_BOTH_START_POSITION_TYPES
			sprintf(buffer,"Start Pos (Multiplayer) %d",start->Index);
#else
			sprintf(buffer,"Start Position %d",start->Index);
#endif
			start->Name = buffer;

		}
	}


	Tools_Object::Destroy();
	SetFileModified();
}


void Tools_StartPosition_Object::CreateStartPosition()
{
	Asura_Environment* env = Asura_Environment_System::GetEnvironment();
	if(!env) return;

	//allocate an enlarged array of start positions , and copy over the old values
	env->NumberOfStartPositions++;
	Asura_Environment_StartPosition* NewStartPositions = new Asura_Environment_StartPosition[env->NumberOfStartPositions];

	for(int i=0;i<env->NumberOfStartPositions-1;i++)
	{
		NewStartPositions[i] = env->StartPositions[i];
	}
	delete [] env->StartPositions;
	env->StartPositions = NewStartPositions;

	int index = env->NumberOfStartPositions-1;
	Asura_Environment_StartPosition* newStart = &env->StartPositions[index];

	//set the position/orientaiton of the new start

	newStart->Position = *Asura_Camera::GetPosition();
	newStart->Orientation = *Asura_Camera::GetOrientation();
	newStart->TeamNumber = 0; // SNH - 18/03/2003 11:56:42 - no team by default

	//create the tools object for this position, and select it
	Tools_Object_System::SelectObject( Project_CreateStartPositionObject(index) );

	Tools_Timed_Message_System::AddMessage(0xffffff,"New start position created");
	SetFileModified();
}

void Tools_StartPosition_Object::OnSelection()
{
	s_pxThisStartPos = this;
	CreateOverlay();
}


void Tools_StartPosition_Object::OnDeselection()
{
	DeleteOverlay();
	s_pxThisStartPos = 0;
}

void Tools_StartPosition_Object::CreateOverlay()
{
	if(!s_pxThisStartPos) return;

	Asura_Overlay* pxOverlay;	
	pxOverlay = new Asura_Overlay(s_pxThisStartPos->GetName(),false,&s_xOverlayPosition);
	Asura_Vector_2 xOffset = Asura_Vector_2(1.0f,3.0f);

	s_pxThisStartPos->AddOverlayControls( pxOverlay, xOffset );
	
	pxOverlay->ID = TOOLS_OVERLAY_SELECTEDOBJECT;
	pxOverlay->Origin = s_xOverlayPosition;
 	Asura_Overlay_System::SubmitNewOverlay(pxOverlay,false);
}

void Tools_StartPosition_Object::AddOverlayControls( Asura_Overlay* pxOverlay, Asura_Vector_2& xOffset )
{
	Asura_Environment* env = Asura_Environment_System::GetEnvironment();
	if(!env) return;

	Asura_Dialog* pxDialog;	

	pxDialog = new Asura_Numerical_Dialog("Team Number:", xOffset, &env->StartPositions[s_pxThisStartPos->Index].TeamNumber, 0, 255, 1, "%i", &s_pxThisStartPos->m_bChanged);
	pxOverlay->AddDialog(pxDialog);
	xOffset.y+=Asura_Dialog::DefaultSpacing();
}


void Tools_StartPosition_Object::DeleteOverlay()
{
	Asura_Overlay_System::CloseOverlays(TOOLS_OVERLAY_SELECTEDOBJECT);
}
void Tools_StartPosition_Object::SetFileModified()
{
	if(Asura_Chunk_StartPosition::s_eStartPositionFile == Asura_Chunk_StartPosition::SPF_ASURA)
	{
		Tools_SaveAsura::SetMainFileModified();
	}
	else
	{
		Tools_SaveAsura::SetEntityModified();
	}
}
