//
// Tools_Entity_MultiDamageVolume.cpp
//
// Created by Andrew Weinkove - 30/01/2003
// 
// Copyright (C) 2003 Rebellion, All Rights Reserved.
//


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

#include "Debugging/Asura_Assert.h"
#include "Entity/Asura_Entity.h"
#include "Entity/Asura_Entity_Classification.h"
#include "Entity/Triggers/Asura_ServerEntity_MultiDamageVolume.h"
#include "Entity/Asura_StaticMessage_System.h"
#include "Entity/Triggers/Asura_ServerEntity_CountedTrigger.h"
#include "Interface/Asura_Dialog.h"
#include "Interface/Asura_Overlay.h"
#include "Mesh/Asura_Mesh_System.h"
#include "Misc/Tools_Render.h"
#include "Volume/Asura_VolumeGroup.h"

#include "Objects/Tools_VolumeBaseEdit_Object.h"
#include "Objects/Tools_VolumeGroupEdit_Controller.h"
#include "Objects/Tools_Object_System.h"
#include "Load&Save/Tools_SaveAsura.h"

bool Tools_Entity_MultiDamageVolume::s_bChanged = false;
bool Tools_Entity_MultiDamageVolume::s_bOverlayChanged = false;

//////////////////////////////////////////////////////////////////////////////////////////////////
/*-----------------------------------**
** Tools_Entity_MultiDamageVolume    **
**-----------------------------------*/

bool Tools_Entity_MultiDamageVolume::s_bMoveVolumeWithObject = true;

Tools_Entity_MultiDamageVolume::Tools_Entity_MultiDamageVolume(Asura_Entity* pxEntity)
:Tools_Entity_Activatable_Object(pxEntity)
{
	Asura_Assert(pxEntity->GetClassification()==AsuraEntityClass_MultiDamageVolume,"");
	Type = TOT_Entity_MultiDamageVolume;
	Mesh = Asura_Mesh_System::GetMesh("ToolsShape_Skull");
	m_xPreviousPosition = Position;
	m_pxVolumeController = 0;
}

Tools_Entity_MultiDamageVolume::~Tools_Entity_MultiDamageVolume()
{
	delete m_pxVolumeController;
}

void Tools_Entity_MultiDamageVolume::AddOverlayControls(class Asura_Overlay* pxNewOverlay,class Asura_Vector_2& xOffset)
{
	Tools_Entity_Activatable_Object::AddOverlayControls(pxNewOverlay,xOffset);

	Asura_Dialog* pxNewDialog;
	pxNewDialog = new Asura_Function_Dialog("Edit Volume",xOffset,EditVolume);
	pxNewDialog->SetHelpText("Edits the volume for this trigger.");
	pxNewOverlay->AddDialog(pxNewDialog);
	xOffset.y += Asura_Dialog::DefaultSpacing();

    pxNewDialog = new Asura_Tickbox_Dialog( "Move Volume With Object", xOffset, &s_bMoveVolumeWithObject);
	pxNewDialog->SetHelpText("The volume attached to this trigger should be moved when the trigger's tools object is moved.\nThis is a global setting for all trigger volumes.");
	pxNewOverlay->AddDialog( pxNewDialog );
	xOffset.y += Asura_Dialog::DefaultSpacing();

	Asura_ServerEntity_MultiDamageVolume* pxAsuraEntity = (Asura_ServerEntity_MultiDamageVolume*) Entity;
	pxNewDialog = new Asura_Numerical_Dialog("Damage Rate", xOffset, &pxAsuraEntity->m_fDamageRate, 0.0f, 9999.9f, 0.1f, "%2.1f");
	pxNewDialog->SetHelpText("Set the damage rate.\nEntities caught in these volumes will lose this amount of health.\nProject code determines how often this amount is applied.");
	pxNewOverlay->AddDialog( pxNewDialog );
	xOffset.y += Asura_Dialog::DefaultSpacing();

//	pxNewDialog = new Asura_Tickbox_Dialog("Uses dynamics when active", xOffset, &m_bUsesDynamics, &s_bOverlayChanged);
//	pxNewDialog->SetHelpText("When this option is ticked, static dynamic blocks are created in the position of the bounding boxes and are enabled when the damage volume is enabled.\nYou should use instant death with this option.");
//	pxNewOverlay->AddDialog( pxNewDialog );
//	xOffset.y += Asura_Dialog::DefaultSpacing();

//	pxNewDialog = new Asura_Tickbox_Dialog("Dynamics block waypoint generation", xOffset, &m_bDynamicsBlockWaypoints, &s_bChanged);
//	pxNewDialog->SetHelpText("If this is ticked then waypoints won't be created in these dynamic objects.");
//	pxNewOverlay->AddDialog( pxNewDialog );
//	pxNewDialog->SetEnabled(pxAsuraEntity->m_bUsesDynamicsWhenActive);
//	xOffset.y += Asura_Dialog::DefaultSpacing();

	pxNewDialog = new Asura_Tickbox_Dialog("Instant Death", xOffset, &m_bInstantDeath, &s_bChanged);
	pxNewDialog->SetHelpText("Characters will die instantly in this damage volume if this option is ticked.\nForced true if dynamics are on.");
	pxNewOverlay->AddDialog( pxNewDialog );
	xOffset.y += Asura_Dialog::DefaultSpacing();
}

void Tools_Entity_MultiDamageVolume::UpdatePositionInAsuraData(bool bUpdateLinkedObjects)
{
	//shift the bounding box by the amount that the object has moved
	Asura_ServerEntity_MultiDamageVolume* pxAsuraEntity = (Asura_ServerEntity_MultiDamageVolume*) Entity;
	if(s_bMoveVolumeWithObject)
	{
		pxAsuraEntity->m_pxVolumeGroup->DisplaceVolumes(Position-m_xPreviousPosition);

		if(m_pxVolumeController)
		{
			m_pxVolumeController->MoveVolumeObjects(Position-m_xPreviousPosition);
		}
	}

	m_xPreviousPosition = Position;
	Tools_Entity_Activatable_Object::UpdatePositionInAsuraData(bUpdateLinkedObjects);
}

void Tools_Entity_MultiDamageVolume::EditVolume()
{
	Asura_Assert(ThisEntity,"");

	Tools_Entity_MultiDamageVolume* pxToolsEntity = (Tools_Entity_MultiDamageVolume*) ThisEntity;
	Asura_ServerEntity_MultiDamageVolume* pxAsuraEntity = (Asura_ServerEntity_MultiDamageVolume*) ThisEntity->Entity;

	//create controller for editing volumes if it hasn't been done yet
	if(!pxToolsEntity->m_pxVolumeController)
	{
		pxToolsEntity->m_pxVolumeController = new Tools_Object_VolumeGroupEdit_Controller(pxToolsEntity, pxAsuraEntity->m_pxVolumeGroup, &pxToolsEntity->Changed);

	}
	//and get it to create the volume objects
	pxToolsEntity->m_pxVolumeController->StartVolumeEditing();
}

Tools_Object* Tools_Entity_MultiDamageVolume::CreateObjectOfThisType() const
{
	Tools_Object* pxOldSelection = Tools_Object_System::SelectedObject;
	Project_Create();
	Tools_Object* pxNewSelection = Tools_Object_System::SelectedObject;

	return (pxOldSelection!=pxNewSelection) ? pxNewSelection : 0;
}

void Tools_Entity_MultiDamageVolume::OnSelection()
{
	s_bChanged = false;
	s_bOverlayChanged = false;
	Asura_ServerEntity_MultiDamageVolume* pxAsuraEntity = (Asura_ServerEntity_MultiDamageVolume*) Entity;
	m_bUsesDynamics = (pxAsuraEntity->m_bUsesDynamicsWhenActive ? true : false);
	m_bDynamicsBlockWaypoints = (pxAsuraEntity->m_bVolumesBlockWaypointCreation ? true : false);
	m_bInstantDeath = (pxAsuraEntity->m_bInstantDeath ? true : false);;
	Tools_Entity_Activatable_Object::OnSelection();
}

void Tools_Entity_MultiDamageVolume::UpdateWhileSelected()
{
	Asura_ServerEntity_MultiDamageVolume* pxAsuraEntity = (Asura_ServerEntity_MultiDamageVolume*) Entity;
	if (s_bChanged ||
		s_bOverlayChanged)
	{
		pxAsuraEntity->m_bUsesDynamicsWhenActive = m_bUsesDynamics;
		pxAsuraEntity->m_bVolumesBlockWaypointCreation = m_bDynamicsBlockWaypoints;
		// (AW - 09.02.2004) - Currently, if you use dynamics you must do instant kill!
		if (m_bUsesDynamics)
		{
			m_bInstantDeath = true;
		}
		pxAsuraEntity->m_bInstantDeath = m_bInstantDeath;
		s_bChanged = false;
		Changed = true; // In order to flag the .ent file as changed.
	}
	Tools_Entity_Activatable_Object::UpdateWhileSelected();
	if (s_bOverlayChanged)
	{
		DeleteOverlay();
		CreateOverlay();
		s_bOverlayChanged = false;
	}
	pxAsuraEntity->SynchroniseDynamicObjects();
}

void Tools_Entity_MultiDamageVolume::Render()
{
	// (AW - 09.02.2004) - Debugging code useful for checking the intersection algorithm.
/*	unsigned uColour = 0xffffffff;
	Asura_ServerEntity_MultiDamageVolume* pxAsuraEntity = (Asura_ServerEntity_MultiDamageVolume*) Entity;
	Asura_Bounding_Box xPlayerBox = PlayerDynamicObject->GetBoundingBox();
	if (pxAsuraEntity &&
		pxAsuraEntity->Overlaps(PlayerDynamicObject->GetBoundingBox()))
	{
		xPlayerBox.MaxY -= Asura_Random::GetFloat();
		xPlayerBox.MinY += Asura_Random::GetFloat();
	}
	Tools_Render::RenderCube(xPlayerBox, Asura_Maths::ZeroVector3, Asura_Maths::IdentityMatrix3x3, uColour);*/
	Tools_Entity_Activatable_Object::Render();
}

void Tools_Entity_MultiDamageVolume::Copy(const Tools_Object* pxObject)
{
	Tools_Entity_Activatable_Object::Copy(pxObject);
	
	const Tools_Entity_MultiDamageVolume* pxFromObject = (const Tools_Entity_MultiDamageVolume*) pxObject;

	Asura_ServerEntity_MultiDamageVolume* pxFromEntity = (Asura_ServerEntity_MultiDamageVolume*) pxFromObject->Entity;
	Asura_ServerEntity_MultiDamageVolume* pxToEntity = (Asura_ServerEntity_MultiDamageVolume*) Entity;

	//delete the volume controller if it exists ,since we will be replacing the volumes
	delete m_pxVolumeController;
	m_pxVolumeController = 0;
	
	//copy everything between the entities
	pxToEntity->m_uFlags = pxFromEntity->m_uFlags;
	pxToEntity->m_iListFlags = pxFromEntity->m_iListFlags;
	pxToEntity->m_fDamageRate = pxFromEntity->m_fDamageRate;

	pxToEntity->m_pxVolumeGroup->Copy(pxFromEntity->m_pxVolumeGroup);

	pxToEntity->SynchroniseDynamicObjects();
}



