#include "AIUseCPA.h"
#include "specif/AIOption.h"
#include "AIMacros.h"
#include "AI_Erm.h"
#include "ActParam.h"
#include "Action.h"
#include "Intell.h"
#include "WPWayPt.h"
#include "specif/AITools.h"
#include "Procedur.h"
#include "EnumProc.h"
#include "safe.h"

/*
 *=================================================================================================
 *=================================================================================================
 */
tdstNodeInterpret *fn_p_stExecuteActionInit(HIE_tdxHandleToSuperObject p_SuperObjPerso, tdstNodeInterpret *p_stTree)
{
	tdxHandleToState	h_WantedState;
 
	p_stTree = fn_p_stDefaultActionInit(p_SuperObjPerso, p_stTree);
	h_WantedState = fn_xGetActionParamStateValue(0, p_SuperObjPerso);
 
	/* Force the state to be changed by setting it with a dummy value */
	fn_v3dDataSetFirstStateOfAction(M_GetMSHandle(p_SuperObjPerso,3dData), NULL);
 
#if defined(__DEBUG_AI__)
    if (!PLA_fn_bSetNewState(p_SuperObjPerso, h_WantedState, FALSE,FALSE))
    {
        fn_vSetActionParamlValue(0, p_SuperObjPerso, 0);
    }
    else
	{
        fn_vSetActionParamlValue(0, p_SuperObjPerso, 1);
	}
#else
	fn_vSetActionParamlValue(0, p_SuperObjPerso, (long) (PLA_fn_bSetNewState(p_SuperObjPerso, h_WantedState, FALSE,FALSE)  ) );
#endif
 
	/* Put the action in the stack parameters */
	fn_vSetActionParamStateValue(1, p_SuperObjPerso, h_WantedState);
 
	return(p_stTree);
}
 
/*===============================================================================================*/
tducActionReturn fn_ucExecuteAction(HIE_tdxHandleToSuperObject p_SuperObjPerso)
{
	tdxHandleToState h_WantedState = fn_xGetActionParamStateValue(1, p_SuperObjPerso);
 
    /* Test if SetNewState has work */
    if (fn_lGetActionParamlValue(0, p_SuperObjPerso) == 0)
		return C_DefaultMetaActionFinished;
 
	/* Test if this the same action */
	if (!PLA_fn_bTestCurrentAction(p_SuperObjPerso, h_WantedState))
    {
#if defined(__DEBUG_AI__)
		char MyMsg[100];
		sprintf(MyMsg,"");
        M_AIWarningErrorAndNeverStopForDebug(E_uwAIWarningExecuteActionInt, C_ucErmNoOpenInfoWindow,MyMsg);
#endif
		return C_DefaultMetaActionFinished;
    }
    /* Test if animation is finished */
    if (PLA_fn_bTestIfEndOfAction(p_SuperObjPerso))
		return C_DefaultMetaActionFinished;
	return C_DefaultMetaActionNotFinished;
}
 
/*
 *=================================================================================================
 *=================================================================================================
 */
#ifdef D_USE_LIPSYNC
tdstNodeInterpret *fn_p_stSpeakAndWaitEndInit(HIE_tdxHandleToSuperObject p_SuperObjPerso, tdstNodeInterpret *p_stTree)
{
    p_stTree = fn_p_stDefaultActionInit(p_SuperObjPerso,p_stTree);
	if(fn_bIsDiscussionOver(p_SuperObjPerso))
	{
		fn_vStartLipsSynchro(p_SuperObjPerso,fn_p_stGetActionParamhLipsSynchro(0, p_SuperObjPerso));
	}
	return p_stTree;
}
#endif /*  D_USE_LIPSYNC*/
 
/*===============================================================================================*/
#ifdef D_USE_LIPSYNC
tducActionReturn fn_ucSpeakAndWaitEnd(HIE_tdxHandleToSuperObject p_SuperObjPerso)
{
	if(fn_bIsDiscussionOver(p_SuperObjPerso))
		return C_DefaultMetaActionFinished;
	return C_DefaultMetaActionNotFinished;
}
#endif /*  D_USE_LIPSYNC*/
 
/*
 *=================================================================================================
 *=================================================================================================
 */
tducActionReturn fn_ucWaitEndOfAction(HIE_tdxHandleToSuperObject p_SuperObjPerso)
{
	if (PLA_fn_bTestIfEndOfAction(p_SuperObjPerso))
		return C_DefaultMetaActionFinished;
	return C_DefaultMetaActionNotFinished;
}
 
/*
 *=================================================================================================
 *=================================================================================================
 */
tducActionReturn fn_ucWaitEndOfAnim(HIE_tdxHandleToSuperObject p_SuperObjPerso)
{
	if (PLA_fn_bTestIfEndOfAnim(p_SuperObjPerso))
		return C_DefaultMetaActionFinished;
	return C_DefaultMetaActionNotFinished;
}
 
/*
 *=================================================================================================
 *=================================================================================================
 */

#define D_FrozenWaitWarn 0
#define D_FrozenWaitForce 0
tdstNodeInterpret *fn_p_stFrozenWaitInit(HIE_tdxHandleToSuperObject p_SuperObjPerso, tdstNodeInterpret *p_stTree)
{
	/* read the meta-action arguments */
	p_stTree = fn_p_stDefaultActionInit(p_SuperObjPerso,p_stTree);

#if D_FrozenWaitWarn && defined(ACTIVE_EDITOR)
	SAF_M_AssertWithMsg(
		( fn_uc3dDataGetBrainComputationFrequency(M_GetMSHandle(p_SuperObjPerso,3dData)) == 1 )
		|| M_IsTheEndOfTree(p_stTree)
		||
		(
			( M_GetTypeInterpret(p_stTree) == E_ti_Procedure )
			&&
			(
				( M_eProcedureIdInterpret(p_stTree) == eProc_ChangeMyComportAndMyReflex )
				|| ( M_eProcedureIdInterpret(p_stTree) == ( AI_M_bGetDoingIntel(AI_M_stGetMindOfSuperObj(p_SuperObjPerso)) ? eProc_ChangeMyComport : eProc_ChangeMyComportReflex ) )
			)
		),
		"il est fortement déconseillé d'appeler cette méta-action à l'intérieur d'un comportement\n"
		"dans une IA qui n'est pas traitée toutes les trames!"
	);
#endif

#if D_FrozenWaitForce
	/* remember the AI computation frequency */
	fn_vSetActionParamlValue(
		1,
		p_SuperObjPerso,
		fn_uc3dDataGetBrainComputationFrequency(M_GetMSHandle(p_SuperObjPerso,3dData))
	);
	/* and force it to 1, to make sure the meta action does not last longer than planned */
	fn_v3dDataSetBrainComputationFrequency(M_GetMSHandle(p_SuperObjPerso,3dData), 1) ;
#endif
 
	/*remember the time at which the metaaction is to end*/
	fn_vSetActionParamlValue(
		0,
		p_SuperObjPerso,
		g_stEngineStructure.stEngineTimer.ulCurrentTimerCount + fn_lGetActionParamlValue(0, p_SuperObjPerso)
		);
 
	return p_stTree;
}
 
/*===============================================================================================*/
tducActionReturn fn_ucFrozenWait(HIE_tdxHandleToSuperObject p_SuperObjPerso)
{
	tducActionReturn ucReturn ;

	/*the meta action ends when the time is later than the specified one*/
	ucReturn = (g_stEngineStructure.stEngineTimer.ulCurrentTimerCount < (unsigned long) fn_lGetActionParamlValue(0, p_SuperObjPerso))
		? C_DefaultMetaActionNotFinished
		: C_DefaultMetaActionFinished ;
#if D_FrozenWaitForce
	/* if it is over, restore the brain computation frequency */
	if ( ucReturn == C_DefaultMetaActionFinished )
	{
		fn_v3dDataSetBrainComputationFrequency(M_GetMSHandle(p_SuperObjPerso,3dData), fn_lGetActionParamlValue(1, p_SuperObjPerso)) ;
	}
#endif
	return 	ucReturn ;
}
