/*=========================================================================
* 
* SECTelem.cpp :  Implementation of Editor Elements 
* 
*
* Version			1.0
* Creation date		
* Revision date
*
* Shaitan
*=======================================================================*/

#include "stdafx.h"
#include "acp_base.h"

#include "SECTint.hpp"

#include "DPT.h" 

//#################################################################################
// Element Base
//#################################################################################
SECT_ElementBase::SECT_ElementBase (Sector_Object *pOwnerSector)
	: CPA_SectionObject ("", fn_szGetLevelsDataPath(), SECT_ElementBase::CallBackSaveSectorsLink, 
						 pOwnerSector, pOwnerSector->fn_bHasSectorsLinkSection())
{
	// init owner
	m_pOwnerSector = pOwnerSector;
	// init section name
	SetReferencedSectionName(m_pOwnerSector->GetSectorsLinkSection());
}

/*===========================================================================
*		Description:	callback for save
*		Creation date:	
*		Author:			Shaitan
*---------------------------------------------------------------------------
*		Revision date:                                      Author:         
*=========================================================================*/
void SECT_ElementBase::CallBackSaveSectorsLink (SCR_tdst_File_Description *p_stFile, char *szSectionName, void *p_vData, SCR_tde_Ntfy_Action eAction)
{
	SECT_SoundEventElement	*pSoundEventElem;
	SECT_SndEvtEngineElem	*pEngineElem;
	SECT_CollisionElement	*pCollisionElem;
	SECT_ActivityElement	*pActivityElem;
	SECT_GraphicElement		*pGraphicElem;
	SECT_SoundElement		*pSoundElem;
	SECT_ElementBase		*pElem;
	Sector_Object			*pSector;
	POSITION				pos, pos1;
	CString					csReference, csSoundEvent;
	char					szNewSectionName[SCR_CV_ui_Cfg_MaxLenName];
	int						iSaveIndentLevel;

	// get sector
	pSector = (Sector_Object *) p_vData;

	switch (eAction)
    {
		case SCR_EA_Ntfy_AddSection:
		case SCR_EA_Ntfy_RebuildSection:
			// indent level
			iSaveIndentLevel = SCR_g_ui_SvL0_IndentationLevel;
			SCR_g_ui_SvL0_IndentationLevel = 1;
			// save begin section
			SCR_fn_v_RdL0_ComputeSectionName(szNewSectionName, NULL, C_szSectorsLinkSubSection, " ");
			SCR_M_SvL0_SaveBeginSection(p_stFile, szNewSectionName, SCR_CC_C_Cfg_EOL);
			// virtual
			if (pSector->fn_bIsVirtual())
			{
				SCR_M_SvL0_SaveEntry(p_stFile, "Virtual", SCR_CC_C_Cfg_EOL);
			}
			pSector->GetVirtualSection()->fn_vSectionSaved();
			// Zfar clipping
			if (pSector->GetZfarInSector() > MTH_C_ZERO)
			{
				SCR_M_SvL0_SaveEntry(p_stFile, "ZFar", SCR_CC_C_Cfg_NoChar);
				SCR_fn_v_SvL0_SaveParameters_MP(p_stFile, SCR_EF_SvL0_Scanf, 1, "%f", GLI_M_ValueToFloat(pSector->GetZfarInSector()));
			}
			// camera type
			SCR_M_SvL0_SaveEntry(p_stFile, "CameraType", SCR_CC_C_Cfg_NoChar);
			SCR_fn_v_SvL0_SaveParameters_MP(p_stFile, SCR_EF_SvL0_Scanf, 1, "%d", (int) pSector->GetCameraType());
			pSector->GetCameraSection()->fn_vSectionSaved();
			// priority
			SCR_M_SvL0_SaveEntry(p_stFile, "Priority", SCR_CC_C_Cfg_NoChar);
			SCR_fn_v_SvL0_SaveParameters_MP(p_stFile, SCR_EF_SvL0_Scanf, 1, "%d", (int) pSector->GetPriority());
			pSector->GetPrioritySection()->fn_vSectionSaved();
			// graphic list
			for (pGraphicElem = pSector->GetGraphicList()->GetHeadElement(pos); pGraphicElem;
				 pGraphicElem = pSector->GetGraphicList()->GetNextElement(pos))
			{
				csReference = pGraphicElem->GetSector()->GetReferencedSectionName();
				SCR_M_SvL0_SaveEntry(p_stFile, "AddLstGraphic", SCR_CC_C_Cfg_NoChar);
				SCR_fn_v_SvL0_SaveParameters_MP(p_stFile, SCR_EF_SvL0_Scanf, 1, "%s,%d,%d",
						(char *) (LPCSTR) csReference, pGraphicElem->GetGraphicLevel(), pGraphicElem->GetGraphicMode());
				pGraphicElem->fn_vSectionSaved();
			}
			// collision list
			for (pCollisionElem = pSector->GetCollisionList()->GetHeadElement(pos); pCollisionElem;
				 pCollisionElem = pSector->GetCollisionList()->GetNextElement(pos))
			{
				csReference = pCollisionElem->GetSector()->GetReferencedSectionName();
				SCR_M_SvL0_SaveEntry(p_stFile, "AddLstCollision", SCR_CC_C_Cfg_NoChar);
				SCR_fn_v_SvL0_SaveParameters_MP(p_stFile, SCR_EF_SvL0_Scanf, 1, "%s,0", 
						(char *) (LPCSTR) csReference);
				pCollisionElem->fn_vSectionSaved();
			}
			// activity list
			for (pActivityElem = pSector->GetActivityList()->GetHeadElement(pos); pActivityElem;
				 pActivityElem = pSector->GetActivityList()->GetNextElement(pos))
			{
				csReference = pActivityElem->GetSector()->GetReferencedSectionName();
				SCR_M_SvL0_SaveEntry(p_stFile, "AddLstActivity", SCR_CC_C_Cfg_NoChar);
				SCR_fn_v_SvL0_SaveParameters_MP(p_stFile, SCR_EF_SvL0_Scanf, 1, "%s,0", 
						(char *) (LPCSTR) csReference);
				pActivityElem->fn_vSectionSaved();
			}
			// sound list
			for (pSoundElem = pSector->GetSoundList()->GetHeadElement(pos); pSoundElem;
				 pSoundElem = pSector->GetSoundList()->GetNextElement(pos))
			{
				csReference = pSoundElem->GetSector()->GetReferencedSectionName();
				SCR_M_SvL0_SaveEntry(p_stFile, "AddLstSound", SCR_CC_C_Cfg_NoChar);
				SCR_fn_v_SvL0_SaveParameters_MP(p_stFile, SCR_EF_SvL0_Scanf, 1, "%s,%d,0", 
						(char *) (LPCSTR) csReference, pSoundElem->GetSoundLevel());
				pSoundElem->fn_vSectionSaved();
			}
			// sound event list
			for (pElem = pSector->GetSoundEventList()->GetHeadElementBase(pos); pElem;
				 pElem = pSector->GetSoundEventList()->GetNextElementBase(pos))
			{
				// get sound event element
				pSoundEventElem = (SECT_SoundEventElement *) pElem;
				if (pSoundEventElem->GetSector())
					csReference = pSoundEventElem->GetSector()->GetReferencedSectionName();
				else
					csReference = "FromAllSectors";
				// save all sound events
				for (pEngineElem = pSoundEventElem->GetSndEvtList()->GetHeadElement(pos1); pEngineElem;
					 pEngineElem = pSoundEventElem->GetSndEvtList()->GetNextElement(pos1))
				{
					// get references
					csSoundEvent = pEngineElem->GetSoundEventReference();
					// save element
					SCR_M_SvL0_SaveEntry(p_stFile, "AddLstSoundEvent", SCR_CC_C_Cfg_NoChar);
					SCR_fn_v_SvL0_SaveParameters_MP(p_stFile, SCR_EF_SvL0_Scanf, 1, "%s,%s", 
							(char *) (LPCSTR) csReference, (char *) (LPCSTR) csSoundEvent);
				}
				pSoundEventElem->fn_vSectionSaved();
			}

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

			// indent level
			SCR_g_ui_SvL0_IndentationLevel = iSaveIndentLevel;
			// reinit super-object
			pSector->SetExistingSectorsLinkSection(TRUE);
			break;

		case SCR_EA_Ntfy_DeleteSection:
			// reinit super-object
			pSector->SetExistingSectorsLinkSection(FALSE);
			// virtual
			pSector->GetVirtualSection()->fn_vSectionDeleted();
			// camera
			pSector->GetCameraSection()->fn_vSectionDeleted();
			// priority
			pSector->GetPrioritySection()->fn_vSectionDeleted();
			// graphic list
			for (pGraphicElem = pSector->GetGraphicList()->GetHeadElement(pos); pGraphicElem;
				 pGraphicElem = pSector->GetGraphicList()->GetNextElement(pos))
				pGraphicElem->fn_vSectionDeleted();
			// collision list
			for (pCollisionElem = pSector->GetCollisionList()->GetHeadElement(pos); pCollisionElem;
				 pCollisionElem = pSector->GetCollisionList()->GetNextElement(pos))
				pCollisionElem->fn_vSectionDeleted();
			// activity list
			for (pActivityElem = pSector->GetActivityList()->GetHeadElement(pos); pActivityElem;
				 pActivityElem = pSector->GetActivityList()->GetNextElement(pos))
				pActivityElem->fn_vSectionDeleted();
			// sound list
			for (pSoundElem = pSector->GetSoundList()->GetHeadElement(pos); pSoundElem;
				 pSoundElem = pSector->GetSoundList()->GetNextElement(pos))
				pSoundElem->fn_vSectionDeleted();
			// sound event list
			for (pElem = pSector->GetSoundEventList()->GetHeadElementBase(pos); pElem;
				 pElem = pSector->GetSoundEventList()->GetNextElementBase(pos))
			{
				// get sound event element
				pSoundEventElem = (SECT_SoundEventElement *) pElem;
				pSoundEventElem->fn_vSectionDeleted();
			}
			break;
	}
}


//#################################################################################
// List Base
//#################################################################################

SECT_ListBase::SECT_ListBase (void)
{
	// init owner
	m_pOwnerSector = NULL;
	// init nb elements
	m_lNbElements = 0;
}

/*===========================================================================
	Add Element
===========================================================================*/
BOOL SECT_ListBase::fn_bAddAnElement (SECT_ElementBase *pNewElem, BOOL bUpdateEngine)
{
	// check owner sector
	if (pNewElem->GetOwnerSector() != m_pOwnerSector)
		return FALSE;
	// check linked sector
	if (pNewElem->GetSector() && (pNewElem->GetSector()->GetObject() == m_pOwnerSector))
		return FALSE;
	
	// update nb elements
	m_lNbElements++;
	// update links
	g_oCoherenceManager.m_fn_vAddALink(m_pOwnerSector, pNewElem->GetSector());
	return TRUE;
}


/*===========================================================================
	Remove Element
===========================================================================*/
void SECT_ListBase::fn_vRemoveAnElement (SECT_ElementBase *pOldElem, BOOL bUpdateEngine)
{
	// update nb elements
	m_lNbElements--;
	// update links
	g_oCoherenceManager.m_fn_vRemoveALink(m_pOwnerSector, pOldElem->GetSector());
}

/*===========================================================================
	Remove All Elements
===========================================================================*/
void SECT_ListBase::fn_vRemoveAllElements (BOOL bUpdateEngine)
{
	// update nb elements
	m_lNbElements = 0;
}

/*===========================================================================
	Get Element With Sector
===========================================================================*/
SECT_ElementBase * SECT_ListBase::GetElementWithSector (CPA_SuperObject *pSector)
{
	SECT_ElementBase	*pElem;
	POSITION			pos;
	
	// search all element in list
	for (pElem = GetHeadElementBase(pos); pElem; pElem = GetNextElementBase(pos))
	{
		if (pElem->GetSector() == pSector)
			return pElem;
	}
	
	// sector was not found
	return NULL;
}



//#################################################################################
// Environment Element Base
//#################################################################################

/*
SECT_EnvElementBase::SECT_EnvElementBase (Sector_Object *pOwnerSector)
	: CPA_SectionObject ("", fn_szGetLevelsDataPath(), SECT_EnvElementBase::CallBackSaveEnvAndSurf, 
						 pOwnerSector, pOwnerSector->fn_bHasEnvAndSurfSection())
{
	// init owner
	m_pOwnerSector = pOwnerSector;
	// init section name
	SetReferencedSectionName(m_pOwnerSector->GetEnvAndSurfSection());
}
*/

/*===========================================================================
*		Description:	callback for save
*		Creation date:	
*		Author:			Shaitan
*---------------------------------------------------------------------------
*		Revision date:                                      Author:         
*=========================================================================*/
/*
void SECT_EnvElementBase::CallBackSaveEnvAndSurf (SCR_tdst_File_Description *p_stFile, char *szSectionName, void *p_vData, SCR_tde_Ntfy_Action eAction)
{
	Sector_Object			*pSector;
	SECT_SurfElem			*pSurfElem;
	SECT_EnvElem			*pEnvElem;
	POSITION				pos;
	CString					csReference;
	char					szNewSectionName[SCR_CV_ui_Cfg_MaxLenName];
	int						iSaveIndentLevel;

	// get sector
	pSector = (Sector_Object *) p_vData;

	switch (eAction)
    {
		case SCR_EA_Ntfy_AddSection:
		case SCR_EA_Ntfy_RebuildSection:
			// indent level
			iSaveIndentLevel = SCR_g_ui_SvL0_IndentationLevel;
			SCR_g_ui_SvL0_IndentationLevel = 1;
			// save begin section
			SCR_fn_v_RdL0_ComputeSectionName(szNewSectionName, NULL, C_szEnvAndSurfSubSection, " ");
			SCR_M_SvL0_SaveBeginSection(p_stFile, szNewSectionName, SCR_CC_C_Cfg_EOL);
			// environment list
			for (pEnvElem = pSector->GetEnvironmentList()->GetHeadElement(pos); pEnvElem;
				 pEnvElem = pSector->GetEnvironmentList()->GetNextElement(pos))
			{
				csReference = pEnvElem->GetEnvironment()->GetReferencedSectionName();
				SCR_M_SvL0_SaveEntry(p_stFile, "AddLstEnvironment", SCR_CC_C_Cfg_NoChar);
				SCR_fn_v_SvL0_SaveParameters_MP(p_stFile, SCR_EF_SvL0_Scanf, 1, "%s", 
						(char *) (LPCSTR) csReference);
				pEnvElem->fn_vSectionSaved();
			}
			// surface list
			for (pSurfElem = pSector->GetSurfaceList()->GetHeadElement(pos); pSurfElem;
				 pSurfElem = pSector->GetSurfaceList()->GetNextElement(pos))
			{
				csReference = pSurfElem->GetSurface()->GetReferencedSectionName();
				SCR_M_SvL0_SaveEntry(p_stFile, "AddLstSurface", SCR_CC_C_Cfg_NoChar);
				SCR_fn_v_SvL0_SaveParameters_MP(p_stFile, SCR_EF_SvL0_Scanf, 1, "%s", 
						(char *) (LPCSTR) csReference);
				pSurfElem->fn_vSectionSaved();
			}

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

			// indent level
			SCR_g_ui_SvL0_IndentationLevel = iSaveIndentLevel;
			// reinit super-object
			pSector->SetExistingEnvAndSurfSection(TRUE);
			break;

		case SCR_EA_Ntfy_DeleteSection:
			// reinit super-object
			pSector->SetExistingEnvAndSurfSection(FALSE);
			// environment list
			for (pEnvElem = pSector->GetEnvironmentList()->GetHeadElement(pos); pEnvElem;
				 pEnvElem = pSector->GetEnvironmentList()->GetNextElement(pos))
				pEnvElem->fn_vSectionDeleted();
			// surface list
			for (pSurfElem = pSector->GetSurfaceList()->GetHeadElement(pos); pSurfElem;
				 pSurfElem = pSector->GetSurfaceList()->GetNextElement(pos))
				pSurfElem->fn_vSectionDeleted();
			break;

	}
}
*/

