// class CPA_MAINWORLD

#include "stdafx.h"
#ifdef ACTIVE_EDITOR
#include "acp_base.h"
#include <direct.h>

#include "itf/CPASObj.hpp"
#include "itf/CPAMWorl.hpp"
#include "itf/CPAWorld.hpp"
//#include "itf/EDTBase.hpp"
#include "itf/DevMul3d.hpp"
#include "itf/DevMulti.hpp"
#include "itf/CPAProj.hpp"
#include "itf/CPAInter.hpp"

#include "itf/StdDLLID.h"

/*===========================================================================
*		Description:	constructor
*		Creation date:	
*		Author:			
*---------------------------------------------------------------------------
*		Revision date:       Author:
*=========================================================================*/
CPA_MainWorld::CPA_MainWorld(long lKey,DEV_MultiDevice *p_oDevice, CPA_Interface *p_oInterface)
{
	CPA_ObjectDLLBase	*p_oDLL, *p_oPreviousDLL;
	CPA_ToolDLLBase		*p_oToolDLL;
	CPA_HierarchyEditor *p_oEditor;
	CString				csMessage;
	long				i;

	CPA_DLLBase **ap_oDLL;
	long lNbOfDLL;

	m_p_oGlobalWorld = NULL;

	m_lKey = lKey;

	// editor
	p_oEditor = (CPA_HierarchyEditor *) M_GetListOfAllDLL()->GetANewDLL(HIERARCHY_DLL, C_szDLLHierarchyName, m_lKey);
	p_oInterface->SetHierarchyEditor(p_oEditor);
	// set parent editor
	m_p_oInterface = p_oInterface;
	// tell parent editor we are its main world
	m_p_oInterface->SetMainWorld(this);
	m_p_oCurrentEditor = m_p_oInterface->GetEditor();
	// link given multidevice to the editor
	p_oDevice->SetInterface(m_p_oInterface);
	// tell parent editor to display the given multidevice (so our world)
	m_p_oInterface->SetMultiDevice(p_oDevice);

    // set CurrentFRMBase
    m_p_oCurrentFrameBaseMenu = NULL;

	// lights
	m_lNbLocalLights = 0;
	m_lNbDynamicLights = 0;

	//-----------------------------------------------------------------------------------
	// get all object dlls

	// create instances for all Object DLLS
	ap_oDLL = new CPA_DLLBase* [M_GetListOfAllDLL()->GetDLLCount()];
	lNbOfDLL = M_GetListOfAllDLL()->GetAllNewDLL(ALL_OBJECTS_DLL,ap_oDLL,m_lKey);

	// init list of DLLs
	m_oListOfObjectDLL.RemoveAll();
	// Add all instances to the world
	for (i=0; i<lNbOfDLL; i++)
	{
		// get current instance
		p_oDLL = (CPA_ObjectDLLBase *) ap_oDLL[i];
		ASSERT(p_oDLL != NULL);
		// set DLL parameters
		p_oDLL->SetMainWorld(this);
		// register the DLL
		if (!p_oDLL->GetName().IsEmpty())
		{
			// check unicity of the DLL with the given engine type
			p_oPreviousDLL = GetObjectDLLWithName(p_oDLL->GetName());
			if (p_oPreviousDLL)
			{
				csMessage = "Two Object DLLs have the same name " + p_oDLL->GetName() + ".";
				M_GetMainWnd()->MessageBox(csMessage, "Unable to load the DLLs", MB_ICONSTOP|MB_OK);
				ASSERT(0);
			}
			// if DLL is OK, add it to Editor List
			m_oListOfObjectDLL.AddTail(p_oDLL);
		}
	}

	//-----------------------------------------------------------------------------------
	// get all tool dlls

	// create instances for all tool DLLS
	lNbOfDLL = M_GetListOfAllDLL()->GetAllNewDLL(ALL_TOOLS_DLL,ap_oDLL,m_lKey);

	// init list of DLLs
	m_oListOfToolDLL.RemoveAll();
    //MT
    m_oListOfToolDLLReceivingWindowMsg.RemoveAll();
    m_oListOfToolDLLReceivingEvtEditorMsg.RemoveAll();
    //MT
	// Add all instances to the world
	for (i=0; i<lNbOfDLL; i++)
	{
		// get current instance
		p_oToolDLL = (CPA_ToolDLLBase *) ap_oDLL[i];
		ASSERT(p_oToolDLL != NULL);
		// Set DLL parmeters
		p_oToolDLL->SetMainWorld(this);
		// register the DLL
		m_oListOfToolDLL.AddTail(p_oToolDLL);
	}
	delete [] ap_oDLL;

	// now that we have the object dll list, we can buil the world
	m_p_oGlobalWorld = new CPA_World(this);

	// tell given multidevice to display our world
	((DEV_MultiDevice3D*)(p_oDevice))->SetWorld(m_p_oGlobalWorld);

	// reserve a slot in the MainWorld's World CameraSlots for the prevcam tip
	CPA_CameraSlots *p_oCamSlots;

	p_oCamSlots = m_p_oGlobalWorld->GetCameraSlots();
	p_oCamSlots->ActivatePrevCamTip();

	// and init the given evt editor
	m_p_oInterface->Create();
}

/*===========================================================================
*		Description:	destructor
*		Creation date:	
*		Author:			
*---------------------------------------------------------------------------
*		Revision date:       Author:
*=========================================================================*/
CPA_MainWorld::~CPA_MainWorld()
{
	delete m_p_oGlobalWorld;
	m_p_oGlobalWorld = NULL;

	delete m_p_oInterface;
	m_p_oInterface = NULL;
}


/*===========================================================================
*		Description:	load a new editor world
*		Creation date:	
*		Author:			
*---------------------------------------------------------------------------
*		Revision date:       Author:
*=========================================================================*/
void CPA_MainWorld::LoadANewWorld(char *szPath, char *szFileName)
{
/*	*** SHAITAN => chargements modifiés + changement script => TODO ***
	
	char szOldPath[C_MaxLenPath];
	CPA_SuperObject *p_oSuperObject;
	SCRIPT_tdstError *err;
	
	// Deplacement dans le repertoire de datas
	getcwd(szOldPath,C_MaxLenPath);
	chdir(szPath);
	
	// Init des scripts et lecture du fichier
	SCRIPT_vRegisterPath(szPath);
	SCRIPT_vSetResultSubSection((long)this);
	p_oSuperObject = (CPA_SuperObject*)SCRIPT_ulAnalyseSection(szFileName,"Edit-SuperObject_Root");
    err = SCRIPT_p_stGetLastError();
	if (err)
	{
		ASSERT(0);
	}
	
	// Replacement dans le repertoire precedent
	chdir(szOldPath);
	
	m_p_oGlobalWorld->fn_vSetRoot(p_oSuperObject);
*/	
}

/*===========================================================================
*		Description:	update main frame
*		Creation date:	
*		Author:			
*---------------------------------------------------------------------------
*		Revision date:       Author:
*=========================================================================*/
void CPA_MainWorld::fn_vSetCurrentFRMBaseMenu(FRMBaseMenu *_p_oCurrentFrameBaseMenu)
{
    m_p_oCurrentFrameBaseMenu = _p_oCurrentFrameBaseMenu;
	m_p_oCurrentFrameBaseMenu->fn_vUpdateCurrentEditor(NULL);
}

//=================================================================================
//=================================================================================
//================= OLE TOOLS =====================================================
//=================================================================================
//=================================================================================
//=================================================================================


/*===========================================================================
*		Description:	get BaseObjectList of valid objects with corresponding type
*		Creation date:	
*		Author:			
*---------------------------------------------------------------------------
*		Revision date:       Author:
*=========================================================================*/
CPA_BaseObjectList *CPA_MainWorld::fn_p_oGetOriginalObjectList(CString csType)
{
	POSITION		stPos;
	CPA_DLLBase		*p_oDLL;
	CPA_BaseObjectList *p_oList;

	p_oList = NULL;
	
	// check with superobject list
	if ((p_oList = GetInterface()->GetEditor()->GetBaseObjectList(csType)) != NULL)
		return p_oList;

	// look in Object DLLs
	stPos = m_oListOfObjectDLL.GetHeadPosition();
	while (stPos)
	{
		p_oDLL = m_oListOfObjectDLL.GetNext(stPos);
		if ((p_oList = p_oDLL->GetBaseObjectList(csType)) != NULL)
			return p_oList;
	}
	// look in Tool DLLs
	stPos = m_oListOfToolDLL.GetHeadPosition();
	while (stPos)
	{
		p_oDLL = m_oListOfToolDLL.GetNext(stPos);
		if ((p_oList = p_oDLL->GetBaseObjectList(csType)) != NULL)
			return p_oList;
	}

	return NULL;
}


/*===========================================================================
*		Description:	get BaseObjectList of invalid objects with corresponding type
*		Creation date:	
*		Author:			
*---------------------------------------------------------------------------
*		Revision date:       Author:
*=========================================================================*/
CPA_BaseObjectList *CPA_MainWorld::fn_p_oGetInvalidObjectList(CString csType)
{
	POSITION		stPos;
	CPA_DLLBase		*p_oDLL;
	CPA_BaseObjectList *p_oList;

	p_oList = NULL;
	
	// check with superobject list
	if ((p_oList = GetInterface()->GetEditor()->GetInvalidObjectList(csType)) != NULL)
		return p_oList;

	// look in Object DLLs
	stPos = m_oListOfObjectDLL.GetHeadPosition();
	while (stPos)
	{
		p_oDLL = m_oListOfObjectDLL.GetNext(stPos);
		if ((p_oList = p_oDLL->GetInvalidObjectList(csType)) != NULL)
			return p_oList;
	}
	// look in Tool DLLs
	stPos = m_oListOfToolDLL.GetHeadPosition();
	while (stPos)
	{
		p_oDLL = m_oListOfToolDLL.GetNext(stPos);
		if ((p_oList = p_oDLL->GetInvalidObjectList(csType)) != NULL)
			return p_oList;
	}

	return NULL;
}

/*===========================================================================
*		Description:	fill list with objects corresponding to criteria
*		Creation date:	
*		Author:			
*---------------------------------------------------------------------------
*		Revision date:       Author:
*=========================================================================*/
long CPA_MainWorld::fn_lFindObjects (CPA_List<CPA_BaseObject> *p_oList, CString csObjectName, CString csObjectType, CPA_BaseObject *p_oOwner, tdeResearchCriteria eCriteria)
{
	POSITION		stPos;
	long			lResult;
	CPA_DLLBase		*p_oDLL;

	lResult = 0;

	// look in EvtEditor
	lResult += GetInterface()->GetEditor()->fn_lFindObjects(p_oList, csObjectName, csObjectType, p_oOwner, eCriteria);

	// look in Object DLLs
	stPos = m_oListOfObjectDLL.GetHeadPosition();
	while (stPos)
	{
		p_oDLL = m_oListOfObjectDLL.GetNext(stPos);
		lResult += p_oDLL->fn_lFindObjects(p_oList, csObjectName, csObjectType, p_oOwner, eCriteria);
	}
	// look in Tool DLLs
	stPos = m_oListOfToolDLL.GetHeadPosition();
	while (stPos)
	{
		p_oDLL = m_oListOfToolDLL.GetNext(stPos);
		lResult += p_oDLL->fn_lFindObjects(p_oList, csObjectName, csObjectType, p_oOwner, eCriteria);
	}
	
	return lResult;
}


/*===========================================================================
*		Description:	fill list with objects corresponding to criteria
*		Creation date:	
*		Author:			
*---------------------------------------------------------------------------
*		Revision date:       Author:
*=========================================================================*/
CPA_BaseObject *CPA_MainWorld::fn_p_oFindObjectWithEngine(void *p_vEngineStruct, CString csObjectType, CPA_BaseObject *p_oOwner, tdeResearchCriteria eCriteria)
{
	POSITION				stPos;
	CPA_DLLBase				*p_oDLL;
	CPA_BaseObject		*p_oResultObject;

	p_oResultObject = NULL;

	// look in EvtEditor
	p_oResultObject = GetInterface()->GetEditor()->GetBaseObject(p_vEngineStruct, csObjectType, p_oOwner, eCriteria);
	if (p_oResultObject)
		return p_oResultObject;

	// look in Object DLLs
	stPos = m_oListOfObjectDLL.GetHeadPosition();
	while (stPos)
	{
		p_oDLL = m_oListOfObjectDLL.GetNext(stPos);
		p_oResultObject = p_oDLL->GetBaseObject(p_vEngineStruct, csObjectType, p_oOwner, eCriteria);
		if (p_oResultObject != NULL)
			return p_oResultObject;
	}
	// look in Tool DLLs
	stPos = m_oListOfToolDLL.GetHeadPosition();
	while (stPos)
	{
		p_oDLL = m_oListOfToolDLL.GetNext(stPos);
		p_oResultObject = p_oDLL->GetBaseObject(p_vEngineStruct, csObjectType, p_oOwner, eCriteria);
		if (p_oResultObject != NULL)
			return p_oResultObject;
	}

	return p_oResultObject;
}

/*===========================================================================
*		Description:	find first object corresponding to criteria
*		Creation date:	
*		Author:			
*---------------------------------------------------------------------------
*		Revision date:       Author:
*=========================================================================*/
CPA_BaseObject *CPA_MainWorld::fn_p_oFindObject(CString csObjectName, CString csObjectType, CPA_BaseObject *p_oOwner, tdeResearchCriteria eCriteria)
{
	POSITION				stPos;
	CPA_DLLBase				*p_oDLL;
	CPA_BaseObject		*p_oResultObject;

	p_oResultObject = NULL;

	// look in EvtEditor
	p_oResultObject = GetInterface()->GetEditor()->GetBaseObject(csObjectName, csObjectType, p_oOwner, eCriteria);
	if (p_oResultObject)
		return p_oResultObject;
	
	// look in Object DLLs
	stPos = m_oListOfObjectDLL.GetHeadPosition();
	while (stPos)
	{
		p_oDLL = m_oListOfObjectDLL.GetNext(stPos);
		p_oResultObject = p_oDLL->GetBaseObject(csObjectName, csObjectType, p_oOwner, eCriteria);
		if (p_oResultObject != NULL)
			return p_oResultObject;
	}
	// look in Tool DLLs
	stPos = m_oListOfToolDLL.GetHeadPosition();
	while (stPos)
	{
		p_oDLL = m_oListOfToolDLL.GetNext(stPos);
		p_oResultObject = p_oDLL->GetBaseObject(csObjectName, csObjectType, p_oOwner, eCriteria);
		if (p_oResultObject != NULL)
			return p_oResultObject;
	}

	return p_oResultObject;
}



/*===========================================================================
*		Description:	check if there is an object corresponding to criteria
*		Creation date:	
*		Author:			
*---------------------------------------------------------------------------
*		Revision date:       Author:
*=========================================================================*/
BOOL CPA_MainWorld::fn_bExist(CString csName, CString csTypeName, CPA_BaseObject *p_oOwner, tdeResearchCriteria eCriteria)
{
	POSITION		stPos;
	CPA_DLLBase		*p_oDLL;
	BOOL			bOK;

	bOK = FALSE;

	// if type == superobject, just look in the SO list
	bOK = GetInterface()->GetEditor()->fn_bExist(csName, csTypeName, p_oOwner, eCriteria);

	// look in Object DLLs
	stPos = m_oListOfObjectDLL.GetHeadPosition();
	while (stPos && !bOK)
	{
		p_oDLL = m_oListOfObjectDLL.GetNext(stPos);
		bOK = p_oDLL->fn_bExist(csName, csTypeName, p_oOwner, eCriteria);
	}
	// look in Tool DLLs
	stPos = m_oListOfToolDLL.GetHeadPosition();
	while (stPos && !bOK)
	{
		p_oDLL = m_oListOfToolDLL.GetNext(stPos);
		bOK = p_oDLL->fn_bExist(csName, csTypeName, p_oOwner, eCriteria);
	}

	return bOK;
}


/*===========================================================================
*		Description:	check if this object is registered (valid, invalid or all)
*		Creation date:	
*		Author:			
*---------------------------------------------------------------------------
*		Revision date:       Author:
*=========================================================================*/
BOOL CPA_MainWorld::fn_bExist(CPA_BaseObject *p_oObject, tdeResearchCriteria eCriteria)
{
	POSITION		stPos;
	CPA_DLLBase		*p_oDLL;
	BOOL			bOK;

	bOK = FALSE;

	// if type == superobject, just look in the SO list
	bOK = GetInterface()->GetEditor()->fn_bExist(p_oObject, eCriteria);

	// look in Object DLLs
	stPos = m_oListOfObjectDLL.GetHeadPosition();
	while (stPos && !bOK)
	{
		p_oDLL = m_oListOfObjectDLL.GetNext(stPos);
		bOK = p_oDLL->fn_bExist(p_oObject, eCriteria);
	}
	// look in Tool DLLs
	stPos = m_oListOfToolDLL.GetHeadPosition();
	while (stPos && !bOK)
	{
		p_oDLL = m_oListOfToolDLL.GetNext(stPos);
		bOK = p_oDLL->fn_bExist(p_oObject, eCriteria);
	}

	return bOK;
}




/*===========================================================================
*		Description:	add an editor to the list
*		Creation date:	
*		Author:			
*---------------------------------------------------------------------------
*		Revision date:       Author:
*=========================================================================*/
void CPA_MainWorld::fn_vRegisterEditor (CPA_EditorBase *p_oEditor)
{ 
	if(!m_oListOfEditorBase.Find(p_oEditor))
		m_oListOfEditorBase.AddTail(p_oEditor);
}

/*===========================================================================
*		Description:	find an editor with its name
*		Creation date:	
*		Author:			
*---------------------------------------------------------------------------
*		Revision date:       Author:
*=========================================================================*/
CPA_EditorBase *CPA_MainWorld::GetEditorByName(CString csName)
{
    POSITION stPos = m_oListOfEditorBase.GetHeadPosition();
    while( stPos )
    {
        CPA_EditorBase *p_oEditor = m_oListOfEditorBase.GetNext(stPos);
        if(p_oEditor -> GetCurrentEditorName() == csName )
            return p_oEditor;
    }
    return NULL;
}

/*===========================================================================
*		Description:	find the DLL that handles this editor type
*		Creation date:	
*		Author:			
*---------------------------------------------------------------------------
*		Revision date:       Author:
*=========================================================================*/
CPA_DLLBase *CPA_MainWorld::GetDLLWithTypeName(CString csType)
{
	POSITION		stPos;
	CPA_DLLBase		*p_oDLL;
	CPA_BaseObjectList *p_oList;

	p_oList = NULL;

	// look in Object DLLs
	stPos = m_oListOfObjectDLL.GetHeadPosition();
	while (stPos)
	{
		p_oDLL = m_oListOfObjectDLL.GetNext(stPos);
		if ((p_oList = p_oDLL->GetBaseObjectList(csType)) != NULL)
			return p_oDLL;
	}
	// look in Tool DLLs
	stPos = m_oListOfToolDLL.GetHeadPosition();
	while (stPos)
	{
		p_oDLL = m_oListOfToolDLL.GetNext(stPos);
		if ((p_oList = p_oDLL->GetBaseObjectList(csType)) != NULL)
			return p_oDLL;
	}

	return NULL;
}

/*===========================================================================
*		Description:	get the object DLL with the given name
*		Creation date:
*		Author:			Shaitan
*---------------------------------------------------------------------------
*		Revision date:       Author:
*=========================================================================*/
CPA_ObjectDLLBase * CPA_MainWorld::GetObjectDLLWithName (CString csName)
{
    POSITION			stPos;
    CPA_ObjectDLLBase	*p_oDLL;

    stPos = m_oListOfObjectDLL.GetHeadPosition();
    while(stPos != NULL)
    {
    	p_oDLL = m_oListOfObjectDLL.GetNext(stPos);
		if (csName == p_oDLL->GetName())
			return p_oDLL;
    }
	return NULL;
}

/*===========================================================================
*		Description:	get the object DLL that can handle the given engine type
*		Creation date:
*		Author:			Shaitan
*---------------------------------------------------------------------------
*		Revision date:       Author:
*=========================================================================*/
CPA_ObjectDLLBase * CPA_MainWorld::GetObjectDLLWithType (long lEngineType)
{
    POSITION			stPos;
    CPA_ObjectDLLBase	*p_oDLL;

    stPos = m_oListOfObjectDLL.GetHeadPosition();
    while(stPos != NULL)
    {
    	p_oDLL = m_oListOfObjectDLL.GetNext(stPos);
		if (p_oDLL->fn_bCanHandleThisType(lEngineType))
			return p_oDLL;
    }
	return NULL;
}

/*===========================================================================
*		Description:	get the tool DLL with the given name
*		Creation date:
*		Author:			MT
*---------------------------------------------------------------------------
*		Revision date:       Author:
*=========================================================================*/
CPA_ToolDLLBase * CPA_MainWorld::GetToolDLLWithName(char *_szName)
{
    POSITION		stPos;
    CPA_ToolDLLBase	*p_oDLL;

    stPos = m_oListOfToolDLL.GetHeadPosition();
    while(stPos != NULL)
    {
    	p_oDLL = m_oListOfToolDLL.GetNext(stPos);
		if (!strcmp(p_oDLL->GetName(), _szName))
			return p_oDLL;
    }
	return NULL;
}

/*===========================================================================
*       Description:    add/remove the tool DLL from the list
*		Creation date:
*		Author:			MT
*---------------------------------------------------------------------------
*		Revision date:       Author:
*=========================================================================*/

void CPA_MainWorld::fn_vSetReceivingWindowMsgState(CPA_ToolDLLBase * _p_oToolDLL,BOOL _bWantToReceive /*=TRUE*/)
{
    POSITION stPos = m_oListOfToolDLLReceivingWindowMsg.Find(_p_oToolDLL);

    if(_bWantToReceive)
    {
        //add Tool on list
        if(!stPos)
            m_oListOfToolDLLReceivingWindowMsg.AddTail(_p_oToolDLL);
    }
    else
    {
        //remove tool from list
        if(stPos)
            m_oListOfToolDLLReceivingWindowMsg.RemoveAt(stPos);
    }
}

/*===========================================================================
*       Description:    add/remove the tool DLL form the list
*		Creation date:
*		Author:			MT
*---------------------------------------------------------------------------
*		Revision date:       Author:
*=========================================================================*/
void CPA_MainWorld::fn_vSetReceivingEvtEditorMsgState(CPA_ToolDLLBase *_p_oToolDLL,BOOL _bWantToReceive /*=TRUE*/)
{
    POSITION stPos = m_oListOfToolDLLReceivingEvtEditorMsg.Find(_p_oToolDLL);

    if(_bWantToReceive)
    {
        //add Tool on list
        if(!stPos)
            m_oListOfToolDLLReceivingEvtEditorMsg.AddTail(_p_oToolDLL);
    }
    else
    {
        //remove tool from list
        if(stPos)
            m_oListOfToolDLLReceivingEvtEditorMsg.RemoveAt(stPos);
    }
}


//********************************************************************************
//********************************************************************************

/*===========================================================================
*		Description:	Activate a new Editor
*		Creation date:	
*		Author:			Shaitan
*---------------------------------------------------------------------------
*		Revision date:       Author:
*=========================================================================*/
BOOL CPA_MainWorld::fn_bActivateEditor (CPA_EditorBase *pNewEditor, CPA_List<CPA_BaseObject> *pParams)
{
	CPA_EditorBase	*p_oOldEditor	= m_p_oCurrentEditor;
	CPA_EditorBase	*p_oCurEditor	= m_p_oCurrentEditor;
	tdePermission	ePermission		= C_CloseBefore;
	
	// ask permission to new DLL
	if (!pNewEditor->fn_bCanActivateEditor(pParams))
		return FALSE;
	// disable refresh to avoid flicking
	g_oFrameGest.mfn_vSetRefresh(FALSE);
	// if necessary, restore context
	while (ePermission == C_CloseBefore)
	{
		ePermission = m_p_oCurrentEditor->fn_eAcceptNewEditor(pNewEditor);
		if (ePermission == C_CloseBefore)
		{
			if (m_p_oCurrentEditor->fn_bIsCurrentEditor())
			{
				m_p_oCurrentEditor->fn_vOnCloseEditor();
				m_p_oCurrentEditor->SetCurrent(FALSE);
				m_p_oCurrentEditor->fn_vRestoreContext();
			}
			else
				ePermission = C_Allow;
		}
	}

	// update old editor
	p_oCurEditor = m_p_oCurrentEditor;

	// if current editor refuse or is the new one, re-activate it
	if ((ePermission != C_Allow)||(pNewEditor == p_oCurEditor))
	{
		fn_bRestoreEditor(p_oOldEditor);
		fn_bSetCurrentEditor(p_oCurEditor);
		g_oFrameGest.mfn_vSetRefresh(TRUE);
		m_p_oCurrentFrameBaseMenu->fn_vUpdateCurrentEditor(m_p_oCurrentEditor);
		return FALSE;
	}

	// save current context
	pNewEditor->fn_vSaveContext();
	// set new editor
	fn_bRestoreEditor(p_oOldEditor);
	fn_bSetCurrentEditor(pNewEditor);
	GetInterface()->fn_vCancelAllModes();
	// activate the new editor
	pNewEditor->fn_vOnActivateEditor(pParams);
	// resfresh all dialogs
	g_oFrameGest.mfn_vSetRefresh(TRUE);
	//VL170997
	// When previous refresh was done some window are hidden after being shown.
	// here we force frame gest to show again windows
	g_oFrameGest.mfn_vRefreshWindows( TRUE );
	//EVL170997

	((DEV_ViewPort3D *) GetInterface()->GetMultiDevice()->GetFocusDevice()->GetViewPort())->SetFocus();
	return TRUE;
}


/*===========================================================================
*		Description:	Close Editor
*		Creation date:	
*		Author:			Shaitan
*---------------------------------------------------------------------------
*		Revision date:       Author:
*=========================================================================*/
BOOL CPA_MainWorld::fn_bCloseEditor (CPA_EditorBase *pOldEditor)
{
	CPA_EditorBase	*p_oOldEditor	= m_p_oCurrentEditor;
	CPA_EditorBase	*p_oCurEditor	= m_p_oCurrentEditor;

	// non-current editor is already closed
	if (!pOldEditor->fn_bIsCurrentEditor())
		return TRUE;

	// ask permission
	if (!pOldEditor->fn_bCanCloseEditor())
		return FALSE;

	g_oFrameGest.mfn_vSetRefresh(FALSE);
	// restore all parameters and close
	pOldEditor->fn_vOnCloseEditor();
	pOldEditor->SetCurrent(FALSE);
	pOldEditor->fn_vRestoreContext();
	// update old editor
	p_oCurEditor = m_p_oCurrentEditor;
	fn_bRestoreEditor(p_oOldEditor);
	fn_bSetCurrentEditor(p_oCurEditor);
	// restore focus
	g_oFrameGest.mfn_vSetRefresh(TRUE);
	((DEV_ViewPort3D *) GetInterface()->GetMultiDevice()->GetFocusDevice()->GetViewPort())->SetFocus();
	
	return TRUE;
}


/*===========================================================================
*		Description:	update the current DLL
*		Creation date:	
*		Author:			Shaitan
*---------------------------------------------------------------------------
*		Revision date:       Author:
*=========================================================================*/
BOOL CPA_MainWorld::fn_bSetCurrentEditor (CPA_EditorBase *p_oEditor)
{
	CPA_ToolDLLBase *pDLLTool;
	POSITION		pos;
	
	// if there's no change
	if (p_oEditor == m_p_oCurrentEditor)
		return FALSE;

	// send message to Tool DLLs
	for (pDLLTool = GetToolDLLReceivingEvtEditorMsg()->GetHeadElement(pos); pDLLTool;
		 pDLLTool = GetToolDLLReceivingEvtEditorMsg()->GetNextElement(pos))
		pDLLTool->fn_vOnChangeCurrentEditor(m_p_oCurrentEditor, p_oEditor);

	// tell the new DLL it just lost focus
	m_p_oCurrentEditor->fn_vHasLostFocus();
	m_p_oCurrentEditor->SetCurrent(FALSE);

	// set current editor
	m_p_oCurrentEditor = p_oEditor;

	// tell the new DLL it just gained focus
	m_p_oCurrentEditor->fn_bHasGainedFocus();
	m_p_oCurrentEditor->SetCurrent(TRUE);

	// update menu
	m_p_oCurrentFrameBaseMenu->fn_vUpdateCurrentEditor(m_p_oCurrentEditor);

	return TRUE;

}

/*===========================================================================
*		Description:	update the current DLL
*		Creation date:	
*		Author:			Shaitan
*---------------------------------------------------------------------------
*		Revision date:       Author:
*=========================================================================*/
BOOL CPA_MainWorld::fn_bRestoreEditor (CPA_EditorBase *p_oEditor)
{
	// if there's no change
	if (p_oEditor == m_p_oCurrentEditor)
		return FALSE;

	// set current editor
	m_p_oCurrentEditor = p_oEditor;
	return TRUE;
}

#endif //ACTIVE_EDITOR