/*=========================================================================
*
* CPASObj.cpp		- EDT_SuperObject : implementation
*
*
* Version			1.0
* Creation date		20.06.97
* Revision date
*
* Shaitan
*=======================================================================*/
#include "stdafx.h"

#ifdef ACTIVE_EDITOR

#include "acp_base.h"

#include "ITF.h"
#include "DPT.h"

#include "EDTModif.hpp"

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

#define HieFriend
#include "incSPO.h"
#undef HieFriend

#include "x:\cpa\Main\inc\_editid.h"

//DeclareTemplateStatic(HIE_tdxHandleToSuperObject); 

BOOL fn_bHasChangedVector (MTH3D_tdstVector *pInitial, MTH3D_tdstVector *pFinal)
{
	return	(	(MTH3D_M_xGetXofVector(pInitial) != MTH3D_M_xGetXofVector(pFinal))
			 ||	(MTH3D_M_xGetYofVector(pInitial) != MTH3D_M_xGetYofVector(pFinal))
			 ||	(MTH3D_M_xGetZofVector(pInitial) != MTH3D_M_xGetZofVector(pFinal))
			);
}


//#################################################################################
// INITS
//#################################################################################

/*===========================================================================
	Constructor
=========================================================================*/
EDT_SuperObject::EDT_SuperObject (EDT_HierarchyEditor *pEditor,
								  HIE_tdxHandleToSuperObject hEngineSO, 
								  tdeSaveStatus eStatus, tdeTypeSO eTypeSO , 
								  CString csName, CString csEngineFileName)
	: CPA_SuperObject(pEditor, hEngineSO, eStatus, eTypeSO)
{
	// section object
    SetSectionData(this);
	SetDataPath(fn_szGetLevelsDataPath());
	SetCallBackSave(EDT_SuperObject::CallBackSave);
	fn_vInitSectionName(csEngineFileName);
	// matrix
	m_pMatrixSection = new CPA_SectionObject (GetMatrixSectionName(), fn_szGetLevelsDataPath(),
											  EDT_SuperObject::CallBackSaveMatrix, this, 
											  fn_bSectionExists());
	// temporary modif
	m_pTempModif = NULL;

	// name
	if (CPA_SaveObject::fn_eRename(csName) != E_mc_None)
		SetDefaultValidName();
	// update section
	fn_vUpdateSectionName();

	// if necessary, notify
	if (!fn_bSectionExists())
		fn_vNotifySave();
}

/*===========================================================================
	New Constructor
=========================================================================*/
EDT_SuperObject::EDT_SuperObject (EDT_HierarchyEditor *pEditor, 
								  tdeSaveStatus eStatus, tdeTypeSO eTypeSO , 
								  CString csName, CString csEngineFileName)
	: CPA_SuperObject(pEditor, eStatus, eTypeSO)
{
	// section object
    SetSectionData(this);
	SetDataPath(fn_szGetLevelsDataPath());
	SetCallBackSave(EDT_SuperObject::CallBackSave);
	fn_vInitSectionName(csEngineFileName);
	// matrix
	m_pMatrixSection = new CPA_SectionObject (GetMatrixSectionName(), fn_szGetLevelsDataPath(),
											  EDT_SuperObject::CallBackSaveMatrix, this, 
											  fn_bSectionExists());
	// temporary modif
	m_pTempModif = NULL;

	// name
	if (CPA_SaveObject::fn_eRename(csName) != E_mc_None)
		SetDefaultValidName();
	// update section
	fn_vUpdateSectionName();

	// if necessary, notify
	if (!fn_bSectionExists())
		fn_vNotifySave();
}


/*===========================================================================
	Copy-Constructor
=========================================================================*/
EDT_SuperObject::EDT_SuperObject (EDT_SuperObject &r_oSource)
	: CPA_SuperObject(r_oSource)
{
	// section 
	SetSectionData(this);
	// matrix
	m_pMatrixSection = new CPA_SectionObject (GetMatrixSectionName(), fn_szGetLevelsDataPath(),
											  EDT_SuperObject::CallBackSaveMatrix, this, FALSE);
	// temporary modif
	m_pTempModif = NULL;

	// rename
	SetDefaultValidName();
	fn_vUpdateSectionName();

	// if necessary, notify
	fn_vNotifySave();
}

 /*===========================================================================
	Destructor
=========================================================================*/
EDT_SuperObject::~EDT_SuperObject(void)
{
	CPA_SuperObjectBase *p_oSuperObject;
	POSITION pos;

	for (p_oSuperObject = GetHeadElement(pos); p_oSuperObject;
		 p_oSuperObject = GetNextElement(pos))
	{
		delete ((EDT_SuperObject *) p_oSuperObject);
		p_oSuperObject = NULL;
	}
}

//#################################################################################
// SECTION NAME
//#################################################################################
	
/*===========================================================================
*		Description:	Init Section Name
*		Creation date:
*		Author:			Shaitan
*---------------------------------------------------------------------------
*		Revision date:     Author:
*=========================================================================*/
void EDT_SuperObject::fn_vInitSectionName (const CString csEngineFileName)
{
	CString csSectionName;
	char	szSectionName[SCR_CV_ui_Cfg_MaxLenName]; 

	// responsibility level 
	if (!fn_bCanBeNotified())
		return;
	
	// check if engine section exists
	csSectionName = GetSuperObjectEditor()->GetEngineSectionName(GetEngineStruct());
	// if section exists, update corresponding parameters
	if (!csSectionName.IsEmpty())
	{
		SetReferencedSectionName(csSectionName);
		SetExistingSection(TRUE);
	}
	else
	{
		SCR_fn_v_RdL0_ComputeSectionName(szSectionName, (char*)(LPCTSTR) csEngineFileName, "SuperObject", " ");
		SetReferencedSectionName(szSectionName);
		SetExistingSection(FALSE);
	}
}

/*===========================================================================
*		Description:	Update Section Name
*		Creation date:
*		Author:			Shaitan
*---------------------------------------------------------------------------
*		Revision date:     Author:
*=========================================================================*/
void EDT_SuperObject::fn_vUpdateSectionName (void)
{
	// update main section
	CPA_SaveObject::fn_vUpdateSectionName();
	// update matrix section
	m_pMatrixSection->SetReferencedSectionName(GetMatrixSectionName());
}


/*===========================================================================
*		Description:	Matrix Section
*		Creation date:
*		Author:			Shaitan
*---------------------------------------------------------------------------
*		Revision date:     Author:
*=========================================================================*/
CString EDT_SuperObject::GetMatrixSectionName (void)
{
	CString csSectionName;
	char	szSectionName[SCR_CV_ui_Cfg_MaxLenName]; 
	char	szActionName[SCR_CV_ui_Cfg_MaxLenName]; 
	char	szFileName[SCR_CV_ui_Cfg_MaxLenName]; 
	char	szName[SCR_CV_ui_Cfg_MaxLenName]; 

	// compute section name
	csSectionName = GetReferencedSectionName();
	SCR_fn_v_RdL0_SplitSectionName((char*)(LPCTSTR)csSectionName, szFileName, szActionName, szName);
	SCR_fn_v_RdL0_ComputeSectionName(szSectionName, szFileName, "Matrix", (char*)(LPCTSTR) CPA_SaveObject::GetName());
	csSectionName = szSectionName;

	return csSectionName;
}


//#################################################################################
// NOTIFICATIONS
//#################################################################################

/*===========================================================================
	Save
=========================================================================*/
void EDT_SuperObject::fn_vNotifySave (void)
{
	// check save status
	if (!fn_bCanBeNotified())
		return;
	
	// main section
	CPA_SaveObject::fn_vNotifySave();
	// matrix section
	m_pMatrixSection->fn_vWriteSection();
}

/*===========================================================================
	UnSave
=========================================================================*/
void EDT_SuperObject::fn_vNotifyUnSave	(void)
{
	// check save status
	if (!fn_bCanBeNotified())
		return;
	
	// main section
	CPA_SaveObject::fn_vNotifyUnSave();
	// matrix section
	m_pMatrixSection->fn_vDeleteSection();
}

/*===========================================================================
	Restore
=========================================================================*/
void EDT_SuperObject::fn_vNotifyRestore	(void)
{
	// check save status
	if (!fn_bCanBeNotified())
		return;
	
	// main section
	CPA_SaveObject::fn_vNotifyRestore();
	// matrix section
	m_pMatrixSection->fn_vRestoreSection();
}

/*===========================================================================
	Renamed
=========================================================================*/
void EDT_SuperObject::fn_vNotifyRename	(void)
{
	// check save status
	if (!fn_bCanBeNotified())
		return;
	
	// main section
	CPA_SaveObject::fn_vNotifyRename();
	// matrix section
	m_pMatrixSection->fn_vRenameSection(GetMatrixSectionName());
}

/*===========================================================================
	Permissions
=========================================================================*/
BOOL EDT_SuperObject::fn_bCanBeNotified (void)
{
	return CPA_SaveObject::fn_bCanBeNotified();
}

//#################################################################################
// VALIDITY
//#################################################################################
	
/*===========================================================================
	Valid Name
=========================================================================*/
tdeMissingCriteria EDT_SuperObject::fn_eCheckValidity (const CString csNewName)
{
	return CPA_SaveObject::fn_eCheckValidity(csNewName);
}


//#################################################################################
// REFERENCES
//#################################################################################
	
/*===========================================================================
	Update reference when object changes
=========================================================================*/
void EDT_SuperObject::fn_vUpdateReference (CPA_SaveObject *pReferencedObject)
{
	CPA_SaveObject::fn_vUpdateReference(pReferencedObject);
}
	
/*===========================================================================
	Find new referenced name
=========================================================================*/
CString EDT_SuperObject::fn_csComputeReferencedSectionName (const CString csNewName)
{
	return CPA_SaveObject::fn_csComputeReferencedSectionName(csNewName);
}


//#################################################################################
// DIALOGS
//#################################################################################
	
/*===========================================================================
	Name
=========================================================================*/
CString EDT_SuperObject::GetNameToDraw (void)
{
	return ( (GetObject() != NULL) ? GetObject()->GetNameToDraw() : CPA_SaveObject::GetNameToDraw() );
}
	
/*===========================================================================
	Type
=========================================================================*/
CString EDT_SuperObject::GetTypeToDraw (void)
{
	return ( (GetObject() != NULL) ? GetObject()->GetTypeToDraw() : CPA_SaveObject::GetTypeToDraw() );
}
	
/*===========================================================================
	Owner
=========================================================================*/
CString EDT_SuperObject::GetOwnerToDraw (void)
{
	return ( (GetObject() != NULL) ? GetObject()->GetOwnerToDraw() : CPA_SaveObject::GetOwnerToDraw() );
}


/*===========================================================================
	Super-Object Owner
=========================================================================*/
CString	EDT_SuperObject::GetOwnerName (void)
{	
	return ( (GetSuperObjectOwner() != NULL) ? GetSuperObjectOwner()->GetName() : "" );
}

/*===========================================================================
	Save Status
=========================================================================*/
CString	EDT_SuperObject::GetLevelName (void)
{
	CString csLevelName;

	switch (GetSaveStatus())
	{
		case E_ss_Responsible:
			csLevelName = "Responsible";
			break;
		case E_ss_Modify:
			csLevelName = "Modify";
			break;
		case E_ss_NoSave:
			csLevelName = "No Save";
			break;
		case E_ss_NoModif:
			csLevelName = "No Modif";
			break;
		default:
			csLevelName = "";
			break;
	}
	return csLevelName;
}


//#################################################################################
// ENGINE STRUCT
//#################################################################################
	
/*===========================================================================
	Set engine struct and update data
=========================================================================*/
void EDT_SuperObject::SetEngineStruct (HIE_tdxHandleToSuperObject hEngineSO)
{
	// set engine struct
	CPA_SuperObject::SetSuperObjectStruct(hEngineSO);
	// section
	fn_vInitSectionName("");
}


//#################################################################################
// COPY / PASTE
//#################################################################################
	
/*===========================================================================
*		Description:	Copy linked object
*		Creation date:
*		Author:			Shaitan
*---------------------------------------------------------------------------
*		Revision date:     Author:
*=========================================================================*/
void EDT_SuperObject::MyObjectIsAlsoACopy(EDT_SuperObject *p_oSource)
{
	CPA_BaseObject *p_oNewObject, *p_oOldObject;

	p_oOldObject = GetObject();
	// duplicate object, and eventually build corresponding protected childs
	p_oNewObject = GetObjectDLL()->Duplicate(GetObject(), this);
	ASSERT(p_oNewObject != NULL);
	// put new object in this so
	SetObject(p_oNewObject);
}



/*===========================================================================
*		Description:	set name for copy
*		Creation date:
*		Author:			Shaitan
*---------------------------------------------------------------------------
*		Revision date:     Author:
*=========================================================================*/
void EDT_SuperObject::SetNameForCopy(EDT_SuperObject *pDesc)
{
	CString	csName;
	CString	csCount;
	long	lCount = 1;

	// change super-object name
	csName = "CopyOf" + pDesc->GetName();
	while (fn_eCheckValidity(csName) != E_mc_None)
	{
		csCount.Format("-%i",lCount++);
		csName = "CopyOf" + pDesc->GetName() + csCount;
	}
	fn_eRename(csName);

	// update object
	if ((GetObject())&&(pDesc->GetObject())&&(pDesc->GetObject() != GetObject()))
	{
		// change object name
		csName = "CopyOf" + pDesc->GetObject()->GetName();
		while (GetObject()->fn_eCheckUnicity(csName) != E_mc_None)
		{
			csCount.Format("-%i",lCount++);
			csName = "CopyOf" + pDesc->GetObject()->GetName() + csCount;
		}
		GetObject()->fn_eRename(csName);
	}
}

/*===========================================================================
*		Description:	set name for paste
*		Creation date:
*		Author:			Shaitan
*---------------------------------------------------------------------------
*		Revision date:     Author:
*=========================================================================*/
void EDT_SuperObject::SetNameForPaste(EDT_SuperObject *pDesc)
{
	CString	csName;
	CString	csCount;
	long	lCount;

	// change super-object name
	csName = pDesc->GetName();
	lCount = 1;
	while (fn_eCheckValidity(csName) != E_mc_None)
	{
		csCount.Format("-%i",lCount++);
		csName = pDesc->GetName() + csCount;
	}
	fn_eRename(csName);

	// update object
	if ((GetObject())&&(pDesc->GetObject())&&(pDesc->GetObject() != GetObject()))
	{
		// change object name
		csName = pDesc->GetObject()->GetName();
		lCount = 1;
		while (GetObject()->fn_eCheckUnicity(csName) != E_mc_None)
		{
			csCount.Format("-%i",lCount++);
			csName = pDesc->GetObject()->GetName() + csCount;
		}
		GetObject()->fn_eRename(csName);
	}
}


//#################################################################################
// MODIFICATIONS
//#################################################################################

/*===========================================================================
	Translation
*=========================================================================*/
void EDT_SuperObject::fn_vTranslate (MTH3D_tdstVector *p_stVector, BOOL bAbsolute)
{
	POS_tdstCompletePosition stMatrix,*p_stMatrix;
	MTH3D_tdstVector	stVector,stTemp;

	POS_fn_vSetIdentityMatrix(&stMatrix);
	// translation on OBJECT axis
	if (!bAbsolute)
	{
		// update vector according to the rotation matrix of the object
		stMatrix = *(HIE_fn_hGetSuperObjectMatrix(GetStruct()));
		MTH3D_M_vNullVector(&stVector);
		POS_fn_vSetTranslationVector(&stMatrix, &stVector);
		POS_fn_vMulMatrixVertex(&stVector, &stMatrix, p_stVector);
	}
	// Translation on CAMERA's axis
	else
	{
		// update vector according to object's position
		POS_fn_vInvertMatrix(&stMatrix,HIE_fn_hGetSuperObjectGlobalMatrix(HIE_fn_hGetSuperObjectFather(GetStruct())));
		MTH3D_M_vNullVector(&stVector);
		POS_fn_vSetTranslationVector(&stMatrix, &stVector);
		POS_fn_vMulMatrixVertex(&stVector, &stMatrix, p_stVector);
	}

	// update the translation vector of the object
	p_stMatrix = HIE_fn_hGetSuperObjectMatrix(GetStruct());
	POS_fn_vGetTranslationVector(p_stMatrix, &stTemp);
	MTH3D_M_vAddVector(&stTemp, &stTemp, &stVector);
	POS_fn_vSetTranslationVector(p_stMatrix, &stTemp);
//	POS_fn_vNormalizeMatrix(p_stMatrix);
}

/*===========================================================================
	Rotation
*=========================================================================*/
void EDT_SuperObject::fn_vRotate (POS_tdstCompletePosition *p_stMatrix)
{
	MTH3D_tdstVector	stVectI,stVectJ,stVectK;

	// Update the rotation matrix of object
	POS_fn_vMulMatrixMatrix(HIE_fn_hGetSuperObjectMatrix(GetStruct()), HIE_fn_hGetSuperObjectMatrix(GetStruct()), p_stMatrix);
	POS_fn_vGetScaleMatrix(HIE_fn_hGetSuperObjectMatrix(GetStruct()),&stVectI,&stVectJ,&stVectK);
	POS_fn_vNormalizeMatrix(HIE_fn_hGetSuperObjectMatrix(GetStruct()));
	POS_fn_vSetScaleMatrix(HIE_fn_hGetSuperObjectMatrix(GetStruct()),&stVectI,&stVectJ,&stVectK);
}

// Begin Silviu Simen 18 August 1998 Cut/Paste Mechanism
/*===========================================================================
	Translation
*=========================================================================*/
void EDT_SuperObject::fn_vSetOnlyPosition (MTH3D_tdstVector *pTransMatrix)
{
	HIE_fn_hGetSuperObjectMatrix(GetStruct()) -> stTranslationVector.xX = pTransMatrix -> xX;
	HIE_fn_hGetSuperObjectMatrix(GetStruct()) -> stTranslationVector.xY = pTransMatrix -> xY;
	HIE_fn_hGetSuperObjectMatrix(GetStruct()) -> stTranslationVector.xZ = pTransMatrix -> xZ;
}
// End Silviu Simen 18 August 1998 Cut/Paste Mechanism

/*===========================================================================
	Position
*=========================================================================*/
void EDT_SuperObject::fn_vSetPosition (POS_tdstCompletePosition  *pRefMatrix)
{
	POS_tdstCompletePosition  stMatrix;

	POS_fn_vSetIdentityMatrix(&stMatrix);
	// calculate the new matrix
	POS_fn_vInvertMatrix(&stMatrix, pRefMatrix);
	POS_fn_vMulMatrixMatrix(HIE_fn_hGetSuperObjectMatrix(GetStruct()), &stMatrix, HIE_fn_hGetSuperObjectGlobalMatrix(GetStruct()));
	POS_fn_vNormalizeMatrix(HIE_fn_hGetSuperObjectMatrix(GetStruct()));
}

/*===========================================================================
	Father
*=========================================================================*/
void EDT_SuperObject::fn_vInsertUnderParent (EDT_SuperObject *pEdParent, EDT_SuperObject *pNextBrother, BOOL bUpdatePos, POS_tdstCompletePosition  *pRefMatrix)
{
	POSITION pos = NULL;
	
	// isolate object from the hierarchy
	IsolateChild();
	// update the matrix to keep the current position
	if (bUpdatePos)
	{
		if (!pRefMatrix)
			pRefMatrix = HIE_fn_hGetSuperObjectGlobalMatrix(pEdParent->GetStruct());
		fn_vSetPosition(pRefMatrix);
	}
	// find position
	pEdParent->AddANewChild(this, TRUE, pNextBrother);
}

/*===========================================================================
	Check parent
*=========================================================================*/
BOOL EDT_SuperObject::fn_bAcceptAsParent (EDT_SuperObject *pEdObj)
{
	// ask the DLL
	if (GetObjectDLL() != NULL)
		return ( GetObjectDLL()->fn_bAcceptAsParent(GetObject(), pEdObj->GetObject()));

	return TRUE;
}

/*===========================================================================
	Check child
*=========================================================================*/
BOOL EDT_SuperObject::fn_bAcceptAsChild (EDT_SuperObject *pEdObj)
{
	// ask the DLL
	if (GetObjectDLL() != NULL)
		return ( GetObjectDLL()->fn_bAcceptAsChild(GetObject(), pEdObj->GetObject()));

	return TRUE;
}

/*===========================================================================
	Protected childs
*=========================================================================*/
void EDT_SuperObject::fn_vRemoveNonProtectedChilds (void)
{
	CPA_List<EDT_SuperObject> stListProtected;
	CPA_SuperObjectBase		  *pElem;
	EDT_SuperObject			  *pChild;
	POSITION				  pos;

	// init list of protected childs
	stListProtected.RemoveAll();
	// update all protected childs
	for (pElem = GetHeadElement(pos); pElem;
		 pElem = GetNextElement(pos))
	{
		pChild = (EDT_SuperObject *) pElem;
		if (pChild->GetSuperObjectOwner())
		{
			// update the child
			pChild->fn_vRemoveNonProtectedChilds();
			// add it to the list of protected childs
			stListProtected.AddTail(pChild);
		}
	}
	// Isolate object from all its childs
	RemoveAllChilds();
	if (stListProtected.GetCount())
		return;
	// Reinsert all protected childs
	for (pChild = stListProtected.GetHeadElement(pos); pChild;
		 pChild = stListProtected.GetNextElement(pos))
		AddANewChild(pChild);
}


//#################################################################################
// COPY / PASTE
//#################################################################################
	
/*===========================================================================
*		Description:	Temporary section
*		Creation date:
*		Author:			Shaitan
*---------------------------------------------------------------------------
*		Revision date:     Author:
*=========================================================================*/
CString EDT_SuperObject::GetTempModifSectionName (void)
{
	char	szSectionName[SCR_CV_ui_Cfg_MaxLenName];
	char	szFileName[SCR_CV_ui_Cfg_MaxLenName];
	char	szName[SCR_CV_ui_Cfg_MaxLenName];

	//CPA2 Stegaru Cristian 98-02
	//if the super object has changed its name, the modif section name is stored separatelly
	if (!m_csModifSectionName.IsEmpty ())
		return m_csModifSectionName;
	//End CPA2 Stegaru Cristian 98-02

	SCR_fn_v_RdL0_SplitSectionName((char*)(LPCSTR) GetReferencedSectionName(), szFileName, szSectionName, szName);
	//CPA2 Stegaru Cristian 98-02
	CString csFileName (szFileName);
	int iPos = csFileName.ReverseFind ('.');
	ASSERT (-1 != iPos);
	csFileName = csFileName.Left (iPos) + szModifExt;
	//End CPA2 Stegaru Cristian 98-02
	SCR_fn_v_RdL0_ComputeSectionName(szSectionName, (char*)(LPCSTR)csFileName, "Modif-SuperObject", szName);

	//CPA2 Stegaru Cristian 98-02
	mfn_vSetTempModifSectionName (szSectionName);

	return m_csModifSectionName;
	//End CPA2 Stegaru Cristian 98-02
}

/*===========================================================================
*		Description:	set temporary objet 
*		Creation date:
*		Author:			Shaitan
*---------------------------------------------------------------------------
*		Revision date:     Author:
*=========================================================================*/
void EDT_SuperObject::SetTemporaryModif (EDT_TempModif *pTempSO)
{
	// init temporary SO
	m_pTempModif = pTempSO;
}


/*===========================================================================
*		Description:	create temporary objet 
*		Creation date:
*		Author:			Shaitan
*---------------------------------------------------------------------------
*		Revision date:     Author:
*=========================================================================*/
BOOL EDT_SuperObject::fn_bInitTemporarySO (void)
{
	// check if modif must be registered
	//CPA2 modified Stegaru Cristian 98-03
	//I added E_ss_Responsible for objects that are imported from Max
	tdeSaveStatus eSaveStatus = GetSaveStatus();
	if (E_ss_Modify != eSaveStatus  &&
		E_ss_Responsible != eSaveStatus)
		return FALSE;

	// init temporary SO
	if (!m_pTempModif)
	{
		// create temporary SO
		m_pTempModif = new EDT_TempModif(this, FALSE);
		// update list
		GetSuperObjectEditor()->fn_vAddTemporaryModif(this);
	}
	return TRUE;
}

/*===========================================================================
*		Description:	update temporary objet in temp manager
*		Creation date:
*		Author:			Shaitan
*---------------------------------------------------------------------------
*		Revision date:     Author:
*=========================================================================*/
void EDT_SuperObject::fn_vUpdateTemporaryModif (CString csTypeModif, BOOL bAddModif)
{
	if (m_pTempModif)
	{
		// update temporary SO
		m_pTempModif->fn_vUpdateModification(csTypeModif, bAddModif);

		// check if object is still temporary
		if ((!m_pTempModif->fn_bIsModified(""))&&(!m_pTempModif->fn_bWasLoaded()))
		{
			// delete corresponding section
			m_pTempModif->fn_vNotifyUnsave();
			// update list
			GetSuperObjectEditor()->fn_vRemoveTemporaryModif(this);
			// delete temporary SO
			delete m_pTempModif;
			m_pTempModif = NULL;
		}
	}
}

/*===========================================================================
*		Description:	set current modification state
*		Creation date:
*		Author:			Shaitan
*---------------------------------------------------------------------------
*		Revision date:     Author:
*=========================================================================*/
void EDT_SuperObject::fn_vSetOnState (const CString csModificationType, BOOL bOnInitialState)
{
	EDT_HierarchyEditor *pEditor;
	EDT_ModifState		*pModif;

	// no modif => no state change !
	if (!m_pTempModif)
		return;
	
	// init modification
	pEditor = GetSuperObjectEditor();
	pModif = new EDT_ModifState (pEditor, this, csModificationType, bOnInitialState);
	// do modif
	pEditor->M_GetEditManager()->AskFor(pModif);
}

/*===========================================================================
*		Description:	validate modification state
*		Creation date:
*		Author:			Shaitan
*---------------------------------------------------------------------------
*		Revision date:     Author:
*=========================================================================*/
void EDT_SuperObject::fn_vValidateState	(const CString csModificationType, BOOL bInitialState)
{
	EDT_HierarchyEditor *pEditor;
	EDT_ModifValidate	*pModif;
	
	// validate only if permission
	if (!fn_bCanBeValidated())
		return;

	// no temporary modif => nothing to validate
	if (!m_pTempModif)
		return;
	// init modification
	pEditor = GetSuperObjectEditor();
	pModif = new EDT_ModifValidate (pEditor, this, csModificationType, bInitialState);
	// do modif
	pEditor->M_GetEditManager()->AskFor(pModif);
}

/*===========================================================================
*		Description:	create temporary objet 
*		Creation date:
*		Author:			Shaitan
*---------------------------------------------------------------------------
*		Revision date:     Author:
*=========================================================================*/
BOOL EDT_SuperObject::fn_bCanBeValidated (void)
{
	// check if modif must be registered
	return (GetSaveStatus() == E_ss_Responsible);
}


//#################################################################################
// SAVE
//#################################################################################
	
/*===========================================================================
*		Description:	Save main section
*		Creation date:
*		Author:			Shaitan
*---------------------------------------------------------------------------
*		Revision date:     Author:
*=========================================================================*/
void EDT_SuperObject::CallBackSave (SCR_tdst_File_Description *p_stFile, char *szSectionName, void *p_vData, SCR_tde_Ntfy_Action eAction)
{
	EDT_SuperObject			*pSupObj;
	EDT_SuperObject			*pChild;
	CPA_SuperObject			*pEdChild;
	CString					csObjectName;
	CString					csChildName;
	char					szNewSectionName[SCR_CV_ui_Cfg_MaxLenName];
	char					szMatrixName[SCR_CV_ui_Cfg_MaxLenName];
	char					szChildName[SCR_CV_ui_Cfg_MaxLenName];
	char					szName[SCR_CV_ui_Cfg_MaxLenName];
	
	// get parameters
	pSupObj = (EDT_SuperObject *) p_vData;

	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:
			// save section name
			strcpy(szName, pSupObj->GetName());
			SCR_fn_v_RdL0_ComputeSectionName(szNewSectionName, NULL, "SuperObject", szName);
			SCR_M_SvL0_SaveBeginSection(p_stFile, szNewSectionName, SCR_CC_C_Cfg_EOL);

			// save matrix
			SCR_fn_v_RdL0_ComputeSectionName(szMatrixName, "*", "Matrix", szName);
			SCR_M_SvL0_SaveEntry(p_stFile, "PutMatrix", SCR_CC_C_Cfg_NoChar);
            SCR_fn_v_SvL0_SaveParameters_MP(p_stFile, SCR_EF_SvL0_Normal, 1, szMatrixName);

			// save linked object
			if (pSupObj->GetObject())
			{
				ASSERT(pSupObj->GetObject()->fn_bCanBeSaved());
				csObjectName = ((CPA_SaveObject *) pSupObj->GetObject())->GetReferencedSectionName();
				SCR_M_SvL0_SaveEntry(p_stFile, "LinkedObject", SCR_CC_C_Cfg_NoChar);
				SCR_fn_v_SvL0_SaveParameters_MP(p_stFile, SCR_EF_SvL0_Normal, 1, (char *)(LPCSTR)csObjectName);
			}

			// save childs
			for (pEdChild = pSupObj->GetSuperObjectFirstChild(); pEdChild;
				 pEdChild = pSupObj->GetSuperObjectNextChild(pEdChild))
			{
				pChild = (EDT_SuperObject *) pEdChild;
				if (pChild->fn_bCanBeNotified())
				{
					// get section name
					csChildName = pChild->GetReferencedSectionName();
					SCR_fn_v_RdL0_SplitSectionName((char*)(LPCSTR)csChildName, NULL, szNewSectionName, szChildName);
					SCR_fn_v_RdL0_ComputeSectionName(szNewSectionName, "*", "SuperObject", szChildName);
					// save entry
					SCR_M_SvL0_SaveEntry(p_stFile, "AddChild", SCR_CC_C_Cfg_NoChar);
					SCR_fn_v_SvL0_SaveParameters_MP(p_stFile, SCR_EF_SvL0_Normal, 1, szNewSectionName);
				}
			}

//ANNECY CO SPOFLAG 03/02/98
			// save flags
			SCR_M_SvL0_SaveEntry(p_stFile, "Flags", SCR_CC_C_Cfg_NoChar);
			SCR_fn_v_SvL0_SaveParameters_MP(p_stFile, SCR_EF_SvL0_Scanf, 1, "%ld", pSupObj->GetFlags());
//ENDANNECY CO SPOFLAG 

//ANNECY Shaitan Transparency (26/03/98) {
			SCR_M_SvL0_SaveEntry(p_stFile, "Transparency", SCR_CC_C_Cfg_NoChar);
			SCR_fn_v_SvL0_SaveParameters_MP(p_stFile, SCR_EF_SvL0_Scanf, 1, "%f", pSupObj->fn_fGetTransparencyLevel());
//ENDANNECY Shaitan Transparency }

			// 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);

			// reinit existence
			pSupObj->fn_vSectionSaved();
			break;
		
		case SCR_EA_Ntfy_DeleteSection:
			// update existence
			pSupObj->fn_vSectionDeleted();
			break;
	}
}

/*===========================================================================
*		Description:	Save matrix section
*		Creation date:
*		Author:			Shaitan
*---------------------------------------------------------------------------
*		Revision date:     Author:
*=========================================================================*/
void EDT_SuperObject::CallBackSaveMatrix (SCR_tdst_File_Description *p_stFile, char *szSectionName, void *p_vData, SCR_tde_Ntfy_Action eAction)
{
	GEO_tdxHandleToMatrix	hMatrix;
	EDT_SuperObject			*pSupObj;
	char					szMatrixName[SCR_CV_ui_Cfg_MaxLenName];
	char					szName[SCR_CV_ui_Cfg_MaxLenName];
	
	
	// get parameters
	pSupObj = (EDT_SuperObject *) p_vData;

	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:
			// save matrix
			hMatrix = HIE_fn_hGetSuperObjectMatrix(pSupObj->GetStruct());
			SCR_fn_v_RdL0_SplitSectionName(szSectionName, NULL, szMatrixName, szName);
			pSupObj->fn_vSaveMatrix(p_stFile, hMatrix, szName);
			// save end section
			if (eAction == SCR_EA_Ntfy_AddSection)
				SCR_M_SvL0_SaveBlankLine (p_stFile);

			// reinit existence
			pSupObj->GetMatrixSection()->fn_vSectionSaved();
			break;

		case SCR_EA_Ntfy_DeleteSection:
			// update existence
			pSupObj->GetMatrixSection()->fn_vSectionDeleted();
			break;
	}
}


/*===========================================================================
*		Description:	Save matrix
*		Creation date:
*		Author:			Shaitan
*---------------------------------------------------------------------------
*		Revision date:     Author:
*=========================================================================*/
void EDT_SuperObject::fn_vSaveMatrix (SCR_tdst_File_Description *p_stFile, GEO_tdxHandleToMatrix hMatrix, CString csMatrixName)
{
	MTH3D_tdstVector	stVecI,stVecJ,stVecK;
	char				szSectionName[SCR_CV_ui_Cfg_MaxLenName];
	double				dUnit;

	dUnit = GLI_dGetUnitInMeterInFile( NULL );
	if (dUnit == 0)
		dUnit = 1;
	
	// save begin section
	SCR_fn_v_RdL0_ComputeSectionName(szSectionName, NULL, "Matrix", (char*)(LPCTSTR) csMatrixName);
	SCR_M_SvL0_SaveBeginSection(p_stFile, szSectionName, SCR_CC_C_Cfg_EOL);
			
	// save translation
	SCR_M_SvL0_SaveEntry(p_stFile, "MatrixTranslation", SCR_CC_C_Cfg_NoChar);
	POS_fn_vGetTranslationVector(hMatrix,&stVecI);
	SCR_fn_v_SvL0_SaveParameters_MP(p_stFile, SCR_EF_SvL0_Scanf, 1, 
		"%f,%f,%f", 
		GLI_M_ValueToFloat(MTH3D_M_xGetXofVector(&stVecI)) / dUnit,
		GLI_M_ValueToFloat(MTH3D_M_xGetYofVector(&stVecI)) / dUnit,
		GLI_M_ValueToFloat(MTH3D_M_xGetZofVector(&stVecI)) / dUnit );

	// save scale
	SCR_M_SvL0_SaveEntry(p_stFile, "MatrixScale", SCR_CC_C_Cfg_NoChar);
	POS_fn_vGetScaleMatrix(hMatrix,&stVecI,&stVecJ,&stVecK);
    SCR_fn_v_SvL0_SaveParameters_MP(p_stFile, SCR_EF_SvL0_Scanf, 1, 
			"%f,%f,%f,%f,%f,%f,%f,%f,%f", 
			GLI_M_ValueToFloat(MTH3D_M_xGetXofVector(&stVecI)),
			GLI_M_ValueToFloat(MTH3D_M_xGetYofVector(&stVecI)),
			GLI_M_ValueToFloat(MTH3D_M_xGetZofVector(&stVecI)),
			GLI_M_ValueToFloat(MTH3D_M_xGetXofVector(&stVecJ)),
			GLI_M_ValueToFloat(MTH3D_M_xGetYofVector(&stVecJ)),
			GLI_M_ValueToFloat(MTH3D_M_xGetZofVector(&stVecJ)),
			GLI_M_ValueToFloat(MTH3D_M_xGetXofVector(&stVecK)),
			GLI_M_ValueToFloat(MTH3D_M_xGetYofVector(&stVecK)),
			GLI_M_ValueToFloat(MTH3D_M_xGetZofVector(&stVecK)));

	// save rotation
	SCR_M_SvL0_SaveEntry(p_stFile, "MatrixRotation", SCR_CC_C_Cfg_NoChar);

	POS_fn_vGetRotationMatrix (hMatrix,&stVecI,&stVecJ,&stVecK);
    SCR_fn_v_SvL0_SaveParameters_MP(p_stFile, SCR_EF_SvL0_Scanf, 1, 
			"%f,%f,%f,%f,%f,%f,%f,%f,%f", 
			GLI_M_ValueToFloat(MTH3D_M_xGetXofVector(&stVecI)),
			GLI_M_ValueToFloat(MTH3D_M_xGetYofVector(&stVecI)),
			GLI_M_ValueToFloat(MTH3D_M_xGetZofVector(&stVecI)),
			GLI_M_ValueToFloat(MTH3D_M_xGetXofVector(&stVecJ)),
			GLI_M_ValueToFloat(MTH3D_M_xGetYofVector(&stVecJ)),
			GLI_M_ValueToFloat(MTH3D_M_xGetZofVector(&stVecJ)),
			GLI_M_ValueToFloat(MTH3D_M_xGetXofVector(&stVecK)),
			GLI_M_ValueToFloat(MTH3D_M_xGetYofVector(&stVecK)),
			GLI_M_ValueToFloat(MTH3D_M_xGetZofVector(&stVecK)));

	// save end section
	SCR_M_SvL0_SaveEndSection (p_stFile, SCR_CC_C_Cfg_EOL);
}




//########################################################################################
//	LOAD
//########################################################################################

/*===========================================================================
*		Description:	callback load modif
*		Creation date:
*		Author:			Shaitan
*---------------------------------------------------------------------------
*		Revision date:     Author:
*=========================================================================*/
SCR_tde_Anl_ReturnValue EDT_SuperObject::CallBackLoadModif (SCR_tdst_File_Description *p_fFile, char *szName, char *szParams[], SCR_tde_Anl_Action eAction)
{
	GEO_tdxHandleToMatrix	hMatrix;
	SCR_tdst_Cxt_Values		*p_stValue;
	EDT_HierarchyEditor		*pEditor; 
	EDT_SuperObject			*pSupObj;
	EDT_SuperObject			*pFather;
	EDT_TempModif			*pTempSO;
//	CString					csSectionName;
	char					szSectionName[SCR_CV_ui_Cfg_MaxLenName];
	char					szParentName[SCR_CV_ui_Cfg_MaxLenName];
	char					szFileName[SCR_CV_ui_Cfg_MaxLenName];
	
	//CPA2 Stegaru Cristian 98-02
	CString					csFileName;
	int						iPos = -1;
	//End CPA2 Stegaru Cristian 98-02
	
	switch (eAction)
	{
		case SCR_EA_Anl_BeginSection:
			// get corresponding super-object
			SCR_M_RdL0_GetContextLong(0, 0, EDT_SuperObject *,  pSupObj);
			// create modif
			pTempSO = new EDT_TempModif(pSupObj, TRUE);
			SCR_M_RdL0_SetSectionLong(0, 0, (long) pTempSO);
			break;

		case SCR_EA_Anl_Entry:
			// get temporary SO
			SCR_M_RdL0_GetSectionLong(0, 0, EDT_TempModif *, pTempSO);
			// set modification
			if (strcmp(szName,"Created") == 0)
			{
				pTempSO->SetCreated(TRUE);
				//CPA2 Stegaru Cristian 98-03
				CString csInitialSPOName = szParams[0];
				pTempSO->mfn_vSetInitialSPOName (csInitialSPOName);
				//End CPA2 Stegaru Cristian 98-03
			}
			if (strcmp(szName, "Deleted") == 0)
				pTempSO->SetDeleted(TRUE);
			// register initial parent
			if (strcmp(szName, "FinalParent") == 0)
			{
				// get section
				//CPA2 Stegaru Cristian 98-02
				SCR_fn_v_RdL0_SplitSectionName(szParams[0], szFileName, szSectionName, szParentName);
//				BOOL bUseTheSameFile = (1 == strlen (szFileName) && '*' == szFileName [0]);
//				if (bUseTheSameFile)
//					strcpy (szFileName, SCR_M_RdL0_GetFileNameR(0));
//				SCR_fn_v_RdL0_ComputeSectionName(szSectionName, szFileName, "SuperObject", szParentName);
				//End CPA2 Stegaru Cristian 98-02
//				csSectionName = szSectionName;
				//assume the final parent file is level\level.spo
				strcpy (szFileName, SCR_M_RdL0_GetFileNameR(0));
				CString csFileName (szFileName);
				int iPos = csFileName.ReverseFind ('.');
				ASSERT (-1 != iPos);
				csFileName = csFileName.Left (iPos) + szStaticExt;
				SCR_fn_v_RdL0_ComputeSectionName(szSectionName, (char*)(LPCSTR)csFileName, "SuperObject", szParentName);

				// get initial parent
				pEditor = pTempSO->GetOriginalSO()->GetSuperObjectEditor();
				pFather = (EDT_SuperObject *) pEditor->GetOrLoadSuperObject(szSectionName);
				//CPA2 Stegaru Cristian 98-02
				pTempSO->SetFinalFather(pFather);
				//End CPA2 Stegaru Cristian 98-02
			}
			// register initial position
			//CPA2 Stegaru Cristian 98-02
			if (strcmp(szName, "FinalMatrix") == 0)
				//End CPA2 Stegaru Cristian 98-02
			{
				p_stValue = SCR_fnp_st_RdL0_AnalyseSection(szParams[0], SCR_CDF_uw_Anl_Normal);
				hMatrix = (GEO_tdxHandleToMatrix) SCR_M_ul_RdL0_ExtractLongValue(p_stValue,0);
				//CPA2 Stegaru Cristian 98-02
				pTempSO->SetFinalPosition(hMatrix);
				//End CPA2 Stegaru Cristian 98-02
			}
			// register initial name
			if (strcmp(szName, "FinalName") == 0)
			{
				pTempSO->SetFinalName(szParams[0]);
			}
			break;

		case SCR_EA_Anl_EndSection:
			break;
	}

	return SCR_ERV_Anl_NormalReturn;
}

//#################################################################################
// DRAWING
//#################################################################################
	
/*===========================================================================
*		Description:	local flag
*		Creation date:
*		Author:			Shaitan
*---------------------------------------------------------------------------
*		Revision date:     Author:
*=========================================================================*/
void EDT_SuperObject::SetDrawingFlag (tdeDrawingFlag eNewFlag)
{
	CPA_SuperObject *pChild;
	EDT_SuperObject *pEdChild;
	
	// set flag
	CPA_SuperObjectBase::SetDrawingFlag(eNewFlag);
	// warn editor
	if (GetObject() != NULL)
		GetObjectDLL()->fn_vOnModifDrawFlag(this);
	// recursive function
	for (pChild = GetSuperObjectFirstChild(); pChild;
		 pChild = GetSuperObjectNextChild(pChild))
	{
		pEdChild = (EDT_SuperObject *) pChild;

		// edit-protected childs of super-object => same flag
		if ((pEdChild->GetSuperObjectOwner() == this) && (pEdChild->fn_bIsEditProtected()))
			pEdChild->SetDrawingFlag(eNewFlag);
	}
}


//#################################################################################
// MATRIX
//#################################################################################
	
/*===========================================================================
*		Description:	compare two matrix
*		Creation date:
*		Author:			Shaitan
*---------------------------------------------------------------------------
*		Revision date:     Author:
*=========================================================================*/
BOOL EDT_SuperObject::fn_bHasSamePosition (GEO_tdxHandleToMatrix hInitialMatrix, GEO_tdxHandleToMatrix hFinalMatrix)
{
	MTH3D_tdstVector stInitT, stFinalT; 
	MTH3D_tdstVector stInitI, stFinalI; 
	MTH3D_tdstVector stInitJ, stFinalJ; 
	MTH3D_tdstVector stInitK, stFinalK; 

	// check translation
	POS_fn_vGetTranslationVector(hInitialMatrix, &stInitT);
	POS_fn_vGetTranslationVector(hFinalMatrix, &stFinalT);
	if (!MTH3D_M_bEqualVector(&stInitT, &stFinalT))
		return FALSE;

	// check rotation
	POS_fn_vGetRotationMatrix(hInitialMatrix, &stInitI, &stInitJ, &stInitK);
	POS_fn_vGetRotationMatrix(hFinalMatrix, &stFinalI, &stFinalJ, &stFinalK);
	if ((!MTH3D_M_bEqualVector(&stInitI, &stFinalI)) ||
		(!MTH3D_M_bEqualVector(&stInitJ, &stFinalJ)) ||
		(!MTH3D_M_bEqualVector(&stInitK, &stFinalK)))
		return FALSE;

	// check scale
	POS_fn_vGetScaleMatrix (hInitialMatrix, &stInitI, &stInitJ, &stInitK);
	POS_fn_vGetScaleMatrix (hFinalMatrix, &stFinalI, &stFinalJ, &stFinalK);
	if ((!MTH3D_M_bEqualVector(&stInitI, &stFinalI)) ||
		(!MTH3D_M_bEqualVector(&stInitJ, &stFinalJ)) ||
		(!MTH3D_M_bEqualVector(&stInitK, &stFinalK)))
		return FALSE;

	// check transform
	POS_fn_vGetTransformMatrix (hInitialMatrix, &stInitI, &stInitJ, &stInitK);
	POS_fn_vGetTransformMatrix (hFinalMatrix, &stFinalI, &stFinalJ, &stFinalK);
	if ((!MTH3D_M_bEqualVector(&stInitI, &stFinalI)) ||
		(!MTH3D_M_bEqualVector(&stInitJ, &stFinalJ)) ||
		(!MTH3D_M_bEqualVector(&stInitK, &stFinalK)))
		return FALSE;

	// matrix are equal
	return TRUE;
}


//ANNECY CO SPOFLAG 03/02/98
//#################################################################################
// FLAG
//#################################################################################
	
/*===========================================================================
*		Description:	get or update super-object flag
*		Creation date:
*		Author:			Shaitan
*---------------------------------------------------------------------------
*		Revision date:     Author:
*=========================================================================*/
unsigned long EDT_SuperObject::GetFlags (void)
{
	return HIE_fn_SO_ulGetFlags(GetStruct());
}

void EDT_SuperObject::SetFlags (unsigned long ulFlags)
{
	unsigned long	ulOldFlag;

	ulOldFlag = HIE_fn_SO_ulGetFlags(GetStruct());

	HIE_fn_SO_vSetFlags(GetStruct(), ulFlags);

	if((((ulOldFlag & HIE_C_Flag_ulTypeOfBoundingVolume) ? TRUE : FALSE) &&
	    ((ulFlags & HIE_C_Flag_ulTypeOfBoundingVolume) ? FALSE : TRUE)) ||
	   (((ulOldFlag & HIE_C_Flag_ulTypeOfBoundingVolume) ? FALSE : TRUE) &&
	    ((ulFlags & HIE_C_Flag_ulTypeOfBoundingVolume) ? TRUE : FALSE)))
	{
// The Flag concerning the type of bounding volume has changed!
// We have to desallocate the old structure.
		GEO_M_CPAFree(GetStruct()->hBoundingVolume);
	}
	// if necessary, notify
	fn_vNotifySave();
}
//ENDANNECY CO SPOFLAG 

//ANNECY CO SPOFLAG 05/02/98
/*===========================================================================
*		Description:	check if super-object can be edited
*		Creation date:
*		Author:			Shaitan
*---------------------------------------------------------------------------
*		Revision date:     Author:
*=========================================================================*/
BOOL EDT_SuperObject::fn_bIsEditProtected (void)
{
	if (!CPA_SuperObject::fn_bIsEditProtected())
		return FALSE;
	else
	{
		if (GetSuperObjectEditor()->fn_bIsCurrentEditor())
			return !GetSuperObjectEditor()->GetInterface()->fn_bFullSelect();
		else
			return TRUE;
	}
}

//ENDANNECY CO SPOFLAG


//ANNECY Shaitan Transparency 26/03/98 {
/*===========================================================================
*		Description:	get the transparency level 
*		Creation date:
*		Author:			Shaitan
*---------------------------------------------------------------------------
*		Revision date:     Author:
*=========================================================================*/
float EDT_SuperObject::fn_fGetTransparencyLevel (void)
{
	return HIE_fn_fGetSuperObjectTransparenceLevel(GetStruct());
}

/*===========================================================================
*		Description:	set the transparency level 
*		Creation date:
*		Author:			Shaitan
*---------------------------------------------------------------------------
*		Revision date:     Author:
*=========================================================================*/
void  EDT_SuperObject::fn_vSetTransparencyLevel (float fNewLevel)
{
	HIE_fn_vSetSuperObjectTransparenceLevel(GetStruct(), fNewLevel);
	// for the actors
	if (GetObjectDLL())
		GetObjectDLL()->fn_vOnModifTransparency(this, fNewLevel);
	// for save
	fn_vNotifySave();
}
//ENDANNECY Shaitan Transparency }
#endif // ACTIVE_EDITOR
