////////////////////////////////////////////
//
// All CallBacks used  by TPG
//
////////////////////////////////////////////

#include "StdAfx.h"

#define D_MSPrtSrc_StructureDefine

#include "ErO.h"
#include "MTH.h"

#include "TPG_ClBk.hpp"
#include "_Minterf.hpp"
#include "Tpg_Strg.hpp"
#include "TPG_Spri.hpp"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/*
 =======================================================================================
	General function 
 =======================================================================================
 */


/*
 ----------------------------------------------------------------------------------------
  Description   : Get a PrtSrc owner data in Editor data
  Returns (PRT_tdstParticlesSource )
 ----------------------------------------------------------------------------------------
 */
PRT_tdstParticlesSource *fn_CB_p_stGetOwnerPrtSrc( CTL_Editor_Data *_p_clData )
{
	/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
	CTL_OwnerData			*p_clOwnerData;
	/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

	ERROR_PREPARE_M
		(
			g_c_csPartGenModuleNameForErrors,
			"Function to get ParticlesSource Owner data",
			"fn_CB_p_stGetOwnerPrtSrc",
			E_ERROR_GRAVITY_FATAL,
			"Ownerdata (PrtSrc) is NULL"
		);
	p_clOwnerData = _p_clData->m_pub_fn_pclGetOwnerDataWithName( "PrtSrc" );
	ERROR_ASSERT( p_clOwnerData != NULL );
	return (PRT_tdstParticlesSource *) p_clOwnerData->m_pub_fn_pvGetDataPtr();
}


/*
 ----------------------------------------------------------------------------------------
  Description   : Check data passed to some call back
  Returns (PRT_tdstParticlesSource )
 ----------------------------------------------------------------------------------------
 */
void fn_CB_vCheckData( CTL_Editor_Data *_p_clData )
{
	ERROR_PREPARE_M
		(
			g_c_csPartGenModuleNameForErrors,
			"Function to check data",
			"fn_CB_p_oCheckData",
			E_ERROR_GRAVITY_FATAL,
			"Data is NULL"
		);
	ERROR_ASSERT( _p_clData != NULL );
}

/*
 ----------------------------------------------------------------------------------------
  Description   : get and check current enum value of an enum data
 ----------------------------------------------------------------------------------------
 */
CTL_Editor_EnumElement *fn_CB_p_oGetCurrentEnumElement( CTL_Editor_Data *_p_clData )
{
	/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
	CTL_Editor_EnumElement *p_clEnumElement;
	/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

	ERROR_PREPARE_M
		(
			g_c_csPartGenModuleNameForErrors,
			"Function to retrieve current enum value",
			"fn_CB_p_oGetCurrentEnumElement",
			E_ERROR_GRAVITY_FATAL,
			"Enum current value is NULL"
		);
	p_clEnumElement = ((CTL_Editor_EnumData*)_p_clData)->m_pclCurrentValue;
	ERROR_ASSERT( p_clEnumElement != NULL );

	return p_clEnumElement;
}



//////////////////////////////////////////////////
// Can Be Displayed CallBacks
//////////////////////////////////////////////////

//*** Probability for source generation mode *****
BOOL g_fn_bCallBackCanBeDisplayedSourceProbability( CTL_Editor_Control *_p_clControl )
{
	CTL_OwnerData *p_clOwnerData;
	unsigned char *p_ucGenerationMode;

	ERROR_PREPARE_M
		(
			g_c_csPartGenModuleNameForErrors,
			"Is source generation probability displayed ?",
			"g_fn_bCallBackCanBeDisplayedSourceProbability",
			E_ERROR_GRAVITY_FATAL,
			"OwnerData to get generation mode is NULL"
		);
	
	p_clOwnerData = _p_clControl->m_fn_pclGetEditedData()->m_pub_fn_pclGetOwnerDataWithName( "GenerationMode" );
	ERROR_ASSERT( p_clOwnerData != NULL );
	
	p_ucGenerationMode = (unsigned char*)( p_clOwnerData->m_pub_fn_pvGetDataPtr() );
	return (*p_ucGenerationMode == PRT_C_ucProbabilistGeneration);
}

//*** Nb Frames For source generation mode ****
BOOL g_fn_bCallBackCanBeDisplayedSourceNbFrames( CTL_Editor_Control *_p_clControl )
{
	CTL_OwnerData *p_clOwnerData;
	unsigned char *p_ucGenerationMode;

	ERROR_PREPARE_M
		(
			g_c_csPartGenModuleNameForErrors,
			"Is source nb frames generation displayed ?",
			"g_fn_bCallBackCanBeDisplayedSourceNbFrames",
			E_ERROR_GRAVITY_FATAL,
			"OwnerData to get generation mode is NULL"
		);
	p_clOwnerData = _p_clControl->m_fn_pclGetEditedData()->m_pub_fn_pclGetOwnerDataWithName( "GenerationMode" );
	ERROR_ASSERT( p_clOwnerData != NULL );

	p_ucGenerationMode = (unsigned char*) p_clOwnerData->m_pub_fn_pvGetDataPtr();
	return (*p_ucGenerationMode == PRT_C_ucCrenelGeneration);
}

//*** Nb Particles For source nb particles to generate mode
BOOL g_fn_bCallBackCanBeDisplayedSourceNbParticles( CTL_Editor_Control *_p_clControl )
{
	CTL_OwnerData *p_clOwnerData;
	unsigned char *p_ucNbParticlesMode;

	ERROR_PREPARE_M
		(
			g_c_csPartGenModuleNameForErrors,
			"Is source nb particles constant displayed ?",
			"g_fn_bCallBackCanBeDisplayedSourceNbParticles",
			E_ERROR_GRAVITY_FATAL,
			"OwnerData to get nb particles to generate mode is NULL"
		);
	p_clOwnerData = _p_clControl->m_fn_pclGetEditedData()->m_pub_fn_pclGetOwnerDataWithName( "NbParticlesMode" );
	ERROR_ASSERT( p_clOwnerData != NULL );
	
	p_ucNbParticlesMode = (unsigned char*) p_clOwnerData->m_pub_fn_pvGetDataPtr();	
	return (*p_ucNbParticlesMode == PRT_C_ucConstantNb);
}

//*** Nb Particles Min/Max For source nb particles to generate mode
BOOL g_fn_bCallBackCanBeDisplayedSourceNbParticlesMinMax( CTL_Editor_Control *_p_clControl )
{
	CTL_OwnerData *p_clOwnerData;
	unsigned char *p_ucNbParticlesMode;

	ERROR_PREPARE_M
		(
			g_c_csPartGenModuleNameForErrors,
			"Is source nb particles min/max displayed ?",
			"g_fn_bCallBackCanBeDisplayedSourceNbParticles",
			E_ERROR_GRAVITY_FATAL,
			"OwnerData to get nb particles to generate mode is NULL"
		);
	p_clOwnerData = _p_clControl->m_fn_pclGetEditedData()->m_pub_fn_pclGetOwnerDataWithName( "NbParticlesMode" );
	ERROR_ASSERT( p_clOwnerData != NULL );

	p_ucNbParticlesMode = (unsigned char*) p_clOwnerData->m_pub_fn_pvGetDataPtr();
	return (*p_ucNbParticlesMode == PRT_C_ucProbabilistNb);
}


//*** Quad geometry for source ********************
BOOL g_fn_bCallBackCanBeDisplayedSourceGeometryQuad( CTL_Editor_Control *_p_clControl )
{
	CTL_OwnerData *p_clOwnerData;
	unsigned char *p_ucNbParticlesMode;

	ERROR_PREPARE_M
		(
			g_c_csPartGenModuleNameForErrors,
			"Is points 1 and 2 displayed ?",
			"g_fn_bCallBackCanBeDisplayedSourceGeometryQuad",
			E_ERROR_GRAVITY_FATAL,
			"OwnerData to get geometry mode is NULL"
		);
	p_clOwnerData = _p_clControl->m_fn_pclGetEditedData()->m_pub_fn_pclGetOwnerDataWithName( "GeometryMode" );
	ERROR_ASSERT( p_clOwnerData != NULL );
	
	p_ucNbParticlesMode = (unsigned char*) p_clOwnerData->m_pub_fn_pvGetDataPtr();
	return (*p_ucNbParticlesMode == PRT_C_ucQuad);
}

//*** Constant Life time  ********************
BOOL g_fn_bCallBackCanBeDisplayedSourceConstantLifeTime( CTL_Editor_Control *_p_clControl )
{
	CTL_OwnerData *p_clOwnerData;
	unsigned char *p_ucMode;

	ERROR_PREPARE_M
		(
			g_c_csPartGenModuleNameForErrors,
			"Is constant life time displayed ?",
			"g_fn_bCallBackCanBeDisplayedSourceConstantLifeTime",
			E_ERROR_GRAVITY_FATAL,
			"OwnerData to get geometry mode is NULL"
		);
	p_clOwnerData = _p_clControl->m_fn_pclGetEditedData()->m_pub_fn_pclGetOwnerDataWithName( "LifeMode" );
	ERROR_ASSERT( p_clOwnerData != NULL );
	
	p_ucMode = (unsigned char*) p_clOwnerData->m_pub_fn_pvGetDataPtr();
	return (*p_ucMode == PRT_C_ucConstantLifeTime);
}


//*** Probabilist Life time  ********************
BOOL g_fn_bCallBackCanBeDisplayedSourceProbabilistLifeTime( CTL_Editor_Control *_p_clControl )
{
	CTL_OwnerData *p_clOwnerData;
	unsigned char *p_ucMode;

	ERROR_PREPARE_M
		(
			g_c_csPartGenModuleNameForErrors,
			"Are min/max life time displayed ?",
			"g_fn_bCallBackCanBeDisplayedSourceProbabilistLifeTime",
			E_ERROR_GRAVITY_FATAL,
			"OwnerData to get geometry mode is NULL"
		);
	p_clOwnerData = _p_clControl->m_fn_pclGetEditedData()->m_pub_fn_pclGetOwnerDataWithName( "LifeMode" );
	ERROR_ASSERT( p_clOwnerData != NULL );
	
	p_ucMode = (unsigned char*) p_clOwnerData->m_pub_fn_pvGetDataPtr();
	return (*p_ucMode == PRT_C_ucProbabilistLifeTime);
}


//*** GameMaterials for system *********************
BOOL g_fn_bCallBackCanBeDisplayedSystemGameMaterials( CTL_Editor_Control * _p_clControl)
{
	ERROR_PREPARE_M(g_c_csPartGenModuleNameForErrors,
									"Is GameMaterials displayed ?",
									"g_fn_bCallBackCanBeDisplayedSystemGameMaterials",
									E_ERROR_GRAVITY_FATAL,
									"OwnerData to get objects type is NULL");
	CTL_OwnerData *p_clOwnerData = _p_clControl->m_fn_pclGetEditedData()->m_pub_fn_pclGetOwnerDataWithName( "ObjectsType" );
	ERROR_ASSERT( p_clOwnerData != NULL );
	
	ACP_tdxIndex *p_xType = (ACP_tdxIndex*)( p_clOwnerData->m_pub_fn_pvGetDataPtr() );
	
	return( (*p_xType == PRT_C_xPointParticles) || (*p_xType == PRT_C_xSegmentParticles) );
}


//*** Sprites for system
BOOL g_fn_bCallBackCanBeDisplayedSystemSprites( CTL_Editor_Control * _p_clControl)
{
	ERROR_PREPARE_M(g_c_csPartGenModuleNameForErrors,
									"Is sprites displayed ?",
									"g_fn_bCallBackCanBeDisplayedSystemSprites",
									E_ERROR_GRAVITY_FATAL,
									"OwnerData to get objects type is NULL");
	CTL_OwnerData *p_clOwnerData = _p_clControl->m_fn_pclGetEditedData()->m_pub_fn_pclGetOwnerDataWithName( "ObjectsType" );
	ERROR_ASSERT( p_clOwnerData != NULL );
	
	ACP_tdxIndex *p_xType = (ACP_tdxIndex*)( p_clOwnerData->m_pub_fn_pvGetDataPtr() );
	
	return( *p_xType == PRT_C_xSpriteParticles );
}


//*** Min Max points for environment box with generator not linked
BOOL g_fn_bCallBackCanBeDisplayedEnvBox( CTL_Editor_Control * _p_clControl)
{
	ERROR_PREPARE_M(g_c_csPartGenModuleNameForErrors,
									"Are min and max points for box displayed ?",
									"g_fn_bCallBackCanBeDisplayedEnvBox",
									E_ERROR_GRAVITY_FATAL,
									"OwnerData to get environment type is NULL");
	CTL_OwnerData *p_clOwnerData = _p_clControl->m_fn_pclGetEditedData()->m_pub_fn_pclGetOwnerDataWithName( "EnvType" );
	ERROR_ASSERT( p_clOwnerData != NULL );

	unsigned long *p_ulType = (unsigned long*)( p_clOwnerData->m_pub_fn_pvGetDataPtr() );

	return( *p_ulType == PRT_C_ulAlignedBoxEnv );
}


//*** Sphere center for environment box with generator not linked
BOOL g_fn_bCallBackCanBeDisplayedEnvSphere( CTL_Editor_Control * _p_clControl)
{
	ERROR_PREPARE_M(g_c_csPartGenModuleNameForErrors,
									"Is center for sphere displayed ?",
									"g_fn_bCallBackCanBeDisplayedEnvSphere",
									E_ERROR_GRAVITY_FATAL,
									"OwnerData to get environment type is NULL");
	CTL_OwnerData *p_clOwnerData = _p_clControl->m_fn_pclGetEditedData()->m_pub_fn_pclGetOwnerDataWithName( "EnvType" );
	ERROR_ASSERT( p_clOwnerData != NULL );

	unsigned long *p_ulType = (unsigned long*)( p_clOwnerData->m_pub_fn_pvGetDataPtr() );

	return( *p_ulType == PRT_C_ulSphereEnv );
}


////////////////////////////////////////
// Data Changed CallBacks
////////////////////////////////////////

//*** data changed for generator ******
void g_fn_vCallBackDataChangedGenerator( CTL_Editor_Data *_p_clData, CTL_eUpdateReason _eReason, long _lUserReason )
{
	CTL_OwnerData			*p_clOwnerData;
	CPA_PartGen_Generator	*p_clGenerator;

	ERROR_PREPARE_M
		(
			g_c_csPartGenModuleNameForErrors,
			"CallBack to notify generator data has changed",
			"g_fn_vCallBackDataChangedGenerator",
			E_ERROR_GRAVITY_FATAL,
			"OwnerData to get edited generator is NULL"
		);
	p_clOwnerData = _p_clData->m_pub_fn_pclGetOwnerDataWithName( "EditedGenerator" );
	ERROR_ASSERT( p_clOwnerData != NULL );

	ERROR_PREPARE_M
		(
			g_c_csPartGenModuleNameForErrors,
			"CallBack to notify generator data has changed",
			"g_fn_vCallBackDataChangedGenerator",
			E_ERROR_GRAVITY_FATAL,
			"Edited generator is NULL"
		);
	p_clGenerator = (CPA_PartGen_Generator*) p_clOwnerData->m_pub_fn_pvGetDataPtr();
	ERROR_ASSERT( p_clGenerator != NULL );
	
	p_clGenerator->fn_vNotifySave();
}

//*** data changed for Particle source ******
void fn_vCBPrtSrcDataChanged( CTL_Editor_Data *_p_clData, CTL_eUpdateReason _eReason, long _lUserReason )
{
	CTL_OwnerData			*p_clOwnerData;
	CPA_PartGen_Source		*p_oPrtSrc;

	ERROR_PREPARE_M
		(
			g_c_csPartGenModuleNameForErrors,
			"CallBack to notify Particle source data has changed",
			"fn_vCBPrtSrcDataChanged",
			E_ERROR_GRAVITY_FATAL,
			"OwnerData to get edited source is NULL"
		);
	p_clOwnerData = _p_clData->m_pub_fn_pclGetOwnerDataWithName( "EditedSource" );
	ERROR_ASSERT( p_clOwnerData != NULL );

	ERROR_PREPARE_M
		(
			g_c_csPartGenModuleNameForErrors,
			"CallBack to notify Particle source data has changed",
			"fn_vCBPrtSrcDataChanged",
			E_ERROR_GRAVITY_FATAL,
			"Edited particle source is NULL"
		);
	p_oPrtSrc = (CPA_PartGen_Source *) p_clOwnerData->m_pub_fn_pvGetDataPtr();
	ERROR_ASSERT( p_oPrtSrc != NULL );
	
	p_oPrtSrc->fn_vNotifySave();
}

//*** data changed for Particle system ******
void g_fn_vCallBackDataChangedSystem( CTL_Editor_Data *_p_clData, CTL_eUpdateReason _eReason, long _lUserReason )
{
	ERROR_PREPARE_M(g_c_csPartGenModuleNameForErrors,
									"CallBack to notify system data has changed",
									"g_fn_vCallBackDataChangedSystem",
									E_ERROR_GRAVITY_FATAL,
									"OwnerData to get edited system is NULL");
	CTL_OwnerData *p_clOwnerData = _p_clData->m_pub_fn_pclGetOwnerDataWithName( "EditedSystem" );
	ERROR_ASSERT( p_clOwnerData != NULL );

	ERROR_PREPARE_M(g_c_csPartGenModuleNameForErrors,
									"CallBack to notify system data has changed",
									"g_fn_vCallBackDataChangedSystem",
									E_ERROR_GRAVITY_FATAL,
									"Edited system is NULL");
	CPA_PartGen_System *p_clSystem = (CPA_PartGen_System*)( p_clOwnerData->m_pub_fn_pvGetDataPtr() );
	ERROR_ASSERT( p_clSystem != NULL );
	p_clSystem->fn_vNotifySave();
}


//*** data changed for Particle environment ******
void g_fn_vCallBackDataChangedEnv( CTL_Editor_Data *_p_clData, CTL_eUpdateReason _eReason, long _lUserReason )
{
	ERROR_PREPARE_M(g_c_csPartGenModuleNameForErrors,
									"CallBack to notify environment data has changed",
									"g_fn_vCallBackDataChangedEnv",
									E_ERROR_GRAVITY_FATAL,
									"OwnerData to get edited environment is NULL");
	CTL_OwnerData *p_clOwnerData = _p_clData->m_pub_fn_pclGetOwnerDataWithName( "EditedEnv" );
	ERROR_ASSERT( p_clOwnerData != NULL );

	ERROR_PREPARE_M(g_c_csPartGenModuleNameForErrors,
									"CallBack to notify environment data has changed",
									"g_fn_vCallBackDataChangedEnv",
									E_ERROR_GRAVITY_FATAL,
									"Edited environment is NULL");
	CPA_PartGen_Environment *p_clEnv = (CPA_PartGen_Environment*)( p_clOwnerData->m_pub_fn_pvGetDataPtr() );
	ERROR_ASSERT( p_clEnv != NULL );
	p_clEnv->fn_vNotifySave();
}

/////////////////////////////////////////////////////
// Data Changed Special CallBacks
/////////////////////////////////////////////////////

//*** Display generator for combo changed ***********
void g_fn_vCallBackDataChangedSpecialDisplayGenerator( CTL_Editor_Data *_p_clData, CTL_eUpdateReason _eReason, long _lUserReason )
{
	if( _eReason == CTL_UPDATE_REASON__DATA_MODIFIED_BY_USER )
		g_pclInterface->m_pub_fn_p_clGetDocument()->m_pub_fn_vDisplayCurrentGenerator();
}


void g_fn_vCallBackDataChangedSpecialDisplayAll( CTL_Editor_Data *_p_clData, CTL_eUpdateReason _eReason, long _lUserReason )
{
	if( _eReason == CTL_UPDATE_REASON__DATA_MODIFIED_BY_USER )
		g_pclInterface->m_pub_fn_p_clGetDocument()->m_pub_fn_vUpdateGenerator(g_pclInterface->m_pub_fn_p_clGetDocument()->m_pub_p_clCurrentGenerator );
}


///////////////////////////////////////////////////
// Read/Write Modification CallBacks
///////////////////////////////////////////////////

///// Check if source is loaded before it is used by generator /////////////
void g_fn_vModificationWriteGeneratorSource( CTL_Editor_Data *_p_clData )
{
	/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
	CTL_Editor_EnumElement	*p_clEnumElement;
	CPA_PartGen_Source		*p_oPrtSrc;
	/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

	fn_CB_vCheckData( _p_clData );
	p_clEnumElement = fn_CB_p_oGetCurrentEnumElement(_p_clData);

	if( p_clEnumElement->m_pub_fn_lGetValue() == (long)0 )
	{
		ERROR_PREPARE_M
			(
				g_c_csPartGenModuleNameForErrors,
				"Function to modify system associated to generator",
				"g_fn_vModificationWriteGeneratorSystem",
				E_ERROR_GRAVITY_WARNING,
				"Set a NULL System"
			);
		p_oPrtSrc = (CPA_PartGen_Source *)p_clEnumElement->m_pub_fn_pvGetAdditionnalPointer();
		ERROR_ASSERT( p_oPrtSrc != NULL );

		if( p_oPrtSrc != NULL )
		{
			p_oPrtSrc->m_pub_fn_vLoadIfUnloaded();
			p_clEnumElement->m_pub_fn_vSetValue( ((long) p_oPrtSrc->GetData()) );
		}
	}
}

///// Check system is loaded before it is used by generator /////////////
void g_fn_vModificationWriteGeneratorSystem( CTL_Editor_Data *_p_clData )
{
	ERROR_PREPARE_M(g_c_csPartGenModuleNameForErrors,
									"Function to modify system associated to generator",
									"g_fn_vModificationWriteGeneratorSystem",
									E_ERROR_GRAVITY_FATAL,
									"Data is NULL");
	ERROR_ASSERT( _p_clData != NULL );

	ERROR_PREPARE_M(g_c_csPartGenModuleNameForErrors,
									"Function to modify system associated to generator",
									"g_fn_vModificationWriteGeneratorSystem",
									E_ERROR_GRAVITY_FATAL,
									"Enum current value is NULL");
	CTL_Editor_EnumElement *p_clEnumElement = ((CTL_Editor_EnumData*)_p_clData)->m_pclCurrentValue;
	ERROR_ASSERT( p_clEnumElement != NULL );

	if( p_clEnumElement->m_pub_fn_lGetValue() == (long)0 )
		{
		ERROR_PREPARE_M(g_c_csPartGenModuleNameForErrors,
									"Function to modify system associated to generator",
									"g_fn_vModificationWriteGeneratorSystem",
									E_ERROR_GRAVITY_WARNING,
									"Set a NULL System");
		CPA_PartGen_System *p_clSystem = (CPA_PartGen_System*)p_clEnumElement->m_pub_fn_pvGetAdditionnalPointer();
		ERROR_ASSERT( p_clSystem != NULL );

		if( p_clSystem != NULL )
		{
			p_clSystem->m_pub_fn_vLoadIfUnloaded();

			p_clEnumElement->m_pub_fn_vSetValue( ((long)p_clSystem->GetData()) );
		}
		}
}


///// Check environment is loaded before it is used by generator /////////////
void g_fn_vModificationWriteGeneratorEnvironment( CTL_Editor_Data *_p_clData )
{
	ERROR_PREPARE_M(g_c_csPartGenModuleNameForErrors,
									"Function to modify environment associated to generator",
									"g_fn_vModificationWriteGeneratorEnvironment",
									E_ERROR_GRAVITY_FATAL,
									"Data is NULL");
	ERROR_ASSERT( _p_clData != NULL );

	ERROR_PREPARE_M(g_c_csPartGenModuleNameForErrors,
									"Function to modify environment associated to generator",
									"g_fn_vModificationWriteGeneratorEnvironment",
									E_ERROR_GRAVITY_FATAL,
									"Enum current value is NULL");
	CTL_Editor_EnumElement *p_clEnumElement = ((CTL_Editor_EnumData*)_p_clData)->m_pclCurrentValue;
	ERROR_ASSERT( p_clEnumElement != NULL );

	if( p_clEnumElement->m_pub_fn_lGetValue() == (long)0 )
		{
		ERROR_PREPARE_M(g_c_csPartGenModuleNameForErrors,
									"Function to modify environment associated to generator",
									"g_fn_vModificationWriteGeneratorEnvironment",
									E_ERROR_GRAVITY_WARNING,
									"Set a NULL environment");
		CPA_PartGen_Environment *p_clEnv = (CPA_PartGen_Environment*)p_clEnumElement->m_pub_fn_pvGetAdditionnalPointer();
		ERROR_ASSERT( p_clEnv != NULL );
		if( p_clEnv != NULL )
		{
			p_clEnv->m_pub_fn_vLoadIfUnloaded();

			p_clEnumElement->m_pub_fn_vSetValue( (long)(p_clEnv->GetData()) );
		}
		}
}

///// Check environment is loaded before it is used by generator /////////////
void g_fn_vModificationWriteGeneratorLinkedGenerator( CTL_Editor_Data *_p_clData )
{
	/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
	CTL_Editor_EnumElement	*p_clEnumElement;
	CPA_PartGen_Generator	*p_oLinkedGen;
	/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

	fn_CB_vCheckData( _p_clData );
	p_clEnumElement = fn_CB_p_oGetCurrentEnumElement(_p_clData);

	if( p_clEnumElement->m_pub_fn_lGetValue() == (long)0 )
	{
		p_oLinkedGen = (CPA_PartGen_Generator *) p_clEnumElement->m_pub_fn_pvGetAdditionnalPointer();

		if( p_oLinkedGen != NULL )
		{
			//p_oLinkedGen->m_pub_fn_vLoadIfUnloaded();
			g_pclInterface->fn_bLoadBaseObject( p_oLinkedGen );
			p_clEnumElement->m_pub_fn_vSetValue( (long)(p_oLinkedGen->GetData()) );

			/*
			 * todo : check for loop
			 */
		}
	}
}



///// Read Nb frames generation using Nb frames total ///////////////////////////
void g_fn_vModificationReadSourceNbFramesGeneration( CTL_Editor_Data *_p_clData )
{
	/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
	PRT_tdstParticlesSource *p_stPrtSrc;
	/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

	fn_CB_vCheckData( _p_clData );
	p_stPrtSrc = fn_CB_p_stGetOwnerPrtSrc( _p_clData );
	((CTL_Editor_IntegerData *) _p_clData)->m_lCurrentValue -= (long) p_stPrtSrc->xNbFramesNoGeneration;
}


///// write nb frames total using nb frames generation ///////////////////////////
void g_fn_vModificationWriteSourceNbFramesGeneration( CTL_Editor_Data *_p_clData )
{
	/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
	PRT_tdstParticlesSource *p_stPrtSrc;
	/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

	fn_CB_vCheckData( _p_clData );
	p_stPrtSrc = fn_CB_p_stGetOwnerPrtSrc( _p_clData );
	((CTL_Editor_IntegerData *) _p_clData)->m_lCurrentValue += (long) p_stPrtSrc->xNbFramesNoGeneration;
}




//*** Get GameMaterial used by system with point or segment
void g_fn_vModificationReadSystemGameMaterials( CTL_Editor_Data *_p_clData )
{
	ERROR_PREPARE_M(g_c_csPartGenModuleNameForErrors,
									"Function to get GameMaterial from Point or Segment",
									"g_fn_vModificationReadSystemGameMaterials",
									E_ERROR_GRAVITY_FATAL,
									"Data is NULL");
	ERROR_ASSERT( _p_clData != NULL );

	ERROR_PREPARE_M(g_c_csPartGenModuleNameForErrors,
									"Function to get GameMaterial from Point or Segment",
									"g_fn_vModificationReadSystemGameMaterials",
									E_ERROR_GRAVITY_FATAL,
									"EnumElement is NULL");
	CTL_Editor_EnumElement *p_clEnumElement = ((CTL_Editor_EnumData*)_p_clData)->m_pclCurrentValue;
	ERROR_ASSERT( p_clEnumElement != NULL );

	ERROR_PREPARE_M(g_c_csPartGenModuleNameForErrors,
									"Function to get GameMaterial from Point or Segment",
									"g_fn_vModificationReadSystemGameMaterials",
									E_ERROR_GRAVITY_FATAL,
									"OwnerData to get objects type is NULL");
	CTL_OwnerData *p_clOwnerData = _p_clData->m_pub_fn_pclGetOwnerDataWithName( "ObjectsType" );
	ERROR_ASSERT( p_clOwnerData != NULL );
	ACP_tdxIndex *p_xType = (ACP_tdxIndex*)( p_clOwnerData->m_pub_fn_pvGetDataPtr() );

	ERROR_PREPARE_M(g_c_csPartGenModuleNameForErrors,
									"Function to get GameMaterial from Point or Segment",
									"g_fn_vModificationReadSystemGameMaterials",
									E_ERROR_GRAVITY_FATAL,
									"OwnerData to get edited system is NULL");
	p_clOwnerData = _p_clData->m_pub_fn_pclGetOwnerDataWithName( "EditedSystem" );
	ERROR_ASSERT( p_clOwnerData != NULL );

	ERROR_PREPARE_M(g_c_csPartGenModuleNameForErrors,
									"Function to get GameMaterial from Point or Segment",
									"g_fn_vModificationReadSystemGameMaterials",
									E_ERROR_GRAVITY_FATAL,
									"Edited system is NULL");
	CPA_PartGen_System *p_clSystem = (CPA_PartGen_System*)( p_clOwnerData->m_pub_fn_pvGetDataPtr() );
	ERROR_ASSERT( p_clSystem != NULL );

	if( *p_xType == PRT_C_xPointParticles )
		p_clEnumElement->m_pub_fn_vSetValue( (long)p_clSystem->m_pub_fn_hGetPointGameMaterial() );

	if( *p_xType == PRT_C_xSegmentParticles )
		p_clEnumElement->m_pub_fn_vSetValue( (long)p_clSystem->m_pub_fn_hGetSegmentGameMaterial() );
}


///// Create Point, Segment or Sprite for system //////////////////////
void g_fn_vModificationWriteSystemObjects( CTL_Editor_Data *_p_clData )
{
	ERROR_PREPARE_M(g_c_csPartGenModuleNameForErrors,
									"Function to create Point, Segment or Sprite",
									"g_fn_vModificationWriteSystemObjects",
									E_ERROR_GRAVITY_FATAL,
									"Data is NULL");
	ERROR_ASSERT( _p_clData != NULL );

	ERROR_PREPARE_M(g_c_csPartGenModuleNameForErrors,
									"Function to create Point, Segment or Sprite",
									"g_fn_vModificationWriteSystemObjects",
									E_ERROR_GRAVITY_FATAL,
									"EnumElement is NULL");
	CTL_Editor_EnumElement *p_clEnumElement = ((CTL_Editor_EnumData*)_p_clData)->m_pclCurrentValue;
	ERROR_ASSERT( p_clEnumElement != NULL );

	ERROR_PREPARE_M(g_c_csPartGenModuleNameForErrors,
									"Function to create Point, Segment or Sprite",
									"g_fn_vModificationWriteSystemObjects",
									E_ERROR_GRAVITY_FATAL,
									"OwnerData to get objects type is NULL");
	CTL_OwnerData *p_clOwnerData = _p_clData->m_pub_fn_pclGetOwnerDataWithName( "ObjectsType" );
	ERROR_ASSERT( p_clOwnerData != NULL );
	ACP_tdxIndex *p_xType = (ACP_tdxIndex*)( p_clOwnerData->m_pub_fn_pvGetDataPtr() );

	ERROR_PREPARE_M(g_c_csPartGenModuleNameForErrors,
									"Function to create Point, Segment or Sprite",
									"g_fn_vModificationWriteSystemObjects",
									E_ERROR_GRAVITY_FATAL,
									"OwnerData to get edited system is NULL");
	p_clOwnerData = _p_clData->m_pub_fn_pclGetOwnerDataWithName( "EditedSystem" );
	ERROR_ASSERT( p_clOwnerData != NULL );

	ERROR_PREPARE_M(g_c_csPartGenModuleNameForErrors,
									"Function to create Point, Segment or Sprite",
									"g_fn_vModificationWriteSystemObjects",
									E_ERROR_GRAVITY_FATAL,
									"Edited system is NULL");
	CPA_PartGen_System *p_clSystem = (CPA_PartGen_System*)( p_clOwnerData->m_pub_fn_pvGetDataPtr() );
	ERROR_ASSERT( p_clSystem != NULL );

	if( *p_xType == PRT_C_xPointParticles )
		p_clSystem->m_pub_fn_vSetObjectPoint( (GMT_tdxHandleToGameMaterial)p_clEnumElement->m_pub_fn_lGetValue() );

	if( *p_xType == PRT_C_xSegmentParticles )
		p_clSystem->m_pub_fn_vSetObjectSegment( (GMT_tdxHandleToGameMaterial)p_clEnumElement->m_pub_fn_lGetValue() );

	if( *p_xType == PRT_C_xSpriteParticles )
		{
		if( p_clEnumElement->m_pub_fn_lGetValue() == 0 )
		{
			ERROR_PREPARE_M(g_c_csPartGenModuleNameForErrors,
										"Function to create Point, Segment or Sprite",
										"g_fn_vModificationWriteSystemObjects",
										E_ERROR_GRAVITY_WARNING,
										"Set a NULL Sprite !");
			TPG_Sprite *p_clSprite = (TPG_Sprite*)p_clEnumElement->m_pub_fn_pvGetAdditionnalPointer();
			ERROR_ASSERT( p_clSprite != NULL );
			if( p_clSprite != NULL )
			{
				p_clSprite->m_pub_fn_vLoadSprite();
				p_clEnumElement->m_pub_fn_vSetValue( (long)p_clSprite->m_pub_fn_hGetSprite() );
			}
		}

		p_clSystem->m_pub_fn_vSetObjectSprite( (ACP_tdxHandleOfSprite)p_clEnumElement->m_pub_fn_lGetValue() );
		}
}


///// Save min max point in environment or in generator linked //
void g_fn_vModificationWriteEnvBox( CTL_Editor_Data *_p_clData )
{
	ERROR_PREPARE_M(g_c_csPartGenModuleNameForErrors,
								"Update engine data min max points for environment",
								"g_fn_vModificationWriteEnvBox",
								E_ERROR_GRAVITY_FATAL,
								"Data is NULL");
	ERROR_ASSERT( _p_clData != NULL );

	ERROR_PREPARE_M(g_c_csPartGenModuleNameForErrors,
								"Update engine data min max points for environment",
								"g_fn_vModificationWriteEnvBox",
								E_ERROR_GRAVITY_FATAL,
								"OwnerData to get edited environment is NULL");
	CTL_OwnerData *p_clOwnerData = _p_clData->m_pub_fn_pclGetOwnerDataWithName( "EditedEnv" );
	ERROR_ASSERT( p_clOwnerData != NULL );

	ERROR_PREPARE_M(g_c_csPartGenModuleNameForErrors,
								"Update engine data min max points for environment",
								"g_fn_vModificationWriteEnvBox",
								E_ERROR_GRAVITY_FATAL,
								"Edited environment is NULL");
	CPA_PartGen_Environment *p_clEnv = (CPA_PartGen_Environment*)( p_clOwnerData->m_pub_fn_pvGetDataPtr() );
	ERROR_ASSERT( p_clEnv != NULL );

	ERROR_PREPARE_M(g_c_csPartGenModuleNameForErrors,
								"Update engine data min max points for environment",
								"g_fn_vModificationWriteEnvBox",
								E_ERROR_GRAVITY_FATAL,
								"Edited engine environment is NULL");
	ERROR_ASSERT( p_clEnv->m_pri_p_stEnv != NULL );

	if( p_clEnv->m_pri_p_clGenerator == NULL )
		{
		MTH3D_M_vCopyVector( (&(p_clEnv->m_pri_p_stEnv->stMinPoint)), (&(p_clEnv->m_pri_stMinPoint)) );
		MTH3D_M_vCopyVector( (&(p_clEnv->m_pri_p_stEnv->stMaxPoint)), (&(p_clEnv->m_pri_stMaxPoint)) );
		}
	else
		{
		if( p_clEnv->m_pri_p_clGenerator->m_pub_fn_bGetLinkToEnv() )
		{
			ERROR_PREPARE_M(g_c_csPartGenModuleNameForErrors,
								"Update engine data min max points for environment",
								"g_fn_vModificationWriteEnvBox",
								E_ERROR_GRAVITY_FATAL,
								"Engine generator using edited environment is NULL");
			ERROR_ASSERT( p_clEnv->m_pri_p_clGenerator->m_pri_hGenerator != NULL );
			MTH3D_M_vCopyVector( (&(p_clEnv->m_pri_p_clGenerator->m_pri_hGenerator->stMinPoint)), (&(p_clEnv->m_pri_stMinPoint)) );
			MTH3D_M_vCopyVector( (&(p_clEnv->m_pri_p_clGenerator->m_pri_hGenerator->stMaxPoint)), (&(p_clEnv->m_pri_stMaxPoint)) );
		}
		else
		{
			MTH3D_M_vCopyVector( (&(p_clEnv->m_pri_p_stEnv->stMinPoint)), (&(p_clEnv->m_pri_stMinPoint)) );
			MTH3D_M_vCopyVector( (&(p_clEnv->m_pri_p_stEnv->stMaxPoint)), (&(p_clEnv->m_pri_stMaxPoint)) );
		}
		}
}

///// Save sphere center in environment or in generator linked ////
void g_fn_vModificationWriteEnvSphere( CTL_Editor_Data *_p_clData )
{
	ERROR_PREPARE_M(g_c_csPartGenModuleNameForErrors,
								"Update engine data center of sphere for environment",
								"g_fn_vModificationWriteEnvSphere",
								E_ERROR_GRAVITY_FATAL,
								"Data is NULL");
	ERROR_ASSERT( _p_clData != NULL );

	ERROR_PREPARE_M(g_c_csPartGenModuleNameForErrors,
								"Update engine data center of sphere for environment",
								"g_fn_vModificationWriteEnvSphere",
								E_ERROR_GRAVITY_FATAL,
								"OwnerData to get edited environment is NULL");
	CTL_OwnerData *p_clOwnerData = _p_clData->m_pub_fn_pclGetOwnerDataWithName( "EditedEnv" );
	ERROR_ASSERT( p_clOwnerData != NULL );

	ERROR_PREPARE_M(g_c_csPartGenModuleNameForErrors,
								"Update engine data center of sphere for environment",
								"g_fn_vModificationWriteEnvSphere",
								E_ERROR_GRAVITY_FATAL,
								"Edited environment is NULL");
	CPA_PartGen_Environment *p_clEnv = (CPA_PartGen_Environment*)( p_clOwnerData->m_pub_fn_pvGetDataPtr() );
	ERROR_ASSERT( p_clEnv != NULL );

	ERROR_PREPARE_M(g_c_csPartGenModuleNameForErrors,
								"Update engine data center of sphere for environment",
								"g_fn_vModificationWriteEnvSphere",
								E_ERROR_GRAVITY_FATAL,
								"Edited engine environment is NULL");
	ERROR_ASSERT( p_clEnv->m_pri_p_stEnv != NULL );

	if( p_clEnv->m_pri_p_clGenerator == NULL )
		{
		MTH3D_M_vCopyVector( (&(p_clEnv->m_pri_p_stEnv->stSphereCenter)), (&(p_clEnv->m_pri_stSphereCenter)) );
		}
	else
		{
		if( p_clEnv->m_pri_p_clGenerator->m_pub_fn_bGetLinkToEnv() )
		{
			ERROR_PREPARE_M(g_c_csPartGenModuleNameForErrors,
								"Update engine data center of sphere for environment",
								"g_fn_vModificationWriteEnvSphere",
								E_ERROR_GRAVITY_FATAL,
								"Engine generator using edited environment is NULL");
			ERROR_ASSERT( p_clEnv->m_pri_p_clGenerator->m_pri_hGenerator != NULL );
			MTH3D_M_vCopyVector( (&(p_clEnv->m_pri_p_clGenerator->m_pri_hGenerator->stMinPoint)), (&(p_clEnv->m_pri_stSphereCenter)) );
		}
		else
		{
			MTH3D_M_vCopyVector( (&(p_clEnv->m_pri_p_stEnv->stSphereCenter)), (&(p_clEnv->m_pri_stSphereCenter)) );
		}
		}
}

///////////////////////////////////////////////////////////////////////////////////
// Must be read_written CallBacks
///////////////////////////////////////////////////////////////////////////////////

//*** Is GameMaterial data of system is taken into account ************************
BOOL g_fn_bCallBackMustBeReadWrittenSystemGameMaterial( CTL_Editor_Data * _p_clData )
{
	ERROR_PREPARE_M(g_c_csPartGenModuleNameForErrors,
									"Is GameMaterial data taken into account ?",
									"g_fn_bCallBackMustBeReadWrittenSystemGameMaterial",
									E_ERROR_GRAVITY_FATAL,
									"OwnerData to get objects type is NULL");
	CTL_OwnerData *p_clOwnerData = _p_clData->m_pub_fn_pclGetOwnerDataWithName( "ObjectsType" );
	ERROR_ASSERT( p_clOwnerData != NULL );
	
	ACP_tdxIndex *p_xType = (ACP_tdxIndex*)( p_clOwnerData->m_pub_fn_pvGetDataPtr() );
	
	return( (*p_xType == PRT_C_xPointParticles) || (*p_xType == PRT_C_xSegmentParticles) );
}


//*** Is Sprite data of system is taken into account 
BOOL g_fn_bCallBackMustBeReadWrittenSystemSprite( CTL_Editor_Data * _p_clData )
{
	ERROR_PREPARE_M(g_c_csPartGenModuleNameForErrors,
									"Is sprite data taken into account ?",
									"g_fn_bCallBackMustBeReadWrittenSystemSprite",
									E_ERROR_GRAVITY_FATAL,
									"OwnerData to get objects type is NULL");
	CTL_OwnerData *p_clOwnerData = _p_clData->m_pub_fn_pclGetOwnerDataWithName( "ObjectsType" );
	ERROR_ASSERT( p_clOwnerData != NULL );
	
	ACP_tdxIndex *p_xType = (ACP_tdxIndex*)( p_clOwnerData->m_pub_fn_pvGetDataPtr() );
	
	return( *p_xType == PRT_C_xSpriteParticles );
}

//ROMTEAM Bugs Correction (Cristian Stegaru 24/03/98)
//////////////////////////////////////////////////////////////////////////////////////////////////////
// Method : g_fnCanISelectThisItemCallBack 
// Date   : 98-03
//////////////////////////////////////////////////////////////////////////////////////////////////////
// Description : this function is called from a combobox when a selection is changed
//				 if the selected item is valid approve the selection
// Author      : Stegaru Cristian - CPA2
//////////////////////////////////////////////////////////////////////////////////////////////////////
// Modification :
// Date         :
// By           :
//////////////////////////////////////////////////////////////////////////////////////////////////////
int g_fnCanISelectThisItemCallBack (CTL_Editor_Data * p_clData, CTL_Editor_EnumElement *pNewElement)
{
	ASSERT (pNewElement);
	CString csSelectedString = pNewElement->m_pub_fn_csGetElementName();
	if ("No Element" == csSelectedString)
		return 1;

	ASSERT (p_clData);
	CString csDataName = p_clData->m_pub_fn_csGetDataName ();
	if ("Environment" != csDataName)
		return 1;

	//get the current generator
	CTL_OwnerData *p_clOwnerData = p_clData->m_pub_fn_pclGetOwnerDataWithName( "EditedGenerator" );
	ASSERT( p_clOwnerData != NULL );
	CPA_PartGen_Generator *p_clGenerator = (CPA_PartGen_Generator*)( p_clOwnerData->m_pub_fn_pvGetDataPtr() );
	ASSERT (p_clGenerator);

	ASSERT (g_pclInterface->m_clDocument.m_pub_p_clCurrentGenerator == p_clGenerator);
	CString csCurrentGeneratorName = p_clGenerator->GetName ();

	CPA_PartGen_Environment *pSelectedEnv = (CPA_PartGen_Environment*)pNewElement->m_pub_fn_pvGetAdditionnalPointer();
	ASSERT (pSelectedEnv);
	PRT_tdstParticlesEnvironment *pSelectedEngEnv = pSelectedEnv->m_pub_fn_p_stGetEnv();
	
	//check every generator to see if the environment is already used
	CPA_BaseObjectList * p_clList = g_pclInterface->GetMainWorld()->fn_p_oGetOriginalObjectList(C_szPartGenGeneratorName);
	CPA_PartGen_Generator *p_Generator = NULL;
	Position pos = p_clList->GetHeadPosition();
	while (pos != NULL)
	{
		p_Generator = (CPA_PartGen_Generator *)p_clList->GetNext (pos);
		ASSERT (p_Generator);
		if (p_Generator->GetName() == csCurrentGeneratorName) //don't count the current generator
			continue;
		
		tdxHandleToParticleGenerator pEngGenerator = p_Generator->m_pub_fn_hGetGenerator();
		if (NULL == pEngGenerator)
			continue;

		PRT_tdstParticlesEnvironment *pEngEnv = pEngGenerator->p_stPrtEnv;
		if (NULL == pEngEnv)
			continue;

		if (pSelectedEngEnv == pEngEnv)
		{
			AfxMessageBox ("This environment is already used.\nPlease, select another one.");
			return 0;
		}
	}
	return 1;
}
//ENDROMTEAM Bugs Correction (Cristian Stegaru)
