//
// Tools_EntityFilterOverlay.cpp
//
// Created by Richard Rice - 07/12/2004
// 
// Copyright (C) 2004 Rebellion, All Rights Reserved.
//

#include "Core/Asura.h"
#include "Entity/Tools_EntityFilterOverlay.h"

#include "Interface/Asura_Dialog.h"
#include "Interface/Asura_Overlay.h"

#include "Entity/Tools_Entity_Object.h"
#include "Objects/Tools_Object.h"
#include "Objects/Tools_Object_System.h"


Tools_EntityFilterOverlay::Tools_EntityFilterOverlay(Asura_String xTitle,List<int>* pxFilterOutList)
:Tools_Modal_Overlay(xTitle)
{
	m_pxFilterOutList = pxFilterOutList;

	m_ppszTypeStrings = 0;
	
	//add all the type names to the overlay
	for(CLIF<Tools_Object*> olif(&Tools_Object_System::ObjectList);!olif.done();olif.next())
	{
		if(!olif()->IsEntityObject()) continue;

		Tools_Entity_Object* pxEntityObject = (Tools_Entity_Object*)olif();

		//add this object's type to the type list
		AddToTypeList(pxEntityObject->GetTypeDescription(),pxEntityObject->Entity->GetClassification());
	}


	m_ppszTypeStrings = new char*[m_xTypeList.size()];
	for(int i=0;i<m_xTypeList.size();i++)
	{
		m_ppszTypeStrings[i] = m_xTypeList[i]->xString.GetString();
	}
}

Tools_EntityFilterOverlay::~Tools_EntityFilterOverlay()
{
	while(m_xTypeList.size())
	{
		delete m_xTypeList.first_entry();
		m_xTypeList.delete_first_entry();
	}

	delete [] m_ppszTypeStrings;
}

void Tools_EntityFilterOverlay::AddToTypeList(const char* pszTypeName,int iType)
{
	if(!pszTypeName || !strlen(pszTypeName)) return;

	//check for this type already being added
	LIF<ListSelectionItem*> xTypeLIF(&m_xTypeList);

	for(xTypeLIF.restart();!xTypeLIF.done();xTypeLIF.next())
	{
		if(iType == xTypeLIF()->iData) return;
	}


	//create a ListSelectionItem
	ListSelectionItem* pxItem = new ListSelectionItem;
	pxItem->xString = pszTypeName;
	pxItem->iData = iType;
	pxItem->bSelectedInitially = false;
	pxItem->bHidden = false;

	//add it into the list (sorted)

	for(xTypeLIF.restart();!xTypeLIF.done();xTypeLIF.next())
	{
		if(pxItem->xString.Compare(xTypeLIF()->xString,true)<=0)
		{
			m_xTypeList.add_entry_before(pxItem,xTypeLIF());
			break;
		}
	}
	if(xTypeLIF.done())
	{
		m_xTypeList.add_entry(pxItem);
	}
}



void Tools_EntityFilterOverlay::InitialiseOverlay(Asura_Overlay* pxOverlay)
{
	m_iSelectionIndex = 0;


	//add controls for the list of object types
	Asura_Dialog* pxDialog;
	Asura_Vector_2 xOffset = Asura_Vector_2(1.0f,3.0f);


	int iNumLines = min(m_xTypeList.size(),10);

	pxDialog = new Asura_List_Dialog(xOffset,m_ppszTypeStrings,&m_iSelectionIndex,iNumLines,m_xTypeList.size(),_IsIncluded,_ToggleInclude,(int)this);
	pxOverlay->AddDialog(pxDialog);
	xOffset.y=pxDialog->m_xMaxCoord.y;
	xOffset.y+=1.0f;

	pxDialog = new Asura_Function_Dialog("Check All",xOffset,_CheckAll,(int)this);
	pxOverlay->AddDialog(pxDialog);
	xOffset.y+=Asura_Dialog::DefaultSpacing();

	pxDialog = new Asura_Function_Dialog("Check None",xOffset,_CheckNone,(int)this);
	pxOverlay->AddDialog(pxDialog);
	xOffset.y+=Asura_Dialog::DefaultSpacing();

	pxDialog = new Asura_Function_Dialog("Invert",xOffset,_Invert,(int)this);
	pxOverlay->AddDialog(pxDialog);
	xOffset.y+=Asura_Dialog::LargeSpacing();

	pxDialog = new Asura_Function_Dialog("Done",xOffset,OkaySelected,&pxOverlay->m_bShouldClose);
	pxOverlay->AddDialog(pxDialog);
	xOffset.y+=2.0f;
	


	
}

bool Tools_EntityFilterOverlay::IsIncluded(int iIndex)
{
	int iType = m_xTypeList[iIndex]->iData;
	return !m_pxFilterOutList->contains(iType);
}

void Tools_EntityFilterOverlay::ToggleInclude(int iIndex)
{
	int iType = m_xTypeList[iIndex]->iData;
	if(m_pxFilterOutList->contains(iType))
		m_pxFilterOutList->delete_entry(iType);
	else
		m_pxFilterOutList->add_entry(iType);
}

void Tools_EntityFilterOverlay::CheckAll()
{
	while(m_pxFilterOutList->size())
	{
		m_pxFilterOutList->delete_first_entry();
	}
}

void Tools_EntityFilterOverlay::CheckNone()
{
	for(int i=0;i<m_xTypeList.size();i++)
	{
		int iType = m_xTypeList[i]->iData;
		if(!m_pxFilterOutList->contains(iType))
		{
			m_pxFilterOutList->add_entry(iType);
		}

	}
}

void Tools_EntityFilterOverlay::Invert()
{
	for(int i=0;i<m_xTypeList.size();i++)
	{
		int iType = m_xTypeList[i]->iData;
		if(m_pxFilterOutList->contains(iType))
			m_pxFilterOutList->delete_entry(iType);
		else
			m_pxFilterOutList->add_entry(iType);
	}
}


