//#################################################################################
//#################################################################################
//#################################################################################
//#################################################################################
//#################################################################################
//
// Section modif disabled
//
// lost last modifications (with tree), recompute it
//
//#################################################################################
//#################################################################################
//#################################################################################
//#################################################################################
//#################################################################################
//#################################################################################
//
// BASE CLASS OF YOUR DLL interface
//
//#################################################################################

#ifdef ACTIVE_EDITOR

#include "stdafx.h"

#include "ACP_Base.h"
#include "incITF.h"			// interface
#include "incGAM.h"

#include "3DGModif.hpp"
#include "3DInterf.hpp"

#include "incGLI.h"
#include "DPT.h"
#include "X:\Cpa\Main\inc\_EditID.h"
#include "ErO.h"

//ROMTEAM WorldEditor (Nicu 16/01/98)
#include "OGD.h"
//ENDROMTEAM WorldEditor (Nicu)

#include "OPD.h"
#include "OIT.h"

//ROMTEAM WorldEditor (Viorel Preoteasa 20/01/98)
#include "DlgCarac.hpp"
//ENDROMTEAM WorldEditor (Viorel Preoteasa)

#include "DlgEditPoints.hpp"

//ROMTEAM WorldEditor (Cristian Stegaru 11/97)
#include "EToolBar.h"
#include "ITView.h"
#include "ITFrame.h"
#include "EdThread.h"
#include "ctriedit.h"
//ENDROMTEAM WorldEditor (Cristian Stegaru)


// infos
static CString g_csOGDName = "Geometry";
static CString g_csOGDAuthor = "Marc Trabucato";
static CString g_csOGDVersion = "V 4.0.3   18/03/98";
static CString g_csOGDFrenchHelpFile = "3DGeom.hlp";
static CString g_csOGDEnglishHelpFile = "";

BOOL g_bTipFirstTime = TRUE;

//--------------------------------------------------------------------------------
// CONSTANTS
//--------------------------------------------------------------------------------

#define C_szGenDoorsDataPath	"Edt_Data\\Objects\\Actors\\Models\\GenDoors"
// PopUp Menu IDs
#define C_ui3DGPopupEdit   10
#define C_ui3DGPopupExit   11
#define C_ui3DGPopupSwap   12
#define C_ui3DGPopupPref   13
// ANNECY MT 23/02/98 {
#define C_ui3DGPopupShowBdV	14
#define C_ui3DGPopupHideBdV 15
// END ANNECY MT }

// List name of DialogList
#define C_szHierarchyList   "World"

// the Keyboard configuration
#define KA_3DG_CTRL     1
#define KA_3DG_SHIFT    2
//CPA2 Corneliu Babiuc 02-09-98 (duplicated points)
#define KA_3DG_DPOINTS  3
#define KA_3DG_UPOINTS  4

// alternate color for objects having selected points
#define C_eAlternateColor E_lc_Violet

const GLI_tdxValue      C_xErrorFactor = 0.005f;
//END CPA2 Corneliu Babiuc 04-09-98 (duplicated points)

// OnQuery
#define C_uiCreateGeometricObject   1
#define C_uiDeleteGeometricObject   2

//--------------------------------------------------------------------------------
// MACROS
//--------------------------------------------------------------------------------

// shortcuts
#define M_RedrawWorld()                                     (M_GetMultiDevice3D()->DrawObject())

#define M_ReturnIfUsePath( szSectionName, szRefPath )       if( ! strnicmp( szSectionName, szRefPath, strlen( szRefPath ) ) ) return szRefPath;

#define M_ForEachElement( oList, oElement, Pos )\
            for( oElement = (oList) . GetHeadElement( Pos ) ; \
                 oElement ; \
                 oElement = (oList) . GetNextElement( Pos ) )

//--------------------------------------------------------------------------------
// STATIC
//--------------------------------------------------------------------------------
double  MTH_gs_dDecal = 3.0F*pow(2, 51);

static tdstKeyboardActionDef gs_a_stAppKeys[] =
{
    {"Multiple selection",   KA_3DG_CTRL},
    {"Sphere selection",     KA_3DG_SHIFT},
//CPA2 Corneliu Babiuc 02-09-98 (duplicated points)
    {"Select duplicated points",    KA_3DG_DPOINTS},
    {"Update duplicated points",    KA_3DG_UPOINTS},
//END CPA2 Corneliu Babiuc 02-09-98 (duplicated points)
    {NULL, 0},
};

// the DLL global definition
tdstDLLIdentity		g_stGeometry3DIdentity;

//--------------------------------------------------------------------------------
// CONSTRUCTOR.
// You must put here all your DLL interface definitions.
//--------------------------------------------------------------------------------
Geometry3D_Interface::Geometry3D_Interface()
{
	// ************************** private internal
	m_p_stDLLIdentity = &g_stGeometry3DIdentity;

    // Does your DLL can output in main game view ?
	m_stBaseDLLDefinition.bCanOutputIn3DView = FALSE;

    // Does your DLL can be refresh by engine ?
	m_stBaseDLLDefinition.bCanBeRefreshedByEngine = FALSE;

    SetCurrent( FALSE );

    SetEditorInfo(g_csOGDName, g_csOGDAuthor, g_csOGDVersion, g_csOGDFrenchHelpFile, g_csOGDEnglishHelpFile);

    //
    m_p_DlgCaract           = NULL;
    m_p_DlgList             = NULL;
    m_p_oKeyConfiguration   = NULL;
    m_bCtrlUsed             = FALSE;
    MTH3D_M_vNullVector(&m_st3DTranslation);
// ANNECY MT 23/02/98 {
	m_bShowBoundingVolume		= FALSE;
    m_p_oBoundingVolumeSprObj	= NULL;
    m_p_oBoundingVolumeObject	= NULL;
    m_p_ModifiedObject          = NULL;
// END ANNECY MT }
    fn_vUnSelect();
    //m_oListOfModifSection . RemoveAll();
	//m_oListOfModificationFiles . RemoveAll();
	// BEGIN CPA2 Cristi Petrescu 98-02-
	mfn_vClearFileModificationsList ();
	// END CPA2 Cristi Petrescu 98-02-
    m_csPreviousSelectMode = "All Types";
    m_oListOfSuperObjectPO . DeleteAllElements();
	// Init ErO Module
	ERROR_g_fn_vAddAModuleDescriptor(C_szOGDModuleNameEro, "v3.9.0",
									 "Marc Trabucato", "0'.50.52.98.84 (Annecy)","mtrabucato@ubisoft.fr",
									 "Daniel PALIX","04 50 51 26 63 (Annecy)","dpalix@ubisoft.fr",
									 "Benoit Germain","04 50 52 90 84 (Annecy)","bgermain@ubisoft.fr" );


//ROMTEAM WorldEditor (Cristian Stegaru 11/97)
	// setup the Shape3D
  Shape3D::SetGeometry3DDLL (this);
	m_pITEditor = NULL;
//ENDROMTEAM WorldEditor (Cristian Stegaru)

//ROMTEAM WorldEditor (Viorel Preoteasa 06/01/98)
//CPA2 Corneliu Babiuc 07-09-98 (duplicated points)
//    m_iNbSelectedPoints = 0;
//END CPA2 Corneliu Babiuc 07-09-98 (duplicated points)
	m_bLButtonIsDown = FALSE;
	m_p_SelectedObject = NULL;
    m_p_SelectedSprObj = NULL;
	m_iDeletePoint = -1;
	m_bShiftUsed = FALSE;
/*CPA2 Corneliu Babiuc 07-09-98 (duplicated points)
	m_fDist = NULL;
	m_xSelectedPointsIndex = NULL;
//END CPA2 Corneliu Babiuc 07-09-98 (duplicated points) */
//ENDROMTEAM WorldEditor (Viorel Preoteasa)
//CPA2 Corneliu Babiuc 03-09-98 (duplicated points)
    m_bSelectDuplicatesMode = FALSE;
    m_bLastMoveWasNormal = TRUE;
//END CPA2 Corneliu Babiuc 16-09-98 (duplicated points)
}


//CPA2 Corneliu Babiuc 14-09-98 (duplicated points)
//--------------------------------------------------------------------------------
// CONSTRUCTOR.
Geometry3D_Interface::~Geometry3D_Interface()
{
    mfn_vClearListOfSelectedPoints();
}
//END CPA2 Corneliu Babiuc 14-09-98 (duplicated points)


//
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
//

///////////////////////////////////////////////////////////////////////////////
// ACP Messages
///////////////////////////////////////////////////////////////////////////////

/////////////////////////
// Begin / End methods //
/////////////////////////

//--------------------------------------------------------------------------------
//
//--------------------------------------------------------------------------------
void Geometry3D_Interface::fn_vJustAfterRegistered()
{
    CString a_csTypeOfObject[] = { C_szGeometricType, C_sz3DFileTypeName };
    CString a_csTypeOfModif[]  = { C_szFormModif, C_szMaterialModif };

    // Type of objects created
    fn_vRegisterObjectsType(a_csTypeOfObject, 2);

    // Type of modification
    fn_vRegisterModificationsType( C_szGeometricType, a_csTypeOfModif, 2 );

	//BEGIN ROMTEAM Cristi Petrescu 98-04-
	SCR_fn_v_RdL0_RegisterCallback( C_szModifListActionName, Geometry3D_Interface::CallBackLoadModifList, SCR_CRC_c_RdL0_ForSection );
	//END ROMTEAM Cristi Petrescu 98-04-
}

//--------------------------------------------------------------------------------
//
//--------------------------------------------------------------------------------
void Geometry3D_Interface::fn_vConstruct()
{
	CString			csFileName;
	char			szDimension[256];
	int				iDim;

	csFileName = M_GetMainApp()->m_csEditorDataPath + "Objects\\3DGeom\\3DGeom.ini";
    // object static init
	Geometry3D::StaticInit( GetMainWorld() );   // must be here (not in fn_vJustAfterRegistered)

    // Frame
	GetPrivateProfileString ("Preference", "Left Frame Width", "200", szDimension, 256, (char*)(LPCSTR)csFileName);
    iDim = atoi(szDimension);

    m_p_oSplitterLeft = new CSplitFrame () ;
    m_p_oSplitterLeft->CreateBase ( "Geometric editor" , 1, 2, GetMainWorld () );
    m_p_oSplitterLeft->m_iInitWidth = iDim;
    m_p_oSplitterLeft->mfn_vEnableCaption(FALSE);
    m_p_oSplitterLeft -> m_stWinRight . cLinkSame = FRM_C_MoveBottom ;

//ROMTEAM WorldEditor (Viorel Preoteasa 20/01/98) 
//    m_p_oSplitterLeft->CreateSplitter ( C_cVerticalSplitter , 2 );
	m_p_oSplitterLeft->CreateSplitter ( C_cVerticalSplitter , 3 );
//ENDROMTEAM WorldEditor (Viorel Preoteasa) 

    // first pane : Dialog list with family list
	GetPrivateProfileString ("Preference", "DialogList Height", "0", szDimension, 256, (char*)(LPCSTR)csFileName);
	iDim = atoi(szDimension);
	m_p_DlgList = new CPA_DialogList;
	m_p_DlgList->fn_vInitDialog(this, m_p_oSplitterLeft);
    m_p_oSplitterLeft->SetPaneView(0, m_p_DlgList, "INSTANCES", iDim );

    // second pane : Caracteristics dialog
    HINSTANCE hOldInst = AfxGetResourceHandle();
    AfxSetResourceHandle( m_p_stDLLIdentity->hModule );

    GetPrivateProfileString ("Preference", "CaracteristicDialog Height", "0", szDimension, 256, (char*)(LPCSTR)csFileName);
	iDim = atoi(szDimension);

    m_p_oSplitterLeft->CreateView ( 1, RUNTIME_CLASS ( CDlgCaract ) , "CARACTERISTICS" , iDim ) ;
    m_p_DlgCaract = (CDlgCaract*)m_p_oSplitterLeft-> m_fn_p_oGetPane ( 1 ) ;
    m_p_DlgCaract -> fn_vSetParentDLL ( this ) ;

//ROMTEAM WorldEditor (Viorel Preoteasa 20/01/98) 
// 3th pane : Edit points dialog
	m_p_oSplitterLeft->CreateView ( 2, RUNTIME_CLASS ( CDlgEditPoints ) , "EDIT POINTS" , iDim ) ;
	m_p_DlgEditPoints = ((CDlgEditPoints*)m_p_oSplitterLeft-> m_fn_p_oGetPane ( 2 ));
	m_p_DlgEditPoints->Init();
//ENDROMTEAM WorldEditor (Viorel Preoteasa) 


    AfxSetResourceHandle( hOldInst );

    // Keyboard
    m_p_oKeyConfiguration = new CPA_KeyActionConfiguration("3DGeom\\3DGeom.ini", gs_a_stAppKeys);
    m_p_oKeyConfiguration->mfn_vSetObjectName("3DGeom Editor");

	// Show Warnings
	GetPrivateProfileString ("Preference", "Show Warnings", "ON", szDimension, 256, (char*)(LPCSTR)csFileName);
	m_bShowWarnings = !strcmpi( szDimension, "ON" );
	m_bStopWarnings = FALSE;
}

//--------------------------------------------------------------------------------
//
//--------------------------------------------------------------------------------
void Geometry3D_Interface::fn_vBeforeEngine(void)
{
    // Frame
    if(fn_bIsCurrentEditor())
    {
	    g_oFrameGest.mfn_vSetRefresh(FALSE);
        g_oFrameGest.mfn_vDisactivateWindow (m_p_oSplitterLeft) ;
        g_oFrameGest.mfn_vSetRefresh(TRUE);
    }
}

//--------------------------------------------------------------------------------
//
//--------------------------------------------------------------------------------
void Geometry3D_Interface::fn_vBeforeEditor(void)
{
    if(fn_bIsCurrentEditor())
    {
        // Dialog Lists
        m_p_DlgList->fn_vInitAllLists();
        m_p_DlgList->fn_vReinitDialog();
        // Frame
	    g_oFrameGest.mfn_vSetRefresh(FALSE);
        g_oFrameGest.mfn_vActivateWindow (m_p_oSplitterLeft) ;
        g_oFrameGest.mfn_vSetRefresh(TRUE);
    }
}

//--------------------------------------------------------------------------------
//
//--------------------------------------------------------------------------------
void Geometry3D_Interface::fn_vBeforeSaveAll(void)
{
    CPA_BaseObjectList *p_oList = GetBaseObjectList( C_szGeometricType );
    Position lPos = p_oList -> GetHeadPosition();
    CString csIdentity;
    char *p_cIdentity;
    CTime oTime = CTime::GetCurrentTime();

    csIdentity = GetInterface() -> GetUserPrefix() + ", " + oTime . Format( "%d/%m/%y   %H:%M" );
    p_cIdentity = (char*)(LPCTSTR)csIdentity;

	// BEGIN CPA2 Cristi Petrescu 98-02-
	tdstModifFile   *p_stModif;
    POSITION        xPos;
	// clear the lists
	M_ForEachElement( m_oListOfModifiedFiles, p_stModif, xPos )
    {
		p_stModif -> oListOfModifiedObjects . RemoveAll ();
	}

    while( lPos )
    {
        Geometry3D *p_oObject = (Geometry3D*) p_oList -> GetNext( lPos );
        //
        if( p_oObject -> mfn_bMustSaveFMD() )
            p_oObject -> mfn_vSaveFMD();
        //
        if( p_oObject -> mfn_bMustSaveModifications() )
        {
			// In order to save the modifications in the .mdf file
			p_oObject -> mfn_vCreateModifSection ();
			// update the lists
			mfn_vAddFileModification (p_oObject);
			
			/*
            char szFileName[SCR_CV_ui_Cfg_MaxLenName];
            FILE *pFile;

            fn_vComputeModificationFile( szFileName, p_oObject );
            // open file
            if( _access( szFileName, 00 ) == -1 )
            {
                // create file
                pFile = fopen( szFileName, "wt" );
                if( pFile == NULL ) return;
                // add header
                fprintf( pFile, "Modifications on objects of file : \"%s\"\n\n", szFileName );
            }
            else
            {
                pFile = fopen( szFileName, "at" );
                if( pFile == NULL ) return;
            }
            p_oObject -> mfn_vSaveModifications( pFile, p_cIdentity );
            fclose( pFile );
			*/
        }
    }

	//delete the unneeded sections, save the others
	xPos = m_oListOfModifiedFiles . GetHeadPosition ();
	POSITION xOldPos = xPos;
	while (xPos)
	{
		p_stModif = m_oListOfModifiedFiles . GetNext (xPos);
		if (p_stModif -> oListOfModifiedObjects . IsEmpty ())
		{
			// delete it!
			p_stModif -> p_oModifSection -> fn_vDeleteSection ();
			m_oListOfModifiedFiles . RemoveAt (xOldPos);
			delete p_stModif -> p_oModifSection;
			delete p_stModif;
		}
		else
		{
			p_stModif -> p_oModifSection -> fn_vWriteSection ();
		}
		xOldPos = xPos;
	}
	//and ready, at last!
	// END CPA2 Cristi Petrescu 98-02-
}

///////////////////////////////////////////////////////////////////////////////
// Windows Messages
///////////////////////////////////////////////////////////////////////////////

//////////////////////
// Keyboard methods //
//////////////////////

//--------------------------------------------------------------------------------
//
//--------------------------------------------------------------------------------
BOOL Geometry3D_Interface::_OnKeyDown(UINT _nChar, UINT, UINT)
{
    if(m_p_oKeyConfiguration->mfn_uwKeyToAction(_nChar) == KA_3DG_CTRL)
        m_bCtrlUsed = TRUE;

//ROMTEAM WorldEditor (Viorel Preoteasa 20/01/98) 
    if(m_p_oKeyConfiguration->mfn_uwKeyToAction(_nChar) == KA_3DG_SHIFT)
		m_bShiftUsed = TRUE;
//ENDROMTEAM WorldEditor (Viorel Preoteasa) 

//CPA2 Corneliu Babiuc 14-09-98 (duplicated points)
    if(m_p_oKeyConfiguration->mfn_uwKeyToAction(_nChar) == KA_3DG_DPOINTS ||
        m_p_oKeyConfiguration->mfn_uwKeyToAction(_nChar) == KA_3DG_UPOINTS)
        // nothing to do, just informs that the key is one of Geometry editor
        return TRUE;
//CPA2 Corneliu Babiuc 14-09-98 (duplicated points)

    return FALSE;
}

//--------------------------------------------------------------------------------
//
//--------------------------------------------------------------------------------
BOOL Geometry3D_Interface::_OnKeyUp(UINT _nChar, UINT, UINT)
{
    if(m_p_oKeyConfiguration->mfn_uwKeyToAction(_nChar) == KA_3DG_CTRL)
        m_bCtrlUsed = FALSE;
//ROMTEAM WorldEditor (Viorel Preoteasa 20/01/98) 
    if(m_p_oKeyConfiguration->mfn_uwKeyToAction(_nChar) == KA_3DG_SHIFT)
		m_bShiftUsed = FALSE;
//ENDROMTEAM WorldEditor (Viorel Preoteasa) 
//CPA2 Corneliu Babiuc 03-09-98 (duplicated points)
    // switch the "Select duplicated points" mode
    if(m_p_oKeyConfiguration->mfn_uwKeyToAction(_nChar) == KA_3DG_DPOINTS)
    {
        m_bSelectDuplicatesMode = !m_bSelectDuplicatesMode;
        CString csMsg;
        csMsg.Format("\"Select duplicated points\" mode is %s ", m_bSelectDuplicatesMode ? "on" : "off");
        M_GetMainWnd()->UpdateStatus((char*)(LPCTSTR)csMsg, C_STATUSPANE_INFOS, C_STATUS_NORMAL);
        return TRUE;
    }

    // update duplicated points positions
    if(m_p_oKeyConfiguration->mfn_uwKeyToAction(_nChar) == KA_3DG_UPOINTS)
    {
        // if the last move wasn't in duplicates mode, update the duplicated points
        if (m_bLastMoveWasNormal)
            mfn_vUpdateDuplicatedPointsPositions();
        return TRUE;
    }
//END CPA2 Corneliu Babiuc 04-09-98 (duplicated points)
    return FALSE;
}

///////////////////
// Mouse methods //
///////////////////

//ROMTEAM WorldEditor (Viorel Preoteasa 20/01/98) 
/*
BOOL Geometry3D_Interface::_OnMouseMove(UINT _nFlags, tdstMousePos *_p_stMousePos, MTH3D_tdstVector *_p_xVertex)
{
    BOOL bHandled = FALSE;                // default : continue

    if( m_bCtrlUsed && fn_bIsCurrentEditor() &&  m_bPointSelected && _p_xVertex)
    {
        m_bPointTranslated = TRUE;
        MTH3D_tdstVector stLocalTranslation;
        mfn_vComputeLocalTranslation( m_p_SelectedSprObj, _p_xVertex, &stLocalTranslation );
        m_p_SelectedObject->fn_vTranslatePoint(m_xSelectedPointIndex,&stLocalTranslation);
        MTH3D_M_vAddVector(&m_st3DTranslation,&m_st3DTranslation,&stLocalTranslation);
        // display the world
        M_RedrawWorld();
        bHandled = TRUE;
    }

    return bHandled;
}
*/
//ENDROMTEAM WorldEditor (Viorel Preoteasa) 

//ROMTEAM WorldEditor (Viorel Preoteasa 20/01/98) 
//////////////////////////////////////////////////////////////////////////////////////////////////////
// Method : _OnMouseMove
// Date   : 98-01-20
//////////////////////////////////////////////////////////////////////////////////////////////////////
// Description : 
// Author      : Viorel Preoteasa - CPA2
//////////////////////////////////////////////////////////////////////////////////////////////////////
// Modification : duplicated points
// Date         : 04-09-98
// By           : Corneliu Babiuc
//////////////////////////////////////////////////////////////////////////////////////////////////////
BOOL Geometry3D_Interface::_OnMouseMove(UINT _nFlags, tdstMousePos *_p_stMousePos, MTH3D_tdstVector *_p_xVertex)
{
    BOOL bHandled = FALSE;                // default : continue

	if(m_bCtrlUsed || !m_bLButtonIsDown) return FALSE;
//CPA2 Corneliu Babiuc (duplicated points) 18-09-98
    if(m_lstListOfSelectedPoints.IsEmpty()) return FALSE;
//END CPA2 Corneliu Babiuc (duplicated points) 18-09-98
	if(m_bShiftUsed && (m_iDeletePoint>-1) && fn_bIsCurrentEditor())
	{
		GEO_tdstGeometricObject *GeomObj = m_p_SelectedObject->GetStruct();
        MTH3D_tdstVector P = GeomObj->d_stListOfPoints[m_iDeletePoint];
		if(!m_bVolSelection)
		{
			m_stTranslatedPoint = P;
		}

		m_bVolSelection = TRUE;
		MTH3D_tdstVector stLocalTranslation;
		mfn_vComputeLocalTranslation( m_p_SelectedSprObj, _p_xVertex, &stLocalTranslation );
//CPA2 Corneliu Babiuc 17-09-98 (duplicated points)
		float fIniDist = MTH3D_M_xVectorGapSqr(&m_stTranslatedPoint, &P);
		CPA_PointsList * p_oPoints = m_lstListOfSelectedPoints.GetHead();
/*
		m_stTranslatedPoint.xX += stLocalTranslation.xX;
		m_stTranslatedPoint.xY += stLocalTranslation.xY;
		m_stTranslatedPoint.xZ += stLocalTranslation.xZ;
*/
		MTH3D_M_vAddVector(&m_stTranslatedPoint, &m_stTranslatedPoint, &stLocalTranslation);
		float fDist = MTH3D_M_xVectorGapSqr(&m_stTranslatedPoint, &P);
/*
		float dist = (m_stTranslatedPoint.xX - P.xX)*(m_stTranslatedPoint.xX - P.xX) +
			         (m_stTranslatedPoint.xY - P.xY)*(m_stTranslatedPoint.xY - P.xY) +
					 (m_stTranslatedPoint.xZ - P.xZ)*(m_stTranslatedPoint.xZ - P.xZ);
		
		m_iNbSelectedPoints = 0;

		int i;
		for(i=0; i<GeomObj->xNbPoints; i++)
		{
			float d = (GeomObj->d_stListOfPoints[i].xX - P.xX)*(GeomObj->d_stListOfPoints[i].xX - P.xX) +
			          (GeomObj->d_stListOfPoints[i].xY - P.xY)*(GeomObj->d_stListOfPoints[i].xY - P.xY) +
					  (GeomObj->d_stListOfPoints[i].xZ - P.xZ)*(GeomObj->d_stListOfPoints[i].xZ - P.xZ);
			if(d<=dist)
			{
				m_xSelectedPointsIndex[m_iNbSelectedPoints] = i;
				m_iNbSelectedPoints++;
			}
		}
*/
		int i;
		if (fDist > fIniDist)
		{
			// in this case the sphere has raised, therefore some points could be added
			for(i=0; i<GeomObj->xNbPoints; i++)
			{
				float d = MTH3D_M_xVectorGapSqr(&(GeomObj->d_stListOfPoints[i]), &P);
				if (fDist>=d && d>fIniDist)
				{
					p_oPoints->AddPointToSelection(i);
					if (m_bSelectDuplicatesMode)
						mfn_vUpdateDuplicatedPointsList(m_p_SelectedSprObj, i, TRUE);
				}
			}
		}
		else
		{
			// in this case the sphere has grown smaller, therefore some points could be removed
			// considering the order of points adding, it is faster to perform removing in oposite order
			for (i=p_oPoints->GetNumberOfSelectedPoints()-1; i>-1; i--)
			{
				float d = MTH3D_M_xVectorGapSqr(&(GeomObj->d_stListOfPoints[p_oPoints->GetPoint(i)]), &P);
				if (fDist<d)
				{
					p_oPoints->RemovePointFromSelection(i);
					if (m_bSelectDuplicatesMode)
						mfn_vUpdateDuplicatedPointsList(m_p_SelectedSprObj, p_oPoints->GetPoint(i), FALSE);
				}
				else
					break;
			}
		}
//END CPA2 Corneliu Babiuc 17-09-98 (duplicated points)

		M_RedrawWorld();
		return TRUE;
	}

	if(fn_bIsCurrentEditor() &&  m_bPointSelected && _p_xVertex)
    {
		BOOL b = TRUE;
		if(!m_bPointTranslated)
		{
			int j;
//CPA2 Corneliu Babiuc 07-09-98 (duplicated points)
/*
            for(i=0; (i<m_iNbSelectedPoints) && (m_xSelectedPointsIndex[i] != m_iDeletePoint); i++);
			b = i < m_iNbSelectedPoints;
			if(b)
			{
				MTH3D_tdstVector P0 = (m_p_SelectedObject->GetStruct())->d_stListOfPoints[m_xSelectedPointsIndex[i]];
				MTH3D_tdstVector P;
				float maxDist = 0;
				for(j=0; j<m_iNbSelectedPoints; j++)
				{
					P = (m_p_SelectedObject->GetStruct())->d_stListOfPoints[m_xSelectedPointsIndex[j]];
					m_fDist[j] = (float)sqrt((P0.xX-P.xX)*(P0.xX-P.xX) + (P0.xY-P.xY)*(P0.xY-P.xY) + (P0.xZ-P.xZ)*(P0.xZ-P.xZ));
					if(m_fDist[j]>maxDist) maxDist = m_fDist[j];
				}
				if(maxDist)
					for(j=0; j<m_iNbSelectedPoints; j++)
					{
						m_fDist[j] = m_p_DlgEditPoints->Effect(m_fDist[j]/maxDist);
					}
				m_fDist[i] = m_p_DlgEditPoints->Effect(0);
			}
		}
*/
            //the delete point is always the last point of the first element in the list
            POS_tdxHandleToPosition hMatrix;
            POSITION        pos;
            CPA_PointsList  * p_oPointList = m_lstListOfSelectedPoints.GetHeadElement(pos);
            MTH3D_tdstVector P0 = (p_oPointList->GetObject()->GetStruct())->d_stListOfPoints[p_oPointList->GetDeletePoint()];
            //transform in world coordinates
	        hMatrix = HIE_fn_hGetSuperObjectGlobalMatrix( p_oPointList->GetSuperObject()->GetStruct() );
            POS_fn_vMulMatrixVertex(&P0, hMatrix, &P0);
            
            MTH3D_tdstVector P;
            // get the maxim of points distances
            float maxDist = 0;
            for (p_oPointList = m_lstListOfSelectedPoints.GetHeadElement(pos); p_oPointList;
                p_oPointList = m_lstListOfSelectedPoints.GetNextElement(pos) )
            {
		        for(j=0; j<p_oPointList->GetNumberOfSelectedPoints(); j++)
                {
                    P = (p_oPointList->GetObject()->GetStruct())->d_stListOfPoints[p_oPointList->GetPoint(j)];
                    //transform in world coordinates
	                hMatrix = HIE_fn_hGetSuperObjectGlobalMatrix( p_oPointList->GetSuperObject()->GetStruct() );
                    POS_fn_vMulMatrixVertex(&P, hMatrix, &P);
                    p_oPointList->m_fDist[j] = (float)sqrt((P0.xX-P.xX)*(P0.xX-P.xX) + (P0.xY-P.xY)*(P0.xY-P.xY) + (P0.xZ-P.xZ)*(P0.xZ-P.xZ)) ;
                    // correction for duplicated points
                    if (p_oPointList->m_fDist[j] < C_xErrorFactor) p_oPointList->m_fDist[j] = 0;
                    else if (p_oPointList->m_fDist[j] > maxDist) maxDist = p_oPointList->m_fDist[j];
                }
            }
            // set distances according to effect
            for (p_oPointList = m_lstListOfSelectedPoints.GetHeadElement(pos); p_oPointList;
                p_oPointList = m_lstListOfSelectedPoints.GetNextElement(pos) )
            {
		        for(j=0; j<p_oPointList->GetNumberOfSelectedPoints(); j++)
                {
                    if (maxDist)
                        p_oPointList->m_fDist[j] = m_p_DlgEditPoints->Effect(p_oPointList->m_fDist[j]/maxDist);
                    else // means that all points are duplicated of the delete point
                        p_oPointList->m_fDist[j] = m_p_DlgEditPoints->Effect(0);
                }
            }
        }
/*
		if(b)
		{
*/
//END CPA2 Corneliu Babiuc 09-09-98 (duplicated points)
			m_bPointTranslated = TRUE;
			MTH3D_tdstVector stLocalTranslation;
			MTH3D_tdstVector P;
			mfn_vComputeLocalTranslation( m_p_SelectedSprObj, _p_xVertex, &stLocalTranslation );
//CPA2 Corneliu Babiuc 07-09-98 (duplicated points)
/*
			int i;
			GEO_tdstGeometricObject *GeomObj = m_p_SelectedObject->GetStruct();
			for(i=0;i<m_iNbSelectedPoints;i++)
			{
				P = stLocalTranslation;
				P.xX = P.xX * m_fDist[i];
				P.xY = P.xY * m_fDist[i];
				P.xZ = P.xZ * m_fDist[i];
				if(m_iNbSelectedPoints == 1)m_p_SelectedObject->fn_vTranslatePoint(m_xSelectedPointsIndex[i],&P);
				else
				{
					(GeomObj->d_stListOfPoints[m_xSelectedPointsIndex[i]]).xX += P.xX;
					(GeomObj->d_stListOfPoints[m_xSelectedPointsIndex[i]]).xY += P.xY;
					(GeomObj->d_stListOfPoints[m_xSelectedPointsIndex[i]]).xZ += P.xZ;
				}
//				m_p_SelectedObject->fn_vTranslatePoint(m_xSelectedPointsIndex[i],&P);
			}
			if(m_iNbSelectedPoints != 1)
			{
				m_p_SelectedObject->fn_vEndModification();
				m_p_SelectedObject->fn_vSetMustRecomputeBdV();
			}
*/
            CPA_PointsList * p_oPointList;
            POSITION        pos;
            for (p_oPointList = m_lstListOfSelectedPoints.GetHeadElement(pos); p_oPointList;
                p_oPointList = m_lstListOfSelectedPoints.GetNextElement(pos) )
            {
                GEO_tdstGeometricObject *GeomObj = p_oPointList->GetObject()->GetStruct();
                int i;
		        for(i=0; i < p_oPointList->GetNumberOfSelectedPoints(); i++)
                {
                    MTH3D_M_vMulScalarVector(&P, p_oPointList->m_fDist[i], &stLocalTranslation);
                    if (i == p_oPointList->GetNumberOfSelectedPoints()-1)
                        p_oPointList->GetObject()->fn_vTranslatePoint(p_oPointList->GetPoint(i), &P);
                    else
                    {
                        MTH3D_M_vAddVector(&(GeomObj->d_stListOfPoints[p_oPointList->GetPoint(i)]), 
                                            &(GeomObj->d_stListOfPoints[p_oPointList->GetPoint(i)]), &P);
                    }
                }
                p_oPointList->GetObject()->fn_vSetMustRecomputeBdV();
             }
//END CPA2 Corneliu Babiuc (duplicated points) 09-09-98
			MTH3D_M_vAddVector(&m_st3DTranslation,&m_st3DTranslation,&stLocalTranslation);
			// display the world
			M_RedrawWorld();
	        //remove all mousemove messages that could have occurred during all this
	        MSG Message;
	        while ( PeekMessage(&Message, NULL, WM_MOUSEMOVE, WM_MOUSEMOVE, PM_REMOVE) );

			bHandled = TRUE;
//CPA2 Corneliu Babiuc (duplicated points) 09-09-98
//		}
//END CPA2 Corneliu Babiuc (duplicated points) 09-09-98
    }

    return bHandled;
}
//ENDROMTEAM WorldEditor (Viorel Preoteasa) 


//--------------------------------------------------------------------------------
//
//--------------------------------------------------------------------------------
BOOL Geometry3D_Interface::_OnLButtonDown(UINT, tdstMousePos *_p_stMousePos, ACP_tdxIndex _xIndex, HIE_tdstPickInfo *p_tdstPickInfo)
{
//ROMTEAM WorldEditor (Viorel Preoteasa 20/01/98) 
//	m_p_SelectedObject = NULL;
//	m_p_SelectedSprObj = NULL;
	m_iDeletePoint = -1;
	m_bVolSelection  = FALSE;
	m_bLButtonIsDown = TRUE;
//ENDROMTEAM WorldEditor (Viorel Preoteasa) 
	m_bPointSelected = FALSE;

    if(fn_bIsCurrentEditor() && (_xIndex > 0) )
    {
        long lSprObjType = HIE_fn_ulGetSuperObjectType( p_tdstPickInfo[0].hSprObject );

        if( lSprObjType & (HIE_C_ulEDT_Geometric | HIE_C_ulPO | HIE_C_ulIPO | HIE_C_ulIPO_Mirror | HIE_C_ulPO_Mirror) )
        {
            CPA_SuperObject *pSelectedSprObj = GetInterface() -> GetEditorObject( p_tdstPickInfo[0].hSprObject );

            if( ( (M_GetCountSelected() == 1) && ( M_GetSingleSelection() != pSelectedSprObj ) ) ||
                ( M_GetCountSelected() > 1 )
              )
			{
                M_CancelSelection();
                // update colors of selected objects 
                POSITION p;
                CPA_PointsList * p_Points = m_lstListOfSelectedPoints.GetHeadElement(p);
                for (p_Points = m_lstListOfSelectedPoints.GetNextElement(p);
                    p_Points;
                    p_Points = m_lstListOfSelectedPoints.GetNextElement(p) )
                    p_Points->GetSuperObject()->SetLocalColor(C_eAlternateColor);
			}
// ANNECY MT 23/02/98 {
			mfn_vShowOrHideBoundingVolume( FALSE );
			mfn_vShowOrHideElement( FALSE );
            m_p_SelectedObject = (Geometry3D*) GetBaseObject( p_tdstPickInfo[0].hGeoObject, C_szGeometricObjectTypeName );
			mfn_vShowOrHideBoundingVolume( TRUE );
// END ANNECY MT }
//-----------------------------------
//ROMTEAM WorldEditor (Viorel Preoteasa 20/01/98) 
//			m_p_SelectedSprObj = pSelectedSprObj;
//CPA2 Corneliu Babiuc 04-09-98 (duplicated points)
/*
			if(m_p_SelectedSprObj != pSelectedSprObj)
			{
                m_iNbSelectedPoints = 0;
				m_p_SelectedSprObj = pSelectedSprObj;
				if(m_fDist) free(m_fDist);
				if(m_xSelectedPointsIndex) free(m_xSelectedPointsIndex);
				m_xSelectedPointsIndex = NULL;
				m_fDist = NULL;
			}
			int NbPoints = (m_p_SelectedObject->GetStruct())->xNbPoints;
			if(!m_xSelectedPointsIndex)
				m_xSelectedPointsIndex = (ACP_tdxIndex *)malloc(NbPoints * sizeof(ACP_tdxIndex));
			if(!m_fDist)
				m_fDist = (float *) malloc(NbPoints * sizeof(float));
*/
			m_p_SelectedSprObj = pSelectedSprObj;
//END CPA2 Corneliu Babiuc 04-09-98 (duplicated points)
//ENDROMTEAM WorldEditor (Viorel Preoteasa) 
//--------------------------------------

//ROMTEAM WorldEditor (Nicu 05/12/97) 
			if(lSprObjType & (HIE_C_ulIPO | HIE_C_ulIPO_Mirror))
				m_LastGeom = &((EditorIPO *)(pSelectedSprObj->GetObject()))->GetPhysicalObject()->m_pGeom;
			else 	m_LastGeom = NULL;
//ENDROMTEAM WorldEditor (Nicu) 

            // add current object
            GetInterface() -> fn_vAddSelectedObject( m_p_SelectedSprObj, FALSE);
//ROMTEAM WorldEditor (Viorel Preoteasa 20/01/98) 
//			if( m_bCtrlUsed && m_p_SelectedSprObj)
            if(m_p_SelectedSprObj)
//ENDROMTEAM WorldEditor (Viorel Preoteasa) 
            {
                // the selected object is picked
                HIE_aDEF_stTabOfPickInfo xPickInfo;

                if(HIE_xIsSuperObjectPick(GLI_C_ModePickingPoint,
                                     M_GetMultiDevice3D()->GetFocusDevice()->GetViewPort()->m_hDisplayDevice,
                                     M_GetMultiDevice3D()->GetFocusDevice()->GetViewPort()->m_hDisplayViewport,
                                     &_p_stMousePos->stPos2D,
                                     p_tdstPickInfo[0].hSprObject,
                                     xPickInfo ))
                {
                    // get the first point of this object
//ROMTEAM WorldEditor (Viorel Preoteasa 06/01/98) 
//					m_xSelectedPointIndex = ((HIE_tdstPickInfo*)xPickInfo)->stPickedObject.aDEF_stDataOfElement[0].xIndexOfPoint;
                    m_iDeletePoint = ((HIE_tdstPickInfo*)xPickInfo)->stPickedObject.aDEF_stDataOfElement[0].xIndexOfPoint;
//CPA2 Corneliu Babiuc 07-09-98 (duplicated points)
                    POSITION pos = NULL;
                    CPA_PointsList * p_Points;
                    int iIndex = -1;
                    pos = mfn_pGetObjectPositionInSelectedPointsList(m_p_SelectedSprObj);
			        if (pos)
                    {
                        p_Points = m_lstListOfSelectedPoints.GetAt(pos);
                        iIndex = p_Points->GetPointIndexInSelection(m_iDeletePoint);
                    }
                    // now we cancel the points selection only if the user clicks on unselected point
                    // and CTRL is not pressed
                    if ( !(pos && iIndex > -1) && !m_bCtrlUsed )
                    {
                        mfn_vClearListOfSelectedPoints();
                    }
                    else
                        if (!m_bCtrlUsed)
                            //remove the the point. It will be inserted again as the last point
                            p_Points->RemovePointFromSelection(iIndex);
                    
                    BOOL bInserted;
                    bInserted = mfn_vUpdateSelectedPointsList(m_p_SelectedSprObj, m_iDeletePoint);
                    if (m_bSelectDuplicatesMode)
                        mfn_vUpdateDuplicatedPointsList(m_p_SelectedSprObj, m_iDeletePoint, bInserted);
//END CPA2 Corneliu Babiuc 07-09-98 (duplicated points)
//ENDROMTEAM WorldEditor (Viorel Preoteasa) 
                    ((DEV_ViewPort3D*)M_GetMultiDevice3D()->GetFocusDevice()->GetViewPort())->InitMouseMove(&xPickInfo->stPickedObject.aDEF_stDataOfElement[0].stHit, &_p_stMousePos->stPos2D);
                    m_bPointSelected = TRUE;
                    MTH3D_M_vNullVector(&m_st3DTranslation);
                    m_bPointTranslated = FALSE;
//END CPA2 Corneliu Babiuc 14-09-98 (duplicated points)
                    M_RedrawWorld();
//END CPA2 Corneliu Babiuc 14-09-98 (duplicated points)
                }
                else
                    fn_vUnSelect();
            }
        }
        m_p_DlgCaract->fn_vUpdateInfo( m_p_SelectedSprObj, m_p_SelectedObject );
        m_p_DlgList->fn_vUpdateSelection(E_lrm_ChangeSelection);
        return TRUE;
    }
    return FALSE;
}

//ROMTEAM WorldEditor (Viorel Preoteasa 20/01/98) 
/*
BOOL Geometry3D_Interface::_OnLButtonUp(UINT, tdstMousePos *)
{
    if( m_bPointSelected )
    {
        if(m_bPointTranslated)
        {

//ROMTEAM WorldEditor (Nicu 19/01/98) 
            Geometry3D_Modif *p_Modif = new Geometry3D_Modif(m_p_SelectedObject,m_xSelectedPointIndex,m_st3DTranslation, (DWORD*)m_LastGeom);
//ENDROMTEAM WorldEditor (Nicu) 

            M_GetEditManager()->AskFor(p_Modif);
        }

        m_xSelectedPointIndex = 0;
        m_bPointSelected = FALSE;
        return TRUE;
    }
    return FALSE;
}
*/

//////////////////////////////////////////////////////////////////////////////////////////////////////
// Method : _OnLButtonUp
// Date   : 98-01-20
//////////////////////////////////////////////////////////////////////////////////////////////////////
// Description : 
// Author      : Viorel Preoteasa - CPA2
//////////////////////////////////////////////////////////////////////////////////////////////////////
// Modification :
// Date         :
// By           :
//////////////////////////////////////////////////////////////////////////////////////////////////////
BOOL Geometry3D_Interface::_OnLButtonUp(UINT, tdstMousePos *)
{
	m_bLButtonIsDown = FALSE;
	if(m_bShiftUsed) return TRUE;
    if( m_bPointSelected )
    {
        if(m_bPointTranslated)
        {
//ROMTEAM WorldEditor (Nicu 19/01/98) 
//ROMTEAM WorldEditor (Viorel Preoteasa 20/01/98) 
//          Geometry3D_Modif *p_Modif = new Geometry3D_Modif(m_p_SelectedObject,m_xSelectedPointIndex,m_st3DTranslation, (DWORD*)m_LastGeom);
    //CPA2 Corneliu Babiuc 09-09-98 (duplicated points)
            // the Modif class has changed in order to use the list of selected points
//            Geometry3D_Modif *p_Modif = new Geometry3D_Modif(m_p_SelectedObject,m_iNbSelectedPoints,m_xSelectedPointsIndex,m_fDist, m_st3DTranslation, (DWORD*)m_LastGeom);
            Geometry3D_Modif *p_Modif = new Geometry3D_Modif(&m_lstListOfSelectedPoints, m_st3DTranslation, (DWORD*)m_LastGeom);
    //END CPA2 Corneliu Babiuc 09-09-98 (duplicated points)
//ENDROMTEAM WorldEditor (Viorel Preoteasa) 
//ENDROMTEAM WorldEditor (Nicu) 
            M_GetEditManager()->AskFor(p_Modif);
//CPA2 Corneliu Babiuc 03-09-98 (duplicated points)
            m_bLastMoveWasNormal = !m_bSelectDuplicatesMode;
        }
/*
        }
		else 
		{
            if(!m_bCtrlUsed)m_iNbSelectedPoints = 0;
			int p = m_iDeletePoint;
			int i;
			for(i=0; (i<m_iNbSelectedPoints) && (m_xSelectedPointsIndex[i] != p); i++);
			if(i==m_iNbSelectedPoints)
			{
				m_xSelectedPointsIndex[m_iNbSelectedPoints] = p;
				m_iNbSelectedPoints++;
			}
			else
			{
				for( ; i<m_iNbSelectedPoints-1; i++)
					m_xSelectedPointsIndex[i] = m_xSelectedPointsIndex[i+1];
				m_iNbSelectedPoints--;
			}
            M_RedrawWorld();
		}
*/
//END CPA2 Corneliu Babiuc 16-09-98 (duplicated points)
        return TRUE;
    }
    return FALSE;
}

// ANNECY MT 23/02/98 {
//////////////////////////////////////////////////////////////////////////////////////////////////////
// Method : _OnRButtonDown
// Date   : 24/02/98
//////////////////////////////////////////////////////////////////////////////////////////////////////
// Description : 
// Author      : Marc Trabucato
//////////////////////////////////////////////////////////////////////////////////////////////////////
// Modification :
// Date         :
// By           :
//////////////////////////////////////////////////////////////////////////////////////////////////////
BOOL Geometry3D_Interface::_OnRButtonDown(UINT, tdstMousePos *_p_stMousePos, ACP_tdxIndex _xIndex, HIE_tdstPickInfo *p_tdstPickInfo)
{
	if(fn_bIsCurrentEditor())
	{
		// cancel mode (for popup)
		GetInterface()->GetEvtEditor()->fn_vCancelAllModes();
		// display popup
		GetInterface()->fn_vDisplayPopupMenu(_p_stMousePos);

		return TRUE;
	}
	return FALSE;
}
// END ANNECY MT }

//////////////////////////////////////////////////////////////////////////////////////////////////////
// Method : fn_vAddObjectsToDraw
// Date   : 98-01-20
//////////////////////////////////////////////////////////////////////////////////////////////////////
// Description : Draw point selection
// Author      : Viorel Preoteasa - CPA2
//////////////////////////////////////////////////////////////////////////////////////////////////////
// Modification : duplicated points
// Date         : 04-09-98
// By           : Corneliu Babiuc
//////////////////////////////////////////////////////////////////////////////////////////////////////
void Geometry3D_Interface::fn_vAddObjectsToDraw	(GLD_tdstViewportAttributes *pViewportAttributes, GLI_tdxHandleToLight p2, DEV_ViewPort* p3)
{
	POS_tdstCompletePosition stMatrix;
	GEO_tdstColor		ColBidon;
	MTH3D_tdstVector	p_stPointList[8];
	int i;
//ANNECY Shaitan Correction 03/02/98 {
	if( fn_bIsCurrentEditor() &&  m_bPointSelected && ((GLI_tdstSpecificAttributesFor3D*)(pViewportAttributes->p_vSpecificToXD))->p_stCam)
//ENDANNECY Shaitan Correction }
   {
//CPA2 Corneliu Babiuc 04-09-98 (duplicated points)
/*
        int j;
		for(j=0; j<m_iNbSelectedPoints; j++)
		{
			POS_tdxHandleToPosition     hMatrix;
			hMatrix = HIE_fn_hGetSuperObjectGlobalMatrix( m_p_SelectedSprObj -> GetStruct() );
			MTH3D_tdstVector stPoint = (m_p_SelectedObject->GetStruct())->d_stListOfPoints[m_xSelectedPointsIndex[j]];
*/
    POSITION pos;
    CPA_PointsList * p_oPointList;
    for (p_oPointList = m_lstListOfSelectedPoints.GetHeadElement(pos); p_oPointList;
        p_oPointList = m_lstListOfSelectedPoints.GetNextElement(pos) )
    {
        int j;
		for(j=0; j<p_oPointList->GetNumberOfSelectedPoints(); j++)
        {
            POS_tdxHandleToPosition     hMatrix;
			hMatrix = HIE_fn_hGetSuperObjectGlobalMatrix( p_oPointList->GetSuperObject()->GetStruct() );
			MTH3D_tdstVector stPoint = (p_oPointList->GetObject()->GetStruct())->d_stListOfPoints[p_oPointList->GetPoint(j)];
//END CPA2 Corneliu Babiuc 04-09-98 (duplicated points)

			POS_fn_vMulMatrixVertex( p_stPointList, hMatrix, &stPoint);

			float f = 0.03f;

			for(i = 1; i<8; i++)p_stPointList[i] = p_stPointList[0];

			p_stPointList[0].xX -= f;
			p_stPointList[0].xY -= f;
			p_stPointList[0].xZ -= f;

			p_stPointList[1].xX -= f;
			p_stPointList[1].xY -= f;
			p_stPointList[1].xZ += f;

			p_stPointList[2].xX += f;
			p_stPointList[2].xY -= f;
			p_stPointList[2].xZ += f;

			p_stPointList[3].xX += f;
			p_stPointList[3].xY -= f;
			p_stPointList[3].xZ -= f;

			p_stPointList[4].xX -= f;
			p_stPointList[4].xY += f;
			p_stPointList[4].xZ -= f;

			p_stPointList[5].xX -= f;
			p_stPointList[5].xY += f;
			p_stPointList[5].xZ += f;

			p_stPointList[6].xX += f;
			p_stPointList[6].xY += f;
			p_stPointList[6].xZ += f;

			p_stPointList[7].xX += f;
			p_stPointList[7].xY += f;
			p_stPointList[7].xZ -= f;

			POS_fn_vSetIdentityMatrix(&stMatrix);
			

			ColBidon.xR=(float)0.5;
			ColBidon.xG=(float)0.5;
			ColBidon.xB=(float)0.5;
			ColBidon.xA=(float)0.5;

			GLI_xGetCameraMatrix(((GLI_tdstSpecificAttributesFor3D*)(pViewportAttributes->p_vSpecificToXD))->p_stCam,&stMatrix);
			GLI_xLoadMatrix(&stMatrix);
			GLI_vSetFog(100,100,200,&ColBidon);
			for (i=0; i<4; i++)
			{
				GLI_xDraw3DLine16
				(
					(struct GLD_tdstViewportAttributes_*)(pViewportAttributes),
					p_stPointList + i,
					p_stPointList + ((i+1)%4),
					0xFFFFFFFF
				);
				GLI_xDraw3DLine16
				(
					(struct GLD_tdstViewportAttributes_*)(pViewportAttributes),
					p_stPointList + (i+4),
					p_stPointList + (4 + (i+1)%4),
					0xFFFFFFFF
				);
				GLI_xDraw3DLine16
				(
					(struct GLD_tdstViewportAttributes_*)(pViewportAttributes),
					p_stPointList + i,
					p_stPointList + (i+4),
					0xFFFFFFFF
				);
			}	
			GLI_xPopMatrix();
		}
	}
//CPA2 Corneliu Babiuc 04-09-98 (duplicated points)
   }
//END CPA2 Corneliu Babiuc 04-09-98 (duplicated points)
}

//ENDROMTEAM WorldEditor (Viorel Preoteasa) 

//--------------------------------------------------------------------------------
//
//--------------------------------------------------------------------------------
void Geometry3D_Interface::fn_vOnChangeRoot(void)
{
    if( fn_bIsCurrentEditor() && m_p_DlgList )
    {
        m_p_DlgList->fn_vInitAllLists();
        m_p_DlgList->fn_vReinitDialog();
    }
    fn_vUnSelect();
    if( fn_bIsCurrentEditor() && m_p_DlgCaract )
        m_p_DlgCaract->fn_vUpdateInfo(NULL,NULL);
}

void Geometry3D_Interface::fn_vOnChangeDevice(void)
{
    fn_vOnChangeRoot();
}

//--------------------------------------------------------------------------------
//
//--------------------------------------------------------------------------------
void Geometry3D_Interface::fn_vOnChangeWorld(void)
{
    fn_vOnChangeRoot();
}

//CPA2 Corneliu Babiuc 02-09-98 (duplicated points)
//////////////////////////////////////////////////////////////////////////////////////////////////////
// Method : fn_vBeforeDrawingWorld
// Date   : 15-09-98
//////////////////////////////////////////////////////////////////////////////////////////////////////
// Description : DLL function overload. Goal: changes the color of objects having selected points
// Parameters: : 
// Author      : Corneliu Babiuc
//////////////////////////////////////////////////////////////////////////////////////////////////////
// Modification :
// Date         :
// By           :
//////////////////////////////////////////////////////////////////////////////////////////////////////
/*void Geometry3D_Interface::fn_vBeforeDrawingWorld (GLD_tdstViewportAttributes *p1, GLI_tdxHandleToLight p2, DEV_ViewPort* p3)
{
	if( fn_bIsCurrentEditor() &&  m_bPointSelected ) //&& ((GLI_tdstSpecificAttributesFor3D*)(pViewportAttributes->p_vSpecificToXD))->p_stCam)
    {
        POSITION        pos;
        //skip the first object in list (is the selected one, so it has to be displayed on selection color
        CPA_PointsList * p_PointsList = m_lstListOfSelectedPoints.GetHeadElement(pos);
        if (!p_PointsList) return;
        while (p_PointsList = m_lstListOfSelectedPoints.GetNextElement(pos))
            p_PointsList->GetSuperObject()->SetLocalColor(C_eAlternateColor);
    }
}
*/        
///////////////////////////////////////////////////////////////////////////////
// Points selection methods
///////////////////////////////////////////////////////////////////////////////
POSITION Geometry3D_Interface::mfn_pGetObjectPositionInSelectedPointsList(CPA_SuperObject * p_SuperObject)
{
    POSITION            pos;
    CPA_PointsList      * pSO;
    for (pSO = m_lstListOfSelectedPoints.GetHeadElement(pos); pSO; pSO = m_lstListOfSelectedPoints.GetNextElement(pos))
        if (pSO->GetSuperObject() == p_SuperObject)
            return pos;
    return NULL;
}

//////////////////////////////////////////////////////////////////////////////////////////////////////
// Method : mfn_vUpdateSelectedPointsList
// Date   : 04-09-98
//////////////////////////////////////////////////////////////////////////////////////////////////////
// Description : Updates the list of selected points. 
// Parameters: : 
//      p_SO - The superobject who is selected. It will be added in the head of selection list 
//             if it is not  already selected
//      xIndex Index of point in geometric object. If the point already exists it will be removed
//             otherwise it will be inserted in selected points list.
//      returns: TRUE if object was inserted FALSE if object was removed
// Author      : Corneliu Babiuc
//////////////////////////////////////////////////////////////////////////////////////////////////////
// Modification :
// Date         :
// By           :
//////////////////////////////////////////////////////////////////////////////////////////////////////
BOOL Geometry3D_Interface::mfn_vUpdateSelectedPointsList(CPA_SuperObject * p_SO, ACP_tdxIndex xIndex)
{
    POSITION        pos;
    CPA_PointsList  * p_SelectedPoints;
    Geometry3D      * p_Object = mfn_pGetGeometricObject(p_SO);
    // check if the object is already in list
    pos = mfn_pGetObjectPositionInSelectedPointsList(p_SO);
    if (pos) //already in list
    {
        p_SelectedPoints = m_lstListOfSelectedPoints.GetAt(pos);
        m_lstListOfSelectedPoints.RemoveAt(pos);
    }
    else
    {
        //new object, then allocate it
/*        pos = mfn_pInsertObjectInSelectedPointsList(p_SO, p_Object);
        p_SelectedPoints = m_lstListOfSelectedPoints.GetAt(pos);
*/
        p_SelectedPoints = new CPA_PointsList(p_SO, p_Object);
    }
    pos = mfn_pInsertPointsElementInHeadPosition(p_SelectedPoints);
    // check if point is already selected
    int iLocalIndex = p_SelectedPoints->GetPointIndexInSelection(xIndex);
    if (iLocalIndex<0)
        p_SelectedPoints->AddPointToSelection(xIndex);
    else
    {
        p_SelectedPoints->RemovePointFromSelection(iLocalIndex);
        // remove the points list if there are no selected points
        if (!p_SelectedPoints->GetNumberOfSelectedPoints())
        {
            m_lstListOfSelectedPoints.RemoveAt(pos);
            delete p_SelectedPoints;
        }
    }
    return iLocalIndex<0 ;
}

//////////////////////////////////////////////////////////////////////////////////////////////////////
// Method : mfn_vUpdateDuplicatedPointsList
// Date   : 04-09-98
//////////////////////////////////////////////////////////////////////////////////////////////////////
// Description : Updates the list of selected points by inserting/removing the duplicated points
//               of the current selected/unselected point
// Parameters: : 
//      p_SO - The superobject who is selected. 
//      xIndex Index of point in geometric object. 
//      bInserted - TRUE if the point is selected, FALSE if the point is unselected
//      returns - none
// Author      : Corneliu Babiuc
//////////////////////////////////////////////////////////////////////////////////////////////////////
// Modification :
// Date         :
// By           :
//////////////////////////////////////////////////////////////////////////////////////////////////////
void Geometry3D_Interface::mfn_vUpdateDuplicatedPointsList(CPA_SuperObject * p_SO, ACP_tdxIndex xIndex, BOOL bInserted, float fDistance)
{
    POSITION                pos;
    MTH3D_tdstVector          stRefPointPosition, stPointPosition;
    MTH3D_tdstVector		stRefCenter, stCenter;
    MTH_tdxReal             xRefRadius, xRadius;
    POS_tdxHandleToPosition hMatrix;
    CPA_SuperObject         * pElem;
    Geometry3D              * pObj;
    CPA_PointsList          * pPointsList;
    //get the physical object
    Geometry3D * p_Object = mfn_pGetGeometricObject(p_SO);
    // get the vertex coordinates
    p_Object->fn_vGetPoint(xIndex, &stRefPointPosition);
    // transform to world coordinates
	hMatrix = HIE_fn_hGetSuperObjectGlobalMatrix( p_SO->GetStruct() );
    POS_fn_vMulMatrixVertex(&stRefPointPosition, hMatrix, &stRefPointPosition);

    // get the bounding volume
    GEO_fn_vGetInfoFromGeometricSphere(&stRefCenter, &xRefRadius, mfn_pGetGeometricObject(p_SO)->fn_hGetBoundingVolume());
    // transform to world coordinates
    POS_fn_vMulMatrixVertex(&stRefCenter, hMatrix, &stRefCenter);
    if (!bInserted) //object was removed
    {
        //remove all duplicates
        for (pPointsList = m_lstListOfSelectedPoints.GetHeadElement(pos);
            pPointsList;
            /*pPointsList = m_lstListOfSelectedPoints.GetNextElement(pos)*/)
        {
            // object is the same with p_SO nothing to do
            if ( pPointsList->GetSuperObject() != p_SO )
            {
                pObj = pPointsList->GetObject();
                // find duplicated points
                for (int iIdx = 0; iIdx < pPointsList->GetNumberOfSelectedPoints(); iIdx++)
                {
                    // get the point position
                    pObj->fn_vGetPoint(pPointsList->GetPoint(iIdx), &stPointPosition);
                    // transform to world coordinates
	                hMatrix = HIE_fn_hGetSuperObjectGlobalMatrix( pPointsList->GetSuperObject()->GetStruct() );
                    POS_fn_vMulMatrixVertex(&stPointPosition, hMatrix, &stPointPosition);

                    // have the two points the same position?
                    if (MTH_M_xSqr(stPointPosition.xX - stRefPointPosition.xX) + 
                        MTH_M_xSqr(stPointPosition.xY - stRefPointPosition.xY) + 
                        MTH_M_xSqr(stPointPosition.xZ - stRefPointPosition.xZ) < C_xErrorFactor)
                    {
                        pPointsList->RemovePointFromSelection(iIdx);
                        break;
                    }
                }
            }
            //if there are no another selected points, remove the element
            if (!pPointsList->GetNumberOfSelectedPoints())
            {
                // set normal color
                pPointsList->GetSuperObject()->SetLocalColor(E_lc_NoColor);
                //delete from list
                POSITION        oldPos = pos;
                CPA_PointsList  * p_prevElem = m_lstListOfSelectedPoints.GetPrevElement(pos);
                m_lstListOfSelectedPoints.RemoveAt(oldPos);
                delete pPointsList;
                if (!p_prevElem) // the removed element was first in list
                    pPointsList = m_lstListOfSelectedPoints.GetHeadElement(pos);
                else
                    pPointsList = m_lstListOfSelectedPoints.GetNextElement(pos);
            }
            else
                pPointsList = m_lstListOfSelectedPoints.GetNextElement(pos);
        }
    return;
    }
    // get all objects from world and for objects colliding with reference objects 
    // select duplicated points
    for (pElem = M_GetWorld()->GetListFromObject(p_SO)->m_stListAllTypes.m_stListObjects.GetHeadElement(pos);
        pElem;
        pElem = M_GetWorld()->GetListFromObject(p_SO)->m_stListAllTypes.m_stListObjects.GetNextElement(pos))
    {
        if (p_SO == pElem) continue;
        pObj = mfn_pGetGeometricObject(pElem);
        // get bounding volume
        GEO_fn_vGetInfoFromGeometricSphere(&stCenter, &xRadius,	pObj->fn_hGetBoundingVolume());
        // transform to world coordinates
	    hMatrix = HIE_fn_hGetSuperObjectGlobalMatrix( pElem->GetStruct() );
        POS_fn_vMulMatrixVertex(&stCenter, hMatrix, &stCenter);

        //check the collision
        if ( MTH_M_xSqr(stCenter.xX-stRefCenter.xX) + MTH_M_xSqr(stCenter.xY-stRefCenter.xY) + MTH_M_xSqr(stCenter.xZ-stRefCenter.xZ) >
            MTH_M_xSqr(xRadius+xRefRadius) ) continue;
        // the two objects collide, try to find the duplicated points
        for (ACP_tdxIndex xIdx = 0; xIdx < (pObj->GetStruct())->xNbPoints; xIdx++)
        {
            // get the point position
            pObj->fn_vGetPoint(xIdx, &stPointPosition);
            // transform to world coordinates
            POS_fn_vMulMatrixVertex(&stPointPosition, hMatrix, &stPointPosition);

            // have the two points the same position?
            if (MTH_M_xSqr(stPointPosition.xX - stRefPointPosition.xX) + 
                MTH_M_xSqr(stPointPosition.xY - stRefPointPosition.xY) + 
                MTH_M_xSqr(stPointPosition.xZ - stRefPointPosition.xZ) < C_xErrorFactor)
            {
                // add the point in selection list. Only if it isn't already selected
                POSITION p = mfn_pGetObjectPositionInSelectedPointsList(pElem);
                //if object isn't in list then add it
                if (!p)
                    p = mfn_pInsertObjectInSelectedPointsList(pElem, mfn_pGetGeometricObject(pElem));
                pPointsList = m_lstListOfSelectedPoints.GetAt(p);
                // check if the point was already selected, and add the point to selection
				if (pPointsList->GetPointIndexInSelection(xIdx) < 0)
					pPointsList->AddPointToSelection(xIdx);
                // set the distance:
                pPointsList->SetDistance(pPointsList->GetNumberOfSelectedPoints()-1, fDistance);
                break;
            }
        }
    }
}

//////////////////////////////////////////////////////////////////////////////////////////////////////
// Method : mfn_vUpdateDuplicatedPointsPositions
// Date   : 10-09-98
//////////////////////////////////////////////////////////////////////////////////////////////////////
// Description : Updates the duplicated points positions in case of a move done in normal mode
// Parameters: : none
// Author      : Corneliu Babiuc
//////////////////////////////////////////////////////////////////////////////////////////////////////
// Modification :
// Date         :
// By           :
//////////////////////////////////////////////////////////////////////////////////////////////////////
void Geometry3D_Interface::mfn_vUpdateDuplicatedPointsPositions(void)
{
    if (!m_bLastMoveWasNormal || m_lstListOfSelectedPoints.IsEmpty() || !m_bPointTranslated) return;

    POSITION                    pos;
    MTH3D_tdstVector            st3DTranslation;
    CPA_List<CPA_PointsList>    lstCopy;
    CPA_PointsList              * p_oPoints;

    // recomcompute the initial position translating the points with thier inverse translation vectors
    lstCopy.RemoveAll();
    for(p_oPoints = m_lstListOfSelectedPoints.GetHeadElement(pos); 
        p_oPoints;
        p_oPoints = m_lstListOfSelectedPoints.GetNextElement(pos) )
    {
        GEO_tdstGeometricObject * GeomObj = p_oPoints->GetObject()->GetStruct();
        for( int i=0; i<p_oPoints->GetNumberOfSelectedPoints(); i++)
        {
            ACP_tdxIndex xPointIndex = p_oPoints->GetPoint(i);
            MTH3D_M_vMulScalarVector(&st3DTranslation, -p_oPoints->m_fDist[i], &m_st3DTranslation);
            if( i == p_oPoints->GetNumberOfSelectedPoints()-1)
                p_oPoints->GetObject()->fn_vTranslatePoint(xPointIndex, &st3DTranslation);
            else
            {
                MTH3D_M_vAddVector(&(GeomObj->d_stListOfPoints[xPointIndex]), 
                                    &(GeomObj->d_stListOfPoints[xPointIndex]), &st3DTranslation);
            }
        }
        lstCopy.AddTail(p_oPoints);
    }
    // remove all elements from list of selected points and fill it again with their duplicates
    m_lstListOfSelectedPoints.RemoveAll();
    for(p_oPoints = lstCopy.GetHeadElement(pos); 
        p_oPoints;
        p_oPoints = lstCopy.GetNextElement(pos) )
    {
        for( int i=0; i<p_oPoints->GetNumberOfSelectedPoints(); i++)
        {
            mfn_vUpdateDuplicatedPointsList(p_oPoints->GetSuperObject(), p_oPoints->GetPoint(i), TRUE, p_oPoints->GetDistance(i));
        }
    }
    // retranslate the initial points
    for(p_oPoints = lstCopy.GetHeadElement(pos); 
        p_oPoints;
        p_oPoints = lstCopy.GetNextElement(pos) )
    {
        GEO_tdstGeometricObject * GeomObj = p_oPoints->GetObject()->GetStruct();
        for( int i=0; i<p_oPoints->GetNumberOfSelectedPoints(); i++)
        {
            ACP_tdxIndex xPointIndex = p_oPoints->GetPoint(i);
            MTH3D_M_vMulScalarVector(&st3DTranslation, p_oPoints->m_fDist[i], &m_st3DTranslation);
            if( i == p_oPoints->GetNumberOfSelectedPoints()-1)
                p_oPoints->GetObject()->fn_vTranslatePoint(xPointIndex, &st3DTranslation);
            else
            {
                MTH3D_M_vAddVector(&(GeomObj->d_stListOfPoints[xPointIndex]), 
                                    &(GeomObj->d_stListOfPoints[xPointIndex]), &st3DTranslation);
            }
        }
    }
    // finaly move the duplicates passing FALSE to modif constructor as last parameter. 
    // That will inform modif::Do function to perform the move
    if (!m_lstListOfSelectedPoints.IsEmpty())
    {
        m_bPointSelected = FALSE;        
        Geometry3D_Modif *p_Modif = new Geometry3D_Modif(&m_lstListOfSelectedPoints, m_st3DTranslation, (DWORD*)m_LastGeom, FALSE);
        M_GetEditManager()->AskFor(p_Modif);
    }
    // clear the copy of the list
    while (!lstCopy.IsEmpty()) delete lstCopy.RemoveHead();
}

//////////////////////////////////////////////////////////////////////////////////////////////////////
// Method : mfn_pInsertObjectInSelectedPointsList
// Date   : 14-09-98
//////////////////////////////////////////////////////////////////////////////////////////////////////
// Description : Inserts a new object in list of selected points and sets its color
// Parameters: : 
//          p_SuperObject   - pointer to SuperObject to be inserted
//          p_Object        - the 3D object coresponding to SuperObject
// Author      : Corneliu Babiuc
//////////////////////////////////////////////////////////////////////////////////////////////////////
// Modification :
// Date         :
// By           :
//////////////////////////////////////////////////////////////////////////////////////////////////////
POSITION Geometry3D_Interface::mfn_pInsertObjectInSelectedPointsList(CPA_SuperObject * p_SuperObject, Geometry3D * p_Object)
{   
    if (m_lstListOfSelectedPoints.GetCount())
        p_SuperObject->SetLocalColor(C_eAlternateColor);
    return m_lstListOfSelectedPoints.AddTail( new CPA_PointsList(p_SuperObject, p_Object)); 
}

//////////////////////////////////////////////////////////////////////////////////////////////////////
// Method : mfn_pInsertPointsElementInHeadPosition
// Date   : 14-09-98
//////////////////////////////////////////////////////////////////////////////////////////////////////
// Description : Inserts a new element in head position of selected points list and sets the 
//               color of previous head element to alternate
// Parameters  : 
//          p_Points   - element to be inserted
// Returns     : the POSITION value of the newly inserted element
// Author      : Corneliu Babiuc
//////////////////////////////////////////////////////////////////////////////////////////////////////
// Modification :
// Date         :
// By           :
//////////////////////////////////////////////////////////////////////////////////////////////////////
POSITION Geometry3D_Interface::mfn_pInsertPointsElementInHeadPosition(CPA_PointsList * p_Points)
{
    // if list is not empty, we must change the color of the head element cause it'll become the second one
    if (m_lstListOfSelectedPoints.GetCount())
        m_lstListOfSelectedPoints.GetHeadElement()->GetSuperObject()->SetLocalColor(C_eAlternateColor);
    return m_lstListOfSelectedPoints.AddHead(p_Points);
}

//////////////////////////////////////////////////////////////////////////////////////////////////////
// Method : mfn_vClearListOfSelectedPoints
// Date   : 14-09-98
//////////////////////////////////////////////////////////////////////////////////////////////////////
// Description : Clears the list of selected points and set the color of objects to normal
// Parameters: : 
// Author      : Corneliu Babiuc
//////////////////////////////////////////////////////////////////////////////////////////////////////
// Modification :
// Date         :
// By           :
//////////////////////////////////////////////////////////////////////////////////////////////////////
void Geometry3D_Interface::mfn_vClearListOfSelectedPoints() 
{   
    while (!m_lstListOfSelectedPoints.IsEmpty())
    {
        CPA_PointsList * p_oPoints = m_lstListOfSelectedPoints.RemoveHead(); 
        if (p_oPoints->GetSuperObject() != m_p_SelectedSprObj)
            p_oPoints->GetSuperObject()->SetLocalColor(E_lc_NoColor);
        delete p_oPoints;
    }
//    while (!m_lstListOfSelectedPoints.IsEmpty()) delete m_lstListOfSelectedPoints.RemoveHead();
}

Geometry3D * Geometry3D_Interface::mfn_pGetGeometricObject(CPA_SuperObject * p_SO)
{
    ASSERT(p_SO);
    CPA_BaseObject * p_oObject = p_SO->GetObject();
    if( p_oObject )
    {
        if (p_oObject->GetType() == C_szGeometricObjectTypeName) return (Geometry3D*)p_oObject;
        else
        if (p_oObject->GetType() == C_szPhysicalObjectTypeName) return ((EditorPO*) p_oObject)->m_fnp_oGetGeometricWithDistance( 0 );
        else
        if (p_oObject->GetType() == C_szInstanciatedPhysicalObjectTypeName) return ((EditorIPO*) p_oObject)->GetPhysicalObject()->m_fnp_oGetGeometricWithDistance( 0 );
        else ASSERT(0);
    }
    return NULL;
}

//END CPA2 Corneliu Babiuc 15-09-98 (duplicated points)

///////////////////////////////////////////////////////////////////////////////
// Editor Messages
///////////////////////////////////////////////////////////////////////////////

void Geometry3D_Interface::fn_vOnSelect(CPA_SuperObject *pEdObj, tdeTypeModif eType, tdeStatus eStatus)
{
    if( eStatus == C_AsCurrentEditor )
    {
        m_p_SelectedObject = NULL;
        m_p_SelectedSprObj = NULL;
        m_bPointSelected = FALSE;
        if( eType == C_EDTDo )
        {
            CPA_BaseObject *p_oObject = pEdObj -> GetObject();
            if( p_oObject )
            {
                if( p_oObject -> fn_bIsOfType( C_szGeometricObjectTypeName ) )
                {
// ANNECY MT 23/02/98 {
					mfn_vShowOrHideBoundingVolume( FALSE );
					mfn_vShowOrHideElement( FALSE );
                    m_p_SelectedObject = (Geometry3D*)p_oObject;
                    m_p_SelectedSprObj = pEdObj;
					mfn_vShowOrHideBoundingVolume( TRUE );
                }
                else if( p_oObject -> fn_bIsOfType( C_szPhysicalObjectTypeName ) )
                {
					mfn_vShowOrHideBoundingVolume( FALSE );
					mfn_vShowOrHideElement( FALSE );
                    m_p_SelectedObject = ((EditorPO*) p_oObject) -> m_fnp_oGetGeometricWithDistance( 0 );
                    m_p_SelectedSprObj = pEdObj;
					mfn_vShowOrHideBoundingVolume( TRUE );
                }
                else if( p_oObject -> fn_bIsOfType( C_szInstanciatedPhysicalObjectTypeName ) )
                {
					mfn_vShowOrHideBoundingVolume( FALSE );
					mfn_vShowOrHideElement( FALSE );
                    m_p_SelectedObject = ((EditorIPO*) p_oObject) -> GetPhysicalObject() -> m_fnp_oGetGeometricWithDistance( 0 );
                    m_p_SelectedSprObj = pEdObj;
					mfn_vShowOrHideBoundingVolume( TRUE );
// END ANNECY MT }
                }
            }
        }
    }
    m_p_DlgCaract->fn_vUpdateInfo( m_p_SelectedSprObj, m_p_SelectedObject );
    if(m_p_DlgList)
        m_p_DlgList->fn_vUpdateSelection(E_lrm_ChangeSelection);
}

//--------------------------------------------------------------------------------
//
//--------------------------------------------------------------------------------
void Geometry3D_Interface::fn_vOnModifDelete  (CPA_List<EDT_SaveParents> *pListObjects, tdeTypeModif eType, tdeStatus eStatus)
{
    if(m_p_DlgList)
        m_p_DlgList->fn_vUpdateSelection(E_lrm_ReinitList);
}

//--------------------------------------------------------------------------------
//
//--------------------------------------------------------------------------------
void Geometry3D_Interface::fn_vOnModifParent  (CPA_List<EDT_SaveParents> *pListObjects, tdeTypeModif eType, tdeStatus eStatus)
{
    if(m_p_DlgList)
        m_p_DlgList->fn_vUpdateSelection(E_lrm_ReinitList);
}

//--------------------------------------------------------------------------------
//
//--------------------------------------------------------------------------------
void Geometry3D_Interface::fn_vOnModifCopy    (CPA_List<EDT_SaveParents> *pListObjects, tdeTypeModif eType, tdeStatus eStatus)
{
    if(m_p_DlgList)
        m_p_DlgList->fn_vUpdateSelection(E_lrm_ReinitList);
}

//--------------------------------------------------------------------------------
//
//--------------------------------------------------------------------------------
void Geometry3D_Interface::fn_vOnModifName    (CPA_SuperObject *pEdObj, CString csInitalName, CString csFinalName, tdeTypeModif eType, tdeStatus eStatus)
{
    if(m_p_DlgList)
        m_p_DlgList->fn_vUpdateSelection(E_lrm_ReinitList);
}

/////////////////
// Dialog List //
/////////////////

//--------------------------------------------------------------------------------
//
//--------------------------------------------------------------------------------
CPA_BaseObject* Geometry3D_Interface::GetDialogSelection (CPA_DialogList *pDialog, CString csTypeName, tdeListDrawMode eDrawMode)
{
    return m_p_SelectedSprObj;
}

//--------------------------------------------------------------------------------
//
//--------------------------------------------------------------------------------
void Geometry3D_Interface::GetListsForDialog(CPA_DialogList *pDialog)
{
    m_oListOfSuperObjectPO . DeleteAllElements();

    mfn_vFillListWithPO( &m_oListOfSuperObjectPO, GetInterface() -> GetSpecificInterface() -> GetDynamicRoot() );
    // list of instances
    m_p_DlgList->fn_vAddANewList(C_szGeometricObjectTypeName,GetInterface()->GetSortedListByType(C_szGeometricObjectTypeName));
    m_p_DlgList->fn_vAddANewList(C_szPhysicalObjectTypeName,&m_oListOfSuperObjectPO);
    m_p_DlgList->fn_vAddANewList(C_szInstanciatedPhysicalObjectTypeName,GetInterface()->GetSortedListByType(C_szInstanciatedPhysicalObjectTypeName));

    // hierarchy
    if(M_GetWorld() && M_GetWorld()->GetRoot())
        m_p_DlgList->fn_vAddANewTree(C_szHierarchyList,M_GetWorld()->GetRoot());
}

//--------------------------------------------------------------------------------
//
//--------------------------------------------------------------------------------
BOOL Geometry3D_Interface::fn_bOnSelChangeHierarchyTree(CPA_DialogList *pDialog, CString csTypeName, CPA_BaseObject *pSelectedObject, CPA_BaseObject *pSelectedParent)
{
    if( fn_bIsCurrentEditor() )
    {
        M_CancelSelection();
        // add current object
        GetInterface()->fn_vAddSelectedObject((CPA_SuperObject*)pSelectedObject,FALSE);
        // update
        GetInterface()->fn_vUpdateAll(E_mc_UpdateDialog);
    }
    return FALSE;
}

//--------------------------------------------------------------------------------
//
//--------------------------------------------------------------------------------
BOOL Geometry3D_Interface::fn_bOnSelChangeListObjects(CPA_DialogList *pDialog, CString csTypeName, CPA_BaseObject *pSelectedObject, BOOL _bUnselect)
{
    if( fn_bIsCurrentEditor() )
    {
        if( _bUnselect )
        {
            M_CancelSelection();
            // update
            GetInterface()->fn_vUpdateAll(E_mc_UpdateDialog);
        }
        else
        {
            M_CancelSelection();
            // add current object
            GetInterface()->fn_vAddSelectedObject((CPA_SuperObject*)pSelectedObject,FALSE);
            // update
            GetInterface()->fn_vUpdateAll(E_mc_UpdateDialog);
        }
    }
    return FALSE;
}

//--------------------------------------------------------------------------------
//
//--------------------------------------------------------------------------------
BOOL Geometry3D_Interface::fn_bOnDblClkHierarchyTree(CPA_DialogList *pDialog, CString csTypeName, CPA_BaseObject *pSelectedObject, CPA_BaseObject *pSelectedParent)
{
	// BEGIN CPA2 Cristi Petrescu 98-03-
	// Launch modal dialog directly from the hierarchy
	CPA_SuperObject *poSuperObject = (CPA_SuperObject *) pSelectedObject;
	if (poSuperObject && (poSuperObject -> GetObjectType () & (HIE_C_ulIPO | HIE_C_ulIPO_Mirror)))
	{
		EditorPO *pPO = ((EditorIPO *) (poSuperObject -> GetObject())) -> GetPhysicalObject ();
		ASSERT (pPO);
		Shape3D *poObject=(Shape3D *) pPO -> m_pGeom;
		if(poObject) 
		{	
			CPA_Modif *o = poObject -> GetUndoData ();
			if(poObject -> _OnLButtonDblClk (0, 0, 0, 0))
			{
				if(o) M_GetEditManager()->AskFor(o);
				poObject->fn_vNotifySaveObject ();
			}
			else delete o;
			poObject->mfn_vRefreshElement ();
			return FALSE;
		}	
	}
	// END CPA2 Cristi Petrescu 98-03-

    return (!GetInterface() -> fn_bSelectObject((CPA_SuperObject*) pSelectedObject, TRUE, FALSE ));
}

//--------------------------------------------------------------------------------
//
//--------------------------------------------------------------------------------
BOOL Geometry3D_Interface::fn_bOnDblClkListObjects(CPA_DialogList *pDialog, CString csTypeName, CPA_BaseObject *pSelectedObject)
{
    return (!GetInterface() -> fn_bSelectObject((CPA_SuperObject*) pSelectedObject, TRUE, FALSE ));
}


//--------------------------------------------------------------------------------
//
//--------------------------------------------------------------------------------
void Geometry3D_Interface::fn_vInitDefaultParameters(CPA_DialogList *pDialog)
{
    m_p_DlgList->SetDefaultTestName("");
    m_p_DlgList->SetDefaultButtonState(FALSE);
    m_p_DlgList->SetDefaultTypeName(C_szHierarchyList);
}

//////////////////
// Menu Methods //
//////////////////
//**************************************************************************************
//Begin Mircea Dunka 31 Aug 1998 - DialogBar interface
void Geometry3D_Interface::fn_vDefineDlgBarBtnIcon (tde_DlgBarCategory wCategory, tds_DlgBarBtn *_pDlgBarBtn)
{
	if(wCategory == C_DlgBarCategoryEditor)
	{
		_pDlgBarBtn->hIcon = ::LoadIcon((HINSTANCE)(GetDLLIdentity()->hModule), MAKEINTRESOURCE(IDI_OGD_DLGBAR_ICON));

        CString oCst;
        oCst = "Geometry";
        if( (M_GetMainApp()) && (M_GetMainApp()->mp_oAppKeyboard) )
        {
            oCst += "  (";
            oCst += M_GetMainApp()->mp_oAppKeyboard->mfn_oConvertIniStringToKeyString((const CString*)&CString("Activate Geometric Object Editor"));
			oCst += ")";
        }
		strcpy(_pDlgBarBtn->szToolTip, (char*)(LPCTSTR)oCst);
		_pDlgBarBtn->uID = (UINT)this;
	}
	
}
//end Mircea Dunka 31 Aug 1998

//--------------------------------------------------------------------------------
//
//--------------------------------------------------------------------------------
BOOL Geometry3D_Interface::fn_bDefineSubMenu(EDT_SubMenu *_p_oEDTSubMenu)
{
    if (_p_oEDTSubMenu->GetSubMenuType() == C_SubMenuEditor)
    {
        CString oCst;

        oCst = "Geometry";
        if( (M_GetMainApp()) && (M_GetMainApp()->mp_oAppKeyboard) )
        {
            oCst += "\t";
            oCst += M_GetMainApp()->mp_oAppKeyboard->mfn_oConvertIniStringToKeyString((const CString*)&CString("Activate Geometric Object Editor"));
        }

        if( fn_bIsCurrentEditor() )
            _p_oEDTSubMenu->AddAnEntry(this, (char*)(LPCTSTR)oCst, C_ui3DGPopupExit,TRUE);
        else
        {
            // try to open with selection
            _p_oEDTSubMenu->AddAnEntry(this, (char*)(LPCTSTR)oCst, C_ui3DGPopupEdit,FALSE,fn_bCanActivateEditor(NULL));
        }
		return TRUE;
	}
	else if (_p_oEDTSubMenu->GetSubMenuType() == C_SubMenuSpecific)
    {
   		// submenu "Preference"
		_p_oEDTSubMenu->AddAnEntry(this, "Save Dialogs Dimensions", C_ui3DGPopupPref);
		return TRUE;
	}
	return FALSE;
}

//--------------------------------------------------------------------------------
//
//--------------------------------------------------------------------------------
void Geometry3D_Interface::_OnSubMenuCommand(EDT_SubMenu *_p_oEDTSubMenu,UINT uiMsgID)
{
    if(_p_oEDTSubMenu->GetSubMenuType() == C_SubMenuEditor)
        _OnPopUpMenuCommand(uiMsgID);
}

///////////////////
// PopUp Methods //
///////////////////

//--------------------------------------------------------------------------------
//
//--------------------------------------------------------------------------------
BOOL Geometry3D_Interface::fn_bDefinePopupMenu(EDT_PopUpMenu *pPopup, CPA_List<CPA_SuperObject> *pSelection, BOOL bIsAlone)
{
    // in/out editor
    if(bIsAlone)
    {
// ANNECY MT 23/02/98 {
		if(m_p_SelectedSprObj)
		{
			if( m_bShowBoundingVolume )
				pPopup->AddAnEntry(this, "Hide Bounding Volume", C_ui3DGPopupHideBdV );
			else
				pPopup->AddAnEntry(this, "Show Bounding Volume", C_ui3DGPopupShowBdV );
		}
// END ANNECY MT }
        // 3DGeom is current editor
        pPopup->AddAnEntry(this, "Exit Geometric editor", C_ui3DGPopupExit);
		return TRUE;
    }

	if( ! fn_bIsCurrentEditor() )
	{
        // pSelection is Selection
        if( fn_bCanActivateEditor(NULL) )
		{
			// adds new entry
			pPopup->AddAnEntry(this, "Edit geometry", C_ui3DGPopupEdit);
			return TRUE;
		}
	}
	return FALSE;
}

//--------------------------------------------------------------------------------
//
//--------------------------------------------------------------------------------
void Geometry3D_Interface::_OnPopUpMenuCommand(UINT m_IDCmdMsg)
{
    switch(m_IDCmdMsg)
    {
        case C_ui3DGPopupEdit:
            GetMainWorld()->fn_bActivateEditor(this,NULL);  // open with selection
            break;
        case C_ui3DGPopupExit:
            GetMainWorld()->fn_bCloseEditor(this);
            break;
        case C_ui3DGPopupPref:
            mfn_vSavePreferences();
            break;
// ANNECY MT 23/02/98 {
		case C_ui3DGPopupShowBdV:
			m_bShowBoundingVolume = TRUE;
			mfn_vShowOrHideBoundingVolume( TRUE );
			break;
		case C_ui3DGPopupHideBdV:
			m_bShowBoundingVolume = FALSE;
			mfn_vShowOrHideBoundingVolume( FALSE );
			break;
// END ANNECY MT }
    }
}

////////////////////
// Editor methods //
////////////////////

//--------------------------------------------------------------------------------
//
//--------------------------------------------------------------------------------
BOOL Geometry3D_Interface::fn_bCanActivateEditor (CPA_List<CPA_BaseObject> *_p_oList)
{
    if( ! fn_bIsCurrentEditor() )
    {
        if( _p_oList != NULL )
        {
            // try to open with given list
            if( _p_oList -> IsEmpty() )
                return TRUE;
            else if( _p_oList -> GetCount() == 1 )
            {
                CPA_BaseObject *p_oBaseObject = _p_oList -> GetHead();
                if( p_oBaseObject -> fn_bIsOfType( C_szGeometricObjectTypeName ) ||
                    p_oBaseObject -> fn_bIsOfType( C_szPhysicalObjectTypeName ) ||
                    p_oBaseObject -> fn_bIsOfType( C_szInstanciatedPhysicalObjectTypeName )
                  )
                  return TRUE;
                else if( p_oBaseObject -> fn_bIsOfType( "SuperObject" ) )
                {
                    p_oBaseObject = ( (CPA_SuperObject*) p_oBaseObject ) -> GetObject();
                    if( p_oBaseObject &&
                        ( p_oBaseObject -> fn_bIsOfType( C_szGeometricObjectTypeName ) ||
                          p_oBaseObject -> fn_bIsOfType( C_szPhysicalObjectTypeName ) ||
                          p_oBaseObject -> fn_bIsOfType( C_szInstanciatedPhysicalObjectTypeName )
                        )
                      )
                      return TRUE;
                }
            }
        }
        else
        {
            if( M_GetCountSelected() == 0 )
                return TRUE;
            else if( M_GetCountSelected() == 1 )
            {
                CPA_BaseObject *p_oBaseObject = M_GetSingleSelection() -> GetObject();
                if( p_oBaseObject &&
                    ( p_oBaseObject -> fn_bIsOfType( C_szGeometricObjectTypeName ) ||
                      p_oBaseObject -> fn_bIsOfType( C_szPhysicalObjectTypeName ) ||
                      p_oBaseObject -> fn_bIsOfType( C_szInstanciatedPhysicalObjectTypeName )
                    )
                  )
                  return TRUE;
            }
        }
    }
    return FALSE;
}

//--------------------------------------------------------------------------------
//
//--------------------------------------------------------------------------------
BOOL Geometry3D_Interface::fn_bCanCloseEditor (void)
{
    return ( fn_bIsCurrentEditor() );
}

//--------------------------------------------------------------------------------
//
//--------------------------------------------------------------------------------
void Geometry3D_Interface::fn_vOnActivateEditor (CPA_List<CPA_BaseObject> *pParam, BOOL bBackActivated /*=FALSE*/)
{
    // Dialog Lists
    m_p_DlgList->fn_vInitAllLists();
    m_p_DlgList->fn_vReinitDialog();
    // activate frame
	g_oFrameGest.mfn_vSetRefresh(FALSE);
    g_oFrameGest.mfn_vActivateWindow (m_p_oSplitterLeft) ;
    g_oFrameGest.mfn_vSetRefresh(TRUE);
    // get selected object
    fn_vUnSelect();

    m_csPreviousSelectMode = GetInterface() -> GetSelectMode();
    GetInterface() -> SetSelectMode( "All Types" );

    m_p_DlgCaract->fn_vUpdateInfo( NULL , NULL );

	// display Tip of the Day
	GetInterface()->fn_vDisplayTipOfDay("Geometry", "OGD", g_bTipFirstTime);
	g_bTipFirstTime = FALSE;

}

//--------------------------------------------------------------------------------
//
//--------------------------------------------------------------------------------
void Geometry3D_Interface::fn_vOnCloseEditor (void)
{
    fn_vUnSelect();
	//
// ANNECY MT 23/02/98 {
	delete m_p_oBoundingVolumeSprObj;
	m_p_oBoundingVolumeSprObj = NULL;
// END ANNECY MT }
	//
    GetInterface() -> SetSelectMode( m_csPreviousSelectMode );
    M_CancelSelection();
}

//--------------------------------------------------------------------------------
//
//--------------------------------------------------------------------------------
long Geometry3D_Interface::OnQueryAction(CPA_EditorBase * p_oSender, WPARAM _wParam, LPARAM _lParam)
{

//ROMTEAM WorldEditor (Cristian Stegaru 01/98)
	static CString csGeomObjName;
//ENDROMTEAM WorldEditor (Cristian Stegaru

    if( _wParam == C_uiCreateGeometricObject )
    {
        // create new Geometry3D with given engine struct
        ACP_tdxHandleOfObject   hEngineObject = (ACP_tdxHandleOfObject) _lParam;
        Geometry3D              *pEdObj = (Geometry3D*)GetBaseObject( hEngineObject, C_szGeometricObjectTypeName );
        if( pEdObj == NULL )
        {
            // new object
            char                    *p_szSectionName;
	        //char					szSectionName[SCR_CV_ui_Cfg_MaxLenName];
	        char					szFileName[SCR_CV_ui_Cfg_MaxLenName];
	        char					szActionName[SCR_CV_ui_Cfg_MaxLenName];
	        char					szName[SCR_CV_ui_Cfg_MaxLenName];
            CPA_BaseObject			*p_oGeomFileOwner = NULL;
// fbolefeysot - 06/08/98
// bidouille pour morphing premiere frame{
			SCR_tdst_Link_Value		*p_stLinkValue;

	        // get parameters
			p_stLinkValue = SCR_fnp_st_Link_SearchValue(GLI_p_stGetLinkTableOfGeometric(),(unsigned long) _lParam);

			if (p_stLinkValue)
			{
				p_szSectionName = SCR_M_p_sz_Link_GetKey(p_stLinkValue);
		        SCR_fn_v_RdL0_SplitSectionName(p_szSectionName, szFileName, szActionName, szName);
			}
			else 
			{
				strcpy(szFileName,"virtualMorph.mod");
			}
//END fbolefeysot}

            p_oGeomFileOwner = GetInterface()->GetFileObject(szFileName);

	        // create object
            pEdObj = new Geometry3D(this, p_oGeomFileOwner, hEngineObject, szName, NULL, p_stLinkValue ? E_ss_Modify : E_ss_NoSave);
            /*
            // update list of Edit-ModifGeometric sections
            mfn_vAddFileOnModifSectionList( szFileName );

            // EDIT-ModifGeometric Section Exists ????
   	        SCR_fn_v_RdL0_ComputeSectionName(szSectionName, NULL, C_szModifActionName, szName);
            if( mfn_bSectionExistsOnModifSectionList( szSectionName ) )
            {
                SCR_fn_v_RdL0_ComputeSectionName(szSectionName, szFileName, C_szModifActionName, szName);
                SCR_M_RdL0_SetContextLong( 1, 0, pEdObj);
                SCR_fnp_st_RdL0_AnalyseSection( szSectionName, SCR_CDF_uw_Anl_Normal );
            }
            */
        }
        return (long)pEdObj;
    }
    else if( _wParam == C_uiDeleteGeometricObject )
    {
        Geometry3D *pEdObj = (Geometry3D*)_lParam;
        delete pEdObj;
        return (long)TRUE;
    }
    else if( _wParam == C_uiGetOGDTypePath )
    {
        return (long) mfn_p_cGetOGDTypePath( (char*) _lParam );
    }
    else if( _wParam == C_uiGetOwnerByFileName )
    {
        return (long)GetInterface()->GetFileObject( (char*) _lParam);
    }

//ROMTEAM WorldEditor (Cristian Stegaru 01/98)
	else if (C_uiStartITEditor == _wParam)
	{
		//save the calling dll params
		m_pCallingDll = p_oSender;
		m_iQueryCt = (int)_lParam;
		return (long)mfn_bStartITEditor ();
	}
	else if (C_uiEndITEditor == _wParam)
	{
		return (long)mfn_bEndITEditor ();
	}
	else if (C_uiGetITEditor == _wParam)
	{
		return (long)mfn_pGetITEditor ();
	}
	else if (C_uiSetName == _wParam)
	{
		csGeomObjName = (char *)_lParam;
	}
//ENDROMTEAM WorldEditor (Cristian Stegaru)

//ROMTEAM WorldEditor (Nicu 24/11/97)
	// BEGIN CPA2 Cristi Petrescu 98-03-
	else if( _wParam == C_uiCreateObject || _wParam == C_uiCreateCloneObject)
	// END CPA2 Cristi Petrescu 98-03-
	{	QueryActionParam *param = new QueryActionParam;
		BOOL bOrigGeomObject = C_origGeomObjectFlag & _lParam;
		_lParam = _lParam & ~C_origGeomObjectFlag;
		// BEGIN CPA2 Cristi Petrescu 98-02-
		tdeSaveStatus eSaveStatus = E_ss_NoSave;
		if (_wParam == C_uiCreateCloneObject)
			eSaveStatus = E_ss_Modify;
		// END CPA2 Cristi Petrescu 98-02-
		switch(_lParam)
		{
			case 0: 
				{
					CString csGeometricName ("sphere");
					if (!csGeomObjName.IsEmpty ())
						csGeometricName = csGeomObjName;
					else if (!bOrigGeomObject)
						csGeometricName =  mfn_csGetGeometricName (csGeometricName);

					param->SetContent(new ITSphere3D(this, 1.f, (LPCSTR)csGeometricName, eSaveStatus), (LPCSTR)csGeometricName, _lParam);
							break;
				}
			case 1: 
				{
					CString csGeometricName ("box");
					if (!csGeomObjName.IsEmpty ())
						csGeometricName = csGeomObjName;
					else if (!bOrigGeomObject)
						csGeometricName =  mfn_csGetGeometricName (csGeometricName);

					param->SetContent(new ITBox3D(this, 1.f, (LPCSTR)csGeometricName, eSaveStatus), (LPCSTR)csGeometricName, _lParam);
							break;
				}
			case 2: 
				{
					CString csGeometricName ("cone");
					if (!csGeomObjName.IsEmpty ())
						csGeometricName = csGeomObjName;
					else if (!bOrigGeomObject)
						csGeometricName =  mfn_csGetGeometricName (csGeometricName);

					param->SetContent(new ITCon3D(this, 1.f, 1.f, (LPCSTR)csGeometricName, eSaveStatus), (LPCSTR)csGeometricName, _lParam);
							break;
				}
			case 3: 
				{
					CString csGeometricName ("altimap");
					if (!csGeomObjName.IsEmpty ())
						csGeometricName = csGeomObjName;
					else if (!bOrigGeomObject)
						csGeometricName =  mfn_csGetGeometricName (csGeometricName);

					param->SetContent(new Altimap3D(this, (LPCSTR)csGeometricName, eSaveStatus), (LPCSTR)csGeometricName, _lParam);
							break;
				}
			default:	delete param;
								param = NULL;
		}
//prepare for next call
		csGeomObjName.Empty (); // Stegaru 98-01
		return (long)param;
	}
//ENDROMTEAM WorldEditor (Nicu)

    return 0L;
}

// --------------------------------------------------------------
// OBJECT DLL FUNCTIONS OVERLOAD
// --------------------------------------------------------------

/***********************************************************************
	You MUST define this function

  Create a new editor instance to be associated with the given engine instance
  !!! must also create all protected childs !!!
************************************************************************/
void Geometry3D_Interface::fn_vBuildNewEditorInstance (CPA_SuperObject *pEditorInstance, HIE_tdxHandleToSuperObject hEngineInstance)
{
	ACP_tdxHandleOfObject	hEngineObject;
	Geometry3D				*pEdObj;
    char                    *p_szSectionName;
	//char					szSectionName[SCR_CV_ui_Cfg_MaxLenName];
	char					szFileName[SCR_CV_ui_Cfg_MaxLenName];
	char					szName[SCR_CV_ui_Cfg_MaxLenName];
    CPA_BaseObject			*p_oGeomFileOwner = NULL;


    hEngineObject = (ACP_tdxHandleOfObject) HIE_fn_hGetSuperObjectObject(hEngineInstance);
	// get parameters
	p_szSectionName = GLI_p_cSearchValueInLinkTableOfGeometric((unsigned long) hEngineObject);
	SCR_fn_v_RdL0_SplitSectionName(p_szSectionName, szFileName, NULL, szName);
	// create object
    p_oGeomFileOwner = GetInterface()->GetFileObject(szFileName);

    pEdObj = new Geometry3D(this, p_oGeomFileOwner, hEngineObject, szName);

    /*
    // update list of Edit-ModifGeometric sections
    mfn_vAddFileOnModifSectionList( szFileName );

    // EDIT-ModifGeometric Section Exists ????
   	SCR_fn_v_RdL0_ComputeSectionName(szSectionName, NULL, C_szModifActionName, szName);
    if( mfn_bSectionExistsOnModifSectionList( szSectionName ) )
    {
        SCR_fn_v_RdL0_ComputeSectionName(szSectionName, szFileName, C_szModifActionName, szName);
        SCR_M_RdL0_SetContextLong( 1, 0, pEdObj);
        SCR_fnp_st_RdL0_AnalyseSection( szSectionName, SCR_CDF_uw_Anl_Normal );
    }
    */
	pEditorInstance->SetObject(pEdObj);
}


/***********************************************************************
	You MUST define this function

  Init the type of objets the DLL can give to Hierarchy Editor
************************************************************************/
////
CPA_SuperObject* Geometry3D_Interface::GetNewEditorInstance(HIE_tdxHandleToSuperObject pEngineInstance)
{
    // probably unused ??????

    ACP_tdxHandleOfObject  hEngineObject;
    CPA_SuperObject        *pSupObj;
    Geometry3D             *pEdObj;

    pSupObj = GetInterface()->GetNewSuperObject(pEngineInstance, E_ss_Responsible, C_Static);
    hEngineObject = (ACP_tdxHandleOfObject) HIE_fn_hGetSuperObjectObject(pEngineInstance);

    pEdObj = (Geometry3D*)GetBaseObject( hEngineObject, C_szGeometricObjectTypeName );
    if( ( pEdObj == NULL ) && ( hEngineObject != NULL ) )
    {
        char					*p_szSectionName;
        char                    szFileName[SCR_CV_ui_Cfg_MaxLenName];
        char                    szName[SCR_CV_ui_Cfg_MaxLenName];
        CPA_BaseObject			*p_oGeomFileOwner = NULL;

	    // get parameters
	    p_szSectionName = GLI_p_cSearchValueInLinkTableOfGeometric((unsigned long) hEngineObject);
        SCR_fn_v_RdL0_SplitSectionName(p_szSectionName, szFileName, NULL, szName);
	    // create object
        p_oGeomFileOwner = GetInterface()->GetFileObject(szFileName);

        pEdObj = new Geometry3D(this, p_oGeomFileOwner, hEngineObject);
    }
    pSupObj->SetObject(pEdObj);

    return pSupObj;
}


//--------------------------------------------------------------------------------
//
//--------------------------------------------------------------------------------
BOOL Geometry3D_Interface::fn_bCanHandleThisType(long lEngineType)
{
    return (lEngineType == HIE_C_ulEDT_Geometric);
}

//--------------------------------------------------------------------------------
//
//--------------------------------------------------------------------------------
void Geometry3D_Interface::fn_vInitListByType(CPA_World *pWorld)
{
	pWorld->fn_vAddANewListByType (C_szGeometricType, this);
}

//--------------------------------------------------------------------------------
//
//--------------------------------------------------------------------------------
CPA_BaseObject * Geometry3D_Interface::Duplicate (CPA_BaseObject *pObject, CPA_SuperObject *pNewSupObj)
{
    Geometry3D *pSourceObj;
    Geometry3D *pNewObj;
    long        lCount = 1;
    ACP_tdxHandleOfObject hObject;

    pSourceObj = (Geometry3D *)pObject;

    // build the copy
    hObject = GEO_xDuplicateGeometricObject(pSourceObj->GetStruct(), 0);
    pNewObj = new Geometry3D( this, pSourceObj->GetOwner(), hObject, "", NULL, pSourceObj->GetSaveStatus());

    return pNewObj;
}

///////////////////
// owner methods //
///////////////////

BOOL Geometry3D_Interface::fn_bShowWarnings(void)
{
	return (m_bShowWarnings && ! m_bStopWarnings);
}

void Geometry3D_Interface::fn_vStopWarnings(void)
{
	m_bStopWarnings = TRUE;
}

//--------------------------------------------------------------------------------
//
//--------------------------------------------------------------------------------
void Geometry3D_Interface::fn_vUnSelect()
{
// ANNECY MT 23/02/98 {
	mfn_vShowOrHideBoundingVolume( FALSE );
	mfn_vShowOrHideElement( FALSE );
// END ANNECY MT }
    m_p_SelectedSprObj = NULL;
    m_p_SelectedObject = NULL;
//ROMTEAM WorldEditor (Viorel Preoteasa 06/01/98)
    //m_xSelectedPointIndex = 0;
//CPA2 Corneliu Babiuc 09-09-98 (duplicated points)
//    m_iNbSelectedPoints = 0;
    mfn_vClearListOfSelectedPoints();
//ENDROMTEAM WorldEditor (Viorel Preoteasa)
    m_bPointSelected = FALSE;
    m_bPointTranslated = FALSE;
}

//--------------------------------------------------------------------------------
// Change object name
//--------------------------------------------------------------------------------
void Geometry3D_Interface::fn_vChangeName(CString _csName)
{
    Geometry3D_Rename *p_oRename = new Geometry3D_Rename( m_p_SelectedObject, _csName );
    M_GetEditManager()->AskFor( p_oRename );
}

//--------------------------------------------------------------------------------
//
//--------------------------------------------------------------------------------
void Geometry3D_Interface::fn_vNameChanged()
{
    m_p_DlgList->fn_vUpdateSelection(E_lrm_ReinitList);
    m_p_DlgCaract->fn_vUpdateInfo(m_p_SelectedSprObj,m_p_SelectedObject);
}

//--------------------------------------------------------------------------------
// Compute bounding volume of the geometric object.
//--------------------------------------------------------------------------------
void Geometry3D_Interface::fn_vComputeBoundingVolume(CPA_BaseObject *_pObj)
{
    Geometry3D *pObj = (Geometry3D *) _pObj;
    pObj -> fn_vComputeBoundingVolume( FALSE );
}

//--------------------------------------------------------------------------------
// return bounding volume of the geometric object.
//--------------------------------------------------------------------------------
ACP_tdxHandleOfObject Geometry3D_Interface::fn_hGetBoundingVolume(CPA_BaseObject *_pObj)
{
    Geometry3D *pObj = (Geometry3D *) _pObj;
    return pObj -> fn_hGetBoundingVolume();
}

//--------------------------------------------------------------------------------
// add Modif sections file on List
//--------------------------------------------------------------------------------
/*
void Geometry3D_Interface::mfn_vAddFileOnModifSectionList(char * _szFileName)
{
    // search FileName to LinkTable
    // if not founded, add FileName and Analyse EDIT_ListModifGeometric section
    if( ! mfn_bSectionExistsOnModifSectionList( _szFileName ) )
    {
        char szSectionName[SCR_CV_ui_Cfg_MaxLenName];

        // add FileName to List
        m_oListOfModifSection . AddHead( CString(_szFileName) );
        // analyse "Edit-ListModifGeometric" section
        SCR_fn_v_RdL0_ComputeSectionName(szSectionName, _szFileName,
                                                        C_szModifListActionName,
                                                        NULL);
        if( SCR_fn_c_RdL0_IsSectionExists( szSectionName ) )
        {
            SCR_M_RdL0_SetContextLong( 1, 0, &m_oListOfModifSection );
            SCR_fnp_st_RdL0_AnalyseSection( szSectionName, SCR_CDF_uw_Anl_Normal );
        }
    }
}
*/

//--------------------------------------------------------------------------------
// search modif section to List
//--------------------------------------------------------------------------------
/*
BOOL Geometry3D_Interface::mfn_bSectionExistsOnModifSectionList(char *_szSectionName)
{
    POSITION stPos = m_oListOfModifSection . GetHeadPosition();
    while( stPos )
    {
        CString csEntry = m_oListOfModifSection . GetNext( stPos );
        if(csEntry == _szSectionName)
            return TRUE;
    }
    return FALSE;
}
*/

// ----------------------------------------------------------------------------
// Save Preferences
// ----------------------------------------------------------------------------
void Geometry3D_Interface::mfn_vSavePreferences(void)
{
	CString	csFileName;
	CString	csDimension;

	csFileName = M_GetMainApp()->m_csEditorDataPath + "Objects\\3DGeom\\3DGeom.ini";
    // Left Frame size
    csDimension.Format("%ld", m_p_oSplitterLeft -> m_oCurPos.right - m_p_oSplitterLeft -> m_oCurPos.left);
    WritePrivateProfileString ("Preference", "Left Frame Width", (char*)(LPCSTR)csDimension, (char*)(LPCSTR)csFileName);
    //  DialogList size
	csDimension.Format("%ld", m_p_oSplitterLeft -> GetPaneSize(0));
	WritePrivateProfileString ("Preference", "DialogList Height", (char*)(LPCSTR)csDimension, (char*)(LPCSTR)csFileName);
    // Caracteristics dialog size
	csDimension.Format("%ld", m_p_oSplitterLeft -> GetPaneSize(1));
	WritePrivateProfileString ("Preference", "CaracteristicDialog Height", (char*)(LPCSTR)csDimension, (char*)(LPCSTR)csFileName);

	// Show Warnings
	csDimension = m_bShowWarnings ? "ON" : "OFF";
	WritePrivateProfileString ("Preference", "Show Warnings", (char*)(LPCSTR)csDimension, (char*)(LPCSTR)csFileName);

    // write on file
	WritePrivateProfileString (NULL , NULL, NULL, (char*)(LPCSTR)csFileName);
}

// ----------------------------------------------------------------------------
// Save Preferences
// ----------------------------------------------------------------------------
void Geometry3D_Interface::mfn_vComputeLocalTranslation(CPA_SuperObject *_p_oSprObj, MTH3D_tdstVector *_p_stInitVector,MTH3D_tdstVector *_p_stResultVector)
{
    POS_tdxHandleToPosition     hMatrix;
    POS_tdstCompletePosition    stMatrix;
    MTH3D_tdstVector            stVect;

	POS_fn_vSetIdentityMatrix(&stMatrix);
	hMatrix = HIE_fn_hGetSuperObjectGlobalMatrix( _p_oSprObj -> GetStruct() );

    POS_fn_vInvertIsoMatrix(&stMatrix, hMatrix );

    MTH3D_M_vNullVector(&stVect);
	POS_fn_vSetTranslationVector(&stMatrix,&stVect);

    POS_fn_vMulMatrixVertex(_p_stResultVector, &stMatrix, _p_stInitVector);
}

// ----------------------------------------------------------------------------
// Fill List with SuperObject PO
// ----------------------------------------------------------------------------
void Geometry3D_Interface::mfn_vFillListWithPO(CPA_BaseObjectList *_p_oList, CPA_SuperObject *_p_oSprObj)
{
    if( _p_oSprObj )
    {
        CPA_BaseObject *p_oObject = _p_oSprObj -> GetObject();
        if( p_oObject && p_oObject -> fn_bIsOfType( C_szPhysicalObjectTypeName ) )
            _p_oList -> fn_bAddObject( _p_oSprObj );

        CPA_SuperObject *p_oEdChild = _p_oSprObj -> GetSuperObjectFirstChild();
        while( p_oEdChild )
        {
            mfn_vFillListWithPO( _p_oList, p_oEdChild );
            p_oEdChild = _p_oSprObj -> GetSuperObjectNextChild( p_oEdChild );
        }
    }
}

/*-----------------------------------------------------------------------------
 *  Description :
 *---------------------------------------------------------------------------*/
char *Geometry3D_Interface::mfn_p_cGetOGDTypePath(char *_szSectionName)
{
    // class
    M_ReturnIfUsePath( _szSectionName, fn_szGetGraphicsClassesDataPath() );
    // bank
    M_ReturnIfUsePath( _szSectionName, fn_szGetGraphicsBanksDataPath() );
    // family
    M_ReturnIfUsePath( _szSectionName, fn_szGetFamiliesDataPath() );
    // level
    M_ReturnIfUsePath( _szSectionName, fn_szGetLevelsDataPath() );
	// GenDoors
    M_ReturnIfUsePath( _szSectionName, C_szGenDoorsDataPath );
    // error
    return NULL;
}

/*-----------------------------------------------------------------------------
 *  Description :
 *---------------------------------------------------------------------------*/
/*CPA_BaseObject *Geometry3D_Interface::mfn_p_oGetGeometricFile(char *_szSectionName)
{
    char szFileName[SCR_CV_ui_Cfg_MaxLenName];
    CPA_BaseObject *p_oGeomFile = NULL;

    if( strchr( _szSectionName, SCR_CC_c_Cfg_NameSeparator ) != NULL )
        SCR_fn_v_RdL0_SplitSectionName(_szSectionName, szFileName, NULL, NULL);
    else
        strcpy( szFileName, _szSectionName );

    // search GeometricFile with this Name
    p_oGeomFile = GetBaseObject( CString(szFileName), C_sz3DFileTypeName );
    if ( p_oGeomFile == NULL )
    {
        p_oGeomFile = new GeometricFile( this, szFileName );
    }
    return p_oGeomFile;
}
*/

/*-----------------------------------------------------------------------------
 *  Description :
 *---------------------------------------------------------------------------*/
void Geometry3D_Interface::fn_vComputeModificationFile(char *_p_cFileName, CPA_SaveObject *_p_oObject)
{
    CString csCompleteSectionName = _p_oObject -> GetCompleteSectionName();
    char *p_cSectionName = (char*)(LPCTSTR)csCompleteSectionName;
    char *p_cPoint = NULL;


    if( strchr( p_cSectionName, SCR_CC_c_Cfg_NameSeparator ) != NULL )
        SCR_fn_v_RdL0_SplitSectionName(p_cSectionName, _p_cFileName, NULL, NULL);
    else
        strcpy( _p_cFileName, p_cSectionName );

    p_cPoint = strrchr( _p_cFileName, '.' );

    if ( p_cPoint )
    {
        ++ p_cPoint;
        strcpy( p_cPoint, "emo" );
    }
}

//ROMTEAM WorldEditor (Cristian Stegaru 11/97) 

//////////////////////////////////////////////////////////////////////////////////////////////////////
// Method : mfn_bStartITEditor 
// Date   : 97-11
//////////////////////////////////////////////////////////////////////////////////////////////////////
// Description :
// Author      : Cristian Stegaru - CPA2
//////////////////////////////////////////////////////////////////////////////////////////////////////
// Modification :
// Date         :
// By           :
//////////////////////////////////////////////////////////////////////////////////////////////////////
BOOL Geometry3D_Interface::mfn_bStartITEditor ()
{
	m_pITEditor = (CEdThread*)AfxBeginThread (RUNTIME_CLASS (CEdThread));
	if (NULL != m_pITEditor)
	{
		m_pITEditor->mfn_vLinkToDll (this);
		return TRUE;
	}
	else 
		return FALSE;
}

//////////////////////////////////////////////////////////////////////////////////////////////////////
// Method : mfn_bEndITEditor 
// Date   : 97-11
//////////////////////////////////////////////////////////////////////////////////////////////////////
// Description :
// Author      : Cristian Stegaru	- CPA2
//////////////////////////////////////////////////////////////////////////////////////////////////////
// Modification :
// Date         :
// By           :
//////////////////////////////////////////////////////////////////////////////////////////////////////
BOOL Geometry3D_Interface::mfn_bEndITEditor ()
{
	BOOL bRet = FALSE;
	if (m_pITEditor)
	{
		if (bRet = m_pITEditor->PostThreadMessage (WM_QUIT, 0, 0))
			m_pITEditor = NULL;
	}
	return bRet;
}

//////////////////////////////////////////////////////////////////////////////////////////////////////
// Method : mfn_pGetITEditor 
// Date   : 97-11
//////////////////////////////////////////////////////////////////////////////////////////////////////
// Description :
// Author      : Cristian Stegaru	- CPA2
//////////////////////////////////////////////////////////////////////////////////////////////////////
// Modification :
// Date         :
// By           :
//////////////////////////////////////////////////////////////////////////////////////////////////////
CTriEdit *Geometry3D_Interface::mfn_pGetITEditor ()
{
	//PAY ATTENTION, THE POINTER IS TEMPORARILY, DON'T STORE IT
	if (m_pITEditor)
		m_pITEditor->mfn_pGetITEditor ();

	return NULL;
}

//////////////////////////////////////////////////////////////////////////////////////////////////////
// Method : mfn_bCreateITObject  
// Date   : 97-11
//////////////////////////////////////////////////////////////////////////////////////////////////////
// Description :
// Author      : Cristian Stegaru	- CPA2
//////////////////////////////////////////////////////////////////////////////////////////////////////
// Modification :
// Date         :
// By           :
//////////////////////////////////////////////////////////////////////////////////////////////////////
BOOL Geometry3D_Interface::mfn_bCreateITObject (CTriEdit *pITEditor, CString csName)
{
	if (pITEditor && pITEditor->GetVerts() && pITEditor->GetFaces())
	{
		HINSTANCE hOldInst = AfxGetResourceHandle();
		AfxSetResourceHandle (GetDLLIdentity()->hModule);
		CString csDefaultITName, csOrigName (csName);
		csDefaultITName.LoadString (IDS_DEFAULT_ITNAME);
		AfxSetResourceHandle(hOldInst);
		csDefaultITName.MakeLower ();
		csOrigName.MakeLower ();
		if (csOrigName == csDefaultITName)
			csName = mfn_csGetGeometricName (csName);

		ITObject3D *pITObject = new ITObject3D (this,
			pITEditor->GetXVertsNumber(),
			pITEditor->GetYVertsNumber(),   
			pITEditor->GetVerts(), 
			pITEditor->GetFaces(),
			csName, E_ss_Modify);
		ASSERT (pITObject);
		if (m_pCallingDll)
		{
			QueryActionParam param (pITObject, csName);
			m_pCallingDll->OnQueryAction (this, m_iQueryCt, (long)&param);
		}

		return TRUE;
	}
	return FALSE;
}


//////////////////////////////////////////////////////////////////////////////////////////////////////
// Method : mfn_csGetGeometricName 
// Date   : 97-12
//////////////////////////////////////////////////////////////////////////////////////////////////////
// Description :
// Author      : Cristian Stegaru	- CPA2
//////////////////////////////////////////////////////////////////////////////////////////////////////
// Modification :
// Date         :
// By           :
//////////////////////////////////////////////////////////////////////////////////////////////////////
CString Geometry3D_Interface::mfn_csGetGeometricName (CString csBaseName)
{
	//CPA2 Stegaru Cristian 98-04
	HINSTANCE hOldInst = AfxGetResourceHandle();
	AfxSetResourceHandle (GetDLLIdentity()->hModule);
	CString csLevelsPath = fn_szGetLevelsDataPath ();
	CString csBasePath;
	csBasePath.LoadString (IDS_BASE_PATH);
	CString csRelativeName;
	CString csFullName (csBaseName);

	csRelativeName = CString ("\\") + fn_p_szGetLevelName () + "\\geomobj.log";
	CString csModFileName = csBasePath + csLevelsPath + csRelativeName;
	CFile file;
	const int iBufLength = 10;
	if (file.Open (csModFileName, CFile::modeReadWrite))
	{
		char buffer [iBufLength], *pBuffer = buffer;
		file.SeekToBegin ();
		file.Read (buffer, iBufLength);
		ASSERT (';' == buffer [0]);
		CString csCount (++pBuffer);
		int iCount = atoi (csCount);
		csCount.TrimRight ();
		csFullName += csCount;
		memset (pBuffer, ' ', iBufLength - 1);
		itoa (++iCount, pBuffer, 10);
		file.SeekToBegin ();
		file.Write (buffer, iBufLength);
		file.Close ();
	}

	AfxSetResourceHandle(hOldInst);
	return csFullName;

//////////////////
/*	HINSTANCE hOldInst = AfxGetResourceHandle();
	AfxSetResourceHandle (GetDLLIdentity()->hModule);
	CString csClassPath = fn_szGetGraphicsClassesDataPath ();
	CString csBasePath;
	csBasePath.LoadString (IDS_BASE_PATH);
	CString csRelativeName;
	CString csFullName (csBaseName);

	csRelativeName.LoadString (IDS_LOG_FILENAME);
	CString csModFileName = csBasePath + csClassPath + csRelativeName;
	CFile file;
	const int iBufLength = 10;
	if (file.Open (csModFileName, CFile::modeReadWrite))
	{
		char buffer [iBufLength], *pBuffer = buffer;
		file.SeekToBegin ();
		file.Read (buffer, iBufLength);
		ASSERT (';' == buffer [0]);
		CString csCount (++pBuffer);
		int iCount = atoi (csCount);
		csCount.TrimRight ();
		csFullName += csCount;
		memset (pBuffer, ' ', iBufLength - 1);
		itoa (++iCount, pBuffer, 10);
		file.SeekToBegin ();
		file.Write (buffer, iBufLength);
		file.Close ();
	}

	AfxSetResourceHandle(hOldInst);
	return csFullName;
  */
	//End CPA2 Stegaru Cristian 98-04
}

//ENDROMTEAM WorldEditor (Cristian Stegaru) 

// ANNECY MT 2302/98 {
void Geometry3D_Interface::mfn_vShowOrHideBoundingVolume( BOOL _bShow )
{
	if( _bShow && m_bShowBoundingVolume && m_p_SelectedSprObj && m_p_SelectedObject)
	{
		// 
		ACP_tdxIndex xNbBdV = GEO_xGetGeometricObjectNumberOfParallelBox( m_p_SelectedObject -> GetStruct() );
		if( xNbBdV )
		{
			// create and add superobject
			if( m_p_oBoundingVolumeSprObj == NULL )
			{
				m_p_oBoundingVolumeSprObj = GetInterface() -> GetNewSuperObject( E_ss_NoSave, C_Protected );
				HIE_fn_SO_vSetFlags( m_p_oBoundingVolumeSprObj -> GetStruct(), HIE_C_Flag_ulNotPickable );
				long lMask = HIE_fn_lGetSuperObjectDrawMask( m_p_oBoundingVolumeSprObj -> GetStruct() );

				HIE_fn_vSetSuperObjectDrawMask( m_p_oBoundingVolumeSprObj -> GetStruct(), 
					   lMask & ~GLI_C_lIsNotDrawCollideInformation  & ~GLI_C_lIsNotDrawCollideInformationLight);
			}

			POS_fn_vSetIdentityMatrix( HIE_fn_hGetSuperObjectMatrix( m_p_oBoundingVolumeSprObj -> GetStruct() ) );
            GetInterface()->fn_bInsertObjectInHierarchy(m_p_oBoundingVolumeSprObj, m_p_SelectedSprObj, FALSE, FALSE, FALSE, FALSE);

			// create object
			m_p_oBoundingVolumeObject = new Geometry3D( this, xNbBdV*2, 1 );

			ACP_tdxHandleOfElement hElementBox = m_p_oBoundingVolumeObject -> fn_hCreateElementAlignedBox( xNbBdV );

			m_p_oBoundingVolumeSprObj -> SetObject( m_p_oBoundingVolumeObject );
			//
			for( ACP_tdxIndex xIndex = 0 ; xIndex < xNbBdV ; xIndex++ )
			{
				MTH3D_tdstVector *p_stVector;

				p_stVector = GEO_fn_pGetMinPointOfParallelBox( GEO_hGetParallelBox( m_p_SelectedObject -> GetStruct(), xIndex ) );
				m_p_oBoundingVolumeObject -> fn_vSetPoint( (xIndex<<1), p_stVector );
				p_stVector = GEO_fn_pGetMaxPointOfParallelBox( GEO_hGetParallelBox( m_p_SelectedObject -> GetStruct(), xIndex ) );
				m_p_oBoundingVolumeObject -> fn_vSetPoint( (xIndex<<1)+1, p_stVector );
				m_p_oBoundingVolumeObject -> fn_eSetAlignedBox( hElementBox, xIndex, (xIndex<<1), (xIndex<<1)+1 );
			}
			m_p_oBoundingVolumeObject -> fn_vEndCreation();
			M_RedrawWorld();
		}
	}
	else
	{
		if( ( m_p_oBoundingVolumeSprObj != NULL )  && ( m_p_oBoundingVolumeObject != NULL ) )
		{
			GetInterface()->fn_bDeleteObjectInHierarchy(m_p_oBoundingVolumeSprObj, FALSE, FALSE );
			//
			m_p_oBoundingVolumeSprObj -> SetObject( NULL );
			delete m_p_oBoundingVolumeObject;
			m_p_oBoundingVolumeObject = NULL;
			M_RedrawWorld();
		}
	}
}

// END ANNECY MT }

void Geometry3D_Interface::mfn_vShowOrHideElement( BOOL _bShow, CPA_SuperObject *_p_oSprObj /*=NULL*/, Geometry3D *_p_oObject /*=NULL*/, ACP_tdxHandleOfElement hElement /*=0*/ )
{
    if( _bShow )
    {
		m_p_ModifiedObject = _p_oObject;
        if( m_p_ModifiedObject && GEO_xGetElementType( m_p_ModifiedObject -> GetStruct(), hElement ) == GEO_C_xElementIndexedTriangles )
        {
            // unselect object
			_p_oSprObj -> SetLocalColor( E_lc_NoColor );						
            // modify material
            m_hModifiedElement = hElement;
            GEO_vGetGameMaterialOfIndexedTriangles( m_p_ModifiedObject -> GetStruct(), m_hModifiedElement , &m_hElementMaterial );
            GEO_vSetGameMaterialOfIndexedTriangles( m_p_ModifiedObject -> GetStruct(), m_hModifiedElement , m_p_ModifiedObject -> fn_hGetDefaultGameMaterial() );
            M_RedrawWorld();
        }
        else
        {
            m_p_ModifiedObject = NULL;
        }
    }
    else
    {
        if( m_p_ModifiedObject )
        {
            // restore material
            GEO_vSetGameMaterialOfIndexedTriangles( m_p_ModifiedObject -> GetStruct(), m_hModifiedElement, m_hElementMaterial );
            m_p_ModifiedObject = NULL;
            M_RedrawWorld();
        }
    }
}

// BEGIN CPA2 Cristi Petrescu 98-02-
//////////////////////////////////////////////////////////////////////////////////////////////////////
// Method : GeometryInterface3D::mfn_vClearFileModificationsList
// Date   : 98.02
//////////////////////////////////////////////////////////////////////////////////////////////////////
// Description : Clear the list of Edit-Modifications sections
// Author      : Cristi Petrescu
//////////////////////////////////////////////////////////////////////////////////////////////////////
// Modification :
// Date         :
// By           :
//////////////////////////////////////////////////////////////////////////////////////////////////////
void Geometry3D_Interface::mfn_vClearFileModificationsList()
{
	POSITION xPos = m_oListOfModifiedFiles . GetHeadPosition ();

    while(! m_oListOfModifiedFiles .IsEmpty ())
    {
        tdstModifFile *p_stModif = m_oListOfModifiedFiles . RemoveHead();
        p_stModif -> oListOfModifiedObjects . RemoveAll ();
		if (p_stModif -> p_oModifSection)
			delete p_stModif -> p_oModifSection;
        delete p_stModif;
    }
}

//////////////////////////////////////////////////////////////////////////////////////////////////////
// Method : Geometry3D::mfn_vAddFileModification
// Date   : 98.02
//////////////////////////////////////////////////////////////////////////////////////////////////////
// Description : add an edit modification
// Author      : Cristi Petrescu
//////////////////////////////////////////////////////////////////////////////////////////////////////
// Modification :
// Date         :
// By           :
//////////////////////////////////////////////////////////////////////////////////////////////////////
void Geometry3D_Interface::mfn_vAddFileModification(Geometry3D *p_oObject)
{
	char szModifSectionName[SCR_CV_ui_Cfg_MaxLenName];

	tdstModifFile *p_stModif = mfn_p_stGetFileModification (p_oObject);

    if( !p_stModif )
    {
        p_stModif = new(tdstModifFile);
		// create the new section
		mfn_vComputeModifSectionName (szModifSectionName, p_oObject);
		p_stModif -> p_oModifSection = new CPA_SectionObject( szModifSectionName, p_oObject -> GetDataPath (), Geometry3D_Interface::CallBackSaveModifListGeometricObject );
		p_stModif -> p_oModifSection -> SetExistingSection( FALSE );
		p_stModif -> p_oModifSection -> SetSectionData( p_stModif );
		
		// pseudo load from file
		if(SCR_fn_c_RdL0_IsSectionExists (szModifSectionName))
		{
			p_stModif -> p_oModifSection -> SetExistingSection( TRUE );
		}
		else
		{
			p_stModif -> p_oModifSection -> SetExistingSection( FALSE );
		}
		/*
		{
			SCR_M_RdL0_SetContextLong (1, 0, this);
			SCR_fnp_st_RdL0_AnalyseSection (szModifSectionName, SCR_CDF_uw_Anl_Normal);
		}
		*/
		
		p_stModif -> p_oModifSection -> fn_vWriteSection ();
		//p_stModif -> p_oModifSection -> fn_vNotifySection (SCR_EA_Ntfy_AddOrRebuildSection);
        
        m_oListOfModifiedFiles . AddTail( p_stModif );
	}
	
	// anyway, add the object
	p_stModif -> oListOfModifiedObjects . AddTail (p_oObject);
}

//////////////////////////////////////////////////////////////////////////////////////////////////////
// Method : Geometry3D_Interface::mfn_p_stGetFileModification
// Date   : 98.02
//////////////////////////////////////////////////////////////////////////////////////////////////////
// Description : retrieves an edit modification section
// Author      : Cristi Petrescu
//////////////////////////////////////////////////////////////////////////////////////////////////////
// Modification :
// Date         :
// By           :
//////////////////////////////////////////////////////////////////////////////////////////////////////
tdstModifFile *Geometry3D_Interface::mfn_p_stGetFileModification(Geometry3D *p_oObject)
{
    tdstModifFile   *p_stModif;
    POSITION        xPos;	

	CString csObjectFileName = p_oObject -> GetDataPath ();
	char *szPoint = NULL;
	char *szFileName = (char *)(LPCSTR) csObjectFileName;

    szPoint = strrchr( szFileName, '.' );

    if ( szPoint )
    {
        ++ szPoint;
        strcpy( szPoint, "mdt" );
    }

    M_ForEachElement( m_oListOfModifiedFiles, p_stModif, xPos )
    {
		if(! strcmp (szFileName, (char *)(LPCSTR) (p_stModif -> p_oModifSection -> GetDataPath ())))
			// same names
            return p_stModif;
    }
    return NULL;
}

//////////////////////////////////////////////////////////////////////////////////////////////////////
// Method : Geometry3D::mfn_vComputeModificationSectionName
// Date   : 98.02
//////////////////////////////////////////////////////////////////////////////////////////////////////
// Description : Computes the name of the modification section
// Author      : Cristi Petrescu
//////////////////////////////////////////////////////////////////////////////////////////////////////
// Modification :
// Date         :
// By           :
//////////////////////////////////////////////////////////////////////////////////////////////////////
void Geometry3D_Interface::mfn_vComputeModifSectionName(char *szModifSectionName, Geometry3D *p_oObject)
{
	CString csReferencedSectionName = p_oObject -> GetReferencedSectionName ();
    char *szSectionName = (char*)(LPCTSTR)csReferencedSectionName;
    char *szPoint = NULL;
	char szFileName[SCR_CV_ui_Cfg_MaxLenName];

    if( strchr( szSectionName, SCR_CC_c_Cfg_NameSeparator ) != NULL )
        SCR_fn_v_RdL0_SplitSectionName(szSectionName, szFileName, NULL, NULL);
    else
        strcpy( szFileName, szSectionName );

    szPoint = strrchr( szFileName, '.' );

    if ( szPoint )
    {
        ++ szPoint;
        strcpy( szPoint, "mdt" );
    }

	SCR_fn_v_RdL0_ComputeSectionName( szModifSectionName, szFileName, C_szModifListActionName, NULL);

	/*
    char *szPoint = NULL;
	char szFileName[SCR_CV_ui_Cfg_MaxLenName];
	char szObjectShortName[SCR_CV_ui_Cfg_MaxLenName];

    if( strchr( p_szObjectName, SCR_CC_c_Cfg_NameSeparator ) != NULL )
        SCR_fn_v_RdL0_SplitSectionName(p_szObjectName, szFileName, NULL, szObjectShortName);
    else
        strcpy( szFileName, p_szObjectName );

    szPoint = strrchr( szFileName, '.' );

    if ( szPoint )
    {
        ++ szPoint;
        strcpy( szPoint, "mdt" );
    }

	SCR_fn_v_RdL0_ComputeSectionName( szModifSectionName, szFileName, C_szModifListActionName, szObjectShortName);
	*/
}

//////////////////////////////////////////////////////////////////////////////////////////////////////
// Method : Geometry3D::CallBackSaveModifListGeometricObject
// Date   : 98.02
//////////////////////////////////////////////////////////////////////////////////////////////////////
// Description : callback to save the list of modifications
// Author      : Cristi Petrescu
//////////////////////////////////////////////////////////////////////////////////////////////////////
// Modification :
// Date         :
// By           :
//////////////////////////////////////////////////////////////////////////////////////////////////////
void Geometry3D_Interface::CallBackSaveModifListGeometricObject(SCR_tdst_File_Description *p_stFile,
                                                                char *p_szSectionName, void *p_vData,
                                                                SCR_tde_Ntfy_Action eAction)
{
    tdstModifFile        *p_stModif             = (tdstModifFile*)p_vData;
    char				  szSectionName[SCR_CV_ui_Cfg_MaxLenName];
    POSITION              stPos;

    switch( eAction )
    {
    case SCR_EA_Ntfy_AddSection:
		// go to end of file (we need all file directive to load this section)
		SCR_fn_v_SvL1_ToEndSection(p_stFile);
        SCR_M_SvL0_SaveBlankLine (p_stFile);

    case SCR_EA_Ntfy_RebuildSection:
		// get section name
		SCR_fn_v_RdL0_ComputeSectionName(szSectionName, NULL, C_szModifListActionName, " ");
		// save begin section
		SCR_M_SvL0_SaveBeginSection(p_stFile, szSectionName, SCR_CC_C_Cfg_EOL);
        // save entries
        stPos = p_stModif -> oListOfModifiedObjects . GetHeadPosition();
        while ( stPos )
        {
			Geometry3D *p_oObject = p_stModif -> oListOfModifiedObjects . GetNext(stPos);
			//CString csCompleteObjectName;

			//SCR_fn_v_RdL0_SplitSectionName(p_szObjectName, NULL, NULL, szObjectShortName);

            //BEGIN ROMTEAM Cristi Petrescu 98-06-
			SCR_M_SvL0_SaveEntry(p_stFile, "Modification", SCR_CC_C_Cfg_NoChar);
            SCR_fn_v_SvL0_SaveParameters_MP(p_stFile, SCR_EF_SvL0_Scanf, 1, "%s,%s:%s",
																			  (char*)(LPCTSTR)p_oObject -> GetCompleteSectionName(),
																			  C_szModifActionName,
																			  p_oObject -> fn_p_szGetName());
			//END ROMTEAM Cristi Petrescu 98-06-
        }		
		// write end section
		SCR_M_SvL0_SaveEndSection(p_stFile, SCR_CC_C_Cfg_EOL);
        if (eAction == SCR_EA_Ntfy_AddSection)
            SCR_M_SvL0_SaveBlankLine (p_stFile);
        //
        p_stModif -> p_oModifSection -> fn_vSectionSaved();
        break;
    case SCR_EA_Ntfy_DeleteSection:
        p_stModif -> p_oModifSection -> fn_vSectionDeleted();
        break;
    }
}

SCR_tde_Anl_ReturnValue Geometry3D_Interface::CallBackLoadModifList(SCR_tdst_File_Description *_p_stFile, char *_pszName,
                                                      char *_ap_szParams[], SCR_tde_Anl_Action _eAction)
{
    Geometry3D *p_oGeom;
    SCR_M_RdL0_GetContextLong(0, 0, Geometry3D*, p_oGeom);

    switch ( _eAction )
    {
    case SCR_EA_Anl_BeginSection:
        
        break;
    case SCR_EA_Anl_Entry:
        
        break;
    case SCR_EA_Anl_EndSection:
        
        break;
    }
    return SCR_ERV_Anl_NormalReturn;
}

/*
void Geometry3D_Interface::mfn_vDelFileModification(Geometry3D *p_oObject)
{
    tdstModifFile   *p_stFMDModif;
    POSITION        xPos;

    M_ForEachElement( m_oListOfModifiedFiles, p_stModif, xPos )
    {
        if( ( p_stFMDModif -> xElementIT == xElementIT ) && ( p_stFMDModif -> xIndexFaceIT == xFaceIT ) )
        {
            m_oListOfFMDModif . RemoveAt( xPos );
            free( p_stFMDModif );
            break;
        }
    }
}
*/
// END CPA2 Cristi Petrescu 98-02-

#endif // ACTIVE_EDITOR