#include "stdafx.h"
#include "selection.h"
#include "EditorWaypoint.h"
#include <Adept\Map.hpp>
#include "LightWnd.h"

CSelectionList*
	CSelectionList::Instance = NULL;

extern CMW4GameEdApp theApp;

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
CSelectionNode::~CSelectionNode()
{
//	selectedEntity->GetElement()->DetachChild(lineCloud);
//	delete lineCloud;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
CSelectionList::CSelectionList():
	Plug(Plug::DefaultData),
	selectionList(NULL)
{
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
CSelectionList::~CSelectionList()
{
	if(!selectionList.IsEmpty())
	{
		ChainIteratorOf<CSelectionNode*> iterator(&selectionList);
		iterator.DeletePlugs();
	}
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void 
	CSelectionList::AddSelection(Entity *entity)
{
	Check_Pointer(this);
	Check_Object(entity);
	Check_Object(Map::Instance);

	if(entity->IsDerivedFrom(Objective::DefaultData)) return;

	if (entity == Map::Instance)	// can't select the map.
		ClearSelectionList();

	if (!FindSelection(entity))
	{
		CSelectionNode *selection_node;

		selection_node = new CSelectionNode(entity);
		Register_Object(selection_node);
		selectionList.Add(selection_node);
		Verify(entity->GetElement()->GetCallbackSet() == ElementRenderer::Element::Callbacks);

		if (entity->IsDerivedFrom(EditorBoundaryNode::DefaultData))
		{
			EditorBoundaryNode* node;
			node = Cast_Object(EditorBoundaryNode*, entity);
			node->CheckValidPos();
		}
		else
		{
			if (entity->GetCollisionMask() != Entity::NeverCollidesMask) // take this out when all objects have collision
			{
				if (entity->IsMultiZone())
					entity->GetElement()->SetCallbackIndex(ElementRenderer::Element::DrawRedBounds);
				else if (entity->IsMultiTile())
					entity->GetElement()->SetCallbackIndex(ElementRenderer::Element::DrawYellowBounds);
				else
					entity->GetElement()->SetCallbackIndex(ElementRenderer::Element::DrawGreenBounds);
			}
			else
				entity->GetElement()->SetCallbackIndex(ElementRenderer::Element::DrawGreenBounds);

			if (theApp.lightDlg && theApp.lightDlg->IsWindowVisible())
			{
				if (GetSelectionCount() == 1)
				{
					if (entity->IsDerivedFrom(EditorLight::DefaultData))
					{
						EditorLight* light;
						light = Cast_Object(EditorLight*,entity);
						theApp.lightDlg->SetLight(light);
					}
					else
					{
						theApp.lightDlg->ShowWindow(SW_HIDE);
					}
				}
				else
				{
					theApp.lightDlg->ShowWindow(SW_HIDE);
				}
			}
		}
	}
//	theApp.toolBar->EnableButton(ID_EDIT_CUT);
//	theApp.toolBar->EnableButton(ID_EDIT_COPY);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void 
	CSelectionList::RemoveSelection(Entity *entity, bool restore_collision)
{
	Check_Pointer(this);
	Check_Object(this);

	CSelectionNode *selection_node;

	entity->GetElement()->SetCallbackIndex(0);
	selection_node = FindSelection(entity);

	if(selection_node)
	{
		if(restore_collision)
		{
			Entity *entity;
			entity = selection_node->selectedEntity;
			Check_Object(entity);
			entity->SetCollisionMask(selection_node->collisionMask);
		}
		Unregister_Object(selection_node);
		delete selection_node;
	}
	if (!GetSelectionCount())
	{
//		theApp.toolBar->EnableButton(ID_EDIT_CUT,FALSE);
//		theApp.toolBar->EnableButton(ID_EDIT_COPY,FALSE);
	}
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void 
	CSelectionList::RestoreCollision()
{
	ChainIteratorOf<CSelectionNode*> iterator(&selectionList);
	CSelectionNode *selection_node;
	Entity *entity;
	
	if (!(selectionList.IsEmpty()))
	{
		while((selection_node = iterator.ReadAndNext()) != NULL)
		{
			entity = selection_node->selectedEntity;
			Check_Object(entity);
			entity->SetCollisionMask(selection_node->collisionMask);
		}
	}
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
CSelectionNode 
	*CSelectionList::FindSelection(Entity *entity)
{
	Check_Pointer(this);
	Check_Object(entity);

	bool found;
	ChainIteratorOf<CSelectionNode*> iterator(&selectionList);
	CSelectionNode *selection_node;
	
	found = false;

	if (!(selectionList.IsEmpty()))
	{
		while((selection_node = iterator.ReadAndNext()) != NULL)
		{
			if(entity == selection_node->selectedEntity)
			{
				return selection_node;
			}
		}
	}
	return NULL;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void 
	CSelectionList::ClearSelectionList(bool restore_collision)
{
	Check_Pointer(this);

	CSelectionNode *selection_node;
	ChainIteratorOf<CSelectionNode*> iterator(&selectionList);

	if(!selectionList.IsEmpty())
	{
		iterator.First();
		while((selection_node = iterator.ReadAndNext()) != NULL)
		{
			if(restore_collision)
			{
				Entity *entity;
				entity = selection_node->selectedEntity;
				Check_Object(entity);
				entity->SetCollisionMask(selection_node->collisionMask);
			}
			selection_node->selectedEntity->GetElement()->SetCallbackIndex(0);
			Unregister_Object(selection_node);
			delete selection_node;
		}
	}
//	theApp.toolBar->EnableButton(ID_EDIT_CUT,FALSE);
//	theApp.toolBar->EnableButton(ID_EDIT_COPY,FALSE);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	CSelectionList::RemoveCollision()
{
	Check_Pointer(this);
	CSelectionNode *selection_node;
	Entity *entity;
	ChainIteratorOf<CSelectionNode*> iterator(&selectionList);

	if(!selectionList.IsEmpty())
	{
		iterator.First();
		while((selection_node = iterator.ReadAndNext()) != NULL)
		{
			Check_Object(selection_node);
			entity = selection_node->selectedEntity;
			Check_Object(entity);

			if (entity->GetSolidVolume() ||
				entity->GetCollisionMask() != Entity::NeverCollidesMask) // take this out when all objects have collision
			{
				entity->SetCollisionMask(Entity::EditorIsMovingFlag);
			}
		}
	}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
int 
	CSelectionList::GetSelectionCount()
{
	Check_Pointer(this);
	ChainIteratorOf<CSelectionNode*> iterator(&selectionList);
	return int(iterator.GetSize());
}
