/*=========================================================================
* 
* SECTsurf.cpp :  Implementation of Editor Surface Lists  
* 
*
* Version			1.0
* Creation date		
* Revision date
*
* Shaitan
*=======================================================================*/

/*
#include "stdafx.h"
#include "acp_base.h"

#define SRF_FRIEND
#define SRF_MAIN

#include "SECTint.hpp"

#include "DPT.h"

#undef SRF_MAIN
#undef SRF_FRIEND

#include "SRF\SRF_Fct.h"

DeclareTemplateStatic(SCT_tdxHandleOfElementLstSurface); 
DeclareTemplateStatic(SRF_tdxHandleToSurface);

static long NbSurf = 0;

//#################################################################################
// Surface 
//#################################################################################

/===========================================================================
	Default Constructor
===========================================================================/
SECT_Surface::SECT_Surface (Sector_Interface *p_oDLL,
							SRF_tdxHandleToSurface hSurface, BOOL bAvailable,
							CString csName, CString csFileName)
	: CPA_SaveObject(p_oDLL, C_szSurfaceTypeName, E_ss_Responsible, NULL, bAvailable, 
					 fn_szGetLevelsDataPath(), SECT_Surface::CallBackSaveSurfaceMatrix),
	  CPA_EdMot<SRF_tdxHandleToSurface>(hSurface)
{
	ACP_tdxHandleOfObject	hVisual;
	CPA_DLLBase				*pGeomDLL;
	CString					csVisualName, csSuperObjectName;
	char					szSectionName[SCR_CV_ui_Cfg_MaxLenName];

	// section object
	SetSectionData(this); 	
	// section name
	SCR_fn_v_RdL0_ComputeSectionName(szSectionName, (char *)(LPCSTR)csFileName, C_szSurfaceActionName, " ");
	SetReferencedSectionName(szSectionName);

	// matrix section
	m_pMatrixSection = new CPA_SectionObject (GetMatrixSectionName(), fn_szGetLevelsDataPath(), 
										  SECT_Surface::CallBackSaveSurfaceMatrix,
										  this, TRUE);

	// create editor visual
	hVisual = SRF_M_hGetVisualOfSurface(GetStruct());
	pGeomDLL = p_oDLL->GetMainWorld()->GetObjectDLLWithName(C_szDLLGeometryName);
	m_pVisualSurface = (CPA_BaseObject *) pGeomDLL->OnQueryAction(p_oDLL, C_uiCreateGeometricObject, (long) hVisual);
	// create visual super-object
	csVisualName = "SPO_Visual" + csName;
	m_pVisualSuperObject = p_oDLL->GetInterface()->GetNewSuperObject(E_ss_NoSave, C_Dynamic, csVisualName, "");
	m_pVisualSuperObject->SetObject(m_pVisualSurface);
	HIE_fn_vSetSuperObjectMatrix(m_pVisualSuperObject->GetStruct(), SRF_M_hGetPositionOfSurface(GetStruct()));
	// name
	if (fn_eRename(csName ) != E_mc_None)
		SetDefaultValidName();
	fn_vUpdateSectionName();

	// create super-object
	csSuperObjectName = "SPO_" + GetName();
	m_pSuperObject = p_oDLL->GetInterface()->GetNewSuperObject(E_ss_NoSave, C_Dynamic, csSuperObjectName, "");
	m_pSuperObject->SetObject(this);
	// update hierarchy
	m_pSuperObject->AddANewChild(m_pVisualSuperObject);
	m_pVisualSuperObject->SetSuperObjectOwner(m_pSuperObject);

	// existence
	SetExistingSection(TRUE);
}


/===========================================================================
	Destructor
===========================================================================/
SECT_Surface::~SECT_Surface (void)
{

}

/===========================================================================
	Matrix 
===========================================================================/
CString SECT_Surface::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];
	
	// get corresponding section
	SCR_fn_v_RdL0_SplitSectionName((char*)(LPCSTR) GetReferencedSectionName(), szFileName, szActionName, szName);
	SCR_fn_v_RdL0_ComputeSectionName(szSectionName, szFileName, "Matrix", szName);
	csSectionName = szSectionName;

	return csSectionName;
}

/===========================================================================
	Height (Get)
===========================================================================/
MTH_tdxReal SECT_Surface::GetHeight (void)
{
   // get engine height
	return SRF_fn_xGetSurfaceHeight(GetStruct());
}


/===========================================================================
	Height (Set)
===========================================================================/
void SECT_Surface::SetHeight (MTH_tdxReal xNewHeight)
{
	MTH3D_tdstVector stSurfacePos;

	// update engine height
	SRF_fn_vSetSurfaceHeight(GetStruct(), xNewHeight);
	// set initial height
	POS_fn_vGetTranslationVector(SRF_M_hGetPositionOfSurface(GetStruct()), &stSurfacePos);
	POS_fn_vSetTranslationVector(SRF_M_hGetInitPositionOfSurface(GetStruct()), &stSurfacePos);
	// update visual super-object
	HIE_fn_vSetSuperObjectMatrix(m_pVisualSuperObject->GetStruct(), SRF_M_hGetPositionOfSurface(GetStruct()));
	// notify the change
	fn_vNotifySave();
}

//#################################################################################
// Save
//#################################################################################

/===========================================================================
	Update Section Name
=========================================================================/
void SECT_Surface::fn_vUpdateSectionName (void)
{
	// update main section
	CPA_SaveObject::fn_vUpdateSectionName();
	// update matrix section
	m_pMatrixSection->SetReferencedSectionName(GetMatrixSectionName());
}
/===========================================================================
	Notifications
=========================================================================/

void SECT_Surface::fn_vNotifySave (void)
{
	// matrix section
	m_pMatrixSection->fn_vWriteSection();
}
//===========================================================================

void SECT_Surface::fn_vNotifyUnSave	(void)
{
	// matrix section
	m_pMatrixSection->fn_vDeleteSection();
}
//===========================================================================

void SECT_Surface::fn_vNotifyRestore	(void)
{
	// matrix section
	m_pMatrixSection->fn_vRestoreSection();
}
//===========================================================================

void SECT_Surface::fn_vNotifyRename	(void)
{
	// matrix section
	m_pMatrixSection->fn_vRenameSection(GetMatrixSectionName());
}

/*===========================================================================
*		Description:	CallBack Save for matrix
*		Creation date:
*		Author:			Shaitan
*---------------------------------------------------------------------------
*		Revision date:     Author:
*=========================================================================*/
/*
void SECT_Surface::CallBackSaveSurfaceMatrix (SCR_tdst_File_Description *p_stFile, char *szSectionName, void *p_vData, SCR_tde_Ntfy_Action eAction)
{
	GEO_tdxHandleToMatrix	hMatrix;
	MTH3D_tdstVector		stVecI,stVecJ,stVecK;
	SECT_Surface			*pSurface;
	CString					csName;
	double					dUnit;
	char					szNewSectionName[SCR_CV_ui_Cfg_MaxLenName];
	char					szMatrixName[SCR_CV_ui_Cfg_MaxLenName];
	char					szName[SCR_CV_ui_Cfg_MaxLenName];
	
	
	// get parameters
	pSurface = (SECT_Surface *) p_vData;

	dUnit = GLI_dGetUnitInMeterInFile(NULL);
	if (dUnit == 0)
		dUnit = 1;

	switch (eAction)
    {
		case SCR_EA_Ntfy_RebuildSection:
			// corresponding matrix
			hMatrix = SRF_M_hGetPositionOfSurface(pSurface->GetStruct());
			// get section name
			SCR_fn_v_RdL0_SplitSectionName(szSectionName, NULL, szNewSectionName, szName);
			strcpy(szMatrixName, szName);
			
			// save begin section
			SCR_fn_v_RdL0_ComputeSectionName(szNewSectionName, NULL, "Matrix", szMatrixName);
			SCR_M_SvL0_SaveBeginSection(p_stFile, szNewSectionName, 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);
			// update section object
			pSurface->fn_vSectionSaved();
			pSurface->GetMatrixSection()->fn_vSectionSaved();
			break;
	}
}



//#################################################################################
// Surface Element
//#################################################################################

/===========================================================================
	Default Constructor
===========================================================================/
SECT_SurfElem::SECT_SurfElem (SCT_tdxHandleOfElementLstSurface hSurfElem, Sector_Object *pOwnerSector)
	: CPA_EdMot<SCT_tdxHandleOfElementLstSurface>(hSurfElem),
	  SECT_EnvElementBase (pOwnerSector)
{
	SRF_tdxHandleToSurface hSurface;

	// init environment
	hSurface = SCT_GetSurfaceInList(hSurfElem);
	m_pSurface = pOwnerSector->GetSectorInterface()->GetOrBuildSurface(hSurface);
}


/===========================================================================
	New Constructor
===========================================================================/
SECT_SurfElem::SECT_SurfElem  (SECT_Surface *pSurface, Sector_Object *pOwnerSector)
	: CPA_EdMot<SCT_tdxHandleOfElementLstSurface>(),
	  SECT_EnvElementBase (pOwnerSector)
{
	// init environment
	m_pSurface = pSurface;
	SCT_fn_vSetHandleOfSurfaceInSurfaceList(GetStruct(), m_pSurface->GetStruct());
}

/===========================================================================
	Destructor
===========================================================================/
SECT_SurfElem::~SECT_SurfElem (void)
{

}


/===========================================================================
	Surface
===========================================================================/
void SECT_SurfElem::SetSurface (SECT_Surface *pSurface)
{
	// if there was a surface, warn coherence manager
	if ((m_pSurface)&&(m_pOwnerSector))
		g_oCoherenceManager.m_fn_vRemoveALink(m_pOwnerSector, m_pSurface);

	// set environment
	m_pSurface = pSurface;
	// update engine element
	SCT_fn_vSetHandleOfSurfaceInSurfaceList(GetStruct(), m_pSurface->GetStruct());
	// warn coherence manager
	if (m_pOwnerSector)
		g_oCoherenceManager.m_fn_vAddALink(m_pOwnerSector, m_pSurface);
	// notify modif
	if (g_bCanSave)
		fn_vWriteSection();
}



//#################################################################################
// Surface List
//#################################################################################

/===========================================================================
	Add Surface Element
===========================================================================/
BOOL SECT_SurfaceList::fn_bAddAnElement	(SECT_SurfElem *pNewElem, SECT_SurfElem *pPreviousElem, BOOL bUpdateEngine)
{
	POSITION pos;
	
	// check element owner
	if (pNewElem->GetOwnerSector() != m_pOwnerSector)
		return FALSE;
	
	// no previous element => add head
	if (!pPreviousElem)
		AddHead(pNewElem, bUpdateEngine);
	// previous element => add at corresponding position
	else
	{
		pos = Find(pPreviousElem, NULL);
		InsertAfter(pos, pNewElem, bUpdateEngine);
	}
	// warn coherence manager
	g_oCoherenceManager.m_fn_vAddALink(m_pOwnerSector, pNewElem->GetSurface());
	return TRUE;
}


/===========================================================================
	Remove Surface Element
===========================================================================/
void SECT_SurfaceList::fn_vRemoveAnElement (SECT_SurfElem *pOldElem, BOOL bUpdateEngine)
{
	POSITION pos;
	
	// add element to the list
	pos = Find(pOldElem, NULL);
	if (pos)
		RemoveAt(pos, bUpdateEngine);
	// warn coherence manager
	g_oCoherenceManager.m_fn_vRemoveALink(m_pOwnerSector, pOldElem->GetSurface());
}

/===========================================================================
	Remove All Elements
===========================================================================/
void SECT_SurfaceList::fn_vRemoveAllElements (BOOL bUpdateEngine)
{
	SECT_SurfElem  *pElem;
	
	while (GetCount() > 0)
	{
		pElem = RemoveTail(bUpdateEngine);
		g_oCoherenceManager.m_fn_vRemoveALink(m_pOwnerSector, pElem->GetSurface());
	}
}
/===========================================================================
	Find Surface Element
===========================================================================/
SECT_SurfElem * SECT_SurfaceList::GetElementWithSurface (SECT_Surface *pSurface)
{
	SECT_SurfElem	*pElem;
	POSITION		pos;
	
	// check every element
	for (pElem = GetHeadElement(pos); pElem; pElem = GetNextElement(pos))
	{
		if (pElem->GetSurface() == pSurface)
			return pElem;
	}
	// element was not found
	return NULL;
}

/===========================================================================
	Find Previous Surface Element
===========================================================================/
long SECT_SurfaceList::GetInsertPosition (SECT_SurfElem *pSurfElem)
{
	SECT_SurfElem	*pElem;
	POSITION		pos;
	long			lPosition = 0;

	// check every element
	for (pElem = GetHeadElement(pos); pElem; pElem = GetNextElement(pos))
	{
		if (pElem->GetSurface()->GetHeight() <=  pSurfElem->GetSurface()->GetHeight())
			return lPosition;
		lPosition++;
	}
	// element was not found
	return GetCount();
}

/===========================================================================
	Find Surface Element
===========================================================================/
long SECT_SurfaceList::GetCurrentPosition (SECT_SurfElem *pSurfElem)
{
	SECT_SurfElem	*pElem;
	POSITION		pos;
	long			lPosition = 0;

	// check every element
	for (pElem = GetHeadElement(pos); pElem; pElem = GetNextElement(pos))
	{
		if (pElem == pSurfElem)
			return lPosition;
		lPosition++;
	}
	// element was not found
	return -1;
}
*/