// Implementation for the List Dialog functions
//
// << Part of _AInterf.cpp >>
//
// YB
////////////////////////////////////////////////
#include "StdAfx.h"

#include "_AInterf.hpp"

#include "EDACInst.hpp"
#include "EDACModl.hpp"
#include "EDACCnst.hpp"
#include "EDACIres.h"
// Shaitan => optimisation lists in the level
#include "EDACQuer.hpp"
// End Shaitan => optimisation lists in the level

//CPA2 Stegaru Cristian 98-05
#include "EDACStrg.hpp"
//End CPA2 Stegaru Cristian 98-05

#include "TFa.h"
#include "ErO.h"
#include "X:\cpa\main\inc\_EditID.h"

#undef CPA_WANTS_IMPORT
#undef CPA_EXPORT
#define CPA_WANTS_EXPORT
    #include "_Actors.hpp"
#undef CPA_WANTS_EXPORT
#define CPA_WANTS_IMPORT


#define EDAC_C_TreeIconSize					16

//######################################################################################
//######################################################################################
// Lists Dialog
//######################################################################################
//######################################################################################

//**************************************************************************************
// This is an Init function
void CPA_Actor_Editor_Interface::GetListsForDialog(CPA_DialogList *pDialog)
{
	//Lists
	pDialog->fn_vAddANewList(EDAC_C_szFamiliesList, GetMainWorld()->fn_p_oGetOriginalObjectList(C_szFamilyTypeName));
	pDialog->fn_vAddANewList(EDAC_C_szModelsList, &(m_clDocument.m_clModelsList));
	pDialog->fn_vAddANewList(EDAC_C_szInstancesList, &(m_clDocument.m_clInstancesList));
	pDialog->fn_vAddANewList(EDAC_C_szAlwaysList, &(m_clDocument.m_clAlwaysList));
	//CPA2 Stegaru Cristian 98-05
	pDialog->fn_vAddANewList(EDAC_C_szUnloadedAlwaysList, &(m_clDocument.m_clUnloadedAlwaysList));
	//End CPA2 Stegaru Cristian 98-05

	//Tree 
	//Prepares Icons for tree
	m_clImageListForTree.Create(EDAC_C_TreeIconSize, EDAC_C_TreeIconSize, ILC_MASK, 0, 6);
	m_clImageListForTree.Add(LoadIcon(GetDLLIdentity()->hModule, MAKEINTRESOURCE(IDI_CAR_TREE_FAMILIES)));
	m_clImageListForTree.Add(LoadIcon(GetDLLIdentity()->hModule, MAKEINTRESOURCE(IDI_CAR_TREE_MODELS)));
	m_clImageListForTree.Add(LoadIcon(GetDLLIdentity()->hModule, MAKEINTRESOURCE(IDI_CAR_TREE_INSTANCES)));
	m_clImageListForTree.Add(LoadIcon(GetDLLIdentity()->hModule, MAKEINTRESOURCE(IDI_CAR_TREE_ALWAYS)));
	
	///States
	m_clImageListForTree.Add(LoadIcon(GetDLLIdentity()->hModule, MAKEINTRESOURCE(IDI_CAR_TREE_LOADED)));
	m_clImageListForTree.Add(LoadIcon(GetDLLIdentity()->hModule, MAKEINTRESOURCE(IDI_CAR_TREE_UNLOADED)));

	m_pclTreeRoot = GetInterface()->GetNewSuperObject(E_ss_NoSave);
	pDialog->fn_vAddANewTree(	EDAC_C_szTreeView,
														m_pclTreeRoot,
														&m_clImageListForTree,
														&m_clImageListForTree);

	m_pri_bTreeMustShowUnloadedObjects = m_clDocument.m_pri_bTreeMustShowUnloadedObjects;
	m_pri_bTreeMustOnlyShowFamiliesWithModels = m_clDocument.m_pri_bTreeMustOnlyShowFamiliesWithModels;
}

//**************************************************************************************
void CPA_Actor_Editor_Interface::fn_vInitDefaultParameters(CPA_DialogList *pDialog)
{
	pDialog->SetDefaultDisplay(FALSE);

	pDialog->SetDefaultButtonState(FALSE);
	pDialog->SetDefaultTestName("<< No Test >>");
//	pDialog->SetDefaultTypeName(EDAC_C_szModelsList);
	pDialog->SetDefaultTypeName(m_clDocument.m_csInitDialogListType);
}

//**************************************************************************************
void CPA_Actor_Editor_Interface::m_pub_fn_vSetSelectionInDialogList(CPA_Actor *_pclNewSelection)
{
	if ( m_clDocument.m_bMustSynchronizeDialogListWithEdition )
	{
		if ( (_pclNewSelection != NULL) && (_pclNewSelection->fn_bIsAvailable()) )
		{
 			if ( _pclNewSelection->m_fn_bIsAModel() )
			{
				m_pclFamilyFilter = NULL;
				m_pclModelFilter = _pclNewSelection;
			}
			else
			{
				m_pclFamilyFilter = NULL;
				m_pclModelFilter = NULL;
				m_pclSelectedInstance = _pclNewSelection;
			}
 			
			m_pclSelectedActorForTreeView = _pclNewSelection;

			//In Tree mode
			if ( m_clDocument.m_pclDialogList->GetCurrentType().CompareNoCase(EDAC_C_szTreeView) != 0 )
			{
				if ( _pclNewSelection->m_fn_bIsAModel() )
					m_clDocument.m_pclDialogList->SetCurrentType(EDAC_C_szModelsList);
				else
					m_clDocument.m_pclDialogList->SetCurrentType(EDAC_C_szInstancesList);
			}

			m_clDocument.m_pclDialogList->fn_vUpdateSelection(E_lrm_ChangeSelection);
		}
	}
}

//**************************************************************************************
void CPA_Actor_Editor_Interface::fn_vSetANewTest(CPA_DialogList *pDialog,
																								 CString csCurrentList)
{
	CString csButtonText = "<< No Filter >>";
	BOOL bButtonMustBeEnabled = TRUE;
	BOOL bButtonState = FALSE;
	
	if ( csCurrentList.Compare(EDAC_C_szModelsList) == 0 )
	{
		if ( m_pclFamilyFilter != NULL )
			csButtonText = CString("Models of Family '") + m_pclFamilyFilter->GetName() + CString("'");
		else
			csButtonText = "All Models";

		bButtonMustBeEnabled = TRUE;
		bButtonState = TRUE;

	}																							
	else if ( csCurrentList.Compare(EDAC_C_szInstancesList) == 0 )
	{
		if ( m_pclModelFilter != NULL )
			csButtonText = CString("Instances of Model '") 
							+ m_pclModelFilter->m_fn_pclGetEditorActor()->m_fn_csGetActorName() + CString ("'");
		else if ( m_pclFamilyFilter != NULL )
			csButtonText = CString("Instances of Family '") 
							+ m_pclFamilyFilter->GetName() + CString ("'");
		else
			csButtonText = "All Instances"; 
			
		bButtonMustBeEnabled = TRUE;
		bButtonState = TRUE;
	}
	else if ( csCurrentList.Compare(EDAC_C_szAlwaysList) == 0 )
	{
		if ( m_pclModelFilter != NULL )
			csButtonText = CString("Always of Model '") 
							+ m_pclModelFilter->m_fn_pclGetEditorActor()->m_fn_csGetActorName() + CString ("'");
		else if ( m_pclFamilyFilter != NULL )
			csButtonText = CString("Always of Family '") 
							+ m_pclFamilyFilter->GetName() + CString ("'");
		else
			csButtonText = "All Always"; 
			
		bButtonMustBeEnabled = TRUE;
		bButtonState = TRUE;
	}

	pDialog->fn_vInitButtonTest((char *)LPCTSTR(csButtonText),
															bButtonState,
															bButtonMustBeEnabled);
}

//**************************************************************************************
BOOL CPA_Actor_Editor_Interface::fn_bTestFunction(CString csCurrentType,
																									CString csTestName,
																									CPA_BaseObject *pEdObj)
{
	BOOL bReturnValue = TRUE;

	if	( csCurrentType.Compare(EDAC_C_szModelsList) == 0 )
	{
		if ( m_pclFamilyFilter != NULL )
			bReturnValue = ( ((CPA_Actor *)pEdObj)->m_pub_fn_pclGetFamily() == m_pclFamilyFilter );
	}
	else if	( csCurrentType.Compare(EDAC_C_szInstancesList) == 0 )
	{
		if ( m_pclModelFilter != NULL )
		{
			CPA_Actor *pclModel = ((EdActors_EditorActorInstance *)(((CPA_Actor *)pEdObj)->m_fn_pclGetEditorActor()))->m_fn_pclGetModel();
			bReturnValue = ( pclModel == m_pclModelFilter );
		}
		else if ( m_pclFamilyFilter != NULL )
		{
			CPA_Family *pclFamily = ((CPA_Actor *)pEdObj)->m_pub_fn_pclGetFamily();
			bReturnValue = ( pclFamily == m_pclFamilyFilter );
		}
	}

	return bReturnValue;
}

//**************************************************************************************
BOOL CPA_Actor_Editor_Interface::fn_bOnButtonTest(CPA_DialogList *pDialog,
																									CString csTypeName,
																									tdeListDrawMode eDraw)
{
	BOOL bReturnValue = TRUE;

	if ( (m_pclFamilyFilter != NULL) || (m_pclModelFilter != NULL) )
	{
 		m_pclFamilyFilter = NULL;
		m_pclModelFilter = NULL;

		pDialog->fn_vUpdateSelection(E_lrm_ReinitList);

		CString csButtonText;
		if ( csTypeName.Compare(EDAC_C_szModelsList) == 0 )
			csButtonText = "All Models";
		else if ( csTypeName.Compare(EDAC_C_szInstancesList) == 0 )
			csButtonText = "All Instances"; 
		else if ( csTypeName.Compare(EDAC_C_szAlwaysList) == 0 )
			csButtonText = "All Always Models"; 

		pDialog->fn_vInitButtonTest((char *)LPCTSTR(csButtonText),
																TRUE,
																TRUE);
	}
	else
	{
		if ( csTypeName.Compare(EDAC_C_szModelsList) == 0 )
		{
			pDialog->SetCurrentType(EDAC_C_szFamiliesList);
			fn_vSetANewTest(pDialog, EDAC_C_szFamiliesList);
		}
		else if ( csTypeName.Compare(EDAC_C_szInstancesList) == 0 )
		{
			pDialog->SetCurrentType(EDAC_C_szModelsList);
			fn_vSetANewTest(pDialog, EDAC_C_szModelsList);
		}
		else if ( csTypeName.Compare(EDAC_C_szAlwaysList) == 0 )
		{
			pDialog->SetCurrentType(EDAC_C_szModelsList);
			fn_vSetANewTest(pDialog, EDAC_C_szModelsList);
		}
	}

	return bReturnValue;
}

//***********************************************************************
BOOL CPA_Actor_Editor_Interface::fn_bOnSelChangeComboList(CPA_DialogList *pDialog,
																													CString csTypeName)
{
	return FALSE;
}

//***********************************************************************
BOOL CPA_Actor_Editor_Interface::fn_bOnSelChangeListObjects(CPA_DialogList *pDialog,
																														CString csTypeName,
																														CPA_BaseObject *pSelectedObject,
																														BOOL bUnselect)
{
	if	(		(csTypeName.CompareNoCase(EDAC_C_szInstancesList) == 0)
			||	( csTypeName.CompareNoCase(EDAC_C_szAlwaysList) == 0 )
			)
	{
		if ( bUnselect )
		{
			m_pclSelectedInstance = NULL;
		}
		else
		{
			m_pclFamilyFilter = NULL;
			m_pclModelFilter = NULL;

			//Displays Instance
			m_pclSelectedInstance = (CPA_Actor *)pSelectedObject;
			m_clDocument.m_fn_vDisplayActor(m_pclSelectedInstance->m_fn_pclGetEditorActor(), ED_ACTORS_eModeOfActorSelection_InListDialog);
		}
	}
	else if ( csTypeName.CompareNoCase(EDAC_C_szModelsList) == 0 )
	{
		if ( bUnselect )
			m_pclModelFilter = NULL;
		else
		{
			CPA_Actor *pclSelectedModel = (CPA_Actor *)pSelectedObject;
			if ( pclSelectedModel->fn_bIsAvailable() )
				m_pclModelFilter = pclSelectedModel;
		}
		m_pclFamilyFilter = NULL;

		//Displays Model
		if ( m_pclModelFilter != NULL )
			m_clDocument.m_fn_vDisplayActor(m_pclModelFilter->m_fn_pclGetEditorActor(), ED_ACTORS_eModeOfActorSelection_InListDialog);
	}
	else if ( csTypeName.CompareNoCase(EDAC_C_szFamiliesList) == 0 )
	{
		if ( bUnselect )
			m_pclFamilyFilter = NULL;
		else
			m_pclFamilyFilter = (CPA_Family *)pSelectedObject;
		
		m_pclModelFilter = NULL;
	}
	//CPA2 Stegaru Cristian 98-05
	else if (csTypeName.CompareNoCase(EDAC_C_szUnloadedAlwaysList) == 0)
	{
		if (bUnselect)
			m_pSelectedUnloadedAlways = NULL;
		else
			m_pSelectedUnloadedAlways = (CPA_UnloadedAlways *)pSelectedObject;
	}
	//End CPA2 Stegaru Cristian 98-05

	else
	{
		CPA_List<CPA_SuperObject>	*pList = GetInterface()->GetObjectListByType(C_szSectorTypeName);
		CPA_SuperObject				*pSector;
		POSITION					pos;
		BOOL						bFound = FALSE;

		for (pSector = pList->GetHeadElement(pos); pSector; pSector = pList->GetNextElement(pos)) 
		{
			 if (csTypeName.CompareNoCase(pSector->GetName()) == 0)
				 bFound = TRUE;
		}
		if (bFound)
		{
			if (bUnselect)
				m_pclSelectedInstance = NULL;
			else
			{
				m_pclFamilyFilter = NULL;
				m_pclModelFilter = NULL;

				//Displays Instance
				m_pclSelectedInstance = (CPA_Actor *)((CPA_SuperObject *)pSelectedObject)->GetObject();
				m_clDocument.m_fn_vDisplayActor(m_pclSelectedInstance->m_fn_pclGetEditorActor(), ED_ACTORS_eModeOfActorSelection_InListDialog);
			}
		}
	}

	pDialog->fn_vUpdateSelection(E_lrm_ChangeSelection);

	return TRUE;
}

//***********************************************************************
BOOL CPA_Actor_Editor_Interface::fn_bOnDblClkListObjects(CPA_DialogList *pDialog,
																												 CString csTypeName,
																												 CPA_BaseObject *pSelectedObject)
{
	if ( pSelectedObject != NULL )
	{
		//CPA2 Stegaru Cristian 98-05
		if (EDAC_C_szUnloadedAlwaysList == csTypeName)
		{
			CPA_UnloadedAlways *pUAlways = (CPA_UnloadedAlways *)pSelectedObject;
			if (pUAlways->mfn_bIsLoaded ()) //use this method to deal with the two times this function is called for every double click action
				delete pUAlways;
			else if (!pUAlways->m_bOnceDblClk && IDYES == AfxMessageBox ("Do you want to load this always character?\n(it will be also added in the *.alw file)", MB_YESNO | MB_ICONQUESTION))
			{
				m_clDocument.m_clUnloadedAlwaysList.fn_bRemoveObject (pUAlways);
				mfn_vLoadAlways (pUAlways);
				pUAlways->mfn_vSetLoaded (TRUE);
				pDialog->fn_vReinitDialog ();
			}
			pUAlways->m_bOnceDblClk = !pUAlways->m_bOnceDblClk;
		}
		else if ( pSelectedObject->fn_bIsAvailable() )
		//End CPA2 Stegaru Cristian 98-05
		{
			//Displays childs of the Object
			if ( pSelectedObject->fn_bIsOfType(C_szActorModelTypeName) )
			{
 				m_pclModelFilter = (CPA_Actor *)pSelectedObject;
				m_pclFamilyFilter = NULL;

				pDialog->SetCurrentType(EDAC_C_szInstancesList);
				fn_vSetANewTest(pDialog, EDAC_C_szInstancesList);
			}
			else if ( pSelectedObject->fn_bIsOfType(C_szFamilyTypeName) )
			{
 				m_pclModelFilter = NULL;
				m_pclFamilyFilter = (CPA_Family *)pSelectedObject;

				pDialog->SetCurrentType(EDAC_C_szModelsList);
				fn_vSetANewTest(pDialog, EDAC_C_szModelsList);
			}
			else if (pSelectedObject->fn_bIsOfType(C_szActorInstanceTypeName) )
			{
				//Displays Instance
				if ((pSelectedObject == m_pclSelectedInstance) && (!m_pclSelectedInstance->m_fn_bIsAnAlways()))
					GetInterface()->fn_bSelectObject(((CPA_Actor *) pSelectedObject)->m_pub_fn_pclGetSuperObject(), TRUE);	
			}
		}
	}

	return FALSE;
}

//***********************************************************************
CPA_BaseObject  *CPA_Actor_Editor_Interface::GetDialogSelection (CPA_DialogList *pDialog,
																																 CString csTypeName,
																																 tdeListDrawMode eDrawMode)
{
	if ( csTypeName.CompareNoCase(EDAC_C_szInstancesList) == 0 )
	{
		return m_pclSelectedInstance;
	}
	else if ( csTypeName.CompareNoCase(EDAC_C_szModelsList) == 0 )
	{
		return m_pclModelFilter;
	}
	else if ( csTypeName.CompareNoCase(EDAC_C_szFamiliesList) == 0 )
	{
		return m_pclFamilyFilter;
	}
	else if ( csTypeName.CompareNoCase(EDAC_C_szAlwaysList) == 0 )
	{
		return m_pclSelectedInstance;
	}
	else if ( csTypeName.CompareNoCase(EDAC_C_szTreeView) == 0 )
	{
		return (m_pclSelectedActorForTreeView) ? m_pclSelectedActorForTreeView : m_clDocument.m_pclCurrentFamily;
	}
	//CPA2 Stegaru Cristian 98-05
	else if (csTypeName.CompareNoCase (EDAC_C_szUnloadedAlwaysList) == 0)
	{
		return m_pSelectedUnloadedAlways;
	}
	//End CPA2 Stegaru Cristian 98-05


	else
	{
		CPA_List<CPA_SuperObject>	*pList = GetInterface()->GetObjectListByType(C_szSectorTypeName);
		CPA_SuperObject				*pSector;
		POSITION					pos;
		BOOL						bFound = FALSE;

		for (pSector = pList->GetHeadElement(pos); pSector; pSector = pList->GetNextElement(pos)) 
		{
			 if (csTypeName.CompareNoCase(pSector->GetName()) == 0)
				 bFound = TRUE;
		}
		if (bFound)
			return (m_pclSelectedInstance ? m_pclSelectedInstance->m_pub_fn_pclGetSuperObject() : NULL);
	}

	return NULL;
}

//***********************************************************************
void CPA_Actor_Editor_Interface::m_fn_vSetListWithAFamily(CPA_Family *pclFamily)
{
	m_pclFamilyFilter = pclFamily;
	m_pclModelFilter = NULL;

	if ( m_clDocument.m_pub_fn_bCurrentModeIsInstance() )
		m_clDocument.m_pclDialogList->SetCurrentType(EDAC_C_szInstancesList);
	else if ( m_clDocument.m_pub_fn_bCurrentModeIsModel() )
		m_clDocument.m_pclDialogList->SetCurrentType(EDAC_C_szModelsList);
	else if ( m_clDocument.m_pub_fn_bCurrentModeIsAlwaysModel() )
		m_clDocument.m_pclDialogList->SetCurrentType(EDAC_C_szAlwaysList);
}

//***********************************************************************
void CPA_Actor_Editor_Interface::m_fn_vSetListWithAModel(EdActors_EditorActorModel *pclModel)
{
	m_pclFamilyFilter = NULL;
	m_pclModelFilter = pclModel->m_pclActor;

	m_clDocument.m_pclDialogList->SetCurrentType(EDAC_C_szInstancesList);
}


//######################################################################################
//######################################################################################
// Tree Dialog
//######################################################################################
//######################################################################################

#define EdActors_C_TreeMenuID_ShowUnloaded				80
#define EdActors_C_TreeMenuID_OnlyWithModels			81
#define EdActors_C_TreeMenuID_OnlyWithoutModels			82
#define EdActors_C_TreeMenuID_PreloadModels				83
#define EdActors_C_TreeMenuID_ForCamera					90


//***********************************************************************
BOOL CPA_Actor_Editor_Interface::fn_bOnSelChangeHierarchyTree(CPA_DialogList *pDialog,
																															CString csListName,
																															CPA_BaseObject *pSelectedObject,
																															CPA_BaseObject *pSelectedParent)
{
	//If a Model was clicked, displays it in Editor
	if	((pSelectedObject->GetType().Compare(C_szActorModelTypeName) == 0)&&(pSelectedObject->fn_bIsAvailable()))
		m_clDocument.m_fn_vDisplayActor(((CPA_Actor *)pSelectedObject)->m_fn_pclGetEditorActor(), ED_ACTORS_eModeOfActorSelection_InTreeView);

	// If an instance was clicked, select it in 3D view
	else if (pSelectedObject->GetType().Compare(C_szActorInstanceTypeName) == 0)
	{
		GetInterface()->fn_vCancelCurrentSelection();
		GetInterface()->fn_vAddSelectedObject(((CPA_Actor *)pSelectedObject)->m_pub_fn_pclGetSuperObject());
	}

	// if a family was clicked, register selection
	else if (pSelectedObject->GetType().Compare(C_szFamilyTypeName) == 0)
	{
		m_clDocument.m_pclCurrentFamily = pSelectedObject;
		m_pclSelectedActorForTreeView = NULL;
	}

	return FALSE;
}

//***********************************************************************
BOOL CPA_Actor_Editor_Interface::fn_bOnDblClkHierarchyTree(CPA_DialogList *pDialog,
																													 CString csListName,
																													 CPA_BaseObject *pSelectedObject,
																													 CPA_BaseObject *pSelectedParent)
{
	ERROR_ASSERT( csListName.CompareNoCase(EDAC_C_szTreeView) == 0 );

	BOOL bReturn = FALSE;

	//If an unloaded object is double-clicked, loads it
	//for Families and Models (Instances are always available)
	if	(		( pSelectedObject->GetType().Compare(C_szFamilyTypeName) == 0 )
			||	( pSelectedObject->GetType().Compare(C_szActorModelTypeName) == 0 )
			)
	{
		if ( !pSelectedObject->fn_bIsAvailable() )
		{
			pSelectedObject->GetEditor()->fn_bLoadBaseObject(pSelectedObject);
//			if (pSelectedObject->GetEditor() != this)
				pDialog->fn_vUpdateSelection(E_lrm_ReinitList);
		}

		bReturn = TRUE;
	}

	else if ( pSelectedObject->GetType().Compare(C_szActorInstanceTypeName) == 0 )
	{
		//Displays Instance
		if ( ! ((CPA_Actor *)pSelectedObject)->m_fn_bIsAnAlways())
			GetInterface()->fn_bSelectObject(((CPA_Actor *) pSelectedObject)->m_pub_fn_pclGetSuperObject(), TRUE);	
	}
	return bReturn;
}



//////////////////////////////////////////////////////////////////////////////////////////////////////
// Method	: mfn_bUnloadAlwaysFromLevel 
// Date		: 98/07/01
//////////////////////////////////////////////////////////////////////////////////////////////////////
// Description	:
// Author		: Stegaru Cristian - CPA
//////////////////////////////////////////////////////////////////////////////////////////////////////
// Modification	: 
// Date			:
// By			:
//////////////////////////////////////////////////////////////////////////////////////////////////////
BOOL CPA_Actor_Editor_Interface::mfn_bUnloadAlwaysFromLevel (CPA_Actor *pActor)
{
	if (NULL == pActor)
		return FALSE;

// SHAITAN => check if always is referenced
	CStringList lstOfRefAlways;
	CStringList lstOfReferences;

	AfxGetApp()->DoWaitCursor(1);

	CString csAlways = pActor->GetName();
	csAlways.MakeLower();

	//treat regular models
	Position pos = m_clDocument.m_clModelsList.GetHeadPosition ();
	while (pos)
	{
		CPA_Actor *pModel = (CPA_Actor *)g_pclInterface->m_clDocument.m_clModelsList.GetNext (pos);
		if (!pModel || !pModel->m_fn_bIsAModel () || (pActor->m_fn_pclGetModel() == pModel))
			continue;

		g_pclInterface->m_clDocument.mfn_vFillRefAlwaysForModel (pModel, lstOfRefAlways);

		if (lstOfRefAlways.Find(csAlways) != NULL)
			lstOfReferences.AddTail(pModel->GetName());			

		lstOfRefAlways.RemoveAll();
	}

	//treat always models
	pos = m_clDocument.m_clAlwaysList.GetHeadPosition ();
	while (pos)
	{
		CPA_Actor *pModel = (CPA_Actor *)g_pclInterface->m_clDocument.m_clAlwaysList.GetNext (pos);
		if (!pModel || !pModel->m_fn_bIsAModel () || (pActor->m_fn_pclGetModel() == pModel))
			continue;

		g_pclInterface->m_clDocument.mfn_vFillRefAlwaysForModel (pModel, lstOfRefAlways);

		if (lstOfRefAlways.Find(csAlways) != NULL)
			lstOfReferences.AddTail(pModel->GetName());			

		lstOfRefAlways.RemoveAll();
	}

	if (lstOfReferences.GetCount() > 0)
	{
		CString msg = "This always is referenced in the following models : \n";
		POSITION pos = lstOfReferences.GetHeadPosition();
		while (pos)
			msg += lstOfReferences.GetNext(pos) + "\n";
		msg += "Removing this always may cause incoherences in these models. \n";
		msg += "Are you sure you want to remove this always from the level ?";
		if (IDNO == AfxMessageBox (msg, MB_YESNO | MB_ICONQUESTION))
			return FALSE;
	}

	AfxGetApp()->DoWaitCursor(-1);

// END SHAITAN

	CPA_SuperObject *pSupObj;
	pSupObj = pActor->m_pub_fn_pclGetSuperObject();
	// if allowed, delete it
	if (pSupObj && !GetInterface()->fn_bDeleteObjectInHierarchy(pSupObj, TRUE))
	{
		CPA_UnloadedAlways *pAlways = new CPA_UnloadedAlways (g_pclInterface, g_c_csUnloadedAlwaysType, pActor->GetName () + CString ("UnloadedAlways"));
		if (!pAlways)
			return FALSE; //not enough memory

		pAlways->mfn_vSetUAlwaysName (pActor->GetName ());
		CString csAlwFile = pActor->GetReferencedSectionName ();
		int iInx = csAlwFile.ReverseFind ('^');
		ASSERT (-1 != iInx);
		csAlwFile = csAlwFile.Left (iInx);
		pAlways->mfn_vSetAlwFile (csAlwFile);
		m_clDocument.m_clUnloadedAlwaysList.fn_bAddObject (pAlways);

		m_clDocument.m_clAlwaysList.fn_bRemoveObject(pActor);
		m_clDocument.m_fn_vNotifyLevel(pActor, FALSE);
		
		m_clDocument.m_clInitializedAlwaysList.fn_bAddObject (pActor);
		fn_bRemoveObject (pActor);

		// update model's list of instances
		CPA_Actor * pModel = pActor->m_fn_pclGetModel();
		pModel->m_fn_pclGetEditorModel()->m_fn_vRemoveFromInstancesList(pActor->m_fn_pclGetEditorInstance());
// Shaitan => optimisation lists in the level
		if (pActor->m_fn_pclGetModel()->m_fn_pclGetEditorModel()->m_clInstancesList.IsEmpty())
			EDAC_fn_vProcessBrain(pActor->m_fn_pclGetModel(),pActor, TRUE);
// End Shaitan => optimisation lists in the level
	}
	return TRUE;					
}


/*===========================================================================
*		Description:	Key Down in cpa_dialoglist
*		Creation date:
*		Author:			Shaitan
*---------------------------------------------------------------------------
*		Revision date:       Author:
*=========================================================================*/
BOOL CPA_Actor_Editor_Interface::fn_bOnKeyDownInDialog (CPA_DialogList *pDialog, CString csTypeName, tdeListDrawMode eDraw, 
														CPA_BaseObject *pSelectedObject, UINT nChar, UINT nRepCnt, UINT nFlags)
{
	CPA_Actor		*pActor;
//	CPA_SuperObject *pSupObj;
	
	switch (nChar)
	{
		// delete selected object
		case 0x2E :
			if (pSelectedObject && ( pSelectedObject->GetType().Compare(C_szActorInstanceTypeName) == 0 ))
			{
				pActor = (CPA_Actor *) pSelectedObject;
				//CPA2 Stegaru Cristian 98/07/01
				if (mfn_bUnloadAlwaysFromLevel (pActor))
					pDialog->fn_vReinitDialog ();
				//End CPA2 Stegaru Cristian 98-05
			}
			return TRUE;
	}

	return FALSE;
}

//***********************************************************************
BOOL CPA_Actor_Editor_Interface::fn_bCanDragItemInHierarchyTree(CPA_DialogList *pDialog,
																																CString csListName,
																																CPA_BaseObject *pObjectToDrag)
{
	return FALSE;
}

//***********************************************************************
BOOL CPA_Actor_Editor_Interface::fn_bCanDropItemInHierarchyTree(CPA_DialogList *pDialog,
																																CString csListName,
																																CPA_BaseObject *pObjectToDrop,
																																CPA_BaseObject *pTarget)
{
	return FALSE;
}

//***********************************************************************
BOOL CPA_Actor_Editor_Interface::fn_bOnDragDropInHierarchyTree(CPA_DialogList *pDialog,
																															 CString csListName,
																															 CPA_BaseObject *pObject,
																															 CPA_BaseObject *pTarget)
{
	return FALSE;
}

//***********************************************************************
//Called to construct the tree
CPA_BaseObject *CPA_Actor_Editor_Interface::GetTreeNodeNextChild(CPA_DialogList *pDialog,
																																 CString csListName,
																																 CPA_BaseObject *pParent,
																																 CPA_BaseObject *pCurrentChild)
{
	ERROR_ASSERT( csListName.CompareNoCase(EDAC_C_szTreeView) == 0 );
	
	CPA_BaseObject *pclReturnedObject = NULL;
	
	if ( pParent == m_pclTreeRoot )
	{
		BOOL bObjectOK = FALSE;
		BOOL bCurrentChildPassed = FALSE;
		CPA_BaseObject *pCurrentFamily;
		Position pos = GetMainWorld()->fn_p_oGetOriginalObjectList(C_szFamilyTypeName)->GetHeadPosition();
		
		while ( ( pos != 0 ) && ( !bObjectOK ) )
		{
			pCurrentFamily = GetMainWorld()->fn_p_oGetOriginalObjectList(C_szFamilyTypeName)->GetNext(pos);

			if ( pCurrentChild == NULL )
			{
				if ( m_pri_bTreeMustShowUnloadedObjects ) 
					bObjectOK = TRUE;
				else
					bObjectOK = pCurrentFamily->fn_bIsAvailable();
			}
			else
			{
				if ( bCurrentChildPassed )
				{
					if ( m_pri_bTreeMustShowUnloadedObjects ) 
						bObjectOK = TRUE;
					else
						bObjectOK = pCurrentFamily->fn_bIsAvailable();
				}
				
				if ( !bCurrentChildPassed )
					bCurrentChildPassed = ( pCurrentFamily == pCurrentChild );
			}

			if ( bObjectOK && m_pri_bTreeMustOnlyShowFamiliesWithModels )
			{
				//Gets the list of Models owned by this Family
				CPA_List<CPA_BaseObject> clListOfModels;
 				GetMainWorld()->fn_lFindObjects(&clListOfModels, "", C_szActorModelTypeName, pCurrentFamily);

				BOOL bFamilyHasAtLeastOneModel = clListOfModels.GetCount() > 0;

				bObjectOK = bObjectOK && bFamilyHasAtLeastOneModel;
			}

			if ( bObjectOK )
				pclReturnedObject = pCurrentFamily;
		}
	}
	else if ( pParent->GetType().Compare(C_szFamilyTypeName) == 0 )
	{
		//Gets the list of Models owned by this Family
		CPA_List<CPA_BaseObject> clListOfModels;
 	  GetMainWorld()->fn_lFindObjects(&clListOfModels, "", C_szActorModelTypeName, pParent);

		BOOL bObjectOK = FALSE;
		BOOL bCurrentChildPassed = FALSE;
		CPA_BaseObject *pCurrentModel;
		POSITION pos = clListOfModels.GetHeadPosition();
		
		while ( ( pos != NULL ) && ( !bObjectOK ) )
		{
			pCurrentModel = clListOfModels.GetNext(pos);

			if ( pCurrentChild == NULL )
			{
				if ( m_pri_bTreeMustShowUnloadedObjects ) 
					bObjectOK = TRUE;
				else
					bObjectOK = pCurrentModel->fn_bIsAvailable();
			}
			else
			{
				if ( bCurrentChildPassed )
				{
					if ( m_pri_bTreeMustShowUnloadedObjects ) 
						bObjectOK = TRUE;
					else
						bObjectOK = pCurrentModel->fn_bIsAvailable();
				}
				
				if ( !bCurrentChildPassed )
					bCurrentChildPassed = ( pCurrentModel == pCurrentChild );
			}

			if ( bObjectOK )
				pclReturnedObject = pCurrentModel;
		}
	}
	else if ( pParent->GetType().Compare(C_szActorModelTypeName) == 0 )
	{
		//Gets the list of Instances owned by this Model
		CPA_List<CPA_BaseObject> clListOfInstances;
 	  GetMainWorld()->fn_lFindObjects(&clListOfInstances, "", C_szActorInstanceTypeName, pParent);

		BOOL bObjectOK = FALSE;
		BOOL bCurrentChildPassed = FALSE;
		CPA_BaseObject *pclCurrentInstance;
		POSITION pos = clListOfInstances.GetHeadPosition();
		
		while ( ( pos != NULL ) && ( !bObjectOK ) )
		{
			pclCurrentInstance = clListOfInstances.GetNext(pos);

			if ( pCurrentChild == NULL )
					bObjectOK = TRUE;
			else
			{
				if ( bCurrentChildPassed )
					bObjectOK = TRUE;
				
				if ( !bCurrentChildPassed )
					bCurrentChildPassed = ( pclCurrentInstance == pCurrentChild );
			}

			if ( bObjectOK )
				pclReturnedObject = pclCurrentInstance;
		}
	}

	return pclReturnedObject;
}

//***********************************************************************
void *CPA_Actor_Editor_Interface::GetInfoForTreeItem(CPA_DialogList *pDialog,
																										 CString csListName,
																										 CPA_BaseObject *pObject,
																										 CPA_BaseObject *pParent)
{
	ERROR_ASSERT( csListName.CompareNoCase(EDAC_C_szTreeView) == 0 );

	return NULL;
}

//***********************************************************************
int CPA_Actor_Editor_Interface::GetIconForTreeItem(CPA_DialogList *pDialog,
																									 CString csListName,
																									 CPA_BaseObject *pObject)
{
	ERROR_ASSERT( csListName.CompareNoCase(EDAC_C_szTreeView) == 0 );

	//Families
	if ( pObject->GetType().Compare(C_szFamilyTypeName) == 0 )
		return 0;
	//Models
	else if ( pObject->GetType().Compare(C_szActorModelTypeName) == 0 )
		return 1;
	else if ( pObject->GetType().Compare(C_szActorInstanceTypeName) == 0 )
	{
		//Instances
		if ( !((CPA_Actor *)pObject)->m_fn_bIsAnAlways() )
			return 2;
		//Always Models
		else
			return 3;
	}

	return -1;
}

//***********************************************************************
int CPA_Actor_Editor_Interface::GetStateForTreeItem(CPA_DialogList *pDialog,
																										CString csListName,
																										CPA_BaseObject *pObject)
{
	ERROR_ASSERT( csListName.CompareNoCase(EDAC_C_szTreeView) == 0 );

	if ( pObject->GetType().Compare(C_szActorInstanceTypeName) == 0 )
		return -1;
	else
	{
		if ( pObject->fn_bIsAvailable() )
			return 4;
		else
			return 5;
	}
}

//***********************************************************************
// Popup menu
//***********************************************************************
BOOL CPA_Actor_Editor_Interface::fn_bAddEntriesToTreePopup(CPA_DialogList *pDialog,
															 CString csListName,
															 CMenu *pMenu,
															 UINT uiCustomEntriesStart)
{
	ERROR_ASSERT( csListName.CompareNoCase(EDAC_C_szTreeView) == 0 );

	DEV_ViewPort3D	  *pCurViewport;
	CPA_DLLBase		  *p_oCameraInterface;

	// get camera interface
	pCurViewport = (DEV_ViewPort3D *) GetInterface()->GetMultiDevice()->GetFocusDevice()->GetViewPort();
	p_oCameraInterface = pCurViewport->GetCameraInterface();	
	
	BOOL bEntries = p_oCameraInterface->fn_bAddEntriesToTreePopup(pDialog, csListName, pMenu, uiCustomEntriesStart+EdActors_C_TreeMenuID_ForCamera);
	if (bEntries)
		pMenu->AppendMenu(MF_SEPARATOR);

	CPA_BaseObject *pSelectedObject = pDialog->GetSelectedObject();
	// get current selection
	if (pSelectedObject && (pSelectedObject->GetType().Compare(C_szFamilyTypeName) == 0))
	{
		CString csFamilyName = pSelectedObject->GetName();
		CString csDirectory = fn_szGetFamiliesDataPath() + CString ("\\") + csFamilyName;

		// propose to preload models of this family
		if (m_clDocument.m_fn_bScanDirectoryForUnloadedModels(csDirectory, 1))
		{
			CString csEntry ;
			csEntry.Format("Preload models for family %s", csFamilyName);
			pMenu->AppendMenu(MF_STRING, uiCustomEntriesStart + EdActors_C_TreeMenuID_PreloadModels, csEntry);
		}
		else
		{
			pMenu->AppendMenu(MF_STRING, uiCustomEntriesStart + EdActors_C_TreeMenuID_PreloadModels, "No model to preload");
			pMenu->EnableMenuItem(uiCustomEntriesStart + EdActors_C_TreeMenuID_PreloadModels, MF_BYCOMMAND |  MF_GRAYED);
		}
		pMenu->AppendMenu(MF_SEPARATOR);
	}

	// global entries
	pMenu->AppendMenu(MF_STRING, uiCustomEntriesStart + EdActors_C_TreeMenuID_ShowUnloaded, "Show preloaded objects");
	if ( m_pri_bTreeMustShowUnloadedObjects )
		pMenu->CheckMenuItem(uiCustomEntriesStart + EdActors_C_TreeMenuID_ShowUnloaded, MF_BYCOMMAND | MF_CHECKED);

	pMenu->AppendMenu(MF_STRING, uiCustomEntriesStart + EdActors_C_TreeMenuID_OnlyWithModels, "only Families with Models");
	if ( m_pri_bTreeMustOnlyShowFamiliesWithModels )
		pMenu->CheckMenuItem(uiCustomEntriesStart + EdActors_C_TreeMenuID_OnlyWithModels, MF_BYCOMMAND | MF_CHECKED);

	return TRUE;
}

//***********************************************************************
void CPA_Actor_Editor_Interface::fn_vOnCommandInTreePopup(CPA_DialogList *pDialog,
															CString csListName,
															UINT uiCustomEntry)
{
	ERROR_ASSERT( csListName.CompareNoCase(EDAC_C_szTreeView) == 0 );

	DEV_ViewPort3D	  *pCurViewport;
	CPA_DLLBase		  *p_oCameraInterface;

	// get camera interface
	pCurViewport = (DEV_ViewPort3D *) GetInterface()->GetMultiDevice()->GetFocusDevice()->GetViewPort();
	p_oCameraInterface = pCurViewport->GetCameraInterface();	
	
	if ( uiCustomEntry >= EdActors_C_TreeMenuID_ForCamera )
	{
		p_oCameraInterface->fn_vOnCommandInTreePopup(pDialog, csListName, uiCustomEntry-EdActors_C_TreeMenuID_ForCamera);
		return;
	}

	if ( uiCustomEntry == EdActors_C_TreeMenuID_PreloadModels )
	{
		m_clDocument.m_fn_vLoadFamilyModels(pDialog->GetSelectedObject()->GetName());
	}
	
	if ( uiCustomEntry == EdActors_C_TreeMenuID_ShowUnloaded )
	{
		m_pri_bTreeMustShowUnloadedObjects = !m_pri_bTreeMustShowUnloadedObjects;
		pDialog->fn_vUpdateSelection(E_lrm_ReinitList);
/*
		if (m_pri_bTreeMustShowUnloadedObjects && !m_clDocument.m_pub_bUnloadedModelsArePrepared)
		{
			m_clDocument.m_fn_vLoadUnloadedModels();
			m_clDocument.m_pclDialogList->fn_vUpdateSelection(E_lrm_ReinitList);
		}
*/
	}
	else if ( uiCustomEntry == EdActors_C_TreeMenuID_OnlyWithModels )
	{
		m_pri_bTreeMustOnlyShowFamiliesWithModels = !m_pri_bTreeMustOnlyShowFamiliesWithModels;
		pDialog->fn_vUpdateSelection(E_lrm_ReinitList);
	}

}



//***********************************************************************
// Popup menu
//***********************************************************************
BOOL CPA_Actor_Editor_Interface::fn_bAddEntriesToListPopup(CPA_DialogList *pDialog,
																													 CString csListName,
																													 CMenu *pMenu,
																													 UINT uiCustomEntriesStart)
{
	DEV_ViewPort3D	  *pCurViewport;
	CPA_DLLBase		  *p_oCameraInterface;

	if (csListName.CompareNoCase(EDAC_C_szInstancesList) == 0)
	{
		// get camera interface
		pCurViewport = (DEV_ViewPort3D *) GetInterface()->GetMultiDevice()->GetFocusDevice()->GetViewPort();
		p_oCameraInterface = pCurViewport->GetCameraInterface();	
		
		return p_oCameraInterface->fn_bAddEntriesToTreePopup(pDialog, csListName, pMenu, uiCustomEntriesStart);
	}

	return FALSE;
}

//***********************************************************************
void CPA_Actor_Editor_Interface::fn_vOnCommandInListPopup(CPA_DialogList *pDialog,
																													CString csListName,
																													UINT uiCustomEntry)
{
	DEV_ViewPort3D	  *pCurViewport;
	CPA_DLLBase		  *p_oCameraInterface;

	if (csListName.CompareNoCase(EDAC_C_szInstancesList) == 0)
	{
		// get camera interface
		pCurViewport = (DEV_ViewPort3D *) GetInterface()->GetMultiDevice()->GetFocusDevice()->GetViewPort();
		p_oCameraInterface = pCurViewport->GetCameraInterface();	
		
		p_oCameraInterface->fn_vOnCommandInTreePopup(pDialog, csListName, uiCustomEntry);
	}
}



