/*=========================================================================
* 
* edit_ot.cpp :  ObjectTable Editor Object - inplementation
* 
* Version			2.0
* Creation date		06/06/97	Author : Vincent Lhullier	
* Revision date		18/08/97	Author : Shaitan	
*
* Shaitan
*=======================================================================*/

#define D_ObjsTbls_Define
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
#include "stdafx.h"
#include "acp_base.h"

#include "TFA.h"

#include "incGAM.h"
#include "ITF.h"
#include "incPO.h"
#include "incOPD.h"
#include "TOT.h"
#include "OT_inter.hpp"
#include "incGam.h"
#include "DPT.h"

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
#undef D_ObjsTbls_Define

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
DeclareTemplateStatic( tdxHandleToObjectsTablesList ); 
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

void del(tdxHandleToObjectsTablesList h)
{
}



/*===========================================================================
*		Description:	Static init (engine struct)
*		Creation date:	06/06/97	
*		Author:			Vincent Lhullier
*---------------------------------------------------------------------------
*		Revision date:					Author:         
*=========================================================================*/
void EditorObjectTable::StaticInit()
{
	CPA_EdMot<tdxHandleToObjectsTablesList>::Init(NULL,NULL,del);
}

/*===========================================================================
*		Description:	Constructor
*		Creation date:	06/06/97	
*		Author:			Vincent Lhullier
*---------------------------------------------------------------------------
*		Revision date:	18/08/97		Author: Shaitan        
*		Revision date:  05/09/97		Author: Vincent Lhullier
*=========================================================================*/
EditorObjectTable::EditorObjectTable (CPA_EditorBase				*p_oDLL, 
									  tdxHandleToObjectsTablesList	hObjTable, 
									  CPA_SaveObject				*p_oOwner,
									  CString						csFileName)

	: CPA_SaveObject (p_oDLL,						// owner editor
					  C_szObjectTableTypeName,		// type
					  E_ss_NoSave,					// status
					  p_oOwner,						// owner
					  (hObjTable != NULL),			// validity
					  fn_szGetFamiliesDataPath(),	// data path
					  NULL							// callback for save
					  ),

	  CPA_EdMot<tdxHandleToObjectsTablesList> (hObjTable)

{
	unsigned short	uwIndex;
	//unsigned short	uwEndName;
	CString			csName;

	// section object
	SetSectionData(this); 	
	// section name
	SetReferencedSectionName(csFileName);

	// name
	uwIndex = csFileName.ReverseFind('\\');
	csName = csFileName.Mid(uwIndex + 1);
	
	if (fn_eRename(csName) != E_mc_None)
		SetDefaultValidName();
	
	fn_vUpdateSectionName();

	// existence
	SetExistingSection(TRUE);

	// validity
	if (hObjTable != NULL)
	{
// Shaitan => module list in the level
		fn_vLoadUnusedPOsInObjectTable();
// End Shaitan => module list in the level	
		fn_vCreateEditorPhysicalObjects();
	}

	SetAvailable(hObjTable!=NULL);
};
	

/*===========================================================================
*		Description:	Destructor
*		Creation date:	06/06/97	
*		Author:			Vincent Lhullier
*---------------------------------------------------------------------------
*		Revision date:					Author:		     
*=========================================================================*/
EditorObjectTable::~EditorObjectTable()
{
}


/*===========================================================================
*		Description:	Section Name
*						 => FamilyName / Name.TBL 
*		Creation date:	18/08/97	
*		Author:			Shaitan
*---------------------------------------------------------------------------
*		Revision date:	05/09/97		Author: Vincent Lhullier
*=========================================================================*/
void EditorObjectTable::fn_vUpdateSectionName (void)
{
	CString csSectionName, csFileName;
	int		iPos;
	
	// get old section name
	csSectionName = GetReferencedSectionName();
	// build new section name
	iPos = csSectionName.ReverseFind('\\');
	csFileName = csSectionName.Left(iPos+1) + GetName(); // + ".tbl";
	// set new section name
	SetReferencedSectionName(csFileName);
}


/*===========================================================================
*		Description:	Name for dialogs
*						 => FamilyName + Name 
*		Creation date:	18/08/97	
*		Author:			Shaitan
*---------------------------------------------------------------------------
*		Revision date:					Author:		       
*=========================================================================*/
CString EditorObjectTable::GetNameToDraw (void)
{	
	CString csName;
	
	csName = (GetOwner()) ? GetOwner()->GetName() : "Unknown";
	csName += "   " + GetName();
	
	return csName;
}


/*===========================================================================
*		Description:	Create all editor POs
*		Creation date:	06/06/97	
*		Author:			Vincent Lhullier
*---------------------------------------------------------------------------
*		Revision date:					Author:		     
*=========================================================================*/
void EditorObjectTable::fn_vCreateEditorPhysicalObjects( void )
{
	PO_tdxHandleToPhysicalObject	hPO;
	CPA_ObjectDLLBase				*p_oDLLPO;
	tdxHandleToObjectsTableElement	hOTElement;
	EditorPO						*p_oPO;
	unsigned short					uwIndex;

	//  Get Physical object DLL 
	p_oDLLPO = GetMainWorld()->GetObjectDLLWithName(C_szDLLPhysicalObjectName);

	if (p_oDLLPO != NULL)
	{
        // First pass
		for (uwIndex = 0 ; uwIndex < GetStruct()->wNumberOfElement; uwIndex ++)
		{
			hOTElement = fn_d_hGetElementByNumberInObjectsTable( GetStruct(), uwIndex );
			// for each po in the object table, create a editor po
			if (fn_wObjectsTableGetTypeOfTarget( hOTElement ) == C_wTdO_PhysicalObject )
			{
				hPO = (PO_tdxHandleToPhysicalObject) fn_hObjectsTableGetTarget( hOTElement );
				if (hPO == NULL)
					p_oPO = NULL;
				else
				{
					p_oPO = (EditorPO *) p_oDLLPO->OnQueryAction( (CPA_DLLBase *) this, OPD_ActionEncapsulateObject, (LPARAM) hPO );
					// update Index
					if (p_oPO)
						p_oPO -> m_fn_vSetIndexInObjectTable( uwIndex );
				}
			}
		}

        // Second pass
		for (uwIndex = 0 ; uwIndex < GetStruct()->wNumberOfElement; uwIndex ++)
		{
			hOTElement = fn_d_hGetElementByNumberInObjectsTable( GetStruct(), uwIndex );
			// for each po in the object table, create a editor po
			if (fn_wObjectsTableGetTypeOfTarget( hOTElement ) == C_wTdO_PhysicalObject )
			{
				hPO = (PO_tdxHandleToPhysicalObject) fn_hObjectsTableGetTarget( hOTElement );
				p_oDLLPO->OnQueryAction( (CPA_DLLBase *) this, OPD_ActionSecondPass, (LPARAM) hPO );
			}
		}
	}

}

// Shaitan => module list in the level
/*===========================================================================
*		Description:	Load unused POs of the object table
*		Creation date:		
*		Author:			
*---------------------------------------------------------------------------
*		Revision date:					Author:		     
*=========================================================================*/
void EditorObjectTable::fn_vLoadUnusedPOsInObjectTable( void )
{
	SCR_tdst_Anl_Callback *pCallback;

	// if the engine object table is not created, it will be loaded as usual
	if (!GetStruct())
		return;
	// if the family is not optimized, no need to reload
	CPA_Family * pFamily = (CPA_Family *) GetOwner();
	if (((tdxHandleToFamilyList) pFamily->GetStruct())->ucOptimized == 0)
		return;
	
	// first get the engine callback functions for tbl file
	pCallback = SCR_fnp_st_RdL0_GetRegisterCallback(C_Section_TBLHeader, SCR_CRC_c_RdL0_ForSection);
	SCR_tdpfn_Anl_Callback pHeaderCallback = pCallback->pfn_eCallback;										
	pCallback = SCR_fnp_st_RdL0_GetRegisterCallback(C_Section_TBLGeneral, SCR_CRC_c_RdL0_ForSection);
	SCR_tdpfn_Anl_Callback pTBLCallback = pCallback->pfn_eCallback;										
	pCallback = SCR_fnp_st_RdL0_GetRegisterCallback(C_Section_EVTGeneral, SCR_CRC_c_RdL0_ForSection);
	SCR_tdpfn_Anl_Callback pEVTCallback = pCallback->pfn_eCallback;
	// then unregister them
	SCR_fn_v_RdL0_DeleteRegisterCallback(C_Section_TBLHeader, SCR_CRC_c_RdL0_ForSection, SCR_CDR_c_RdL0_Match);
	SCR_fn_v_RdL0_DeleteRegisterCallback(C_Section_TBLGeneral, SCR_CRC_c_RdL0_ForSection, SCR_CDR_c_RdL0_Match);
	SCR_fn_v_RdL0_DeleteRegisterCallback(C_Section_EVTGeneral, SCR_CRC_c_RdL0_ForSection, SCR_CDR_c_RdL0_Match);
	// register the new callback
	SCR_fn_v_RdL0_RegisterCallback(C_Section_TBLHeader, m_fn_tdeEmtpyCallBack,SCR_CRC_c_RdL0_ForSection);
	SCR_fn_v_RdL0_RegisterCallback(C_Section_TBLGeneral, m_fn_tdeCallBackLoadUnusedPOs,SCR_CRC_c_RdL0_ForSection);
	SCR_fn_v_RdL0_RegisterCallback(C_Section_EVTGeneral,m_fn_tdeEmtpyCallBack,SCR_CRC_c_RdL0_ForSection);

	// then force the script to analyze the section
	SCR_M_RdL0_SetContextLong(C_GrandChildContext,0,GetStruct());
	SCR_fnp_st_RdL0_AnalyseSection((char *)(LPCTSTR) GetReferencedSectionName(), SCR_CDF_uw_Anl_ForceAnalyse);

	// unregister the editor callback
	SCR_fn_v_RdL0_DeleteRegisterCallback(C_Section_TBLHeader, SCR_CRC_c_RdL0_ForSection, SCR_CDR_c_RdL0_Match);
	SCR_fn_v_RdL0_DeleteRegisterCallback(C_Section_TBLGeneral, SCR_CRC_c_RdL0_ForSection, SCR_CDR_c_RdL0_Match);
	SCR_fn_v_RdL0_DeleteRegisterCallback(C_Section_EVTGeneral, SCR_CRC_c_RdL0_ForSection, SCR_CDR_c_RdL0_Match);
	// restore the normal loading function
	SCR_fn_v_RdL0_RegisterCallback(C_Section_TBLHeader, pHeaderCallback,SCR_CRC_c_RdL0_ForSection);
	SCR_fn_v_RdL0_RegisterCallback(C_Section_TBLGeneral, pTBLCallback,SCR_CRC_c_RdL0_ForSection);
	SCR_fn_v_RdL0_RegisterCallback(C_Section_EVTGeneral, pEVTCallback,SCR_CRC_c_RdL0_ForSection);
}
// End Shaitan => module list in the level	


/*===========================================================================
*		Description:	Load engine struct 
*		Creation date:	06/06/97	
*		Author:			Vincent Lhullier
*---------------------------------------------------------------------------
*		Revision date:	18/08/97		Author:	Shaitan	     
*=========================================================================*/
void EditorObjectTable::fn_vLoadEngineObjectTable (void)
{
	SCR_tdst_Cxt_Values				*p_stVal;
	tdxHandleToObjectsTablesList	hOT;
	BOOL							bIsLoadingWorld;

    if (!fn_bIsAvailable())
	{
		// loading flag
		bIsLoadingWorld = GetEditor()->GetInterface()->fn_bIsLoadingWorld();
		GetEditor()->GetInterface()->SetLoadingWorld( TRUE );

// Shaitan => module list in the level	
		// make sure that all POs will be loaded !
		CPA_Family * pFamily = (CPA_Family *) GetOwner();
		((tdxHandleToFamilyList) pFamily->GetStruct())->ucOptimized = 0;
// End Shaitan => module list in the level	

		// load engine struct
		p_stVal = SCR_fnp_st_RdL0_AnalyseSection( (char *)(LPCTSTR) GetReferencedSectionName(), SCR_CDF_uw_Anl_Normal );
		hOT = (tdxHandleToObjectsTablesList) SCR_M_ul_RdL0_ExtractLongValue(p_stVal,0);

		// update flag
		GetEditor()->GetInterface()->SetLoadingWorld(bIsLoadingWorld);

        // update engine struct
		fn_vUpdateData( hOT );
		SetStruct(hOT);
		fn_vCreateEditorPhysicalObjects();

		// update validity
		SetAvailable(TRUE);

		// add to family list
//		((CPA_Family *) GetOwner())->mfn_vAddObjectTable(this);

	}
}


// Shaitan => module list in the level
/*===========================================================================
*		Description:	loa unused POs of the object table
*		Creation date:	06/06/97	
*		Author:			Vincent Lhullier
*---------------------------------------------------------------------------
*		Revision date:	18/08/97		Author:	Shaitan	     
*=========================================================================*/
SCR_tde_Anl_ReturnValue EditorObjectTable::m_fn_tdeCallBackLoadUnusedPOs(SCR_tdst_File_Description *_p_stFile,char *_p_szName,char *_ap_szParams[],SCR_tde_Anl_Action	_eAction)
{
	SCR_tde_Anl_ReturnValue			eReturnValue = SCR_ERV_Anl_NormalReturn;
	tdxHandleToObjectsTablesList	h_ObjectsTablesListElement;
	PO_tdxHandleToPhysicalObject	hPO;
	long							l_NumberInTable;
 
	if ( M_IsTitle )
	{
		SCR_M_RdL0_SetContextLong(C_ThisContext,1,atoi(_p_szName));
	}
	else if ( M_IsEntry )
	{
		
		SCR_M_RdL0_GetContextLong(C_ThisContext,0,tdxHandleToObjectsTablesList,h_ObjectsTablesListElement);
		SCR_M_RdL0_GetContextLong(C_ThisContext,1,long,l_NumberInTable);
 
		if ( M_ActionIs( C_Entry_PHY ) )
		{
            PO_tdxHandleToPhysicalObject  hPO;

			if (!h_ObjectsTablesListElement->d_stObjectsTable[l_NumberInTable-1].h_Target)
			{
				hPO = CS_fn_xLoadPhysicalObject(_ap_szParams[0]);
				if (hPO)
				{
					h_ObjectsTablesListElement->d_stObjectsTable[l_NumberInTable-1].h_Target = hPO; 
					h_ObjectsTablesListElement->d_stObjectsTable[l_NumberInTable-1].wTypeOfTarget = C_wTdO_PhysicalObject;
 
					if (PO_fn_hGetCollideSet (hPO))
					{
						if (PCS_fn_hGetGeoObjOfPhysicalCollSet (C_ucTypeZdd , PO_fn_hGetCollideSet (hPO)))  h_ObjectsTablesListElement->wZDxUsed |= C_wObjectTableHasZdd;
						if (PCS_fn_hGetGeoObjOfPhysicalCollSet (C_ucTypeZde , PO_fn_hGetCollideSet (hPO)))  h_ObjectsTablesListElement->wZDxUsed |= C_wObjectTableHasZde;
					}
				}
			}
		}
		if ( M_ActionIs( C_Entry_MIRROR ) )
		{
			hPO = CS_fn_xFindPhysicalObject(_ap_szParams[0]);
			if (!h_ObjectsTablesListElement->d_stObjectsTable[l_NumberInTable-1].h_Target)
			{
				hPO = CS_fn_xLoadPhysicalObject(_ap_szParams[0]);
				if (hPO)
				{
					h_ObjectsTablesListElement->d_stObjectsTable[l_NumberInTable-1].h_Target = hPO; 
					h_ObjectsTablesListElement->d_stObjectsTable[l_NumberInTable-1].wTypeOfTarget = C_wTdO_PhysicalObject;
				}
			}
		}
	}
	else if( M_IsEnd )
	{
		SCR_M_RdL0_GetSectionLong(C_ParentSection,0,tdxHandleToObjectsTablesList,h_ObjectsTablesListElement);
	}
 
	return ( eReturnValue );
}
// End Shaitan => module list in the level	

// Shaitan => module list in the level
/*===========================================================================
*		Description:	loa unused POs of the object table
*		Creation date:	06/06/97	
*		Author:			Vincent Lhullier
*---------------------------------------------------------------------------
*		Revision date:	18/08/97		Author:	Shaitan	     
*=========================================================================*/
SCR_tde_Anl_ReturnValue EditorObjectTable::m_fn_tdeEmtpyCallBack(SCR_tdst_File_Description *_p_stFile,char *_p_szName,char *_ap_szParams[],SCR_tde_Anl_Action	_eAction)
{
	return ( SCR_ERV_Anl_NormalReturn );
}