/*
 =======================================================================================
  Name        : ipo_intf.cpp
 
  Author      : vincent lhullier            Date :22/05/97
 
  Description :IPO DLL Interface - implementation
 =======================================================================================
  Modification -> Author :  Shaitan         Date : 26/06/97
  Description :
 =======================================================================================
  Modification -> Author :  Vincent Lhullier Date : 07/07/97
  Description :
 =======================================================================================
  Modification -> Author :  Shaitan         Date : 18/08/97
  Description :
 =======================================================================================
 */

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
#include <direct.h>

#include "stdafx.h"
#include "acp_base.h"
#include "ITF.h"
#include "dpt.h"
#include "IPO_intf.hpp"
#include "edit_cla.hpp"
#include "isi.h"

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

//ROMTEAM WorldEditor (Nicu 28/10/97) 
#include "ogd.h"
#include "po\postruc.h"
#include "x:\cpa\tempgrp\gliGLOU\MULTIDRV\inc\visus_st.h"
#undef __PCSStruc_H__
#define PCS_MAIN
#include "pcs\pcs_str.h"
//ENDROMTEAM WorldEditor (Nicu) 

// infos
static CString g_csOITName = "Instanciated Physical";
static CString g_csOITAuthor = "Vincent Lhullier";
static CString g_csOITVersion = "V 2.0.2   18/03/98";
static CString g_csOITFrenchHelpFile = "";
static CString g_csOITEnglishHelpFile = "";

BOOL g_bTipFirstTime = TRUE;

/*
 =======================================================================================
	GLOBALS 
 =======================================================================================
 */

/*
 * the DLL global definition
 */
tdstDLLIdentity g_stIPOIdentity;

/*
 =======================================================================================
	Functions 
 =======================================================================================
 */

/*
 ----------------------------------------------------------------------------------------
  Description   : Constructor
 ----------------------------------------------------------------------------------------
 */
IPOInterface::IPOInterface (void)
{
	m_p_stDLLIdentity = &g_stIPOIdentity;
	
    // Does your DLL can output in main game view ?
	m_stBaseDLLDefinition.bCanOutputIn3DView = FALSE;

	SetCurrent(FALSE);
    SetEditorInfo(g_csOITName, g_csOITAuthor, g_csOITVersion, g_csOITFrenchHelpFile, g_csOITEnglishHelpFile);

	m_bAllClassCreated = FALSE;
	m_p_oDialogList = NULL;
	m_p_oLeftFrame = NULL;
	m_p_oPOClassDlg = NULL;
	m_p_oIPOEditDlg = NULL;
	m_p_oSelectedIPO = NULL;
	m_p_oSelectedSuperObject = NULL;

//ROMTEAM WorldEditor (Cristian Stegaru 11/97)
	m_pEPOInxTriangle = NULL;
//ENDROMTEAM WorldEditor (Cristian Stegaru)
	m_b3DView = NULL; // Nicu
	m_bMainDeviceWasSwapped = FALSE;
	m_p_oMainDevice = NULL;

// CPA2 ASilvescu 98-04-14
	m_pSelectedSPO = NULL;
// CPA2 ASilvescu 98-04-14
}


/*
 =======================================================================================
	Inits 
 =======================================================================================
 */

/*
 ----------------------------------------------------------------------------------------
  Description   : Register type and static initialisatoin
 ----------------------------------------------------------------------------------------
 */
void IPOInterface::fn_vJustAfterRegistered (void)
{
	CString types[] = { C_szInstanciatedPhysicalObjectTypeName,  C_szPhysicalObjectClassTypeName };

	fn_vRegisterObjectsType(types,2);
	EditorIPO::StaticInit();
}

/*
 ----------------------------------------------------------------------------------------
  Description   : Construct editor interface
 ----------------------------------------------------------------------------------------
 */
void IPOInterface::fn_vConstruct (void)
{
	/*~~~ In case of inactive editor, don't create dialogs ~~~*/
	#ifndef __INACTIVE_INTERFACE__
	/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

	// Frame
	m_p_oLeftFrame = new CSplitFrame;
	m_p_oLeftFrame->CreateBase("LIST", 1, 2, GetMainWorld());
    m_p_oLeftFrame->m_iInitWidth = 180;
    m_p_oLeftFrame->mfn_vEnableCaption(FALSE);
    m_p_oLeftFrame->m_stWinBottom.cLinkSame = FRM_C_MoveRight;
	m_p_oLeftFrame->CreateSplitter(C_cVerticalSplitter, 3);

	// Dialog List
	m_p_oDialogList = new CPA_DialogList;
	m_p_oDialogList->fn_vInitDialog(this, m_p_oLeftFrame);
	m_p_oDialogList->fn_vInitAllLists();
	m_p_oLeftFrame->SetPaneView(0, m_p_oDialogList, "IPO", 240);
	
	// resource
	HINSTANCE hOldInst = AfxGetResourceHandle();
    AfxSetResourceHandle(m_p_stDLLIdentity->hModule);


	// create view
	m_p_oLeftFrame->CreateView( 1, RUNTIME_CLASS( CIPOEditionDialog ), "PO & RLI", 11 );
	m_p_oIPOEditDlg = (CIPOEditionDialog *) m_p_oLeftFrame->m_fn_p_oGetPane( 1 );
	m_p_oIPOEditDlg->fn_vSetEditor( this );
	m_p_oIPOEditDlg->fn_vUpdateIPO( NULL );

	// create view
	m_p_oLeftFrame->CreateView( 2, RUNTIME_CLASS( CPhysicalObjectClassDialog ), "CLASSES & MODELS", 400 );
	m_p_oPOClassDlg = (CPhysicalObjectClassDialog *) m_p_oLeftFrame->m_fn_p_oGetPane( 2 );
	m_p_oPOClassDlg->fn_vSetEditor( this );

    // resource
	AfxSetResourceHandle(hOldInst);

	m_p_oLeftFrame->SetPaneSize( 1, 11 );
	
	/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
	#endif  /*__INACTIVE_INTERFACE__*/
	/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
}

/*
 ----------------------------------------------------------------------------------------
  Description   : Called when root world change
 ----------------------------------------------------------------------------------------
 */
void IPOInterface::fn_vOnChangeRoot (void)
{
	if (m_p_oDialogList)
	{
		m_p_oDialogList->fn_vInitAllLists();
		m_p_oDialogList->fn_vReinitDialog();
	}
}

/*
 ----------------------------------------------------------------------------------------
  Description   : Called when world change
 ----------------------------------------------------------------------------------------
 */
void IPOInterface::fn_vOnChangeWorld (void)
{
	fn_vOnChangeRoot();
}

/*
 ----------------------------------------------------------------------------------------
  Description   : Called when device change
 ----------------------------------------------------------------------------------------
 */
void IPOInterface::fn_vOnChangeDevice (void)
{
	fn_vOnChangeRoot();
}

/*
 =======================================================================================
	EDITOR <-> ENGINE 
 =======================================================================================
 */

/*
 ----------------------------------------------------------------------------------------
  Description   : called before engine loop
 ----------------------------------------------------------------------------------------
 */
void IPOInterface::fn_vBeforeEngine (void)
{
	if (fn_bIsCurrentEditor())
    {
	    g_oFrameGest.mfn_vSetRefresh(FALSE);
		g_oFrameGest.mfn_vDisactivateWindow(m_p_oLeftFrame);
		g_oFrameGest.mfn_vDisactivateWindow(GetInterface()->GetModelFrame() );
        g_oFrameGest.mfn_vSetRefresh(TRUE);
    }
	m_p_oIPOEditDlg->m_fn_vSwapLOD( 0, TRUE, FALSE );
}

/*
 ----------------------------------------------------------------------------------------
  Description   : called before editor mode
 ----------------------------------------------------------------------------------------
 */
void IPOInterface::fn_vBeforeEditor (void)
{
	/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
	CPA_BaseObjectList	*p_oPOList;
	EditorPOClass		*p_oPOClass;
	EditorPO			*p_oPO;
	long				lIndex;
	long				lCount;
	char				szClassName[ _MAX_PATH ];
	/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

	/*
	 * build list of PO class object
	 */
	if (!m_bAllClassCreated)
	{
		fn_vFindAllClasses();
		m_bAllClassCreated = TRUE;
	}

	//CPA2 Stegaru Cristian 98-04
	mfn_vLoadITObjects ();
	//End CPA2 Stegaru Cristian 98-04
	
	// get list of all physical and load classes that have at least one representation in level
	p_oPOList = GetMainWorld()->fn_p_oGetOriginalObjectList(C_szPhysicalObjectTypeName);

	if (p_oPOList != NULL)
	{
		lCount = p_oPOList->GetCount();
		for (lIndex = 0; lIndex < lCount; lIndex ++)
		{
			p_oPO = (EditorPO *) p_oPOList->GetObjectWithIndex(lIndex, E_lo_Object);
			if (p_oPO->fn_cGetOrigin() == C_cFromClasses)
			{
				// find class that contain this PO Model
				strcpy (szClassName, p_oPO->GetReferencedSectionName());
				*strchr(szClassName, '\\') = 0;
				p_oPOClass = (EditorPOClass *) GetMainWorld()->fn_p_oFindObject(szClassName, C_szPhysicalObjectClassTypeName);
				// load class if she doesn't exist

//ROMTEAM WorldEditor (Nicu 28/10/97) 
				if (p_oPOClass)
//ENDROMTEAM WorldEditor (Nicu) 
				if (!p_oPOClass->fn_bIsAvailable())
				{
					fn_bLoadBaseObject(p_oPOClass);
				}
				p_oPO->fn_bSetOwner(p_oPOClass);
			}
			//CPA2 Stegaru Cristian 98-04
			else
			{
				CString csObjectName = p_oPO->GetName ();
				CString csITObjectName;
				POSITION pos = m_lstOfInitialITObjects.GetHeadPosition ();
				while (pos)
				{
					csITObjectName = m_lstOfInitialITObjects.GetNext (pos);
					if (csObjectName == csITObjectName)
					{
						mfn_vLoadBaseITObject (mfn_pGetITClass (), csITObjectName);
						break;
					}
				}
			}
			//End CPA2 Stegaru Cristian 98-04
		}
	}

	m_p_oPOClassDlg->fn_vInitClassList();

	if (m_p_oDialogList)
	{
		m_p_oDialogList->fn_vInitAllLists();
		m_p_oDialogList->fn_vReinitDialog();
	}


	if (fn_bIsCurrentEditor())
    {
        // Frame
	    g_oFrameGest.mfn_vSetRefresh(FALSE);
        //g_oFrameGest.mfn_vActivateWindow (m_p_oPOClassFrame);
		g_oFrameGest.mfn_vActivateWindow (m_p_oLeftFrame );
		g_oFrameGest.mfn_vActivateWindow (GetInterface()->GetModelFrame());
        g_oFrameGest.mfn_vSetRefresh(TRUE);
    }

	
}


/*
 =======================================================================================
	CURRENT EDITOR
 =======================================================================================
 */

/*
 ----------------------------------------------------------------------------------------
  Description   : return TRUE if IPO editor can be activated
 ----------------------------------------------------------------------------------------
 */
BOOL IPOInterface::fn_bCanActivateEditor (CPA_List<CPA_BaseObject> *pParam)
{
	/*~~~ In case of inactive editor, refuse access to editor ~~~*/
	#ifdef __INACTIVE_INTERFACE__
	return FALSE;
	#endif /*__INACTIVE_INTERFACE__*/
	/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
	
	return (!fn_bIsCurrentEditor() );
}

/*
 ----------------------------------------------------------------------------------------
  Description   : return TRUE if IPO editor can be closed
 ----------------------------------------------------------------------------------------
 */
BOOL IPOInterface::fn_bCanCloseEditor (void)
{
	return ( fn_bIsCurrentEditor() );
}

/*
 ----------------------------------------------------------------------------------------
  Description   : Activate editor
 ----------------------------------------------------------------------------------------
 */
void IPOInterface::fn_vOnActivateEditor (CPA_List<CPA_BaseObject> *pParam, BOOL bBackActivated /*=FALSE*/)
{
	g_oFrameGest.mfn_vActivateWindow (m_p_oLeftFrame) ;
	g_oFrameGest.mfn_vActivateWindow (GetInterface()->GetModelFrame());

	m_p_oPOClassDlg->fn_vOnOpen();

	fn_bGetIPOFromListOrSelection( pParam );

	if(m_p_oDialogList)
        m_p_oDialogList->fn_vUpdateSelection(E_lrm_ChangeSelection);

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

/*
 ----------------------------------------------------------------------------------------
  Description   : Close editor
 ----------------------------------------------------------------------------------------
 */
void IPOInterface::fn_vOnCloseEditor (void)
{
	if (m_b3DView)
		fn_vSet3DView(FALSE);
	m_p_oPOClassDlg->fn_vOnClose();
	m_p_oIPOEditDlg->m_fn_vSwapLOD( 0, TRUE, TRUE );
}


/*
 =======================================================================================
	MENUS
 =======================================================================================
 */
//**************************************************************************************
//Begin Mircea Dunka 3 Sept 1998 - DialogBar interface
void IPOInterface::fn_vDefineDlgBarBtnIcon (tde_DlgBarCategory wCategory, tds_DlgBarBtn *_pDlgBarBtn)
{
	if(wCategory == C_DlgBarCategoryEditor)
	{
		_pDlgBarBtn->hIcon = ::LoadIcon((HINSTANCE)(GetDLLIdentity()->hModule), MAKEINTRESOURCE(IDI_IPO_DLGBAR_ICON));

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

/*
 ----------------------------------------------------------------------------------------
  Description   : Add entries to sub menus
 ----------------------------------------------------------------------------------------
 */
BOOL IPOInterface::fn_bDefineSubMenu (EDT_SubMenu *p_oEDTSubMenu)
{
	/*
	 * add entries only in "Editor" submenu
	 */
	if (p_oEDTSubMenu->GetSubMenuType() == C_SubMenuEditor)
    {
        CString oCst;

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

        if (fn_bIsCurrentEditor())
            p_oEDTSubMenu->AddAnEntry(this, (char*)(LPCTSTR)oCst, 2,TRUE);
        else
            p_oEDTSubMenu->AddAnEntry(this, (char*)(LPCTSTR)oCst, 1,FALSE,fn_bCanActivateEditor(NULL));
		return TRUE;
	}

	return FALSE;
}

/*
 ----------------------------------------------------------------------------------------
  Description   : Answer submenu commands
 ----------------------------------------------------------------------------------------
 */
void IPOInterface::_OnSubMenuCommand (EDT_SubMenu *p_oEDTSubMenu,UINT uiMsgID)
{
	if (p_oEDTSubMenu->GetSubMenuType() == C_SubMenuEditor)
        _OnPopUpMenuCommand(uiMsgID);
}

/*
 ----------------------------------------------------------------------------------------
  Description   : add entries in popup menu
 ----------------------------------------------------------------------------------------
 */
BOOL IPOInterface::fn_bDefinePopupMenu (EDT_PopUpMenu *pPopup, CPA_List<CPA_SuperObject> *pSelection, BOOL bIsAlone)
{
    if (bIsAlone)
    {
        pPopup->AddAnEntry(this, "Exit IPO editor", 2);
		return TRUE;
    }

	if (!fn_bIsCurrentEditor())
	{
        if (fn_bGetIPOFromListOrSelection( NULL ))
		{
			pPopup->AddAnEntry(this, "Edit IPO Object", 1);
			return TRUE;
		}
	}
	return FALSE;
}

/*
 ----------------------------------------------------------------------------------------
  Description   : Answer to popup commands
 ----------------------------------------------------------------------------------------
 */
void IPOInterface::_OnPopUpMenuCommand (UINT m_IDCmdMsg)
{
    switch (m_IDCmdMsg)
    {
        case 1:
            GetMainWorld()->fn_bActivateEditor(this,NULL);  // open with selection
            break;
        case 2:
            GetMainWorld()->fn_bCloseEditor(this);
            break;
    }
}

/*
 =======================================================================================
	HIERARCHY INITS
 =======================================================================================
 */

/*
 ----------------------------------------------------------------------------------------
  Description   : Add a PO Type name in model list
 ----------------------------------------------------------------------------------------
 */
void IPOInterface::fn_vInitListsOfModels (void)
{
	GetInterface()->fn_bAddANewModelList(C_szPhysicalObjectTypeName, this);
}

/*
 ----------------------------------------------------------------------------------------
  Description   : Add an IPO Type name in dialod lists
 ----------------------------------------------------------------------------------------
 */
void IPOInterface::fn_vInitListByType (CPA_World *pWorld)
{
	pWorld->fn_vAddANewListByType(C_szInstanciatedPhysicalObjectTypeName, this);
}

/*
 ----------------------------------------------------------------------------------------
  Description   : Identify the engine types of the objects handled by the DLL
 ----------------------------------------------------------------------------------------
 */
BOOL IPOInterface::fn_bCanHandleThisType (long lEngineType)
{
	if (lEngineType & (HIE_C_ulIPO | HIE_C_ulIPO_Mirror))
		return TRUE;
	else
		return FALSE;

}


/*
 =======================================================================================
	Hierarchy Build 
 =======================================================================================
 */

/*
 ----------------------------------------------------------------------------------------
  Description   : Create a new editor IPO with an engine IPO
  hEngineInstance     -> engine IPO object
  Returns (CPA_SuperObject * ) new editor IPO
 ----------------------------------------------------------------------------------------
 */
CPA_SuperObject * IPOInterface::GetNewEditorInstance (HIE_tdxHandleToSuperObject hEngineInstance)
{
	CPA_SuperObject	*pSupObj;
	
	pSupObj = GetInterface()->GetNewSuperObject(hEngineInstance, E_ss_NoSave);
	fn_vBuildNewEditorInstance(pSupObj, hEngineInstance);
	return pSupObj;
}

/*
 ----------------------------------------------------------------------------------------
  Description   : encapsulate an engine IPO in an editor IPO
  pEditorInstance     -> editor IPO
  hEngineInstance     -> engine IPO
 ----------------------------------------------------------------------------------------
 */
void IPOInterface::fn_vBuildNewEditorInstance (CPA_SuperObject *pEditorInstance, HIE_tdxHandleToSuperObject hEngineInstance)
{
	/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
	IPO_tdxHandleToIPO	hEngineObject;
	EditorIPO			*pEdObj;
    char				*p_szSectionName;
	char				szFileName[SCR_CV_ui_Cfg_MaxLenName];
	char				szActionName[SCR_CV_ui_Cfg_MaxLenName];
	char				szName[SCR_CV_ui_Cfg_MaxLenName];
	char				*p_szFileName;
	/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

    hEngineObject = (IPO_tdxHandleToIPO) HIE_fn_hGetSuperObjectObject(hEngineInstance);
	/*
	 *	get parameters
	 */
	p_szSectionName = SCR_M_p_sz_Link_GetKey(SCR_fnp_st_Link_SearchValue(&IPO_g_stLinkTable, (unsigned long) hEngineObject));
	SCR_fn_v_RdL0_SplitSectionName(p_szSectionName, szFileName, szActionName, szName);

	p_szFileName = szFileName + 1 + strlen(fn_szGetLevelsDataPath()); 
	
	/* 
	 * create object
	 */
    pEdObj = new EditorIPO(this, hEngineObject, szName, p_szFileName, szActionName, TRUE, HIE_fn_ulGetSuperObjectType((HIE_tdxHandleToSuperObject)pEditorInstance->GetSuperObjectStruct()));

	pEditorInstance->SetObject(pEdObj);
}

/*
 ----------------------------------------------------------------------------------------
  Description   : update editor instance according to engine instance
  pEditorInstance     -> editor IPO instance
  pEngineInstance     -> engine IPO instance
 ----------------------------------------------------------------------------------------
 */
void IPOInterface::fn_vUpdateEditorInstance (CPA_SuperObject *pEditorInstance, HIE_tdxHandleToSuperObject pEngineInstance)
{
}

/*
 =======================================================================================
	MODELS & INSTANCES 
 =======================================================================================
 */


/*
 ----------------------------------------------------------------------------------------
  Description   : Say were in hierarchy IPO object could be inserted
 ----------------------------------------------------------------------------------------
 */
tdeTypeSO IPOInterface::GetTypeInstance (CString csTypeName, CString csModelName)
{
	if (strcmp((char *) (LPCTSTR) csTypeName, C_szPhysicalObjectTypeName) == 0)
		return C_Static;

	return C_NoType;
}

//ANNECY Shaitan EmptySectors 25/02/98
/*
 ----------------------------------------------------------------------------------------
  Description   : Say were in hierarchy IPO object could be inserted
 ----------------------------------------------------------------------------------------
 */
tdeSaveStatus IPOInterface::GetStatusInstance (CString csTypeName, CString csModelName)
{
	if (strcmp((char *) (LPCTSTR) csTypeName, C_szPhysicalObjectTypeName) == 0)
		return E_ss_Modify;

	return E_ss_NoStatus;
}
//ENDANNECY Shaitan EmptySectors


/*
 ----------------------------------------------------------------------------------------
  Description   : Crate a new IPO with a model (PO)
  csTypeName          -> type of model (Physical object)
  csModelName         -> model name
  pParent             -> parent in hierarchy
  Returns (CPA_SuperObject) new IPO instance
 ----------------------------------------------------------------------------------------
 */
CPA_SuperObject *IPOInterface::GetNewInstance(CString csTypeName, CString csModelName, CPA_SuperObject *pParent)
{
	/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
	PO_tdxHandleToPhysicalObject	hEnginePO;
	IPO_tdxHandleToIPO				hEngineIPO;
	CPA_ObjectDLLBase				*p_oPODll;
	CPA_SuperObject					*p_oSuperObject;
	EditorIPO						*p_oIPO;
	EditorPO						*p_oPO;
	char							szFileName[SCR_CV_ui_Cfg_MaxLenName];
	char							szName[SCR_CV_ui_Cfg_MaxLenName];
	char							*p_szPOName;
	char							*p_szFileName;
	/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/


	if (strcmp((char*) (LPCTSTR) csTypeName, C_szPhysicalObjectTypeName) == 0)
	{
		/*
		 * Get PO model
		 */

//ROMTEAM WorldEditor (Nicu 24/11/97) 
		p_oPO = (EditorPO *) GetMainWorld()->fn_p_oFindObject(csModelName, csTypeName);
		if (p_oPO == NULL) return NULL;

		EditorPO *p_oPO1 = mfn_vCreateCloneGeomPO (p_oPO);
		if (p_oPO1 != NULL)	p_oPO = p_oPO1;
		if (m_p_oPOClassDlg) m_p_oPOClassDlg->fn_vUpdateClassList ();
//ENDROMTEAM WorldEditor (Nicu) 

		/*
		 * load eventually PO
		 */
		if (!p_oPO->fn_bIsAvailable())
		{
			p_oPODll = GetMainWorld()->GetObjectDLLWithName(C_szDLLPhysicalObjectName);
			if (p_oPODll != NULL)
			{
				if (p_oPODll->fn_bLoadBaseObject(p_oPO))
					if (m_p_oPOClassDlg)
						m_p_oPOClassDlg->GetDlgItem(IDC_LIST_POMODEL)->Invalidate();
			}
		}
		
		/*
		 * Get engine PO and create engine IPO
		 */
		hEnginePO = p_oPO->GetStruct();
		hEngineIPO = IPO_fn_hAllocInstanciatedPhysicalObject();
		IPO_fn_vSetPhysicalObject(hEngineIPO, hEnginePO);
		IPO_fn_vSetRadiosity(hEngineIPO, NULL);

		/*
		 * compute name of file, section and IPO object section
		 */
		p_szPOName = p_oPO->fn_p_szGetName();
		if (strnicmp(p_szPOName, "PO_", 3) == 0)
			p_szPOName += 3;
		strcpy(szName, "IPO_");
		strcpy(szName + 4, p_szPOName);
		
		fn_zsGetActualLevelFilename(szFileName, "IPO");

		/*
 		 * create Editor IPO object
		 */
		p_oIPO = new EditorIPO(this, hEngineIPO, szName, szFileName, "IPO", FALSE,HIE_C_ulIPO);

		/*
		 * create super object
		 */
		fn_zsGetActualLevelFilename(szFileName, "SPO");
		p_szFileName = szFileName + strlen( fn_szGetLevelsDataPath()) + 1;
		strcpy(szName, "SO-");
		strcpy(szName + 3, p_szPOName);
		p_oSuperObject = GetInterface()->GetNewSuperObject(E_ss_Modify, C_Static, szName, p_szFileName);
		p_oSuperObject->SetObject(p_oIPO);

		return p_oSuperObject;
	}

	return NULL;
}

/*
 ----------------------------------------------------------------------------------------
  Description   : Duplicate IPO
 ----------------------------------------------------------------------------------------
 */
CPA_BaseObject * IPOInterface::Duplicate (CPA_BaseObject *pObject, CPA_SuperObject *pNewSuperObject)
{
	EditorIPO   *pObj, *pNewObj;

	pObj = (EditorIPO *) pObject;
	pNewObj = new EditorIPO(*pObj);

	return pNewObj;
}

/*
 =======================================================================================
	Editor Modifs 
 =======================================================================================
 */

/*
 ----------------------------------------------------------------------------------------
  Description   : Selection
 ----------------------------------------------------------------------------------------
 */
void IPOInterface::fn_vOnSelect(CPA_SuperObject *pEdObj, tdeTypeModif eType, tdeStatus eStatus)
{
	if( eStatus == C_AsCurrentEditor )
	{
		m_p_oSelectedSuperObject = m_p_oSelectedIPO = NULL;
		/*
		if( eType == C_EDTDo )
		{
			m_p_oSelectedSuperObject = pEdObj;
			m_p_oSelectedIPO = (EditorIPO *) pEdObj->GetObject();
		}
		*/
		//if (fn_bGetIPOFromObject( pEdObj->GetObject() ) )
		if (fn_bGetIPOFromObject( pEdObj ) )
		{
			/*
			 * force current object to be the only one that is selected
			 */
			if (M_GetCountSelected() > 1)
			{
                M_CancelSelection();
                GetInterface()->fn_vAddSelectedObject(pEdObj,FALSE);
            }
		}
		m_p_oIPOEditDlg->fn_vUpdateIPO( m_p_oSelectedIPO );
	}

    if(m_p_oDialogList)
        m_p_oDialogList->fn_vUpdateSelection(E_lrm_ChangeSelection);
}


/*
 ----------------------------------------------------------------------------------------
  Description   : Insertion
 ----------------------------------------------------------------------------------------
 */
void IPOInterface::fn_vOnModifInsert 
		(
			CPA_SuperObject *pEdObj, 
			CPA_SuperObject *pParent,
			tdstPosition *p_stPosition, 
			tdeTypeModif eType, 
			tdeStatus eStatus
		)
{
	CPA_ObjectDLLBase	*p_oLightDLL;
	EditorIPO			*p_oIPO;

	/*
	 * check status
	 */
	if (eStatus != C_AsConcernedDLL) 
		return;

	/*
	 * get corresponding object
	 */
	p_oIPO = (EditorIPO *) pEdObj->GetObject();
	if (!(p_oIPO->GetDataType() & (HIE_C_ulIPO | HIE_C_ulIPO_Mirror))) 
		return;

	/*
	 * update section
	 */
//ROMTEAM Correction (Cristian Stegaru 27/02/98)
	if (C_EDTDo == eType || C_EDTRedo == eType)
//ENDROMTEAM Correction (Cristian Stegaru)
		p_oIPO->fn_vNotifySave();
	else
		p_oIPO->fn_vNotifyUnSave();

	/*
	 * update RLI
	 */
	p_oLightDLL = GetMainWorld()->GetObjectDLLWithName(C_szDLLLightName);
	if (p_oLightDLL != NULL)
	{
		p_oLightDLL->OnQueryAction(this, C_uiQueryComputeRli, (long)p_oIPO);
//ANNECY Shaitan Correction 03/03/98 {
		CString oRLIName = fn_szGetLevelsDataPath();
		oRLIName += "\\" + p_oIPO->GetRLISectionName();
		SCR_fnp_st_Link_SetValue(ISI_fn_pGetLinkTable(), (char*)(LPCSTR)oRLIName, (unsigned long)IPO_fn_hGetRadiosity(p_oIPO->GetStruct()));
//ENDANNECY Shaitan Correction }
	}

    if(m_p_oDialogList)
        m_p_oDialogList->fn_vUpdateSelection(E_lrm_ReinitList);
}


/*
 ----------------------------------------------------------------------------------------
  Description   : Supression
 ----------------------------------------------------------------------------------------
 */
void IPOInterface::fn_vOnModifDelete (CPA_List<EDT_SaveParents> *pListObjects, tdeTypeModif eType, tdeStatus eStatus)
{
	/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
	CPA_ObjectDLLBase	*p_oLightDLL;
	EDT_SaveParents		*pElem;
	EditorIPO			*p_oIPO;
	POSITION			pos;
	/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

	/*
	 * check status
	 */
	if (eStatus != C_AsConcernedDLL) 
		return;

	/*
	 * for all elements in the list
	 */
	for (pElem = pListObjects->GetHeadElement(pos); pElem; pElem = pListObjects->GetNextElement(pos))
	{
		/*
		 * get corresponding object
		 */
		p_oIPO = (EditorIPO *) pElem->m_pChild->GetObject();
		if (p_oIPO->GetDataType() & (HIE_C_ulIPO | HIE_C_ulIPO_Mirror)) 
		{
			/*
			 *	update section
			 */
//ROMTEAM Correction (Cristian Stegaru 27/02/98)
			if (C_EDTDo == eType || C_EDTRedo == eType)
//ENDROMTEAM Correction (Cristian Stegaru)
				p_oIPO->fn_vNotifyUnSave();
			else
				p_oIPO->fn_vNotifyRestore();
		}
	}

	/*
	 * update RLI
	 */
	p_oLightDLL = GetMainWorld()->GetObjectDLLWithName(C_szDLLLightName);
	if (p_oLightDLL)
		p_oLightDLL->OnQueryAction(this, C_uiQueryComputeRli, NULL);
    if(m_p_oDialogList)
        m_p_oDialogList->fn_vUpdateSelection(E_lrm_ReinitList);

}

/*
 ----------------------------------------------------------------------------------------
  Description   : Copy
 ----------------------------------------------------------------------------------------
 */
void IPOInterface::fn_vOnModifCopy	(CPA_List<EDT_SaveParents> *pListObjects, tdeTypeModif eType, tdeStatus eStatus)
{
	/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
	CPA_ObjectDLLBase	*p_oLightDLL;
	EDT_SaveParents		*pElem;
	EditorIPO			*p_oIPO;
	POSITION			pos;
	/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

	/*
	 * check status
	 */
	if (eStatus != C_AsConcernedDLL) 
		return;

	/*
	 * for all elements in the list
	 */
	for (pElem = pListObjects->GetHeadElement(pos); pElem; pElem = pListObjects->GetNextElement(pos))
	{
		/*
		 * get corresponding object
		 */
		p_oIPO = (EditorIPO *) pElem->m_pChild->GetObject();
		if (p_oIPO->GetDataType() & (HIE_C_ulIPO | HIE_C_ulIPO_Mirror)) 
		{
			/* 
			 * update section
			 */
//ROMTEAM Correction (Cristian Stegaru 27/02/98)
			if (C_EDTDo == eType || C_EDTRedo == eType)
//ENDROMTEAM Correction (Cristian Stegaru)
				p_oIPO->fn_vNotifySave();
			else
				p_oIPO->fn_vNotifyUnSave();
		}
	}

	/*
	 * update RLI
	 */
	p_oLightDLL = GetMainWorld()->GetObjectDLLWithName(C_szDLLLightName);
	if (p_oLightDLL)
		p_oLightDLL->OnQueryAction(this, C_uiQueryComputeRli, NULL);
//ANNECY Shaitan Correction 30/03/98 {
	CString oRLIName = fn_szGetLevelsDataPath();
	oRLIName += "\\" + p_oIPO->GetRLISectionName();
	SCR_fnp_st_Link_SetValue(ISI_fn_pGetLinkTable(), (char*)(LPCSTR)oRLIName, (unsigned long)IPO_fn_hGetRadiosity(p_oIPO->GetStruct()));
//ENDANNECY Shaitan Correction }

	if(m_p_oDialogList)
        m_p_oDialogList->fn_vUpdateSelection(E_lrm_ReinitList);

}

/*
 ----------------------------------------------------------------------------------------
  Description   : Move
 ----------------------------------------------------------------------------------------
 */
void IPOInterface::fn_vOnModifMove (CPA_List<EDT_SavePos> *pListObjects, CPA_List<EDT_SaveGlobalPos> *pListConcerned, tdeTypeModif eType, tdeStatus eStatus)
{
	CPA_ObjectDLLBase	*p_oLightDLL;

	/*
	 * update RLI
	 */
	p_oLightDLL = GetMainWorld()->GetObjectDLLWithName(C_szDLLLightName);
	if (p_oLightDLL)
		p_oLightDLL->OnQueryAction(this, C_uiQueryComputeRli, NULL);
}

/*
 =======================================================================================
	For dialog list 
 =======================================================================================
 */

/*
 ----------------------------------------------------------------------------------------
  Description   : return selected Super object
 ----------------------------------------------------------------------------------------
 */
CPA_BaseObject* IPOInterface::GetDialogSelection (CPA_DialogList *pDialog, CString csTypeName, tdeListDrawMode eDrawMode)
{
    return m_p_oSelectedSuperObject;
}


/*
 ----------------------------------------------------------------------------------------
  Description   : init list to display in dialog list box
 ----------------------------------------------------------------------------------------
 */
void IPOInterface::GetListsForDialog (CPA_DialogList *pDialog)
{
	if (pDialog == m_p_oDialogList )
		pDialog->fn_vAddANewList(C_szInstanciatedPhysicalObjectTypeName,GetInterface()->GetSortedListByType(C_szInstanciatedPhysicalObjectTypeName));
}


/*
 ----------------------------------------------------------------------------------------
  Description   : init default parameters for dialog list
 ----------------------------------------------------------------------------------------
 */
void IPOInterface::fn_vInitDefaultParameters( CPA_DialogList *pDialog )
{
	if (pDialog == m_p_oDialogList )
	{
		pDialog->SetPermanentHeaders(FALSE);
		pDialog->SetDefaultTypeName(C_szInstanciatedPhysicalObjectTypeName);
		pDialog->SetDefaultTestName("No Test");
		pDialog->SetDefaultButtonState(FALSE);
	}
}

/*
 ----------------------------------------------------------------------------------------
  Description   : called when selection change in Dialog list
 ----------------------------------------------------------------------------------------
 */
BOOL IPOInterface::fn_bOnSelChangeListObjects(CPA_DialogList *pDialog, CString csTypeName, CPA_BaseObject *pSelectedObject, BOOL _bUnselect)
{
    if( fn_bIsCurrentEditor() )
    {
        if( _bUnselect )
        {
            M_CancelSelection();
            GetInterface()->fn_vUpdateAll(E_mc_UpdateDialog);
			m_p_oSelectedIPO = NULL;
        }
        else
        {
            M_CancelSelection();
            GetInterface()->fn_vAddSelectedObject((CPA_SuperObject*)pSelectedObject,FALSE);
            GetInterface()->fn_vUpdateAll(E_mc_UpdateDialog);
			fn_bGetIPOFromObject( ((CPA_SuperObject *)pSelectedObject)->GetObject() );			
        }
		m_p_oIPOEditDlg->fn_vUpdateIPO( m_p_oSelectedIPO );
    }
    return FALSE;
}

/*
 =======================================================================================
	BOUNDING VOLUMES
 =======================================================================================
 */

/*
 ----------------------------------------------------------------------------------------
  Description   : compute bounding volume of given IPO
 ----------------------------------------------------------------------------------------
 */
void IPOInterface::fn_vComputeBoundingVolume (CPA_BaseObject *pObject)
{
	EditorIPO	*pObj       = (EditorIPO *) pObject;
    EditorPO    *poPOObj    = pObj->GetPhysicalObject(); 

    if (poPOObj != NULL)
    {
        ((CPA_ObjectDLLBase*) poPOObj->GetEditor())->fn_vComputeBoundingVolume(poPOObj);
    }
}

/*
 ----------------------------------------------------------------------------------------
  Description   : return bounding volume of given IPO
 ----------------------------------------------------------------------------------------
 */
ACP_tdxHandleOfObject IPOInterface::fn_hGetBoundingVolume (CPA_BaseObject *pObject)
{
	EditorIPO   *pObj       = (EditorIPO *) pObject;
    EditorPO    *poPOObj    = pObj->GetPhysicalObject(); 

    if (poPOObj != NULL)
    {
        return ((CPA_ObjectDLLBase*) poPOObj->GetEditor())->fn_hGetBoundingVolume(poPOObj);
    }
	return NULL;
}


/*
 =======================================================================================
	Communication 
 =======================================================================================
 */

/*
 ----------------------------------------------------------------------------------------
  Description   : communication (query action from other DLL)
  p_oSender           -> DLL that query the action
  wQuery              -> action
  lParam              -> additional parameters
 ----------------------------------------------------------------------------------------
 */
long IPOInterface::OnQueryAction (CPA_EditorBase *p_oSender, WPARAM wQuery, LPARAM lParam)
{
	EditorPOClass *p_oClass;
	
	switch (wQuery)
	{
		case C_IPO_dwLoadPhysicalObjectClass:
			// load new class
			p_oClass = (EditorPOClass *) lParam;
			return fn_bLoadBaseObject(p_oClass);

//ROMTEAM WorldEditor (Cristian Stegaru 11/97)
		case C_IPO_uiCreateITModel:
			{
				QueryActionParam paramInput = *(QueryActionParam*)lParam;
				ITObject3D *pITObject = (ITObject3D *)paramInput.m_p3DObject;
				if (!pITObject || !m_pEPOInxTriangle)
					return FALSE;
				
				CPA_ObjectDLLBase *p_oPODll = GetMainWorld()->GetObjectDLLWithName (C_szDLLPhysicalObjectName);

				//CPA2 Stegaru Cristian 98-04

				CString csLevelsPath (fn_szGetLevelsDataPath ());
				CString csLevelName (fn_p_szGetLevelName ());
				CString csPhyName;
				HINSTANCE hOldInst = AfxGetResourceHandle();
				AfxSetResourceHandle (GetDLLIdentity()->hModule);

				csPhyName = "\\" + csLevelName + "\\" + csLevelName + ".phy^PHY:";

				//"GameData\\World\\Levels\\level\\level.phy^PHY:"
				CString csFileName = csLevelsPath + csPhyName + paramInput.m_csName;
				QueryActionParam paramOutput;
				paramOutput.SetContent (pITObject, csFileName, -1);
				EditorPO *pEditorPO = (EditorPO*)p_oPODll->OnQueryAction( (CPA_EditorBase *) m_pEPOInxTriangle, OPD_ActionCreateGeometricPO, (LPARAM) &paramOutput);
				ASSERT (pEditorPO);
				pEditorPO->mfn_vSetClone (TRUE);
				pEditorPO->SetExistingSection (FALSE);
				pEditorPO->fn_vNotifySave ();
				ASSERT (pITObject);
				CString csReferencedSectionName, csElementSectionName, csElementName, csElementSufix;
				//"level\\level.mod^Geometric: "
				csReferencedSectionName = csLevelName + "\\" + csLevelName + ".mod^Geometric:";
				pITObject->SetReferencedSectionName ((LPCTSTR)csReferencedSectionName);
				pITObject->fn_vUpdateSectionName ();
				pITObject->SetDataPath ((char*)(LPCTSTR)csLevelsPath);
				//"level\\level.mod^ElementIndexedTriangles:"
				csElementSectionName = csLevelName + "\\" + csLevelName + ".mod^ElementIndexedTriangles:";
				csElementSufix.LoadString (IDS_ELEMENT_SUFIX_NAME);
				csElementName = pITObject->GetName () + csElementSufix;
				csElementSectionName += csElementName;

				AfxSetResourceHandle(hOldInst);
				//construct the element indexed triangle section
				pITObject->mfn_vInitElement ((char*)(LPCTSTR)csElementSectionName, (char*)(LPCTSTR)csLevelsPath);
				pITObject->fn_vNotifySave ();

				//End CPA2 Stegaru Cristian 98-04

				if (m_p_oPOClassDlg)
					m_p_oPOClassDlg->fn_vUpdateClassList ();
				return TRUE;
			}
//ENDROMTEAM WorldEditor (Cristian Stegaru

	}
	return FALSE;
}

/*
 ----------------------------------------------------------------------------------------
  Description   : Load content of a class
 ----------------------------------------------------------------------------------------
 */
BOOL IPOInterface::fn_bLoadBaseObject (CPA_BaseObject *p_oObject)
{
	if ( strcmp(p_oObject->fn_p_szGetType(), C_szPhysicalObjectClassTypeName) == 0 )
	{
		return ((EditorPOClass *) p_oObject)->fn_bLoadEditorPO();
	}
	return FALSE;
}


/*
 =======================================================================================
	SPECIFIC FUNCTIONS 
 =======================================================================================
 */

/*
 ----------------------------------------------------------------------------------------
  Description   : Find All po classes on disk
 ----------------------------------------------------------------------------------------
 */
void IPOInterface::fn_vFindAllClasses (void)
{
	WIN32_FIND_DATA stFindData;
	HANDLE			hFind;
	char			szFilter[ _MAX_PATH ];
	EditorPOClass	*p_oNewClass;
	BOOL			bIsLoadingWorld;

	sprintf(szFilter, "%s\\*.*", fn_szGetGraphicsClassesDataPath());

	if ((hFind = FindFirstFile(szFilter, &stFindData)) == INVALID_HANDLE_VALUE)
		return;

	/*
	 * Avoid prefixage of name
	 */
	bIsLoadingWorld = GetInterface()->fn_bIsLoadingWorld();
	GetInterface()->SetLoadingWorld(TRUE);

//ROMTEAM WorldEditor (Cristian Stegaru 11/97)
	CString csITName;
	HINSTANCE hOldInst = AfxGetResourceHandle();
	AfxSetResourceHandle (GetDLLIdentity()->hModule);

	csITName.LoadString (IDS_ITNAME);
	AfxSetResourceHandle(hOldInst);
//ENDROMTEAM WorldEditor (Cristian Stegaru)
	
	/*
	 * for each directory class create a EditorPOClass
	 */
	do
	{
		if (stFindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
		{
			if (*stFindData.cFileName != '.')
			{
				p_oNewClass = new EditorPOClass(stFindData.cFileName, this);
//ROMTEAM WorldEditor (Nicu 06/01/98)
				//CPA2 Stegaru Cristian 98-04
				if (csITName == stFindData.cFileName)
					ASSERT (FALSE);
				//End CPA2 Stegaru Cristian 98-04
//				if (csITName == stFindData.cFileName) m_pEPOInxTriangle = p_oNewClass;
//ENDROMTEAM WorldEditor (Nicu)
			}
		}
	} 
	while(FindNextFile(hFind, &stFindData));

//ROMTEAM WorldEditor (Nicu 28/10/97)
	p_oNewClass = new EditorPOClass("Geometric", this);
	CPA_ObjectDLLBase *p_oPODll = GetMainWorld()->GetObjectDLLWithName( C_szDLLPhysicalObjectName );

	QueryActionParam *param;
	CPA_ObjectDLLBase *p_oGeomDll = GetMainWorld()->GetObjectDLLWithName (C_szDLLGeometryName);

// Create geometric objects
	int i = 0;
	do			// for all Geom Objects in Geometric DLL
	{
		param = (QueryActionParam *)p_oGeomDll->OnQueryAction(p_oGeomDll, C_uiCreateObject, i | C_origGeomObjectFlag);
		if(param)
		{
			//CPA2 Stegaru Cristian 98-04
			CString csLevelName = fn_p_szGetLevelName ();
			CString csLevelsPath (fn_szGetLevelsDataPath ());
			param->m_csName = csLevelsPath  + "\\" + csLevelName + "\\" + csLevelName + ".phy^PHY:PO_" + param->m_csName;
			p_oPODll->OnQueryAction( (CPA_EditorBase *) p_oNewClass, OPD_ActionCreateGeometricPO, (LPARAM)param);
			p_oNewClass->SetAvailable(TRUE);
			delete param;
//			CString csClassPath (fn_szGetGraphicsClassesDataPath ());
//			param->m_csName = csClassPath  + "\\" + csITName + "\\" + csITName + ".phy^PHY:PO_" + param->m_csName;
//			p_oPODll->OnQueryAction( (CPA_EditorBase *) p_oNewClass, OPD_ActionCreateGeometricPO, (LPARAM)param);
//			p_oNewClass->SetAvailable(TRUE);
//			delete param;
			//End CPA2 Stegaru Cristian 98-04
		}
		i++;			// next object
	} while(param);

// Create the <Indexed Triangle> PO Class if the directory IT doesn't exist

	//CPA2 Stegaru Cristian 98-04
		mfn_vCreateITDirectory ();
		p_oNewClass = m_pEPOInxTriangle = new EditorPOClass("it", this);
		m_pEPOInxTriangle->SetAvailable(TRUE);
	//End CPA2 Stegaru Cristian 98-04

//ENDROMTEAM WorldEditor (Nicu)

	GetInterface()->SetLoadingWorld(bIsLoadingWorld);

	FindClose(hFind);
}

/*
 ----------------------------------------------------------------------------------------
  Description   : try to find an IPO from list or selected object
  pParam              -> list of object (or NULL to take selected object )
  Returns (BOOL ) TRUE if selected object is alone and is an IPO
 ----------------------------------------------------------------------------------------
 */
BOOL IPOInterface::fn_bGetIPOFromListOrSelection( CPA_List<CPA_BaseObject> *_p_oListObjects )
{
	CPA_BaseObject *p_oObject;

	/* init */
	p_oObject = NULL;

	if ( _p_oListObjects != NULL )
	{
		/* 
		 * can be activate with only one object 
		 */
		if ( _p_oListObjects->GetCount() == 1 )
			p_oObject = _p_oListObjects->GetHead();
	}
	else
	{
		/* 
		 * take selection has list of objects 
		 */
		if (M_GetCountSelected() == 1)
		{
			p_oObject = M_GetSingleSelection()->GetObject();
		}
	}

	return fn_bGetIPOFromObject( p_oObject );
}

/*
 ----------------------------------------------------------------------------------------
  Description   : try to find an IPO from a given object
  _p_oObject-> given object
  Returns (BOOL ) TRUE if object is an IPO
 ----------------------------------------------------------------------------------------
 */
BOOL IPOInterface::fn_bGetIPOFromObject( CPA_BaseObject *_p_oObject )
{
	CPA_BaseObject *p_oObj;
	if (_p_oObject == NULL)
		return FALSE;

	/*
	 * check if object is an IPO
	 */ 
	if (_p_oObject->fn_bIsOfType( C_szSuperObjectTypeName ))
	{
		p_oObj = ((CPA_SuperObject *) _p_oObject )->GetObject();
		if (p_oObj && p_oObj->fn_bIsOfType( C_szInstanciatedPhysicalObjectTypeName ) )
		{
			m_p_oSelectedSuperObject = _p_oObject;
			m_p_oSelectedIPO = (EditorIPO *) p_oObj;
			return TRUE;
		}
	}
	if (_p_oObject->fn_bIsOfType( C_szInstanciatedPhysicalObjectTypeName ) )
	{
		m_p_oSelectedSuperObject = NULL;
		m_p_oSelectedIPO = (EditorIPO *) _p_oObject;
		return TRUE;
	}

	char *szType = _p_oObject->fn_p_szGetType();
	return FALSE;
}


//ROMTEAM WorldEditor (Nicu 10/11/97) 
BOOL IPOInterface::_OnLButtonDblClk (UINT nFlags, tdstMousePos *p_stPos, ACP_tdxIndex xIndex, HIE_tdstPickInfo *p_stPickInfo)
{
	if (m_b3DView)
		return TRUE;

	CPA_SuperObject* psoSuperObject=NULL;
	int j=0;
	for (ACP_tdxIndex i=0; i<xIndex; i++)
	{
		CPA_SuperObject* pChild = GetInterface()->GetEditorObject(p_stPickInfo[i].hSprObject);
		while (pChild )
		{
			if ((pChild && pChild->GetObjectType() & (HIE_C_ulIPO | HIE_C_ulIPO_Mirror)) && j!=1 )
			{
					psoSuperObject = pChild;
					j=1;

			}
			pChild = (CPA_SuperObject*)pChild->GetParent();
		}
	}

	if (psoSuperObject)
	{
		EditorPO *pPO = ((EditorIPO *)(psoSuperObject->GetObject()))->GetPhysicalObject();
		ASSERT (pPO);
		Shape3D * 	poObject=(Shape3D *) pPO->m_pGeom;
		if(poObject) 
		{	
      CPA_Modif *o = poObject->GetUndoData();
			if(poObject->_OnLButtonDblClk ( nFlags,  p_stPos,   xIndex,  p_stPickInfo))
			{
				if(o) M_GetEditManager()->AskFor(o);
				poObject->fn_vNotifySaveObject ();
			}
			else delete o;
			poObject->mfn_vRefreshElement ();
			return FALSE;
		}
	}	 
	return FALSE;
}


static Shape3D* sh = NULL;
CPA_Modif *undo = NULL;
BOOL IPOInterface::_OnMouseMove     (UINT nFlags, tdstMousePos * p_stPos, MTH3D_tdstVector * p_stObject)
{
	if (m_b3DView)
		return TRUE;

	if(sh) 
	{	
		if(!undo) undo = sh->GetUndoData();
		BOOL retval = sh->_OnMouseMove (nFlags, p_stPos, p_stObject);
		if(retval) 
		{
			sh->fn_vNotifySaveObject ();
			return TRUE;
		}
		delete undo;
		undo = NULL;
	}
	return FALSE;
}



BOOL IPOInterface::_OnRButtonDown   (UINT nFlags, tdstMousePos * p_stPos, ACP_tdxIndex xIndex, HIE_tdstPickInfo * p_stPickInfo)
{
	if (m_b3DView)
		return TRUE;

	return FALSE;
}

BOOL IPOInterface::_OnLButtonDown   (UINT nFlags, tdstMousePos * p_stPos, ACP_tdxIndex xIndex, HIE_tdstPickInfo * p_stPickInfo)
{
	if (m_b3DView)
		return TRUE;

	CPA_SuperObject* psoSuperObject=NULL;
	int j=0;
	if(GetAsyncKeyState(VK_CONTROL) & 0x8000 == 0) return FALSE;

	for (ACP_tdxIndex i=0; i<xIndex; i++)
	{
		CPA_SuperObject* pChild = GetInterface()->GetEditorObject(p_stPickInfo[i].hSprObject);
		while (pChild )
		{
			if ((pChild && pChild->GetObjectType() & (HIE_C_ulIPO | HIE_C_ulIPO_Mirror)) && j!=1 )
			{
					psoSuperObject = pChild;
					j=1;
			}
			pChild = (CPA_SuperObject*)pChild->GetParent();
		}
	}

	sh = NULL;
	undo = NULL;
	if (psoSuperObject)
	{
		Shape3D * 	m_poObject=sh=(Shape3D *) ((EditorIPO *)(psoSuperObject->GetObject()))->GetPhysicalObject()->m_pGeom;
		if(m_poObject) 
	  { 
			m_poObject->SetSuperObject(psoSuperObject);
			return m_poObject->_OnLButtonDown( nFlags,  p_stPos,   xIndex,  p_stPickInfo);
		}
	}	 
	return FALSE;
}


BOOL IPOInterface::_OnLButtonUp     (UINT nFlags, tdstMousePos * p_stPos)          // Called when the left button is released
{
	if (m_b3DView)
		return TRUE;

	if(sh)
	{	BOOL b = sh->_OnLButtonUp (nFlags, p_stPos);
		sh = NULL;
		if(undo) M_GetEditManager()->AskFor(undo);
		undo = NULL;
		return b;
	}
	return FALSE;
}


BOOL IPOInterface::_OnKeyDown (UINT _nChar , UINT , UINT)
{
	return Shape3D::_OnKeyDown (_nChar);
}


BOOL IPOInterface::_OnKeyUp (UINT _nChar , UINT , UINT)
{
	return Shape3D::_OnKeyUp (_nChar);
}
//ENDROMTEAM WorldEditor (Nicu) 


//ROMTEAM WorldEditor (Cristian Stegaru 24/11/97) 

//////////////////////////////////////////////////////////////////////////////////////////////////////
// Method : mfn_vCreateCloneGeomPO 
// Date   : 97-11
//////////////////////////////////////////////////////////////////////////////////////////////////////
// Description :
// Author      : Cristian Stegaru - CPA2 
//////////////////////////////////////////////////////////////////////////////////////////////////////
// Modification :	Nicolae Suparatu
// Date         :	97-24-11
// By           :
//////////////////////////////////////////////////////////////////////////////////////////////////////
EditorPO* IPOInterface::mfn_vCreateCloneGeomPO (EditorPO *po)
{
	ASSERT (po);
	if (NULL == m_pEPOInxTriangle || po->mfn_bIsClone ())	
		return NULL;

	if (po->m_iIdx >= 0)
	{
		CPA_ObjectDLLBase *p_oPODll = GetMainWorld()->GetObjectDLLWithName( C_szDLLPhysicalObjectName );
		CPA_ObjectDLLBase *p_oOGDDll = GetMainWorld()->GetObjectDLLWithName (C_szDLLGeometryName);
		// BEGIN CPA2 Cristi Petrescu 98-03-
		QueryActionParam *param = (QueryActionParam *)p_oOGDDll->OnQueryAction(p_oOGDDll, C_uiCreateCloneObject, po->m_iIdx);
		// END CPA2 Cristi Petrescu 98-03-
		ASSERT (param);

		//CPA2 Stegaru Cristian 98-04
		//		//save the geometry object in order to add the information needed for save
		Geometry3D *p3D = param->m_p3DObject;
//		CString csITName;
		HINSTANCE hOldInst = AfxGetResourceHandle();
		AfxSetResourceHandle (GetDLLIdentity()->hModule);

//		csITName.LoadString (IDS_ITNAME);
		CString *pcsLevelsPath = new CString(fn_szGetLevelsDataPath ());
		CString csLevelName (fn_p_szGetLevelName ());
		param->m_csName = *pcsLevelsPath  + "\\" + csLevelName + "\\" + csLevelName + ".phy^PHY:PO_" + param->m_csName;
		EditorPO *pEditorPO = (EditorPO*)p_oPODll->OnQueryAction( (CPA_EditorBase *) m_pEPOInxTriangle, OPD_ActionCreateGeometricPO, (LPARAM)param);
//ROMTEAM WorldEditor (Cristian Stegaru 12/97)
		ASSERT (pEditorPO);
		pEditorPO->mfn_vSetClone (TRUE);
		pEditorPO->SetExistingSection (FALSE);
		pEditorPO->fn_vNotifySave ();
//ENDROMTEAM WorldEditor (Cristian Stegaru)
		delete param;
		ASSERT (p3D);
		CString csReferencedSectionName, csElementSectionName, csElementName, csElementSufix;
		//"level\\level.mod^Geometric: "
		csReferencedSectionName = csLevelName + "\\" + csLevelName + ".mod^Geometric:";
		p3D->SetReferencedSectionName ((LPCTSTR)csReferencedSectionName);
		p3D->fn_vUpdateSectionName ();
		p3D->SetDataPath ((char *)(LPCSTR)*pcsLevelsPath);
		// BEGIN CPA2 Cristi Petrescu 98-03-
		p3D -> mfn_vCreateModifSection ();
		// END CPA2 Cristi Petrescu 98-03-
		//"level\\level.mod^ElementIndexedTriangles:"
		// BEGIN CPA2 Cristi Petrescu 98-03-
		if (po->m_iIdx == 3)
		{
			// ALTIMAP !!!
			//CPA2 Stegaru Cristian 98-04
			//			csElementSectionName.LoadString (IDS_ELEMENT_ALTIMAP_SECTION_NAME);
			csElementSectionName = csLevelName + "\\" + csLevelName + ".mod^ElementAltimap:";
			//End CPA2 Stegaru Cristian 98-04
			csElementSufix.LoadString (IDS_ELEMENT_ALTIMAP_SUFIX_NAME);
		}
		else
		{
			csElementSectionName = csLevelName + "\\" + csLevelName + ".mod^ElementIndexedTriangles:";
			csElementSufix.LoadString (IDS_ELEMENT_SUFIX_NAME);
		}
		// END CPA2 Cristi Petrescu 98-03-
		csElementName = p3D->GetName () + csElementSufix;
        csElementSectionName += csElementName;

		AfxSetResourceHandle(hOldInst);
		//construct the element indexed triangle section
		p3D->mfn_vInitElement ((char*)(LPCTSTR)csElementSectionName, (char *)(LPCSTR)*pcsLevelsPath);
		p3D->fn_vNotifySave ();
		return pEditorPO;

		//End CPA2 Stegaru Cristian 98-04
	}
	return NULL;
}

//////////////////////////////////////////////////////////////////////////////////////////////////////
// Method : mfn_vCreateITDirectory 
// Date   : 97-12
//////////////////////////////////////////////////////////////////////////////////////////////////////
// Description :
// Author      : Cristian Stegaru - CPA2
//////////////////////////////////////////////////////////////////////////////////////////////////////
// Modification :
// Date         :
// By           :
//////////////////////////////////////////////////////////////////////////////////////////////////////
void IPOInterface::mfn_vCreateITDirectory (void)
{

	//CPA2 Stegaru Cristian 98-04
	CFile file;
	UINT uOpenFlags = CFile::modeCreate | CFile::modeWrite;
	CString csInitialText, csFileName, csDirName = fn_szGetLevelsDataPath ();
	CString csLevelName (fn_p_szGetLevelName ());

	csDirName += "\\" + csLevelName;

/*
	csFileName = csDirName + "\\geomobj.log";
	CFileStatus status;
	BOOL bFileExists = TRUE == CFile::GetStatus (csFileName, status);
	if (!bFileExists)
	{
		if (file.Open (csFileName, uOpenFlags))
		{
			csInitialText = ";1               xxx";
			file.Write ((LPCSTR)csInitialText, csInitialText.GetLength ());
			file.Close ();
		}
	}
*/
	csFileName = csDirName + "\\" + csLevelName + ".mdt";
	CFileStatus status;
	BOOL bFileExists = TRUE == CFile::GetStatus (csFileName, status);
	if (!bFileExists)
	{
		if (file.Open (csFileName, uOpenFlags))
			file.Close ();
	}

	//End CPA2 Stegaru Cristian 98-04
}
//ENDROMTEAM WorldEditor (Cristian Stegaru) 

//ANNECY Shaitan Correction (15/04/98) {
void IPOInterface::fn_vSet3DView (BOOL b3DView)
{
	static DEV_MultiDevice* s_p_oMulti;

	// update flag
	m_b3DView = b3DView;

	if(!m_p_oMainDevice) m_p_oMainDevice = m_p_oPOClassDlg->m_p_oMainDevice;
// CPA2 ASilvescu 98-04-09
	POSITION			pos;
	if(m_b3DView)
	{
		m_pSelectedSPO = M_GetWorld()->GetListSelected()->GetHeadElement(pos);	// get first selected object;
		if(m_pSelectedSPO) GetInterface()->fn_vRemoveSelectedObject(m_pSelectedSPO, FALSE);
	}
// End CPA2 ASilvescu 98-04-09

	// swap to full screen
	if (m_p_oMainDevice)
	{
		if (b3DView)
		{
			if (m_p_oMainDevice->IsFullScreen())
			{
				m_p_oMainDevice->SwapFullScreen();
				m_bMainDeviceWasSwapped = TRUE;
			}
		}
	}

	m_p_oPOClassDlg->GetFrameForDevice3D()->ShowWindow( b3DView );

    if (b3DView)
	{
		s_p_oMulti = (DEV_MultiDevice*)g_oFrameGest.ma_p_oWinArray[2][2]->GetActiveView();
		GetInterface()->SetMultiDevice(m_p_oPOClassDlg->GetDevice3D());
	}
	else 
	{
		GetInterface()->SetMultiDevice(s_p_oMulti);
	}

	if (m_p_oMainDevice)
	{
		if (!b3DView)
		{
			if (m_bMainDeviceWasSwapped)
			{
				m_bMainDeviceWasSwapped = FALSE;
				if (!m_p_oMainDevice->IsFullScreen() )
					m_p_oMainDevice->SwapFullScreen();
			}
		}
	}

// CPA2 ASilvescu 98-04-09
	if(m_pSelectedSPO && m_b3DView)
	{
		if(m_pSelectedSPO)
		{
			m_SPOMatrix = HIE_fn_hGetSuperObjectMatrix(m_pSelectedSPO->GetStruct());
			m_SPOGlobelMatrix = m_pSelectedSPO->GetStruct()->hGlobalMatrix;
			HIE_fn_vSetSuperObjectMatrix(m_pSelectedSPO->GetStruct(), HIE_fn_hGetSuperObjectMatrix(m_p_oPOClassDlg->m_p_oRootSO->GetStruct()));
			m_pSelectedSPO->GetStruct()->hGlobalMatrix =  m_p_oPOClassDlg->m_p_oRootSO->GetStruct()->hGlobalMatrix;
			m_p_oPOClassDlg->DisplayModelIcon();
		}
	}

	if(m_pSelectedSPO && !m_b3DView)
	{
		m_p_oPOClassDlg->m_p_oWorld->fn_vSetRoot( m_p_oPOClassDlg->m_p_oRootSO );
		HIE_fn_vSetSuperObjectMatrix(m_pSelectedSPO->GetStruct(), m_SPOMatrix);
		m_pSelectedSPO->GetStruct()->hGlobalMatrix =  m_SPOGlobelMatrix;
		GetInterface()->fn_vAddSelectedObject(m_pSelectedSPO, TRUE);
	}
// End CPA2 ASilvescu 98-04-09

	GetInterface()->fn_vUpdateAll(E_mc_JustDraw);
}
//ENDANNECY Shaitan Correction }

//////////////////////////////////////////////////////////////////////////////////////////////////////
// Method : fn_vAfterSaveAll 
// Date   : 98-04
//////////////////////////////////////////////////////////////////////////////////////////////////////
// Description :
// Author      : Stegaru Cristian - CPA2
//////////////////////////////////////////////////////////////////////////////////////////////////////
// Modification :
// Date         :
// By           :
//////////////////////////////////////////////////////////////////////////////////////////////////////
void IPOInterface::fn_vAfterSaveAll (void)
{
	mfn_vSaveITObjects ();
}

//////////////////////////////////////////////////////////////////////////////////////////////////////
// Method : mfn_vLoadITObjects 
// Date   : 98-04
//////////////////////////////////////////////////////////////////////////////////////////////////////
// Description :
// Author      : Stegaru Cristian - CPA2
//////////////////////////////////////////////////////////////////////////////////////////////////////
// Modification :
// Date         :
// By           :
//////////////////////////////////////////////////////////////////////////////////////////////////////
void IPOInterface::mfn_vLoadITObjects ()
{
	CStdioFile file;
	CString csFileName = mfn_csGetITObjectsFileName ();
	if (!file.Open (csFileName, CFile::modeRead | CFile::typeText))
		return; //first time we enter the level

	CString csITObject;
	while (file.ReadString (csITObject))
	{
		csITObject.TrimLeft ();
		csITObject.TrimRight ();
		if (!csITObject.IsEmpty ())
			m_lstOfInitialITObjects.AddTail (csITObject);;

	}
	file.Close ();
}

//////////////////////////////////////////////////////////////////////////////////////////////////////
// Method : mfn_vSaveITObjects 
// Date   : 98-04
//////////////////////////////////////////////////////////////////////////////////////////////////////
// Description :
// Author      : Stegaru Cristian - CPA2
//////////////////////////////////////////////////////////////////////////////////////////////////////
// Modification :
// Date         :
// By           :
//////////////////////////////////////////////////////////////////////////////////////////////////////
void IPOInterface::mfn_vSaveITObjects ()
{
	CPA_BaseObject				*p_oClass = mfn_pGetITClass ();
	CPA_List<CPA_BaseObject>	oPOList;
	CPA_BaseObject				*p_oPO;
	POSITION					xPos;
	CStdioFile file;
	CString csFileName = mfn_csGetITObjectsFileName ();

	if (!file.Open (csFileName, CFile::modeCreate | CFile::modeWrite | CFile::typeText))
		return; //can't open the file

	long lCount = GetMainWorld ()->fn_lFindObjects (&oPOList, "", C_szPhysicalObjectTypeName, p_oClass);
	for (p_oPO = oPOList.GetHeadElement (xPos); xPos; p_oPO = oPOList.GetNextElement (xPos))
	{
		CString csName = p_oPO->GetName();
		csName += "\n";
		file.WriteString (csName);
	}
	file.Close ();
}

//////////////////////////////////////////////////////////////////////////////////////////////////////
// Method : mfn_csGetITObjectsFileName 
// Date   : 98-04
//////////////////////////////////////////////////////////////////////////////////////////////////////
// Description :
// Author      : Stegaru Cristian - CPA2
//////////////////////////////////////////////////////////////////////////////////////////////////////
// Modification :
// Date         :
// By           :
//////////////////////////////////////////////////////////////////////////////////////////////////////
CString IPOInterface::mfn_csGetITObjectsFileName ()
{
	char szBaseRoot [_MAX_PATH];
	GetModuleFileName (NULL, szBaseRoot, _MAX_PATH);
	CString csBaseRoot (szBaseRoot);
	int iInx = csBaseRoot.ReverseFind ('\\');
	ASSERT (-1 != iInx);
	csBaseRoot = csBaseRoot.Left (iInx + 1);
	CString csFileName = csBaseRoot + fn_szGetLevelsDataPath () + "\\" + fn_p_szGetLevelName () + "\\" + fn_p_szGetLevelName () + szITObjectsExt;
	return csFileName;
}

//////////////////////////////////////////////////////////////////////////////////////////////////////
// Method : mfn_vLoadBaseITObject 
// Date   : 98-04
//////////////////////////////////////////////////////////////////////////////////////////////////////
// Description :
// Author      : Stegaru Cristian - CPA2
//////////////////////////////////////////////////////////////////////////////////////////////////////
// Modification :
// Date         :
// By           :
//////////////////////////////////////////////////////////////////////////////////////////////////////
void IPOInterface::mfn_vLoadBaseITObject (CPA_BaseObject *pObject, CString csITObjectName)
{
	ASSERT (strcmp(pObject->fn_p_szGetType(), C_szPhysicalObjectClassTypeName) == 0);
	((EditorPOClass *) pObject)->mfn_vLoadITEditorPO (csITObjectName);
}

