/*=========================================================================
*
* Actors.h	- LVL and ALW functions
*
* Version			1.0
* Revision date
*
*=======================================================================*/
#include "Actors.h"

#include "conventi.h"		
#include "system.h"
#include "vertex.h"		


//--- Global statics --------------------------------------------------------

MLT_tdstAlways	**gs_hAlwaysInFile	= NULL;
long			  gs_lAlwaysIndex	= 0;


//--------------------------------------------------------------------



/****************************************************************************
*		Description:	register the loading function for the LVL file
*
*		Parameters:		
*---------------------------------------------------------------------------
*		Revision date:                                      Author:         
*****************************************************************************/
void MLT_vInitLVLLoad ()
{
  SCR_fn_v_RdL0_RegisterCallback(M_InsertCharacter, MLT_xLoadInsertCharacter,SCR_CRC_c_RdL0_ForSection);  
}


/****************************************************************************
*		Description:	save character in LVL file
*
*		Parameters:		p_stFile	: script file pointer
*						sFileName	: file name
*						p_vPtr		: data pointer
*						xAction		: script action
*---------------------------------------------------------------------------
*		Revision date:                                      Author:         
*****************************************************************************/
void MLT_vSaveInsertCharacter(SCR_tdst_File_Description *p_stFile, char *sFileName, void *p_vPtr, SCR_tde_Ntfy_Action xAction)
{
  MLT_tdstInsertCharacter	*p_stInsertCharacter;
  MLT_tdstInsertCharacter	*p_stOldInsertCharacter=NULL;
  xString					sFile, sAction, sIdent, sSection, sChar;
  char						*p_Char;

  // get character pointer
  p_stInsertCharacter = (MLT_tdstInsertCharacter *)p_vPtr;

  if(xAction != SCR_EA_Ntfy_AddSection) 
  {
	SCR_fn_v_SvL1_DeleteSection(p_stFile);
  }

  // compute section name
  sprintf(sFile, "%s", p_stFile->a_szOpenFileName);
  sprintf(sAction, M_InsertCharacter);
  sprintf(sIdent, "World", (MLT_p_cGetFileNameWithoutExt(sFile)));
  SCR_fn_v_RdL0_ComputeSectionName(sSection, sFile, sAction, sIdent);

  // save character section
  SCR_M_SvL0_SaveBeginSection(p_stFile, MLT_p_cGetSectionName(sSection), SCR_CC_C_Cfg_EOL);

  // save linked character
  SCR_M_SvL0_SaveEntry(p_stFile, M_LVLActionLinkCharacter, SCR_CC_C_Cfg_NoChar);
  // compute character name
  p_Char = strstr(p_stInsertCharacter->szLink, "World1");
  strcpy(sChar, p_Char);
  p_stInsertCharacter->szLink[strlen(p_stInsertCharacter->szLink)-strlen(sChar)]='\0';
  strcat(p_stInsertCharacter->szLink, "Level");
  strcat(p_stInsertCharacter->szLink, MLT_p_cGetFileNameWithoutExt(sFile));
  strcat(p_stInsertCharacter->szLink, sChar + 6);
  // save corresponding name
  SCR_fn_v_SvL0_SaveParameters_MP(p_stFile, SCR_EF_SvL0_Normal, 1, p_stInsertCharacter->szLink);

  // save character translation
  SCR_M_SvL0_SaveEntry(p_stFile, M_LVLActionTranslation, SCR_CC_C_Cfg_NoChar);
  SCR_fn_v_SvL0_SaveParameters_MP(p_stFile, SCR_EF_SvL0_Scanf, 4, "%.6f,%.6f,%.6f", 
	  p_stInsertCharacter->Translation.xX,
	  p_stInsertCharacter->Translation.xY,
	  p_stInsertCharacter->Translation.xZ);

  // save character rotation
  SCR_M_SvL0_SaveEntry(p_stFile, M_LVLActionRotation, SCR_CC_C_Cfg_NoChar);
  SCR_fn_v_SvL0_SaveParameters_MP(p_stFile, SCR_EF_SvL0_Scanf, 10, "%.6f,%.6f,%.6f,%.6f,%.6f,%.6f,%.6f,%.6f,%.6f",
          p_stInsertCharacter->RotMatrix[0][0],
          p_stInsertCharacter->RotMatrix[1][0],
          p_stInsertCharacter->RotMatrix[2][0],
          p_stInsertCharacter->RotMatrix[0][1],
          p_stInsertCharacter->RotMatrix[1][1],
          p_stInsertCharacter->RotMatrix[2][1],
          p_stInsertCharacter->RotMatrix[0][2],
          p_stInsertCharacter->RotMatrix[1][2],
          p_stInsertCharacter->RotMatrix[2][2]);

  // save character scale
  SCR_M_SvL0_SaveEntry(p_stFile, M_LVLActionScale, SCR_CC_C_Cfg_NoChar);
  SCR_fn_v_SvL0_SaveParameters_MP(p_stFile, SCR_EF_SvL0_Scanf, 10, "%.6f,%.6f,%.6f,%.6f,%.6f,%.6f,%.6f,%.6f,%.6f",
          p_stInsertCharacter->ScaleMatrix[0][0],
          p_stInsertCharacter->ScaleMatrix[1][0],
          p_stInsertCharacter->ScaleMatrix[2][0],
          p_stInsertCharacter->ScaleMatrix[0][1],
          p_stInsertCharacter->ScaleMatrix[1][1],
          p_stInsertCharacter->ScaleMatrix[2][1],
          p_stInsertCharacter->ScaleMatrix[0][2],
          p_stInsertCharacter->ScaleMatrix[1][2],
          p_stInsertCharacter->ScaleMatrix[2][2]);


  // save character initial state
  SCR_M_SvL0_SaveEntry(p_stFile, M_LVLActionInitialState, SCR_CC_C_Cfg_NoChar);
  SCR_fn_v_SvL0_SaveParameters_MP(p_stFile, SCR_EF_SvL0_Normal, 1, p_stInsertCharacter->szInitial);

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



/****************************************************************************
*		Description:	load character section in LVL file
*
*		Parameters:		p_stFile	: script file pointer
*						szAction	: section or entry name
*						szParams	: parameters
*						cType		: action type
*---------------------------------------------------------------------------
*		Revision date:                                      Author:         
*****************************************************************************/
SCR_tde_Anl_ReturnValue MLT_xLoadInsertCharacter (SCR_tdst_File_Description *p_fFile, char *szAction, char *szParams[], SCR_tde_Anl_Action cType)
{
  MLT_tdstInsertCharacter *p_stInsertCharacter;
  MTH_tdxReal a_xVertex[3];
  int i, j;
	
  switch (cType)
  {
	case SCR_EA_Anl_BeginSection:
		// create character structure
		p_stInsertCharacter=(MLT_tdstInsertCharacter*)malloc(sizeof(MLT_tdstInsertCharacter));

		SCR_M_RdL0_SetSectionLong(0,0,(long)p_stInsertCharacter);
        SCR_M_RdL0_SetContextLong(0,0,(long)p_stInsertCharacter);
        sprintf(p_stInsertCharacter->sName,"%s",SCR_M_RdL0_GetCompleteSectionNameR(0));
		break;

	case SCR_EA_Anl_Entry:
        // get character pointer
        SCR_M_RdL0_GetContextLong(0,0,MLT_tdstInsertCharacter*,p_stInsertCharacter);

	    // load linked character
		if (strcmp(szAction,M_LVLActionLinkCharacter)==0)	
		{	
			strcpy(p_stInsertCharacter->szLink, szParams[0]);
		}
		// load translation
		if (strcmp(szAction,M_LVLActionTranslation)==0)
		{
			for (i=0;i<3;i++)
				a_xVertex[i]=(MTH_tdxReal)MTH_M_xFloatToReal(atof(szParams[i])/**MLT_dGetUnitInMeterInFile(p_fFile->a_szOpenFileName)*/);
			MLT_M_SetVertexXYZ(&p_stInsertCharacter->Translation,a_xVertex[0],a_xVertex[1],a_xVertex[2]);
		}
		// load the rotation
		if (strcmp(szAction,M_LVLActionRotation)==0)
		{
			for (i=0;i<3;i++)
				for (j=0;j<3;j++)
					p_stInsertCharacter->RotMatrix[j][i] = (MTH_tdxReal)MTH_M_xFloatToReal(atof(szParams[3*i+j]));
		}
		// load the scale
		if (strcmp(szAction,M_LVLActionScale)==0)
		{
			for (i=0;i<3;i++)
				for (j=0;j<3;j++)
					p_stInsertCharacter->ScaleMatrix[j][i] = (MTH_tdxReal)MTH_M_xFloatToReal(atof(szParams[3*i+j]));
		}		
	    // load initial state
		if (strcmp(szAction,M_LVLActionInitialState)==0)	
		{	
			strcpy(p_stInsertCharacter->szInitial, szParams[0]);
		}
		break;

		case SCR_EA_Anl_EndSection:
		break;
  }
  return  SCR_ERV_Anl_NormalReturn;
}




/****************************************************************************
*		Description:	register the loading function for the ALW file
*
*		Parameters:		
*---------------------------------------------------------------------------
*		Revision date:                                      Author:         
*****************************************************************************/
void MLT_vInitALWLoad()
{
  SCR_fn_v_RdL0_RegisterCallback(M_InsertAlways,MLT_xLoadAlways, SCR_CRC_c_RdL0_ForSection);
  SCR_fn_v_RdL0_RegisterCallback(M_FichierALW,MLT_xLoadALWCallback, SCR_CRC_c_RdL0_ForFile);
}


/****************************************************************************
*		Description:	save character in ALW file
*
*		Parameters:		p_stFile	: script file pointer
*						sFileName	: file name
*						p_vPtr		: data pointer
*						xAction		: script action
*---------------------------------------------------------------------------
*		Revision date:                                      Author:         
*****************************************************************************/
void MLT_vSaveAlways(SCR_tdst_File_Description *p_stFile, char *sFileName, void *p_vPtr, SCR_tde_Ntfy_Action xAction)
{
  MLT_tdstAlways *p_stAlways;
  xString mes, sFile, sAction, sIdent;

  p_stAlways = (MLT_tdstAlways *)p_vPtr;
  if(xAction == SCR_EA_Ntfy_AddSection) 
  {
    SCR_fn_v_SvL1_ToEndSection(p_stFile);
  }
  else
    return;

  SCR_fn_v_RdL0_SplitSectionName(p_stAlways->sName, sFile, sAction, sIdent);
  sprintf(sFile, "%s%s.alw", g_sDirectorySave, g_sFileIn);
  SCR_fn_v_RdL0_ComputeSectionName(mes, sFile, M_InsertAlways, sIdent);
  if (! SCR_fn_c_RdL0_IsSectionExists(mes)) //the section don't exist
  {   SCR_M_SvL0_SaveBeginSection(p_stFile, MLT_p_cGetSectionName(mes), SCR_CC_C_Cfg_EOL);
	  SCR_M_SvL0_SaveEntry(p_stFile, M_LVLActionLinkCharacter, SCR_CC_C_Cfg_NoChar);
      SCR_fn_v_SvL0_SaveParameters_MP(p_stFile, SCR_EF_SvL0_Scanf, 2, "%s", p_stAlways->sLinkCharacter);
	  if (p_stAlways->iCharacter != -1)
	  {	  SCR_M_SvL0_SaveEntry(p_stFile, M_LVLActionCharacterFlags, SCR_CC_C_Cfg_NoChar);
          SCR_fn_v_SvL0_SaveParameters_MP(p_stFile, SCR_EF_SvL0_Scanf, 2, "%d", p_stAlways->iCharacter);
	  }
	  if (p_stAlways->fTransparency != -1)
	  {	  SCR_M_SvL0_SaveEntry(p_stFile, M_LVLActionTransparency, SCR_CC_C_Cfg_NoChar);
		  SCR_fn_v_SvL0_SaveParameters_MP(p_stFile, SCR_EF_SvL0_Scanf, 2, "%f", p_stAlways->fTransparency);
	  }
      SCR_M_SvL0_SaveEndSection(p_stFile, SCR_CC_C_Cfg_EOL);
  }
}

/****************************************************************************
*		Description:	load character section in ALW file
*
*		Parameters:		p_stFile	: script file pointer
*						szAction	: section or entry name
*						szParams	: parameters
*						cType		: action type
*---------------------------------------------------------------------------
*		Revision date:                                      Author:         
*****************************************************************************/
SCR_tde_Anl_ReturnValue MLT_xLoadAlways (SCR_tdst_File_Description *p_fFile, char *szAction, char *szParams[], SCR_tde_Anl_Action cType)
{
  MLT_tdstAlways *p_stAlways;

  switch (cType)
  {
    case SCR_EA_Anl_BeginSection:
      p_stAlways=(MLT_tdstAlways*)malloc(sizeof(MLT_tdstAlways));
      SCR_M_RdL0_SetSectionLong(0,0,(long)p_stAlways);
      SCR_M_RdL0_SetContextLong(0,0,(long)p_stAlways);
      sprintf(p_stAlways->sName,"%s",SCR_M_RdL0_GetCompleteSectionNameR(0));
      p_stAlways->iCharacter= -1;
      p_stAlways->fTransparency= -1;
      break;
                
    case SCR_EA_Anl_Entry:
      SCR_M_RdL0_GetContextLong(0,0,MLT_tdstAlways*,p_stAlways);

      // Loading object's Always
      if (strcmp(szAction,M_LVLActionLinkCharacter)==0)
      {
	      sprintf(p_stAlways->sLinkCharacter,"%s",szParams[0]);
      } 
      if (strcmp(szAction,M_LVLActionCharacterFlags)==0)
      {
	      p_stAlways->iCharacter= (int)atoi(szParams[0]);
      } 
      if (strcmp(szAction,M_LVLActionTransparency)==0)
      {
	      p_stAlways->fTransparency= (float)atof(szParams[0]);
      } 
      break;

    case SCR_EA_Anl_EndSection:
      break;
  }
  return  SCR_ERV_Anl_NormalReturn;
}


/****************************************************************************
*		Description:	load ALW file
*
*		Parameters:		p_stFile	: script file pointer
*						szAction	: section or entry name
*						szParams	: parameters
*						cType		: action type
*---------------------------------------------------------------------------
*		Revision date:                                      Author:         
*****************************************************************************/
SCR_tde_Anl_ReturnValue MLT_xLoadALWCallback(SCR_tdst_File_Description *p_fFile, char *szAction, char *szParams[], SCR_tde_Anl_Action cType)
{
  MLT_tdstAlways **p_xAlwaysInFile;
  long xNbAlways;
  
  switch (cType)
  {
    case SCR_EA_Anl_BeginSection:
      p_xAlwaysInFile = (MLT_tdstAlways**)malloc(sizeof(MLT_tdstAlways*));
    
      SCR_M_RdL0_SetContextLong(0,0,(long)p_xAlwaysInFile);
      SCR_M_RdL0_SetContextLong(0,1,(long)0);
      break;

    case SCR_EA_Anl_EndSubSection:
      if (strcmp(szParams[0],M_InsertAlways)==0)
      {
        MLT_tdstAlways *hAlways;

        SCR_M_RdL0_GetContextLong(0,0,MLT_tdstAlways**,p_xAlwaysInFile);
        SCR_M_RdL0_GetContextLong(0,1,long,xNbAlways);

        p_xAlwaysInFile = (MLT_tdstAlways**)realloc(p_xAlwaysInFile,(++xNbAlways)*sizeof(MLT_tdstAlways*));

        SCR_M_RdL0_GetSectionLong(1,0,MLT_tdstAlways*,hAlways);
        p_xAlwaysInFile[xNbAlways-1]=hAlways;

        SCR_M_RdL0_SetContextLong(0,0,(long)p_xAlwaysInFile);
        SCR_M_RdL0_SetContextLong(0,1,(long)xNbAlways);
      }
      break;

    case SCR_EA_Anl_EndSection:
      SCR_M_RdL0_GetContextLong(0,0,MLT_tdstAlways**,p_xAlwaysInFile);
      SCR_M_RdL0_GetContextLong(0,1,long,xNbAlways);
      SCR_M_RdL0_SetSectionLong(0,0,(long)p_xAlwaysInFile);
      SCR_M_RdL0_SetSectionLong(0,1,(long)xNbAlways);
      break;
  }
  return  SCR_ERV_Anl_NormalReturn;
}


/****************************************************************************
*		Description:	free all the always in the library
*
*		Parameters:		
*---------------------------------------------------------------------------
*		Revision date:                                      Author:         
*****************************************************************************/
void MLT_vEraseALWLib()
{
  int i;

  if (gs_hAlwaysInFile == NULL) 
	  return;

  for (i=0; i<gs_lAlwaysIndex; i++)
  {
    if (gs_hAlwaysInFile[i] == NULL) 
		continue;
    free(gs_hAlwaysInFile[i]);
  }
  gs_lAlwaysIndex = 0;
  free(gs_hAlwaysInFile);
  gs_hAlwaysInFile = NULL;
}

/****************************************************************************
*		Description:	load alw file in library
*
*		Parameters:		
*---------------------------------------------------------------------------
*		Revision date:                                      Author:         
*****************************************************************************/
void MLT_vLoadALWFileInLib()
{
  SCR_tdst_Cxt_Values *p_stVal;
  xString szFileName;

  //Inits 
  strcpy(szFileName, g_sGameCommon);
  strcat(szFileName, "\\default\\Default.alw");

  if(SCR_fn_c_RdL0_IsSectionExists(szFileName))
  {
	p_stVal = SCR_fnp_st_RdL0_AnalyseSection(szFileName, SCR_CDF_uw_Anl_ForceAnalyse);

	gs_hAlwaysInFile = (MLT_tdstAlways **)SCR_M_ul_RdL0_ExtractLongValue(p_stVal,0);
	gs_lAlwaysIndex = (long)SCR_M_ul_RdL0_ExtractLongValue(p_stVal,1);
  }
}


/****************************************************************************
*		Description:	save library in alw file 
*
*		Parameters:		
*---------------------------------------------------------------------------
*		Revision date:                                      Author:         
*****************************************************************************/
void MLT_vSaveLibInALWFile ()
{
  long i;
  xString sFile, sIdent, sSection;

  for (i=0; i<gs_lAlwaysIndex; i++)
  {
    SCR_fn_v_RdL0_SplitSectionName(gs_hAlwaysInFile[i]->sName, sFile, sSection, sIdent);
    sprintf(sFile, "%s.alw", g_sFileIn);
    SCR_fn_v_RdL0_ComputeSectionName(sSection, sFile, M_InsertAlways, sIdent);
    SCR_fn_v_SvL1_RegisterNotify(sSection, MLT_vSaveAlways, gs_hAlwaysInFile[i], SCR_EA_Ntfy_AddOrModifySection);
  }
}



