#include "stdafx.h"

#include "MW4GameEd.h"
#include "DeleteCommand.h"
#include <Adept\Entity.hpp>
#include <Adept\Map.hpp>
#include <mw4\building.hpp>
#include "EditorWaypoint.h"
#include <MW4\rail_move.hpp>
#include <mw4\Cultural.hpp>
#include <Adept\NameTable.hpp>
#include <mw4\mwobject.hpp>
#include "TransDlg.h"
#include "DisplayWindow.h"
#include "OverviewWindow.h"
#include "InstanceWindow.h"
#include "Selection.h"
#include <mw4\noncom.hpp>
#include <mw4\navpoint.hpp>

extern CMW4GameEdApp theApp;

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
DeleteCommand::DeleteCommand()
: Command()
{
	Check_Object(Map::Instance);
	CSelectionNode *selection_node;
	Entity *entity = NULL;
	ChainIteratorOf<CSelectionNode *> iterator(&selectedEntities);
	theApp.MakeObjectNamesUnique();

	int sels,cursel,i;
	sels=iterator.GetSize();
	
	CSelectionNode **sel_list=new CSelectionNode *[sels];
	
	cursel=0;
	while((selection_node = iterator.ReadAndNext()) != NULL)
	{
		sel_list[cursel++]=selection_node;
	}
	

	for(cursel=0;cursel<sels;cursel++)
	{
		
		if (sel_list[cursel]!=NULL && sel_list[cursel]->selectedEntity->IsDerivedFrom(MWObject::DefaultData))
		{
			MWObject *obj;
			
			obj = Cast_Object (MWObject *,sel_list[cursel]->selectedEntity);
			if (obj->m_AI)	//Remove redundant AI objects
			{
				for(i=0;i<sels;i++)
				{
					if(sel_list[i] != NULL &&
						sel_list[i]->selectedEntity->objectID==obj->m_AI->objectID)
					{
						sel_list[i]=NULL;
					}
				}
			}
		}
		
	}
	
	for(cursel=0;cursel<sels;cursel++)
	{
		selection_node=sel_list[cursel];
		
		if(selection_node!=NULL)
		{
			Check_Object(selection_node);
			entity = selection_node->selectedEntity;
			
			
			if (entity->IsDerivedFrom (MWObject::DefaultData))
			{
				MWObject *obj;
				
				obj = Cast_Object (MWObject *,entity);
				if (obj->m_AI)
				{
					Map::Instance->RemoveChild(obj->m_AI);
					NameTable::Instance->RemoveEntry(obj->m_AI->objectID);
						NameTable::Instance->IsValid();
	
				}
			}
			
			if (entity->IsDerivedFrom(EditorObjectiveMarker::DefaultData))
			{
				EditorObjectiveMarker* node;
				node = Cast_Object(EditorObjectiveMarker*,entity);
				Map::Instance->RemoveChild(node->objective);
			} 
			else if (entity->IsDerivedFrom(EditorLatticeNode::DefaultData))
			{
				EditorLatticeNode* latticeNode;
				latticeNode = Cast_Object(EditorLatticeNode*,entity);
				if (latticeNode->railNode)
					MW4AI::g_MissionGraph->DeleteNode(latticeNode->railNode->ID());
			}
			else if (entity->IsDerivedFrom(EditorDropZonePoint::DefaultData))
			{
				EditorDropZonePoint* node;
				node = Cast_Object(EditorDropZonePoint*,entity);
				node->dropNode->pointChain.Remove(node);
				node->dropNode->UpdatePoints();
			}
			else if (entity->IsDerivedFrom(EditorMovementPath::DefaultData))
			{
				EditorMovementPath* path;
				EditorPathNode* node;
				
				path = Cast_Object(EditorMovementPath*,entity);
				
				ChainIteratorOf<EditorPathNode*> nodeIterator(&path->pathNodes);
				
				while ((node = nodeIterator.ReadAndNext()) != NULL)
				{
					node->ShowLink(false);
					if(node->GetParentEntity())
					{
						NameTable::Instance->RemoveEntry(node->objectID);
						NameTable::Instance->IsValid();
						Map::Instance->RemoveChild(node);
					}
				}
				NameTable::Instance->RemoveEntry(path->pathSlot.GetCurrent()->objectID);
				NameTable::Instance->IsValid();
				Map::Instance->RemoveChild(path->pathSlot.GetCurrent());
			}
			else if (entity->IsDerivedFrom(EditorPathNode::DefaultData))
			{
				Point3D loc;
				loc = entity->GetLocalToWorld();
				
				EditorPathNode* node;
				node = Cast_Object(EditorPathNode*,entity);
				node->pathSlot.GetCurrent()->pathSlot.GetCurrent()->ErasePoint(node->index);
				node->pathSlot.GetCurrent()->pathNodes.Remove(node);
				
				if (node->prevnode)
					node->prevnode->nextnode = node->nextnode;
				if (node->nextnode)
					node->nextnode->prevnode = node->prevnode;
				else
					theApp.m_LastPathNode = node->prevnode;
				
				EditorPathNode* tnode = node->nextnode;
				while (tnode)
				{
					tnode->index--;
					tnode = tnode->nextnode;
				}
				if (node->nextnode)
					node->nextnode->UpdateLinkPointData();
				else if (node->prevnode)
					node->prevnode->UpdateLinkPointData(true);
				
				node->ShowLink(false);
				
				if (!node->pathSlot.GetCurrent()->pathSlot.GetCurrent()->pathPoints.size())
				{
					Map::Instance->RemoveChild(node->pathSlot.GetCurrent());
					NameTable::Instance->RemoveEntry(node->pathSlot.GetCurrent()->objectID);
					theApp.instanceWindow->RemoveInstance(node->pathSlot.GetCurrent());
					Map::Instance->RemoveChild(node->pathSlot.GetCurrent()->pathSlot.GetCurrent());
					NameTable::Instance->RemoveEntry(node->pathSlot.GetCurrent()->pathSlot.GetCurrent()->objectID);
					theApp.instanceWindow->RemoveInstance(node->pathSlot.GetCurrent()->pathSlot.GetCurrent());
					theApp.displayWindow->translationDlg->CheckObject(node->pathSlot.GetCurrent()->pathSlot.GetCurrent());
					NameTable::Instance->IsValid();

				}
			}
			else if(entity->IsDerivedFrom(EditorLight::DefaultData))
			{
				EditorLight* light;
				light = Cast_Object(EditorLight*,entity);
				light->LightSwitch();
			}
			
			Check_Object(entity);
			NameTable::Instance->RemoveEntry(entity->objectID);
			Map::Instance->RemoveChild(entity);
		NameTable::Instance->IsValid();
			
			if (entity)
			{
				theApp.instanceWindow->RemoveInstance(entity);
				theApp.displayWindow->translationDlg->CheckObject(entity);
			}
		}
	}
	undone = false;
	delete sel_list;
	theApp.overviewWindow->DrawWindow();
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
DeleteCommand::~DeleteCommand()
{
	if (!undone)
	{
		CSelectionNode *selection_node;
		Entity *entity;
		ChainIteratorOf<CSelectionNode *> iterator(&selectedEntities);
		while((selection_node = iterator.ReadAndNext()) != NULL)
		{
			Check_Object(selection_node);
			entity = selection_node->selectedEntity;
			Check_Object(entity);
			if(entity->IsDerivedFrom(EditorDropNode::DefaultData))
			{
				Check_Object(NameTable::Instance);
				NameTable::Instance->RemoveEntry(entity->objectID);
			NameTable::Instance->IsValid();
			}
			if(entity->IsDerivedFrom(EditorCameraShip::DefaultData))
			{
				Check_Object(NameTable::Instance);
				NameTable::Instance->RemoveEntry(entity->objectID);
			NameTable::Instance->IsValid();
		}
			
			else if (entity->IsDerivedFrom(EditorMovementPath::DefaultData))
			{
				EditorMovementPath* path;
				
				path = Cast_Object(EditorMovementPath*,entity);
				
				ChainIteratorOf<EditorPathNode*> node_iterator(&path->pathNodes);
				node_iterator.DeletePlugs();
				
//				NameTable::Instance->RemoveEntry(path->objectID);
				//				delete Cast_Object(Stuff::Plug *, path);
			}
			else if(entity->IsDerivedFrom(EditorPathNode::DefaultData))
			{
				EditorPathNode* node;
				node = Cast_Object(EditorPathNode*,entity);
				EditorMovementPath *editor_path;
				editor_path = node->pathSlot.GetCurrent();
				if(editor_path)
				{
					Check_Object(editor_path);
					Path *adept_path;
					adept_path = editor_path->pathSlot.GetCurrent();
					if(adept_path)
					{
						Check_Object(adept_path);
						if(adept_path->pathPoints.size() == 0)
						{
							delete Cast_Object(Stuff::Plug *, node->pathSlot.GetCurrent()->pathSlot.GetCurrent());
							delete Cast_Object(Stuff::Plug *, node->pathSlot.GetCurrent());
						}
					}
				}
			}
			
  delete Cast_Object(Stuff::Plug *, entity);
		}
	}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
DeleteCommand::Execute()
{
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
DeleteCommand::Undo()
{
	CSelectionNode *selection_node;
	Entity *entity = NULL;
	ChainIteratorOf<CSelectionNode *> iterator(&selectedEntities);
	while((selection_node = iterator.ReadAndNext()) != NULL)
	{
		Check_Object(selection_node);
		entity = selection_node->selectedEntity;
		Check_Object(entity);
		Check_Object(Map::Instance);
		Map::Instance->AddChild(entity);
		if(entity->IsDerivedFrom(Vehicle::DefaultData))
		NameTable::Instance->AddEntry(selection_node->selectedEntity, NameTable::VehicleArray);
		else if(entity->IsDerivedFrom(Building::DefaultData) || entity->IsDerivedFrom(Cultural::DefaultData))
		NameTable::Instance->AddEntry(selection_node->selectedEntity, NameTable::BuildingArray);
		else if(entity->IsDerivedFrom(NavPoint::DefaultData))
		 NameTable::Instance->AddEntry(selection_node->selectedEntity, NameTable::NavArray);
		else if(entity->IsDerivedFrom(DropZone::DefaultData))
		 NameTable::Instance->AddEntry(selection_node->selectedEntity, NameTable::DropZoneArray);
		else if(entity->IsDerivedFrom(NonCom::DefaultData))
		 NameTable::Instance->AddEntry(selection_node->selectedEntity, NameTable::BuildingArray);
		else
		 NameTable::Instance->AddEntry(selection_node->selectedEntity);

		NameTable::Instance->IsValid();
	
		if (entity->IsDerivedFrom (MWObject::DefaultData))
		{
			MWObject *obj;
			obj = Cast_Object (MWObject *,entity);
			if (obj->m_AI)
			{
				Map::Instance->AddChild(obj->m_AI);
				 NameTable::Instance->AddEntry(obj->m_AI,NameTable::AIArray);
		NameTable::Instance->IsValid();

			}
		}
		entity->SyncMatrices(true);
		
		if (entity->IsDerivedFrom(EditorLatticeNode::DefaultData))
		{
			EditorLatticeNode* latticeNode;
			latticeNode = Cast_Object(EditorLatticeNode*,entity);
			MW4AI::g_MissionGraph->AddNode(latticeNode->railNode);
		}
		else if (entity->IsDerivedFrom(EditorDropZonePoint::DefaultData))
		{
			EditorDropZonePoint* node;
			node = Cast_Object(EditorDropZonePoint*,entity);
			node->dropNode->pointChain.Add(node);
			node->dropNode->UpdatePoints();
		}
		else if (entity->IsDerivedFrom(EditorMovementPath::DefaultData))
		{
			EditorMovementPath* path;
			EditorPathNode* node;
			
			path = Cast_Object(EditorMovementPath*,entity);
			
			ChainIteratorOf<EditorPathNode*> nodeIterator(&path->pathNodes);
			
			while ((node = nodeIterator.ReadAndNext()) != NULL)
			{
				Map::Instance->AddChild(node);
				node->ShowLink(true);
				
				node->SyncMatrices(true);
				node->GetElement()->Sync();
				
				Time till = gos_GetElapsedTime();
				node->PostCollisionExecute(till);
			}
			Map::Instance->AddChild(path->pathSlot.GetCurrent());
			 NameTable::Instance->AddEntry(path->pathSlot.GetCurrent(), NameTable::PathArray);
			NameTable::Instance->IsValid();
			path->pathSlot.GetCurrent()->SyncMatrices(true);
		}
		else if (entity->IsDerivedFrom(EditorPathNode::DefaultData))
		{
			EditorPathNode* node;
			node = Cast_Object(EditorPathNode*,entity);
			
			if (!node->pathSlot.GetCurrent()->pathSlot.GetCurrent()->pathPoints.size())
			{
				Map::Instance->AddChild(node->pathSlot.GetCurrent());
				node->pathSlot.GetCurrent()->SyncMatrices(true);
				//				node->path->objectID = NameTable::Instance->AddEntry(node->path, NameTable::PathArray);
			}
			
			Point3D loc;
			loc = node->GetLocalToWorld();
			
			if (node->nextnode)		// insert node
			{
				LinearMatrix4D matrix = LinearMatrix4D::Identity;
				
				node->nextnode->InsertNode(node);
				
				matrix.BuildTranslation(loc);
				node->SetNewLocalToParent(matrix);
				node->SyncMatrices(true);
				node->pathSlot.GetCurrent()->pathSlot.GetCurrent()->pathPoints[node->index] = loc;
				node->pathSlot.GetCurrent()->pathNodes.Add(node);
				
				node->SetLinkColor(Stuff::RGBAColor(1.0f,1.0f,0.0f,0.0f));
				node->ShowLink(true);
				node->GetElement()->SetVolumeCullMode();
				node->GetElement()->Sync();
				node->UpdateLinkPointData();
			}
			else					// append node
			{
				node->pathSlot.GetCurrent()->pathSlot.GetCurrent()->pathPoints.push_back(loc);
				theApp.m_LastPathNode = node;
				
				if (node->prevnode)
				{
					node->prevnode->SetLinkColor(Stuff::RGBAColor(1.0f,1.0f,0.0f,0.0f));
					node->prevnode->ShowLink(true);
					node->prevnode->GetElement()->SetVolumeCullMode();
					node->prevnode->GetElement()->Sync();
					node->prevnode->UpdateLinkPointData();
				}
			}
			Time till = gos_GetElapsedTime();
			node->PostCollisionExecute(till);
		}
		else if(entity->IsDerivedFrom(EditorLight::DefaultData))
		{
			EditorLight* light;
			light = Cast_Object(EditorLight*,entity);
			light->LightSwitch();
		}
	}
	undone = true;
		theApp.instanceWindow->ResetInstanceLists();
	theApp.overviewWindow->DrawWindow();
}
