/*=========================================================================
* 
* EDTModif.cpp :  Class Modif* - Implementation file
* 
*
* Version			1.0
* Creation date		
* Revision date
*
* Shaitan
*=======================================================================*/
#include "stdafx.h"

#ifdef ACTIVE_EDITOR
#include "acp_base.h"

#include "ITF.h"

#include "EDTModif.hpp"
#include "EDTBase.hpp"
#include "EDTSObj.hpp"
#include "EDTTemp.hpp"
#include "EDTdedit.hpp"

#define M_GetToolDLLs()		m_pEditor->GetMainWorld()->GetToolDLLReceivingEvtEditorMsg()

inline POS_tdxHandleToPosition M_EDT_AllocMatrix()
{
	POS_tdxHandleToPosition hPos = (POS_tdxHandleToPosition) malloc (sizeof (POS_tdstCompletePosition) );
	POS_fn_vSetIdentityMatrix(hPos);

	return hPos;
}


//#################################################################################
// class ModifInsert 
//#################################################################################

/*===========================================================================
		Constructor
=========================================================================*/
EDT_ModifInsert::EDT_ModifInsert(EDT_HierarchyEditor *pEditor, EDT_SuperObject *pEdObj, 
								 EDT_SuperObject *pParent, tdstPosition *p_stPosition, 
								 EDT_SuperObject *pBrother, BOOL bUpdateDrawing,
								 BOOL bSelect, BOOL pBlock,
								 BOOL bUpdatePosition, BOOL bCutSpecial)// Silviu Simen 18 August 1998 Cut/Paste Mechanism
		: CPA_Modif(TYPE_INSERT, "Insert", pBlock)
{
	ACP_tdxIndex	xInd;

	if (bSelect)
		m_bSelect = 1;
	// init parent editor
	m_pEditor = pEditor;
	m_bFirstTime = TRUE;
	// Init parameters
	m_pParent = pParent;
	m_pBrother = pBrother;
	m_csType = pEdObj->GetRealTypeName();
	m_bUpdate = bUpdateDrawing;
	m_bSelect = bSelect;

// Begin Silviu Simen 18 August 1998 Cut/Paste Mechanism
	m_bCutSpecial = bCutSpecial;

	// save position
  	m_bUpdatePosition = bUpdatePosition;
  	if (bUpdatePosition)
  	{
  		POS_fn_vGetTranslationVector(HIE_fn_hGetSuperObjectGlobalMatrix(pEdObj->GetStruct()), &m_stTranslation);
  		POS_fn_vGetTranslationVector(HIE_fn_hGetSuperObjectMatrix(pEdObj->GetStruct()), &m_stLocale);
  	}
// End Silviu Simen 18 August 1998 Cut/Paste Mechanism
  


	// init save for DLL
	if (p_stPosition)
	{
		for (xInd = 0; xInd < p_stPosition->xIndex; xInd++)
			m_stPosition.a_stPickInfo[xInd] = p_stPosition->a_stPickInfo[xInd];
		m_stPosition.xIndex = p_stPosition->xIndex;
		m_stPosition.stPos = p_stPosition->stPos;
	}
	else
		m_stPosition.xIndex = -1;
	// Create the new object
	m_pInsertedObject = pEdObj; 
	m_stListInsert.RemoveAll();
	fn_vFillListForInsertion(m_pInsertedObject, m_pParent);
}


EDT_ModifInsert::~EDT_ModifInsert (void) 
{ 
	// if insertion was canceled (UNDO), delete object
/*	if (m_pInsertedObject->GetSuperObjectFather() == NULL)
		delete m_pInsertedObject;*/
}


/*===========================================================================
		Interface
=========================================================================*/
CPA_Interface * EDT_ModifInsert::GetInterface (void)
{
	return GetParentEditor()->GetInterface();
}


/*===========================================================================
		Do
=========================================================================*/
BOOL EDT_ModifInsert::Do (void)
{
	EDT_SaveParents		*pElem;
	EDT_SuperObject		*pEdObj;
	POSITION			posElem;

	// world must be valid
	if (!M_HasCurrentWorld())
		return FALSE;

 	// update position
 	if (m_bUpdatePosition)
 	{
 		POS_tdstCompletePosition	*pParentMatrix, *pInstanceMatrix, *pGlobalMatrix;
 		POS_tdstCompletePosition	stMatrix;
 		MTH3D_tdstVector			stTranslation;
 
 		// get position
 		pParentMatrix = HIE_fn_hGetSuperObjectGlobalMatrix(m_pParent->GetStruct());
 		pInstanceMatrix = HIE_fn_hGetSuperObjectMatrix(m_pInsertedObject->GetStruct());
 		pGlobalMatrix = HIE_fn_hGetSuperObjectGlobalMatrix(m_pInsertedObject->GetStruct());
 		// correct position according to pParent's matrix
 		POS_fn_vSetIdentityMatrix(&stMatrix);
 		POS_fn_vInvertMatrix(&stMatrix, pParentMatrix);
 		POS_fn_vMulMatrixVertex(&stTranslation, &stMatrix, &m_stPosition.stPos.stPos3D); 
 		POS_fn_vSetTranslationVector(pInstanceMatrix,&stTranslation);
 		POS_fn_vSetTranslationVector(pGlobalMatrix,&m_stPosition.stPos.stPos3D);
 	}
 	
	
	// insert object in the hierarchy
	m_pInsertedObject->fn_vInsertUnderParent(m_pParent, m_pBrother);
	m_pInsertedObject->fn_vUpdateValidity(TRUE);
	if (m_pInsertedObject->fn_bCanBeNotified())
		m_pParent->fn_vNotifySave();
	// update matrix
	POS_fn_vNormalizeMatrix(HIE_fn_hGetSuperObjectMatrix(m_pInsertedObject->GetStruct()));
	// update the corresponding list
	M_GetWorld()->fn_vUpdateListObjects(m_pInsertedObject, E_lum_Insert);
	// update absolute position
	HIE_fn_vInvalidateAllGlobalMatrices();
	if (m_pParent)
		HIE_fn_vRefreshHierarchy(m_pParent->GetStruct());
//	GetInterface()->fn_vUpdatePositions();
	// if necessary, register as temporary
	for (pElem = m_stListInsert.GetHeadElement(posElem); pElem; 
		 pElem = m_stListInsert.GetNextElement(posElem))
	{
		pEdObj = (EDT_SuperObject *) pElem->m_pChild;
		// temporary modif
		pEdObj->fn_bInitTemporarySO();
		pEdObj->fn_vUpdateTemporaryModif(C_szCreation, TRUE);
		// check notify
		pEdObj->fn_vNotifySave();
	}

// Begin Silviu Simen 01 september 1998 List of Objects in Sectors
	if (GetInterface()->GetSpecificInterface()->fn_bHasValidWorld())
	{
		MTH3D_tdstVector	stObjectPosition;
		CPA_SuperObject * pSector;

		stObjectPosition = HIE_fn_hGetSuperObjectMatrix  (m_pInsertedObject->GetStruct()) -> 
							stTranslationVector;
		pSector = GetInterface()->GetSpecificInterface()->
							GetCurrentSectorFromPos(&stObjectPosition);
		M_GetMainWorld()->m_stListObjectsInSectors.AddElement(m_pInsertedObject,pSector);
	}
// End Silviu Simen 01 september 1998 List of Objects in Sectors
	
	// tell DLLs
	if (m_stPosition.xIndex != -1)
		fn_vSendMessageInsert((m_bFirstTime) ? C_EDTDo : C_EDTRedo, &m_stPosition);
	else
		fn_vSendMessageInsert((m_bFirstTime) ? C_EDTDo : C_EDTRedo, NULL);
	// update current selection
	if (m_bSelect)
	{
		GetInterface()->fn_vCancelCurrentSelection(FALSE);
		GetInterface()->fn_vAddSelectedObject(m_pInsertedObject, FALSE);
		// update type
		if (M_GetSelectMode() != "All Types")
			GetInterface()->SetSelectMode(m_pInsertedObject->GetRealTypeName());
	}
	// update all 
	if (m_bUpdate)
	{
		GetInterface()->fn_vUpdateAll(E_mc_UpdateDialog);
		if (!m_bFirstTime)
			M_GetMainWnd()->UpdateStatus("Insertion Done", C_STATUSPANE_INFOS, C_STATUS_NORMAL);
	}
	m_bFirstTime = FALSE;
	return TRUE;
}

/*===========================================================================
		Undo
=========================================================================*/
BOOL EDT_ModifInsert::Undo (void)
{
	EDT_SaveParents		*pElem;
	EDT_SuperObject		*pEdObj;
	POSITION			posElem;

	// world must be valid
	if (!M_HasCurrentWorld())
		return FALSE;

// Begin Silviu Simen 18 August 1998 Cut/Paste Mechanism
	if (m_bCutSpecial) // we have removed a special object... 
	{
		GetParentEditor()->SetRegisteredCuttedObject(m_pInsertedObject);
		GetParentEditor()->SetSpecialObject(TRUE);
	}
// End Silviu Simen 18 August 1998 Cut/Paste Mechanism

 	// update position
 	if (m_bUpdatePosition)
 	{
 		// restore position
 		POS_fn_vSetTranslationVector(HIE_fn_hGetSuperObjectMatrix(m_pInsertedObject->GetStruct()),&m_stLocale);
 		POS_fn_vSetTranslationVector(HIE_fn_hGetSuperObjectGlobalMatrix(m_pInsertedObject->GetStruct()),&m_stTranslation);
 	}
 

	// update current selection
	GetInterface()->fn_vCancelCurrentSelection(FALSE);
	// delete object in the hierarchy
	m_pInsertedObject->IsolateChild();
	m_pInsertedObject->fn_vUpdateValidity(FALSE);
	// update the corresponding lists
	M_GetWorld()->fn_vUpdateListObjects(m_pInsertedObject, E_lum_Delete);

	// cancel temporary modif
	for (pElem = m_stListInsert.GetHeadElement(posElem); pElem; 
		 pElem = m_stListInsert.GetNextElement(posElem))
	{
		pEdObj = (EDT_SuperObject *) pElem->m_pChild;
		pEdObj->fn_vUpdateTemporaryModif(C_szCreation, FALSE);
		// check notify
		pEdObj->fn_vNotifyUnSave();
	}

	// tell DLLs
	if (m_stPosition.xIndex != -1)
		fn_vSendMessageInsert(C_EDTUndo, &m_stPosition);
	else
		fn_vSendMessageInsert(C_EDTUndo, NULL);
	// update all but select mode
	if (m_bUpdate)
	{
		GetInterface()->fn_vUpdateAll(E_mc_UpdateDialog);
		M_GetMainWnd()->UpdateStatus("Insertion Undone", C_STATUSPANE_INFOS, C_STATUS_NORMAL);
	}
// Begin Silviu Simen 01 september 1998 List of Objects in Sectors
	if (GetInterface()->GetSpecificInterface()->fn_bHasValidWorld())
	{
		M_GetMainWorld()->m_stListObjectsInSectors.RemoveElement(m_pInsertedObject);
	}
// End Silviu Simen 01 september 1998 List of Objects in Sectors
	return TRUE;
}


/*===========================================================================
		fill List for DLLs
=========================================================================*/
void EDT_ModifInsert::fn_vFillListForInsertion (EDT_SuperObject *pEdObj, EDT_SuperObject *pParent)
{
	EDT_SaveParents  *pNewElem;
	EDT_SuperObject  *pEdChild;
	
	// create and save elem
	pNewElem = new EDT_SaveParents(pEdObj, NULL, pParent);
	m_stListInsert.AddTail(pNewElem);
	// for each child
	pEdChild = (EDT_SuperObject *) pEdObj->GetSuperObjectFirstChild();
	while (pEdChild)
	{
		fn_vFillListForInsertion(pEdChild, pEdObj);
		pEdChild = (EDT_SuperObject *) pEdObj->GetSuperObjectNextChild(pEdChild);
	}
}


/*===========================================================================
		Message
=========================================================================*/
void EDT_ModifInsert::fn_vSendMessageInsert (tdeTypeModif eType, tdstPosition *pPosition)
{
	CPA_ObjectDLLBase	*pDLLObject;
	CPA_ToolDLLBase		*pDLLTool;
	EDT_SuperObject		*pInsertedObject, *pParent;
	EDT_SaveParents		*pElem;
	POSITION			pos, posElem;
		
	for (pElem = m_stListInsert.GetHeadElement(posElem); pElem; 
		 pElem = m_stListInsert.GetNextElement(posElem))
	{
		pInsertedObject = (EDT_SuperObject *) pElem->m_pChild;
		pParent = (EDT_SuperObject *) pElem->m_pFinalParent;
		
		// Current Editor
		if (!M_IsCurrentEditor())
			M_GetCurrentEditor()->fn_vOnModifInsert(pInsertedObject, pParent, pPosition, eType, C_AsCurrentEditor);
		//  corresponding DLL
		if (pInsertedObject->GetObjectDLL())
			pInsertedObject->GetObjectDLL()->fn_vOnModifInsert(pInsertedObject, pParent, pPosition, eType, C_AsConcernedDLL);
		// if necessary, owner DLL
		if (pInsertedObject->GetSuperObjectOwner())
		{
			pDLLObject = pInsertedObject->GetSuperObjectOwner()->GetObjectDLL();
			pDLLObject->fn_vOnModifInsert(pInsertedObject, pParent, pPosition, eType, C_AsChildOwner);
		}
		// Tool DLLs
		for (pDLLTool = M_GetToolDLLs()->GetHeadElement(pos); pDLLTool;
			 pDLLTool = M_GetToolDLLs()->GetNextElement(pos))
		{
			if (pDLLTool != M_GetCurrentEditor())
				pDLLTool->fn_vOnModifInsert(pInsertedObject, pParent, pPosition, eType, C_AsToolDLL);
		}
	}
}



//#################################################################################
// class ModifDelete
//#################################################################################

/*===========================================================================
		Constructor
=========================================================================*/
EDT_ModifDelete::EDT_ModifDelete (EDT_HierarchyEditor *pEditor, CPA_List<EDT_ListByDLL> *pSelectByType, 
								  CString csType, BOOL bUpdateDrawing, BOOL bDestroy,
								  BOOL bSelect, BOOL pBlock, BOOL bCutSpecial) 
		: CPA_Modif(TYPE_DELETE, "Delete", pBlock)
{
	EDT_ListByDLL	 *pListSelect;
	EDT_ParentByType *pNewList;
	EDT_SaveParents	 *pNewElem;
	EDT_SuperObject  *pEdObj;
	EDT_SuperObject  *pParent;
	CPA_SuperObject  *pSupObj;
	POSITION		 pos, pos1;

// Begin Silviu Simen 18 August 1998 Cut/Paste Mechanism
	m_bCutSpecial = bCutSpecial;
// End Silviu Simen 18 August 1998 Cut/Paste Mechanism
	
	// init parent editor
	m_pEditor = pEditor;
	m_bFirstTime = TRUE;
	m_bUpdate = bUpdateDrawing;
	m_bDestroy = bDestroy;
	m_bSelect = bSelect;
	// init the lists
	m_stListObjects.RemoveAll();
	// fill the lists for DLLs
	for (pListSelect = pSelectByType->GetHeadElement(pos); pListSelect;
		 pListSelect = pSelectByType->GetNextElement(pos))
	{
		// save only if there are elements
		if ((pListSelect->m_stListConcerned.GetCount())
		  ||(pListSelect->m_stListProtectSelected.GetCount()))
		{
			// create the corresponding list
			pNewList = new EDT_ParentByType(pListSelect->GetDLL());
			if (pListSelect->GetDLL())
				m_lstModifByType.AddTail(pNewList);
			// copy the list of objects
			for (pSupObj = pListSelect->m_stListConcerned.GetHeadElement(pos1); pSupObj;
				 pSupObj = pListSelect->m_stListConcerned.GetNextElement(pos1))
			{
				pEdObj = (EDT_SuperObject *) pSupObj;
				pParent = (EDT_SuperObject *) pEdObj->GetSuperObjectFather();
				// if this is a top object, add it to the list
				if (pListSelect->m_stListSelected.Find(pEdObj, NULL) != NULL)
				{
					pNewElem = new EDT_SaveParents(pEdObj, pParent, NULL);
					m_stListObjects.AddTail(pNewElem);
				}
				// else only DLLs need this info
				else
					pNewElem = new EDT_SaveParents(pEdObj, pParent, pParent);
				// add it to DLL list
				pNewList->m_stListObjects.AddTail(pNewElem);
				m_stListForTools.AddTail(pNewElem);
			}
			// copy the list of protected childs
			for (pSupObj = pListSelect->m_stListProtectSelected.GetHeadElement(pos1); pSupObj;
				 pSupObj = pListSelect->m_stListProtectSelected.GetNextElement(pos1))
			{
				pEdObj = (EDT_SuperObject *) pSupObj;
				// find new parent
				pNewElem = new EDT_SaveParents(pEdObj, (EDT_SuperObject *) pEdObj->GetSuperObjectFather(), NULL);
				// add it to DLL list
				pNewList->m_stListProtected.AddTail(pNewElem);
			}
		}
	}
	// init parameters
	m_csType = csType;
	m_bDeleted = FALSE;
}

/*===========================================================================
		Constructor
=========================================================================*/
EDT_ModifDelete::EDT_ModifDelete (EDT_HierarchyEditor *pEditor, EDT_SuperObject *pObjectToDelete,
								  CString csType, BOOL bUpdateDrawing, BOOL bDestroy,
								  BOOL bSelect, BOOL pBlock, BOOL bCutSpecial) 
		: CPA_Modif(TYPE_DELETE, "Delete", pBlock)
{
	EDT_ParentByType *pNewList;
	EDT_SaveParents	 *pNewElem;
	EDT_SuperObject  *pParent;

// Begin Silviu Simen 18 August 1998 Cut/Paste Mechanism
	m_bCutSpecial = bCutSpecial;
// End Silviu Simen 18 August 1998 Cut/Paste Mechanism

	// init parent editor
	m_pEditor = pEditor;
	m_bFirstTime = TRUE;
	m_bUpdate = bUpdateDrawing;
	m_bDestroy = bDestroy;
	m_bSelect = bSelect;
	// init the lists
	m_stListObjects.RemoveAll();
	// fill the lists for DLLs
	pNewList = new EDT_ParentByType(pObjectToDelete->GetObjectDLL());
	if (pObjectToDelete->GetObjectDLL())
		m_lstModifByType.AddTail(pNewList);
	// copy object
	pParent = (EDT_SuperObject *) pObjectToDelete->GetSuperObjectFather();
	pNewElem = new EDT_SaveParents(pObjectToDelete, pParent, NULL);
	m_stListObjects.AddTail(pNewElem);
	// add it to DLL list
	pNewList->m_stListObjects.AddTail(pNewElem);
	m_stListForTools.AddTail(pNewElem);
	// protected objet ?
	if (pObjectToDelete->GetSuperObjectOwner())
	{
		// find new parent
		pNewElem = new EDT_SaveParents(pObjectToDelete, (EDT_SuperObject *) pObjectToDelete->GetSuperObjectFather(), NULL);
		// add it to DLL list
		pNewList->m_stListProtected.AddTail(pNewElem);
	}
	// fill list for DLLs
	fn_vFillListForDLLs(pObjectToDelete);
	// init parameters
	m_csType = csType;
	m_bDeleted = FALSE;
}


/*===========================================================================
		Destructor
=========================================================================*/
EDT_ModifDelete::~EDT_ModifDelete (void)
{
//	CPA_SuperObject	 *pEdObj;
//	EDT_SaveParents	 *pElem;
//	POSITION		 pos;
	
	// if objects were removed from hierarchy (DONE), delete them
/*
	if ((m_bDeleted)&&(m_bDestroy))
	{
		for (pElem = m_stListObjects.GetHeadElement(pos); pElem;
			 pElem = m_stListObjects.GetNextElement(pos))
		{
			// delete only if object is not temporary
			pEdObj = pElem->m_pChild;
			if (!m_pEditor->GetListOfTemporarySO()->Find(pEdObj))
				delete pEdObj;
		}
	}
*/	m_stListObjects.RemoveAll();

	// free the ModifList
	while (m_lstModifByType.GetCount() > 0)
		delete m_lstModifByType.RemoveTail();
}


/*===========================================================================
		Interface
=========================================================================*/
CPA_Interface * EDT_ModifDelete::GetInterface (void)
{
	return GetParentEditor()->GetInterface();
}

/*===========================================================================
		Do
=========================================================================*/
BOOL EDT_ModifDelete::Do (void)
{
	EDT_SaveParents  *pElem;
	EDT_SuperObject  *pEdObj;
	POSITION		 pos;
	
	// world must be valid
	if (!M_HasCurrentWorld())
		return FALSE;

	// if necessary, register temporary modif
	for (pElem = m_stListForTools.GetHeadElement(pos); pElem; 
		 pElem = m_stListForTools.GetNextElement(pos))
	{
		pEdObj = (EDT_SuperObject *) pElem->m_pChild;
		// check modif
		pEdObj->fn_bInitTemporarySO();
		pEdObj->fn_vUpdateTemporaryModif(C_szSuppression, TRUE);
		// temporary SO => keep section in file
		if (!pEdObj->fn_bIsTemporary())
			pEdObj->fn_vNotifyUnSave();
	}
	
//ANNECY Shaitan Correction 20/02/98
//	// cancel current selection
//	GetInterface()->fn_vCancelCurrentSelection(FALSE);
//ENDANNECY Shaitan Correction
	// delete all objects in the list
	for (pElem = m_stListObjects.GetHeadElement(pos); pElem; 
		 pElem = m_stListObjects.GetNextElement(pos))
	{
		pEdObj = (EDT_SuperObject *) pElem->m_pChild;
//ANNECY Shaitan Correction 20/02/98
		// update selection
		if (M_GetWorld()->GetListSelected()->Find(pEdObj))
			GetInterface()->fn_vRemoveSelectedObject(pEdObj, FALSE);
//ENDANNECY Shaitan Correction

		// delete object in the hierarchy
		pEdObj->IsolateChild();
		pEdObj->fn_vUpdateValidity(FALSE);
		if (pEdObj->fn_bCanBeNotified())
			pElem->m_pInitialParent->fn_vNotifySave();
		// update the corresponding lists
		M_GetWorld()->fn_vUpdateListObjects(pEdObj, E_lum_Delete);
		// update current selection
		GetInterface()->fn_vSetLocalColor(pEdObj, E_lm_ShowNormal);
// Begin Silviu Simen 01 september 1998 List of Objects in Sectors
		if (GetInterface()->GetSpecificInterface()->fn_bHasValidWorld())
		{
			M_GetMainWorld()->m_stListObjectsInSectors.RemoveElement(pEdObj);
		}
// End Silviu Simen 01 september 1998 List of Objects in Sectors
	}
	
	// tell DLLs
	fn_vSendMessageDelete((m_bFirstTime) ? C_EDTDo : C_EDTRedo) ;
	// update all 
	if (m_bUpdate)
	{
		GetInterface()->fn_vUpdateAll(E_mc_UpdateDialog);
		if (!m_bFirstTime)
			M_GetMainWnd()->UpdateStatus("Suppression Done", C_STATUSPANE_INFOS, C_STATUS_NORMAL);
	}
	// Objects were deleted
	m_bDeleted = TRUE;
	m_bFirstTime = FALSE;
	return TRUE;
}


/*===========================================================================
		Undo
=========================================================================*/
BOOL EDT_ModifDelete::Undo (void)
{
	EDT_SaveParents  *pElem;
	EDT_SuperObject  *pEdObj, *pParent;
	POSITION		 pos;
	
	// world must be valid
	if (!M_HasCurrentWorld())
		return FALSE;

// Begin Silviu Simen 18 August 1998 Cut/Paste Mechanism
	if (m_bCutSpecial) // we have inserted special object... 
	{
		GetParentEditor()->SetRegisteredCuttedObject(NULL);
		GetParentEditor()->SetSpecialObject(TRUE);
	}
// End Silviu Simen 18 August 1998 Cut/Paste Mechanism

	// cancel current selection
	if (m_bSelect)
		GetInterface()->fn_vCancelCurrentSelection(FALSE);
	// delete all objects in the list
	for (pElem = m_stListObjects.GetHeadElement(pos); pElem; 
		 pElem = m_stListObjects.GetNextElement(pos))
	{
		pEdObj = (EDT_SuperObject *) pElem->m_pChild;
		pParent = (EDT_SuperObject *) pElem->m_pInitialParent;
		// re-insert the object in the hierarchy
		pEdObj->fn_vInsertUnderParent(pParent);
		pEdObj->fn_vUpdateValidity(TRUE);
		// update the corresponding lists
// Begin Silviu Simen 01 september 1998 List of Objects in Sectors
		if (GetInterface()->GetSpecificInterface()->fn_bHasValidWorld())
		{
			MTH3D_tdstVector	stObjectPosition;
			CPA_SuperObject * pSector;

			stObjectPosition = HIE_fn_hGetSuperObjectMatrix  (pEdObj->GetStruct()) -> 
								stTranslationVector;
			pSector = GetInterface()->GetSpecificInterface()->
								GetCurrentSectorFromPos(&stObjectPosition);
			M_GetMainWorld()->m_stListObjectsInSectors.AddElement(pEdObj,pSector);
		}
// End Silviu Simen 01 september 1998 List of Objects in Sectors
		M_GetWorld()->fn_vUpdateListObjects(pEdObj, E_lum_ReInsert);
	}

	// if necessary, register temporary modif
	for (pElem = m_stListForTools.GetHeadElement(pos); pElem; 
		 pElem = m_stListForTools.GetNextElement(pos))
	{
		pEdObj = (EDT_SuperObject *) pElem->m_pChild;
		// temporary SO => section was not removed
		if (!pEdObj->fn_bIsTemporary())
			pEdObj->fn_vNotifyRestore();
		// update temporary modif
		pEdObj->fn_vUpdateTemporaryModif(C_szSuppression, FALSE);
	}
	
	// update select type
	if ((m_bSelect)&&(M_GetSelectMode() != "All Types"))
		GetInterface()->SetSelectMode(m_csType);
	// delete was canceled
	m_bDeleted = FALSE;

	// tell DLLs
	GetInterface()->fn_vUpdatePositions();
	fn_vSendMessageDelete(C_EDTUndo);
	// update current selection
	if (m_bSelect)
	{
		for (pElem = m_stListObjects.GetHeadElement(pos); pElem;
			 pElem = m_stListObjects.GetNextElement(pos))
			GetInterface()->fn_vAddSelectedObject(pElem->m_pChild, FALSE);
	}
	// update all
	if (m_bUpdate)
	{
		GetInterface()->fn_vUpdateAll(E_mc_UpdateDialog);
		M_GetMainWnd()->UpdateStatus("Suppression Undone", C_STATUSPANE_INFOS, C_STATUS_NORMAL);
	}
	return TRUE;
}


/*===========================================================================
		Message
=========================================================================*/
void EDT_ModifDelete::fn_vSendMessageDelete (tdeTypeModif eType)
{
	CPA_ToolDLLBase	 *pDLLTool;
	EDT_ParentByType *pList;
	POSITION		 pos;
	
	// current editor
	if (!M_IsCurrentEditor())
		M_GetCurrentEditor()->fn_vOnModifDelete(&m_stListForTools, eType, C_AsCurrentEditor);
	// corresponding DLLs
	for (pList = m_lstModifByType.GetHeadElement(pos); pList;
		 pList = m_lstModifByType.GetNextElement(pos))
	{
		if (pList->m_stListObjects.GetCount())
			pList->m_poDLL->fn_vOnModifDelete(&pList->m_stListObjects, eType, C_AsConcernedDLL);
	}
	// owner DLLs
	for (pList = m_lstModifByType.GetHeadElement(pos); pList;
		 pList = m_lstModifByType.GetNextElement(pos))
	{
		if (pList->m_stListProtected.GetCount())
			pList->m_poDLL->fn_vOnModifDelete(&pList->m_stListProtected, eType, C_AsChildOwner);
	}
	// Tool DLLs
	for (pDLLTool = M_GetToolDLLs()->GetHeadElement(pos); pDLLTool;
		 pDLLTool = M_GetToolDLLs()->GetNextElement(pos))
	{
		if (pDLLTool != M_GetCurrentEditor())
			pDLLTool->fn_vOnModifDelete(&m_stListForTools, eType, C_AsToolDLL);
	}
}


/*===========================================================================
		Find corresponding list
=========================================================================*/
EDT_ParentByType * EDT_ModifDelete::fn_pstFindParentListFromObj (EDT_SuperObject *pEdObj)
{
	CPA_ObjectDLLBase *p_oDLL;
	EDT_ParentByType  *pList;
	POSITION		  pos;
	
	// find object DLL
	p_oDLL = pEdObj->GetObjectDLL();
	if (!p_oDLL)
		return NULL;
	
	// find the corresponding list
	for (pList = m_lstModifByType.GetHeadElement(pos); pList;
	 	 pList = m_lstModifByType.GetNextElement(pos))
	{
		if (pList->m_poDLL == p_oDLL)
			return pList;
	}
	
	// List was not found -> create it
	pList = new EDT_ParentByType(p_oDLL);
	m_lstModifByType.AddTail(pList);
	return pList;
}

/*===========================================================================
		fill List for DLLs
=========================================================================*/
void EDT_ModifDelete::fn_vFillListForDLLs (EDT_SuperObject *pEdObj)
{
	EDT_ParentByType *pList;
	EDT_SaveParents  *pNewElem;
	EDT_SuperObject  *pEdChild;
	
	// for each child
	pEdChild = (EDT_SuperObject *) pEdObj->GetSuperObjectFirstChild();
	while (pEdChild)
	{
		pNewElem = new EDT_SaveParents(pEdChild, pEdObj, pEdObj);
		// find corresponding list
		pList = fn_pstFindParentListFromObj(pEdChild);
		// add new elem
		if (pList)
			pList->m_stListObjects.AddTail(pNewElem);
		m_stListForTools.AddTail(pNewElem);
		// next level of the hierarchy
		fn_vFillListForDLLs(pEdChild);
		// next brother
		pEdChild = (EDT_SuperObject *) pEdObj->GetSuperObjectNextChild(pEdChild);
	}
}





//#################################################################################
// Class ModifPaste
//#################################################################################

	

/*===========================================================================
		Constructor
=========================================================================*/
EDT_ModifPaste::EDT_ModifPaste (EDT_HierarchyEditor *pEditor, CPA_List<EDT_SaveParents> *pListObjects, 
								CString csType, long lNbCopy, BOOL bUpdateDrawing) 
		: CPA_Modif(TYPE_PASTE, "Paste", FALSE)
{
	EDT_ParentByType *pNewList;
	EDT_SaveParents  *pSaveParent, *pNewSaveParent;
	EDT_SuperObject  *pElem, *pNewElem, *pParent, *pInitParent;
	POSITION		 pos;
	
	// init parent editor
	m_pEditor = pEditor;
	m_bFirstTime = TRUE;
	m_bUpdate = bUpdateDrawing;
	// init the lists
	m_stListObjects.RemoveAll();

	// fill the list of objects to paste
	for (pSaveParent = pListObjects->GetHeadElement(pos); pSaveParent; 
		 pSaveParent = pListObjects->GetNextElement(pos))
	{
		// find new object and parent
		pElem = (EDT_SuperObject *) pSaveParent->m_pChild;
		pInitParent = (EDT_SuperObject *) pSaveParent->m_pInitialParent;
		pParent = (EDT_SuperObject *) pSaveParent->m_pFinalParent;
		// create new elem
		pNewElem = m_pEditor->GetACopy(pElem, FALSE, FALSE);
		// add element in the list
		pNewSaveParent = new EDT_SaveParents(pNewElem, pInitParent, pParent);
		m_stListObjects.AddTail(pNewSaveParent);
		// update the lists for DLLs
		pNewList = fn_pstFindParentListFromObj(pNewElem);
		pNewList->m_stListObjects.AddTail(pNewSaveParent);
		m_stListForTools.AddTail(pNewSaveParent);
		fn_vFillListForDLLs(pNewElem);
		// if necessary, update list for protected
		if (pNewElem->GetSuperObjectOwner())
		{
			pNewSaveParent = new EDT_SaveParents(pNewElem, pParent, NULL);
			pNewList = fn_pstFindParentListFromObj((EDT_SuperObject *) pNewElem->GetSuperObjectOwner());
			pNewList->m_stListProtected.AddTail(pNewSaveParent);
		}
	}
	m_csType = csType;
	m_bDone = FALSE;
}


/*===========================================================================
		Destructor
=========================================================================*/
EDT_ModifPaste::~EDT_ModifPaste (void)
{
//	EDT_SaveParents *pElem;
//	POSITION		pos;

	// if modif was canceled (UNDONE), delete objects
/*	if (!m_bDone)
	{
		for (pElem = m_stListObjects.GetHeadElement(pos); pElem;
			 pElem = m_stListObjects.GetNextElement(pos))
			delete pElem->m_pChild;
	}
*/	m_stListObjects.RemoveAll();

	// free the ModifList
	while (m_lstModifByType.GetCount() > 0)
		delete m_lstModifByType.RemoveTail();


}


/*===========================================================================
		Interface
=========================================================================*/
CPA_Interface * EDT_ModifPaste::GetInterface (void)
{
	return GetParentEditor()->GetInterface();
}


/*===========================================================================
		Do
=========================================================================*/
BOOL EDT_ModifPaste::Do (void)
{
	EDT_SaveParents  *pElem;
	EDT_SuperObject  *pEdObj, *pParent;
	POSITION		 pos;
	
	// world must be valid
	if (!M_HasCurrentWorld())
		return FALSE;

	// cancel current selection
	GetInterface()->fn_vCancelCurrentSelection(FALSE);
	// paste all objects in the list
	for (pElem = m_stListObjects.GetHeadElement(pos); pElem; 
		 pElem = m_stListObjects.GetNextElement(pos))
	{
		pEdObj = (EDT_SuperObject *) pElem->m_pChild;
		pParent = (EDT_SuperObject *) pElem->m_pFinalParent;
		// re-insert the object in the hierarchy
		pEdObj->fn_vInsertUnderParent(pParent, NULL, TRUE);
		pEdObj->fn_vUpdateValidity(TRUE);
		if (pEdObj->fn_bCanBeNotified())
			pParent->fn_vNotifySave();
		// update the corresponding lists
// Begin Silviu Simen 01 september 1998 List of Objects in Sectors
		if (GetInterface()->GetSpecificInterface()->fn_bHasValidWorld())
		{
			MTH3D_tdstVector	stObjectPosition;
			CPA_SuperObject * pSector;

			stObjectPosition = HIE_fn_hGetSuperObjectMatrix  (pEdObj->GetStruct()) -> 
								stTranslationVector;
			pSector = GetInterface()->GetSpecificInterface()->
								GetCurrentSectorFromPos(&stObjectPosition);
			M_GetMainWorld()->m_stListObjectsInSectors.AddElement(pEdObj,pSector);
		}
// End Silviu Simen 01 september 1998 List of Objects in Sectors
		M_GetWorld()->fn_vUpdateListObjects(pEdObj, E_lum_Insert);
	}
	
	// update matrices
	GetInterface()->fn_vUpdatePositions();
		 
	// if necessary, register temporary modif
	for (pElem = m_stListForTools.GetHeadElement(pos); pElem; 
		 pElem = m_stListForTools.GetNextElement(pos))
	{
		// check modif
		pEdObj = (EDT_SuperObject *) pElem->m_pChild;
		//CPA2 Stegaru Cristian 98-03
		if (E_ss_Responsible == pEdObj->GetSaveStatus ())
		pEdObj->SetSaveStatus (E_ss_Modify);
		
		if (E_ss_Modify == pEdObj->GetSaveStatus ())
		{
			pEdObj->fn_bInitTemporarySO();
			EDT_TempModif *pTempModif = pEdObj->GetTemporaryModif ();
			ASSERT (pTempModif);
			pTempModif->mfn_vSetInitialSPOName (pEdObj->mfn_csGetInitialSPOName ());
			pEdObj->fn_vUpdateTemporaryModif(C_szCreation, TRUE);
		}
		//End CPA2 Stegaru Cristian 98-03
		// update notify
		pEdObj->fn_vNotifySave();
	}
	
		 
	// update select type
	if (M_GetSelectMode() != "All Types")
		GetInterface()->SetSelectMode(m_csType);
	
	// tell DLLs
	fn_vSendMessageCopy((m_bFirstTime) ? C_EDTDo : C_EDTRedo);

	m_bFirstTime = FALSE;
	// update current selection
	for (pElem = m_stListObjects.GetHeadElement(pos); pElem;
		 pElem = m_stListObjects.GetNextElement(pos))
		GetInterface()->fn_vAddSelectedObject(pElem->m_pChild, FALSE);
	// update all 
	if (m_bUpdate)
	{
		GetInterface()->fn_vUpdateAll(E_mc_UpdateDialog);
		if (!m_bFirstTime)
			M_GetMainWnd()->UpdateStatus("Paste Done", C_STATUSPANE_INFOS, C_STATUS_NORMAL);
	}
	m_bDone = TRUE;
	return TRUE;
}


/*===========================================================================
		Undo
=========================================================================*/
BOOL EDT_ModifPaste::Undo (void)
{
	EDT_SaveParents  *pElem;
	EDT_SuperObject  *pEdObj;
	POSITION		 pos;
	
	// world must be valid
	if (!M_HasCurrentWorld())
		return FALSE;

	GetInterface()->fn_vCancelCurrentSelection(FALSE);
	// delete all objects in the list
	for (pElem = m_stListObjects.GetHeadElement(pos); pElem; 
		 pElem = m_stListObjects.GetNextElement(pos))
	{
		pEdObj = (EDT_SuperObject *) pElem->m_pChild;
		// delete object in the hierarchy
		pEdObj->IsolateChild();
		pEdObj->fn_vUpdateValidity(FALSE);
		// update the corresponding lists
// Begin Silviu Simen 01 september 1998 List of Objects in Sectors
		if (GetInterface()->GetSpecificInterface()->fn_bHasValidWorld())
		{
			M_GetMainWorld()->m_stListObjectsInSectors.RemoveElement(pEdObj);
		}
// End Silviu Simen 01 september 1998 List of Objects in Sectors
		M_GetWorld()->fn_vUpdateListObjects(pEdObj, E_lum_Delete);
		// update current selection
		GetInterface()->fn_vSetLocalColor(pEdObj, E_lm_ShowNormal);
	}

	// if necessary, register temporary modif
	for (pElem = m_stListForTools.GetHeadElement(pos); pElem; 
		 pElem = m_stListForTools.GetNextElement(pos))
	{
		pEdObj = (EDT_SuperObject *) pElem->m_pChild;
		pEdObj->fn_vUpdateTemporaryModif(C_szCreation, FALSE);
		// update notify
		pEdObj->fn_vNotifyUnSave();
	}

	// update all but select mode
	if (m_bUpdate)
	{
		GetInterface()->fn_vUpdateAll(E_mc_UpdateDialog);
		M_GetMainWnd()->UpdateStatus("Paste Undone", C_STATUSPANE_INFOS, C_STATUS_NORMAL);
	}

	// tell DLLs
	fn_vSendMessageCopy(C_EDTUndo);

	m_bDone = FALSE;
	return TRUE;
}



/*===========================================================================
		Find corresponding list
=========================================================================*/
EDT_ParentByType * EDT_ModifPaste::fn_pstFindParentListFromObj (EDT_SuperObject *pEdObj)
{
	CPA_ObjectDLLBase *p_oDLL;
	EDT_ParentByType  *pList;
	POSITION		  pos;
	
	// find object DLL
	p_oDLL = pEdObj->GetObjectDLL();
	if (!p_oDLL)
		return NULL;
	
	// find the corresponding list
	for (pList = m_lstModifByType.GetHeadElement(pos); pList;
	 	 pList = m_lstModifByType.GetNextElement(pos))
	{
		if (pList->m_poDLL == p_oDLL)
			return pList;
	}
	
	// List was not found -> create it
	pList = new EDT_ParentByType(p_oDLL);
	m_lstModifByType.AddTail(pList);
	return pList;
}

/*===========================================================================
		fill List for DLLs
=========================================================================*/
void EDT_ModifPaste::fn_vFillListForDLLs (EDT_SuperObject *pEdObj)
{
	EDT_ParentByType *pList;
	EDT_SaveParents  *pNewElem;
	EDT_SuperObject  *pEdChild;
	
	// for each child
	pEdChild = (EDT_SuperObject *) pEdObj->GetSuperObjectFirstChild();
	while (pEdChild)
	{
		pNewElem = new EDT_SaveParents(pEdChild, pEdObj, pEdObj);
		// find corresponding list
		pList = fn_pstFindParentListFromObj(pEdChild);
		// add new elem
		if (pList)
			pList->m_stListObjects.AddTail(pNewElem);
		m_stListForTools.AddTail(pNewElem);
		// next level of the hierarchy
		fn_vFillListForDLLs(pEdChild);
		// next brother
		pEdChild = (EDT_SuperObject *) pEdObj->GetSuperObjectNextChild(pEdChild);
	}
}



/*===========================================================================
		Message
=========================================================================*/
void EDT_ModifPaste::fn_vSendMessageCopy (tdeTypeModif eType)
{
	CPA_ToolDLLBase	 *pDLLTool;
	EDT_ParentByType *pList;
	POSITION		 pos;

	// current editor
	if (!M_IsCurrentEditor())
		M_GetCurrentEditor()->fn_vOnModifCopy(&m_stListForTools, eType, C_AsCurrentEditor);
	// corresponding DLLs
	for (pList = m_lstModifByType.GetHeadElement(pos); pList;
		 pList = m_lstModifByType.GetNextElement(pos))
	{
		if (pList->m_stListObjects.GetCount())
			pList->m_poDLL->fn_vOnModifCopy(&pList->m_stListObjects, eType, C_AsConcernedDLL);
	}
	// owner DLLs
	for (pList = m_lstModifByType.GetHeadElement(pos); pList;
		 pList = m_lstModifByType.GetNextElement(pos))
	{
		if (pList->m_stListProtected.GetCount())
			pList->m_poDLL->fn_vOnModifCopy(&pList->m_stListProtected, eType, C_AsChildOwner);
	}
	// Tool DLLs
	for (pDLLTool = M_GetToolDLLs()->GetHeadElement(pos); pDLLTool;
		 pDLLTool = M_GetToolDLLs()->GetNextElement(pos))
	{
		if (pDLLTool != M_GetCurrentEditor())
			pDLLTool->fn_vOnModifCopy(&m_stListForTools, eType, C_AsToolDLL);
	}
}


//#################################################################################
// Class ModifMove
//#################################################################################

/*===========================================================================
		Constructor
=========================================================================*/
EDT_ModifMove::EDT_ModifMove (EDT_HierarchyEditor *pEditor, CPA_List<EDT_ListByDLL> *pSelectByType, 
							  CString csType, BOOL bUpdateDrawing) 
		: CPA_Modif(TYPE_MOVE, "Move", FALSE)
{
	EDT_SaveGlobalPos	*pNewSaveGlobalPos;
	EDT_ListByDLL		*pListSelect;
	EDT_SavePos			*pNewSavePos;
	EDT_SuperObject		*pEdObj;
	CPA_SuperObject		*pSupObj;
	EDT_PosByType		*pNewList;
	POSITION			pos, pos1;
	
	// init parent editor
	m_pEditor = pEditor;
	m_bFirstTime = TRUE;
	m_bUpdate = bUpdateDrawing;
	// fill the lists for DLLs
	for (pListSelect = pSelectByType->GetHeadElement(pos); pListSelect;
		 pListSelect = pSelectByType->GetNextElement(pos))
	{
		// save only if there are elements
		if (pListSelect->m_stListConcerned.GetCount())
		{
			// create the corresponding list
			pNewList = new EDT_PosByType(pListSelect->GetDLL());
			if (pListSelect->GetDLL())
				m_lstModifByType.AddTail(pNewList);
			// copy the list of selected objects
			for (pSupObj = pListSelect->m_stListSelected.GetHeadElement(pos1); pSupObj;
				 pSupObj = pListSelect->m_stListSelected.GetNextElement(pos1))
			{
				pEdObj = (EDT_SuperObject *) pSupObj;
				// update list of selected objets
				pNewSavePos = new EDT_SavePos(pEdObj, HIE_fn_hGetSuperObjectMatrix(pEdObj->GetStruct()));
				pNewList->m_stListObjects.AddTail(pNewSavePos);
				m_stListForTools.m_stListObjects.AddTail(pNewSavePos);
			}
			// copy the list of concerned objects
			for (pSupObj = pListSelect->m_stListConcerned.GetHeadElement(pos1); pSupObj;
				 pSupObj = pListSelect->m_stListConcerned.GetNextElement(pos1))
			{
				pEdObj = (EDT_SuperObject *) pSupObj;
				// update list of concerned objets
				pNewSaveGlobalPos = new EDT_SaveGlobalPos(pEdObj, HIE_fn_hGetSuperObjectGlobalMatrix(pEdObj->GetStruct()));
				pNewList->m_stListConcerned.AddTail(pNewSaveGlobalPos);
				m_stListForTools.m_stListConcerned.AddTail(pNewSaveGlobalPos);
			}
			// copy the list of protected childs
			for (pSupObj = pListSelect->m_stListProtectSelected.GetHeadElement(pos1); pSupObj;
				 pSupObj = pListSelect->m_stListProtectSelected.GetNextElement(pos1))
			{
				pEdObj = (EDT_SuperObject *) pSupObj;
				pNewSavePos = new EDT_SavePos(pEdObj, HIE_fn_hGetSuperObjectMatrix(pEdObj->GetStruct()));
				pNewList->m_stListProtected.AddTail(pNewSavePos);
			}
			// copy the list of protected childs
			for (pSupObj = pListSelect->m_stListProtectConcerned.GetHeadElement(pos1); pSupObj;
				 pSupObj = pListSelect->m_stListProtectConcerned.GetNextElement(pos1))
			{
				pEdObj = (EDT_SuperObject *) pSupObj;
				pNewSaveGlobalPos = new EDT_SaveGlobalPos(pEdObj, HIE_fn_hGetSuperObjectGlobalMatrix(pEdObj->GetStruct()));
				pNewList->m_stListProtectConcerned.AddTail(pNewSaveGlobalPos);
			}
		}
	}
	// init parameters
	m_csType = csType;
	// init modif parent
	m_pModifParent = NULL;
}


/*===========================================================================
		Constructor
=========================================================================*/
EDT_ModifMove::~EDT_ModifMove (void)
{
	// raz list for tools
	m_stListForTools.m_stListObjects.RemoveAll();
	m_stListForTools.m_stListConcerned.RemoveAll();
	// free select list
	while (m_lstModifByType.GetCount() > 0)
		delete m_lstModifByType.RemoveTail();
}


/*===========================================================================
		Interface
=========================================================================*/
CPA_Interface * EDT_ModifMove::GetInterface (void)
{
	return GetParentEditor()->GetInterface();
}


/*===========================================================================
		Do
=========================================================================*/
BOOL EDT_ModifMove::Do (void)
{
	EDT_SaveGlobalPos	*pElem1;
	EDT_SavePos			*pElem;
	tdeTypeModif		eType;
	POSITION			pos, pos1;
	
	
	// world must be valid
	if (!M_HasCurrentWorld())
		return FALSE;

	eType = (m_bFirstTime) ? C_EDTDo : C_EDTRedo ;
	
	// first call : register the move and update parents
	if (m_bFirstTime)
	{
		GetInterface()->fn_vUpdatePositions();
		fn_vRegisterPositions();
	}
	// cancel the current selection
	if (!m_bFirstTime)
		GetInterface()->fn_vCancelCurrentSelection(FALSE);

	// init the modif

	for (pElem1 = m_stListForTools.m_stListConcerned.GetHeadElement(pos1); pElem1;
		 pElem1 = m_stListForTools.m_stListConcerned.GetNextElement(pos1))
		((EDT_SuperObject *) pElem1->m_pObject)->fn_bInitTemporarySO();

	// do the modif
	for (pElem = m_stListForTools.m_stListObjects.GetHeadElement(pos); pElem;
		 pElem = m_stListForTools.m_stListObjects.GetNextElement(pos))
	{
		// select the current object
		if (!m_bFirstTime)
			GetInterface()->fn_vAddSelectedObject(pElem->m_pObject, FALSE);
		// set the final position
		GEO_M_vCopyMatrix(HIE_fn_hGetSuperObjectMatrix(pElem->m_pObject->GetStruct()), pElem->m_hFinalMatrix);
		// notify section
		pElem->m_pObject->fn_vNotifySave();
// Begin Silviu Simen 01 september 1998 List of Objects in Sectors
		if (GetInterface()->GetSpecificInterface()->fn_bHasValidWorld())
		{
			MTH3D_tdstVector	stObjectPosition;
			CPA_SuperObject * pSector;

			stObjectPosition = pElem -> m_hFinalMatrix -> stTranslationVector;
			pSector = GetInterface() -> GetSpecificInterface()->
								GetCurrentSectorFromPos(&stObjectPosition);
			M_GetMainWorld()->m_stListObjectsInSectors.UpdateElement(pElem->m_pObject,pSector);
		}
// End Silviu Simen 01 september 1998 List of Objects in Sectors

	}

	// update file names
	for (pElem1 = m_stListForTools.m_stListConcerned.GetHeadElement(pos1); pElem1;
		 pElem1 = m_stListForTools.m_stListConcerned.GetNextElement(pos1))
	{
		// set the final position
		GEO_M_vCopyMatrix(HIE_fn_hGetSuperObjectGlobalMatrix(pElem1->m_pObject->GetStruct()), pElem1->m_hFinalGlobalMatrix);
		// if necessary, register the modif
		((EDT_SuperObject *) pElem1->m_pObject)->fn_vUpdateTemporaryModif(C_szChangePosition, TRUE);
	}

	// tell DLLs
	fn_vSendMessageMove(eType);
	// update parents
	if (m_pModifParent)
		m_pModifParent->Do();
	// set select mode
	if (strcmp(M_GetSelectMode(), "All Types"))
		GetInterface()->SetSelectMode(m_csType);

	// for autotarget
	if (m_stListForTools.m_stListObjects.GetCount() == 1) 
	{
		CPA_SuperObject *pEdObj = m_stListForTools.m_stListObjects.GetHeadElement(pos1)->m_pObject;
		BOOL bAutoTarget = GetInterface()->fn_bAutoTarget();
		BOOL bAutoZoom = GetInterface()->fn_bAutoZoom();

		if (bAutoTarget || bAutoZoom)
			GetInterface()->fn_vCenterOnObject(pEdObj, bAutoZoom, bAutoTarget);
	}

	if (m_bUpdate)
	{
// Begin Silviu Simen 01 september 1998 List of Objects in Sectors
//		GetInterface()->fn_vUpdateAll(E_mc_JustDraw);
//		m_pEditor->GetDialogEdit()->fn_vUpdateDialog();
		GetInterface()->fn_vUpdateAll(E_mc_UpdateDialog);
// End  Silviu Simen 01 september 1998 List of Objects in Sectors
		if (!m_bFirstTime)
			M_GetMainWnd()->UpdateStatus("Move Done", C_STATUSPANE_INFOS, C_STATUS_NORMAL);
	}
	// update parameters
	m_bFirstTime = FALSE;
	return TRUE;
}


/*===========================================================================
		Undo
=========================================================================*/
BOOL EDT_ModifMove::Undo (void)
{
	EDT_SaveGlobalPos	*pElem1;
	EDT_SavePos			*pElem;
	POSITION			pos, pos1;
	
	// world must be valid
	if (!M_HasCurrentWorld())
		return FALSE;

	// cancel the current selection
	GetInterface()->fn_vCancelCurrentSelection(FALSE);
	// undo the modif
	for (pElem = m_stListForTools.m_stListObjects.GetHeadElement(pos); pElem;
		 pElem = m_stListForTools.m_stListObjects.GetNextElement(pos))
	{
		// select the current object
		GetInterface()->fn_vAddSelectedObject(pElem->m_pObject, FALSE);
		// set the initial matrix
		GEO_M_vCopyMatrix(HIE_fn_hGetSuperObjectMatrix(pElem->m_pObject->GetStruct()), pElem->m_hInitialMatrix);
// Begin Silviu Simen 01 september 1998 List of Objects in Sectors
		if (GetInterface()->GetSpecificInterface()->fn_bHasValidWorld())
		{
			MTH3D_tdstVector	stObjectPosition;
			CPA_SuperObject * pSector;

			stObjectPosition = pElem -> m_hInitialMatrix -> stTranslationVector;
			pSector = GetInterface() -> GetSpecificInterface() ->
								GetCurrentSectorFromPos(&stObjectPosition);
			M_GetMainWorld()->m_stListObjectsInSectors.UpdateElement(pElem->m_pObject,pSector);
		}
// End Silviu Simen 01 september 1998 List of Objects in Sectors
	}
	// update file names
	for (pElem1 = m_stListForTools.m_stListConcerned.GetHeadElement(pos1); pElem1;
		 pElem1 = m_stListForTools.m_stListConcerned.GetNextElement(pos1))
	{
		// set the final position
		GEO_M_vCopyMatrix(HIE_fn_hGetSuperObjectGlobalMatrix(pElem1->m_pObject->GetStruct()), pElem1->m_hInitialGlobalMatrix);
		// if necessary, register the modif
		((EDT_SuperObject *) pElem1->m_pObject)->fn_vUpdateTemporaryModif(C_szChangePosition, FALSE);
	}
	// tell DLLs
	fn_vSendMessageMove(C_EDTUndo);
	// update parents
	if (m_pModifParent)
		m_pModifParent->Undo();
	// set select mode
	if (strcmp(M_GetSelectMode(), "All Types"))
		GetInterface()->SetSelectMode(m_csType);

	// for autotarget
	if (m_stListForTools.m_stListObjects.GetCount() == 1) 
	{
		CPA_SuperObject *pEdObj = m_stListForTools.m_stListObjects.GetHeadElement(pos1)->m_pObject;
		BOOL bAutoTarget = GetInterface()->fn_bAutoTarget();
		BOOL bAutoZoom = GetInterface()->fn_bAutoZoom();

		if (bAutoTarget || bAutoZoom)
			GetInterface()->fn_vCenterOnObject(pEdObj, bAutoZoom, bAutoTarget);
	}

	// update all 
	if (m_bUpdate)
	{
// Begin Silviu Simen 01 september 1998 List of Objects in Sectors
//		GetInterface()->fn_vUpdateAll(E_mc_JustDraw);
//		m_pEditor->GetDialogEdit()->fn_vUpdateDialog();
		GetInterface()->fn_vUpdateAll(E_mc_UpdateDialog);
// End  Silviu Simen 01 september 1998 List of Objects in Sectors
		M_GetMainWnd()->UpdateStatus("Move Undone", C_STATUSPANE_INFOS, C_STATUS_NORMAL);
	}
	return TRUE;
}

/*===========================================================================
		Cancel
=========================================================================*/
BOOL EDT_ModifMove::Cancel (void)
{
	EDT_SavePos		*pElem;
	POSITION		pos1;
	
	// world must be valid
	if (!M_HasCurrentWorld())
		return FALSE;

	// undo the modif
	for (pElem = m_stListForTools.m_stListObjects.GetHeadElement(pos1); pElem;
		 pElem = m_stListForTools.m_stListObjects.GetNextElement(pos1))
		GEO_M_vCopyMatrix(HIE_fn_hGetSuperObjectMatrix(pElem->m_pObject->GetStruct()), pElem->m_hInitialMatrix);
	// tell DLLs
	fn_vSendMessageMove(C_EDTCancel);
	// update all 
	GetInterface()->fn_vUpdateAll(E_mc_UpdateDialog);
	return TRUE;
}


/*===========================================================================
		Init Modif Parent
=========================================================================*/
void EDT_ModifMove::fn_vInitListModif (CPA_List<EDT_SaveParents> *pListModif)
{
	if (pListModif->GetCount())
		m_pModifParent = new EDT_ModifParent(m_pEditor, pListModif, m_csType);
}


/*===========================================================================
		Init Modif Move
=========================================================================*/
void EDT_ModifMove::fn_vRegisterPositions (void)
{
	EDT_PosByType		*pListPos;
	EDT_SaveGlobalPos	*pElem1;
	EDT_SavePos			*pElem;
	POSITION			pos, pos1;

	// update the list of selected objects
	for (pElem = m_stListForTools.m_stListObjects.GetHeadElement(pos); pElem;
		 pElem = m_stListForTools.m_stListObjects.GetNextElement(pos))
	{
		// register final position
		pElem->m_hFinalMatrix = M_EDT_AllocMatrix();
		GEO_M_vCopyMatrix(pElem->m_hFinalMatrix, HIE_fn_hGetSuperObjectMatrix(pElem->m_pObject->GetStruct()));
	}

	// update the list of concerned objects
	for (pElem1 = m_stListForTools.m_stListConcerned.GetHeadElement(pos1); pElem1;
		 pElem1 = m_stListForTools.m_stListConcerned.GetNextElement(pos1))
	{
		// register final position
		pElem1->m_hFinalGlobalMatrix = M_EDT_AllocMatrix();
		GEO_M_vCopyMatrix(pElem1->m_hFinalGlobalMatrix, HIE_fn_hGetSuperObjectGlobalMatrix(pElem1->m_pObject->GetStruct()));
	}

	// protected objects
	for (pListPos = m_lstModifByType.GetHeadElement(pos); pListPos;
		 pListPos = m_lstModifByType.GetNextElement(pos))
	{
		// update the list of selected objects
		for (pElem = pListPos->m_stListProtected.GetHeadElement(pos1); pElem1;
			 pElem = pListPos->m_stListProtected.GetNextElement(pos1))
		{
			// register final position
			pElem->m_hFinalMatrix = M_EDT_AllocMatrix();
			GEO_M_vCopyMatrix(pElem1->m_hFinalGlobalMatrix, HIE_fn_hGetSuperObjectGlobalMatrix(pElem1->m_pObject->GetStruct()));
		}
		// update the list of concerned objects
		for (pElem1 = pListPos->m_stListProtectConcerned.GetHeadElement(pos1); pElem1;
			 pElem1 = pListPos->m_stListProtectConcerned.GetNextElement(pos1))
		{
			// register final position
			pElem1->m_hFinalGlobalMatrix = M_EDT_AllocMatrix();
			GEO_M_vCopyMatrix(pElem1->m_hFinalGlobalMatrix, HIE_fn_hGetSuperObjectGlobalMatrix(pElem1->m_pObject->GetStruct()));
		}
	}

	// reinit selected objects
	for (pElem = m_stListForTools.m_stListObjects.GetHeadElement(pos); pElem;
		 pElem = m_stListForTools.m_stListObjects.GetNextElement(pos))
		GEO_M_vCopyMatrix(HIE_fn_hGetSuperObjectMatrix(pElem->m_pObject->GetStruct()), pElem->m_hInitialMatrix);

	// reinit concerned objects
	for (pElem1 = m_stListForTools.m_stListConcerned.GetHeadElement(pos1); pElem1;
		 pElem1 = m_stListForTools.m_stListConcerned.GetNextElement(pos1))
		GEO_M_vCopyMatrix(HIE_fn_hGetSuperObjectGlobalMatrix(pElem1->m_pObject->GetStruct()), pElem1->m_hInitialGlobalMatrix);
}




/*===========================================================================
		Message
=========================================================================*/
void EDT_ModifMove::fn_vSendMessageMove (tdeTypeModif eType)
{
	CPA_ToolDLLBase	*pDLLTool;
	EDT_PosByType	*pListPos;
	POSITION		pos;
	
	if (!M_IsCurrentEditor())
		M_GetCurrentEditor()->fn_vOnModifMove(&m_stListForTools.m_stListObjects, &m_stListForTools.m_stListConcerned, eType, C_AsCurrentEditor);
	// object DLLs
	for (pListPos = m_lstModifByType.GetHeadElement(pos); pListPos;
		 pListPos = m_lstModifByType.GetNextElement(pos))
	{
		if (pListPos->m_stListConcerned.GetCount())
			pListPos->m_poDLL->fn_vOnModifMove(&pListPos->m_stListObjects, &pListPos->m_stListConcerned, eType, C_AsConcernedDLL);
	}
	// owner DLLs
	for (pListPos = m_lstModifByType.GetHeadElement(pos); pListPos;
		 pListPos = m_lstModifByType.GetNextElement(pos))
	{
		if (pListPos->m_stListProtectConcerned.GetCount())
			pListPos->m_poDLL->fn_vOnModifMove(&pListPos->m_stListProtected, &pListPos->m_stListProtectConcerned, eType, C_AsChildOwner);
	}
	// Tool DLLs
	for (pDLLTool = M_GetToolDLLs()->GetHeadElement(pos); pDLLTool;
		 pDLLTool = M_GetToolDLLs()->GetNextElement(pos))
	{
		if (pDLLTool != M_GetCurrentEditor())
			pDLLTool->fn_vOnModifMove(&m_stListForTools.m_stListObjects, &m_stListForTools.m_stListConcerned, eType, C_AsToolDLL);
	}
}

//#################################################################################
// Class ModifParent
//#################################################################################

/*===========================================================================
		Constructor (EDT_HierarchyEditor)
=========================================================================*/
EDT_ModifParent::EDT_ModifParent (EDT_HierarchyEditor *pEditor, CPA_List<EDT_ListByDLL> *pSelectByType, 
						  EDT_SuperObject *pNewParent, CString csType, BOOL bUpdateDrawing) 
		: CPA_Modif(TYPE_PARENT, "ModifParent", FALSE)
{
	EDT_ListByDLL	 *pListSelect;
	EDT_SaveParents	 *pNewSaveParent;
	EDT_ParentByType *pNewList;
	EDT_SuperObject  *pEdObj, *pParent;
	CPA_SuperObject	 *pSupObj;
	POSITION		 pos, pos1;
	
	// init parent editor
	m_pEditor = pEditor;
	m_bFirstTime = TRUE;
	m_bUpdate = bUpdateDrawing;
	// fill the lists for DLLs
	for (pListSelect = pSelectByType->GetHeadElement(pos); pListSelect;
		 pListSelect = pSelectByType->GetNextElement(pos))
	{
		// save only if there are elements
		if ((pListSelect->m_stListSelected.GetCount())
		  ||(pListSelect->m_stListProtectSelected.GetCount()))
		{
			// create the corresponding list
			pNewList = new EDT_ParentByType(pListSelect->GetDLL());
			if (pListSelect->GetDLL())
				m_lstModifByType.AddTail(pNewList);
			// copy the list of objects
			for (pSupObj = pListSelect->m_stListSelected.GetHeadElement(pos1); pSupObj;
				 pSupObj = pListSelect->m_stListSelected.GetNextElement(pos1))
			{
				pEdObj = (EDT_SuperObject *) pSupObj;
				// init parameters
				pParent = (EDT_SuperObject *) pEdObj->GetSuperObjectFather();
				// create element
				pNewSaveParent = new EDT_SaveParents(pEdObj, pParent, pNewParent);
				// update lists
				pNewList->m_stListObjects.AddTail(pNewSaveParent);
				m_stListForTools.AddTail(pNewSaveParent);
			}
			// copy the list of protected
			for (pSupObj = pListSelect->m_stListProtectSelected.GetHeadElement(pos1); pSupObj;
				 pSupObj = pListSelect->m_stListProtectSelected.GetNextElement(pos1))
			{
				pEdObj = (EDT_SuperObject *) pSupObj;
				pNewSaveParent = new EDT_SaveParents(pEdObj, (EDT_SuperObject *) pEdObj->GetSuperObjectFather(), pNewParent);
				pNewList->m_stListProtected.AddTail(pNewSaveParent);
			}
		}
	}
	// save select mode
	m_csType = csType;
}


/*===========================================================================
		Constructor (from ModifMove)
=========================================================================*/
EDT_ModifParent::EDT_ModifParent (EDT_HierarchyEditor *pEditor, CPA_List<EDT_SaveParents> *pListModif, 
								  CString csType) 
		: CPA_Modif(TYPE_PARENT, "ModifParent", FALSE)
{
	EDT_ParentByType *pListSelect;
	EDT_ParentByType *pListProtect;
	EDT_SaveParents	 *pNewSaveParent;
	EDT_SaveParents	 *pElem;
	POSITION		 pos;
	
	// init parent editor
	m_pEditor = pEditor;
	m_bFirstTime = TRUE;
	m_bUpdate = FALSE;
	m_lstModifByType.RemoveAll();

	// fill the lists
	for (pElem = pListModif->GetHeadElement(pos); pElem;
		 pElem = pListModif->GetNextElement(pos))
	{
		// create new element
		pNewSaveParent = new EDT_SaveParents(pElem->m_pChild, pElem->m_pInitialParent, pElem->m_pFinalParent);
		// fill list for tools
		m_stListForTools.AddTail(pNewSaveParent);
		// find corresponding list
		pListSelect = GetOrCreateListByDLL(pElem->m_pChild->GetObjectDLL());
		// add element to the list
		pListSelect->m_stListObjects.AddTail(pNewSaveParent);
		// protected childs => add to protect list
		if (pElem->m_pChild->GetSuperObjectOwner())
		{
			// create new element
			pNewSaveParent =  new EDT_SaveParents(pElem->m_pChild, pElem->m_pInitialParent, pElem->m_pFinalParent);
			// get protect list
			pListProtect = GetOrCreateListByDLL(pElem->m_pChild->GetSuperObjectOwner()->GetObjectDLL());
			// add element to protect list
			pListProtect->m_stListProtected.AddTail(pNewSaveParent);
		}
	}
	// save select mode
	m_csType = csType;
}


/*===========================================================================
		Destructor
=========================================================================*/
EDT_ModifParent::~EDT_ModifParent (void)
{
	// free Select List
	while (m_lstModifByType.GetCount() > 0)
		delete m_lstModifByType.RemoveTail();
}


/*===========================================================================
		Interface
=========================================================================*/
CPA_Interface * EDT_ModifParent::GetInterface (void)
{
	return GetParentEditor()->GetInterface();
}


/*===========================================================================
		Do
=========================================================================*/
BOOL EDT_ModifParent::Do (void)
{
	EDT_SaveParents  *pElem;
	EDT_SuperObject  *pEdObj, *pParent;
	POSITION		 pos, pos1;
	
	// world must be valid
	if (!M_HasCurrentWorld())
		return FALSE;

	// cancel current selection
	GetInterface()->fn_vCancelCurrentSelection(FALSE);
	// change parent for all objects in the list
	for (pElem = m_stListForTools.GetHeadElement(pos1); pElem;
		 pElem = m_stListForTools.GetNextElement(pos1))
	{
		pEdObj = (EDT_SuperObject *) pElem->m_pChild;
		pParent = (EDT_SuperObject *) pElem->m_pFinalParent;
		// update object status
		pEdObj->fn_bInitTemporarySO();
		// move the object in the hierarchy
		pEdObj->fn_vInsertUnderParent(pParent, NULL, TRUE);
		// if necessary, register the modif
		pEdObj->fn_vUpdateTemporaryModif(C_szChangeFather, TRUE);
		// register notify
		if (pEdObj->fn_bCanBeNotified())
		{
			pElem->m_pInitialParent->fn_vNotifySave();
			pElem->m_pFinalParent->fn_vNotifySave();
			pEdObj->fn_vNotifySave();
		}
		// show new parent
		if (M_GetWorld()->GetRoot() != pParent)
		GetInterface()->fn_vSetLocalColor(pParent, E_lm_ShowParent);
	}
	
	// tell DLLs
	fn_vSendMessageParent((m_bFirstTime) ? C_EDTDo : C_EDTRedo);

	// update current selection
	for (pElem = m_stListForTools.GetHeadElement(pos); pElem;
		 pElem = m_stListForTools.GetNextElement(pos))
		GetInterface()->fn_vAddSelectedObject(pElem->m_pChild, FALSE);
	// update all
	GetInterface()->SetSelectMode("All Types");
	if (m_bUpdate)
	{
		GetInterface()->fn_vUpdateAll(E_mc_UpdateDialog);
		if (!m_bFirstTime)
			M_GetMainWnd()->UpdateStatus("Modif Parent Done", C_STATUSPANE_INFOS, C_STATUS_NORMAL);
	}
	m_bFirstTime = FALSE;
	return TRUE;
}

/*===========================================================================
		Undo
=========================================================================*/
BOOL EDT_ModifParent::Undo (void)
{
	EDT_SaveParents  *pElem;
	EDT_SuperObject  *pEdObj, *pParent;
	POSITION		 pos, pos1;
	
	// world must be valid
	if (!M_HasCurrentWorld())
		return FALSE;

	// cancel current selection
	GetInterface()->fn_vCancelCurrentSelection(FALSE);
	// delete all objects in the list
	for (pElem = m_stListForTools.GetHeadElement(pos1); pElem;
		 pElem = m_stListForTools.GetNextElement(pos1))
	{
		pEdObj = (EDT_SuperObject *) pElem->m_pChild;
		pParent = (EDT_SuperObject *) pElem->m_pInitialParent;
		// move the object in the hierarchy
		pEdObj->fn_vInsertUnderParent(pParent, NULL, TRUE);
		// update object status
		pEdObj->fn_vUpdateTemporaryModif(C_szChangeFather, FALSE);
		// show new parent
		if (M_GetWorld()->GetRoot() != pParent)
			GetInterface()->fn_vSetLocalColor(pParent, E_lm_ShowParent);
	}
	// tell DLLs
	fn_vSendMessageParent(C_EDTUndo);
	// update current selection
	for (pElem = m_stListForTools.GetHeadElement(pos); pElem;
		 pElem = m_stListForTools.GetNextElement(pos))
		GetInterface()->fn_vAddSelectedObject(pElem->m_pChild, FALSE);
	// update select type
	if (M_GetSelectMode() != "All Types")
		GetInterface()->SetSelectMode(m_csType);
	// update all 
	if (m_bUpdate)
	{
		GetInterface()->fn_vUpdateAll(E_mc_UpdateDialog);
		M_GetMainWnd()->UpdateStatus("Modif Parent Undone", C_STATUSPANE_INFOS, C_STATUS_NORMAL);
	}
	return TRUE;
}


/*===========================================================================
		Functions
=========================================================================*/
EDT_ParentByType * EDT_ModifParent::GetOrCreateListByDLL (CPA_ObjectDLLBase *p_oDLL)
{
	EDT_ParentByType	*pList;
	POSITION			pos;

	// check the existing lists
	for (pList = m_lstModifByType.GetHeadElement(pos); pList;
		 pList = m_lstModifByType.GetNextElement(pos))
	{
		if (pList->m_poDLL == p_oDLL)
			return pList;
	}
	// list was not found => create it
	pList = new EDT_ParentByType(p_oDLL);
	if (p_oDLL)
		m_lstModifByType.AddTail(pList);
	return pList;
}

/*===========================================================================
		Message
=========================================================================*/
void EDT_ModifParent::fn_vSendMessageParent (tdeTypeModif eType)
{
	CPA_ToolDLLBase  *pDLLTool;
	EDT_ParentByType *pListParent;
	POSITION		 pos;
	
	// Current Editor
	if (!M_IsCurrentEditor())
		M_GetCurrentEditor()->fn_vOnModifParent(&m_stListForTools, eType, C_AsCurrentEditor);
	// concerned DLLs
	for (pListParent = m_lstModifByType.GetHeadElement(pos); pListParent;
		 pListParent = m_lstModifByType.GetNextElement(pos))
	{
		if (pListParent->m_stListObjects.GetCount())
			pListParent->m_poDLL->fn_vOnModifParent(&pListParent->m_stListObjects, eType, C_AsConcernedDLL);
	}
	// owner DLLs
	for (pListParent = m_lstModifByType.GetHeadElement(pos); pListParent;
		 pListParent = m_lstModifByType.GetNextElement(pos))
	{
		if (pListParent->m_stListProtected.GetCount())
			pListParent->m_poDLL->fn_vOnModifParent(&pListParent->m_stListProtected, eType, C_AsChildOwner);
	}
		 // Tool DLLs
	for (pDLLTool = M_GetToolDLLs()->GetHeadElement(pos); pDLLTool;
		 pDLLTool = M_GetToolDLLs()->GetNextElement(pos))
	{
		if (pDLLTool != M_GetCurrentEditor())
			pDLLTool->fn_vOnModifParent(&m_stListForTools, eType, C_AsToolDLL);
	}
}


//#################################################################################
// class ModifName
//#################################################################################

/*===========================================================================
		Constructor
=========================================================================*/
EDT_ModifName::EDT_ModifName(EDT_HierarchyEditor *pEditor, EDT_SuperObject *pModifiedObject, CString csFinalName, BOOL bRenameObject)
		: CPA_Modif(TYPE_RENAME, "Rename", FALSE)
{
	// init parent editor
	m_pEditor = pEditor;
	// Init parameters
	m_pModifiedObject = pModifiedObject;
	m_bRenameObject = bRenameObject;
	if (!m_bRenameObject)
		m_csInitialName = pModifiedObject->GetName();
	else
		m_csInitialName = pModifiedObject->GetObject()->GetName();
	m_csFinalName = csFinalName;
	m_csType = pModifiedObject->GetRealTypeName();
	// init modif
	m_bFirstTime = TRUE;
}


EDT_ModifName::~EDT_ModifName (void) 
{ 
}


/*===========================================================================
		Interface
=========================================================================*/
CPA_Interface * EDT_ModifName::GetInterface (void)
{
	return GetParentEditor()->GetInterface();
}


/*===========================================================================
		Do
=========================================================================*/
BOOL EDT_ModifName::Do (void)
{
	// update current selection
	if (!m_bFirstTime)
	{
		GetInterface()->fn_vCancelCurrentSelection(FALSE);
		GetInterface()->fn_vAddSelectedObject(m_pModifiedObject, FALSE);
	}

	// if necessary, register as temporary

	if (!m_bRenameObject)
		m_pModifiedObject->fn_bInitTemporarySO();
	
	// update name
	if (!m_bRenameObject)
		m_pModifiedObject->fn_eRename(m_csFinalName);
	else
		m_pModifiedObject->GetObject()->fn_eRename(m_csFinalName);

	// if necessary, update modif
	if (!m_bRenameObject)
		m_pModifiedObject->fn_vUpdateTemporaryModif(C_szChangeName, TRUE);

	// tell DLLs
	fn_vSendMessageName((m_bFirstTime) ? C_EDTDo : C_EDTRedo);
	// update all 
	GetInterface()->fn_vUpdateAll(E_mc_UpdateDialog);
	if (!m_bFirstTime)
		M_GetMainWnd()->UpdateStatus("Rename Done", C_STATUSPANE_INFOS, C_STATUS_NORMAL);
	m_bFirstTime = FALSE;
	return TRUE;
}

/*===========================================================================
		Undo
=========================================================================*/
BOOL EDT_ModifName::Undo (void)
{
	BOOL bIsLoadingWorld;
	
	// update current selection
	GetInterface()->fn_vCancelCurrentSelection(FALSE);
	GetInterface()->fn_vAddSelectedObject(m_pModifiedObject, FALSE);

	// undo => no prefix added !!
	bIsLoadingWorld = GetInterface()->fn_bIsLoadingWorld();
	GetInterface()->SetLoadingWorld(TRUE);
	// update name
	if (!m_bRenameObject)
		m_pModifiedObject->fn_eRename(m_csInitialName);
	else
		m_pModifiedObject->GetObject()->fn_eRename(m_csInitialName);
	// undo => no prefix added !!
	GetInterface()->SetLoadingWorld(bIsLoadingWorld);

	// if necessary, update modif
	if (!m_bRenameObject)
		m_pModifiedObject->fn_vUpdateTemporaryModif(C_szChangeName, FALSE);

	// tell DLLs
	fn_vSendMessageName(C_EDTUndo);
	// update all 
	GetInterface()->fn_vUpdateAll(E_mc_UpdateDialog);
	M_GetMainWnd()->UpdateStatus("Rename Undone", C_STATUSPANE_INFOS, C_STATUS_NORMAL);
	return TRUE;
}


/*===========================================================================
		Message
=========================================================================*/
void EDT_ModifName::fn_vSendMessageName (tdeTypeModif eType)
{
	CPA_ObjectDLLBase	*pDLLObject;
	CPA_ToolDLLBase		*pDLLTool;
	POSITION			pos;
		
	// for current editor
	if (!M_IsCurrentEditor())
		M_GetCurrentEditor()->fn_vOnModifName(m_pModifiedObject, m_csInitialName, m_csFinalName, eType, C_AsCurrentEditor);
	// tell the corresponding DLL
	if (m_pModifiedObject->GetObjectDLL())
		m_pModifiedObject->GetObjectDLL()->fn_vOnModifName(m_pModifiedObject, m_csInitialName, m_csFinalName, eType, C_AsConcernedDLL);
	// if necessary, tell owner
	if (m_pModifiedObject->GetSuperObjectOwner())
	{
		pDLLObject = m_pModifiedObject->GetSuperObjectOwner()->GetObjectDLL();
		pDLLObject->fn_vOnModifName(m_pModifiedObject, m_csInitialName, m_csFinalName, eType, C_AsChildOwner);
	}
	// Tool DLLs
	for (pDLLTool = M_GetToolDLLs()->GetHeadElement(pos); pDLLTool;
		 pDLLTool = M_GetToolDLLs()->GetNextElement(pos))
	{	
		if (pDLLTool != M_GetCurrentEditor())
			pDLLTool->fn_vOnModifName(m_pModifiedObject, m_csInitialName, m_csFinalName, eType, C_AsToolDLL);
	}	
}





//#################################################################################
// Class ModifState
//#################################################################################

/*===========================================================================
		Constructor 
=========================================================================*/
EDT_ModifState::EDT_ModifState (EDT_HierarchyEditor *pEditor, EDT_SuperObject *pModifiedObject, CString csTypeModif, BOOL bInitialState)
		: CPA_Modif(TYPE_STATE, "State", FALSE)
{
	// init parameters
	m_pEditor = pEditor;
	m_pModifiedObject = pModifiedObject;
	m_csTypeModif = csTypeModif;
	m_bInitialState = bInitialState;
	m_bFirstTime = TRUE;

	// creation => register parent and lists 
	if (csTypeModif == C_szCreation)
	{
		if (bInitialState)
		{
			m_pInitialParent = pModifiedObject->GetTemporaryModif()->GetFinalFather();
			m_pFinalParent = NULL;
			fn_vFillListForDelete(m_pModifiedObject, m_pInitialParent, m_pFinalParent);
		}
		else
		{
			m_pInitialParent = NULL;
			m_pFinalParent = pModifiedObject->GetTemporaryModif()->GetFinalFather();
		}

	}
	
	// suppression => register parent and lists
	if (csTypeModif == C_szSuppression) 
	{
		if (bInitialState)
		{
			m_pInitialParent = NULL;
			m_pFinalParent = pModifiedObject->GetTemporaryModif()->GetFinalFather();
		}
		else
		{
			m_pInitialParent = pModifiedObject->GetTemporaryModif()->GetFinalFather();
			m_pFinalParent	 = NULL;
			fn_vFillListForDelete(m_pModifiedObject, m_pInitialParent, m_pFinalParent);
		}
	}

	// change parent => simply register parent
	if (csTypeModif == C_szChangeFather)
	{
		if (bInitialState)
		{
			m_pInitialParent = pModifiedObject->GetTemporaryModif()->GetFinalFather();
			//CPA2 Stegaru Cristian 98-02
			//			m_pFinalParent	 = pModifiedObject->GetTemporaryModif()->GetOriginalFather();
		}
		else
		{
			//CPA2 Stegaru Cristian 98-02
			//m_pInitialParent = pModifiedObject->GetTemporaryModif()->GetOriginalFather();
			m_pFinalParent	 = pModifiedObject->GetTemporaryModif()->GetFinalFather();
		}
		m_stParentForTools.RemoveAll();
		m_stParentForTools.AddTail(new EDT_SaveParents(m_pModifiedObject, m_pInitialParent, m_pFinalParent));
	}

	// change position => register position and init lists
	if (csTypeModif ==  C_szChangePosition)
	{
		m_hInitialMatrix = M_EDT_AllocMatrix();
		m_hFinalMatrix = M_EDT_AllocMatrix();
		if (bInitialState)
		{
			GEO_M_vCopyMatrix(m_hInitialMatrix, pModifiedObject->GetTemporaryModif()->GetFinalPosition());
			//CPA2 Stegaru Cristian 98-02
			//GEO_M_vCopyMatrix(m_hFinalMatrix, pModifiedObject->GetTemporaryModif()->GetOriginalPosition());
		}
		else
		{
			//CPA2 Stegaru Cristian 98-02
			//GEO_M_vCopyMatrix(m_hInitialMatrix, pModifiedObject->GetTemporaryModif()->GetOriginalPosition());
			GEO_M_vCopyMatrix(m_hFinalMatrix, pModifiedObject->GetTemporaryModif()->GetFinalPosition());
		}
		// lists
		fn_vFillListForMove(m_pModifiedObject);
	}

	// init name
	if (csTypeModif == C_szChangeName)
	{
		if (bInitialState)
		{
			m_csInitialName = pModifiedObject->GetTemporaryModif()->GetFinalName();
			//CPA2 Stegaru Cristian 98-02
			//m_csFinalName = pModifiedObject->GetTemporaryModif()->GetOriginalName();
		}
		else
		{
			//CPA2 Stegaru Cristian 98-02
			//m_csInitialName = pModifiedObject->GetTemporaryModif()->GetOriginalName();
			m_csFinalName = pModifiedObject->GetTemporaryModif()->GetFinalName();
		}
	}
}

/*===========================================================================
		Destructor
=========================================================================*/
EDT_ModifState::~EDT_ModifState (void)
{
}


/*===========================================================================
		Interface
=========================================================================*/
CPA_Interface * EDT_ModifState::GetInterface (void)
{
	return GetParentEditor()->GetInterface();
}


/*===========================================================================
		Do
=========================================================================*/
BOOL EDT_ModifState::Do (void)
{
	BOOL bIsLoadingWorld;
	
	// cancel current selection
	GetInterface()->fn_vCancelCurrentSelection(FALSE);

	// creation 
	if (m_csTypeModif == C_szCreation)
	{
		if (m_bInitialState)
		{
			// remove in hierarchy
			fn_vRemoveFromHierarchy();
			// tell DLLs
			fn_vSendMessageDelete((m_bFirstTime) ? C_EDTDo : C_EDTRedo);
		}
		else
		{
			// insert in hierarchy
			fn_vInsertInHierarchy();
			// tell DLLs
			fn_vSendMessageCreate((m_bFirstTime) ? C_EDTDo : C_EDTRedo);
			// select object
			GetInterface()->fn_vAddSelectedObject(m_pModifiedObject, FALSE);
		}
	}

	// suppression
	else if (m_csTypeModif == C_szSuppression)
	{
		if (m_bInitialState)
		{
			// insert in hierarchy
			fn_vInsertInHierarchy();
			// tell DLLs
			fn_vSendMessageCreate((m_bFirstTime) ? C_EDTDo : C_EDTRedo);
			// select object
			GetInterface()->fn_vAddSelectedObject(m_pModifiedObject, FALSE);
		}
		else
		{
			// remove in hierarchy
			fn_vRemoveFromHierarchy();
			// tell DLLs
			fn_vSendMessageDelete((m_bFirstTime) ? C_EDTDo : C_EDTRedo);
		}
	}

	// father
	else if (m_csTypeModif == C_szChangeFather)
	{
		// select object
		GetInterface()->fn_vAddSelectedObject(m_pModifiedObject, FALSE);
		// change parent
		m_pModifiedObject->fn_vInsertUnderParent(m_pFinalParent, NULL, TRUE);
		// show new parent
		if (M_GetWorld()->GetRoot() != m_pFinalParent)
			GetInterface()->fn_vSetLocalColor(m_pFinalParent, E_lm_ShowParent);
		// update absolute position
		GetInterface()->fn_vUpdateAll(E_mc_JustDraw);
		// tell DLLs
		fn_vSendMessageParent((m_bFirstTime) ? C_EDTDo : C_EDTRedo);
	}

	// position
	else if (m_csTypeModif == C_szChangePosition)
	{
		// select object
		GetInterface()->fn_vAddSelectedObject(m_pModifiedObject, FALSE);
		// change matrix
		GEO_M_vCopyMatrix(HIE_fn_hGetSuperObjectMatrix(m_pModifiedObject->GetStruct()), m_hFinalMatrix);
		// update absolute position
		GetInterface()->fn_vUpdateAll(E_mc_JustDraw);
		// if necessary, register position
		if (m_bFirstTime)
			fn_vRegisterPositions();
		// Tell DLLs
		fn_vSendMessageMove((m_bFirstTime) ? C_EDTDo : C_EDTRedo);
	}

	// name
	else if (m_csTypeModif == C_szChangeName)
	{
		// select object
		GetInterface()->fn_vAddSelectedObject(m_pModifiedObject, FALSE);
		// change name
		bIsLoadingWorld = GetInterface()->fn_bIsLoadingWorld();
		GetInterface()->SetLoadingWorld(TRUE);
		m_pModifiedObject->fn_eRename(m_csFinalName);
		GetInterface()->SetLoadingWorld(bIsLoadingWorld);
		// Tell DLLs
		fn_vSendMessageName((m_bFirstTime) ? C_EDTDo : C_EDTRedo);
	}

	// update state
	if (!m_bFirstTime)
		m_pModifiedObject->fn_vUpdateModification(m_csTypeModif, TRUE, m_bInitialState);
	// update drawing & dialogs
	GetInterface()->fn_vUpdateAll(E_mc_UpdateDialog);
	// update parameters
	m_bFirstTime = FALSE;
	return TRUE;
}


/*===========================================================================
		Undo
=========================================================================*/
BOOL EDT_ModifState::Undo (void)
{
	BOOL bIsLoadingWorld;
	
	// cancel current selection
	GetInterface()->fn_vCancelCurrentSelection(FALSE);

	// creation 
	if (m_csTypeModif == C_szCreation)
	{
		if (m_bInitialState)
		{
			// insert in hierarchy
			fn_vInsertInHierarchy();
			// tell DLLs
			fn_vSendMessageDelete(C_EDTUndo);
			// select object
			GetInterface()->fn_vAddSelectedObject(m_pModifiedObject, FALSE);
		}
		else
		{
			// remove in hierarchy
			fn_vRemoveFromHierarchy();
			// tell DLLs
			fn_vSendMessageCreate(C_EDTUndo);
		}
	}

	// suppression
	else if (m_csTypeModif == C_szSuppression)
	{
		if (m_bInitialState)
		{
			// remove in hierarchy
			fn_vRemoveFromHierarchy();
			// tell DLLs
			fn_vSendMessageCreate(C_EDTUndo);
		}
		else
		{
			// insert in hierarchy
			fn_vInsertInHierarchy();
			// tell DLLs
			fn_vSendMessageDelete(C_EDTUndo);
			// select object
			GetInterface()->fn_vAddSelectedObject(m_pModifiedObject, FALSE);
		}
	}

	// father
	else if (m_csTypeModif == C_szChangeFather)
	{
		// select object
		GetInterface()->fn_vAddSelectedObject(m_pModifiedObject, FALSE);
		// change parent
		m_pModifiedObject->fn_vInsertUnderParent(m_pInitialParent, NULL, TRUE);
		// show new parent
		if (M_GetWorld()->GetRoot() != m_pInitialParent)
			GetInterface()->fn_vSetLocalColor(m_pInitialParent, E_lm_ShowParent);
		// update absolute position
		GetInterface()->fn_vUpdateAll(E_mc_JustDraw);
		// tell DLLs
		fn_vSendMessageParent(C_EDTUndo);
	}

	// position
	else if (m_csTypeModif == C_szChangePosition)
	{
		// select object
		GetInterface()->fn_vAddSelectedObject(m_pModifiedObject, FALSE);
		// change matrix
		GEO_M_vCopyMatrix(HIE_fn_hGetSuperObjectMatrix(m_pModifiedObject->GetStruct()), m_hInitialMatrix);
		// update absolute position
		GetInterface()->fn_vUpdateAll(E_mc_JustDraw);
		// tell DLLs
		fn_vSendMessageMove(C_EDTUndo);
	}

	// name
	else if (m_csTypeModif == C_szChangeName)
	{
		// select object
		GetInterface()->fn_vAddSelectedObject(m_pModifiedObject, FALSE);
		// change name
		bIsLoadingWorld = GetInterface()->fn_bIsLoadingWorld();
		GetInterface()->SetLoadingWorld(TRUE);
		m_pModifiedObject->fn_eRename(m_csInitialName);
		GetInterface()->SetLoadingWorld(bIsLoadingWorld);
		// tell DLLs
		fn_vSendMessageName(C_EDTUndo);
	}

	m_pModifiedObject->fn_vUpdateModification(m_csTypeModif, TRUE, !m_bInitialState);
	// update drawing & dialogs
	GetInterface()->fn_vUpdateAll(E_mc_UpdateDialog);
	return TRUE;
}


/*===========================================================================
		Creation
=========================================================================*/
void EDT_ModifState::fn_vInsertInHierarchy (void)
{
	// insert object in the hierarchy
	m_pModifiedObject->fn_vInsertUnderParent(m_pFinalParent);
	// update matrix
	POS_fn_vNormalizeMatrix(HIE_fn_hGetSuperObjectMatrix(m_pModifiedObject->GetStruct()));
	// update the corresponding list
	M_GetWorld()->fn_vUpdateListObjects(m_pModifiedObject, E_lum_Insert);
	GetInterface()->fn_vUpdatePositions();
}

/*===========================================================================
		Suppression
=========================================================================*/
void EDT_ModifState::fn_vRemoveFromHierarchy (void)
{
	// remove object from hierarchy
	m_pModifiedObject->IsolateChild();
	// update the corresponding lists
	M_GetWorld()->fn_vUpdateListObjects(m_pModifiedObject, E_lum_Delete);
	// update current selection
	GetInterface()->fn_vSetLocalColor(m_pModifiedObject, E_lm_ShowNormal);
}



/*===========================================================================
		Find corresponding list
=========================================================================*/
EDT_ParentByType * EDT_ModifState::fn_pstFindParentListFromObj (EDT_SuperObject *pEdObj)
{
	CPA_ObjectDLLBase *p_oDLL;
	EDT_ParentByType  *pList;
	POSITION		  pos;
	
	// find object DLL
	p_oDLL = pEdObj->GetObjectDLL();
	if (!p_oDLL)
		return NULL;
	
	// find the corresponding list
	for (pList = m_lstParentByType.GetHeadElement(pos); pList;
	 	 pList = m_lstParentByType.GetNextElement(pos))
	{
		if (pList->m_poDLL == p_oDLL)
			return pList;
	}
	
	// List was not found -> create it
	pList = new EDT_ParentByType(p_oDLL);
	m_lstParentByType.AddTail(pList);
	return pList;
}

/*===========================================================================
		fill List for DLLs
=========================================================================*/
void EDT_ModifState::fn_vFillListForDelete (EDT_SuperObject *pEdObj, EDT_SuperObject *pInitialFather, EDT_SuperObject *pFinalFather)
{
	EDT_ParentByType *pList;
	EDT_SaveParents  *pNewElem;
	CPA_SuperObject  *pEdChild;
	
	// create new elem
	pNewElem = new EDT_SaveParents(pEdObj, pInitialFather, pFinalFather);
	// find corresponding list
	pList = fn_pstFindParentListFromObj(pEdObj);
	// add new elem
	if (pList)
		pList->m_stListObjects.AddTail(pNewElem);
	m_stParentForTools.AddTail(pNewElem);

	// for each child
	pEdChild = pEdObj->GetSuperObjectFirstChild();
	while (pEdChild)
	{
		// next level of the hierarchy
		fn_vFillListForDelete((EDT_SuperObject *) pEdChild, pEdObj, pEdObj);
		// next brother
		pEdChild = pEdObj->GetSuperObjectNextChild(pEdChild);
	}
}

/*===========================================================================
		Find corresponding list
=========================================================================*/
EDT_PosByType * EDT_ModifState::fn_pstFindPosListFromObj (EDT_SuperObject *pEdObj)
{
	CPA_ObjectDLLBase *p_oDLL;
	EDT_PosByType  *pList;
	POSITION		  pos;
	
	// find object DLL
	p_oDLL = pEdObj->GetObjectDLL();
	if (!p_oDLL)
		return NULL;
	
	// find the corresponding list
	for (pList = m_lstPosByType.GetHeadElement(pos); pList;
	 	 pList = m_lstPosByType.GetNextElement(pos))
	{
		if (pList->m_poDLL == p_oDLL)
			return pList;
	}
	
	// List was not found -> create it
	pList = new EDT_PosByType(p_oDLL);
	m_lstPosByType.AddTail(pList);
	return pList;
}

/*===========================================================================
		fill List for DLLs
=========================================================================*/
void EDT_ModifState::fn_vFillListForMove (EDT_SuperObject *pEdObj)
{
	EDT_SaveGlobalPos *pNewSaveGlobalPos;
	CPA_SuperObject   *pEdChild;
	EDT_PosByType	  *pList;
	EDT_SavePos		  *pNewSavePos;
	
	// create new save pos
	pNewSavePos = new EDT_SavePos(pEdObj, HIE_fn_hGetSuperObjectMatrix(pEdObj->GetStruct()));
	pList = fn_pstFindPosListFromObj(pEdObj);
	if (pList)
		pList->m_stListObjects.AddTail(pNewSavePos);
	m_stPosForTools.m_stListObjects.AddTail(pNewSavePos);

	// create new save global pos
	pNewSaveGlobalPos = new EDT_SaveGlobalPos(pEdObj, HIE_fn_hGetSuperObjectGlobalMatrix(pEdObj->GetStruct()));
	pList = fn_pstFindPosListFromObj(pEdObj);
	if (pList)
		pList->m_stListConcerned.AddTail(pNewSaveGlobalPos);
	m_stPosForTools.m_stListConcerned.AddTail(pNewSaveGlobalPos);

	// for each child
	pEdChild = pEdObj->GetSuperObjectFirstChild();
	while (pEdChild)
	{
		// next level of the hierarchy
		fn_vFillListForMove((EDT_SuperObject *)pEdChild);
		// next brother
		pEdChild = pEdObj->GetSuperObjectNextChild(pEdChild);
	}
}

/*===========================================================================
		Init Modif Move
=========================================================================*/
void EDT_ModifState::fn_vRegisterPositions (void)
{
	EDT_SaveGlobalPos	*pElem1;
	EDT_SavePos			*pElem;
	POSITION			pos, pos1;

	// update the list of selected objects
	for (pElem = m_stPosForTools.m_stListObjects.GetHeadElement(pos); pElem;
		 pElem = m_stPosForTools.m_stListObjects.GetNextElement(pos))
	{
		// register final position
		pElem->m_hFinalMatrix = M_EDT_AllocMatrix();
		GEO_M_vCopyMatrix(pElem->m_hFinalMatrix, HIE_fn_hGetSuperObjectMatrix(pElem->m_pObject->GetStruct()));
	}

	// update the list of concerned objects
	for (pElem1 = m_stPosForTools.m_stListConcerned.GetHeadElement(pos1); pElem1;
		 pElem1 = m_stPosForTools.m_stListConcerned.GetNextElement(pos1))
	{
		// register final position
		pElem1->m_hFinalGlobalMatrix = M_EDT_AllocMatrix();
		GEO_M_vCopyMatrix(pElem1->m_hFinalGlobalMatrix, HIE_fn_hGetSuperObjectGlobalMatrix(pElem1->m_pObject->GetStruct()));
	}
}


/*===========================================================================
		Message Create
=========================================================================*/
void EDT_ModifState::fn_vSendMessageCreate (tdeTypeModif eType)
{
	CPA_ObjectDLLBase	*pDLLObject;
	CPA_ToolDLLBase		*pDLLTool;
	POSITION			pos;
		
	// Current Editor
	if (!M_IsCurrentEditor())
		M_GetCurrentEditor()->fn_vOnModifInsert(m_pModifiedObject, m_pFinalParent, NULL, eType, C_AsCurrentEditor);
	//  corresponding DLL
	if (m_pModifiedObject->GetObjectDLL())
		m_pModifiedObject->GetObjectDLL()->fn_vOnModifInsert(m_pModifiedObject, m_pFinalParent, NULL, eType, C_AsConcernedDLL);
	// if necessary, owner DLL
	if (m_pModifiedObject->GetSuperObjectOwner())
	{
		pDLLObject = m_pModifiedObject->GetSuperObjectOwner()->GetObjectDLL();
		pDLLObject->fn_vOnModifInsert(m_pModifiedObject, m_pFinalParent, NULL, eType, C_AsChildOwner);
	}
	// Tool DLLs
	for (pDLLTool = M_GetToolDLLs()->GetHeadElement(pos); pDLLTool;
		 pDLLTool = M_GetToolDLLs()->GetNextElement(pos))
	{
		if (pDLLTool != M_GetCurrentEditor())
			pDLLTool->fn_vOnModifInsert(m_pModifiedObject, m_pFinalParent, NULL, eType, C_AsToolDLL);
	}
}


/*===========================================================================
		Message Remove
=========================================================================*/
void EDT_ModifState::fn_vSendMessageDelete (tdeTypeModif eType)
{
	CPA_ToolDLLBase	 *pDLLTool;
	EDT_ParentByType *pList;
	POSITION		 pos;
	
	// current editor
	if (!M_IsCurrentEditor())
		M_GetCurrentEditor()->fn_vOnModifDelete(&m_stParentForTools, eType, C_AsCurrentEditor);
	// corresponding DLLs
	for (pList = m_lstParentByType.GetHeadElement(pos); pList;
		 pList = m_lstParentByType.GetNextElement(pos))
	{
		if (pList->m_stListObjects.GetCount())
			pList->m_poDLL->fn_vOnModifDelete(&pList->m_stListObjects, eType, C_AsConcernedDLL);
	}
	// owner DLLs
	for (pList = m_lstParentByType.GetHeadElement(pos); pList;
		 pList = m_lstParentByType.GetNextElement(pos))
	{
		if (pList->m_stListProtected.GetCount())
			pList->m_poDLL->fn_vOnModifDelete(&pList->m_stListProtected, eType, C_AsChildOwner);
	}
	// Tool DLLs
	for (pDLLTool = M_GetToolDLLs()->GetHeadElement(pos); pDLLTool;
		 pDLLTool = M_GetToolDLLs()->GetNextElement(pos))
	{
		if (pDLLTool != M_GetCurrentEditor())
			pDLLTool->fn_vOnModifDelete(&m_stParentForTools, eType, C_AsToolDLL);
	}
}


/*===========================================================================
		Message
=========================================================================*/
void EDT_ModifState::fn_vSendMessageParent (tdeTypeModif eType)
{
	CPA_ObjectDLLBase	*pDLLObject;
	CPA_ToolDLLBase		*pDLLTool;
	POSITION			pos;
	
	// Current Editor
	if (!M_IsCurrentEditor())
		M_GetCurrentEditor()->fn_vOnModifParent(&m_stParentForTools, eType, C_AsCurrentEditor);
	// tell the corresponding DLL
	if (m_pModifiedObject->GetObjectDLL())
		m_pModifiedObject->GetObjectDLL()->fn_vOnModifParent(&m_stParentForTools, eType, C_AsConcernedDLL);
	// if necessary, tell owner
	if (m_pModifiedObject->GetSuperObjectOwner())
	{
		pDLLObject = m_pModifiedObject->GetSuperObjectOwner()->GetObjectDLL();
		pDLLObject->fn_vOnModifParent(&m_stParentForTools, eType, C_AsChildOwner);
	}
	// Tool DLLs
	for (pDLLTool = M_GetToolDLLs()->GetHeadElement(pos); pDLLTool;
		 pDLLTool = M_GetToolDLLs()->GetNextElement(pos))
	{
		if (pDLLTool != M_GetCurrentEditor())
			pDLLTool->fn_vOnModifParent(&m_stParentForTools, eType, C_AsToolDLL);
	}
}

/*===========================================================================
		Message
=========================================================================*/
void EDT_ModifState::fn_vSendMessageMove (tdeTypeModif eType)
{
	CPA_ToolDLLBase	*pDLLTool;
	EDT_PosByType	*pListPos;
	POSITION		pos;
	
	if (!M_IsCurrentEditor())
		M_GetCurrentEditor()->fn_vOnModifMove(&m_stPosForTools.m_stListObjects, &m_stPosForTools.m_stListConcerned, eType, C_AsCurrentEditor);
	// object DLLs
	for (pListPos = m_lstPosByType.GetHeadElement(pos); pListPos;
		 pListPos = m_lstPosByType.GetNextElement(pos))
	{
		if (pListPos->m_stListConcerned.GetCount())
			pListPos->m_poDLL->fn_vOnModifMove(&pListPos->m_stListObjects, &pListPos->m_stListConcerned, eType, C_AsConcernedDLL);
	}
	// owner DLLs
	for (pListPos = m_lstPosByType.GetHeadElement(pos); pListPos;
		 pListPos = m_lstPosByType.GetNextElement(pos))
	{
		if (pListPos->m_stListProtectConcerned.GetCount())
			pListPos->m_poDLL->fn_vOnModifMove(&pListPos->m_stListProtected, &pListPos->m_stListProtectConcerned, eType, C_AsChildOwner);
	}
	// Tool DLLs
	for (pDLLTool = M_GetToolDLLs()->GetHeadElement(pos); pDLLTool;
		 pDLLTool = M_GetToolDLLs()->GetNextElement(pos))
	{
		if (pDLLTool != M_GetCurrentEditor())
			pDLLTool->fn_vOnModifMove(&m_stPosForTools.m_stListObjects, &m_stPosForTools.m_stListConcerned, eType, C_AsToolDLL);
	}
}

/*===========================================================================
		Message Name
=========================================================================*/
void EDT_ModifState::fn_vSendMessageName (tdeTypeModif eType)
{
	CPA_ObjectDLLBase	*pDLLObject;
	CPA_ToolDLLBase		*pDLLTool;
	POSITION			pos;
		
	// for current editor
	if (!M_IsCurrentEditor())
		M_GetCurrentEditor()->fn_vOnModifName(m_pModifiedObject, m_csInitialName, m_csFinalName, eType, C_AsCurrentEditor);
	// tell the corresponding DLL
	if (m_pModifiedObject->GetObjectDLL())
		m_pModifiedObject->GetObjectDLL()->fn_vOnModifName(m_pModifiedObject, m_csInitialName, m_csFinalName, eType, C_AsConcernedDLL);
	// if necessary, tell owner
	if (m_pModifiedObject->GetSuperObjectOwner())
	{
		pDLLObject = m_pModifiedObject->GetSuperObjectOwner()->GetObjectDLL();
		pDLLObject->fn_vOnModifName(m_pModifiedObject, m_csInitialName, m_csFinalName, eType, C_AsChildOwner);
	}
	// Tool DLLs
	for (pDLLTool = M_GetToolDLLs()->GetHeadElement(pos); pDLLTool;
		 pDLLTool = M_GetToolDLLs()->GetNextElement(pos))
	{	
		if (pDLLTool != M_GetCurrentEditor())
			pDLLTool->fn_vOnModifName(m_pModifiedObject, m_csInitialName, m_csFinalName, eType, C_AsToolDLL);
	}	
}



//#################################################################################
// Class ModifValidate
//#################################################################################

/*===========================================================================
		Constructor 
=========================================================================*/
EDT_ModifValidate::EDT_ModifValidate (EDT_HierarchyEditor *pEditor, EDT_SuperObject *pModifiedObject, CString csTypeModif, BOOL bInitialState)
		: CPA_Modif(TYPE_VALIDATE, "Validate", FALSE)
{
	// init parameters
	m_pEditor = pEditor;
	m_pModifiedObject = pModifiedObject;
	m_csTypeModif = csTypeModif;
	m_bInitialState = bInitialState;
	m_bFirstTime = TRUE;

	m_pModifState = new EDT_ModifState(pEditor, pModifiedObject, csTypeModif, bInitialState);

	m_pTempModif = m_pModifiedObject->GetTemporaryModif();
	m_bCreated = m_pTempModif->fn_bWasCreated();
	m_bDeleted = m_pTempModif->fn_bWasDeleted();
	//CPA2 Stegaru Cristian 98-02
	//m_csOriginalName = m_pTempModif->GetOriginalName();
	//m_pOriginalFather = m_pTempModif->GetOriginalFather();
	//m_hOriginalPosition = m_pTempModif->GetOriginalPosition();

}

/*===========================================================================
		Destructor
=========================================================================*/
EDT_ModifValidate::~EDT_ModifValidate (void)
{
}


/*===========================================================================
		Interface
=========================================================================*/
CPA_Interface * EDT_ModifValidate::GetInterface (void)
{
	return GetParentEditor()->GetInterface();
}


/*===========================================================================
		Do
=========================================================================*/
BOOL EDT_ModifValidate::Do (void)
{
	// cancel current selection
	GetInterface()->fn_vCancelCurrentSelection(FALSE);

	// do modif
	m_pModifState->Do();
	
	// validate final result 
	if (m_csTypeModif == C_szCreation)
		m_pTempModif->SetCreated(FALSE);
	// suppression
	else if (m_csTypeModif == C_szSuppression)
		m_pTempModif->SetDeleted(FALSE);

	// father
	else if (m_csTypeModif == C_szChangeFather)
		//CPA2 Stegaru Cristian 98-02
		;//m_pTempModif->SetOriginalFather((EDT_SuperObject *) m_pModifiedObject->GetSuperObjectFather());
		

	// position
	else if (m_csTypeModif == C_szChangePosition)
		//CPA2 Stegaru Cristian 98-02
		;//m_pTempModif->SetOriginalPosition(HIE_fn_hGetSuperObjectMatrix(m_pModifiedObject->GetStruct()));


	// name
	else if (m_csTypeModif == C_szChangeName)
		//CPA2 Stegaru Cristian 98-02
		;//m_pTempModif->SetOriginalName(m_pModifiedObject->GetName());

	// test modification
	if (!m_pTempModif->fn_bIsModified(""))
	{
		m_pModifiedObject->SetTemporaryModif(NULL);
		m_pModifiedObject->fn_vUpdateModification(m_csTypeModif, FALSE, m_bInitialState);
		GetInterface()->fn_vUpdateAll(E_mc_UpdateDialog);
	}

	// update parameters
	m_bFirstTime = FALSE;
	return TRUE;
}


/*===========================================================================
		Undo
=========================================================================*/
BOOL EDT_ModifValidate::Undo (void)
{
	// cancel current selection
	GetInterface()->fn_vCancelCurrentSelection(FALSE);

	// validate final result 
	if (m_csTypeModif == C_szCreation)
		m_pTempModif->SetCreated(m_bCreated);
	// suppression
	else if (m_csTypeModif == C_szSuppression)
		m_pTempModif->SetDeleted(m_bDeleted);

	// father
	else if (m_csTypeModif == C_szChangeFather)
		//CPA2 Stegaru Cristian 98-02
		;//m_pTempModif->SetOriginalFather(m_pOriginalFather);

	// position
	else if (m_csTypeModif == C_szChangePosition)
		//CPA2 Stegaru Cristian 98-02
		;//m_pTempModif->SetOriginalPosition(m_hOriginalPosition);

	// name
	else if (m_csTypeModif == C_szChangeName)
		//CPA2 Stegaru Cristian 98-02
		;//m_pTempModif->SetOriginalName(m_csOriginalName);

	// test modification
	m_pModifiedObject->SetTemporaryModif(m_pTempModif);
	m_pModifiedObject->fn_vUpdateModification(m_csTypeModif, TRUE, m_bInitialState);

	// undo modif
	m_pModifState->Undo();

	// update temporary modif
	GetInterface()->fn_vUpdateAll(E_mc_UpdateDialog);

	return TRUE;
}


#endif