//////////////////////////////////////////////////////////////////////////////////////////
//
//  FILE        :  Tools_Entity_Extended_Particle_Generator.cpp
//
//  CREATED     :  Adam A. Brown  (25.3.2003)
//
//  Copyright (C) 2003 Rebellion, All Rights Reserved.
//
//////////////////////////////////////////////////////////////////////////////////////////


#include "Core/Asura.h"

// This file's header.
#include "Entity/Tools_Entity_Extended_Particle_Generator.h"

#include "Entity/Tools_Entity_Data.h"
#include "Objects/Tools_Object_System.h"

#include "Entity/Asura_Entity_Classification.h"
#include "Entity/ParticleGenerator/Asura_ServerEntity_Extended_Particle_Generator.h"
#include "Interface/Asura_Dialog.h"
#include "Interface/Asura_Overlay.h"
#include "Load&Save/Tools_SaveAsura.h"
#include "Mesh/Asura_Mesh_System.h"



Tools_Entity_Extended_Particle_Generator* Tools_Entity_Extended_Particle_Generator::s_pxThis = NULL;
char** Tools_Entity_Extended_Particle_Generator::s_pszNameList = NULL;
Asura_Extended_Particle_Generator* Tools_Entity_Extended_Particle_Generator::s_pxPreviewGenerator = NULL;


////////////////////////////////////////////////////////////////////////////////
//
// Constructor / Destructor
//
////////////////////////////////////////////////////////////////////////////////
Tools_Entity_Extended_Particle_Generator::Tools_Entity_Extended_Particle_Generator(Asura_Entity* pxEntity)
: Tools_Entity_Activatable_Object(pxEntity)
, m_eType(ASURA_EXTENDED_PARTICLE_GENERATOR_NONE)
, m_bTriggered(false)
, m_iListSelection(0)
, m_iListOffset(0)
, m_iDestructionCounter(-1)
, m_bActive(false)
{
	Type = TOT_Entity_ExtendedParticleGenerator;

	//Get data from server.
	if(pxEntity != NULL)
	{
		Asura_ServerEntity_Extended_Particle_Generator* pxServerEntity = static_cast<Asura_ServerEntity_Extended_Particle_Generator*>(pxEntity);

		Position = pxServerEntity->GetPosition();
		Orientation = pxServerEntity->GetOrientation();
		m_eType = pxServerEntity->GetType();
		m_bTriggered = pxServerEntity->HasBeenTriggered();

		//Set the position in the list according to the generator template being used.
		int iRef = Asura_Extended_Particle_Generator_Template_System::GetReferenceNumber(m_eType);

		m_iListSelection = 7;
		m_iListOffset = iRef-7;

		if(m_iListOffset < 0)
		{
			m_iListSelection += m_iListOffset;
			m_iListOffset = 0;
		}
	}
	else
	{
		Orientation.Identity();
	}

	s_pxThis = this;

	Asura_String xMeshName("ToolsShape_CutsceneTrackPoint");
	Mesh = Asura_Mesh_System::GetMesh(xMeshName);
}


Tools_Entity_Extended_Particle_Generator::~Tools_Entity_Extended_Particle_Generator()
{
	StopPreview();

	if(s_pszNameList != NULL)
	{
		for(int i = 0; i < NUM_ENTRIES_IN_PARTICLE_ENUM; i++)
		{
			if(s_pszNameList[i] != NULL)
			{
				delete [] s_pszNameList[i];
				s_pszNameList[i] = NULL;
			}
		}

		delete [] s_pszNameList;
		s_pszNameList = NULL;
	}
}


////////////////////////////////////////////////////////////////////////////////
//
// UpdateWhileSelected
//
////////////////////////////////////////////////////////////////////////////////
void Tools_Entity_Extended_Particle_Generator::UpdateWhileSelected()
{
	m_eType = Asura_Extended_Particle_Generator_Template_System::GetTemplatePointer(m_iListSelection+m_iListOffset)->m_eEnum;

	Asura_ServerEntity_Extended_Particle_Generator* pxServerEntity = static_cast<Asura_ServerEntity_Extended_Particle_Generator*>(Entity);

	if(!(pxServerEntity->GetPosition() == Position) || pxServerEntity->GetType() != m_eType || pxServerEntity->HasBeenTriggered() != m_bTriggered)
	{
		Changed = true;
	}

	pxServerEntity->SetTriggered(m_bTriggered);
	pxServerEntity->SetType(m_eType);
	pxServerEntity->SetPosition(Position);
	pxServerEntity->SetOrientation(Orientation);

	if(m_iDestructionCounter >= 0) m_iDestructionCounter--;

	Tools_Entity_Activatable_Object::UpdateWhileSelected();
}



////////////////////////////////////////////////////////////////////////////////
//
// On selection etc...
//
////////////////////////////////////////////////////////////////////////////////
void Tools_Entity_Extended_Particle_Generator::OnSelection()
{
	s_pxThis = this;

	Tools_Entity_Activatable_Object::OnSelection();
}


void Tools_Entity_Extended_Particle_Generator::OnDeselection()
{
	StopPreview();

	Tools_Entity_Activatable_Object::OnDeselection();
}



////////////////////////////////////////////////////////////////////////////////
//
// Add overlay controls
//
////////////////////////////////////////////////////////////////////////////////
void Tools_Entity_Extended_Particle_Generator::AddOverlayControls(class Asura_Overlay* pxNewOverlay,class Asura_Vector_2& xOffset)
{
	//Tools_Entity_Activatable_Object::AddOverlayControls(pxNewOverlay, xOffset);

	MakeNames();

	Asura_Dialog *pxNewDialog = new Asura_List_Dialog(xOffset, s_pszNameList, &s_pxThis->m_iListOffset, &s_pxThis->m_iListSelection, 9, NUM_ENTRIES_IN_PARTICLE_ENUM, NULL);
	pxNewOverlay->AddDialog(pxNewDialog);
	xOffset.y += 12.f;

	pxNewDialog = new Asura_Tickbox_Dialog("Triggered", xOffset, &s_pxThis->m_bTriggered, &s_pxThis->Changed);
	pxNewOverlay->AddDialog(pxNewDialog);
	xOffset.y += 2.f;

	pxNewDialog = new Asura_Function_Dialog("Start Preview", xOffset, StartPreview);
	pxNewOverlay->AddDialog(pxNewDialog);
	xOffset.y += 1.5f;

	pxNewDialog = new Asura_Function_Dialog("Stop Preview", xOffset, StopPreview);
	pxNewOverlay->AddDialog(pxNewDialog);
	xOffset.y += 1.5f;
}



////////////////////////////////////////////////////////////////////////////////
//
// static functions
//
////////////////////////////////////////////////////////////////////////////////
void Tools_Entity_Extended_Particle_Generator::Create()
{
	const char* szTypeName = "Extended Particle Generator";
	const char* szShortName = "Ext. Part. Gen.";

	// Create the server object and set its data.
	Asura_ServerEntity_Extended_Particle_Generator* pxServerObject = Asura_ServerEntity_Extended_Particle_Generator::CreateFromTools();
	if(!pxServerObject) return;

	// Set up tools data and auto-create a unique name (prompt for new name if there is a clash).
	Tools_Entity_Data* pxToolsData = CreateToolsDataWithDefaultName(szTypeName, szShortName, pxServerObject->GetGuid(), GetNamePrefix());
	if (!pxToolsData) return;
	
	if (pxServerObject)
	{
		pxServerObject->ToolsData = pxToolsData;
		pxServerObject->SetPosition(pxToolsData->Position);
	}

	// Create the game specific tools object and select it.
	Tools_Object* pxToolsObject = static_cast<Tools_Object*>(new Tools_Entity_Extended_Particle_Generator(pxServerObject));
	Tools_Object_System::SelectObject(pxToolsObject);

	Tools_SaveAsura::SetEntityModified();
}



Tools_Object* Tools_Entity_Extended_Particle_Generator::Create(Asura_Entity* pxEntity)
{
	Asura_Assert(pxEntity,"");
	if (!pxEntity) return NULL;
	
	Asura_ServerEntity_Extended_Particle_Generator* pxGen = static_cast<Asura_ServerEntity_Extended_Particle_Generator*>( Asura_ServerEntity_Extended_Particle_Generator::FindEntity(pxEntity->GetGuid()) );

	if(pxGen == NULL)
	{
		Asura_Assert(false, "NULL server object");
		return NULL;
	}

	if( pxGen->GetClassification() != AsuraEntityClass_ExtendedParticleGenerator )
	{
		Asura_Assert(false, "ERROR - Not an extended particle generator" );		
		return NULL;
	}

	return new Tools_Entity_Extended_Particle_Generator(pxGen);
}



void Tools_Entity_Extended_Particle_Generator::MakeNames()
{
	if(s_pszNameList == NULL)
	{
		s_pszNameList = new char * [NUM_ENTRIES_IN_PARTICLE_ENUM];

		for(int i = 0; i < NUM_ENTRIES_IN_PARTICLE_ENUM; i++)
		{
			const char* szName = Asura_Extended_Particle_Generator_Template_System::GetName(i);
			int j;

			s_pszNameList[i] = new char [40];

			for(j = 0; j < 39; j++)
			{
				s_pszNameList[i][j] = szName[j];
				if(szName[j] == 0) break;
			}

			if(j == 39)
			{
				s_pszNameList[i][j] = 0;
			}
		}
	}
}



////////////////////////////////////////////////////////////////////////////////
//
// Preview functions
//
////////////////////////////////////////////////////////////////////////////////
void Tools_Entity_Extended_Particle_Generator::StartPreview()
{
	if(s_pxThis->m_iDestructionCounter == -1 && s_pxThis->m_bActive == false)
	{
		Asura_Vector_3 xOriVec;

		xOriVec.x = s_pxThis->Orientation.e13;
		xOriVec.y = s_pxThis->Orientation.e23;
		xOriVec.z = s_pxThis->Orientation.e33;

		s_pxPreviewGenerator = Asura_Extended_Particle_Generator::Create(Asura_Extended_Particle_Generator_Template_System::GetTemplatePointer(s_pxThis->m_eType), s_pxThis->Position, xOriVec);
		s_pxPreviewGenerator->SetShutdownCallback(StopPreview);
		s_pxThis->m_bActive = true;
	}
}


void Tools_Entity_Extended_Particle_Generator::StopPreview()
{
	if(s_pxThis->m_iDestructionCounter == -1 && s_pxThis->m_bActive)
	{
		s_pxPreviewGenerator->NoReallyIMeanItShutdown();
		s_pxThis->m_iDestructionCounter = 2;
		s_pxThis->m_bActive = false;
	}
}
