//*****************************************************************************
//*  _zInterf.cpp                                                             *
//*****************************************************************************
//*                                                                           *
//* This file contains all the functions of the ZDx_Interface class           *
//* which is the base class of the dll interface                              *
//*                                                                           *
//*****************************************************************************
//* Author : Alexis Vaisse                                                    *
//*****************************************************************************


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

#include "TFA.h"        // Family dll include

#define HieFriend
#include "IncGAM.h"
#include "DPT.h"
#include "..\Main\Inc\_EditID.h"

// personal include
//ROMTEAM WorldEditor (Cristi Petrescu 12/12/97)
#include "ozo.h"
//#include "Ozo\_zQuery.hpp"
//ENDROMTEAM WorldEditor (Cristi Petrescu)
#include "_zInterf.hpp"
#include "_zObject.hpp"
#include "_zModif.hpp"
#include "_zWEdit.hpp"
#include "_zWList1.hpp"
#include "_zWList2.hpp"

#include "OGD.h"        // 3dGeom dll include
#include "OAC.h"        // Actors dll include
#include "OPD.h"        // Physical Object dll include
#include "TUT.h"        // Tutorial dll include

//CPA2 Stegaru Cristian 98-06
#include "..\inc\checkzones.h"
//End CPA2 Stegaru Cristian 98-06

class EdActors_EditorActorInstance;
class EdActors_EditorActorModel;
class CPA_Family;


// infos
static CString g_csOZOName = "Zone";
static CString g_csOZOAuthor = "Alexis Vaisse";
static CString g_csOZOVersion = "V 5.0.2   31/03/99";
static CString g_csOZOFrenchHelpFile = "Zone.hlp";
static CString g_csOZOEnglishHelpFile = "Zdd_Us.hlp";

BOOL g_bTipFirstTime = TRUE;

//-----------------------------------------------------------------------------
// Global variables
//-----------------------------------------------------------------------------

#define ID_ZDxMenuEditor                1                  // Private ID for entry in menu
#define ID_ZDxMenuPreference            2
#define ID_ZDxMenuEditGlobalZone        3
#define ID_ZDxMenuEditModuleZone        4
#define ID_ZDxMenuShowGlobalZone        5
#define ID_ZDxMenuHideGlobalZone        6
#define ID_ZDxMenuShowModuleZone        7
#define ID_ZDxMenuHideModuleZone        8
#define ID_ZDxMenuShowZoneOfOneModule   9
#define ID_ZDxMenuHideZoneOfOneModule  10
#define ID_ZDxMenuShowZoneOfAllModule  11
#define ID_ZDxMenuHideZoneOfAllModule  12
#define ID_ZDxMenuLeave                13

//Stefan Dumitrean 8-07-98 ( zone types )
#define NumberOfZDxModels               3
//End Stefan Dumitrean 8-07-98 ( zone types )

#define C_szActorZDxFileExtension       ".ZDx"          // Extension of the file for the ZDx of actor
#define C_szModuleZDxFileExtension      ".Zoo"          // Extension of the file for the ZDx of module
#define C_szBoundingVolumeFileExtension ".Bdv"          // Extension of the file for the bounding volume


typedef struct stZDxModel
{
    char *               szZDxModelName;
    char *               szBitmapName;
    tdeZDxGeometricType  eZDxGeometricType;
} tdstZDxModel;

// List of models
const tdstZDxModel ListOfZDxModels [NumberOfZDxModels] =
{
    {"Sphere" , "Objects\\Zdd\\zSphere.bmp" , eSphere } ,
    {"Box"    , "Objects\\Zdd\\zBox.bmp"    , eBox    } ,
//Stefan Dumitrean 8-07-98 ( zone types )
//  {"Point"  , "Objects\\Zdd\\zPoint.bmp"  , ePoint  } ,
//End Stefan Dumitrean 8-07-98 ( zone types )
    {"Cone"   , "Objects\\Zdd\\zCone.bmp"   , eCone   }
};


// the dll global definition
tdstDLLIdentity	         g_stZDxDllIdentity;

// Keyboard configuration

#define C_szZDxIniFileName    "Objects\\Zdd\\Zdd.ini"

#define KA_CHANGE_ZDX_SIZE    1
//CPA2 (Corneliu Babiuc) 13-04-97
#define KA_MOVE_ONLY_ACTOR    2
//END CPA2 (Corneliu Babiuc) 13-04-97

static tdstKeyboardActionDef  gs_a_stZDxKeys [] =
{
    {"ChangeZoneSize" , KA_CHANGE_ZDX_SIZE},
//CPA2 (Corneliu Babiuc) 13-04-97
	{"MoveOnlyActor" ,  KA_MOVE_ONLY_ACTOR},
//END CPA2 (Corneliu Babiuc) 13-04-97
    {NULL , 0}
};
//CPA2 Corneliu Babiuc 30-04-98
static BOOL gbMoveWasOnlyActor;
//END CPA2 Corneliu Babiuc 30-04-98

#include "_zInterf.inc"    // Internal functions of the ZDx_Interface class


//-----------------------------------------------------------------------------
// Class ZDx_Interface - Constructor
// Here are all the DLL interface properties
//-----------------------------------------------------------------------------
ZDx_Interface::ZDx_Interface (void)
{
    // Identity of the DLL
    m_p_stDLLIdentity = & g_stZDxDllIdentity;

    // Can the DLL output in main game view ?
	m_stBaseDLLDefinition.bCanOutputIn3DView = FALSE;

    // Can the DLL be refreshed by engine ?
	m_stBaseDLLDefinition.bCanBeRefreshedByEngine = FALSE;

    SetEditorInfo(g_csOZOName, g_csOZOAuthor, g_csOZOVersion, g_csOZOFrenchHelpFile, g_csOZOEnglishHelpFile);

    // Init the variables
    SetCurrent (FALSE);
    m_bSizeKeyPressed                  = FALSE;
//CPA2 (Corneliu Babiuc) 13-04-1997
	m_bMoveOnlyActorKeyPressed         = FALSE;
	m_bMoveOnlyActor                   = FALSE;
//CPA2 (Corneliu Babiuc) 13-04-1997
    m_bMoveHasBegun                    = FALSE;
    m_stSizeChangingMode . bActiveMode = FALSE;
    m_bIsSelectingObject               = FALSE;
    m_bIsAskingToSelectObject          = FALSE;
    m_bIsShowingOrHidingZDx            = FALSE;
    m_bIsInsertingZDxObject            = FALSE;
    m_bIsDeletingZDxObject             = FALSE;
    m_bIsInsideOnModifInsertDelete     = FALSE;
    m_bAskToEditModuleZone             = FALSE;
    m_pActorSuperObjectToUnselect      = NULL;
    m_pModuleSuperObjectToUnselect     = NULL;
    m_lRefreshDisplayCallerID          = 0;
//ANNECY TQ 18/06/98{
	m_GlobalBoundingVolume				= GEO_fn_hCreateGeometricSphere();
//ENDANNECY TQ}
	m_stSizeChangingMode.pZDxModif = NULL;
}


//*****************************************************************************
//     Virtual functions of the base class : general functions for editor
//*****************************************************************************


//-----------------------------------------------------------------------------
// Class ZDx_Interface - fn_vJustAfterRegistered
// This function is called for the first initializations
//-----------------------------------------------------------------------------
void ZDx_Interface::fn_vJustAfterRegistered (void)
{
    // Register the ZDx object type
// ANNECY AV CLEAN_MEC {
    CString Name [/* 6 */ 5] = { C_szZddName , C_szZdeName , C_szZdmName , C_szZdrName , C_szBoundingVolumeName /* , C_szTestPointName */ };
    fn_vRegisterObjectsType (Name , /* 6 */ 5);
// END ANNECY AV }
    
    // Init the keyboard
    m_pZDxKeyActionConfiguration = new CPA_KeyActionConfiguration (C_szZDxIniFileName , gs_a_stZDxKeys);
    m_pZDxKeyActionConfiguration -> mfn_vSetObjectName ("Zone Editor");
}

//-----------------------------------------------------------------------------
// Class ZDx_Interface - fn_vConstruct
// Fonction called at the end of the initialization of the program
// we create the ZDx info window (here because the main window must be initialized)
//-----------------------------------------------------------------------------
void ZDx_Interface::fn_vConstruct (void)
{

#ifndef __INACTIVE_INTERFACE__

    // We want the resources to be searched into the DLL and not into the program
    HINSTANCE hOldInst = AfxGetResourceHandle ();
    AfxSetResourceHandle (GetDLLIdentity () -> hModule);

    // Look into .INI file
    CString csFileName = M_GetMainApp () -> m_csEditorDataPath + "Objects\\Zdd\\Zdd.ini";
	char szFrameWidth [256];
	GetPrivateProfileString ("Preference" , "Frame Width" , "228" , szFrameWidth , 256 , (char *) (LPCSTR) csFileName);

    // Create a splitter frame
    m_pSplitFrame = new CSplitFrame;
    m_pSplitFrame -> CreateBase         ("ZDx LIST FRAME" , 1 , 2 , GetMainWorld ());  // Col=1, Row=2
    m_pSplitFrame -> mfn_vEnableCaption (FALSE);
    m_pSplitFrame -> CreateSplitter     (C_cVerticalSplitter , 4);
    m_pSplitFrame -> m_iInitWidth = atoi (szFrameWidth);

    // Register the frame to the tutorial
    TUT_M_vGetTutDll ();
    TUT_M_vRegisterControl (m_pSplitFrame -> m_hWnd , "TUT_FrameBase" , TUT_e_Window);

    // Get the size of the screen
    RECT FrameSize;
    ::GetClientRect (GetDesktopWindow () , & FrameSize);
    long Width = FrameSize . bottom - 32;

    // Create the four views
    m_pSplitFrame -> CreateView     (1 , RUNTIME_CLASS (CDisplayControlWindow) , "Display control" , 104);
    m_pSplitFrame -> CreateView     (3 , RUNTIME_CLASS (CZDxInfoWindow       ) , "Zone edit"       , 275);
    m_pSplitFrame -> CreateView     (0 , RUNTIME_CLASS (CList1Window         ) , "General list"    , (Width - 104 - 275) * 55 / 100);
    m_pSplitFrame -> CreateView     (2 , RUNTIME_CLASS (CList2Window         ) , "Zones list"      , (Width - 104 - 275) * 45 / 100);

    // Get the adresses of the windows and store them
    m_pDisplayControlWindow = (CDisplayControlWindow *) m_pSplitFrame -> m_fn_p_oGetPane (1);
    m_pList1Window          = (CList1Window          *) m_pSplitFrame -> m_fn_p_oGetPane (0);
    m_pList2Window          = (CList2Window          *) m_pSplitFrame -> m_fn_p_oGetPane (2);
    m_pEditWindow           = (CZDxInfoWindow        *) m_pSplitFrame -> m_fn_p_oGetPane (3);

    m_pDisplayControlWindow -> SetZDxInterface (this);
    m_pList1Window          -> SetZDxInterface (this);
    m_pList2Window          -> SetZDxInterface (this);

    AfxSetResourceHandle (hOldInst);

#endif  // __INACTIVE_INTERFACE__

    // Init the ZDx objects
    ZDx_Object::InitZDxObject ();
}

//-----------------------------------------------------------------------------
// Class ZDx_Interface - fn_vBeforeEditor ()
// This function is called just before entering editor mode
//-----------------------------------------------------------------------------
void ZDx_Interface::fn_vBeforeEditor ()
{
    // If we are the current editor, we open the windows
    if (fn_bIsCurrentEditor ())
    {
        CPA_SuperObject * pSelectedActorSuperObject = GetSelectedActorSuperObject ();
        if (! pSelectedActorSuperObject)  pSelectedActorSuperObject = m_pList2Window -> GetActorSuperObject ();
        if (pSelectedActorSuperObject)
            ShowZDxOfActor (pSelectedActorSuperObject , m_pList2Window -> GetZDxTypeToShow () , m_pList2Window -> GetSelectedZDx ());

        g_oFrameGest . mfn_vActivateWindow (m_pSplitFrame);
        g_oFrameGest . mfn_vActivateWindow (GetInterface () -> GetModelFrame ());
    }
}

//-----------------------------------------------------------------------------
// Class ZDx_Interface - fn_vBeforeEngine ()
// This function is called just before leaving editor mode
//-----------------------------------------------------------------------------
void ZDx_Interface::fn_vBeforeEngine ()
{
    m_pEditWindow -> Apply ();		// clic on the Apply button

    // If we are the current editor, we close the windows
    if (fn_bIsCurrentEditor ())
    {
        if (m_pList1Window -> IsEditingBoundingVolume ())  m_pList1Window -> LeaveEditionOfBoundingVolume ();
// ANNECY AV CLEAN_MEC {
//        else
//        if (m_pList1Window -> IsEditingTestPoint      ())  m_pList1Window -> LeaveEditionOfTestPoint      ();
// END ANNECY AV }

        CPA_SuperObject * pSelectedActorSuperObject = GetSelectedActorSuperObject ();
        if (! pSelectedActorSuperObject)  pSelectedActorSuperObject = m_pList2Window -> GetActorSuperObject ();
        if (pSelectedActorSuperObject)
        {
            CPA_Actor * pSelectedActor = (CPA_Actor *) pSelectedActorSuperObject -> GetObject ();
            if (pSelectedActor)
            {
                unsigned char ucZDxToShow;
                tdeDisplayType eDisplayForAllActors = m_pDisplayControlWindow -> GetDisplayForAllActors ();
                switch (eDisplayForAllActors)
                {
                    case eNoZone     :
                    case eOff      : ucZDxToShow = C_ucHideAllZDx;    break;
                    case eOn       : ucZDxToShow = C_ucShowAllZDx;    break;
                    case eSelected : if (pSelectedActor -> GetDisplayZone ())  ucZDxToShow = C_ucShowAllZDx;
                                                                         else  ucZDxToShow = C_ucHideAllZDx;
                                     break;
                }
                ShowZDxOfActor (pSelectedActorSuperObject , ucZDxToShow , NULL ,
                                eDisplayForAllActors == eSelected ? (int) pSelectedActor -> GetDisplayZone () == 2 : FALSE);
            }
        }

        g_oFrameGest.mfn_vDisactivateWindow (m_pSplitFrame);
    }
}

//-----------------------------------------------------------------------------
// Class ZDx_Interface - fn_vOnActivateEditor
// This function is called when somebody wants to open the ZDx editor
//-----------------------------------------------------------------------------
void ZDx_Interface::fn_vOnActivateEditor (CPA_List<CPA_BaseObject> * pSelectedObjectList , BOOL bBackActivated /* = FALSE */)
{
    // Get the given super object, if any
    POSITION Pos;
    CPA_SuperObject * pSelectedSuperObject = pSelectedObjectList
                                             ? (CPA_SuperObject*) pSelectedObjectList -> GetHeadElement (Pos)
                                             : NULL;
    // If no given super object, get the first selected super object
    if (! pSelectedSuperObject)  pSelectedSuperObject = GetInterface () -> GetCurrentWorld () -> GetListSelected () -> GetHeadElement (Pos);

    CPA_ToolDLLBase * pT3DDll = GetMainWorld () -> GetToolDLLWithName (C_szDLLTool3DName);
    if (pT3DDll)
    {
        // Check if the grid is displayed
        long lTypeOfDisplay = pT3DDll -> OnQueryInfos (this , C_wTool3D_QI_GetState , 0);
        if (lTypeOfDisplay == C_wTool3D_Mod_Object || lTypeOfDisplay == C_wTool3D_Mod_List ||
            lTypeOfDisplay == C_wTool3D_Table)
        {
            m_bAskToEditModuleZone = TRUE;
            // Get the displayed actor
            CPA_World       * pWorld           = (CPA_World *) pT3DDll -> OnQueryInfos (this , C_wTool3D_QI_GetWorld , NULL);
            CPA_SuperObject * pRoot            = pWorld ? pWorld -> GetRoot () : NULL;
            CPA_SuperObject * pGridSuperObject = (CPA_SuperObject *) (pRoot ? pRoot -> GetHeadElement () : NULL);

            if (pGridSuperObject)  pSelectedSuperObject = pGridSuperObject;    // Ne marche pas ???
        }
    }

    if (pSelectedSuperObject)  fn_vOnSelect (pSelectedSuperObject , C_EDTDo , C_AsCurrentEditor);

    // Add the models of ZDx into the model window and show them
    AddModelOfZDx ();
    GetInterface () -> GetDialogInsert () -> fn_vSetCurrentListModel (C_szZDxListName);

    // If one asks to edit the zones of module, and if there is an instance to edit, we open the list of modules
    if (m_bAskToEditModuleZone && m_pList1Window -> GetSelectedActor ())
        m_pList1Window -> CreateListOfModule (m_pList1Window -> GetSelectedActorSuperObject ());
    m_bAskToEditModuleZone = FALSE;

    // show the editor window and the model window
	g_oFrameGest . mfn_vActivateWindow (m_pSplitFrame);
    g_oFrameGest . mfn_vActivateWindow (GetInterface () -> GetModelFrame ());

	// display Tip of the Day
	GetInterface()->fn_vDisplayTipOfDay("Zones", "OZO", g_bTipFirstTime);
	g_bTipFirstTime = FALSE;
}

//-----------------------------------------------------------------------------
// Class ZDx_Interface - fn_vOnCloseEditor
// This function is called when somebody wants to close the ZDx editor
//-----------------------------------------------------------------------------
void ZDx_Interface::fn_vOnCloseEditor (void)
{
    m_pEditWindow -> Apply ();                                 // We clic on the Apply button of the window

    // Remove the models of ZDx from the model window
    GetInterface () -> GetDialogInsert () -> fn_vSetCurrentListModel ("All Types");
    RemoveModelOfZDx ();

    // If we are editing the ZDx of module, we close the T3D grid
    if (m_pList1Window -> IsEditingZDxOfModule ())  m_pList1Window -> CreateListOfFamily ();

    if (m_pList1Window -> IsEditingBoundingVolume ())  m_pList1Window -> LeaveEditionOfBoundingVolume ();
// ANNECY AV CLEAN_MEC {
//    else
//    if (m_pList1Window -> IsEditingTestPoint      ())  m_pList1Window -> LeaveEditionOfTestPoint      ();
// END ANNECY AV }

    // We show or hide the ZDx of the selected actor
    CPA_SuperObject * pSelectedActorSuperObject = GetSelectedActorSuperObject ();
    if (! pSelectedActorSuperObject)  pSelectedActorSuperObject = m_pList2Window -> GetActorSuperObject ();
    if (pSelectedActorSuperObject)
    {
        CPA_Actor * pSelectedActor = (CPA_Actor *) pSelectedActorSuperObject -> GetObject ();
        if (pSelectedActor)
        {
            unsigned char ucZDxToShow;
            tdeDisplayType eDisplayForAllActors = m_pDisplayControlWindow -> GetDisplayForAllActors ();
            switch (eDisplayForAllActors)
            {
                case eNoZone     :
                case eOff      : ucZDxToShow = C_ucHideAllZDx;    break;
                case eOn       : ucZDxToShow = C_ucShowAllZDx;    break;
                case eSelected : if (pSelectedActor -> GetDisplayZone ())  ucZDxToShow = C_ucShowAllZDx;
                                                                     else  ucZDxToShow = C_ucHideAllZDx;
                                 break;
            }
            ShowZDxOfActor (pSelectedActorSuperObject , ucZDxToShow , NULL ,
                            eDisplayForAllActors == eSelected ? (int) pSelectedActor -> GetDisplayZone () == 2 : FALSE);
        }
    }
}

//-----------------------------------------------------------------------------
// Class ZDx_Interface - fn_vHasGainFocus
// This function is called when the dll becomes the current dll
//-----------------------------------------------------------------------------
BOOL ZDx_Interface::fn_bHasGainedFocus (void)
{
    // Refresh the list
    m_pList1Window -> ReCreateCurrentList ();

	return TRUE;
}

//-----------------------------------------------------------------------------
// Class ZDx_Interface - fn_vHasLostFocus
// This function is called when the dll is no longer the current dll
//-----------------------------------------------------------------------------
void ZDx_Interface::fn_vHasLostFocus (void)
{
    // If the editor is open, we close it
    if (fn_bIsCurrentEditor ())  GetMainWorld () -> fn_bCloseEditor (this);
}

//-----------------------------------------------------------------------------
// Class ZDx_Interface - OnQueryAction
// To communicate with the dll
//-----------------------------------------------------------------------------
long ZDx_Interface::OnQueryAction (CPA_EditorBase * pCallingDll , WPARAM wParam , LPARAM lParam)
{
    switch (wParam)
    {
        case C_uiQueryCreateZDxObject     : return (long) CreateZdxObject (lParam);

// ANNECY AV CLEAN_MEC {
        case C_uiQueryCreateZDxTestPoints : //CreateZdxTestPoints ((CPA_TestPointsList *) lParam);
// END ANNECY AV }
                                            return 0;
//ROMTEAM WorldEditor (Cristi Petrescu 12/97)
		case C_uiQueryTypeOfZoneByGeometricObject:
											return m_lGetTypeOfZoneByGeometricObject ((Geometry3D *) lParam);
//ENDROMTEAM WorldEditor (Cristi Petrescu)
        //CPA2 Stegaru Cristian 98-04
		case C_uiQueryCreateBoundingVolumeObject	: 
					{
						ZDx_Object *pObject = CreateZdxObject (lParam);
						ASSERT (pObject);
						Shape3D   *pShape = (Shape3D *)pObject->GetZDxShape ()->GetGeometric3dObject ();
						if (((Sphere3D *)pShape)->GetRadius() <= 0)
						{
							GLI_tdxValue     fRadius = 1.0f;
							((Sphere3D *)pShape)->SetRadius(&fRadius);
							((Sphere3D *)pShape)->SetCenterX(0.0f);
							((Sphere3D *)pShape)->SetCenterY(0.0f);
							((Sphere3D *)pShape)->SetCenterZ(0.0f);
						}
						pShape->SetExistingSection (FALSE);
						CString csElementSectionName = pShape->GetReferencedSectionName ();
						int iFileDelimitInx = csElementSectionName.Find (SCR_CC_c_Cfg_NameSeparator);
						ASSERT (-1 != iFileDelimitInx);
						CString csElementFile = csElementSectionName.Left (iFileDelimitInx + 1);
						int iSectionDelimInx = csElementSectionName.Find (SCR_CC_c_Cfg_SectionIdMark);
						ASSERT (-1 != iSectionDelimInx);
						CString csSectionName = csElementSectionName.Mid (iSectionDelimInx);
						csSectionName += "Element00";
						csElementSectionName.Empty ();
						csElementSectionName = csElementFile + "ElementSpheres";
						csElementSectionName += csSectionName;
						pShape->mfn_vInitElement ((char*)(LPCTSTR)csElementSectionName, pShape->GetDataPath ());
						pObject->fn_vNotifySave ();
						return (long)pObject; 
					}
		case C_uiQueryCheckZonesAgainstBV:
			{
				mfn_vCheckActorsZonesAndBV ((CPA_SuperObject *)lParam);
				return 0;
			}
		//End CPA2 Stegaru Cristian 98-04
//CPA2 Corneliu Babiuc 24-04-1998
		case C_uiQueryActorWasMoved:
			//if is not the current editor does nothing
			if ( !fn_bIsCurrentEditor() || !gbMoveWasOnlyActor) return 0;
			// in this case LPARAM parameter is a pointer to a tdstMoveZoneMess structure
			tdstMoveZoneMess * pstZoneMess = (tdstMoveZoneMess *) lParam;

			// We look for all ZDx children of the actors :
			// For each ZDx, we will set its translation vesctor 
			CPA_SuperObject * pSuperObject =  pstZoneMess->pActorSuperObject->GetSuperObjectFirstChild ();
			CPA_SuperObject * pNextChild;
			while (pSuperObject)
			{
				pNextChild = pstZoneMess->pActorSuperObject->GetSuperObjectNextChild (pSuperObject);
				// No object or not a ZDx -> go to the next child
				CPA_BaseObject * pObject = pSuperObject -> GetObject ();
				if (pObject == NULL || ! M_bIsThisObjectAZDx (pObject))
				{
					pSuperObject = pNextChild;
					continue;
				}

				//set the translation vector 
				MoveBackZone(pSuperObject, &(pstZoneMess->stTranslation));
				//refresh geometric data
				ZDx_Object * pZDxObject = (ZDx_Object *) pSuperObject->GetObject();
				pZDxObject -> GetZDxShape () -> RefreshData (pSuperObject);
// ANNECY AV CLEAN_MEC {
//				if (pZDxObject -> GetZDxType () == eTestPoint)  m_pList2Window -> GetListOfTestPoint () -> fn_vNotifySave ();
//														   else pZDxObject                              -> fn_vNotifySave ();
pZDxObject -> fn_vNotifySave ();
// END ANNECY AV }
				pSuperObject = pNextChild;
			}
			return 0;
//END CPA2 Corneliu Babiuc 27-04-1998
	}

    if (wParam == C_uiQueryEditAnObject || wParam == C_uiQueryEditAnObjectList || wParam == C_uiQueryAnObjectHasBeenChanged
		//CPA2 Stegaru Cristian 98-04
		|| C_uiQueryEditBoundingVolume == wParam)
		//End CPA2 Stegaru Cristian 98-04
    {
        tdstEdtListMess             * pEdtListMess      = (tdstEdtListMess *) lParam;
        CPA_BaseObject              * pActorSuperObject = pEdtListMess -> pActor;
        tdeZDxType                    eZDxType          = ConvertListTypeToZDxType (pEdtListMess -> csListType);
        CPA_List<CPA_BaseObject> ListOfObject;
        if (pActorSuperObject)  ListOfObject . AddTail (pActorSuperObject);

        switch (wParam)
        {
        case C_uiQueryEditAnObject           : GetMainWorld () -> fn_bActivateEditor (this , & ListOfObject);
                                               return 0;

        case C_uiQueryEditAnObjectList       : GetMainWorld () -> fn_bActivateEditor (this , & ListOfObject);
                                               m_pList2Window -> SelectZDx (eZDxType , 0);
                                               return 0;

        case C_uiQueryAnObjectHasBeenChanged : AZDxHasBeenChangedInList (pEdtListMess);
                                               return 0;
		//CPA2 Stegaru Cristian 98-04
		case C_uiQueryEditBoundingVolume	 : GetMainWorld () -> fn_bActivateEditor (this , & ListOfObject);
                                               return 0;
     	//End CPA2 Stegaru Cristian 98-04
        }
    }

    ASSERT (0);    // Unknown command
    return 0;
}

//-----------------------------------------------------------------------------
// Class ZDx_Interface - OnQueryInfos
// To communicate with the dll
//-----------------------------------------------------------------------------
long ZDx_Interface::OnQueryInfos (CPA_EditorBase * pCallingDll , WPARAM wParam , LPARAM lParam)
{
    if (wParam == C_uiQueryInfoT3DStateChange)
    {
        if (! fn_bIsCurrentEditor ())  return 0;            // We used the message only if we are the current editor

        if (pCallingDll == this)       return 0;            // If we made the change, we do nothing else

        // Set the aspect of the "Show actor" button
        m_pList1Window -> SetShowActorButtonState (lParam == C_wTool3D_Char || lParam == C_wTool3D_Mod_Object);

        CPA_SuperObject * pActorSuperObject = m_pList2Window -> GetActorSuperObject ();
        if (pActorSuperObject)  HIE_fn_vSetSuperObjectDrawMask (pActorSuperObject -> GetStruct () ,
                                                                GLI_C_lAllIsEnable ^ GLI_C_lIsNotDrawCollideInformation);

        switch (lParam)
        {
            case C_wTool3D_None          :
            case C_wTool3D_Char          :
            case C_wTool3D_Geom_Object   :
            case C_wTool3D_Viewer        : if (m_pList1Window -> IsEditingZDxOfModule ())
                                           {
                                               CPA_SuperObject * pSelectedActorSuperObject = m_pList1Window -> GetSelectedActorSuperObject ();
                                               if (pSelectedActorSuperObject)
                                               {
                                                   CPA_BaseObject * pSelectedActor = pSelectedActorSuperObject -> GetObject ();
                                                   m_pList1Window -> CreateListOfInstance (pSelectedActor -> GetOwner () , pSelectedActor);
                                               }
                                               else m_pList1Window -> CreateListOfFamily ();
                                           }
                                           break;

            case C_wTool3D_Mod_Object    :
            case C_wTool3D_Mod_List      :
            case C_wTool3D_Table         : if (! m_pList1Window -> IsEditingZDxOfModule ())
                                           {
                                               CPA_SuperObject * pSelectedActorSuperObject = m_pList1Window -> GetSelectedActorSuperObject ();
                                               if (pSelectedActorSuperObject)
                                               {
                                                   // We hide the zones of the selected actor, so they will be able to be shown again later
                                                   ShowZDxOfActor (pSelectedActorSuperObject , C_ucHideAllZDx);
                                                   HideModuleZDxOfActor (pSelectedActorSuperObject);

                                                   m_pList1Window -> CreateListOfModule (pSelectedActorSuperObject , NULL , FALSE);
                                               }
                                           }
                                           break;
        }
    }
    else
    if (wParam == C_uiQueryGetZDxType)
    {
        CPA_SuperObject * pSuperObject       = (CPA_SuperObject *) lParam;
        CPA_BaseObject  * pObject            = pSuperObject -> GetObject ();
        if (pObject == NULL || ! pObject -> fn_bIsOfType (C_szGeometricObjectTypeName))  return C_lNotAZone;

        CPA_SuperObject * pFatherSuperObject = pSuperObject -> GetSuperObjectFather ();
        if (! pFatherSuperObject)  return C_lNotAZone;
        CPA_BaseObject  * pFather            = pFatherSuperObject -> GetObject ();
        if (pObject == NULL)  return C_lNotAZone;

        if (pFather -> fn_bIsOfType (C_szActorInstanceTypeName))
        {
            CPA_Actor * pActor = (CPA_Actor *) pFather;
            if (IsObjectInList (pObject , pActor , eZdd))  return C_lZddOfActor;
            if (IsObjectInList (pObject , pActor , eZde))  return C_lZdeOfActor;
            if (IsObjectInList (pObject , pActor , eZdm))  return C_lZdmOfActor;
            if (IsObjectInList (pObject , pActor , eZdr))  return C_lZdrOfActor;

            return C_lNotAZone;
        }
        else
        if (pFather -> fn_bIsOfType (C_szPhysicalObjectTypeName))
        {
            EditorPO * pModule = (EditorPO *) pFather;
            if (pModule -> GetZone (C_ucTypeZdd) == pObject)  return C_lZddOfModule;
            if (pModule -> GetZone (C_ucTypeZde) == pObject)  return C_lZdeOfModule;
            if (pModule -> GetZone (C_ucTypeZdm) == pObject)  return C_lZdmOfModule;
            if (pModule -> GetZone (C_ucTypeZdr) == pObject)  return C_lZdrOfModule;

            return C_lNotAZone;
        }
        else return C_lNotAZone;
    }
    else ASSERT (0);

    return 0;
}


//*****************************************************************************
//                Virtual functions of the base class : menu
//*****************************************************************************

//**************************************************************************************
//Begin Mircea Dunka 3 Sept 1998 - DialogBar interface
void ZDx_Interface::fn_vDefineDlgBarBtnIcon (tde_DlgBarCategory wCategory, tds_DlgBarBtn *_pDlgBarBtn)
{
	if(wCategory == C_DlgBarCategoryEditor)
	{
		_pDlgBarBtn->hIcon = ::LoadIcon((HINSTANCE)(GetDLLIdentity()->hModule), MAKEINTRESOURCE(IDI_ZDX_DLGBAR_ICON));
        CString oCst;
        oCst = "Zone";
        if( (M_GetMainApp()) && (M_GetMainApp()->mp_oAppKeyboard) )
        {
            oCst += "  (";
            oCst += M_GetMainApp()->mp_oAppKeyboard->mfn_oConvertIniStringToKeyString((const CString*)&CString("Activate Zone Editor"));
			oCst += ")";
        }
		strcpy(_pDlgBarBtn->szToolTip, (char*)(LPCTSTR)oCst);
		_pDlgBarBtn->uID = (UINT)this;
	}
}
//end Mircea Dunka 3 Sept 1998


//-----------------------------------------------------------------------------
// Class ZDx_Interface - fn_vDefineSubMenu
// This function lets the dll add an entry in a sub menu
//-----------------------------------------------------------------------------
BOOL ZDx_Interface::fn_bDefineSubMenu (EDT_SubMenu * _p_oEDTSubMenu)
{
    // if we are in the "Editor" sub menu
    if (_p_oEDTSubMenu -> GetSubMenuType () == C_SubMenuEditor)
    {
        // we add a entry to open the ZDx editor with the short cut
        CString sEntry = "&Zone\t" + M_GetMainApp () -> mp_oAppKeyboard -> mfn_oConvertIniStringToKeyString
                                                ((const CString *) & CString ("Activate Zone Editor"));

        _p_oEDTSubMenu -> AddAnEntry (this , (char *) (LPCTSTR) sEntry , ID_ZDxMenuEditor , fn_bIsCurrentEditor ()); // Check if current editor

        return TRUE;
    }
    else
    // if we are in the "Preference" sub menu
    if (_p_oEDTSubMenu -> GetSubMenuType () == C_SubMenuSpecific)
    {
   		// we add an entry to save the dimension of the dialog
		_p_oEDTSubMenu -> AddAnEntry (this , "Save Dialog Dimensions" , ID_ZDxMenuPreference);

		return TRUE;
	}

    return FALSE;
}

//-----------------------------------------------------------------------------
// Class ZDx_Interface - _OnSubMenuCommand
// This function is called when the user clics on the entry
//-----------------------------------------------------------------------------
void ZDx_Interface::_OnSubMenuCommand (EDT_SubMenu * _p_oEDTSubMenu , UINT uiMsgID)
{
    // if the user has cliqued on the entry to open the ZDx editor
    if (_p_oEDTSubMenu -> GetSubMenuType () == C_SubMenuEditor && uiMsgID == ID_ZDxMenuEditor)
    {
        if (fn_bIsCurrentEditor ())
        {
            GetMainWorld () -> fn_bCloseEditor (this);
        }
        else
        {
            // Take the selected object
            CPA_SuperObject * pSelectedSuperObject = M_GetSingleSelection ();
            // If there is a selected object, we send it
            if (pSelectedSuperObject)
            {
                // Create a list with the selected object
                CPA_List<CPA_BaseObject> List;
                List . AddTail (pSelectedSuperObject);
                GetMainWorld () -> fn_bActivateEditor (this , & List);
            }
            else
            {
                GetMainWorld () -> fn_bActivateEditor (this , NULL);
            }
        }
    }
    else
    if (_p_oEDTSubMenu -> GetSubMenuType () == C_SubMenuSpecific && uiMsgID == ID_ZDxMenuPreference)
    {
        // Save frame dimension in .INI file
	    CString	csFileName = M_GetMainApp () -> m_csEditorDataPath + "Objects\\Zdd\\Zdd.ini";
        char *  szFileName = (char *) (LPCSTR) csFileName;

        CString csDimension;
        csDimension . Format ("%ld" , m_pSplitFrame -> m_oCurPos . right - m_pSplitFrame -> m_oCurPos . left);
        WritePrivateProfileString ("Preference" , "Frame Width" , (char *) (LPCSTR) csDimension , szFileName);
	    WritePrivateProfileString (NULL , NULL , NULL , szFileName);    // Flush buffer
    }
}

//-----------------------------------------------------------------------------
// Class ZDx_Interface - fn_vDefinePopupMenu
// This function lets the dll add an entry in the popup menu
//-----------------------------------------------------------------------------
BOOL ZDx_Interface::fn_bDefinePopupMenu (EDT_PopUpMenu * pPopup , CPA_List<CPA_SuperObject> * pSelection ,
                                         BOOL bAsCurrentEditor)
{
    if (bAsCurrentEditor)            // If the zone editor is open, we add an entry into the popup menu to close it
    {
        pPopup -> AddAnEntry (this , "Exit Zone editor" , ID_ZDxMenuLeave);
        return TRUE;
    }
    else
    if (! fn_bIsCurrentEditor ())    // If the editor is not open, we add an entry to open it, only if an actor is selected
    {
        CPA_SuperObject * pSelectedSuperObject = M_GetSingleSelection ();
        CPA_BaseObject  * pSelectedObject      = pSelectedSuperObject ? pSelectedSuperObject -> GetObject ()            : NULL;
        CPA_SuperObject * pFatherSuperObject   = pSelectedSuperObject ? pSelectedSuperObject -> GetSuperObjectFather () : NULL;
        CPA_BaseObject  * pFatherObject        = pFatherSuperObject   ? pFatherSuperObject   -> GetObject ()            : NULL;

        // We try to find a selected actor
        CPA_BaseObject  * pSelectedActor = NULL;
        CPA_SuperObject * pSelectedActorSuperObject;
        if (pSelectedObject && pSelectedObject -> fn_bIsOfType (C_szActorInstanceTypeName))
        {
            pSelectedActor            = pSelectedObject;
            pSelectedActorSuperObject = pSelectedSuperObject;
        }
        else
        if (pFatherObject   && pFatherObject   -> fn_bIsOfType (C_szActorInstanceTypeName))
        {
            pSelectedActor            = pFatherObject;
            pSelectedActorSuperObject = pFatherSuperObject;
        }

        if (pSelectedActor)
        {
            // edit zones
			CString csMessage = "Edit Zones of actor \"";
            csMessage        += pSelectedActor -> GetName () + "\"";
            EDT_SubMenu * pSubMenu = pPopup -> fn_p_oGetNewSubMenu ((char *) (LPCTSTR) csMessage);

            pSubMenu -> AddAnEntry (this , "Global zones" , ID_ZDxMenuEditGlobalZone);
            pSubMenu -> AddAnEntry (this , "Module zones" , ID_ZDxMenuEditModuleZone);

            pPopup -> AddASubMenu (pSubMenu);

            // show zones
			csMessage = "Show Zones of actor \"";
            csMessage        += pSelectedActor -> GetName () + "\"";
            pSubMenu = pPopup -> fn_p_oGetNewSubMenu ((char *) (LPCTSTR) csMessage);

            if (DoesActorHaveZDx (pSelectedActor))
            {
                if (AreZDxOfActorDisplayed (pSelectedActorSuperObject))
                     pSubMenu -> AddAnEntry (this , "Global zones" , ID_ZDxMenuHideGlobalZone, TRUE);
                else pSubMenu -> AddAnEntry (this , "Global zones" , ID_ZDxMenuShowGlobalZone, FALSE);
            }

            if (DoesActorHaveModuleZDx (pSelectedActorSuperObject))
            {
                if (AreModuleZDxOfActorDisplayed (pSelectedActorSuperObject))
                     pSubMenu -> AddAnEntry (this , "Module zones" , ID_ZDxMenuHideModuleZone, TRUE);
                else pSubMenu -> AddAnEntry (this , "Module zones" , ID_ZDxMenuShowModuleZone, FALSE);
            }
 
			pPopup -> AddASubMenu (pSubMenu);


            return TRUE;
        }

        // We try to find a selected module
        CPA_SuperObject * pSelectedModuleSuperObject = NULL;
        if (pSelectedObject && pSelectedObject -> fn_bIsOfType (C_szPhysicalObjectTypeName))  pSelectedModuleSuperObject = pSelectedSuperObject;
        else
        if (pFatherObject   && pFatherObject   -> fn_bIsOfType (C_szPhysicalObjectTypeName))  pSelectedModuleSuperObject = pFatherSuperObject;

        if (pSelectedModuleSuperObject && DoesAtLeastOneModuleHaveZDx ())
        {
            if (DoesModuleHaveZDx ((EditorPO *) pSelectedModuleSuperObject -> GetObject ()))
            {
                if (AreZDxOfModuleDisplayed (pSelectedModuleSuperObject))
                     pPopup -> AddAnEntry (this , "Hide zones of module" , ID_ZDxMenuHideZoneOfOneModule);
                else pPopup -> AddAnEntry (this , "Show zones of module" , ID_ZDxMenuShowZoneOfOneModule);
            }

            if (AreZDxOfAllModuleDisplayed ())
                 pPopup -> AddAnEntry (this , "Hide zones of all modules" , ID_ZDxMenuHideZoneOfAllModule);
            else pPopup -> AddAnEntry (this , "Show zones of all modules" , ID_ZDxMenuShowZoneOfAllModule);

            return TRUE;
        }
    }

    return FALSE;
}

//-----------------------------------------------------------------------------
// Class ZDx_Interface - _OnPopUpMenuCommand
// This function is called when the user clics on the entry
//-----------------------------------------------------------------------------
void ZDx_Interface::_OnPopUpMenuCommand (UINT m_IDCmdMsg)
{
    CPA_SuperObject * pSelectedActorSuperObject = GetSelectedActorSuperObject ();

    switch (m_IDCmdMsg)
    {
    case ID_ZDxMenuEditModuleZone      : m_bAskToEditModuleZone = TRUE;  // no break, it is not an error
    case ID_ZDxMenuEditGlobalZone      : {
                                          // Take the selected object
                                          CPA_SuperObject * pSelectedSuperObject = M_GetSingleSelection ();
                                          // If there is a selected object, we send it
                                          if (pSelectedSuperObject)
                                          {
                                              // Create a list with the selected object
                                              CPA_List<CPA_BaseObject> List;
                                              List . AddTail (pSelectedSuperObject);
                                              GetMainWorld () -> fn_bActivateEditor (this , & List);
                                          }
                                          else  GetMainWorld () -> fn_bActivateEditor (this , NULL);
                                          }
                                          break;

    case ID_ZDxMenuShowGlobalZone       : if (pSelectedActorSuperObject)
                                          {
                                              IWillRefreshDisplay  (C_lPopupMenuShowZone);
                                              ShowZDxOfActor       (pSelectedActorSuperObject , C_ucShowAllZDx);
                                              RefreshDisplay       (C_lPopupMenuShowZone);
                                          }
                                          break;
    case ID_ZDxMenuHideGlobalZone       : if (pSelectedActorSuperObject)
                                          {
                                              IWillRefreshDisplay  (C_lPopupMenuShowZone);
                                              ShowZDxOfActor       (pSelectedActorSuperObject , C_ucHideAllZDx);
                                              RefreshDisplay       (C_lPopupMenuShowZone);
                                          }
                                          break;
    case ID_ZDxMenuShowModuleZone       : if (pSelectedActorSuperObject)
                                          {
                                              IWillRefreshDisplay  (C_lPopupMenuShowZone);
                                              ShowModuleZDxOfActor (pSelectedActorSuperObject);
                                              RefreshDisplay       (C_lPopupMenuShowZone);
                                          }
                                          break;
    case ID_ZDxMenuHideModuleZone       : if (pSelectedActorSuperObject)
                                          {
                                              IWillRefreshDisplay  (C_lPopupMenuShowZone);
                                              HideModuleZDxOfActor (pSelectedActorSuperObject);
                                              RefreshDisplay       (C_lPopupMenuShowZone);
                                          }
                                          break;
    case ID_ZDxMenuShowZoneOfOneModule  : 
    case ID_ZDxMenuHideZoneOfOneModule  : {
                                          IWillRefreshDisplay (C_lShowZDxOfOneModule);
                                          // The selected object or its father must be a module
                                          CPA_SuperObject * pSelectedModuleSuperObject = M_GetSingleSelection ();
                                          if (! pSelectedModuleSuperObject -> GetObject () -> fn_bIsOfType (C_szPhysicalObjectTypeName))
                                          {
                                              pSelectedModuleSuperObject = pSelectedModuleSuperObject -> GetSuperObjectFather ();
                                              ASSERT (pSelectedModuleSuperObject -> GetObject () -> fn_bIsOfType (C_szPhysicalObjectTypeName));
                                          }
                                          ShowZDxOfModule (pSelectedModuleSuperObject ,
                                                           m_IDCmdMsg == ID_ZDxMenuShowZoneOfOneModule ? C_ucShowAllZDx : C_ucHideAllZDx);
                                          RefreshDisplay      (C_lShowZDxOfOneModule);
                                          }
                                          break;

    case ID_ZDxMenuShowZoneOfAllModule  : ShowZDxOfAllModule (C_ucShowAllZDx);
                                          break;

    case ID_ZDxMenuHideZoneOfAllModule  : ShowZDxOfAllModule (C_ucHideAllZDx);
                                          break;

    case ID_ZDxMenuLeave                : GetMainWorld () -> fn_bCloseEditor (this);  break;

    default                             : ASSERT (0);
    }
}


//*****************************************************************************
//    Virtual functions of the base class : questions to manage ZDx objects
//*****************************************************************************


//-----------------------------------------------------------------------------
// Class ZDx_Interface - fn_bCanActivateEditor
// Return if the editor can be activated
//-----------------------------------------------------------------------------
BOOL ZDx_Interface::fn_bCanActivateEditor (CPA_List<CPA_BaseObject> * _pParams)
{

#ifdef __INACTIVE_INTERFACE__
    return FALSE;
#endif

    return CPA_ObjectDLLBase::fn_bCanActivateEditor (_pParams);
}

//-----------------------------------------------------------------------------
// Class ZDx_Interface - fn_bCanHandleThisType
// The type of the objects we can handle
//-----------------------------------------------------------------------------
BOOL ZDx_Interface::fn_bCanHandleThisType (long lEngineType)
{
    return lEngineType == C_lZDD
        || lEngineType == C_lZDE
        || lEngineType == C_lZDM
        || lEngineType == C_lZDR
        || lEngineType == C_lBoundingVolume
        || lEngineType == C_lTestPoint;
}

//-----------------------------------------------------------------------------
// Class ZDx_Interface - fn_bAcceptModifParent
// One cannot change the parent of a zone
//-----------------------------------------------------------------------------
BOOL ZDx_Interface::fn_bAcceptModifParent (CPA_List<CPA_SuperObject> * pListObjects , tdeStatus eStatus)
{
    if (eStatus != C_AsConcernedDLL)  return TRUE;

    for (CPA_SuperObject * pSuperObject = pListObjects -> GetHeadElement () ; pSuperObject ;
                           pSuperObject = pListObjects -> GetNextElement (pSuperObject))
    {
        CPA_BaseObject * pObject = pSuperObject ? pSuperObject -> GetObject () : NULL;
        if (pObject && M_bIsThisObjectAZDx (pObject))  return FALSE;    // A zone -> we don't accept
    }

    return TRUE;
}

//-----------------------------------------------------------------------------
// Class ZDx_Interface - fn_bAcceptModifCopy
// A ZDx object can be copied
//-----------------------------------------------------------------------------
BOOL ZDx_Interface::fn_bAcceptModifCopy (CPA_List<CPA_SuperObject> * pListObjects , tdeStatus eStatus)
{
    // If we are not called to copy a ZDx object, it is OK
    if (eStatus != C_AsConcernedDLL)  return TRUE;

    // We cannot copy a bounding volume or a test point
// ANNECY AV CLEAN_MEC {
    if (m_pList1Window -> IsEditingBoundingVolume () /* || m_pList1Window -> IsEditingTestPoint () */)  return FALSE;
// END ANNECY AV }

    // Here, we are asked if a ZDx object can be copied
    // We answer YES only if the ZDx object is alone
    return pListObjects -> GetCount () == 1;
}

//-----------------------------------------------------------------------------
// Class ZDx_Interface - fn_bAcceptAsParent
// Only actors can be parent for a ZDx object
//-----------------------------------------------------------------------------
BOOL ZDx_Interface::fn_bAcceptAsParent (CPA_BaseObject * pChild , CPA_BaseObject * pParent)
{
    if (m_bIsShowingOrHidingZDx)  return TRUE;

    if (m_pList1Window -> IsEditingBoundingVolume ())  return m_pList2Window -> GetSelectedZDx () == NULL;
// ANNECY AV CLEAN_MEC {
//    if (m_pList1Window -> IsEditingTestPoint      ())  return m_pList2Window -> GetNumberOfUnusedPosition () > 0;
// END ANNECY AV }

    if (m_pList1Window -> IsEditingZDxOfModule ())    // Zone of module
    {
        // The parent must be a module
        if (! pParent -> fn_bIsOfType (C_szPhysicalObjectTypeName))  return FALSE;

        EditorPO * pModule  = (EditorPO *) pParent;
        tdeZDxType eZDxType = ((ZDx_Object *) pChild) -> GetZDxType ();
        return GetZDxOfPhysicalObject (pModule , eZDxType) == NULL;
    }
    else                                              // Zone of actor
    {
        // The parent must be an actor
        if (! pParent -> fn_bIsOfType (C_szActorInstanceTypeName))  return FALSE;

        // We get the list of ZDx
        EdtList * pEdtList = GetZDxList (pParent , ((ZDx_Object *) pChild) -> GetZDxType ());
        if (! pEdtList)  return FALSE;

        POSITION Pos = pEdtList -> GetHeadPosition ();
        while (Pos)
        {
            // One unused position => OK
            if (pEdtList -> GetNext (Pos) == NULL) return TRUE;
        }

        // No unused position => not OK
        return FALSE;
    }
}

//-----------------------------------------------------------------------------
// Class ZDx_Interface - fn_bAcceptModifInsert
// This function is called before a object is inserted into the hierarchy
//-----------------------------------------------------------------------------
BOOL ZDx_Interface::fn_bAcceptModifInsert (CPA_SuperObject * pSuperObjectToInsert ,
                                           CPA_SuperObject * pParent, tdeStatus eStatus)
{
    // if we receive this message because we are the current editor, we don't treat it, because
    // we will receive this message again if it concerns a ZDx
    if (eStatus != C_AsConcernedDLL)  return TRUE;

    // We do nothing when showing or hiding a ZDx or when inserting a ZDx object
    if (m_bIsShowingOrHidingZDx || m_bIsInsertingZDxObject)  return TRUE;

    // The zone editor must be open
    if (! fn_bIsCurrentEditor ())
    {
        MessageBox (NULL , "You must open the zone editor before you can drop a zone onto it" , "Warning" , MB_OK + MB_ICONSTOP + MB_TASKMODAL);
        return FALSE;
    }

    if (m_pList1Window -> IsEditingBoundingVolume ())  return AcceptModifInsertBoundingVolume (pSuperObjectToInsert , pParent);
    else
// ANNECY AV CLEAN_MEC {
//    if (m_pList1Window -> IsEditingTestPoint      ())  return AcceptModifInsertTestPoint      (pSuperObjectToInsert , pParent);
// END ANNECY AV }
    if (m_pList1Window -> IsEditingZDxOfModule    ())  return AcceptModifInsertZDxOfModule    (pSuperObjectToInsert , pParent);
                                                  else return AcceptModifInsertZDxOfActor     (pSuperObjectToInsert , pParent);
}


//*****************************************************************************
//    Virtual functions of the base class : functions to manage ZDx objects
//*****************************************************************************


//-----------------------------------------------------------------------------
// Class ZDx_Interface - fn_vInitListByType
// This function is called once to load all ZDx types
//-----------------------------------------------------------------------------
void ZDx_Interface::fn_vInitListByType (CPA_World * pWorld)
{
    pWorld -> fn_vAddANewListByType (C_szZddName , this);
    pWorld -> fn_vAddANewListByType (C_szZdeName , this);
    pWorld -> fn_vAddANewListByType (C_szZdmName , this);
    pWorld -> fn_vAddANewListByType (C_szZdrName , this);
}

//-----------------------------------------------------------------------------
// Class ZDx_Interface - fn_vInitListsOfModels
// This function is called once to load all model names of the ZDx object
//-----------------------------------------------------------------------------
void ZDx_Interface::fn_vInitListsOfModels (void)
{
    // Create a list of ZDx models
    GetInterface () -> fn_bAddANewModelList (C_szZDxListName , this);
}

//-----------------------------------------------------------------------------
// Class ZDx_Interface - GetNewInstance
// Create a new instance of a given ZDx model
//-----------------------------------------------------------------------------
CPA_SuperObject * ZDx_Interface::GetNewInstance (CString _csZDxGeometricTypeName , CString _csZDxModelName ,
                                                 CPA_SuperObject * pParent)
{
    if (_csZDxGeometricTypeName != _csZDxModelName)  return NULL;    // csZDxTypeName and csZDxModelName must be the same

    // Search the selected model
    int ModelNumber = 0;
    while (_csZDxModelName != ListOfZDxModels [ModelNumber] . szZDxModelName)
    {   
        if (++ ModelNumber >= NumberOfZDxModels)  return NULL;    // If we reach the end of the list -> not found -> return NULL
    }

    // We check if the selected position in the list of zones is empty
    tdeZDxType eZDxType;
    long       lPosition;
    if (m_pList2Window -> GetSelectedZDx (& eZDxType , & lPosition) != NULL || lPosition == -1)
    {
        if (! m_pList2Window -> SelectZDx (NULL , TRUE))  return NULL;    // if not, we select a empty position
        m_pList2Window -> GetSelectedZDx (& eZDxType , & lPosition);
    }

    tdeZDxGeometricType eZDxGeometricType = ListOfZDxModels [ModelNumber] . eZDxGeometricType;

    if (m_pList1Window -> IsEditingBoundingVolume () && eZDxGeometricType != eSphere)
    {
        MessageBox (NULL , "A bounding volume must be a sphere" , "Warning" , MB_OK + MB_ICONSTOP + MB_TASKMODAL);
        return NULL;
    }

// ANNECY AV CLEAN_MEC {
/*
    if (m_pList1Window -> IsEditingTestPoint () && eZDxGeometricType != ePoint)
    {
        MessageBox (NULL , "A test point must be a point" , "Warning" , MB_OK + MB_ICONSTOP + MB_TASKMODAL);
        return NULL;
    }
*/
// END ANNECY AV }

//ANNECY Shaitan Correction (15/04/98) {
  if ((eZDxType == eZdr) && (eZDxGeometricType == eBox))
  {
      MessageBox (NULL , "Box cannot be used for the Zdr" , "Warning" , MB_OK + MB_ICONSTOP + MB_TASKMODAL);
      return NULL;
  }
//ENDANNECY Shaitan Correction }

//Stefan Dumitrean 8-07-98 ( zone types )
	if ((eZDxType == eZdm) && (eZDxGeometricType == eCone))
    {
        MessageBox (NULL , "Cone cannot be used for the Zdm" , "Warning" , MB_OK + MB_ICONSTOP + MB_TASKMODAL);
        return NULL;
    }
	if ((eZDxType == eZde) && (eZDxGeometricType == eCone))
    {
        MessageBox (NULL , "Cone cannot be used for the Zde" , "Warning" , MB_OK + MB_ICONSTOP + MB_TASKMODAL);
        return NULL;
    }
	if ((eZDxType == eZdr) && (eZDxGeometricType == eCone))
    {
        MessageBox (NULL , "Cone cannot be used for the Zdr" , "Warning" , MB_OK + MB_ICONSTOP + MB_TASKMODAL);
        return NULL;
    }
//End Stefan Dumitrean 8-07-98 ( zone types )

    // Create a graphic super object (this also create a graphic object)
    char *  szDataPath;
    CString csReferenceSectionName;
    ComputeSectionNameForNewInstance (& szDataPath , & csReferenceSectionName , pParent -> GetObject ());

//ROMTEAM WorldEditor (Cristi Petrescu 12/97)
    //ACP_tdxHandleOfElement HandleOfElement;
    CPA_SuperObject * pGraphicSuperObject = CreateGraphicSuperObject (eZDxGeometricType /*, & HandleOfElement */, szDataPath , csReferenceSectionName);
    Shape3D         * pGraphicObject      = (Shape3D *) pGraphicSuperObject -> GetObject ();
//ENDROMTEAM WorldEditor (Cristi Petrescu)

    // Create a super object
    CPA_SuperObject * pSuperObject = CreateSuperObject ();

    // Give it the graphic super object as child
    pGraphicSuperObject -> SetEditProtected (TRUE);                  // So the user cannot move it
    pGraphicSuperObject -> SetSuperObjectOwner (pSuperObject);
    pSuperObject -> AddTail (pGraphicSuperObject);

    // set the model name of the super object
    pSuperObject -> SetModelName (_csZDxModelName);

    // Get the family of the actor which will be the owner of the ZDx object
    CPA_BaseObject * pFamily = GetFamilyForNewInstance (pParent -> GetObject ());

    // Create a ZDx Object with the loaded 3D geometric object
//ROMTEAM WorldEditor (Cristi Petrescu 12/97)
    ZDx_Object * pObject = new ZDx_Object (this , GetZDxTypeName (eZDxType) ,  eZDxType ,
                                           eZDxGeometricType , "" , pFamily , pGraphicObject /*, pGraphicObject->GetEngineHandle ()*/);//HandleOfElement);
//ENDROMTEAM WorldEditor (Cristi Petrescu)
    
    // Give to the geometric object the same name as the ZDx object, and it must be valid
    if (pObject -> fn_bCanBeNotified ())  pGraphicObject -> fn_vNotifySave ();    // Must be done before a fn_eRename
    tdeMissingCriteria eResult = pGraphicObject -> fn_eRename (pObject -> GetName ());
    ASSERT (eResult == E_mc_None);

//ANNECY TQ 29/04/98{
	pGraphicSuperObject -> fn_vHasALinkedZDM(FALSE);
//ENDANNECY TQ}
    
	// Set the correct size depending on the size of the parent
    switch (eZDxGeometricType)
    {
    case eSphere : {
                   MTH3D_tdstVector Center;
                   MTH_tdxReal Radius = ComputeInitialSizeOfSphere (pParent , & Center);
//ROMTEAM WorldEditor (Cristi Petrescu 12/97)
                   ZDx_Shape * pSphere = (ZDx_Shape*) pObject -> GetZDxShape ();
				   ((Sphere3D *)pGraphicObject) -> SetRadius (& Radius);
                   ((Sphere3D *)pGraphicObject) -> SetCenter (& Center);
				   /*
                   pSphere -> SetRadius (& Radius);
                   pSphere -> SetCenter (& Center);
				   */
//ENDROMTEAM WorldEditor (Cristi Petrescu)
                   }
                   break;

    case eBox    : {
                   MTH3D_tdstVector MinPoint , MaxPoint;
                   ComputeInitialSizeOfBox (pParent , & MinPoint , & MaxPoint);
//ROMTEAM WorldEditor (Cristi Petrescu 12/97)
                   ZDx_Shape * pBox = (ZDx_Shape *) pObject -> GetZDxShape ();
				   /*
                   pBox -> SetMinPoint (& MinPoint);
                   pBox -> SetMaxPoint (& MaxPoint);
                   pBox -> SetMinPoint (& MinPoint);    // Necessary because one must have Min < Max
				   */
                   ((Box3D *)pGraphicObject) -> SetMinPoint (& MinPoint);
                   ((Box3D *)pGraphicObject) -> SetMaxPoint (& MaxPoint);
                   ((Box3D *)pGraphicObject) -> SetMinPoint (& MinPoint);    // Necessary because one must have Min < Max
//ENDROMTEAM WorldEditor (Cristi Petrescu)
//ANNECY TQ 29/04/98{
				   if (eZDxType == eZdm)
					   pGraphicSuperObject -> fn_vHasALinkedZDM(TRUE);
//ENDANNECY TQ}
				   }
		break;
    }

    pSuperObject -> SetObject (pObject);            // Super object points to object
    pSuperObject -> SetTypeSO (C_Protected);        // Set the type of the super object

    pObject -> fn_vNotifySave ();

    return pSuperObject;                            // Return the created super object
}

//-----------------------------------------------------------------------------
// Class ZDx_Interface - fn_bChooseInsertPosition
// Fill the matrix of the super object of the zone to insert
//-----------------------------------------------------------------------------
BOOL ZDx_Interface::fn_bChooseInsertPosition (CPA_SuperObject * pNewInstance , CPA_SuperObject * pParent ,
                                              tdstPosition * pPosition)
{
    // The matrix is always the identity
    POS_fn_vSetIdentityMatrix(HIE_fn_hGetSuperObjectMatrix (pNewInstance -> GetStruct ()));
    // We set the position for zde, zdm, zdr, bounding volume of type sphere or box , but not zdd
    // But when there is no picking information available, we must set the position too
    ZDx_Object        * pZDxObject        = (ZDx_Object *) pNewInstance -> GetObject ();
    tdeZDxGeometricType eZDxGeometricType = pZDxObject -> GetZDxGeometricType ();
    return pPosition -> xIndex == 0 || 
           (pZDxObject -> GetZDxType () != eZdd && (eZDxGeometricType == eSphere || eZDxGeometricType == eBox));
}

//-----------------------------------------------------------------------------
// Class ZDx_Interface - GetParentForInsertion
// This function is called when a ZDx object is inserted into the hierarchy :
// We have to select the parent
//-----------------------------------------------------------------------------
CPA_SuperObject * ZDx_Interface::GetParentForInsertion (CString csTypeName , CString csModelName ,
                                                        tdstPosition * pPosition)
{
    if (m_pList1Window -> IsEditingZDxOfModule ())    // We ask for a ZDx of module
    {
        if (m_pList1Window -> GetShowActorButtonState () == FALSE)    // Drag&drop into the grid : we send the position
        {                                                             // to the T3D tool dll, and it give the picked super object
            CPA_ToolDLLBase * pT3DDll = GetMainWorld () -> GetToolDLLWithName (C_szDLLTool3DName);
            ASSERT (pT3DDll);
            return (CPA_SuperObject *) pT3DDll -> OnQueryInfos (this , C_wTool3D_QI_GetSOOnGrid , (LPARAM) & pPosition -> stPos);
        }

//ROMTEAM WorldEditor (Cristi Petrescu 12/97)
	//return (CPA_SuperObject *) pT3DDll -> OnQueryInfos (this , C_wTool3D_QI_GetSOOnGrid , (LPARAM) & pPosition -> stPos);
		return m_pList1Window -> GetSelectedModuleSuperObject ();    // Return the selected module
/*
        // Return the first super object of type Physical, null if none
        CPA_SuperObject * pSelectedSuperObject =
            GetInterface () -> GetUserMouseSelection (pPosition -> xIndex , pPosition -> a_stPickInfo , C_szPhysicalObjectTypeName);
        if (pSelectedSuperObject == NULL)
        {
            MessageBox (NULL , "A ZDx of module can only be dropped onto a module of an actor !" , "Warning" , MB_OK + MB_ICONSTOP + MB_TASKMODAL);
            return NULL;
        }
        else  return pSelectedSuperObject;
*/
//ENDROMTEAM WorldEditor (Cristi Petrescu)
    }
    else  return m_pList2Window -> GetActorSuperObject ();    // We ask for a ZDx of actor, a bounding volume or a test point
}

//-----------------------------------------------------------------------------
// Class ZDx_Interface - Duplicate
// This function is called to duplicate a ZDx object
//-----------------------------------------------------------------------------
CPA_BaseObject * ZDx_Interface::Duplicate (CPA_BaseObject * pOldObject, CPA_SuperObject * pSuperObject)
{
    if (m_pList1Window -> IsEditingZDxOfModule ())               // Zone of module -> we return the same zone
         return pOldObject;
    else return new ZDx_Object (* (ZDx_Object *) pOldObject);    // Zone of actor : call the ZDx_Object copy constructor to make a copy
}

//-----------------------------------------------------------------------------
// Class ZDx_Interface - GetCopyOfProtectedChild
// This function is called to duplicate a protected child of a ZDx object
// In fact, we return te Geometric 3d object of the new parent
//-----------------------------------------------------------------------------
CPA_SuperObject * ZDx_Interface::GetCopyOfProtectedChild (CPA_SuperObject * pInitialChild,
                                                          CPA_SuperObject * pNewOwner)
{
    CPA_SuperObject * pSuperObject = CreateSuperObject ();
    CPA_BaseObject  * pObject      = ((ZDx_Object *) pNewOwner -> GetObject ()) -> GetZDxShape () -> GetGeometric3dObject ();

    pSuperObject -> SetObject      (pObject);
    pSuperObject -> SetTypeSO      (C_Protected);

    return pSuperObject;
}

//-----------------------------------------------------------------------------
// Class ZDx_Interface - fn_vComputeBoundingVolume
// Compute the bounding volume of a ZDx object
//-----------------------------------------------------------------------------
void ZDx_Interface::fn_vComputeBoundingVolume (CPA_BaseObject * _pObject)
{
    // We do nothing
}

//-----------------------------------------------------------------------------
// Class ZDx_Interface - fn_hGetBoundingVolume
// Return the bounding volume of a ZDx object
//-----------------------------------------------------------------------------
ACP_tdxHandleOfObject ZDx_Interface::fn_hGetBoundingVolume (CPA_BaseObject * _pObject)
{
	MTH3D_tdstVector	stCenter;
	MTH_tdxReal			xRadius;
    ZDx_Object * pZDxObject = (ZDx_Object *) _pObject;

	MTH3D_M_vNullVector(&stCenter);
	xRadius = NULL;

//ANNECY TQ 18/06/98{
	GEO_fn_vAddObjectToSphere(pZDxObject -> GetZDxShape () -> GetGeometric3dObject () -> GetStruct (), &stCenter, &xRadius);
	GEO_fn_vSetGeometricSphere(&stCenter, xRadius, m_GlobalBoundingVolume);
//ENDANNECY TQ}


	return m_GlobalBoundingVolume;
}


//*****************************************************************************
//             Virtual functions of the base class : modifications
//*****************************************************************************


//-----------------------------------------------------------------------------
// Class ZDx_Interface - fn_vOnModifInsert
// This function is called when a ZDx object is inserted
//-----------------------------------------------------------------------------
void ZDx_Interface::fn_vOnModifInsert (CPA_SuperObject * pSuperObject, CPA_SuperObject * pParent, 
                                       tdstPosition * p_stPosition, tdeTypeModif eType, tdeStatus eStatus)
{
    // We do nothing when showing, hiding or inserting a ZDx object
    if (m_bIsShowingOrHidingZDx || m_bIsInsertingZDxObject)  return;
    
    CPA_BaseObject * pObject = pSuperObject -> GetObject ();
	if (! pObject)  return;

    m_bIsInsideOnModifInsertDelete = TRUE;

    // If we are called because we are the current editor
    switch (eStatus)
    {
    case C_AsCurrentEditor : {   // We see if the created object is an actor
                                if (pObject -> fn_bIsOfType (C_szActorInstanceTypeName))
                                {
                                    if (eType == C_EDTUndo)  OnDeleteActor (pSuperObject);  
                                                       else  OnInsertActor (pSuperObject);
                                }
                             }
                             break;

    case C_AsConcernedDLL  : {  // The inserted object must be a ZDx object
                                ASSERT (M_bIsThisObjectAZDx (pObject));
                                ZDx_Object * pZDxObject = (ZDx_Object *) pObject;
                                CPA_BaseObject * pObjectParent = pParent -> GetObject ();

                                if (m_pList1Window -> IsEditingBoundingVolume ())
                                {
                                    if (eType == C_EDTUndo)  OnDeleteBoundingVolume (pSuperObject , pParent);
                                                       else  OnInsertBoundingVolume (pSuperObject , pParent, FALSE);
                                }
                                else
// ANNECY AV CLEAN_MEC {
/*
                                if (m_pList1Window -> IsEditingTestPoint ())
                                {
                                    if (eType == C_EDTUndo)  OnDeleteTestPoint      (pSuperObject , pParent);
                                                       else  OnInsertTestPoint      (pSuperObject , pParent);
                                }
                                else
*/
// END ANNECY AV }
                                if (m_pList1Window -> IsEditingZDxOfModule ())
                                {
                                    if (eType == C_EDTUndo)  OnDeleteZDxOfModule    (pSuperObject , pParent);
                                                       else  OnInsertZDxOfModule    (pSuperObject , pParent);
                                }
                                else
                                {
                                    if (eType == C_EDTUndo)  OnDeleteZDxOfActor     (pSuperObject , pParent);
                                                       else  OnInsertZDxOfActor     (pSuperObject , pParent);
                                }
                                // Notify to delete the section (for Undo)
                                if (eType == C_EDTUndo)  pZDxObject -> fn_vNotifyUnSave ();
                             }
                             break;
    }

    m_bIsInsideOnModifInsertDelete = FALSE;
}

//-----------------------------------------------------------------------------
// Class ZDx_Interface - fn_vOnModifDelete
// This function is called when a ZDx object is deleted
//-----------------------------------------------------------------------------
void ZDx_Interface::fn_vOnModifDelete (CPA_List<EDT_SaveParents> * pListObjects , tdeTypeModif eType , tdeStatus eStatus)
{
    // We do nothing when showing, hiding or deleting a ZDx
    if (m_bIsShowingOrHidingZDx || m_bIsDeletingZDxObject)  return;

    m_bIsInsideOnModifInsertDelete = TRUE;
    
    // If we are called because we are the current editor
    if (eStatus == C_AsCurrentEditor)
    {
        for (EDT_SaveParents * pSaveParents = pListObjects -> GetHead () ; pSaveParents ;
             pSaveParents = pListObjects -> GetNextElement (pSaveParents))
        {
            CPA_SuperObject * pSuperObject = pSaveParents -> m_pChild;
            CPA_BaseObject  * pObject      = pSuperObject -> GetObject ();

            // We see if the deleted object is an actor
            if (pObject && pObject -> fn_bIsOfType (C_szActorInstanceTypeName))
            {
                if (eType == C_EDTUndo)  OnInsertActor (pSuperObject);  
                                   else  OnDeleteActor (pSuperObject);
            }
        }
    }
    else
    // If we are not called because we are the current editor, the deleted object is a ZDx
    {
        for (EDT_SaveParents * pSaveParents = pListObjects -> GetHead () ; pSaveParents ;
             pSaveParents = pListObjects -> GetNextElement (pSaveParents))
        {
            CPA_SuperObject * pSuperObject = pSaveParents -> m_pChild;
            CPA_BaseObject  * pObject      = pSuperObject -> GetObject ();

            // The inserted object must be a ZDx object
            ASSERT (M_bIsThisObjectAZDx (pObject));
            ZDx_Object * pZDxObject = (ZDx_Object *) pObject;
            CPA_SuperObject * pParent       = pSaveParents -> m_pInitialParent;
            CPA_BaseObject  * pObjectParent = pParent -> GetObject ();

            if (m_pList1Window -> IsEditingBoundingVolume ())
            {
                if (eType == C_EDTUndo)  OnInsertBoundingVolume (pSuperObject , pParent, FALSE);
                                   else  OnDeleteBoundingVolume (pSuperObject , pParent);
            }
            else
// ANNECY AV CLEAN_MEC {
/*
            if (m_pList1Window -> IsEditingTestPoint ())
            {
                if (eType == C_EDTUndo)  OnInsertTestPoint      (pSuperObject , pParent);
                                   else  OnDeleteTestPoint      (pSuperObject , pParent);
            }
            else
*/
// END ANNECY AV }
            if (m_pList1Window -> IsEditingZDxOfModule ())
            {
                if (eType == C_EDTUndo)  OnInsertZDxOfModule (pSuperObject , pParent);
                                   else  OnDeleteZDxOfModule (pSuperObject , pParent);
            }
            else
            {
                if (eType == C_EDTUndo)  OnInsertZDxOfActor (pSuperObject , pParent);
                                   else  OnDeleteZDxOfActor (pSuperObject , pParent);
            }
            // We notify to delete the ZDx object from file, or to cancel the deletion
            if (eType == C_EDTUndo)  pZDxObject -> fn_vNotifyRestore ();
                                else pZDxObject -> fn_vNotifyUnSave  ();
        }
    }

    m_bIsInsideOnModifInsertDelete = FALSE;
}

//-----------------------------------------------------------------------------
// Class ZDx_Interface - fn_vOnCancelInsertion
// This function is called when a insertion of a ZDx is canceled
//-----------------------------------------------------------------------------
void ZDx_Interface::fn_vOnCancelInsertion (CPA_SuperObject * _pSuperObject)
{
    ZDx_Object * pZDxObject =   (ZDx_Object *) _pSuperObject -> GetObject ();
    pZDxObject -> fn_vNotifyUnSave ();
    delete pZDxObject;
//??? A FAIRE QUAND CA NE PLANTERA PLUS    delete _pSuperObject;
}

//-----------------------------------------------------------------------------
// Class ZDx_Interface - fn_vOnModifCopy
// This function is called when an object has been copied and pasted
//-----------------------------------------------------------------------------
void ZDx_Interface::fn_vOnModifCopy (CPA_List<EDT_SaveParents> *pListObjects, tdeTypeModif eType, tdeStatus eStatus)
{
    if (eStatus != C_AsConcernedDLL)  return;

    // Only one ZDx object can be copied at once
    ASSERT (pListObjects -> GetCount () == 1);

    ZDx_Object          * pZDxObject         = (ZDx_Object *) pListObjects -> GetHead () -> m_pChild -> GetObject ();
//ROMTEAM WorldEditor (Cristi Petrescu 12/97)
    Shape3D             * pGeometric3dObject = pZDxObject -> GetZDxShape () -> GetGeometric3dObject ();
//ENDROMTEAM WorldEditor (Cristi Petrescu)

    if (m_pList1Window -> IsEditingZDxOfModule ())              // Copy of a zone of module
    {
        EditorPO * pModule = (EditorPO *) pListObjects -> GetHead () -> m_pFinalParent -> GetObject ();    // We get the module

        if (eType == C_EDTUndo)
        {
            // We remove the ZDx object from the physical object
            SetZDxOfPhysicalObject (pModule , NULL , pZDxObject -> GetZDxType ());
            m_pList1Window -> SelectModule (pModule , TRUE);
        }
        else
        {
            // We put the ZDx object into the physical object
            SetZDxOfPhysicalObject (pModule , pZDxObject , pZDxObject -> GetZDxType ());

            // We refresh the current list
            m_pList1Window -> SelectZDxOfModule (pModule , pZDxObject , TRUE);
        }
    }
    else                                                        // Copy of a zone of actor
    {
        // We get the actor and the family
        CPA_BaseObject      * pActor           = pListObjects -> GetHead () -> m_pFinalParent -> GetObject ();
        ASSERT (pActor);
        CPA_BaseObject      * pFamily          = pActor -> GetOwner () -> GetOwner ();
        ASSERT (pFamily);

        if (eType == C_EDTUndo)
        {
            // Remove the ZDx object from the list of ZDx
            EdtList * pEdtList = GetZDxList (pActor , pZDxObject -> GetZDxType ());
            RemoveZDxFromList (pEdtList , pZDxObject , pActor);
            // Refresh the list
            m_pList1Window -> ReCreateCurrentList ();
        }
        else
        {
            EdtList * pEdtList     = GetZDxList (pActor , pZDxObject -> GetZDxType ());
            long      lIndexInList = pZDxObject -> GetIndexInList ();
            // If the specified position is used, select the first unused position (-1)
            if (lIndexInList != -1 && pEdtList -> FindElementFromIndex (lIndexInList) != NULL)  lIndexInList = -1;
            // Put the ZDx object into the list of ZDx
            InsertZDxIntoList (pEdtList , pZDxObject , & lIndexInList , pActor , eZDxNormal);
            // Refresh the lists
            m_pList1Window -> SelectZDxOfActor (pActor , pZDxObject , TRUE);
        }
    }
}

//-----------------------------------------------------------------------------
// Class ZDx_Interface - fn_vOnBeginMove
// This function is called just before a move
//-----------------------------------------------------------------------------
void ZDx_Interface::fn_vOnBeginMove (CPA_List<CPA_SuperObject> *pListObjects,
                                     CPA_List<CPA_SuperObject> *pListConcerned, tdeStatus eStatus)
{
    // if we receive this message because we are the current editor, we don't treat it, because
    // we will receive this message again if it concerns a ZDx
    if (eStatus != C_AsConcernedDLL)  return;

    // A ZDx object is moving : we save the modifications (if any) on the edited ZDx object (even if it is not
    // the one that is moving) by cliquing on the Apply button
//    m_pEditWindow -> Apply ();

    m_bMoveHasBegun = TRUE;
//CPA2 (Corneliu Babiuc) 27-04-1998
	m_bMoveOnlyActor = m_bMoveOnlyActorKeyPressed;
//END CPA2 (Corneliu Babiuc) 15-04-1998
}

//CPA2 (Corneliu Babiuc) 15-04-1998
//-----------------------------------------------------------------------------
// Class ZDx_Interface - fn_vOnMoving
// This function is called when a ZDx object is moved
// For each moved ZDx object, we refresh the graphic data
//-----------------------------------------------------------------------------

void ZDx_Interface::fn_vOnMoving (CPA_List<CPA_SuperObject>   * pListObjects ,
                                  CPA_List<CPA_SuperObject>   * pListConcerned ,
                                  tdeStatus eStatus)
{
    // we'll treat this message if the zones are moved as child of an actor 
	// in this case we have to move them back 
    if (eStatus != C_AsConcernedDLL)  return;
    // if the special move mode is not activated we do nothing
	if (!m_bMoveOnlyActor ) return;
	
    POSITION Position = pListObjects -> GetHeadPosition ();
	//if the user has selected a zone there is nothing to do
	if (Position) return;

	Position = pListConcerned -> GetHeadPosition ();
    while (Position)
    {
        //we'll translate the zone with father deplacement to keep the initial position

		CPA_SuperObject  * pZDxSuperObject    = pListConcerned -> GetNext (Position);
		MoveBackZone (pZDxSuperObject);
	}  

    // Refresh the data of the window without redrawing the world
    m_pEditWindow -> RefreshData (FALSE); 
}
//END CPA2 (Corneliu Babiuc) 17-04-1998

//-----------------------------------------------------------------------------
// Class ZDx_Interface - fn_vOnModifMove
// This function is called after a ZDx object has been moved
// For each moved ZDx object, we refresh the graphic data
//-----------------------------------------------------------------------------
void ZDx_Interface::fn_vOnModifMove (CPA_List<EDT_SavePos>       * pListObjects   ,
                                     CPA_List<EDT_SaveGlobalPos> * pListConcerned ,
                                     tdeTypeModif eType, tdeStatus eStatus)
{
//CPA2 (Corneliu Babiuc) 16-04-1998
//this code is intended to set gbMoveWasOnlyActor global variable in case of move only actor
	if ((eStatus == C_AsCurrentEditor) && (eType != C_EDTCancel))
	{
		gbMoveWasOnlyActor = FALSE;
		POSITION Pos = pListConcerned -> GetHeadPosition ();
		while (Pos)
		{
			EDT_SaveGlobalPos * pSaveGlobalPos = pListConcerned -> GetNext (Pos);
			CPA_SuperObject   * pSuperObject = pSaveGlobalPos -> m_pObject;
			
			//test if the object is a ZDx
			CPA_BaseObject * pObject = pSuperObject -> GetObject ();
			if (pObject != NULL && M_bIsThisObjectAZDx (pObject))
			{
				MTH3D_tdstVector   InitialTranslation , FinalTranslation ;

				POS_fn_vGetTranslationVector (pSaveGlobalPos -> m_hInitialGlobalMatrix , & InitialTranslation);
				POS_fn_vGetTranslationVector (pSaveGlobalPos -> m_hFinalGlobalMatrix   , & FinalTranslation);

				BOOL bMoveToMode = (eType == C_EDTDo) && (m_bMoveHasBegun == FALSE) && m_bMoveOnlyActorKeyPressed;

				//if the initial position is the same with final position then the move was 'Move Only Actor'
				if ( MTH3D_M_bEqualVector (& InitialTranslation , & FinalTranslation) 
					|| bMoveToMode)
					gbMoveWasOnlyActor = TRUE;
				return;
			}
		}
	}
//this code will ensure that un ReDo/UnDo action in case of MoveTo mode could be distinguished
	if ((eStatus == C_AsConcernedDLL) && (eType != C_EDTCancel))
	{
		gbMoveWasOnlyActor = FALSE;
		POSITION Pos = pListConcerned -> GetHeadPosition ();
		BOOL bMoveToMode = (eType == C_EDTDo) && (m_bMoveHasBegun == FALSE) && m_bMoveOnlyActorKeyPressed;	
		if (bMoveToMode)
		{
			while (Pos)
			{
				EDT_SaveGlobalPos * pSaveGlobalPos = pListConcerned -> GetNext (Pos);
				MTH3D_tdstVector   InitialTranslation , FinalTranslation;
				POS_fn_vGetTranslationVector (pSaveGlobalPos -> m_hInitialGlobalMatrix , & InitialTranslation);
				POS_fn_vGetTranslationVector (pSaveGlobalPos -> m_hFinalGlobalMatrix   , & FinalTranslation);
				//set the final Global matrix the initial one
				POS_fn_vSetTranslationVector(pSaveGlobalPos -> m_hFinalGlobalMatrix  , & InitialTranslation);
			}
		} 
	}
	m_bMoveOnlyActor = FALSE;
//END CPA2 (Corneliu Babiuc) 30-04-1998

    // if we receive this message because we are the current editor, we don't treat it, because
    // we will receive this message again if it concerns a ZDx
    if (eStatus != C_AsConcernedDLL)  return;
    // if the operation was canceled, we do nothing
    if (eType == C_EDTCancel)
    {
        m_bMoveHasBegun = FALSE;
        return;
    }

    POSITION Position = pListObjects -> GetHeadPosition ();

    while (Position)
    {
        EDT_SavePos      * pSavePos           = pListObjects -> GetNext (Position);
        CPA_SuperObject  * pZDxSuperObject    = pSavePos -> m_pObject;
        ZDx_Object       * pZDxObject         = (ZDx_Object *) pZDxSuperObject -> GetObject ();
        MTH3D_tdstVector   InitialTranslation , FinalTranslation , NewTranslation;
        POS_fn_vGetTranslationVector (pSavePos -> m_hInitialMatrix , & InitialTranslation);
        POS_fn_vGetTranslationVector (pSavePos -> m_hFinalMatrix   , & FinalTranslation);
        if (! MTH3D_M_bEqualVector (& InitialTranslation , & FinalTranslation))
        {
            BOOL bMoveToMode = (eType == C_EDTDo) && (m_bMoveHasBegun == FALSE);
            if (bMoveToMode)
            {
                MTH3D_tdstVector stCenter = pZDxObject -> GetZDxShape () -> GetCenter ();
                MTH3D_M_vSubVector (& FinalTranslation , & FinalTranslation , & stCenter);
                POS_fn_vSetTranslationVector(pSavePos -> m_hFinalMatrix , & FinalTranslation);
            }

            if (eType != C_EDTUndo)  { MTH3D_M_vSubVector (& NewTranslation , & FinalTranslation , & InitialTranslation); }
                               else  { MTH3D_M_vSubVector (& NewTranslation , & InitialTranslation , & FinalTranslation); }
            POS_fn_vSetTranslationVector(HIE_fn_hGetSuperObjectMatrix (pZDxSuperObject -> GetStruct ()) ,
                                       & NewTranslation);
            pZDxObject -> GetZDxShape () -> RefreshData (pZDxSuperObject);
// ANNECY AV CLEAN_MEC {
//            if (pZDxObject -> GetZDxType () == eTestPoint)  m_pList2Window -> GetListOfTestPoint () -> fn_vNotifySave ();
//                                                       else pZDxObject                              -> fn_vNotifySave ();
pZDxObject -> fn_vNotifySave ();
// END ANNECY AV }
        }
    }

    m_bMoveHasBegun = FALSE;

    // Refresh the data of the window without redrawing the world
    m_pEditWindow -> RefreshData (FALSE);
}

//-----------------------------------------------------------------------------
// Class ZDx_Interface - fn_vOnSelect
// This function is called when a ZDx Object is selected or deselected
//-----------------------------------------------------------------------------
void ZDx_Interface::fn_vOnSelect (CPA_SuperObject * pSuperObject, tdeTypeModif eType, tdeStatus eStatus)
{
    if (m_bIsShowingOrHidingZDx || eStatus != C_AsCurrentEditor)  return;

    CPA_BaseObject * pObject = pSuperObject -> GetObject ();
    if (! pObject)  return;

    // We see if an actor object is selected
    if (pObject -> fn_bIsOfType (C_szActorInstanceTypeName))  OnSelectActor (pSuperObject , eType); else
    // We see if a ZDx is selected
    if (M_bIsThisObjectAZDx (pObject))
    {
        ZDx_Object * pZDxObject = (ZDx_Object *) pObject;

        CPA_SuperObject * pParent = pSuperObject -> GetSuperObjectFather (); 
        // If pParent is NULL, it means that the ZDx object is not in the hierarchy (this can happen because of a Undo delete
        // of a zone of an actor while another actor is edited). In this case, we do nothing
        if (! pParent)  return;

        if (m_pList1Window -> IsEditingBoundingVolume ())  OnSelectBoundingVolume (pSuperObject , pParent , eType);
        else
// ANNECY AV CLEAN_MEC {
/*
        if (m_pList1Window -> IsEditingTestPoint      ())  OnSelectTestPoint      (pSuperObject , pParent , eType);
        else
*/
// END ANNECY AV }
        if (m_pList1Window -> IsEditingZDxOfModule    ())  OnSelectZDxOfModule    (pSuperObject , pParent , eType);
                                                     else  OnSelectZDxOfActor     (pSuperObject , pParent , eType);
    }
    else
    // We see if a module is selected
    if (m_pList1Window -> IsEditingZDxOfModule () && pObject -> fn_bIsOfType (C_szPhysicalObjectTypeName))
        OnSelectModule (pSuperObject , eType);
    else
    // We see if the parent of the selected object is an actor
    {
        CPA_SuperObject * pParent       = pSuperObject -> GetSuperObjectFather ();
        CPA_BaseObject  * pObjectParent = pParent ? pParent -> GetObject () : NULL;
        if (pObjectParent && pObjectParent -> fn_bIsOfType (C_szActorInstanceTypeName))  OnSelectActor (pParent , eType);
    }
}


//*****************************************************************************
//           Virtual functions of the base class : Windows messages
//*****************************************************************************

//-----------------------------------------------------------------------------
// Class ZDx_Interface - _OnKeyDown
// This function is called when a key is pressed
//-----------------------------------------------------------------------------
BOOL ZDx_Interface::_OnKeyDown (UINT _nChar , UINT , UINT)
{
//ROMTEAM WorldEditor (Cristi Petrescu 12/97)
//CPA2 (Corneliu Babiuc) 13-04-1997
    if (m_pZDxKeyActionConfiguration -> mfn_uwKeyToAction (_nChar) == KA_MOVE_ONLY_ACTOR)
    {
        m_bMoveOnlyActorKeyPressed = TRUE;
        return FALSE;  // We have used the message
    }
//CPA2 (Corneliu Babiuc) 13-04-1997//ROMTEAM WorldEditor (Cristi Petrescu 12/97)
	/*
    if (m_pZDxKeyActionConfiguration -> mfn_uwKeyToAction (_nChar) == KA_CHANGE_ZDX_SIZE)
        m_bSizeKeyPressed = TRUE;

    return FALSE;    // We have used the message
	*/
	return Shape3D::_OnKeyDown (_nChar);
//ENDROMTEAM WorldEditor (Cristi Petrescu)
}

//-----------------------------------------------------------------------------
// Class ZDx_Interface - _OnKeyUp
// This function is called when a key is released
//-----------------------------------------------------------------------------
BOOL ZDx_Interface::_OnKeyUp (UINT _nChar , UINT , UINT)
{
//CPA2 (Corneliu Babiuc) 13-04-1997
    if (m_pZDxKeyActionConfiguration -> mfn_uwKeyToAction (_nChar) == KA_MOVE_ONLY_ACTOR)
    {
        m_bMoveOnlyActorKeyPressed = FALSE;
        return FALSE;  // We have used the message
    }
//CPA2 (Corneliu Babiuc) 13-04-1997
//ROMTEAM WorldEditor (Cristi Petrescu 12/97)
	/*
    if (m_pZDxKeyActionConfiguration -> mfn_uwKeyToAction (_nChar) == KA_CHANGE_ZDX_SIZE)
        m_bSizeKeyPressed = FALSE;

    return FALSE;    // We have used the message
	*/
	return Shape3D::_OnKeyUp (_nChar);
//ENDROMTEAM WorldEditor (Cristi Petrescu)
}

//-----------------------------------------------------------------------------
// Class ZDx_Interface - OnMouseMove
// Used when one changes the size of the ZDx object
//-----------------------------------------------------------------------------
BOOL ZDx_Interface::_OnMouseMove (UINT nFlags , tdstMousePos * p_stMousePos , MTH3D_tdstVector * pDeplacement)
{
//ROMTEAM WorldEditor (Cristi Petrescu 12/97)
	/*
    // If we are not in "size changing" mode, we don't use the message
    if (m_stSizeChangingMode . bActiveMode == FALSE )//|| m_bSizeKeyPressed == FALSE) 
		return FALSE;
	*/

	ZDx_Object *pZDxObject = m_pEditWindow -> GetZDxObjectEdited ();
	/*
	ZDx_Object *pZDxObject = (ZDx_Object *)m_stSizeChangingMode . pSelectedZDxSuperObject -> GetObject (); 
			-> GetObject ()
	*/
	if (pZDxObject && pZDxObject -> GetZDxShape () -> GetGeometric3dObject () -> _OnMouseMove (nFlags, p_stMousePos, pDeplacement))
	{
		// we made the resizing
		IWillRefreshDisplay (C_lOnMouseMove);
	/*
	// Change the size of the ZDx object
	switch (((ZDx_Object *) m_stSizeChangingMode . pSelectedZDxSuperObject -> GetObject ()) -> GetZDxGeometricType ())
	{
	case eSphere : ChangeSizeZDxSphereObject (pDeplacement);       break;
    case eBox    : ChangeSizeZDxBoxObject    (pDeplacement);       break;
    case eCone   : ChangeSizeZDxConeObject   (pDeplacement);       break;
    default:       ASSERT (0);                                     break;
	}
	*/

		m_pEditWindow -> RefreshData (FALSE);       // Refresh the data of the window without redrawing the ZDx object
		m_pEditWindow -> RefreshModif ();           // Reinitialize the modif for the ZDx object
		RefreshDisplay (C_lOnMouseMove);            // Redraw the world

		return TRUE;
	}
	else
		return FALSE;
//ENDROMTEAM WorldEditor (Cristi Petrescu)
}

//-----------------------------------------------------------------------------
// Class ZDx_Interface - OnLButtonDown
// Clic on the left button + Ctrl : we change the size of the ZDx object
//-----------------------------------------------------------------------------
BOOL ZDx_Interface::_OnLButtonDown (UINT nFlags , tdstMousePos * p_stMousePos , ACP_tdxIndex xIndex , HIE_tdstPickInfo * p_stObject)
{
//ROMTEAM WorldEditor (Cristi Petrescu 12/97)
	/*
    // If the key to change the size is not pressed, we don't use the message
    if (! m_bSizeKeyPressed) return FALSE;

    // We begin the change of the size of a ZDx object
    OnBeginChangingSize (xIndex , p_stObject);
	*/

	// we ask if there is a pointed zdd, zde, zdm, zdr or bounding volume
    CString TypeList [5] = { C_szZddName , C_szZdeName , C_szZdmName , C_szZdrName , C_szBoundingVolumeName};
    CPA_List<CPA_SuperObject> * pSelectedSuperObjectList = GetInterface () -> GetMouseSelection (xIndex , p_stObject , TypeList , 5);
    // if the list is empty, we do nothing
    if (pSelectedSuperObjectList -> IsEmpty ())  
		return FALSE;
    // else, we select the first super object in the list
    CPA_SuperObject * pSelectedSuperObject = pSelectedSuperObjectList -> GetHeadElement ();

    ZDx_Object * pZDxObject = (ZDx_Object *) pSelectedSuperObject -> GetObject ();

	/*
    // one can only change the size of a sphere, box or cone ZDx object
	tdeZDxGeometricType eZDxType = pZDxObject -> GetZDxGeometricType ();
	if (eZDxType != eSphere && eZDxType != eBox && eZDxType != eCone) 
		return;
	*/

    // if the pointed ZDx object is not the actual selected ZDx object, we select it
    if (pZDxObject != m_pEditWindow -> GetZDxObjectEdited ())
    {
        GetInterface () -> fn_vCancelCurrentSelection (FALSE);
        GetInterface () -> fn_vAddSelectedObject (pSelectedSuperObject , TRUE);
    }


    // enter the "size changing" mode
    //m_stSizeChangingMode . bActiveMode              = TRUE;
    //m_stSizeChangingMode . pSelectedZDxSuperObject  = pSelectedSuperObject;
    //m_stSizeChangingMode . GlobalSelectedPoint      = p_stObject->stPickedObject.aDEF_stDataOfElement->stHit;

	/*
    switch (pZDxObject -> GetZDxGeometricType ())
    {
    case eSphere:
        {
        // Get the center of the sphere
        ZDx_Sphere * pSphere = (ZDx_Sphere *) pZDxObject -> GetZDxShape ();
        MTH3D_tdstVector SphereCenter;
        // Compute coordinates in the global repere
        ConvertPointLocalToGlobal (& SphereCenter , 
                                   HIE_fn_hGetSuperObjectGlobalMatrix (m_stSizeChangingMode .
                                       pSelectedZDxSuperObject -> GetStruct ()) , & pSphere -> GetCenter ());

        // Get the matrix of the camera
        GLI_tdxHandleToCamera hHandleToCamera = GetInterface () -> GetMultiDevice () -> GetFocusDevice () -> GetCamera ();
        POS_tdstCompletePosition CameraMatrix , InvMatrix;
        GLI_xGetCameraMatrix (hHandleToCamera , & CameraMatrix);
        POS_fn_vInvertIsoMatrix(& InvMatrix , & CameraMatrix);
        // Get the coordinates of the Z axe
        MTH3D_tdstVector        ZAxe , DummyVector;
        POS_fn_vGetRotationMatrix(& InvMatrix , & DummyVector , & DummyVector , & ZAxe);
        // Compute the sphere center, projected into the plane where the mouse moves into
        MTH3D_M_vSubVector       (& SphereCenter , & SphereCenter , & m_stSizeChangingMode . GlobalSelectedPoint);
        GLI_tdxValue DotProduct = MTH3D_M_xDotProductVector (& ZAxe , & SphereCenter);
        MTH3D_M_vMulScalarVector (& ZAxe , DotProduct , & ZAxe);
        MTH3D_M_vSubVector       (& SphereCenter , & SphereCenter , & ZAxe);
        MTH3D_M_vAddVector       (& m_stSizeChangingMode . CenterInMousePlane ,
                                  & SphereCenter , & m_stSizeChangingMode . GlobalSelectedPoint);
        }
        break;

    case eBox:
        {
        ZDx_Box * pBox = (ZDx_Box *) pZDxObject -> GetZDxShape ();

        ConvertPointGlobalToLocal (& m_stSizeChangingMode . LocalSelectedPoint , 
                                   HIE_fn_hGetSuperObjectGlobalMatrix (pSelectedSuperObject -> GetStruct ()) ,
                                   & m_stSizeChangingMode . GlobalSelectedPoint);
        MTH3D_M_vSubVector        (& m_stSizeChangingMode . LocalSelectedPoint , & m_stSizeChangingMode . LocalSelectedPoint ,
                                   & pBox -> GetCenter ());
        m_stSizeChangingMode . LocalSelectedPoint . xX /= pBox -> GetLength ();
        m_stSizeChangingMode . LocalSelectedPoint . xY /= pBox -> GetWidth  ();
        m_stSizeChangingMode . LocalSelectedPoint . xZ /= pBox -> GetHeight ();
        }
        break;

    case eCone:
        {
        ZDx_Cone * pCone = (ZDx_Cone *) pZDxObject -> GetZDxShape ();

        ConvertPointGlobalToLocal (& m_stSizeChangingMode . LocalSelectedPoint , 
                                   HIE_fn_hGetSuperObjectGlobalMatrix (pSelectedSuperObject -> GetStruct ()) ,
                                   & m_stSizeChangingMode . GlobalSelectedPoint);

        // We see if we must change the top point or the radius of the cone
        MTH3D_tdstVector TopPoint                    = pCone -> GetTopPoint  ();
        MTH3D_tdstVector BasePoint                   = pCone -> GetBasePoint ();
        MTH_tdxReal      SquareDistanceToTopPoint    = MTH3D_M_xVectorGapSqr (& m_stSizeChangingMode . LocalSelectedPoint , & TopPoint);
        MTH_tdxReal      SquareDistanceToBasePoint   = MTH3D_M_xVectorGapSqr (& m_stSizeChangingMode . LocalSelectedPoint , & BasePoint);
        if (SquareDistanceToTopPoint < SquareDistanceToBasePoint)
        {
            m_stSizeChangingMode . bChangeTopPointOfCone = TRUE;
        }
        else
        {
            m_stSizeChangingMode . bChangeTopPointOfCone = FALSE;

            // We project the picked point into the base plane
            MTH3D_tdstVector BaseTopVector;
            MTH3D_M_vSubVector (& BaseTopVector , & TopPoint , & BasePoint);
            MTH3D_tdstVector BasePointVector;
            MTH3D_M_vSubVector (& BasePointVector , & m_stSizeChangingMode . LocalSelectedPoint , & BasePoint);
            MTH_tdxReal      DotProduct = MTH3D_M_xDotProductVector (& BaseTopVector , & BasePointVector);
            MTH3D_tdstVector ProjectedVector;
            MTH3D_M_vMulScalarVector (& ProjectedVector , DotProduct , & BaseTopVector);
            MTH3D_M_vDivScalarVector (& ProjectedVector , & ProjectedVector , MTH3D_M_xSqrVector (& BaseTopVector));
            MTH3D_M_vAddVector (& m_stSizeChangingMode . LocalSelectedPoint ,
                                & m_stSizeChangingMode . LocalSelectedPoint , & ProjectedVector);
        }
        break;
        }

    default:
        ASSERT (0);
        break;
    }
	*/

	if (pZDxObject -> GetZDxShape () -> GetGeometric3dObject () -> _OnLButtonDown (nFlags, p_stMousePos, xIndex, p_stObject))
	{
		// we create a modif for the Undo
		if (m_pEditWindow -> GetZDxObjectEdited ())
		{
			m_stSizeChangingMode.pZDxModif = 
				new ZDx_Modif (/*(ZDx_Object *) m_stSizeChangingMode . pSelectedZDxSuperObject -> GetObject ()*/m_pEditWindow -> GetZDxObjectEdited () , "Changing ZDx size");
		}
	}

    return FALSE;    // We do not use the message, so the hierarchy editor can make its initialization for moving the oject
//ENDROMTEAM WorldEditor (Cristi Petrescu)
}

//-----------------------------------------------------------------------------
// Class ZDx_Interface - OnLButtonUp
// End of the clic on the right button : end of the changement of the size of the ZDx object
//-----------------------------------------------------------------------------
BOOL ZDx_Interface::_OnLButtonUp (UINT nFlags , tdstMousePos * p_stPos)
{
//ROMTEAM WorldEditor (Cristi Petrescu 12/97)
    // if we are not in "size changing" mode, we don't use the message
	/*
    if (! m_stSizeChangingMode . bActiveMode) return FALSE;

    OnEndChangingSize ();    // We end the change of the size of a ZDx object
	*/
	ZDx_Object * pZDxObject = m_pEditWindow -> GetZDxObjectEdited ();
	pZDxObject && pZDxObject -> GetZDxShape () -> GetGeometric3dObject () -> _OnLButtonUp (nFlags, p_stPos);

	if (m_stSizeChangingMode.pZDxModif)
	{
		m_stSizeChangingMode . pZDxModif -> Undo (FALSE);
		// ... because the edit manager redoes them
		GetInterface () -> GetMultiDevice () -> GetEditManager () -> AskFor (m_stSizeChangingMode . pZDxModif);
	}
	m_stSizeChangingMode.pZDxModif = NULL;

    return FALSE;    // We do not use the message, so the hierarchy editor can make the end of a move
//ENDROMTEAM WorldEditor (Cristi Petrescu)
}

//ROMTEAM WorldEditor (Cristi Petrescu 12/97)

//-----------------------------------------------------------------------------
// Class ZDx_Interface - OnLButtonDblClk
// Double clic on the left button : we launch the dialog for changing the objects
//-----------------------------------------------------------------------------
BOOL ZDx_Interface::_OnLButtonDblClk (UINT nFlags, tdstMousePos *p_stPos, ACP_tdxIndex xIndex, HIE_tdstPickInfo *p_stPickInfo)
{
	// BEGIN CPA2 Cristi Petrescu 97-11-18
	CString TypeList [5] = { C_szZddName , C_szZdeName , C_szZdmName , C_szZdrName , C_szBoundingVolumeName};
    CPA_List<CPA_SuperObject> * pSelectedSuperObjectList = GetInterface () -> GetMouseSelection (xIndex , p_stPickInfo , TypeList , 5);
    // if the list is empty, we do nothing
    if (pSelectedSuperObjectList -> IsEmpty ())  
		return FALSE;
    // else, we select the first super object in the list
    CPA_SuperObject * pSelectedSuperObject = pSelectedSuperObjectList -> GetHeadElement ();

    ZDx_Object * pZDxObject = (ZDx_Object *) pSelectedSuperObject -> GetObject ();

    // if the pointed ZDx object is not the actual selected ZDx object, we select it
    if (pZDxObject != m_pEditWindow -> GetZDxObjectEdited ())
    {
        GetInterface () -> fn_vCancelCurrentSelection (FALSE);
        GetInterface () -> fn_vAddSelectedObject (pSelectedSuperObject , TRUE);
    }

	// we will make a modification, so we might wanna undo it
	ZDx_Modif *pZDxModif = new ZDx_Modif (m_pEditWindow -> GetZDxObjectEdited () , "Edit ZDx");

	if (pZDxObject -> GetZDxShape () -> GetGeometric3dObject () -> _OnLButtonDblClk (nFlags, p_stPos, xIndex, p_stPickInfo))
	{
		pZDxModif -> Undo (FALSE);
		// ... because the edit manager redoes them
		GetInterface () -> GetMultiDevice () -> GetEditManager () -> AskFor (pZDxModif);
	}

	return FALSE;
}

//ENDROMTEAM WorldEditor (Cristi Petrescu)


//*****************************************************************************
//                    Internal functions for questions
//*****************************************************************************


//-----------------------------------------------------------------------------
// Class ZDx_Interface - AcceptModifInsertZDxOfActor
// This function is called before a ZDx of actor is inserted into the hierarchy
//-----------------------------------------------------------------------------
BOOL ZDx_Interface::AcceptModifInsertZDxOfActor (CPA_SuperObject * pSuperObjectToInsert , CPA_SuperObject * pParent)
{
   // The parent must be an actor
    CPA_BaseObject * pActor = pParent -> GetObject ();
    ASSERT (pActor -> fn_bIsOfType (C_szActorInstanceTypeName));

    // We check if the selected position in the list of zones is empty
    tdeZDxType eZDxType;
    long       lPosition;
    if (m_pList2Window -> GetSelectedZDx (& eZDxType , & lPosition) != NULL || lPosition == -1)
    {
        // if not, we try to select a empty position. If there is not, don't accept the insertion
        if (! m_pList2Window -> SelectZDx (NULL , TRUE))  return FALSE;

        m_pList2Window -> GetSelectedZDx (& eZDxType , & lPosition);
    }

    // Insert the ZDx into the selected position
    ZDx_Object * pZDxObject = (ZDx_Object *) pSuperObjectToInsert -> GetObject ();
    ASSERT (eZDxType == pZDxObject -> GetZDxType ());
    SetZDxObjectInList (pActor , eZDxType , lPosition , pZDxObject , eZDxNormal);

    return TRUE;
}

//-----------------------------------------------------------------------------
// Class ZDx_Interface - AcceptModifInsertZDxOfModule
// This function is called before a ZDx of module is inserted into the hierarchy
//-----------------------------------------------------------------------------
BOOL ZDx_Interface::AcceptModifInsertZDxOfModule (CPA_SuperObject * pSuperObjectToInsert , CPA_SuperObject * pParent)
{
    // The parent must be a Physical Object
    ASSERT (pParent -> GetObject () -> fn_bIsOfType (C_szPhysicalObjectTypeName));
    EditorPO * pPhysicalObject = (EditorPO *) pParent -> GetObject ();

    ZDx_Object * pZDxObject    = (ZDx_Object *) pSuperObjectToInsert -> GetObject ();
    tdeZDxType   eZDxType      = pZDxObject -> GetZDxType ();

    // We see if the physical object already has a ZDx with the same type
    if (GetZDxOfPhysicalObject (pPhysicalObject , eZDxType))
    {
        CString Message = "The module already has a ";
        Message        += GetZDxTypeName (eZDxType);
        MessageBox (NULL , Message , "Warning" , MB_OK + MB_ICONSTOP + MB_TASKMODAL);
        return FALSE;
    }

    // We set the ZDx into the physical object
    SetZDxOfPhysicalObject (pPhysicalObject , pZDxObject , eZDxType);

    return TRUE;
}

//-----------------------------------------------------------------------------
// Class ZDx_Interface - AcceptModifInsertBoundingVolume
// This function is called before a ZDx which is a bounding volume is inserted into the hierarchy
//-----------------------------------------------------------------------------
BOOL ZDx_Interface::AcceptModifInsertBoundingVolume (CPA_SuperObject * pSuperObjectToInsert , CPA_SuperObject * pParent)
{
   // The parent must be an actor
    CPA_BaseObject * pActor = pParent -> GetObject ();
    ASSERT (pActor -> fn_bIsOfType (C_szActorInstanceTypeName));

    // The selected position in list 2 must be empty
    return m_pList2Window -> GetSelectedZDx () == NULL;
}

//-----------------------------------------------------------------------------
// Class ZDx_Interface - AcceptModifInsertTestPoint
// This function is called before a ZDx which is a test point is inserted into the hierarchy
//-----------------------------------------------------------------------------
// ANNECY AV CLEAN_MEC {
/*
BOOL ZDx_Interface::AcceptModifInsertTestPoint (CPA_SuperObject * pSuperObjectToInsert , CPA_SuperObject * pParent)
{
   // The parent must be an actor
    CPA_BaseObject * pActor = pParent -> GetObject ();
    ASSERT (pActor -> fn_bIsOfType (C_szActorInstanceTypeName));

    // We check if the selected position in the list of zones is empty
    if (m_pList2Window -> GetSelectedZDx () != NULL)
    {
        // if not, we try to select a empty position. If there is not, don't accept the insertion
        if (! m_pList2Window -> SelectZDx (NULL , TRUE))  return FALSE;
    }

    return TRUE;
}
*/
// END ANNECY AV }

//*****************************************************************************
//                   Internal functions for modifications
//*****************************************************************************


//-----------------------------------------------------------------------------
// Class ZDx_Interface - OnInsertActor
// Called when an actor is inserted into the hierarchy
//-----------------------------------------------------------------------------
void ZDx_Interface::OnInsertActor (CPA_SuperObject * _pActorSuperObject)
{
    IWillRefreshDisplay                   (C_lOnInsertActor);
    m_pList1Window -> ReCreateCurrentList ();
    RefreshDisplay                        (C_lOnInsertActor , FALSE);    // Hierarchy editor will refresh the display
}

//-----------------------------------------------------------------------------
// Class ZDx_Interface - OnDeleteActor
// Called when an actor is deleted from the hierarchy
//-----------------------------------------------------------------------------
void ZDx_Interface::OnDeleteActor (CPA_SuperObject * _pActorSuperObject)
{
    IWillRefreshDisplay                   (C_lOnDeleteActor);
    m_pList1Window -> ReCreateCurrentList ();
    RefreshDisplay                        (C_lOnDeleteActor , FALSE);    // Hierarchy editor will refresh the display
}

//-----------------------------------------------------------------------------
// Class ZDx_Interface - OnInsertZDxOfActor
// Called when a ZDx of actor is inserted into the hierarchy
//-----------------------------------------------------------------------------
void ZDx_Interface::OnInsertZDxOfActor (CPA_SuperObject * _pZDxSuperObject , CPA_SuperObject * _pActorSuperObject)
{
    IWillRefreshDisplay (C_lOnInsertZDxOfActor);

    // We refresh the position of the ZDx object
    ZDx_Object * pZDxObject = (ZDx_Object *) _pZDxSuperObject -> GetObject ();
    pZDxObject -> GetZDxShape () -> RefreshData (_pZDxSuperObject);

	//CPA2 Stegaru Cristian 98-04
	//if necessary, add new zone to the bounding volume
	if ((pZDxObject->GetZDxType() == eZdm) ||(pZDxObject->GetZDxType() == eZdr))
   	{
		ACP_tdxHandleOfObject hGeomObject = (ACP_tdxHandleOfObject)pZDxObject->GetData ();
		CPA_Actor *pActor = (CPA_Actor *)_pActorSuperObject->GetObject ();
		CPA_Family *pFamily = pActor->m_pub_fn_pclGetFamily();
		CPA_BaseObject *pBVolume = pFamily->mfn_p_oGetBoundingVolume ();
		MTH3D_tdstVector	stCenter;
		MTH_tdxReal			xRadius;
		if (NULL != pBVolume) //the actor has a bounding volume
		{
			ACP_tdxHandleOfObject hBoundingVolume = (ACP_tdxHandleOfObject)pBVolume->GetData ();
			if (mfn_bObjectIsOutsideTheBV ((ZDx_Object *)pBVolume, pZDxObject))
			{
				if (IDYES == AfxMessageBox ("New zone is outside the bounding volume. Do you want to adjust the bounding volume?", MB_YESNO | MB_ICONQUESTION))
				{
					GEO_fn_vAddObjectToSphere(hGeomObject, &stCenter, &xRadius);
	//ANNECY TQ 19/06/98{
					GEO_fn_vSetGeometricSphere(&stCenter, xRadius, hBoundingVolume);
					((ZDx_Object *)pBVolume)->fn_vNotifySave ();
	//ENDANNECY TQ}

				}
			}
		}
	}
	//End CPA2 Stegaru Cristian 98-04

    // We put the ZDx object at its correct position into the list of zone
    SetZDxObjectInList (_pActorSuperObject -> GetObject () , pZDxObject -> GetZDxType () , pZDxObject -> GetIndexInList () ,
                        pZDxObject , eZDxModifyAllActors);

    // We refresh the current list
    m_pList1Window -> SelectZDxOfActor (_pActorSuperObject -> GetObject () , pZDxObject , TRUE);

    RefreshDisplay (C_lOnInsertZDxOfActor , FALSE);    // Hierarchy editor will refresh the display
}

//-----------------------------------------------------------------------------
// Class ZDx_Interface - OnDeleteZDxOfActor
// Called when a ZDx of actor is deleted from the hierarchy
//-----------------------------------------------------------------------------
void ZDx_Interface::OnDeleteZDxOfActor (CPA_SuperObject * _pZDxSuperObject , CPA_SuperObject * _pActorSuperObject)
{
    // check if this is really an actor
	if (_pActorSuperObject->GetObject() && _pActorSuperObject->GetObject()->fn_bIsOfType (C_szActorInstanceTypeName))
	{
		IWillRefreshDisplay (C_lOnDeleteZDxOfActor);

		// We get the list of ZDx of the actor
		ZDx_Object     * pZDxObject = (ZDx_Object *) _pZDxSuperObject -> GetObject ();
		CPA_BaseObject * pActor     = _pActorSuperObject -> GetObject ();
		EdtList * pListOfZDx = GetZDxList (pActor , pZDxObject -> GetZDxType ());
		ASSERT (pListOfZDx);

		// We remove the ZDx object from the list
		RemoveZDxFromList (pListOfZDx , pZDxObject , pActor , TRUE);

		tdeZDxType eZDxType;
		long       lPosition;
		m_pList2Window -> GetSelectedZDx      (& eZDxType , & lPosition);
		m_pList1Window -> ReCreateCurrentList ();
		m_pList2Window -> SelectZDx           (eZDxType , lPosition);

		RefreshDisplay (C_lOnDeleteZDxOfActor , FALSE);    // Hierarchy editor will refresh the display
	}
	else
		OnDeleteZDxOfModule(_pZDxSuperObject, _pActorSuperObject);
}

//-----------------------------------------------------------------------------
// Class ZDx_Interface - OnInsertZDxOfModule
// Called when a ZDx of module is inserted into the hierarchy
//-----------------------------------------------------------------------------
void ZDx_Interface::OnInsertZDxOfModule (CPA_SuperObject * _pZDxSuperObject , CPA_SuperObject * _pModuleSuperObject)
{
    IWillRefreshDisplay (C_lOnInsertZDxOfModule);

    ZDx_Object * pZDxObject = (ZDx_Object *) _pZDxSuperObject    -> GetObject ();
    EditorPO   * pModule    = (EditorPO   *) _pModuleSuperObject -> GetObject ();

    // We refresh the position of the ZDx object
    pZDxObject -> GetZDxShape () -> RefreshData (_pZDxSuperObject);

    // We put the ZDx object into the physical object
    SetZDxOfPhysicalObject (pModule , pZDxObject , pZDxObject -> GetZDxType ());

    // We refresh the current list
    m_pList1Window -> SelectZDxOfModule (pModule , pZDxObject , TRUE);

    RefreshDisplay (C_lOnInsertZDxOfModule , FALSE);    // Hierarchy editor will refresh the display
}

//-----------------------------------------------------------------------------
// Class ZDx_Interface - OnDeleteZDxOfModule
// Called when a ZDx of module is deleted from the hierarchy
//-----------------------------------------------------------------------------
void ZDx_Interface::OnDeleteZDxOfModule (CPA_SuperObject * _pZDxSuperObject , CPA_SuperObject * _pModuleSuperObject)
{
    IWillRefreshDisplay (C_lOnDeleteZDxOfModule);

    ZDx_Object * pZDxObject = (ZDx_Object *) _pZDxSuperObject    -> GetObject ();
    EditorPO   * pModule    = (EditorPO   *) _pModuleSuperObject -> GetObject ();

    // We remove the ZDx object from the physical object
    SetZDxOfPhysicalObject (pModule , NULL , pZDxObject -> GetZDxType ());
	ShowZDxOfModule (_pModuleSuperObject , C_ucHideAllZDx , NULL);

    m_pList1Window -> ReCreateCurrentList ();

    RefreshDisplay (C_lOnDeleteZDxOfModule , FALSE);    // Hierarchy editor will refresh the display
}

//-----------------------------------------------------------------------------
// Class ZDx_Interface - OnInsertBoundingVolume
// Called when a ZDx that is a bounding volume is inserted into the hierarchy
//-----------------------------------------------------------------------------
void ZDx_Interface::OnInsertBoundingVolume (CPA_SuperObject * _pBoundingVolumeSuperObject , CPA_SuperObject * _pActorSuperObject, BOOL bCreateBdV)
{
    IWillRefreshDisplay (C_lOnInsertBV);

    ZDx_Object     * pBoundingVolume = (ZDx_Object *) _pBoundingVolumeSuperObject -> GetObject ();
    CPA_BaseObject * pActor          = _pActorSuperObject -> GetObject ();

    // We get the family of the actor
    CPA_Family * pFamily = (CPA_Family *) pActor -> GetOwner () -> GetOwner ();
    // We set the reference to the new bounding volume
    pFamily -> mfn_vSetBoundingVolume (pBoundingVolume);

	m_pList2Window -> CreateBoundingVolume (_pActorSuperObject , pBoundingVolume, TRUE, bCreateBdV);

    SetAspectOfZDx (_pBoundingVolumeSuperObject , TRUE);

    RefreshDisplay (C_lOnInsertBV , FALSE);    // Hierarchy editor will refresh the display
}

//-----------------------------------------------------------------------------
// Class ZDx_Interface - OnDeleteBoundingVolume
// Called when a ZDx that is a bounding volume is deleted from the hierarchy
//-----------------------------------------------------------------------------
void ZDx_Interface::OnDeleteBoundingVolume (CPA_SuperObject * _pBoundingVolumeSuperObject , CPA_SuperObject * _pActorSuperObject)
{
    IWillRefreshDisplay (C_lOnDeleteBV);

    ZDx_Object     * pBoundingVolume = (ZDx_Object *) _pBoundingVolumeSuperObject -> GetObject ();
    CPA_BaseObject * pActor          = _pActorSuperObject -> GetObject ();

    // We get the family of the actor
    CPA_Family * pFamily = (CPA_Family *) pActor -> GetOwner () -> GetOwner ();
    // We set the reference of the bounding volume to NULL
    pFamily -> mfn_vSetBoundingVolume (NULL);

    m_pList2Window -> CreateBoundingVolume (_pActorSuperObject , NULL);

    RefreshDisplay (C_lOnDeleteBV , FALSE);    // Hierarchy editor will refresh the display
}

//-----------------------------------------------------------------------------
// Class ZDx_Interface - OnInsertTestPoint
// Called when a ZDx that is a test point is inserted into the hierarchy
//-----------------------------------------------------------------------------
// ANNECY AV CLEAN_MEC {
/*
void ZDx_Interface::OnInsertTestPoint (CPA_SuperObject * _pTestPointSuperObject , CPA_SuperObject * _pActorSuperObject)
{
    IWillRefreshDisplay (C_lOnInsertTestPoint);

    ZDx_Object         * pZDxObject       = (ZDx_Object *) _pTestPointSuperObject -> GetObject ();
    CPA_TestPointsList * pListOfTestPoint = m_pList2Window -> GetListOfTestPoint ();

    CPA_TestPointNode * pTestPoint;
    if (pZDxObject -> GetTestPoint ())
    {
        pTestPoint = pZDxObject -> GetTestPoint ();
        // Reinsert the test point into the list of test points
        pListOfTestPoint -> m_oListOfTestPoints . AddTail (pTestPoint);
    }
    else
    {
        // We ask the Family tool dll to create a new test point
        CPA_ToolDLLBase * pFamilyDll = GetMainWorld () -> GetToolDLLWithName (C_szDLLFamilyName);
        ASSERT (pFamilyDll);
        // This create a new test point and put it into the current list of test points
        pTestPoint = (CPA_TestPointNode *) pFamilyDll -> OnQueryAction (this , C_uiGetTestPoint , (LPARAM) pListOfTestPoint);
        pTestPoint -> SetZdxObject (pZDxObject);
        pTestPoint -> SetKindOfPoint (m_pList2Window -> GetTypeOfSelectedTestPoint ());
        pZDxObject -> SetTestPoint (pTestPoint);
    }

    // We refresh the position of the ZDx object
    pZDxObject -> GetZDxShape () -> RefreshData (_pTestPointSuperObject);

    MTH3D_tdstVector stPosition = pZDxObject -> GetZDxShape () -> GetCenter ();
    pTestPoint -> SetPosition (& stPosition);

    m_pList2Window -> CreateListOfTestPoint (_pActorSuperObject , pListOfTestPoint);
    pListOfTestPoint -> fn_vNotifySave ();

    RefreshDisplay (C_lOnInsertTestPoint , FALSE);    // Hierarchy editor will refresh the display
}
*/
// END ANNECY AV }

//-----------------------------------------------------------------------------
// Class ZDx_Interface - OnDeleteTestPoint
// Called when a ZDx that is a test point is deleted from the hierarchy
//-----------------------------------------------------------------------------
// ANNECY AV CLEAN_MEC {
/*
void ZDx_Interface::OnDeleteTestPoint (CPA_SuperObject * _pTestPointSuperObject , CPA_SuperObject * _pActorSuperObject)
{
    IWillRefreshDisplay (C_lOnDeleteTestPoint);

    // We get the ZDx object
    ZDx_Object * pZDxObject = (ZDx_Object *) _pTestPointSuperObject -> GetObject ();
    // We get the current list of test points
    CPA_TestPointsList * pListOfTestPoint = m_pList2Window -> GetListOfTestPoint ();

    // We find the test point of the list that have this ZDx object
    POSITION PosTestPoint = pListOfTestPoint -> m_oListOfTestPoints . GetHeadPosition ();
    CPA_TestPointNode * pTestPoint;
    while (PosTestPoint)
    {
        pTestPoint = pListOfTestPoint -> m_oListOfTestPoints . GetAt (PosTestPoint);
        if (pTestPoint -> mfn_p_oGetZdxObject () == pZDxObject)  break;

        pListOfTestPoint -> m_oListOfTestPoints . GetNext (PosTestPoint);
    }
    ASSERT (PosTestPoint);    // PosTestPoint == NULL --> not found -> error

    // Remove the test point from the list but do not delete it (in case of Undo)
    pListOfTestPoint -> m_oListOfTestPoints . RemoveAt (PosTestPoint);

    m_pList2Window -> CreateListOfTestPoint (_pActorSuperObject , pListOfTestPoint);
    pListOfTestPoint -> fn_vNotifySave ();

    RefreshDisplay (C_lOnDeleteTestPoint , FALSE);    // Hierarchy editor will refresh the display
}
*/
// END ANNECY AV }

//-----------------------------------------------------------------------------
// Class ZDx_Interface - OnSelectActor
// Called when an actor is selected or unselected
//-----------------------------------------------------------------------------
void ZDx_Interface::OnSelectActor (CPA_SuperObject * _pActorSuperObject , tdeTypeModif eType)
{
    // If we are editing a bounding volume, we do nothing
    if (m_pList1Window -> IsEditingBoundingVolume ())  return;

    CPA_BaseObject * pActor = _pActorSuperObject -> GetObject ();

    m_bIsSelectingObject = TRUE;

    if (eType != C_EDTUndo)                                // Selection of an actor
    {
        IWillRefreshDisplay (C_lOnSelectActor);

        ShowZDxOfActor (_pActorSuperObject , m_pList2Window -> GetZDxTypeToShow ());

        if (! m_bIsAskingToSelectObject)  m_pList1Window -> SelectInstance (pActor , FALSE);

        RefreshDisplay (C_lOnSelectActor , FALSE);    // Interface will refresh the display
    }
    else m_pActorSuperObjectToUnselect = _pActorSuperObject;      // Unselection of an actor

    m_bIsSelectingObject = FALSE;
}

//-----------------------------------------------------------------------------
// Class ZDx_Interface - OnSelectZDxOfActor
// Called when a ZDx of actor is selected or unselected
//-----------------------------------------------------------------------------
void ZDx_Interface::OnSelectZDxOfActor (CPA_SuperObject * _pZDxSuperObject , CPA_SuperObject * _pActorSuperObject , tdeTypeModif eType)
{
    m_bIsSelectingObject = TRUE;

    ZDx_Object     * pZDxObject = (ZDx_Object *) _pZDxSuperObject -> GetObject ();
    CPA_BaseObject * pActor     = _pActorSuperObject -> GetObject ();

    if (eType != C_EDTUndo)                                // Selection of a ZDx of an actor
    {
        IWillRefreshDisplay (C_lOnSelectZDxOfActor);

        if (! m_bIsAskingToSelectObject)  m_pList1Window -> SelectZDxOfActor (pActor , pZDxObject , FALSE);

        ShowZDxOfActor (_pActorSuperObject , m_pList2Window -> GetZDxTypeToShow () , pZDxObject);

        RefreshDisplay (C_lOnSelectZDxOfActor , FALSE);    // Interface will refresh the display
    }
    else m_pActorSuperObjectToUnselect = _pActorSuperObject;      //  Unselection of a ZDx of an actor

    m_bIsSelectingObject = FALSE;
}

//-----------------------------------------------------------------------------
// Class ZDx_Interface - OnSelectedModule
// Called when a module is selected or unselected
//-----------------------------------------------------------------------------
void ZDx_Interface::OnSelectModule (CPA_SuperObject * _pModuleSuperObject , tdeTypeModif eType)
{
    m_bIsSelectingObject = TRUE;

    if (eType != C_EDTUndo)                                // Selection of a module
    {
        ShowZDxOfModule (_pModuleSuperObject , m_pList2Window -> GetZDxTypeToShow ());

        if (! m_bIsAskingToSelectObject)  m_pList1Window -> SelectModule (_pModuleSuperObject -> GetObject () , FALSE);
    }
    else m_pModuleSuperObjectToUnselect = _pModuleSuperObject;    // Unselection of a module

    m_bIsSelectingObject = FALSE;
}

//-----------------------------------------------------------------------------
// Class ZDx_Interface - OnSelectZDxOfModule
// Called when a ZDx of a module is selected or unselected
//-----------------------------------------------------------------------------
void ZDx_Interface::OnSelectZDxOfModule (CPA_SuperObject * _pZDxSuperObject , CPA_SuperObject * _pModuleSuperObject , tdeTypeModif eType)
{
    m_bIsSelectingObject = TRUE;

    ZDx_Object * pZDxObject = (ZDx_Object *) _pZDxSuperObject    -> GetObject ();
    EditorPO   * pModule    = (EditorPO   *) _pModuleSuperObject -> GetObject ();

    if (eType != C_EDTUndo)                                // Selection of a ZDx of a module
    {
        ShowZDxOfModule (_pModuleSuperObject , m_pList2Window -> GetZDxTypeToShow () , pZDxObject);

        if (! m_bIsAskingToSelectObject)  m_pList1Window -> SelectZDxOfModule (pModule , pZDxObject , FALSE);
    }
    else m_pModuleSuperObjectToUnselect = _pModuleSuperObject;    //  Unselection of a ZDx of a module

    m_bIsSelectingObject = FALSE;
}

//-----------------------------------------------------------------------------
// Class ZDx_Interface - OnSelectBoundingVolume
// Called when a ZDx that is a bounding volume is selected or unselected
//-----------------------------------------------------------------------------
void ZDx_Interface::OnSelectBoundingVolume (CPA_SuperObject * _pZDxSuperObject , CPA_SuperObject * _pModuleSuperObject , tdeTypeModif eType)
{
    // We do nothing when the user tries to select or unselect a bounding volume
}

//-----------------------------------------------------------------------------
// Class ZDx_Interface - OnSelectTestPoint
// Called when a ZDx that is a test point is selected or unselected
//-----------------------------------------------------------------------------
// ANNECY AV CLEAN_MEC {
/*
void ZDx_Interface::OnSelectTestPoint (CPA_SuperObject * _pZDxSuperObject , CPA_SuperObject * _pModuleSuperObject , tdeTypeModif eType)
{
    //???
}
*/
// END ANNECY AV }

//ROMTEAM WorldEditor (Cristi Petrescu 12/97)
//////////////////////////////////////////////////////////////////////////////////////////////////////
// Method : long ZDx_Interface::m_lGetTypeOfZoneByGeometricObject(Geometry3D * pGeometry3D)
// Date   : 97.12.12
//////////////////////////////////////////////////////////////////////////////////////////////////////
// Description : 
//  Tells the type of the zone which have its geometric3d member equal with the supplied geometric object
//  Done by searching the list of zones. Hmmm, not very efficient
// Author      : Cristi Petrescu
//////////////////////////////////////////////////////////////////////////////////////////////////////
// Modification :
// Date         :
// By           :
//////////////////////////////////////////////////////////////////////////////////////////////////////
long ZDx_Interface::m_lGetTypeOfZoneByGeometricObject(Geometry3D * pGeometry3D)
{
	Position xPos;
	ZDx_Object *poZoneObject;
	int iZoneType;
// ANNECY AV CLEAN_MEC {
	char *a6szZoneTypeName[6] = {C_szZddName,
								 C_szZdeName,
								 C_szZdrName,
								 C_szZdmName,
								 C_szBoundingVolumeName/*,
								 C_szTestPointName*/};

	// search in all six lists
	// it seems that is no ForEach implemented for the objects in a editor
	for (iZoneType = 0; iZoneType < 5/*6*/; iZoneType++)
// END ANNECY AV }
	{
		CPA_BaseObjectList *poZoneObjectList = GetBaseObjectList (a6szZoneTypeName [iZoneType]);
		for (xPos = poZoneObjectList -> GetHeadPosition (); xPos; poZoneObjectList -> GetNext(xPos))
		{
			poZoneObject = 	(ZDx_Object *) poZoneObjectList -> GetAt (xPos);
			if (poZoneObject -> GetZDxShape () -> GetGeometric3dObject () == pGeometry3D)
				// this is the one
				return poZoneObject -> GetDataType ();
		}
	}
		
	return -1;
}
//ENDROMTEAM WorldEditor (Cristi Petrescu)

//CPA2 (Corneliu Babiuc) 15-04-1998
//////////////////////////////////////////////////////////////////////////////////////////////////////
// Method : void ZDx_Interface::MoveBackZone(CPA_SuperObject * pZDxSuperObject, 
//                                           MTH3D_tdstVector * p_stVector)
// Date   : 15-04-1998
//////////////////////////////////////////////////////////////////////////////////////////////////////
// Description : 
//  Sets the local translation vector of a zone to keep unchanged its global position
//  This is done recalculating the local translation from its father global move
// Parameters:
//  _pZDxSuperObject       - pointer to zone superobjects who has to be moved
//  p_stVector             - pointer to MTH3D_tdstVector representing the global deplacement
//                         if it is NULL recompute the position
// Author      : Corneliu Babiuc
//////////////////////////////////////////////////////////////////////////////////////////////////////

void ZDx_Interface::MoveBackZone(CPA_SuperObject * _pZDxSuperObject, MTH3D_tdstVector * p_stVector)
{
	ZDx_Object       * pZDxObject         = (ZDx_Object *) _pZDxSuperObject -> GetObject();
    CPA_SuperObject  * pActorSuperObject  = _pZDxSuperObject->GetSuperObjectFather();

	MTH3D_tdstVector   stFatherVector, stCurrentVector, stTempVector, stVector;
	POS_tdstCompletePosition * p_stMatrix,stMatrix;

	if (!p_stVector)
	{
		//get the global translation of super object
		//in this moment it is supposed to not be calculated to the new position!
		POS_fn_vGetTranslationVector (HIE_fn_hGetSuperObjectGlobalMatrix(_pZDxSuperObject->GetStruct()),
									&stFatherVector); 
		//get the local translation of super object father
		//it is recalculated acording to the new position
		POS_fn_vGetTranslationVector (HIE_fn_hGetSuperObjectMatrix(pActorSuperObject->GetStruct()),
									&stCurrentVector);
		//recalculate the new global position of father and get the deplacement substracting the two vectors
		ConvertVectorLocalToGlobal(&stTempVector, HIE_fn_hGetSuperObjectGlobalMatrix(HIE_fn_hGetSuperObjectFather(pActorSuperObject->GetStruct())), 
									&stCurrentVector);
		MTH3D_M_vSubVector(&stTempVector, &stFatherVector, &stTempVector);
	}
	else MTH3D_M_vCopyVector(&stTempVector, p_stVector);

	POS_fn_vSetIdentityMatrix(&stMatrix);
	// update vector according to object's position
	POS_fn_vInvertMatrix(&stMatrix,HIE_fn_hGetSuperObjectGlobalMatrix(
								HIE_fn_hGetSuperObjectFather(_pZDxSuperObject->GetStruct())));
	MTH3D_M_vNullVector(&stVector);
	POS_fn_vSetTranslationVector(&stMatrix, &stVector);
	POS_fn_vMulMatrixVertex(&stVector, &stMatrix, &stTempVector);
	// update the translation vector of the object
	p_stMatrix = HIE_fn_hGetSuperObjectMatrix(_pZDxSuperObject->GetStruct());
	POS_fn_vSetTranslationVector(p_stMatrix, &stVector);
	POS_fn_vNormalizeMatrix(p_stMatrix); 
	//the global matrix of zone must not be set to the new position. 
	//This will be done when the move has finished
}
//END CPA2 (Corneliu Babiuc) 23-04-1998
//////////////////////////////////////////////////////////////////////////////////////////////////////
// Method : mfn_bObjectIsOutsideTheBV 
// Date   : 98-04
//////////////////////////////////////////////////////////////////////////////////////////////////////
// Description :
// Author      : Stegaru Cristian - CPA2
//////////////////////////////////////////////////////////////////////////////////////////////////////
// Modification :
// Date         :
// By           :
//////////////////////////////////////////////////////////////////////////////////////////////////////
BOOL ZDx_Interface::mfn_bObjectIsOutsideTheBV (ZDx_Object *pBVolume, ZDx_Object *pZDxObject)
{
	GLI_tdxValue tdxMasterRadius, tdxSlaveRadius;
	MTH3D_tdstVector tdstMasterCenter, tdstSlaveCenter;
	ZDx_Shape  *pBVShape = pBVolume->GetZDxShape ();
	Sphere3D   *pBVSphere = (Sphere3D *)pBVShape->GetGeometric3dObject ();

	tdeZDxGeometricType eBVGeometricType = pBVolume->GetZDxGeometricType ();
	if (eSphere == eBVGeometricType)
	{
		tdxMasterRadius = pBVSphere->GetRadius ();
		tdstMasterCenter = pBVSphere->GetCenter ();
	}
	else //treat the case as it is a sphere
	{
		ACP_tdxHandleOfObject hBoundingVolume = (ACP_tdxHandleOfObject)pBVolume->GetData ();
//ANNECY TQ 22/06/98{
		GEO_fn_vGetInfoFromGeometricSphere(&tdstMasterCenter, &tdxMasterRadius, hBoundingVolume );
//ENDANNECY TQ}
	}

	ZDx_Shape  *pZDxShape = pZDxObject->GetZDxShape ();
	Shape3D    *pZDxGeometric3dObject = pZDxShape->GetGeometric3dObject ();
	tdeZDxGeometricType eZDxGeometricType = pZDxObject->GetZDxGeometricType ();
	switch (eZDxGeometricType)
	{
	case eSphere:
		tdxSlaveRadius = ((Sphere3D *)pZDxGeometric3dObject)->GetRadius ();
		tdstSlaveCenter = ((Sphere3D *)pZDxGeometric3dObject)->GetCenter ();
		break;
	case eBox:
		{
			MTH3D_tdstVector tdstMaxPoint = ((Box3D *)pZDxGeometric3dObject)->GetMaxPoint ();
			MTH3D_tdstVector tdstMinPoint = ((Box3D *)pZDxGeometric3dObject)->GetMinPoint ();
			GEO_fn_vGetSphereFromParallelBox(&tdstSlaveCenter, &tdxSlaveRadius, &tdstMaxPoint, &tdstMinPoint);
		}
		break;
	case eCone:
		{
			Cone3D *pCone = (Cone3D *)pZDxGeometric3dObject;
			MTH3D_tdstVector tdstTop = pCone->GetTopPoint ();
			MTH3D_tdstVector tdstBase = pCone->GetBasePoint ();
			GLI_tdxValue tdxCRadius = pCone->GetRadius ();
			//cone height
			GLI_tdxValue tdxCHeight = (GLI_tdxValue)sqrt (pow (tdstTop.xX - tdstBase.xX, 2) +
														  pow (tdstTop.xY - tdstBase.xY, 2) +
														  pow (tdstTop.xZ - tdstBase.xZ, 2));
			//sphere radius
			GLI_tdxValue tdxSRadius = (GLI_tdxValue)(pow (tdxCHeight, 2) + pow (tdxCRadius, 2)) / (2 * tdxCHeight);
			//sphere center coordinates
			GLI_tdxValue tdxCt = tdxSRadius / tdxCHeight;
			tdstSlaveCenter.xX = tdstTop.xX + tdxCt * (tdstBase.xX - tdstTop.xX); 
			tdstSlaveCenter.xY = tdstTop.xY + tdxCt * (tdstBase.xY - tdstTop.xY); 
			tdstSlaveCenter.xZ = tdstTop.xZ + tdxCt * (tdstBase.xZ - tdstTop.xZ); 
			tdxSlaveRadius = tdxSRadius;
		}
		break;
	case ePoint:
		tdstSlaveCenter = ((Point3D *)pZDxGeometric3dObject)->GetPoint ();
		tdxSlaveRadius = 0;
		break;
	default:
		ASSERT (FALSE);
	}
	return mfn_bIs1SphereOutsideThe2Sphere (&tdstMasterCenter, tdxMasterRadius, &tdstSlaveCenter, tdxSlaveRadius);
}

//////////////////////////////////////////////////////////////////////////////////////////////////////
// Method : mfn_bIs1SphereOutsideThe2Sphere 
// Date   : 98-04
//////////////////////////////////////////////////////////////////////////////////////////////////////
// Description :
// Author      : Stegaru Cristian - CPA2
//////////////////////////////////////////////////////////////////////////////////////////////////////
// Modification :
// Date         :
// By           :
//////////////////////////////////////////////////////////////////////////////////////////////////////
BOOL ZDx_Interface::mfn_bIs1SphereOutsideThe2Sphere (MTH3D_tdstVector *ptdstMasterCenter, GLI_tdxValue tdxMasterRadius, MTH3D_tdstVector *ptdstSlaveCenter, GLI_tdxValue tdxSlaveRadius)
{
	ASSERT (ptdstMasterCenter);
	ASSERT (ptdstSlaveCenter);
	GLI_tdxValue tdxDistanceBetweenSpheres = (GLI_tdxValue)sqrt (pow (ptdstMasterCenter->xX - ptdstSlaveCenter->xX, 2) + 
												   pow (ptdstMasterCenter->xY - ptdstSlaveCenter->xY, 2) + 
												   pow (ptdstMasterCenter->xZ - ptdstSlaveCenter->xZ, 2));
	return (tdxDistanceBetweenSpheres + tdxSlaveRadius) > tdxMasterRadius;
}

//////////////////////////////////////////////////////////////////////////////////////////////////////
// Method	: mfn_vCheckActorsZonesAndBV 
// Date		: 98-06
//////////////////////////////////////////////////////////////////////////////////////////////////////
// Description	:
// Author		: Stegaru Cristian - CPA
//////////////////////////////////////////////////////////////////////////////////////////////////////
// Modification	: 
// Date			:
// By			:
//////////////////////////////////////////////////////////////////////////////////////////////////////
void ZDx_Interface::mfn_vCheckActorsZonesAndBV (CPA_SuperObject * pActorSuperObject)
{
	//add new zone to the bounding volume
	if (!pActorSuperObject)
		return;

	CPA_Actor *pActor = (CPA_Actor *)pActorSuperObject->GetObject ();
	if (FALSE == pActor->mfn_bGet_CheckZonesAgainstBV ())
		return;

    HINSTANCE hOldInst = AfxGetResourceHandle ();
    AfxSetResourceHandle (GetDLLIdentity () -> hModule);

	CPA_Family *pFamily = pActor->m_pub_fn_pclGetFamily();
	CPA_BaseObject *pBVolume = pFamily->mfn_p_oGetBoundingVolume ();
	CStringList lstZonesList;
	for (int eType = eZdm; eType <= eZdr; eType++)
	{
		EdtList     *pZDxList =  GetZDxList (pActor, (eZDxType_)eType);
		if (pZDxList)
		{
			CPA_SaveObject *pZoneObject = NULL;
			POSITION pos = pZDxList->GetHeadPosition ();
			while (pos)
			{
				pZoneObject = pZDxList->GetNext (pos);
				if (pZoneObject && mfn_bObjectIsOutsideTheBV ((ZDx_Object *)pBVolume, (ZDx_Object *)pZoneObject))
					lstZonesList.AddTail (pZoneObject->GetName ());
			}
		}
	}

	if (!lstZonesList.IsEmpty ())
	{
		CCheckZones dlg (pActor, &lstZonesList);
		if (IDOK == dlg.DoModal ())	//edit the bounding volume
		{
			CPA_List<CPA_BaseObject> ListOfObject;
			ListOfObject.AddTail (pActorSuperObject);
			pActorSuperObject->SetDrawingFlag(E_df_BoundingV);
			GetMainWorld ()->fn_bActivateEditor (this , &ListOfObject);
		}
	}

    AfxSetResourceHandle (hOldInst);
}


