//////////////////////////////////////////////////////////////////////
//
// SectorList.c: interface for the CPA_SectorList class.
//
//////////////////////////////////////////////////////////////////////
// Author: Silviu Simen  01 september 1998
//////////////////////////////////////////////////////////////////////

#include "itf/cpaslist.hpp"

/////////////////////////////////////////////////////////////////////////////
CPA_ListBySector::CPA_ListBySector	(void)
{

}

/////////////////////////////////////////////////////////////////////////////
CPA_ListBySector::~CPA_ListBySector (void)
{

}


/////////////////////////////////////////////////////////////////////////////
void CPA_ListBySector::fn_vCleanAllListsOfSectors (void)
{
	CPA_ListOfObjectsInSectorsByType	*pListType;
	CPA_ListOfObjectsInSectors			*pList;
	POSITION							pos;

	// update list by sector
	pos = m_lstList.GetHeadPosition();
	while (pos)
	{
		pList = m_lstList.GetNext(pos);
		pList->m_lstObjectList.DeleteAllElements();
	}

	// update list by sector and type
	pos = m_lstTypeList.GetHeadPosition();
	while (pos)
	{
		pListType = m_lstTypeList.GetNext(pos);
		pListType->m_lstObjectList.DeleteAllElements();
	}
}

/////////////////////////////////////////////////////////////////////////////
void CPA_ListBySector::AddElement (CPA_SuperObject * pObject, SECTOR_TYPE pSector)
{
	CPA_BaseObjectList	*pListType;
	CPA_BaseObjectList	*pList;

	// update list by sector
	pList = GetListOfSector(pSector);
	if (pList)
		pList->fn_bAddObject(pObject);

	// update list by sector and type
	pListType = GetListOfSectorByType(pSector, HIE_fn_ulGetSuperObjectType(pObject->GetStruct()));
	if (pListType)
		pListType->fn_bAddObject(pObject);
}

/////////////////////////////////////////////////////////////////////////////
BOOL CPA_ListBySector::RemoveElement (CPA_SuperObject * pObject)
{
	CPA_ListOfObjectsInSectorsByType	*pListType;
	CPA_ListOfObjectsInSectors			*pList;
	POSITION							pos;
	BOOL								bFound;
	BOOL								bRes = FALSE;

	// update list by sector
	bFound = FALSE;
	pos = m_lstList.GetHeadPosition();
	while (pos && !bRes)
	{
		pList = m_lstList.GetNext(pos);
		if (pList->m_lstObjectList.fn_bExist(pObject))
		{
			bRes = pList->m_lstObjectList.fn_bRemoveObject(pObject);
			bFound = TRUE;
		}
	}

	// update list by sector and type
	bFound = FALSE;
	pos = m_lstTypeList.GetHeadPosition();
	while (pos && !bRes)
	{
		pListType = m_lstTypeList.GetNext(pos);
		if (pListType->m_lstObjectList.fn_bExist(pObject))
		{
			bRes = pListType->m_lstObjectList.fn_bRemoveObject(pObject);
			bFound = TRUE;
		}
	}

	return bRes;
}

/////////////////////////////////////////////////////////////////////////////
BOOL CPA_ListBySector::UpdateElement (CPA_SuperObject * pObject, SECTOR_TYPE pNewSector)
{
	CPA_ListOfObjectsInSectorsByType	*pListType;
	CPA_ListOfObjectsInSectors			*pList;
	CPA_BaseObjectList					*pNewListType;
	CPA_BaseObjectList					*pNewList;
	POSITION							pos;
	BOOL								bFound = FALSE;
	BOOL								bRes = FALSE;

	// get list by sector
	pNewList = GetListOfSector(pNewSector);
	if (!pNewList)
		return FALSE;

	if (!pNewList->fn_bExist(pObject))
	{
		// update list by sector
		bFound = FALSE;
		pos = m_lstList.GetHeadPosition();
		while (pos && !bRes)
		{
			pList = m_lstList.GetNext(pos);
			if (pList->m_lstObjectList.fn_bExist(pObject))
			{
				pList->m_lstObjectList.fn_bRemoveObject(pObject);
				bFound = TRUE;
			}
		}
		bRes = pNewList->fn_bAddObject(pObject);
	}

	// get list by sector
	pNewListType = GetListOfSectorByType(pNewSector, HIE_fn_ulGetSuperObjectType(pObject->GetStruct()));
	if (!pNewListType)
		return FALSE;

	if (!pNewListType->fn_bExist(pObject))
	{
		// update list by sector
		bFound = FALSE;
		pos = m_lstTypeList.GetHeadPosition();
		while (pos && !bRes)
		{
			pListType = m_lstTypeList.GetNext(pos);
			if (pListType->m_lstObjectList.fn_bExist(pObject))
			{
				bRes = pListType->m_lstObjectList.fn_bRemoveObject(pObject);
				bFound = TRUE;
			}
		}
		bRes = pNewListType->fn_bAddObject(pObject);
	}

	return bRes;
}

/////////////////////////////////////////////////////////////////////////////
CPA_BaseObjectList * CPA_ListBySector::GetListOfSector (SECTOR_TYPE pSector)
{
	CPA_ListOfObjectsInSectors *pList;
	POSITION					pos;

	// search list by sector
	pos = m_lstList.GetHeadPosition();
	while (pos)
	{
		pList = m_lstList.GetNext(pos);
		if (pList->m_pSector == pSector)
			return &pList->m_lstObjectList;
	}
	// sector was not found => create it
	pList = new CPA_ListOfObjectsInSectors;
	pList->m_pSector = pSector;
	m_lstList.AddTail(pList);
	return &pList->m_lstObjectList;
}

/////////////////////////////////////////////////////////////////////////////
CPA_BaseObjectList * CPA_ListBySector::GetListOfSectorByType (SECTOR_TYPE pSector,unsigned long ulType)
{
	CPA_ListOfObjectsInSectorsByType	*pList;
	POSITION							pos;

	// search list by sector
	pos = m_lstTypeList.GetHeadPosition();
	while (pos)
	{
		pList = m_lstTypeList.GetNext(pos);
		if ((pList->m_pSector == pSector) && (pList->m_ulType == ulType))
			return &pList->m_lstObjectList;
	}
	// sector was not found => create it
	pList = new CPA_ListOfObjectsInSectorsByType;
	pList->m_pSector = pSector;
	pList->m_ulType = ulType;
	m_lstTypeList.AddTail(pList);
	return &pList->m_lstObjectList;
}

/////////////////////////////////////////////////////////////////////////////
CPA_BaseObjectList * CPA_ListBySector::GetListOfSectorByName (CString csName)
{
	CPA_ListOfObjectsInSectors *pList;
	POSITION					pos;

	// search list by sector
	pos = m_lstList.GetHeadPosition();
	while (pos)
	{
		pList = m_lstList.GetNext(pos);
		if (pList->m_pSector->GetName() == csName)
			return &pList->m_lstObjectList;
	}
	// sector was not found
	return NULL;
}


