// Implementation for the class of Editor Actors Models
///////////////////////////////////////////////////////
#include "StdAfx.h"

// Shaitan FastC {
/////////////////////////////////////////////////////
//////// !!!!!!!!!!!! DANGER !!!!!!!!!!! ////////////
/////////////////////////////////////////////////////
#define _ED_CAR_MUST_DEFINE_STRUCT_
#include "EdAllAct.hpp"
/////////////////////////////////////////////////////
//////// !!!!!!!!!!!! End DANGER !!!!!!!!!!! ////////
/////////////////////////////////////////////////////
//End Shaitan FastC }

//ANNECY CHRISTOPHE MODIFICATIONS
#define D_ZdxStuff_StructureDefine
//ANNECY END CHRISTOPHE MODIFICATIONS

#include "EDACModl.hpp"

#include "EDACDef.hpp"
#include "_Ainterf.hpp"
#include "Defines.hpp"
#include "EDACDgIf.hpp"
#include "EDACStrg.hpp"

//External Modules
#include "ErO.h"
#include "TFa.h"
//End of External Modules

//-----------------IR-------------------------
#include "EdIRBeEn.hpp"
#include "EDACQuer.hpp"
//--------------------------------------------

#undef CPA_WANTS_IMPORT
#undef CPA_EXPORT
#define CPA_WANTS_EXPORT
//-----------------IR-------------------------
		#include "EdIRIRD.hpp"
// Shaitan FastC {
		#include "EdIRStrg.hpp"
//End Shaitan FastC }
//--------------------------------------------
    #include "_Actors.hpp"
#undef CPA_WANTS_EXPORT
#define CPA_WANTS_IMPORT

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

// Shaitan FastC {
#define	M_SAVEENTRY1PARM(a,b)						SCR_M_SvL0_SaveEntry(p_tdstFile,								\
																															M_MAKECHAR(a),						\
																															SCR_CC_C_Cfg_NoChar);			\
																				SCR_fn_v_SvL0_SaveParameters_MP(p_tdstFile,			\
																															SCR_EF_SvL0_Normal,				\
																															1,												\
																															M_MAKECHAR(b));
//End Shaitan FastC }

//****************************************************************
EdActors_EditorActorModel::EdActors_EditorActorModel(CPA_Family *pclFamily,
																										 CPA_Actor *pclActor)
													:EdActors_EditorActor(EDCAR_ACTOR_TYPE_MODEL) 
{
	//Creates a new 'motor actor' for the model 
	//This is an editor data !
	CAR_EDIT_TDSTACTOR *p_tdstMotorActor = (CAR_EDIT_TDSTACTOR *)malloc(sizeof(CAR_EDIT_TDSTACTOR));
	m_fn_vSetMotorActor(p_tdstMotorActor);

	m_fn_vSetMSPointersToNULL();
  	
	//Creates datas
	m_fn_vCreateActorMSDataList();

	if ( pclFamily->fn_bIsAvailable() )
	{
		m_fn_vMinimalAllocation();

		//Sets Initial and Current States
		CPA_Action *pclInitialAction = pclFamily->mfn_p_oGetInitialAction();
		
		CString csMsg = "Family '";
		csMsg += pclFamily->GetName();
		csMsg += "' has no initial Action. Check if your family directory is empty !";
		ERROR_PREPARE_M(g_c_csActorModuleNameForErrors,
										"Creation of an Editor Model",
										"EdActors_EditorActorModel::EdActors_EditorActorModel(...)",
										E_ERROR_GRAVITY_FATAL,
										csMsg);
		ERROR_CHECK( pclInitialAction != NULL );

		tdxHandleToState hInitialState = (tdxHandleToState)pclInitialAction->mfn_p_oGetDefaultState()->GetData();
		fn_v3dDataSetInitialState(p_tdstMotorActor->h_3dData, hInitialState);
		fn_v3dDataSetCurrentState(p_tdstMotorActor->h_3dData, hInitialState);
 	}

	m_pclActor = pclActor;

//-----------------IR-------------------------
	m_pclBrain=EDAC_fn_pclGetNewBrain(pclActor);
//--------------------------------------------
}												  
												  
//****************************************************************
//"Empty" Constructor (for loading)
EdActors_EditorActorModel::EdActors_EditorActorModel(CPA_Actor *pclActor)
													:EdActors_EditorActor(EDCAR_ACTOR_TYPE_MODEL) 
{
	//Creates a new 'motor actor' for the model 
	//This is an editor data !
	CAR_EDIT_TDSTACTOR *p_tdstMotorActor = (CAR_EDIT_TDSTACTOR *)malloc(sizeof(CAR_EDIT_TDSTACTOR));
	m_fn_vSetMotorActor(p_tdstMotorActor);
 
	m_fn_vSetMSPointersToNULL();

	//Creates datas
	m_fn_vCreateActorMSDataList();

	///////////////////////////////////////////
	// Do not call m_fn_vMinimalAllocation() //
	///////////////////////////////////////////
 
	m_pclActor = pclActor;

//-----------------IR-------------------------
	m_pclBrain=EDAC_fn_pclGetNewBrain(pclActor);
//--------------------------------------------
}												  
												  
//****************************************************************
//Copy constructor
EdActors_EditorActorModel::EdActors_EditorActorModel(EdActors_EditorActorModel *_pclSourceModel,
																										 CPA_Actor *_pclActor)
													: EdActors_EditorActor(EDCAR_ACTOR_TYPE_MODEL)
{
	m_pclActor = _pclActor;
	_pclActor->m_fn_vSetEditorActor(this);

	m_csBitmapName = _pclSourceModel->m_csBitmapName;

	//Creates a new 'motor actor'
	CAR_EDIT_TDSTACTOR *p_tdstMotorActor = (CAR_EDIT_TDSTACTOR *)malloc(sizeof(CAR_EDIT_TDSTACTOR));
 	m_fn_vSetMotorActor(p_tdstMotorActor);
 	m_fn_vSetMSPointersToNULL();

	//Allocates MS if the corresponding MS in the Model is allocated
	m_fn_vAllocateMSAsInModel(_pclSourceModel);

	//Creates datas
	m_fn_vCreateActorMSDataList();

	//Updates datas with model's ones (including 'model link' state)
	m_fn_vUpdateDatas(_pclSourceModel, TRUE, CTL_UPDATE_REASON__USE_USER_DEFINED_REASON, OAC_E_ur_InstanciatedFromModel);

//-----------------IR-------------------------
	m_pclBrain=EDAC_fn_pclGetNewCopyOfBrain(_pclActor,_pclSourceModel->m_pclBrain);
//--------------------------------------------
}												  
												  
//****************************************************************
EdActors_EditorActorModel::~EdActors_EditorActorModel()
{
	//Deletes all MS and their Datas
	m_fn_vDeleteAllMS();

	//Deletes motor (structure) actor (this is merely an editor Data !!)
	free(m_fn_ptdstGetMotorActor());

//-----------------IR-------------------------
	EDAC_fn_vDeleteBrain(m_pclBrain);
//--------------------------------------------
}

//****************************************************************
//Updates all instances of this model because "pclSourceData" has changed
void EdActors_EditorActorModel::m_fn_vUpdateAllInstances(	CTL_Editor_Data *_pclSourceData,
																													CTL_tdeUpdateReason _eReason,
																													long _lUserDefinedReason /*= 0*/)
{
//	ERROR_ASSERT( _pclSourceData->m_pub_fn_bIsLinked() );

	unsigned char ucModelListIndex = m_fn_ucGetCurrentMSListIndex();

	EdActors_EditorActorInstance *pclCurrentInstance;
	POSITION InstancesPos = m_clInstancesList.GetHeadPosition();
	while ( InstancesPos != NULL )
	{
		pclCurrentInstance = m_clInstancesList.GetNext(InstancesPos);

		ERROR_PREPARE_M(g_c_csActorModuleNameForErrors,
										"Updating All Instances of a Model, because a Data has changed",
										"EdActors_EditorActorModel::m_fn_vUpdateAllInstances(...)",
										E_ERROR_GRAVITY_WARNING, 
										"The Model and one of its Instances do no have the same number of AMS");
		ERROR_ASSERT( pclCurrentInstance->m_clListOfAMSLists.m_fn_pclGetListFromIndex(ucModelListIndex)->GetCount()
									== m_clListOfAMSLists.m_fn_pclGetListFromIndex(ucModelListIndex)->GetCount()
								);
		
		ERROR_PREPARE_M(g_c_csActorModuleNameForErrors,
										"Updating All Instances of a Model, because a Data has changed",
										"EdActors_EditorActorModel::m_fn_vUpdateAllInstances(...)",
										E_ERROR_GRAVITY_WARNING, 
										"The Data to be updated has not been found in the lists");
		ERROR_VERIFY( !m_fn_bUpdateList(pclCurrentInstance->m_clListOfAMSLists.m_fn_pclGetListFromIndex(ucModelListIndex),
																		m_clListOfAMSLists.m_fn_pclGetListFromIndex(ucModelListIndex), 
																		_pclSourceData,
																		_eReason,
																		_lUserDefinedReason)
								);
	}
}

//****************************************************************
//Updates all instances of this model because "pclSourceData" has changed
// returns TRUE if Data has not been found, i.e. search must continue in another list
BOOL EdActors_EditorActorModel::m_fn_bUpdateList(EdActors_ActorMiniStructureList *_pclDestList,
																								 EdActors_ActorMiniStructureList *_pclSourceList,
																								 CTL_Editor_Data *_pclSourceData,
																								 CTL_tdeUpdateReason _eReason,
//CPA2 Stegaru Cristian 98/06/24
																								 long _lUserDefinedReason /*= 0*/,
																								 BOOL bUsePropagate/* = FALSE*/)
//End CPA2 Stegaru Cristian 98/06/24
{
	//Gets the MS in which "pclSourceData" is										 
	long lMSIndex = 0;
	long lDataIndex;
	BOOL bFound = FALSE;	   
	POSITION DataPos;
	POSITION MSPos = _pclSourceList->GetHeadPosition();
	while ( (MSPos != NULL) && (!bFound) )
	{
		//Gets the Data list
		CTL_Editor_DataList *pclDataList = (_pclSourceList->GetNext(MSPos))->m_pclDataList;
		
		lDataIndex = 0;
		DataPos = pclDataList->GetHeadPosition();
		while (	( DataPos != NULL ) && ( !bFound ) )
		{
			bFound = (pclDataList->GetNext(DataPos) == _pclSourceData);
			if ( !bFound )
				lDataIndex ++;
		}
  		
		if ( !bFound )
			lMSIndex ++;
	}

	//Sets the data for the current instance
	if ( bFound )
	{
		//Gets the data
		ERROR_PREPARE_M(g_c_csActorModuleNameForErrors,
										"Updating a Data of an Instance because the corresponding Data has changed in its Model",
										"EdActors_EditorActorModel::m_fn_bUpdateList(...)",
										E_ERROR_GRAVITY_WARNING, 
										"The Data can't be found");
		ERROR_ASSERT( lMSIndex < _pclDestList->GetCount() );

		MSPos = _pclDestList->FindIndex(lMSIndex);
		ERROR_PREPARE_M(g_c_csActorModuleNameForErrors,
										"Updating a Data of an Instance because the corresponding Data has changed in its Model",
										"EdActors_EditorActorModel::m_fn_bUpdateList(...)",
										E_ERROR_GRAVITY_WARNING, 
										"The Data can't be found");
		ERROR_ASSERT( MSPos != NULL );
		
		EdActors_ActorMiniStructure *pclMS = _pclDestList->GetAt(MSPos);
 		ERROR_PREPARE_M(g_c_csActorModuleNameForErrors,
										"Updating a Data of an Instance because the corresponding Data has changed in its Model",
										"EdActors_EditorActorModel::m_fn_bUpdateList(...)",
										E_ERROR_GRAVITY_WARNING, 
										"The Data can't be found");
		ERROR_ASSERT(lDataIndex < pclMS->m_pclDataList->GetCount());

		DataPos = pclMS->m_pclDataList->FindIndex(lDataIndex);
		ERROR_PREPARE_M(g_c_csActorModuleNameForErrors,
										"Updating a Data of an Instance because the corresponding Data has changed in its Model",
										"EdActors_EditorActorModel::m_fn_bUpdateList(...)",
										E_ERROR_GRAVITY_WARNING, 
										"The Data can't be found");
		ERROR_ASSERT( DataPos != NULL );

		CTL_Editor_Data *pclInstanceData = pclMS->m_pclDataList->GetAt(DataPos);

		//CPA2 Stegaru Cristian 98/06/24
		if (bUsePropagate)
		{
			if (pclMS->m_fn_bIsAllocated())
			{
				if (OAC_fn_bLinkAllowPropagation (pclInstanceData))
					pclInstanceData->m_fn_vUpdateData(_pclSourceData, _eReason, _lUserDefinedReason);
			}
			else
			{
				MessageBox(NULL, "The mini-structure is not allocated in the instance, \nthe modification cannot be propagated",
							"Propagation of a modification - WARNING !", MB_OK);
			}
		}
		else if ( OAC_fn_bIsLinked(pclInstanceData) )
			//Updates it...
			pclInstanceData->m_fn_vUpdateData(_pclSourceData, _eReason, _lUserDefinedReason);
		//End CPA2 Stegaru Cristian 98/06/24
	}

	return ( !bFound && (_pclSourceData->m_pub_fn_csGetDataName() != "FastC_Index") && (_pclSourceData->m_pub_fn_csGetDataName() != "FastC_Run"));
}

//****************************************************************
//Allocates MS and all corresponding MS in existing Instances
BOOL EdActors_EditorActorModel::m_fn_bAllocateMS(	EdActors_ActorMiniStructure *pclAMS)
{
	ERROR_ASSERT ( !(pclAMS->m_fn_bIsAllocated()) );

	return pclAMS->m_fn_bAllocate(TRUE);
}

//****************************************************************
//Unallocates MS and all corresponding MS in existing Instances
BOOL EdActors_EditorActorModel::m_fn_bUnallocateMS(EdActors_ActorMiniStructure *pclAMS)
{
	ERROR_ASSERT ( pclAMS->m_fn_bIsAllocated() );

	return pclAMS->m_fn_bUnallocate();
}

//****************************************************************
void EdActors_EditorActorModel::m_fn_vAllocateMSInInstances(EdActors_ActorMiniStructure *pclAMS)
{
	//Searches for the right list of MS
	EdActors_ActorMiniStructureList *m_pclActorMSList = NULL;
	char cGroupIndex = m_clListOfAMSLists.m_fn_cGetIndexFromAMS(pclAMS);
	ERROR_ASSERT( cGroupIndex != -1 );
	
	m_pclActorMSList = m_clListOfAMSLists.m_fn_pclGetListFromIndex(cGroupIndex);

	//Searches for MS Index
	BOOL bFound = FALSE;
	long lModelMSIndex = 0;
	POSITION ModelMSPos = m_pclActorMSList->GetHeadPosition();
	while ( (ModelMSPos != NULL) && (!bFound) )
	{
		bFound = ( m_pclActorMSList->GetNext(ModelMSPos) == pclAMS );

		if ( !bFound )
			lModelMSIndex ++;
	}
			
	ERROR_ASSERT(bFound);

	//Allocates in Instances
 	long lInstanceMSIndex;	
	POSITION InstanceMSPos;	 
	EdActors_ActorMiniStructure *pclInstAMS;
	EdActors_EditorActorInstance *pclInstance;
	POSITION InstancesPos = m_clInstancesList.GetHeadPosition();
	while ( InstancesPos != NULL )
	{
		pclInstance = m_clInstancesList.GetNext(InstancesPos);	   
		pclInstance->m_fn_vSetCurrentMSListIndex(m_fn_ucGetCurrentMSListIndex());
		
		lInstanceMSIndex = 0;
		InstanceMSPos = pclInstance->m_pclActorCurrentMSList->GetHeadPosition();
		while (	lInstanceMSIndex <= lModelMSIndex )
		{
			ERROR_ASSERT(InstanceMSPos != NULL);
			pclInstAMS = pclInstance->m_pclActorCurrentMSList->GetNext(InstanceMSPos);
			lInstanceMSIndex ++;
		}

		if ( !pclInstAMS->m_fn_bIsAllocated() )
		{
			if ( !pclInstAMS->m_bIsReallyAllocated )
				pclInstAMS->m_fn_bAllocate();
			else
				pclInstAMS->m_fn_vUnrealAllocate();

			//Notifies
			pclInstance->m_pclActor->fn_vNotifySave();
		}
	}
}

//****************************************************************
void EdActors_EditorActorModel::m_fn_vUnallocateMSInInstances(EdActors_ActorMiniStructure *pclAMS)
{
	//Searches for the right list of MS
	EdActors_ActorMiniStructureList *m_pclActorMSList = NULL;
	char cGroupIndex = m_clListOfAMSLists.m_fn_cGetIndexFromAMS(pclAMS);
	ERROR_ASSERT( cGroupIndex != -1 );
	
	m_pclActorMSList = m_clListOfAMSLists.m_fn_pclGetListFromIndex(cGroupIndex);

	//Searches for MS Index
	BOOL bFound = FALSE;
	long lModelMSIndex = 0;
	POSITION ModelMSPos = m_pclActorMSList->GetHeadPosition();
	while ( (ModelMSPos != NULL) && (!bFound) )
	{
		bFound = ( m_pclActorMSList->GetNext(ModelMSPos) == pclAMS );

		if ( !bFound )
			lModelMSIndex ++;
	}
			
	ERROR_ASSERT(bFound);

	//Allocates in Instances
 	long lInstanceMSIndex;	
	POSITION InstanceMSPos;	 
	EdActors_ActorMiniStructure *pclInstAMS;
	EdActors_EditorActorInstance *pclInstance;
	POSITION InstancesPos = m_clInstancesList.GetHeadPosition();
	while ( InstancesPos != NULL )
	{
		pclInstance = m_clInstancesList.GetNext(InstancesPos);	   
		pclInstance->m_fn_vSetCurrentMSListIndex(m_fn_ucGetCurrentMSListIndex());
		
		lInstanceMSIndex = 0;
		InstanceMSPos = pclInstance->m_pclActorCurrentMSList->GetHeadPosition();
		while (	lInstanceMSIndex <= lModelMSIndex )
		{
			ERROR_ASSERT(InstanceMSPos != NULL);
			pclInstAMS = pclInstance->m_pclActorCurrentMSList->GetNext(InstanceMSPos);
			lInstanceMSIndex ++;
		}

		if ( (pclInstAMS->m_fn_bIsAllocated()) && (pclInstAMS->m_fn_bCanBeUnallocated()) )
		{
			pclInstAMS->m_fn_bUnallocate();

			//Notifies
			pclInstance->m_pclActor->fn_vNotifySave();
		}
	}
}

//****************************************************************
//Links the Data to Instances
void EdActors_EditorActorModel::m_pri_fn_vLinkData(CTL_Editor_Data *pclData)
{
	//Searches for the Data
	BOOL bFound = FALSE;
	long lModelMSIndex = 0;
	long lDataIndex;
	EdActors_ActorMiniStructure *pclAMS;
	POSITION DataPos;
	POSITION ModelMSPos = m_pclActorCurrentMSList->GetHeadPosition();
	while ( (ModelMSPos != NULL) && (!bFound) )
	{
		pclAMS = m_pclActorCurrentMSList->GetNext(ModelMSPos);
		
		lDataIndex = 0;
		DataPos	= pclAMS->m_pclDataList->GetHeadPosition();
		while ( (DataPos != NULL) && (!bFound) )
		{
			bFound = ( pclAMS->m_pclDataList->GetNext(DataPos) == pclData);
			
			if ( !bFound )
				lDataIndex ++;
		}

		if ( !bFound )
			lModelMSIndex ++;
	}
			
	ERROR_PREPARE_M(g_c_csActorModuleNameForErrors,
									"Linking data in Instances according to Model",
									"EdActors_EditorActorModel::m_fn_vLinkData(...)",
									E_ERROR_GRAVITY_INSTABLE,
									"The given Data can't be found in Model's data list");
	ERROR_ASSERT(bFound);

	if ( bFound )
	{
		//Updates link state of Model data
//		pclData->m_fn_bSetLink(eNot(pclData->m_fn_eGetLink()));

		//Links in all existing Instances
 		long lInstanceMSIndex;	
		POSITION InstanceMSPos;	 
 		long lInstanceDataIndex;	
		POSITION InstanceDataPos;	 
		EdActors_ActorMiniStructure *pclInstAMS;
		EdActors_EditorActorInstance *pclInstance;
		CTL_Editor_Data *pclCurrentData;
		POSITION InstancesPos = m_clInstancesList.GetHeadPosition();
		while ( InstancesPos != NULL )
		{
			pclInstance = m_clInstancesList.GetNext(InstancesPos);
			char cOldListIndex = pclInstance->m_fn_ucGetCurrentMSListIndex();
			pclInstance->m_fn_vSetCurrentMSListIndex(m_fn_ucGetCurrentMSListIndex());
			
			lInstanceMSIndex = 0;
			InstanceMSPos = pclInstance->m_pclActorCurrentMSList->GetHeadPosition();
			while (	lInstanceMSIndex <= lModelMSIndex )
			{
				ERROR_ASSERT(InstanceMSPos != NULL);
				pclInstAMS = pclInstance->m_pclActorCurrentMSList->GetNext(InstanceMSPos);	 
				
				lInstanceMSIndex ++;
			}

  			InstanceDataPos = pclInstAMS->m_pclDataList->GetHeadPosition();
			lInstanceDataIndex = 0;
			while ( lInstanceDataIndex <= lDataIndex )
			{
				ERROR_ASSERT(InstanceDataPos != NULL);
				pclCurrentData = pclInstAMS->m_pclDataList->GetNext(InstanceDataPos);

				lInstanceDataIndex ++;
			}
			
			//Sets link in Instance Data
//			pclCurrentData->m_fn_bSetLink(pclData->m_fn_eGetLink());
			//Immediatly updates Instance Data value with Model's one
			pclCurrentData->m_fn_vUpdateData(pclData);

			//Restores old List for Instance
 			pclInstance->m_fn_vSetCurrentMSListIndex(cOldListIndex);
		}
	}
}

//****************************************************************
CString EdActors_EditorActorModel::m_fn_csGetBitmapName()
{
	return m_csBitmapName;
}

//****************************************************************
void EdActors_EditorActorModel::m_fn_vSetBitmapName(CString csNewBitmapName)
{
	m_csBitmapName = csNewBitmapName;
}

//****************************************************************
short EdActors_EditorActorModel::m_fn_wGetRelatedInstancesCount()
{
	return m_clInstancesList.GetCount();
}

//****************************************************************
//This function allocates the MS which must always be Allocated
void EdActors_EditorActorModel::m_fn_vMinimalAllocation()
{
	EdActors_ActorMiniStructureList *pclCurrentAMSList;
	EdActors_MiniStructureList *pclCurrentMSList;
	POSITION AMSpos = m_clListOfAMSLists.GetHeadPosition();
	POSITION MSpos = g_pclInterface->m_clDocument.m_clListOfMSLists.GetHeadPosition();

	EdActors_ActorMiniStructure *pclAMS;
	EdActors_MiniStructure *pclMS;
	POSITION AMSSubPos;
	POSITION MSSubPos;
	unsigned long c_lI = 0;

	while ( AMSpos != NULL )
	{
		ERROR_ASSERT( MSpos != NULL );

		pclCurrentAMSList = m_clListOfAMSLists.GetNext(AMSpos);
		pclCurrentMSList = g_pclInterface->m_clDocument.m_clListOfMSLists.GetNext(MSpos);

		AMSSubPos = pclCurrentAMSList->GetHeadPosition();
		MSSubPos = pclCurrentMSList->GetHeadPosition();
		
		while ( AMSSubPos != NULL )
		{
			ERROR_ASSERT( MSSubPos != NULL );

			pclAMS = pclCurrentAMSList->GetNext(AMSSubPos);
			pclMS = pclCurrentMSList->GetNext(MSSubPos);

			if ( !(pclMS->m_fn_bCanBeUnallocated()) )
				pclAMS->m_fn_bAllocate();
		}

		c_lI ++;
	}
}

//*************************************************************************
void EdActors_EditorActorModel::m_fn_vRemoveFromInstancesList(EdActors_EditorActorInstance *pclInstanceToRemove)
{
	EdActors_EditorActorInstance *pclCurrentInstance;
	BOOL bFound = FALSE;
	POSITION pos = m_clInstancesList.GetHeadPosition();
	POSITION KeepPos;
	while ( (pos != NULL) && (!bFound) )
	{
		KeepPos = pos;

		pclCurrentInstance = m_clInstancesList.GetNext(pos);

		bFound = ( pclCurrentInstance == pclInstanceToRemove );
	}

	ERROR_ASSERT( bFound );

	m_clInstancesList.RemoveAt(KeepPos);
}

//*************************************************************************
void EdActors_EditorActorModel::m_fn_vAddToInstancesList(EdActors_EditorActorInstance *pclInstanceToAdd)
{
	m_clInstancesList.AddTail(pclInstanceToAdd);
}

//*************************************************************************
//Returns TRUE only if Data exists and belongs to an allocated MS
BOOL EdActors_EditorActorModel::m_fn_bDataBelongsToAnAllocatedMS(CString csDataName)
{
	BOOL bReturn = FALSE;
	
	CTL_Editor_Data *pclBaseData = m_fn_p_oFindDataByName(csDataName);

	if ( pclBaseData != NULL )
		bReturn = OAC_fn_pclGetParentAMSOfData(pclBaseData)->m_fn_bIsAllocated();
	//else
		//Data has not been found, so returns FALSE

	return bReturn;
}

//*************************************************************************
//Updates all linked Data in given Instance, according to Model
void EdActors_EditorActorModel::m_pub_fn_vUpdateLinkedDataInInstance(CPA_Actor *_pclInstanceToUpdate)
{
	ERROR_PREPARE_M(g_c_csActorModuleNameForErrors,
									"Updating Instance linked data according to Model",
									"EdActors_EditorActorModel::m_pub_fn_vUpdateLinkedDataInInstance(...)",
									E_ERROR_GRAVITY_INSTABLE,
									"The given Actor is not an Instance");
	ERROR_ASSERT( _pclInstanceToUpdate->m_fn_bIsAnInstance() );

	_pclInstanceToUpdate->m_fn_pclGetEditorActor()->m_fn_vUpdateDatas(this, FALSE, CTL_UPDATE_REASON__USE_USER_DEFINED_REASON, OAC_E_ur_InstanciatedFromModel);
}

#if defined ( D_DoNotInstanciateIncompleteModels )
//****************************************************************
//checks that all datae handling object lists have a valid name list specified
BOOL EdActors_EditorActorModel::m_bAllListsAreSpecified()
{
	short wMSIndex;
	
	for
		(//scan all lists of ministructures
		wMSIndex = 0;
		wMSIndex < sizeof(m_a_poMSLists) / sizeof(void *);
		wMSIndex ++
		)
	{
		EdActors_ActorMiniStructureList *p_oMSList = m_a_poMSLists[wMSIndex];
		
		POSITION xMSPos = p_oMSList->GetHeadPosition();
		while ( xMSPos ) //for each ministructure in the list
		{
			EdActors_ActorMiniStructure *p_oMS = p_oMSList->GetNext(xMSPos);
			
			CTL_Editor_DataList *p_oDataList = &p_oMS->m_clDataList;
			POSITION xDataPos = p_oDataList->GetHeadPosition();
			while (xDataPos) //check each data ofthe current list
			{
				CTL_Editor_Data *p_oData = p_oDataList->GetNext(xDataPos);
				if ( p_oData->m_tdeDataType == EDITOR_DATA_TYPE_OBJECTLIST )
				{ //we care only about object lists
					CPA_Editor_ObjectListData &r_oObjectListData = (CPA_Editor_ObjectListData &) *p_oData;
					
					// if no name list exists in this data, we tell it...
					if ( !r_oObjectListData.m_p_oNameList )
						return FALSE;
				}
			}
		}
	}
	return TRUE;
}
#endif /* D_DoNotInstanciateIncompleteModels */

//****************************************************************
void EdActors_EditorActorModel::m_pub_fn_vSetLink(CTL_Editor_Data *_pclSourceData,
																									BOOL _bMustLink)
{
	m_pri_fn_vLinkData(_pclSourceData);
}

//////////////////////////////////////////////////////////////////////////////////////////////////////
// Method	: mfn_vUpdateInstances 
// Date		: 98/06/22
//////////////////////////////////////////////////////////////////////////////////////////////////////
// Description	:
// Author		: Stegaru Cristian - CPA
//////////////////////////////////////////////////////////////////////////////////////////////////////
// Modification	: 
// Date			:
// By			:
//////////////////////////////////////////////////////////////////////////////////////////////////////
void EdActors_EditorActorModel::mfn_vUpdateInstances (CTL_Editor_Data *_pclSourceData, int nReason/* = REASON_ALL_INSTANCES*/, CStringList *pInstanceNames/* = NULL*/)
{
	unsigned char ucModelListIndex = m_fn_ucGetCurrentMSListIndex();

	EdActors_EditorActorInstance *pclCurrentInstance;
	POSITION InstancesPos = m_clInstancesList.GetHeadPosition();
	while (InstancesPos != NULL)
	{
		pclCurrentInstance = m_clInstancesList.GetNext(InstancesPos);
		ASSERT (pclCurrentInstance);
		if (REASON_INSTANCES_IN_THE_LIST == nReason)
		{
			ASSERT (pInstanceNames);
			CString csInstanceName = pclCurrentInstance->m_pclActor->GetName ();
			BOOL bInstanceIsInTheList = FALSE;
			POSITION pos = pInstanceNames->GetHeadPosition ();
			while (pos)
			{
				const CString csName = pInstanceNames->GetNext (pos);
				if (csName == csInstanceName)
				{
					bInstanceIsInTheList = TRUE;
					break;
				}
			}
			if (!bInstanceIsInTheList)
				continue;
		}
		//treat all instances for REASON_ALL_INSTANCES == nReason

		ERROR_PREPARE_M(g_c_csActorModuleNameForErrors,
										"Updating Instances of a Model, because the user propagate a value",
										"EdActors_EditorActorModel::mfn_vUpdateInstances(...)",
										E_ERROR_GRAVITY_WARNING, 
										"The Model and one of its Instances do no have the same number of AMS");
		ERROR_ASSERT( pclCurrentInstance->m_clListOfAMSLists.m_fn_pclGetListFromIndex(ucModelListIndex)->GetCount()
									== m_clListOfAMSLists.m_fn_pclGetListFromIndex(ucModelListIndex)->GetCount());
		
		ERROR_PREPARE_M(g_c_csActorModuleNameForErrors,
										"Updating Instances of a Model, because the user propagate a value",
										"EdActors_EditorActorModel::mfn_vUpdateInstances(...)",
										E_ERROR_GRAVITY_WARNING, 
										"The Data to be updated has not been found in the lists");
		ERROR_VERIFY( !m_fn_bUpdateList(pclCurrentInstance->m_clListOfAMSLists.m_fn_pclGetListFromIndex(ucModelListIndex),
															m_clListOfAMSLists.m_fn_pclGetListFromIndex(ucModelListIndex), 
															_pclSourceData,
															CTL_UPDATE_REASON__DATA_MODIFIED_BY_USER, 0, TRUE));
	}

}

//////////////////////////////////////////////////////////////////////////////////////////////////////
// Method	: mfn_vGetStandardInstances 
// Date		: 98/06/24
//////////////////////////////////////////////////////////////////////////////////////////////////////
// Description	:
// Author		: Stegaru Cristian - CPA
//////////////////////////////////////////////////////////////////////////////////////////////////////
// Modification	: 
// Date			:
// By			:
//////////////////////////////////////////////////////////////////////////////////////////////////////
void EdActors_EditorActorModel::mfn_vGetStandardInstances (CTL_Editor_Data *pSourceData, CTL_Editor_Data *pModifiedData, CStringList &rlstStandardInstances)
{
	if (!pSourceData || !pModifiedData)
		return;

	EdActors_EditorActorInstance *pclCurrentInstance;
	POSITION InstancesPos = m_clInstancesList.GetHeadPosition();
	while (InstancesPos != NULL)
	{
		pclCurrentInstance = m_clInstancesList.GetNext(InstancesPos);
		ASSERT (pclCurrentInstance);
		if (mfn_bIsAStandardInstance (pclCurrentInstance, pSourceData, pModifiedData))
			rlstStandardInstances.AddTail (pclCurrentInstance->m_pclActor->GetName ());
	}
}
	
//////////////////////////////////////////////////////////////////////////////////////////////////////
// Method	: mfn_bIsAStandardInstance 
// Date		: 98/06/24
//////////////////////////////////////////////////////////////////////////////////////////////////////
// Description	:
// Author		: Stegaru Cristian - CPA
//////////////////////////////////////////////////////////////////////////////////////////////////////
// Modification	: 
// Date			:
// By			:
//////////////////////////////////////////////////////////////////////////////////////////////////////
BOOL EdActors_EditorActorModel::mfn_bIsAStandardInstance (EdActors_EditorActorInstance *pclInstance, CTL_Editor_Data *pSourceData, CTL_Editor_Data *pModifiedData)
{
	ASSERT (pclInstance);
	ASSERT (pModifiedData);

	unsigned char ucModelListIndex = m_fn_ucGetCurrentMSListIndex();
	EdActors_ActorMiniStructureList *pInstanceMSList = pclInstance->m_clListOfAMSLists.m_fn_pclGetListFromIndex(ucModelListIndex);
	EdActors_ActorMiniStructureList *pModelMSList = m_clListOfAMSLists.m_fn_pclGetListFromIndex(ucModelListIndex);
	if (!pInstanceMSList || !pModelMSList)
		return FALSE;
	
	//Gets the MS in which "pclSourceData" is										 
	long lMSIndex = 0;
	long lDataIndex;
	BOOL bFound = FALSE;	   
	POSITION DataPos;
	POSITION MSPos = pModelMSList->GetHeadPosition();
	while ( (MSPos != NULL) && (!bFound) )
	{
		//Gets the Data list
		CTL_Editor_DataList *pclDataList = (pModelMSList->GetNext(MSPos))->m_pclDataList;
		
		lDataIndex = 0;
		DataPos = pclDataList->GetHeadPosition();
		while (	( DataPos != NULL ) && ( !bFound ) )
		{
			bFound = (pclDataList->GetNext(DataPos) == pSourceData);
			if ( !bFound )
				lDataIndex ++;
		}
  		
		if ( !bFound )
			lMSIndex ++;
	}

	//Sets the data for the current instance
	if ( bFound )
	{
		//Gets the data
		ASSERT (lMSIndex < pInstanceMSList->GetCount());

		MSPos = pInstanceMSList->FindIndex (lMSIndex);
		ASSERT (MSPos != NULL);
		
		EdActors_ActorMiniStructure *pclMS = pInstanceMSList->GetAt (MSPos);
		ASSERT (lDataIndex < pclMS->m_pclDataList->GetCount());

		DataPos = pclMS->m_pclDataList->FindIndex(lDataIndex);
		ASSERT( DataPos != NULL );

		CTL_Editor_Data *pclInstanceData = pclMS->m_pclDataList->GetAt(DataPos);
		ASSERT (pclInstanceData);

		if (OAC_fn_bLinkAllowPropagation (pclInstanceData) && pclInstanceData->mfn_bEqualsModifiedDataOldValue (pModifiedData))
			return TRUE;

	}
	return FALSE;
}
	
//////////////////////////////////////////////////////////////////////////////////////////////////////
// Method	: mfn_vGetAllInstances 
// Date		: 98/06/25
//////////////////////////////////////////////////////////////////////////////////////////////////////
// Description	:
// Author		: Stegaru Cristian - CPA
//////////////////////////////////////////////////////////////////////////////////////////////////////
// Modification	: 
// Date			:
// By			:
//////////////////////////////////////////////////////////////////////////////////////////////////////
void EdActors_EditorActorModel::mfn_vGetAllInstances (CStringList &rlstAllInstances)
{
	EdActors_EditorActorInstance *pclCurrentInstance;
	POSITION InstancesPos = m_clInstancesList.GetHeadPosition();
	while (InstancesPos != NULL)
	{
		pclCurrentInstance = m_clInstancesList.GetNext(InstancesPos);
		ASSERT (pclCurrentInstance);
		rlstAllInstances.AddTail (pclCurrentInstance->m_pclActor->GetName ());
	}
}



// Shaitan FastC {
//****************************************************************
void EdActors_EditorActorModel::m_pub_fn_vNotifyBrain (void)
{
	// at loading time, do not notify !
	if (m_pclActor->GetEditor()->GetInterface()->fn_bIsLoadingWorld())
		return;	
	
	CString	csFamilyName	= m_pclActor->m_pub_fn_pclGetFamily()->GetName();
	CString	csModelName		= m_pclActor->GetName();
	CString	csPathName		= fn_szGetFamiliesDataPath();
			
	csPathName += "\\" + csFamilyName + "\\"+ csModelName + "\\" + csModelName + ".ai";
	SCR_fn_v_SvL1_RegisterNotify((char *) (LPCSTR) csPathName,
		EdActors_EditorActorModel::m_fn_vSaveEngineAI,
		this,
		SCR_EA_Ntfy_RebuildSection);
}

/**********************************************************************************/
void EdActors_EditorActorModel::m_fn_vSaveEngineAI(SCR_tdst_File_Description	*p_tdstFile,
																				char											*p_szSectionName,
																				void											*p_vData,
																				SCR_tde_Ntfy_Action				eAction)
{
	EdActors_EditorActorModel *pModel = (EdActors_EditorActorModel *)p_vData;
	CPA_EdIR_Brain	*pclBrain=pModel->m_pclBrain;
	CPA_Actor	*pclActor=pModel->m_pclActor;
	CString		csFamilyName=pclActor->m_pub_fn_pclGetFamily()->GetName();
	CString		csModelName=pclActor->GetName();
  long            CFast_bIsC ;


	SCR_M_SvL0_SaveScriptFileHeader(p_tdstFile);

	//Saves version number
	SCR_M_SvL0_SaveComment(p_tdstFile,C_VERSION);
	SCR_M_SvL0_SaveBlankLine(p_tdstFile);
	
	//Computes date
	SYSTEMTIME stSystemTime;
	::GetLocalTime(&stSystemTime); 
	CTime cTime(stSystemTime);
	CString csDate=cTime.Format("%A,%B,%d,%Y,%Hh%Mm");
  
	CString csLine="Save date:"+csDate;
	SCR_M_SvL0_SaveComment(p_tdstFile,M_MAKECHAR(csLine));
	SCR_M_SvL0_SaveBlankLine(p_tdstFile);

	SCR_M_SvL0_SaveBeginSection(p_tdstFile,
															M_MAKECHAR(g_c_csAISectionName+":"),
															SCR_CC_C_Cfg_EOL);

	M_SAVEENTRY1PARM(g_c_csAIDecSectionName,
									 csFamilyName+"\\"+csModelName+"\\"+csModelName+g_c_csAIDecFileExtension);
	M_SAVEENTRY1PARM(g_c_csAIRulSectionName,
									 csFamilyName+"\\"+csModelName+"\\"+csModelName+g_c_csAIRulFileExtension);
	M_SAVEENTRY1PARM(g_c_csAIRfxSectionName,
									 csFamilyName+"\\"+csModelName+"\\"+csModelName+g_c_csAIRfxFileExtension);
	if (!pclBrain->m_clListOfSubrs.IsEmpty ())
	{
		M_SAVEENTRY1PARM(g_c_csAISubrSectionName,
									 csFamilyName+"\\"+csModelName+"\\"+csModelName+g_c_csAISubrFileExtension);
	}

  CFast_bIsC = pModel->m_fn_ptdstGetMotorActor()->h_Brain->p_stMind->p_stAIModel->CFast_bIsC ;
  if ( CFast_bIsC ) {
	  M_SAVEENTRY1PARM(g_c_csAICrrSectionName,
									   csFamilyName+"\\"+csModelName+"\\"+csModelName+g_c_csAICrrFileExtension);
	  M_SAVEENTRY1PARM( g_c_csAINodeSectionName,
                      csFamilyName+"\\"+csModelName+"\\"+csModelName+g_c_csAINodeFileExtension );
  }
  CString csFast_IsC;
  CString csFast_FunctionIndex;

  csFast_IsC.Format("%ld", CFast_bIsC);
  M_SAVEENTRY1PARM(g_c_csAIFastIsC_SectionName, csFast_IsC);
  csFast_FunctionIndex.Format("%ld", pModel->m_fn_ptdstGetMotorActor()->h_Brain->p_stMind->p_stAIModel->CFast_lFunction);
  M_SAVEENTRY1PARM(g_c_csAIFastFId_SectionName, csFast_FunctionIndex);
  
	SCRIPT_vSaveEndSection(p_tdstFile);
}
//End Shaitan FastC }
