/*=========================================================================================
File:			EdtList.cpp
Prupose:		Handle lists in editor
Author:			Yann Le Tensorer
Creation Date:	february 11, 1997 (it's my birthday!!)
Version:		1.0
===========================================================================================
Revisions:		Version		Date				Author
                ----------------------------------------------------------------

=========================================================================================*/


/*=========================================================================================
Notes:
=========================================================================================*/



// "standard" include
#include "stdafx.h"

#include "ACP_Base.h"
#include "ITF.h"
#include "IncMEC.h"
#define D_State_Define
#include "IncGAM.h"
#undef D_State_Define
#include "GLI.h"

#include "EDACstrg.hpp"
#include "EDACactr.hpp"

#include "edtList.hpp"
#include "CPA_dato.hpp"
#include "CPA_nll.hpp"
#include "x:\Cpa\Main\Inc\_EditID.h"
#include "_AInterf.hpp"

#include "DPT.h"

#include "OZO.h"    // Zones dll
#include "owp.h"    // Waypoint dll


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


#define  C_ucTypeWay  18


/*==========================================================
Function name:	Class EdtList Constructor
Description:	Creates a EdtList
Input:			pOwner:			pointer on a name list
				ucOwnerType:	type of owner of the list (instance or model)
				ucListType:		type of list to be created (C_ucTypeZdd,C_ucTypeZdm,C_ucTypeZde,C_ucTypeZdr,C_ucTypeWay)
				Output:			none
Author:			Yann Le Tensorer
Date:			february 11, 1997
Revision:		Alexis Vaisse, March 17, 1997. Set the engine list to NULL
                Alexis Vaisse, May   16, 1997. Add a new parameter : the name of the list to create
                Alexis Vaisse, June   3, 1997. Change the call to CPA_ReachableObject contructor
==========================================================*/
EdtList::EdtList(
	CPA_tdoNameList		*pNameList,
	CString				csListType,
	CString             csEdtListName,
	BOOL                _bSectionExist,
	BOOL				_bForModel
)
	: CPA_SaveObject (
    	g_pclInterface,        // Creating dll
        C_szEdtListTypeName,   // Type name
        E_ss_Responsible,
        pNameList              // Owner
		)
{
    SetSectionData  (this);
    SetCallBackSave (CallbackToSaveObjectList);

	m_bForModelOnly = _bForModel;

    char szTmp [SCR_CV_ui_Cfg_MaxLenName];
    char szSectionName [SCR_CV_ui_Cfg_MaxLenName];
    char * szFamilyName = pNameList -> GetOwner () -> fn_p_szGetName ();
    if (csListType == C_szWayName)                                           // List of ways saved in the level directory
    {
        SetDataPath (fn_szGetLevelsDataPath ());                 // "GameData\Levels"

        fn_zsGetActualLevelFilename (szTmp , "");       // szSectionName = "GameData\Level\Cave\Cave"
        char * p_cSlash = strrchr (szTmp , '\\');
        char * p_cPoint = strrchr (szTmp , '.');
        *p_cPoint = 0;
        sprintf (szTmp , "%s\\Families\\%s\\%s%s" , p_cSlash+1 , szFamilyName , szFamilyName , (LPCTSTR) g_csWayListExtension);
                                                                 // szSectionName = "Cave\Families\Ed\Ed.way"
        SCR_fn_v_RdL0_ComputeSectionName (szSectionName, szTmp , (char *) (LPCTSTR) g_c_csActorScriptWayListSectionName , "");
                                                                 // szSectionName = "Cave\Families\Ed\Ed.way^WayLst"
    }
    else
    if ( (!pNameList->m_bHasAVirgeField()) || (_bForModel && pNameList->m_bHasACommonField()))                                                                    // Saved in the Family directory
    {
        SetDataPath (fn_szGetLevelsDataPath ());               // "GameData\Levels"

        sprintf (szTmp , "_Common\\Families\\%s\\%s%s" , szFamilyName , szFamilyName , (LPCTSTR) g_csZoneListExtension);                    // "Ed\Ed.zdx"
        SCR_fn_v_RdL0_ComputeSectionName (szSectionName, szTmp , (char *) (LPCTSTR) g_c_csActorScriptZoneListSectionName , "" );
                                                                 // szSectionName = "_Common\Families\Ed\Ed.zdx^CreateNewArrayOfZdx"
    }
    else                                   // List of zones saved in the level directory
    {
        SetDataPath (fn_szGetLevelsDataPath ());                 // "GameData\Levels"

        fn_zsGetActualLevelFilename (szTmp , "");        // szSectionName = "GameData\Level\Cave\Cave."
        char * p_cSlash = strrchr (szTmp , '\\');
        char * p_cPoint = strrchr (szTmp , '.');
        *p_cPoint = 0;
        sprintf (szTmp , "%s\\Families\\%s\\%s%s" , p_cSlash + 1, szFamilyName , szFamilyName , (LPCTSTR) g_csZoneListExtension);
                                                                 // szSectionName = "Cave\Families\Ed\Ed.zdx"
        SCR_fn_v_RdL0_ComputeSectionName (szSectionName, szTmp , (char *) (LPCTSTR) g_c_csActorScriptZoneListSectionName , "" );
                                                                 // szSectionName = "Cave\Families\Ed\Ed.zdx^CreateNewArrayOfZdx"
    }
    SetReferencedSectionName (szSectionName);

  //set the value returned by GetData() before the insertion in the list by the first rename()
  m_hMotorList = NULL;
	// Name
	if (fn_eRename (csEdtListName ) != E_mc_None)
		SetDefaultValidName ();

    fn_vUpdateSectionName ();

    SetExistingSection (_bSectionExist);

    if (fn_bCanBeNotified () && ! fn_bSectionExists ())
    {
	    fn_vNotifySave ();
        pNameList -> fn_vUpdateReference (this);    // This makes a NotifySave
    }

	unsigned long NumberOfElements;

	m_pNameList		=pNameList;
	m_csListType    =csListType;

	/* gets the number of elements */
	NumberOfElements=pNameList->GetCount();

	/* creates an empty list with NumberOfElements elements */
	if (NumberOfElements>0)
		for (unsigned int i=0;i<NumberOfElements;i++)
		{
			AddTail((CPA_SaveObject*)0);
		}

    /* create an empty list of editor actors using this list */
    m_p_oListOfReferencingEditorActors = new CPA_List<EdActors_EditorActor>;
    m_ulNumberOfActorsUsingThisList = -1;

	// init
	m_lDrawObjects=1;
}

/*==========================================================
Function name: fn_oGetFirstActorUsingThisList
Description: returns the first actor referencing this list
Input:   none
    Output:   pointer to the obtained list
Author:			Yann Le Tensorer
Date:			february 11, 1997
Revision:		Alexis Vaisse, march 17, 1997. Set the engine list to NULL
==========================================================*/
CPA_BaseObject *EdtList::fn_oGetFirstActorUsingThisList()
{
 //return (CPA_SaveObject *) fn_oGetListOfActorsUsingThisList() -> GetHead () -> m_pclActor;
	POSITION xPos;
	EdActors_EditorActor* poActor;
	CPA_List<EdActors_EditorActor>* poListOfEditorActor;

	poListOfEditorActor = fn_oGetListOfActorsUsingThisList();
	for ( poActor = poListOfEditorActor->GetHeadElement(xPos); poActor; poActor = poListOfEditorActor->GetNextElement(xPos) )
		if ( poActor->m_fn_bIsAnInstance() ) return poActor->m_pclActor;

// jt 3/11/97	
	// if the list is empty, no head element ! 
	if (poListOfEditorActor->GetCount()==0) return NULL;	
// end jt 3/11/97
		return poListOfEditorActor->GetHead()->m_pclActor;
}

/*==========================================================
Function name: fn_oGetListOfActorsUsingThisList
Description: returns the list of editor actors referencing this list
Input:   none
    Output:   pointer to the obtained list
Author:			Yann Le Tensorer
Date:			february 11, 1997
Revision:		Alexis Vaisse, march 17, 1997. Set the engine list to NULL
==========================================================*/
CPA_List<EdActors_EditorActor> *EdtList::fn_oGetListOfActorsUsingThisList()
{
 if ( m_ulNumberOfActorsUsingThisList == -1 )
 {
  //empty our current list
  m_p_oListOfReferencingEditorActors->RemoveAll();
  //get the list of motor actors (reachable) using this object list

  CList< CPA_BaseObject *, CPA_BaseObject *> oFatherList;
  m_ulNumberOfActorsUsingThisList = g_oCoherenceManager.m_fn_iGetFatherList(this, &oFatherList);
  //build an equivalent list of editor actors
  POSITION xPos = oFatherList.GetHeadPosition();
  while ( xPos )
   m_p_oListOfReferencingEditorActors->AddTail(((CPA_Actor *) oFatherList.GetNext(xPos))->m_fn_pclGetEditorActor());
  //empty the list of motor actors before it is destroyed
  oFatherList.RemoveAll();
 }
 return m_p_oListOfReferencingEditorActors;
}

/*==========================================================
Function name:	EdtList::GetDataType
Description:	Convert m_csListType to a type used by the engine
Input:
Output:			the engine type
Author:			Alexis Vaisse
Date:			March 17, 1997
Revision:       July 2, 1997
==========================================================*/
long EdtList::GetDataType ()
{
    if (m_csListType == C_szZddName)  return C_ucTypeZdd;
    if (m_csListType == C_szZdeName)  return C_ucTypeZde;
    if (m_csListType == C_szZdmName)  return C_ucTypeZdm;
    if (m_csListType == C_szZdrName)  return C_ucTypeZdr;
    if (m_csListType == C_szWayName)  return C_ucTypeWay;

    ASSERT (0);
    return 0;
}

/*==========================================================
Function name:	EdtList::fn_bMakeActorUseThisList
Description:	Makes an actor use an object list
Input:			pActor: actor that uses the list
Output:			FALSE if operation failed, TRUE if not
Author:			Yann Le Tensorer
Date:			february 25, 1997
Revision:		Alexis Vaisse, march 17, 1997 : also link the engine actor and the engine list
                                                (if the engine list is NULL, create a new one)
                Alexis Vaisse, may 20, 1997   : add the bNotifySave parameter
==========================================================*/
BOOL EdtList::fn_bMakeActorUseThisList(EdActors_EditorActor* pActor , BOOL bNotifySave /* = TRUE */)
{
	int Answer;
	CString text1;
	CString text2;

  if ( pActor == NULL )
    return FALSE;

  g_oCoherenceManager.m_fn_vAddALink(pActor->m_pclActor, this);
  m_ulNumberOfActorsUsingThisList = -1;
// pos = fn_oGetListOfActorsUsingThisList()->Find(pActor);
// if (pos==0) /* actor not found in the list of actors */
// {
//  /* add actor in the list of actors using the edt list*/
//  fn_oGetListOfActorsUsingThisList()->AddTail(pActor);
//  /* increments number of actor using the list*/
//  m_ulNumberOfActorsUsingThisList++;
// }

	if (m_csListType!="")
	{
		pActor->m_fn_vSetObjectList(m_csListType,this);
		if (bNotifySave/* && pActor->m_pclActor->GetFileName () != "" && pActor->m_pclActor->GetFileName () != "NoFileName"*/)
			pActor->m_pclActor->fn_vNotifySave ();
        if (pActor -> m_fn_bIsAnInstance ())
        {
          HIE_tdxHandleToSuperObject hSuperObject = pActor -> m_pclActor -> m_pub_fn_hGetMotorSuperObject ();
          if (hSuperObject)
          {
            unsigned char ucEngineType = (unsigned char) GetDataType ();

            if (m_hMotorList == NULL)
            {   // Create a engine list with the correct type and the correct number of elements
              void *hCreatedMotorList;
              if (ucEngineType != C_ucTypeWay)
                hCreatedMotorList = ZDX_fn_hCreateEmptyListOftype (ucEngineType  , GetCount ());

              fn_vUpdateData(hCreatedMotorList);
              m_hMotorList = hCreatedMotorList;
            }

            // Set the list to the actor
            if (ucEngineType != C_ucTypeWay)
              CS_fn_vSetZdxList (ucEngineType , hSuperObject , (ZDX_tdxHandleToZdxList) m_hMotorList);

            // For each existing object (zone or way) in the list, ask the associated dll to put the engine object into the engine list of the actor
              POSITION Pos = GetHeadPosition ();
              unsigned long ulIndexInList = 0;
              while (Pos)
              {
                  CPA_BaseObject * pObject = GetNext (Pos);
                  if (pObject)
                  {
                      tdstEdtListMess ListMess;

                      ListMess.csListType       =  m_csListType;
                      ListMess.pActor           = pActor -> m_pclActor;
                      ListMess.ulIndexInList    = ulIndexInList;
                      ListMess.pList            = this;
                      ListMess.pObject          = NULL;

                      pObject -> GetEditor () -> OnQueryAction (NULL , C_uiQueryAnObjectHasBeenChanged , (long) & ListMess);
                  }
                  ulIndexInList ++;
              }
          }
        }
	}
	else
	{
		text2="Error: Undefined list type";
		text1="Program attempted to set an undefined object list\n to an actor";
		Answer = MessageBox(NULL,(LPCTSTR)text1,(LPCTSTR)text2,MB_YESNO | MB_ICONQUESTION /*| MB_SYSTEMMODAL*/);
		return FALSE;
	}
	return TRUE;

}

/*==========================================================
Function name:	EdtList::fn_bMakeActorNotUseThisList
Description:	makes an actor not use the list anymore
Input:			pActor: actor that does not uses the list anymore
Output:			true if operation succeded, false if not
Author:			Yann Le Tensorer
Date:			february 25, 1997
Revision:       Alexis Vaisse, may 20, 1997   : add the bNotifySave parameter
==========================================================*/
BOOL EdtList::fn_bMakeActorNotUseThisList(EdActors_EditorActor* pActor , BOOL bNotifySave /* = TRUE */)
{
	int Answer;
	CString text1;
	CString text2;

 g_oCoherenceManager.m_fn_vRemoveALink(pActor->m_pclActor, this);
 m_ulNumberOfActorsUsingThisList = -1;
// pos = fn_oGetListOfActorsUsingThisList()->Find(pActor);
// if (pos!=0) /* actor was found in the list */
// {
//  fn_oGetListOfActorsUsingThisList()->RemoveAt(pos);
//  m_ulNumberOfActorsUsingThisList--;
// }

	if (m_csListType!="")
	{
		pActor->m_fn_vSetObjectList(m_csListType,NULL);
		if (bNotifySave/* && pActor->m_pclActor->GetFileName () != "" && pActor->m_pclActor->GetFileName () != "NoFileName"*/)
			pActor->m_pclActor->fn_vNotifySave ();
	}
	else
	{
		text2="Error: Undefined list type";
		text1="Program attempted to set to NULL\nan undefined object list\n to an actor";
		Answer = MessageBox(NULL,(LPCTSTR)text1,(LPCTSTR)text2,MB_YESNO | MB_ICONQUESTION /*| MB_SYSTEMMODAL*/);
		return FALSE;
	}
	return TRUE;

}

/*==========================================================
Function name:	EdtList::fn_vInformEditorForAllActors
Description:
Input:
Output:			none
Author:			Yann Le Tensorer
Date:			march 4, 1997
Revision:
==========================================================*/
void EdtList::fn_vInformEditorForAllActors(
						long		    		ulIndexInList,
						CPA_BaseObject      	*OldObject,
						EdActors_EditorActor	*pNotToBeTreatedActor)
{
	POSITION			pos;
	EdActors_EditorActor	*pActor;
	tdstEdtListMess     ListMess;

	if (m_csListType=="")
	{
		return;
	}

    // we have to inform the zone editor or the way editor
    CPA_EditorBase * pDll = NULL;
    // we find the dll to call
    if (OldObject)  pDll = OldObject -> GetEditor ();
    else
    {
        pos = this -> GetHeadPosition ();
        while (pos)
        {
            CPA_SaveObject * pObject = this -> GetNext (pos);
            if (pObject)
            {
                pDll = pObject -> GetEditor ();
                break;
            }
        }
    }
    ASSERT (pDll);    // The Dll must exist

 pos  =fn_oGetListOfActorsUsingThisList()->GetHeadPosition();
	while (pos!=0)
	{
  pActor=fn_oGetListOfActorsUsingThisList()->GetNext(pos);
        if ((pActor->m_fn_tdeGetActorType()!=EDCAR_ACTOR_TYPE_MODEL))
	    {
			ListMess.csListType		=m_csListType;
			ListMess.pActor			=pActor -> m_pclActor;
			ListMess.ulIndexInList	=ulIndexInList;
			ListMess.pList			=this;
			ListMess.pObject		=OldObject;

			pDll -> OnQueryAction (NULL , C_uiQueryAnObjectHasBeenChanged , (long) & ListMess);
		}
    }
}

/*==========================================================
Function name:	EdtList::fn_ulGetNumberOfActorsUsingThisList
Description:
Input:
Output:			none
Author:			Yann Le Tensorer
Date:			february 17, 1997
Revision:
==========================================================*/
unsigned long EdtList::fn_ulGetNumberOfActorsUsingThisList()
{
 fn_oGetListOfActorsUsingThisList();        //update the list if necessary
 return m_ulNumberOfActorsUsingThisList;
}

/*==========================================================
Function name:	EdtList::CallbackToSaveObjectList
Description:	static function : callback to save an object list
Author:			Alexis Vaisse
Date:			april 8, 1997
Revision:       april 23, 1997
==========================================================*/
void EdtList::CallbackToSaveObjectList (SCR_tdst_File_Description * _p_stFile        ,
                                        char                      * _p_szSectionName ,
                                        void                      * _p_vData         ,
                                        SCR_tde_Ntfy_Action         _eAction)
{
  // Get the object list to save
  EdtList * pEdtList = (EdtList *) _p_vData;
  
  switch (_eAction)
  {
  case SCR_EA_Ntfy_AddSection:
    // go to the end of the file
    SCR_fn_v_SvL1_ToEndSection (_p_stFile);
    //and fall through
    
  case SCR_EA_Ntfy_RebuildSection:
    {
      // Compute the correct section name
      char szIdName [SCR_CV_ui_Cfg_MaxLenName];
      char szActionName [SCR_CV_ui_Cfg_MaxLenName];
      char szCorrectSectionName [SCR_CV_ui_Cfg_MaxLenName];
      
      SCR_fn_v_RdL0_SplitSectionName ( _p_szSectionName, NULL, szActionName, szIdName );
      SCR_fn_v_RdL0_ComputeSectionName (szCorrectSectionName , NULL ,szActionName, szIdName );
      
      CString csListType = pEdtList -> fn_csGetListType ();
      if (csListType == C_szWayName)    // List of ways
      {
        // We save the begin section, that is the name of the section
        SCR_M_SvL0_SaveBeginSection( _p_stFile, szCorrectSectionName , SCR_CC_C_Cfg_EOL);

      }
      else                              // List of zones
      {
        // We save the begin section, that is the name of the section
        SCR_M_SvL0_SaveBeginSection( _p_stFile, szCorrectSectionName , SCR_CC_C_Cfg_NoChar);
        // Then we save the parameters : the type (ZDD/ZDE/ZDM/ZDR) of the zones, and the number of zones
        char * szType;
        if (csListType == C_szZddName)
          szType = "Zdd";
        else if (csListType == C_szZdeName)
          szType = "Zde";
        else if (csListType == C_szZdmName)
          szType = "Zdm";
        else if (csListType == C_szZdrName)
          szType = "Zdr";
        else
          ASSERT (0);
        SCR_fn_v_SvL0_SaveParameters_MP (_p_stFile , SCR_EF_SvL0_Scanf , 2 , "%s,%d" , szType , pEdtList -> GetCount ());
        
        // Then we save the objects of the list
        POSITION Pos = pEdtList -> GetHeadPosition ();
        while (Pos)
        {
          CPA_SaveObject * pObject = pEdtList -> GetNext (Pos);
          if (pObject)
          {
            SCR_M_SvL0_SaveEntry            (_p_stFile , "GeometricObject" , SCR_CC_C_Cfg_NoChar);
            // We get the section name of the object
            SCR_fn_v_SvL0_SaveParameters_MP (_p_stFile , SCR_EF_SvL0_Normal , 1 , (char *) (LPCTSTR) pObject -> GetReferencedSectionName ());
          }
          else
            SCR_M_SvL0_SaveEntry            (_p_stFile , "Nothing" , SCR_CC_C_Cfg_EOL);
        }
      }
      
      // Now, we save the end section and we go to the next line
      SCR_M_SvL0_SaveEndSection (_p_stFile , SCR_CC_C_Cfg_EOL);
      
      // We put a blank line just for the fun
      //       SCR_M_SvL0_SaveBlankLine  (_p_stFile);
      
      // We say that the section exists
      //        pEdtList -> SetExistingSection (TRUE);
      pEdtList ->fn_vSectionSaved ();		// jt 8/7/97
      
    }
    break;
    
  case SCR_EA_Ntfy_DeleteSection:
    // We say that the section does not exist anymore
    //		pEdtList -> SetExistingSection (FALSE);
    pEdtList ->fn_vSectionDeleted ();	// jt 8/7/97
    break;
  }
}

/*==========================================================
Function name:	EdtList::CallbackToCreateZDxFile
Description:	static function : callback to add a special line when creating a file
Author:			Alexis Vaisse
Date:			July 11, 1997
Revision:
==========================================================*/
void EdtList::CallbackToCreateZDxFile (SCR_tdst_File_Description * _pFile         ,
                                       char                      * _szSectionName ,
                                       void                      * _pData         ,
                                       SCR_tde_Ntfy_Action         _eAction)
{
    switch (_eAction)
    {
        case SCR_EA_Ntfy_AddSection    : // The ZDx file does not exist : we ad a special line
                                         fn_v_SvL0_fputs (_pFile , "$SetCurrentFileDouble(1,1.0)\n");
                                         break;
        case SCR_EA_Ntfy_ModifySection : // The ZDx file already exists : we do nothing
                                         break;
    }
}

/*==========================================================
Function name:	EdtList::AddObjectInZoneMotorList
Description:	Used for a zone list only : add a NULL object into the motor list
                (in fact, delete the old list and create a bigger new one)
Author:			Alexis Vaisse
Date:			may 7, 1997
Revision:
==========================================================*/
void EdtList::AddObjectInZoneMotorList (short wInsertIndex)
{
    // Get the old list and create a bigger new one
    unsigned char          ucEngineType  = (unsigned char) GetDataType ();
    ZDX_tdxHandleToZdxList hOldMotorList = (ZDX_tdxHandleToZdxList) m_hMotorList;
    unsigned short         uwNumberOfZDx = GetCount () + 1;
    ZDX_tdxHandleToZdxList hNewMotorList = ZDX_fn_hCreateEmptyListOftype (ucEngineType  , uwNumberOfZDx);
    fn_vUpdateData(hNewMotorList);
    m_hMotorList                         = hNewMotorList;

    // Copy the object from the old list to the new one, with the hole at the right place
    int i , j;
    for (i = j = 0 ; i < uwNumberOfZDx - 1 ; i++ , j++)
    {
        ACP_tdxHandleOfObject hObject = ZDX_fn_hGetGeometricZdxInListAtIndex (i , hOldMotorList);
        if (j == wInsertIndex)  j++;
        ZDX_fn_vSetGeometricZdxInListAtIndex (j , hNewMotorList , hObject);
    }

    // Put the new list for all engine actors
    CPA_List<EdActors_EditorActor> * pListOfAllActors = fn_oGetListOfActorsUsingThisList ();
    for (EdActors_EditorActor * pEditorActor = pListOfAllActors -> GetHeadElement () ; pEditorActor ;
                                pEditorActor = pListOfAllActors -> GetNextElement (pEditorActor))
    {
        CPA_Actor                  * pActor             = pEditorActor -> m_pclActor;
        if (pActor -> m_fn_bIsAnInstance ())
        {
            HIE_tdxHandleToSuperObject   hEngineSuperObject = pActor -> m_pub_fn_hGetMotorSuperObject ();
            CS_fn_vSetZdxList (ucEngineType , hEngineSuperObject , hNewMotorList);
        }
    }

    // Delete the old list
    if (hOldMotorList)  ZDX_fn_vDestructZdxList (hOldMotorList);
    fn_vNotifySave ();
}

/*==========================================================
Function name:	EdtList::RemoveObjectInZoneMotorList
Description:	Used for a zone list only : delete an object from the motor list
                (in fact, delete the old list and create a smaller new one)
Author:			Alexis Vaisse
Date:			may 16, 1997
Revision:
==========================================================*/
void EdtList::RemoveObjectInZoneMotorList (short wIndex)
{
    // Get the old list and create a smaller new one
    unsigned char          ucEngineType  = (unsigned char) GetDataType ();
    ZDX_tdxHandleToZdxList hOldMotorList = (ZDX_tdxHandleToZdxList) m_hMotorList;
    unsigned short         uwNumberOfZDx = GetCount () - 1;
    ZDX_tdxHandleToZdxList hNewMotorList = ZDX_fn_hCreateEmptyListOftype (ucEngineType  , uwNumberOfZDx);
    fn_vUpdateData(hNewMotorList);
    m_hMotorList                         = hNewMotorList;

    // Copy the object from the old list to the new one
    int i , j;
    for (i = j = 0 ; j < uwNumberOfZDx ; i++ , j++)
    {
        if (i == wIndex)  i++;
        ACP_tdxHandleOfObject hObject = ZDX_fn_hGetGeometricZdxInListAtIndex (i , hOldMotorList);
        ZDX_fn_vSetGeometricZdxInListAtIndex (j , hNewMotorList , hObject);
    }

    // Put the new list for all engine actors
    CPA_List<EdActors_EditorActor> * pListOfAllActors = fn_oGetListOfActorsUsingThisList ();
    for (EdActors_EditorActor * pEditorActor = pListOfAllActors -> GetHeadElement () ; pEditorActor ;
                                pEditorActor = pListOfAllActors -> GetNextElement (pEditorActor))
    {
        CPA_Actor                  * pActor             = pEditorActor -> m_pclActor;
        if (pActor -> m_fn_bIsAnInstance ())
        {
            HIE_tdxHandleToSuperObject   hEngineSuperObject = pActor -> m_pub_fn_hGetMotorSuperObject ();
            CS_fn_vSetZdxList (ucEngineType , hEngineSuperObject , hNewMotorList);
        }
    }

    // Delete the old list
    if (hOldMotorList)  ZDX_fn_vDestructZdxList (hOldMotorList);
    fn_vNotifySave ();
}

/*==========================================================
Function name:	fn_vNotifyRename
Description:	Called when a fn_eRename is done : we make
                notification to save the list of names
                and all actors using this list
Input:			the new name
Author:			Alexis   Vaisse
Date:			May 16, 1997
Revision:       July 1, 1997
==========================================================*/
void EdtList::fn_vNotifyRename ()
{
    CPA_SaveObject::fn_vNotifyRename ();

    // Notify to save the list of names
    ((CPA_SaveObject *) GetOwner ()) -> fn_vUpdateReference (this);    // This makes a fn_vNotifySave

    // Notify to save all the actors using this list
    CPA_List<EdActors_EditorActor> * pListOfEditorActor = fn_oGetListOfActorsUsingThisList ();
    EdActors_EditorActor * pEditorActor = pListOfEditorActor -> GetHead ();
    while (pEditorActor)
    {
        CPA_Actor * pActor = pEditorActor -> m_pclActor;
        pActor -> fn_vNotifySave ();
        pEditorActor = pListOfEditorActor -> GetNextElement (pEditorActor);
    }
}

/*==========================================================
Function name:	fn_vNotifySave
Description:	Called to make a notification to save the EdtList
Author:			Alexis Vaisse
Date:			July 11, 1997
Revision:
==========================================================*/
void EdtList::fn_vNotifySave ()
{
    CPA_SaveObject::fn_vNotifySave ();

    // If the file does not exist, register a callback on it
    char szFileName [SCR_CV_ui_Cfg_MaxLenName];
    SCR_fn_v_RdL0_SplitSectionName ((char *) (LPCTSTR) GetCompleteSectionName () , szFileName , NULL , NULL);
    if (_access (szFileName , 0) == -1)
        SCR_fn_v_SvL1_RegisterNotify (szFileName , CallbackToCreateZDxFile , NULL , SCR_EA_Ntfy_AddOrModifySection);
}

/*==========================================================
Function name:	fn_eCheckUnicity
Description:	Check unicity : Name+Type+Family
Author:			Alexis Vaisse
Date:			August 5, 1997
Revision:
==========================================================*/
tdeMissingCriteria EdtList::fn_eCheckUnicity (const CString csNewName)
{
    CPA_BaseObject              *p_oFamily = GetOwner() -> GetOwner();
    CPA_List<CPA_BaseObject>     oList;
    long                         lNbObjects;

	if (csNewName.IsEmpty())
		return E_mc_NoName;
    //
    // search EdtList with same name on invalid objects
    lNbObjects = GetInvalidObjectList() -> fn_lFindObjects( & oList, csNewName, GetType() );
    if( lNbObjects > 0 )
    {
        // find objects with same name
        // search object with same family
        POSITION xPos = oList . GetHeadPosition();
        while( xPos )
        {
            CPA_BaseObject* p_oEdtList = oList . GetNext( xPos );
            if( p_oEdtList -> GetOwner() -> GetOwner() == p_oFamily )
            {
                // find one object, invalid name
                return ( E_mc_OwnerUnicity );
            }
        }
    }
    oList . RemoveAll();
    // search EdtList with same name on valid objects
    lNbObjects = GetBaseObjectList() -> fn_lFindObjects( & oList, csNewName, GetType() );
    if( lNbObjects > 0 )
    {
        // find objects with same name
        // search object with same family
        POSITION xPos = oList . GetHeadPosition();
        while( xPos )
        {
            CPA_BaseObject* p_oEdtList = oList . GetNext( xPos );
            if( p_oEdtList -> GetOwner() -> GetOwner() == p_oFamily )
            {
                // find one object, invalid name
                return ( E_mc_OwnerUnicity );
            }
        }
    }
    // ok
    return ( E_mc_None );
}

/*==========================================================
Function name:	fn_vCopyNonVirgeReferences
Description:	Copies non virge references from one list to another
Input:
Output:
Author:			Yann Le Tensorer
Date:			february 20, 1997
Revision:		Yann Le Tensorer july 30, 1997
				Add a boolean to inform or not the editor of the changes
==========================================================*/
void fn_vCopyNonVirgeReferences(EdtList* src,EdtList* dst,BOOL _bInformEditor=NULL,CPA_BaseObject* _pActor=NULL)
{
	tdoObjectName	*Name;
	POSITION		pos,posSrc,posDst;
	CPA_tdoNameList *pNameList;
	unsigned long	ulIndexInList;
	CPA_SaveObject  *pObject;

	pNameList=src->fn_oGetNameList();
	pos				=pNameList->GetHeadPosition();
	posSrc			=src->GetHeadPosition();
	posDst			=dst->GetHeadPosition();
	ulIndexInList = 0;

	while (pos!=0)
	{
		Name=pNameList->GetNext(pos);
		if (Name->m_eGetShareMode()!=E_sm_Virge)
		{
			pObject=src->GetNext(posSrc);
			dst->GetNext(posDst)=pObject;

			if (_bInformEditor && pObject)
			{
				tdstEdtListMess ListMess;
                ListMess . csListType    = dst -> fn_csGetListType ();
                ListMess . pActor        = _pActor;
                ListMess . ulIndexInList = ulIndexInList;
                ListMess . pList         = dst;
                ListMess . pObject       = NULL;  // old object
                pObject -> GetEditor () -> OnQueryAction (NULL , C_uiQueryAnObjectHasBeenChanged , (long) & ListMess);
			}
		}
		else
		{
			dst->GetNext(posDst);
			src->GetNext(posSrc);
		}
		ulIndexInList++;
	}
}

/*==========================================================
Function name:	fn_oGetCopyOfEdtList
Description:	Creates a new EdtList and Copies the given EdtList into it
Input:
Output:
Author:			Yann Le Tensorer
Date:			february 21, 1997
Revision:
==========================================================*/
EdtList* fn_oGetCopyOfEdtList(EdtList* src)
{
	POSITION		posSrc,posDst;
	CPA_tdoNameList *pNameList;
	EdtList			*dst;

	pNameList=src->fn_oGetNameList();

	/* create a new list of same type with same list of name */
	dst=new EdtList(pNameList,src->fn_csGetListType(),"",FALSE);

	posSrc			=src->GetHeadPosition();
	posDst			=dst->GetHeadPosition();

	while (posSrc!=0)
	{
		dst->GetNext(posDst)=src->GetNext(posSrc);
	}

	return dst;
}

/*==========================================================
Function name:	fn_p_oGetsNameListOfAnActor
Description:	returns the Name List of an editor actor
Input:			pointer to the actor
Output:			returns a pointer to the NameList
Author:			Yann Le Tensorer
Date:			february 12, 1997
Revision:
==========================================================*/
CPA_tdoNameList* fn_poGetsNameListOfAnActor(EdActors_EditorActor *pActor,CString ListTypeString)
{
CPA_tdoNameList*	pNameList;

	pNameList=((CPA_Editor_ObjectListData*)(pActor->m_fn_p_oFindDataByName(ListTypeString)))->m_p_oNameList;
	return pNameList;
}





/*==========================================================
Function name:	Class EdtListHandler Constructor
Description:	Creates a EdtListHandler
Input:
Output:			none
Author:			Yann Le Tensorer
Date:			february 14, 1997
Revision:
===================================================*/
EdtListHandler::EdtListHandler()
{
	m_pListOfEdtLists		=new CPA_List<EdtList>;
}

/*==========================================================
Function name:	EdtListHandler::fn_vAddObjectToAllLists
Description:	insert a null pointer at the tail of all lists of the handler
Input:
Output:			none
Author:			Yann Le Tensorer
Date:			february 21, 1997
Revision:
===================================================*/
void EdtListHandler::fn_vAddObjectToAllLists
(
 tdoObjectName *p_oNewObjectName,
 short wInsertIndex /* = -1 */
 /*CPA_List<CPA_BaseObject> *p_oReferencesList*/ /* = NULL */
 )
{
  //if we have to reinsert object references, make sure we have as many references as object lists
  //ASSERT(p_oReferencesList == NULL || p_oReferencesList->GetCount() == m_pListOfEdtLists->GetCount());
  POSITION			posListOfLists;
  //short wReinsertedReferencesCount = 0;
  //we have to reinsert the reference before the tail of the lists
  BOOL bInsertBefore = (wInsertIndex >= 0 && wInsertIndex < m_pNameList->GetCount());
  if ( bInsertBefore )
    m_pNameList->InsertBefore(m_pNameList->FindIndex(wInsertIndex), p_oNewObjectName);
  else
    m_pNameList->AddTail(p_oNewObjectName);
  
  //scan all object lists created with this name list
  posListOfLists = m_pListOfEdtLists->GetHeadPosition();
  while (posListOfLists != 0)
  {
    EdtList *CurList = m_pListOfEdtLists->GetNext(posListOfLists);
    POSITION xInsertPos = CurList->FindIndex(wInsertIndex);
    /*CPA_BaseObject *pInsertedReference;
    
      //get the reference to insert back
      pInsertedReference = p_oReferencesList
      ? p_oReferencesList->GetAt(p_oReferencesList->FindIndex(wReinsertedReferencesCount ++))
    : NULL;*/
    
    //update engine lists as well
    if (CurList -> fn_csGetListType () != C_szWayName)
      CurList -> AddObjectInZoneMotorList (wInsertIndex);
    //and store it back in the object list
    if ( bInsertBefore )
      CurList->InsertBefore(xInsertPos, (CPA_SaveObject *) NULL);
    else
      CurList->AddTail((CPA_SaveObject *) NULL);
  }
}

/*==========================================================
Function name: EdtListHandler::m_p_oRemoveObjectFromAllLists
Description:	remove an object from all lists of the handler at a specified position
Input:
Output:			none
Author:			Yann Le Tensorer
Date:			february 21, 1997
Revision:
				march 6, 1997 / YLT / remove object from name list too
===================================================*/
void /*CPA_List<CPA_BaseObject> **/EdtListHandler::m_vRemoveObjectFromAllLists(unsigned long ulIndex)
{
  POSITION			posListOfLists;
  EdtList				*CurList;
  CPA_tdoNameList		*NameList;
  POSITION			posInList;
  POSITION			posInNameList;
  //CPA_List<CPA_BaseObject> *p_oRemovedReferencesList = new CPA_List<CPA_BaseObject>;
  
  /* remove it from name list */
  NameList=fn_oGetNameList();
  posInNameList=NameList->FindIndex(ulIndex);
  delete  NameList->GetAt(posInNameList);
  NameList->RemoveAt(posInNameList);
  
  if (m_pListOfEdtLists!=0)
  {
    posListOfLists=m_pListOfEdtLists->GetHeadPosition();
    
    while (posListOfLists!=0)
    {
      CurList	= m_pListOfEdtLists->GetNext(posListOfLists);
      posInList = CurList->FindIndex(ulIndex);
      //remembers the reference that is removed from the list
      //p_oRemovedReferencesList->AddTail(CurList->GetAt(posInList));
      
      //update engine lists as well
      if (CurList -> fn_csGetListType () != C_szWayName)
        CurList->RemoveObjectInZoneMotorList((short) ulIndex);

      CurList->RemoveAt(posInList);
    }
  }
  //return p_oRemovedReferencesList;
}

/*==========================================================
Function name:	EdtListHandler::fn_bSetObjectInAllLists
Description:	Set an object in all the lists of the handler at a specified position
Input:			pObject:	Object to set
				ulIndex:	Position
Output:			none
Author:			Yann Le Tensorer
Date:			february 24, 1997
Revision:
===================================================*/
BOOL EdtListHandler::fn_bSetObjectInAllLists(unsigned long ulIndex,CPA_SaveObject *pObject)
{
	POSITION			posListOfLists;
	EdtList				*CurList;
	POSITION			posInList;

	if (m_pListOfEdtLists==NULL) return FALSE;

	posListOfLists=m_pListOfEdtLists->GetHeadPosition();
	while (posListOfLists!=0)
		{
			CurList	= m_pListOfEdtLists->GetNext(posListOfLists);
			posInList = CurList->FindIndex(ulIndex);
			if (posInList==NULL) return FALSE;
			CurList->SetAt(posInList,pObject);
		}
	return TRUE;
}

/*==========================================================
Function name:	EdtListHandler::fn_bSetObjectInModelListForSharedField
Description:	Set an object at a specified position in a given model list
Input:			pObject:	Object to set
				ulIndex:	Position
				pModelList:	ListOfModel
Output:			TRUE if modification was done, false if not
Author:			Yann Le Tensorer
Date:			february 24, 1997
Revision:

Note:			If actors are using the model list as object list, and a
				shared field is being modified, the old list must be duplicated, and the
				two actors must point on it, before changing the value in the new list
===================================================*/
BOOL EdtListHandler::fn_bSetObjectInModelListForSharedField(unsigned long ulIndex,
												CPA_SaveObject *pObject,
												EdtList *pModelList)
{

	POSITION			posInList;

	posInList = pModelList->FindIndex(ulIndex);
	if (posInList==NULL) return FALSE;

	//ModelList->SetAt(posInList,pObject);

	return TRUE;
}

/*==========================================================
Function name:	EdtListHandler::fn_bChangeNameListShareMode
Description:	Change an attribute of a name list and makes all
				modifications in the associated object lists
Input:
Output:			TRUE if modification was done, False if not
Author:			Yann Le Tensorer
Date:			march 5, 1997
Revision:
===================================================*/
BOOL	EdtListHandler::fn_bChangeNameListShareMode(unsigned long		ulIndex,
													tdeShareMode		NewAttribute,
             EdtList    *pModelList
)
{
	POSITION			pos;
	tdeShareMode		OldAttribute;
	tdoObjectName		*Name;
	BOOL				RetValue;
	CPA_SaveObject	*ModelValue;

	POSITION			posListOfLists;
	POSITION			posInListOfActors;
	EdtList				*CurList;
	EdtList				*NewList;
	POSITION			posInList;
	BOOL				bFirstDone;
	unsigned long		NumberOfNewLists;
	CPA_List<EdActors_EditorActor> *ListOfActors;
	EdActors_EditorActor	*CurActor;

	RetValue=TRUE;


	/* finds the old attribute */
	pos	= m_pNameList->FindIndex(ulIndex);
	if (pos!=0)
	{
		Name=m_pNameList->GetAt(pos);
		OldAttribute=Name->m_eGetShareMode();
	}
	else return FALSE;

	/* if no modele list is given, changes the share mode without modifying anything else */
	if (pModelList==NULL)
	{
		Name->m_vSetShareMode(NewAttribute);
		return TRUE;
	}

	/* finds the object in the model list at the given index */
	pos = pModelList->FindIndex(ulIndex);
	if (pos!=0)
	{
		ModelValue=pModelList->GetAt(pos);
	}
 else
  return FALSE;

// if (
//  (OldAttribute==E_sm_Shared && NewAttribute==E_sm_Common) ||
//  (OldAttribute==E_sm_Virge && NewAttribute==E_sm_Common)
//  )
// {
//  //set in all object lists the value found in the model's object list
//  fn_bSetObjectInAllLists(ulIndex, ModelValue);
//  Name->m_vSetShareMode(NewAttribute);
//  return TRUE;
// }

 if
		(
		(OldAttribute==E_sm_Common && NewAttribute==E_sm_Virge) ||
		(OldAttribute==E_sm_Shared && NewAttribute==E_sm_Virge)
		)
	{
		/* this one is a bit complex...*/

		/* test number of virge fields
		 if >0, it means the list had already a virge field, so no need
		 to separate the lists
		 else (==0), separate all lists so that the number of actors using one
		 list is always 1 */
		if ( m_pNameList->m_ulGetNumberOfVirgeFields() == 0)
		{
			/* loop thru all lists of the handler */

			if (m_pListOfEdtLists==NULL) return FALSE;

			posListOfLists=m_pListOfEdtLists->GetHeadPosition();
			while (posListOfLists!=0)
			{
				/* set the value of the list to the model value */
				CurList	= m_pListOfEdtLists->GetNext(posListOfLists);
				posInList = CurList->FindIndex(ulIndex);
				if (posInList==NULL) return FALSE;
				CurList->SetAt(posInList,ModelValue);

				/* for each list, see how many actors are using the list
				if there are more than one, loop thru all actors
				using the current list and create a new list for each actor
				except the first one...*/

    NumberOfNewLists = (CurList->fn_ulGetNumberOfActorsUsingThisList())-1;
				ListOfActors=CurList->fn_oGetListOfActorsUsingThisList();
    if (NumberOfNewLists > 0)
				{
					posInListOfActors=ListOfActors->GetHeadPosition();
					bFirstDone=FALSE;
					while (posInListOfActors!=0)
					{
						CurActor	= ListOfActors->GetNext(posInListOfActors);
						if (bFirstDone)
						{
							NewList=fn_oGetCopyOfEdtList(CurList);
                            m_pListOfEdtLists -> AddTail (NewList);
							CurList->fn_bMakeActorNotUseThisList(CurActor);
							NewList->fn_bMakeActorUseThisList(CurActor);
       NumberOfNewLists --; /* this is just a check for debuging */
						}
						else
							bFirstDone=TRUE;
					}
				}

			}

		}


	}

 else if
 (
		(OldAttribute==E_sm_Shared && NewAttribute==E_sm_Common) ||
		(OldAttribute==E_sm_Virge && NewAttribute==E_sm_Common)
		)
	{
		/* copy the default model value to all fields */
  if ( fn_bSetObjectInAllLists(ulIndex, ModelValue) == FALSE )
			RetValue=FALSE;


	}

	if (RetValue==TRUE)
	{
		Name->m_vSetShareMode(NewAttribute);
	}
	return RetValue;
}

/*==========================================================
Function name:	EdtListHandler::fn_poGetEdtList
Description:	Returns the EdtList of a given type from an actor
Input:
Output:			returns a pointer to the list
Author:			Yann Le Tensorer
Date:			february 14, 1997
Revision:
==========================================================*/
class EdtList*	EdtListHandler::fn_poGetEdtList(tdstEdtListMess* p_ListMess)
{
	EdActors_EditorActor  *pActor;

	if (p_ListMess==NULL) return NULL;
	if (p_ListMess->pActor==NULL) return NULL;

	/* gets the Editor Actor */
	pActor=((CPA_Actor*)p_ListMess->pActor)->m_fn_pclGetEditorActor();

	return pActor->m_fn_p_oGetObjectList(p_ListMess->csListType);
}

/*==========================================================
Function name:	EdtListHandler::fn_vSetEdtList
Description:	Assign an EdtList of a given type to an actor
Input:			p_ListMess->csListType  :type of list
				p_ListMess->pList		:list to set to actor and handler
				p_ListMess->pActor		:actor who the list will belong
Output:			returns a pointer to the list
Author:			Yann Le Tensorer
Date:			february 14, 1997
Revision:
==========================================================*/
void EdtListHandler::fn_vSetEdtList(tdstEdtListMess* p_ListMess)
{
	EdActors_EditorActor  *pActor;
	EdtList*			OldList;
	EdtList*			NewList;
	POSITION			pos;

	if (p_ListMess==NULL) return;
	if (p_ListMess->pActor==NULL) return;


	/* gets the Editor Actor */
	pActor=((CPA_Actor*)p_ListMess->pActor)->m_fn_pclGetEditorActor();

	/* gets the old list of the actor */
	OldList=pActor->m_fn_p_oGetObjectList(p_ListMess->csListType);
	NewList=p_ListMess->pList;

	/* if a list is already attached to the actor, decrement the
	number of actors using the old list */
	if (OldList!=NULL)
	{
		OldList->fn_bMakeActorNotUseThisList(pActor);
	}

	if (NewList!=NULL)
	{
		/* makes the actor use this list */
		NewList->fn_bMakeActorUseThisList(pActor);

		/* look if the new list can be found in the list of Edtlists */
		/* if not, add the list in the list of Edtlists of the handler */
		pos=m_pListOfEdtLists->Find(NewList);
		if (pos==NULL)
		{
			m_pListOfEdtLists->AddTail(NewList);
		}
	}
	else
	{
	/* assign a null list of type p_ListMess->csListType to the actor */
	pActor->m_fn_vSetObjectList(p_ListMess->csListType,NULL);
	}

}

/*==========================================================
Function name:	EdtListHandler::fn_vCreateEdtList
Description:	Creates an EdtList
Input:
Output:			returns a pointer to the created list;
				returns NULL if an error occured
Author:			Yann Le Tensorer
Date:			february 12, 1997
Revision:		Yann Le Tensorer July 30, 1997
				Don't create an empty model list anymore
				but fill the common fields with those of any other list
				Y l T & B G September 11, 1997
				When a specific list is created for an instance
				from a model which as no object list, attach a single
				object list to both actors instead of creating one
				object list for each actor
==========================================================*/
class EdtList*	EdtListHandler::fn_poCreateEdtList(tdstEdtListMess* p_ListMess)
{
	EdActors_EditorActor  *pActor;

	unsigned char		ucOwnerType; // is it a model or instance ?
	CPA_tdoNameList	*pNameList = NULL;
	EdtList				*NewList = NULL, *pTemplateList = NULL;
	EdtList				*pModelList = NULL;
	EdtList				*pCurrentList = NULL;
	EdActors_EditorActor  *pModel = NULL;	// model of the actor
	EdtList				* pReferenceEdtList = NULL; // list used to get all the common fields
	BOOL bNotifySaveActor = !g_pclInterface->GetInterface()->fn_bIsLoadingWorld();

	if ( p_ListMess == NULL )
		return NULL;
	if ( p_ListMess->pActor == NULL )
		return NULL;



	/* gets the CarEditor Actor */
	pActor = ((CPA_Actor*) p_ListMess->pActor)->m_fn_pclGetEditorActor();

	//get the current object list for the specified actor
	pCurrentList = pActor->m_fn_p_oGetObjectList(p_ListMess->csListType);
	//if it already has one, do nothing
	if ( pCurrentList )
		return pCurrentList;

	/* find the type of the actor */
	switch (pActor->m_fn_tdeGetActorType())
	{
	case EDCAR_ACTOR_TYPE_INSTANCE:
		ucOwnerType = C_ucInstance;
		break;

	case EDCAR_ACTOR_TYPE_MODEL:
		ucOwnerType = C_ucModele;
		break;

	default:
		ucOwnerType = C_ucInstance;
		break;
	}

	// find the Model and the NameList of the actor
  if ( ucOwnerType == C_ucInstance )
  {
		pModel = ((CPA_Actor *) (p_ListMess -> pActor)) -> m_fn_pclGetModel () -> m_fn_pclGetEditorActor ();
		ASSERT (pModel);
		pNameList = fn_poGetsNameListOfAnActor(pModel, p_ListMess->csListType);
		// find the object list of the model
		pModelList = pModel->m_fn_p_oGetObjectList(p_ListMess->csListType);
  }
  else
  {
    pNameList = fn_poGetsNameListOfAnActor(pActor, p_ListMess->csListType);
  }
  ASSERT (pNameList);

	//must each actor have its own copy of an object list for the object list ?
	BOOL bListsAreSharable = !pNameList->m_bHasAVirgeField();

	//here we  have all the information we need, and the actor has no object list yet

	//now if it is a model, or an instance whose model has no object list, find a template object list
	if ( ucOwnerType == C_ucModele || !pModelList )
	{
		CList<CPA_BaseObject *, CPA_BaseObject *> oFatherList;
		int iNbFathers = g_oCoherenceManager.m_fn_iGetFatherList(pNameList, &oFatherList);
		while ( !oFatherList.IsEmpty() )
		{
			CPA_Actor *p_oOtherOwningModel = (CPA_Actor *) oFatherList.RemoveHead();
			pTemplateList = p_oOtherOwningModel->m_fn_pclGetEditorActor()->m_fn_p_oGetObjectList(p_ListMess->csListType); // get other model's object list
			//and give it to our current model
			if ( pTemplateList )
				break;
		}
	}
	else //it is an instance and its model list is valid
		pTemplateList = pModelList;

// add jt 	15/9/97
	if (pNameList->GetType ()==g_c_csWayNameListType)
	{
		NewList = new EdtList(pNameList, p_ListMess->csListType, "", FALSE);
		if (m_pListOfEdtLists->GetCount())
		{
			pReferenceEdtList = m_pListOfEdtLists->GetTail();
			fn_vCopyNonVirgeReferences(pReferenceEdtList, NewList);
		}	
		m_pListOfEdtLists->AddTail(NewList);
		NewList->fn_bMakeActorUseThisList(pActor, bNotifySaveActor);
		return NewList;
	}
// end jt 	15/9/97

	//if the template cannot be used directly, create a copy from it
	BOOL bNewListCreatedforTheModel = FALSE;
	if ( !bListsAreSharable || !pTemplateList )
	{
		NewList = new EdtList(pNameList, p_ListMess->csListType, "", FALSE, (!pModelList));
		bNewListCreatedforTheModel = TRUE;
		if ( pTemplateList && (m_pListOfEdtLists->GetCount() > 0) )
		{
			pReferenceEdtList = m_pListOfEdtLists->GetTail();
			fn_vCopyNonVirgeReferences(pReferenceEdtList, NewList);
		}
		// add it in the list of EdtLists of the handler
		m_pListOfEdtLists->AddTail(NewList);
	}
	else
		NewList = pTemplateList;

	//here either we created a copy of the list from the template, or it is the template itself
	ASSERT(NewList);

	if ( ucOwnerType == C_ucModele )
	{
		//make the model use the object list we found for him
		NewList->fn_bMakeActorUseThisList(pActor, bNotifySaveActor);
	}
	else //the actor for which we create the list is an instance
	{
		if ( !pModelList ) //its model had no object list
		{
			//give it the one we got
			NewList->fn_bMakeActorUseThisList(pModel, bNotifySaveActor);
			//if the list is not sharable, the instance must get its own copy,
			//unless we created a list for the model because this is the only
			//object list yet, hence the instance can use it,
			//unless this is a zone object list in which case we create a copy anyway
			if ( !bListsAreSharable /*&& !bNewListCreatedforTheModel*/ )
			{
				NewList = new EdtList(pNameList, p_ListMess->csListType, "", FALSE);
				if ( m_pListOfEdtLists->GetCount() > 0 )
				{
					pReferenceEdtList = m_pListOfEdtLists->GetTail();
					fn_vCopyNonVirgeReferences(pReferenceEdtList, NewList);
				}
				// add it in the list of EdtLists of the handler
				m_pListOfEdtLists->AddTail(NewList);
			}
		}
		//in either case, give an object list to the instance
		NewList->fn_bMakeActorUseThisList(pActor, bNotifySaveActor);
	}

	return NewList;

	//LE GROS PATE INCOMPREHENSIBLE DE YANN LA-DESSOUS NE SERT NORMALEMENT PLUS,
	//SAUF A TITRE DE REFERENCE S'IL Y A DES BUGS AU-DESSUS

	/*
		Modified by Yann Le Tensorer on July 30, 1997:

	  if the actor is a model, we create a new model list and we do the following:
		The list handler handles all the list attached to the name list,
		so, if there are already lists, all the common fields of the new list must be filled
		with those of any other list...
		if there are no lists, the common fields remain empty.
	*/
	if (ucOwnerType==C_ucModele)
	{
		/* create the new model list */
		NewList=new EdtList(pNameList,p_ListMess->csListType,"",FALSE);
		NewList->fn_bMakeActorUseThisList(pActor, bNotifySaveActor);

		/* if there are other lists, copy the non virge */
		if (m_pListOfEdtLists->GetCount()>0)
		{
			pReferenceEdtList = m_pListOfEdtLists -> GetTail ();
			fn_vCopyNonVirgeReferences(pReferenceEdtList,NewList);
		}

		/* add it in the list of EdtLists of the handler*/
		m_pListOfEdtLists->AddTail(NewList);
	}
	else
	/* the actor is an instance */
	{

    if ( pModelList == 0 )
    {
			/* the model doesn't have a object list */

			//if the name list is used by some other model, find an object list from him and give it to
			//the current model
			BOOL bFoundASuitableList = FALSE;
      CList<CPA_BaseObject *, CPA_BaseObject *> oFatherList;
			int iNbFathers = g_oCoherenceManager.m_fn_iGetFatherList(pNameList, &oFatherList);
			while ( !oFatherList.IsEmpty() )
			{
				CPA_Actor *p_oOtherOwningModel = (CPA_Actor *) oFatherList.RemoveHead();
        NewList = p_oOtherOwningModel->m_fn_pclGetEditorActor()->m_fn_p_oGetObjectList(p_ListMess->csListType); // get other model's object list
				//and give it to our current model
				if ( NewList )
				{
					NewList->fn_bMakeActorUseThisList(pModel, bNotifySaveActor);
					bFoundASuitableList = TRUE;
					break;
				}
      }

      // if we did not find another object list, create it and attach it to the model
      if ( !NewList )
			{
	      NewList = new EdtList(pNameList,p_ListMess->csListType,"",FALSE);

				/* if there are other lists, copy the non virge fields*/
				if (m_pListOfEdtLists->GetCount()>0)
				{
					pReferenceEdtList = m_pListOfEdtLists -> GetTail ();
					fn_vCopyNonVirgeReferences(pReferenceEdtList,NewList,TRUE,p_ListMess->pActor);
				}
			}

			/* make the model use this list, except for waypoints */
      NewList->fn_bMakeActorUseThisList(pModel, (pNameList->GetType()!= g_c_csWayNameListType) && bNotifySaveActor);
			pModelList=NewList;

		/*
            // This new EdtList is actually empty.
            // But if it has common fields, these fields must have the same objects
            // as the other EdtList of the list of names have :
            // If there is at least another EdtList ...
            if (m_pListOfEdtLists -> GetCount () > 0)
            {
                // we take the last list, because now, we don't use the model list anymore, but we
                // use any other list. By taking the last, we are sure not to take the model list which is the first...
                pReferenceEdtList = m_pListOfEdtLists -> GetTail ();

                // Then we check each name in the list of name
                unsigned long ulIndexInList = 0;
                POSITION ReferencePos = pReferenceEdtList -> GetHeadPosition ();
                POSITION NewPos       = NewList           -> GetHeadPosition ();
                for (tdoObjectName * pName = m_pNameList -> GetHeadElement () ; pName ;
                                     pName = m_pNameList -> GetNextElement (pName))
                {
                    // If it has a common field ...
                    if (pName -> m_eGetShareMode () == E_sm_Common)
                    {
                        // we set in the new list the same object as in the reference EdtList
                        CPA_SaveObject * pObject = pReferenceEdtList -> GetAt (ReferencePos);
                        NewList -> SetAt (NewPos , pObject);

                        // and we inform the zone editor or the way editor so that it can modify the engine list
                        if (pObject)
                        {
                            tdstEdtListMess ListMess;
                            ListMess . csListType    = NewList -> fn_csGetListType ();
                            ListMess . pActor        = p_ListMess -> pActor;
                            ListMess . ulIndexInList = ulIndexInList;
                            ListMess . pList         = NewList;
                            ListMess . pObject       = NULL;  // old object
                            pObject -> GetEditor () ->
                                OnQueryAction (NULL , C_uiQueryAnObjectHasBeenChanged , (long) & ListMess);
                        }
                    }

                    pReferenceEdtList -> GetNext (ReferencePos);
                    NewList           -> GetNext (NewPos);

                    ulIndexInList ++;
                }
            }

			*/


			// add it in the list of EdtLists, if it is a new list we just created, of course ...
			if ( !bFoundASuitableList )
				m_pListOfEdtLists->AddTail(NewList);
    }

		if ( pNameList->m_bHasAVirgeField() )
		{
			/* it has a virge field in the list,*/
			/* so create a new list for the instance*/
			NewList= new EdtList(pNameList,p_ListMess->csListType,"",FALSE);
			/* add it in the list of EdtLists*/
			m_pListOfEdtLists->AddTail(NewList);
			/* and copy all references of the non Virge fields into the new list */
			fn_vCopyNonVirgeReferences(pModelList,NewList,TRUE,p_ListMess->pActor);
			NewList->fn_bMakeActorUseThisList(pActor, bNotifySaveActor);
    }
		else
		{
			/* the new list is the list of the model */
			NewList= pModelList;
			/* and the instance uses this list*/
			NewList->fn_bMakeActorUseThisList(pActor, bNotifySaveActor);
		}
	}

	return NewList;
}

/*==========================================================
Function name:	EdtListHandler::fn_vCreateEdtList
Description:	Creates an EdtList, child of a name list, with a given name and an already created engine list
Input:          p_NameList    : the name list which will be the parent of the new EdtList
                csName        : the name to give to the new EdtList
                p_vEngineList : the engine list to associate to the new EdtList
Output:			returns a pointer to the created list;
Author:			Alexis Vaisse
Date:			april 17, 1997
Revision:
==========================================================*/
EdtList * EdtListHandler::fn_poCreateEdtList (CPA_tdoNameList * p_NameList , CString csName , void * p_vEngineList ,
                                              BOOL _bSectionExists)
{
//??? A FAIRE : Si la taille de la liste de zones ou de chemins est inférieure à la taille de la liste de noms, l'agrandir
//              et faire une notification de sauvegarde

  CString csEdtListType = fn_csConvertNameListTypeToEdtListType (p_NameList -> GetType ());
  EdtList* p_NewEdtList = new EdtList (p_NameList , csEdtListType , csName , _bSectionExists);    // Create the EdtList
  
  m_pListOfEdtLists -> AddTail (p_NewEdtList);                            // Add it in the list of EdtLists
  p_NewEdtList -> fn_vSetMotorList (p_vEngineList);                       // Set the engine list

  if (p_NameList -> GetType () != g_c_csWayNameListType)
  {
    ZDX_tdxHandleToZdxList hZdxList     = (ZDX_tdxHandleToZdxList) p_vEngineList;    // The engine zone list
    int                    iNumberOfZDx = p_NameList -> GetCount ();                 // The number of zones
    CPA_DLLBase          * pZdxDll      = M_GetMainApp () -> fn_p_oGetMainWorld () -> GetObjectDLLWithName (C_szDLLZDxName);
    ASSERT (pZdxDll);
    
    // More names that ZDx objects : we must grow up the ZDx list
    if (fn_uwGetNumberOfGeoObjInList (hZdxList) < iNumberOfZDx)
    {
      while (fn_uwGetNumberOfGeoObjInList (hZdxList) < p_NewEdtList -> GetCount ())
        p_NewEdtList -> RemoveTail ();                                                     // Remove one zdx from the editor list
      
      while (fn_uwGetNumberOfGeoObjInList (hZdxList) < iNumberOfZDx)
      {
        p_NewEdtList -> AddObjectInZoneMotorList (fn_uwGetNumberOfGeoObjInList (hZdxList));    // Add one zdx into the engine list
        p_NewEdtList -> AddTail ((CPA_SaveObject *) NULL);                                     // Add one zdx into the editor list
        hZdxList = (ZDX_tdxHandleToZdxList) p_NewEdtList -> fn_hGetMotorList ();
      }
      p_NewEdtList -> fn_vNotifySave ();
    }
    
    POSITION               PosEdtList   = p_NewEdtList -> GetHeadPosition ();
    POSITION               PosNameList  = p_NameList   -> GetHeadPosition ();
    
    for (int i = 0 ; i < iNumberOfZDx ; i++)    // For each engine zone :
    {
      // We get the name in the list of names
      tdoObjectName * pObjectName = p_NameList -> GetNext (PosNameList);
      
      // We get the engine zone
      ACP_tdxHandleOfObject hGeometricObject = ZDX_fn_hGetGeometricZdxInListAtIndex (i , hZdxList);
      CPA_SaveObject      * pZdxObject;
      
      if (hGeometricObject)
      {
        // We search the section name of the zone and it MUST exist
        char * szZoneSectionName = GLI_p_cSearchValueInLinkTableOfGeometric ((unsigned long) hGeometricObject);
        ASSERT (szZoneSectionName);
        
        // We compute the zone name
        char * szFamilyName = p_NameList -> GetOwner () -> fn_p_szGetName ();
        char szZoneName [SCR_CV_ui_Cfg_MaxLenName];
        SCR_fn_v_RdL0_SplitSectionName (szZoneSectionName , NULL , NULL , szZoneName);
        
        // We ask the Zone dll to give us a ZDx object associated to the engine zone
        tdstCreateZoneMess  stCreateZoneMess;
        stCreateZoneMess . csTypeName             = csEdtListType;
        stCreateZoneMess . hEngineZone            = hGeometricObject;
        stCreateZoneMess . pOwner                 = p_NameList -> GetOwner ();    // Owner = the family
        stCreateZoneMess . csName                 = szZoneName;
        stCreateZoneMess . szDataPath             = fn_szGetLevelsDataPath ();
        
        char szSectionName [SCR_CV_ui_Cfg_MaxLenName];
        if (pObjectName -> m_eGetShareMode () == E_sm_Virge)
        {
          fn_zsGetActualLevelFilename (szSectionName , "");        // szSectionName = "GameData\Level\Cave\Cave"
          char * p_cSlash = strrchr (szSectionName , '\\');
          char * p_cPoint = strrchr (szSectionName , '.');
          *p_cPoint = 0;
          sprintf (szSectionName , "%s\\Families\\%s\\%s%s" , p_cSlash+1 , szFamilyName , szFamilyName , (LPCTSTR) g_csZoneListExtension);
          // szSectionName = "Cave\Families\Ed\Ed.zdx"
        }
        else
        {
          sprintf (szSectionName , "_Common\\Families\\%s\\%s%s" , szFamilyName , szFamilyName ,
            (LPCTSTR) g_csZoneListExtension);              // "_Common\Families\Ed\Ed.zdx"
        }
        stCreateZoneMess . csReferenceSectionName = szSectionName;
        
        pZdxObject = (CPA_SaveObject *) pZdxDll -> OnQueryAction (g_pclInterface , C_uiQueryCreateZDxObject , (LPARAM) & stCreateZoneMess);
      }
      else pZdxObject = NULL;
      
      // And we put the editor zone into the object list
      p_NewEdtList -> SetAt   (PosEdtList , pZdxObject);
      p_NewEdtList -> GetNext (PosEdtList);
    }
  }
  
  return p_NewEdtList;
}

/*==========================================================
Function name:	EdtListHandler::fn_ucDeleteEdtList
Description:	Deletes an EdtList
Input:
Output:			return value=	0 list could be deleted
								1 There are other actors using this list
								2 Error: the p_ListMess pointer is null
								3 Error: the pointer to the actor is null
Author:			Yann Le Tensorer
Date:			february 17, 1997
Revision:		february 24, 1997
==========================================================*/
unsigned char EdtListHandler::fn_ucDeleteEdtList(tdstEdtListMess* p_ListMess)
{
	EdActors_EditorActor  *pActor;
	unsigned char		ucOwnerType; // is it a model or instance ?
	unsigned char		RetValue;
	EdtList             *pListToDelete;	// list to delete

	EdtList				*pModelList;	// object list of the model
    EdActors_EditorActor  *pModel;		// model of the actor
	POSITION			pos;


	if (p_ListMess==NULL) return 2;
	if (p_ListMess->pActor==NULL) return 3;

	RetValue=0;

	/* gets the Editor Actor */
	pActor=((CPA_Actor*)p_ListMess->pActor)->m_fn_pclGetEditorActor();

	/* find the type of the actor */
	switch (pActor->m_fn_tdeGetActorType())
	{
		case EDCAR_ACTOR_TYPE_INSTANCE: ucOwnerType=C_ucInstance;	break;
		case EDCAR_ACTOR_TYPE_MODEL:	ucOwnerType=C_ucModele;		break;
		default:						ucOwnerType=C_ucInstance;	break;
	}

	/* find the Model and list of the model of the actor */
    if (ucOwnerType == C_ucInstance)
    {
        pModel = ((CPA_Actor *) (p_ListMess -> pActor)) -> m_fn_pclGetModel () -> m_fn_pclGetEditorActor ();
		ASSERT (pModel);
	    /* find the object list of the model */
		pModelList=pModel->m_fn_p_oGetObjectList(p_ListMess->csListType);
    }

	/* gets the list to delete */
	pListToDelete=pActor->m_fn_p_oGetObjectList(p_ListMess->csListType);

	/* deletes list only if actor is the only one to use this list*/
 if ( pListToDelete->fn_ulGetNumberOfActorsUsingThisList() == 1 )
	{
		/* remove list from list of edtlist */
		pos=m_pListOfEdtLists->Find(pListToDelete);
		if (pos!=NULL) m_pListOfEdtLists->RemoveAt(pos);

		pListToDelete->fn_bMakeActorNotUseThisList(pActor);
        pListToDelete->fn_vNotifyUnSave ();
        pListToDelete->fn_bUnValidate();
        ((CPA_SaveObject *) pListToDelete -> GetOwner ()) -> fn_vUpdateReference (pListToDelete);    // This makes a fn_vNotifySave
		delete (pListToDelete);
	}
	else
		RetValue=1;

	return RetValue;
}

/*==========================================================
Function name:	EdtListHandler::fn_bUserWantsANewList
Description:	Asks to the user if he wants a new list to be created
				or if wants the modifications to be done on all instances
				using the same list.
Input:
Output:			TRUE if he wants a new list
				FALSE if not
Author:			Yann Le Tensorer
Date:			february 20, 1997
Revision:
==========================================================*/
BOOL EdtListHandler::fn_bUserWantsANewList()
{
	int Answer;
	CString text1;
	CString text2;

	text2="Warning! Modifiying a shared field";
	text1="Do you want the modification to be done on all\nactors using this EdtList ?";
	Answer = MessageBox(NULL,(LPCTSTR)text1,(LPCTSTR)text2,MB_YESNO | MB_ICONQUESTION /*| MB_SYSTEMMODAL*/);
	if (Answer==IDYES) return FALSE;
	else return TRUE;
}

/*==========================================================
Function name:	EdtListHandler::fn_vModifyEdtList
Description:	handles the modifications on an EdtList
Input:
Output:
Author:			Yann Le Tensorer
Date:			february 20, 1997
Revision:
==========================================================*/
unsigned char EdtListHandler::fn_ucModifyEdtList(tdstEdtListMess* p_ListMess)
{

	EdActors_EditorActor  *pActor;		// editor actor whom the list belongs.
	unsigned char		ucOwnerType;	// is it a model or instance ?
	unsigned char		RetValue;		// return value of the function
	EdtList             *pListToChange;	// list that changed

	EdtList				*pModelList;	// object list of the model
    EdActors_EditorActor  *pModel;		// model of the actor
	CPA_tdoNameList		*pNameList;		// name list of the actor (or of the model of the actor)

	tdoObjectName		*Name;			// name of the object in the name list
	POSITION			pos;			// position of object in the list to change

	POSITION			posListOfLists; // used when changing all lists
	POSITION			posInCurList;	// used when changing all lists
	EdtList				*CurList;		// used when changing all lists
	CPA_SaveObject	*OldObject;		// old object (to inform editors when changing an object in list )


	if (p_ListMess==NULL) return C_ucNullPointerError;
	if (p_ListMess->pActor==NULL) return C_ucNullPointerError;

	RetValue=0;

	/* gets the Editor Actor */
	pActor=((CPA_Actor*)p_ListMess->pActor)->m_fn_pclGetEditorActor();

	/* find the type of the actor */
	switch (pActor->m_fn_tdeGetActorType())
	{
		case EDCAR_ACTOR_TYPE_INSTANCE: ucOwnerType=C_ucInstance;	break;
		case EDCAR_ACTOR_TYPE_MODEL:	ucOwnerType=C_ucModele;		break;
		default:						ucOwnerType=C_ucInstance;	break;
	}


	/* find the Model and the NameList of the actor */
    if (ucOwnerType == C_ucInstance)
    {
        pModel = ((CPA_Actor *) (p_ListMess -> pActor)) -> m_fn_pclGetModel () -> m_fn_pclGetEditorActor ();
		if (pModel==0) return C_ucActorHasNoModel;
		pNameList=fn_poGetsNameListOfAnActor(pModel,p_ListMess->csListType);
		/* find the object list of the model */
		pModelList=pModel->m_fn_p_oGetObjectList(p_ListMess->csListType);
    }
    else
    {
        pNameList=fn_poGetsNameListOfAnActor(pActor,p_ListMess->csListType);
    }
	if (pNameList==NULL) return C_ucActorHasNoNameList;


	/* gets the list to be changed */
	pListToChange=pActor->m_fn_p_oGetObjectList(p_ListMess->csListType);
    /* say that the list has to be saved */
    pListToChange->fn_vNotifySave ();

	/* gets the name of the object in the name list */
	Name=pNameList->GetAt(pNameList->FindIndex(p_ListMess->ulIndexInList));

	/* gets the position in the list of the object */
	pos	=pListToChange->FindIndex(p_ListMess->ulIndexInList);

	switch (Name->m_eGetShareMode())
	{
		/* if object to be changed is a virge field, no problem, just change it */
		case
			E_sm_Virge:
                OldObject=pListToChange->GetAt(pos);
                pListToChange->SetAt(pos, (CPA_SaveObject *) p_ListMess->pObject);
			    pListToChange->fn_vInformEditorForAllActors
				(
					p_ListMess->ulIndexInList,
					OldObject,
					pActor
				);
			break;

		/* shared field, a bit more complex...*/
		case E_sm_Shared:
			{
				/* if only one actor is using this list just change it */
                if ( pListToChange->fn_ulGetNumberOfActorsUsingThisList() == 1)
				{
                    OldObject = pListToChange -> GetAt (pos);
					pListToChange->SetAt(pos, (CPA_SaveObject *) p_ListMess->pObject);
                    pListToChange -> fn_vInformEditorForAllActors (p_ListMess->ulIndexInList , OldObject , pActor);
				}
				else
                {
				    /* more than one actor is using this list: We ask to the user if he wants to
				    create a new list for this actor or if he wants all actors using this list
				    to be changed */
                    if (p_ListMess->eConstraintType != eModifyAllActors &&
                        p_ListMess->eConstraintType != eModifyOneActor)
                    {
                        p_ListMess->eConstraintType = fn_bUserWantsANewList () ? eModifyOneActor : eModifyAllActors;
                    }
				    if (p_ListMess->eConstraintType == eModifyOneActor)
				    {
					    /* makes the actor not use the old list */
					    pListToChange->fn_bMakeActorNotUseThisList(pActor);
					    /* create a new list */
					    pListToChange=fn_oGetCopyOfEdtList(pListToChange);
					    /* and makes the actor use it*/
					    pListToChange->fn_bMakeActorUseThisList(pActor);
					    /* add the new list in the list of edtlists */
					    m_pListOfEdtLists->AddTail(pListToChange);


					    /* get the position in the new list of the object */
					    pos	=pListToChange->FindIndex(p_ListMess->ulIndexInList);
					    /* and set the object */
					    OldObject		=pListToChange->GetAt(pos);
					    pListToChange->SetAt(pos, (CPA_SaveObject *) p_ListMess->pObject);
					    /* inform editor of all changes on other actors that the one
					    given to me*/
					    pListToChange->fn_vInformEditorForAllActors(
						    p_ListMess->ulIndexInList,
						    OldObject,
						    pActor);
				    }
				    else
				    {
					    /* just change it, so all actors will be affected*/
					    OldObject		=pListToChange->GetAt(pos);
					    pListToChange->SetAt(pos, (CPA_SaveObject *) p_ListMess->pObject);
					    /* inform editor of all changes on other actors that the one
					    given to me*/
					    pListToChange->fn_vInformEditorForAllActors(
						    p_ListMess->ulIndexInList,
						    OldObject,
						    pActor);
				    }
                }
				break;
			}
		/* if object to be changed is a common field, change it for all lists */
		case E_sm_Common:
			{
				posListOfLists=m_pListOfEdtLists->GetHeadPosition();
				while (posListOfLists!=0)
				{
					CurList			=m_pListOfEdtLists->GetNext(posListOfLists);
					posInCurList	=CurList->FindIndex(p_ListMess->ulIndexInList);
					OldObject		=CurList->GetAt(posInCurList);
					CurList->SetAt(posInCurList, (CPA_SaveObject *) p_ListMess->pObject);
					/* inform editor of all changes on other actors that the one
					given to me*/
					CurList->fn_vInformEditorForAllActors(
						p_ListMess->ulIndexInList,
						OldObject,
						pActor);
// ALX
					CurList -> fn_vNotifySave ();
// End ALX
				}
				break;
			}
	}

	return RetValue;
}

/*==========================================================
Function name:	EdtListHandler::fn_csConvertNameListTypeToEdtListType
Description:	convert a name list type to an EdtList type
Author:			Alexis Vaisse
Date:			april 17, 1997
Revision:
==========================================================*/
CString EdtListHandler::fn_csConvertNameListTypeToEdtListType (CString csNameListType)
{
    if (csNameListType == g_c_csZDdNameListType)  return C_szZddName;
    if (csNameListType == g_c_csZDeNameListType)  return C_szZdeName;
    if (csNameListType == g_c_csZDmNameListType)  return C_szZdmName;
    if (csNameListType == g_c_csZDrNameListType)  return C_szZdrName;
    if (csNameListType == g_c_csWayNameListType)  return C_szWayName;

    ASSERT (0);
    return "";
}
