/*=============================================================================
 *
 *  Filename:			CPAState.cpp
 *  Version:            1.0
 *  Date:				30/12/96
 *  Author:             Marc Trabucato & V.L.
 *
 *  Description:		implementation of CPA_State class
 *                      (this is a derivation of CPA_SaveObject)
 *
 *===========================================================================*/

#ifdef ACTIVE_EDITOR

#include "stdafx.h"

//ACP
#include "ACP_Base.h"
#include "incITF.h"
#include "incDPT.h"
#include "TAC.h"
#include "TFa.h"
#include "TAn.h"
// Shaitan Clean Env {
//#include "incsrf.h"
//End Shaitan Clean Env }
#include "x:\cpa\main\inc\_editid.h"
#include "ACInterf.hpp"

/******************************************************************************
* unexisting engine function
******************************************************************************/
/*
static tdxHandleToState fn_hGetProhibitedStateInProhibit( tdxHandleToProhibit _hProhibit )
{
	return ( _hProhibit ? _hProhibit -> h_ProhibitedState : NULL );
}

static void fn_vSetProhibitedStateInProhibit( tdxHandleToProhibit _hProhibit, tdxHandleToState _hState )
{
	ASSERT( _hProhibit );
	_hProhibit -> h_ProhibitedState = _hState;
}

static tdxHandleToTransition fn_hGetTransitionalWithTargetState( tdxHandleToState _hState, tdxHandleToState _hTargetState )
{
	ASSERT( _hState );

	tdxHandleToTransition hTransition;

	hTransition = LST2_M_StaticGetFirstElement( & _hState -> hForTransitionArray );
	while( hTransition )
	{
		if( fn_hGetTargetStateInTransition( hTransition ) == _hTargetState)
		{
			return( hTransition );
		}
		hTransition = LST2_M_StaticGetNextElement( hTransition );
	}
	return(NULL);
}
*/
  void del(tdxHandleToState h)
{
	if (M_GetMainApp()->m_bLeavingApplication)
		return;

	fn_h_StateFree(h);
}

/******************************************************************************
* Macros
******************************************************************************/
#define M_AddTransitionalStateToState( p_oState , p_stTransState )  \
            p_oState -> m_oListOfTransitionalStates.AddTail (p_stTransState )

#define M_Char(string)      ((char*)(LPCTSTR)(string))

#define M_ForEachElement(p_oList,p_oElement,Pos)\
            for( p_oElement = (p_oList) -> GetHeadElement( Pos ) ;\
                 p_oElement ;\
                 p_oElement = (p_oList) -> GetNextElement( Pos )\
                )

#define M_FindStateByEngineHandle( p_oState, hState, p_oOwnerFamily ) ((CPA_State*) p_oState -> GetBaseObjectList() -> fn_p_oFindObjectWithdData( (void*)hState, C_szStateTypeName, p_oOwnerFamily ))

DeclareTemplateStatic(tdxHandleToState);

/******************************************************************************
* Class
******************************************************************************/

void CPA_State::Init()
{
    CPA_EdMot<tdxHandleToState>::Init(fn_h_StateAlloc,NULL,del);
}

/*-----------------------------------------------------------------------------
 *  Description :
 *---------------------------------------------------------------------------*/
void CPA_State::fn_vCallBackSave( SCR_tdst_File_Description *_p_stFile, char *_p_szSectionName,
                                  void *_p_vData, SCR_tde_Ntfy_Action _eAction)
{
    CPA_State*              p_oState = (CPA_State*)_p_vData;
    char                    szActionName[SCR_CV_ui_Cfg_MaxLenName];
    char                    szIdName[SCR_CV_ui_Cfg_MaxLenName];
    char                    szSectionName[SCR_CV_ui_Cfg_MaxLenName];
    char                    szValue[10];
    int                     iIndex;
    tdxHandleToProhibit     hProhibit;
    tdxHandleToTransition   hTransition;
    BOOL                    bProhibit = p_oState -> mfn_bIsProhibitedByDefault();
    CPA_Animation*          p_oAnimation;

    switch ( _eAction )
    {
    case SCR_EA_Ntfy_AddSection:
        SCR_fn_v_SvL1_ToEndSection( _p_stFile );
    case SCR_EA_Ntfy_RebuildSection:
        // construct section name
        SCR_fn_v_RdL0_SplitSectionName( _p_szSectionName, NULL, szActionName, szIdName );
        SCR_fn_v_RdL0_ComputeSectionName( szSectionName, NULL, szActionName, szIdName );

        // save begin section
        SCR_M_SvL0_SaveBeginSection(_p_stFile, szSectionName, SCR_CC_C_Cfg_EOL );
        // save entries

        // Animation
        p_oAnimation = p_oState -> mfn_p_oGetAnimation();
        if ( p_oAnimation )
        {
            if( p_oAnimation -> GetOwner() == p_oState -> GetOwner() )
            {
                // anim of current family
                SCR_M_SvL0_SaveEntry(_p_stFile, C_Entry_Animation, SCR_CC_C_Cfg_NoChar );
                SCR_fn_v_SvL0_SaveParameters_MP(_p_stFile, SCR_EF_SvL0_Normal, 1, p_oAnimation -> fn_p_szGetName() );
            }
            else
            {
                // anim of other family
                SCR_M_SvL0_SaveEntry(_p_stFile, "ExternAnimation", SCR_CC_C_Cfg_NoChar );
                SCR_fn_v_SvL0_SaveParameters_MP(_p_stFile, SCR_EF_SvL0_Normal, 2, p_oAnimation -> fn_p_szGetName(),
                                                                                  p_oAnimation -> GetOwner() -> fn_p_szGetName() );
            }
        }

        // Repeat
        SCR_M_SvL0_SaveEntry(_p_stFile, C_Entry_Repeat, SCR_CC_C_Cfg_NoChar );
        SCR_fn_v_SvL0_SaveParameters_MP(_p_stFile, SCR_EF_SvL0_Normal, 1, itoa( p_oState -> mfn_ucGetReplay(), szValue, 10 ) );

        // Speed
        SCR_M_SvL0_SaveEntry(_p_stFile, C_Entry_Speed, SCR_CC_C_Cfg_NoChar );
        SCR_fn_v_SvL0_SaveParameters_MP(_p_stFile, SCR_EF_SvL0_Normal, 1, itoa( p_oState -> mfn_cGetSpeed(), szValue, 10 ) );

        // TransitionalState Flag
        SCR_M_SvL0_SaveEntry(_p_stFile, C_Entry_TransitionStatusFlag, SCR_CC_C_Cfg_NoChar );
        SCR_fn_v_SvL0_SaveParameters_MP(_p_stFile, SCR_EF_SvL0_Normal, 1, p_oState -> mfn_bIsProhibitedByDefault() ? C_Value_TransitionProhibitedbyDefault
                                                                                                                   : C_Value_TransitionAllowedByDefault );
        // prohibited states
        if( ! bProhibit )
        {
            iIndex = 0;
            LST2_M_StaticForEachElementOf( & p_oState -> GetStruct() -> hForProhibitArray, hProhibit, iIndex)
            {
                // get State
				tdxHandleToState        hState              = fn_hGetProhibitedStateInProhibit( hProhibit );
                CPA_State               *p_oProhibitState   = M_FindStateByEngineHandle( p_oState, hState, p_oState -> GetOwner() );
                ASSERT( p_oProhibitState );
                // save entry
                SCR_M_SvL0_SaveEntry(_p_stFile, C_Entry_ProhibitedTargetState, SCR_CC_C_Cfg_NoChar );
                SCR_fn_v_SvL0_SaveParameters_MP(_p_stFile, SCR_EF_SvL0_Normal, 1, p_oProhibitState -> fn_p_szGetName() );
            }
        }

        // allowed states
        iIndex = 0;
        LST2_M_StaticForEachElementOf( & p_oState -> GetStruct() -> hForTransitionArray, hTransition, iIndex)
        {
            tdxHandleToState    hTargetState    = fn_hGetTargetStateInTransition( hTransition );
            tdxHandleToState    hStateToGo      = fn_hGetStateToGoInTransition( hTransition );
            CPA_State           *p_oTargetState = M_FindStateByEngineHandle( p_oState, hTargetState, p_oState -> GetOwner() );
            CPA_State           *p_oStateToGo   = M_FindStateByEngineHandle( p_oState, hStateToGo, p_oState -> GetOwner() );
//ANNECY CT 11/02/98{
			unsigned char ucLink = fn_ucGetLinkingTypeInTransition(hTransition);

            if( bProhibit || ( p_oTargetState != p_oStateToGo ) || (ucLink!=C_ucStandardLink))
            {
				char szInt[5];

				sprintf(szInt,"%d",ucLink);
                SCR_M_SvL0_SaveEntry(_p_stFile, C_Entry_AddTargetState, SCR_CC_C_Cfg_NoChar );
                if( p_oStateToGo )
                    SCR_fn_v_SvL0_SaveParameters_MP(_p_stFile, SCR_EF_SvL0_Normal, 3, p_oTargetState -> fn_p_szGetName() , p_oStateToGo -> fn_p_szGetName(),szInt);
                else
                    SCR_fn_v_SvL0_SaveParameters_MP(_p_stFile, SCR_EF_SvL0_Normal, 3, p_oTargetState -> fn_p_szGetName() , p_oTargetState -> fn_p_szGetName(),szInt);
            }
//ENDANNECY CT}
        }

        // Next State
        SCR_M_SvL0_SaveEntry(_p_stFile, C_Entry_NextState, SCR_CC_C_Cfg_NoChar );
        if( p_oState -> mfn_p_oGetNextState() )
            SCR_fn_v_SvL0_SaveParameters_MP(_p_stFile, SCR_EF_SvL0_Normal, 1, p_oState -> mfn_p_oGetNextState() -> fn_p_szGetName() );
        else
            SCR_fn_v_SvL0_SaveParameters_MP(_p_stFile, SCR_EF_SvL0_Normal, 1, C_szNoState);

        // Mechanic
        if( p_oState -> mfn_p_oGetMecaCard() )
        {
            SCR_M_SvL0_SaveEntry(_p_stFile, C_Entry_LinkMechanics, SCR_CC_C_Cfg_NoChar );
            SCR_fn_v_SvL0_SaveParameters_MP(_p_stFile, SCR_EF_SvL0_Normal, 1, M_Char( p_oState -> mfn_p_oGetMecaCard() -> GetReferencedSectionName() ) );
        }

		// Custom bits
        SCR_M_SvL0_SaveEntry(_p_stFile, C_Entry_CustomBits, SCR_CC_C_Cfg_NoChar );
        SCR_fn_v_SvL0_SaveParameters_MP(_p_stFile, SCR_EF_SvL0_Normal, 1, itoa( p_oState -> mfn_ucGetCustomBits(), szValue, 10 ) );

        // save end section
        SCR_M_SvL0_SaveEndSection(_p_stFile, SCR_CC_C_Cfg_EOL );
        SCR_M_SvL0_SaveBlankLine( _p_stFile );

        // update 'Existing section' bool
        p_oState -> fn_vSectionSaved();
        break;
    case SCR_EA_Ntfy_DeleteSection:
        p_oState -> fn_vSectionDeleted();
        break;
    }
}

/*-----------------------------------------------------------------------------
 *  Constructor : create new engine state or use existing engine state
 *---------------------------------------------------------------------------*/
CPA_State::CPA_State( CPA_EditorBase *p_oEditor, CPA_BaseObject *_p_oOwnerFamily, tdxHandleToState _hEngineState /*=NULL*/,
                      CPA_Animation *p_oAnimation /*=NULL*/, CString _csStateName /*=""*/ )
          :CPA_SaveObject( p_oEditor, C_szStateTypeName, E_ss_Responsible, _p_oOwnerFamily, TRUE, fn_szGetFamiliesDataPath(),
                           CPA_State::fn_vCallBackSave ),
           CPA_EdMot<tdxHandleToState>(_hEngineState)
{
    ASSERT( _p_oOwnerFamily );
    // Section & File Name
    char szFileName[SCR_CV_ui_Cfg_MaxLenName];
    char szReferencedSectionName[SCR_CV_ui_Cfg_MaxLenName];

    strcpy( szFileName, _p_oOwnerFamily -> fn_p_szGetName() );
    strcat( szFileName, "\\" );
    strcat( szFileName, _p_oOwnerFamily -> fn_p_szGetName() );
    strcat( szFileName, ".sta" );

    SCR_fn_v_RdL0_ComputeSectionName( szReferencedSectionName, szFileName, C_szStateSectionName, "" );
    SetReferencedSectionName( szReferencedSectionName );
    SetSectionData( this );

    SetExistingSection( _hEngineState != NULL );
    //
    // Create Engine Data ????
    if( GetStruct() == NULL )
        SetStruct( fn_h_StateAlloc() );
    //
    // Name
    if( fn_eRename( _csStateName ) != E_mc_None )
        SetDefaultValidName( _csStateName );
    fn_vUpdateSectionName();
    //
    // Datas
    m_p_oNextState = NULL;
    m_p_oMecaCard = NULL;
    m_p_oAnimation = NULL;

    if ( _hEngineState != NULL )
    {
        // use existing engine state
        mfn_vInitNextState();
        // use existing meca
        mfn_vInitMechanics();
        // use existing anim
        mfn_vInitAnimation();
    }
    else
    {
        mfn_vSetReplay(1);
        mfn_vSetSpeed(1);
        mfn_vSetAnimation( p_oAnimation );
		mfn_vSetProhibitedByDefault( FALSE );	// Allowed by default
        // about saving
        fn_vNotifySave();
    }
    //
    m_bTransitional         = FALSE;
    m_oListOfTransitionStateInfo . RemoveAll();
    m_oListOfUsedAsNextState.RemoveAll () ;
    m_oListOfUsedAsTransitional.RemoveAll () ;
	m_bMustRecomputeTransitions = FALSE;
//  CPA_Ed_1 Mihaela Tancu begin
	m_iNumber=0;
//  CPA_Ed_1 Mihaela Tancu end
}

/*-----------------------------------------------------------------------------
 *  Destructor
 *---------------------------------------------------------------------------*/
CPA_State::~CPA_State(void)
{
    mfn_vResetTransitionStateInfoList();
    while ( ! m_oListOfUsedOnZAList . IsEmpty() )
    {
        free( m_oListOfUsedOnZAList . RemoveHead() );
    }
}

// ----------------------------------------------------------------------------
// Description : set engine struct
// ----------------------------------------------------------------------------
void CPA_State::SetStruct(tdxHandleToState _hState)
{
    CPA_EdMot<tdxHandleToState>::SetStruct( _hState );
}

void CPA_State::fn_vNotifyRename(void)
{
    CPA_SaveObject::fn_vNotifyRename();

    CPA_Action *p_oAction = (CPA_Action*) mfn_p_oGetAction();

    if( this == p_oAction -> mfn_p_oGetDefaultState() )
    {
        // save al IA using this Action
        CPA_DLLBase *p_oActorDLL = GetMainWorld() -> GetObjectDLLWithName( C_szDLLActorName );
		CPA_DLLBase	*pclIADLL = GetMainWorld()->GetToolDLLWithName(C_szDLLAIEditorName);
        CList< CPA_BaseObject *, CPA_BaseObject *> oList;

        if( p_oActorDLL != NULL )
        {
            p_oActorDLL -> OnQueryAction( GetEditor(), C_uiActor_ActionModif, (LPARAM)p_oAction );
            if((pclIADLL != NULL) && ( g_oCoherenceManager . m_fn_iGetFatherList( p_oAction,  &oList ) > 0 ))
            {
                POSITION xPos = oList . GetHeadPosition();
                while( xPos )
                {
                    CPA_BaseObject *p_oBsObj = oList . GetNext( xPos );
                    if( p_oBsObj -> fn_bIsOfType( C_szActorModelTypeName ) )
                        pclIADLL -> OnQueryAction( GetEditor(), C_uiAI_SaveIA, (LPARAM)p_oBsObj );
                }
            }
        }
    }
}

/******************************************************************************
 * Owner functions :
******************************************************************************/
void CPA_State::mfn_vObtainSpaceNumbers(void)
{
	CPA_State* p_oNextState = m_p_oNextState;

	while (p_oNextState->mfn_bGetTransitional())
	{	m_iNumber+=4;
		p_oNextState = p_oNextState->mfn_p_oGetNextState();
	}

}


/*-----------------------------------------------------------------------------
 *  Description : return a copy of current state
 *---------------------------------------------------------------------------*/
CPA_State * CPA_State::mfn_p_oDuplicateState(void)
{
    CPA_State *p_oNewState = new CPA_State( GetEditor(), GetOwner(), NULL, m_p_oAnimation, "CopyOf" + GetName() );
    POSITION xPos;
    tdstTransitionStateInfo *p_stTSI;

    // copy action
    p_oNewState -> mfn_vSetAction( m_p_oAction );
    // copy next state
	p_oNewState -> mfn_vSetNextState( m_p_oNextState == this ? p_oNewState : m_p_oNextState );
    // cop mechanic
    p_oNewState -> mfn_vSetMecaCard( m_p_oMecaCard );
    // copy speed
    p_oNewState -> mfn_vSetSpeed( mfn_cGetSpeed() );
    // copy replay
    p_oNewState -> mfn_vSetReplay( mfn_ucGetReplay() );
    // copy list of transitional states
    M_ForEachElement( & m_oListOfTransitionStateInfo, p_stTSI, xPos )
    {
        p_oNewState -> mfn_vSetTransitionStateInfo( p_stTSI -> p_oAction, p_stTSI-> eState, p_stTSI-> p_oStateToGo );
    }

    // copy flag 'Transitional'
    p_oNewState -> m_bTransitional = m_bTransitional;

    return p_oNewState;
}


/*-----------------------------------------------------------------------------
 *  Description : change Animation of state
 *---------------------------------------------------------------------------*/
void CPA_State::mfn_vSetAnimation(CPA_Animation *_p_oAnimation)
{
    m_p_oAnimation = _p_oAnimation;
    if(m_p_oAnimation)
        fn_vSetAnimInState( GetStruct(), (struct tdstAnim3d_*)_p_oAnimation->GetData() );
    else
        fn_vSetAnimInState( GetStruct(), NULL );

    mfn_vSetSpeed( m_p_oAnimation ? m_p_oAnimation -> mfn_ucGetFrameRate() : 0 );
}

/*-----------------------------------------------------------------------------
 *  Description : change next state of state
 *---------------------------------------------------------------------------*/
void CPA_State::mfn_vSetNextState(CPA_State *_p_oNextState, BOOL _bPreviousRemoved /*=FALSE*/)
{
    if(m_p_oNextState)
        m_p_oNextState -> mfn_vDelAsNextStateOf( this );

    // update engine struct
	if( _p_oNextState == NULL )
	{
		if( _bPreviousRemoved && m_p_oNextState && m_p_oNextState -> mfn_p_oGetNextState() &&
			(m_p_oNextState -> mfn_p_oGetNextState() != m_p_oNextState) )
			_p_oNextState = m_p_oNextState -> mfn_p_oGetNextState();
		else if( mfn_bGetTransitional() )
			_p_oNextState = mfn_p_oGetAction() -> mfn_p_oGetDefaultState();
	}
    fn_vSetNextStateInState( GetStruct(), _p_oNextState ? _p_oNextState->GetStruct() : NULL );

    // update coherence
    if(_p_oNextState)
        _p_oNextState -> mfn_vAddAsNextStateOf( this );

    m_p_oNextState = _p_oNextState;
}

/*-----------------------------------------------------------------------------
 *  Description : change mechanic of state
 *---------------------------------------------------------------------------*/
void CPA_State::mfn_vSetMecaCard(CPA_SaveObject *_p_oMeca)
{
    m_p_oMecaCard = _p_oMeca;
    if(m_p_oMecaCard)
        fn_vSetStateMechanicsIdCard( GetStruct(), (DNM_tdxHandleToMecIdentityCard)m_p_oMecaCard -> GetData() );
    else
        fn_vSetStateMechanicsIdCard( GetStruct(), NULL );
}

/*-----------------------------------------------------------------------------
 *  Description : change replay of state
 *---------------------------------------------------------------------------*/
void CPA_State::mfn_vSetReplay(unsigned char _ucReplay)
{
    fn_vSetRepeatAnimationInState( GetStruct(), (unsigned char)(_ucReplay-1) );
}

/*-----------------------------------------------------------------------------
 *  Description : change speed of state
 *---------------------------------------------------------------------------*/
void CPA_State::mfn_vSetSpeed(signed char _cSpeed)
{
    fn_vSetSpeedInState( GetStruct(), (signed char)_cSpeed);
}

/*-----------------------------------------------------------------------------
 *  Description : Set transitional state of current state
 *---------------------------------------------------------------------------*/
void CPA_State::mfn_vSetTransitional(BOOL _bTransitional, BOOL _bUpdateEngine /*=TRUE*/)
{
    m_bTransitional = _bTransitional;
	if( m_bTransitional && _bUpdateEngine && mfn_p_oGetAction() && !mfn_p_oGetNextState() )
	{
		mfn_vSetNextState( mfn_p_oGetAction() -> mfn_p_oGetDefaultState() );
	}
}

/*-----------------------------------------------------------------------------
 *  Description : Set Custom bits
 *---------------------------------------------------------------------------*/
void CPA_State::mfn_vSetCustomBits(unsigned char _ucCustomBits)
{
	fn_vSetStateCustomBits( GetStruct() , _ucCustomBits );
}

/*-----------------------------------------------------------------------------
 *  Description :
 *---------------------------------------------------------------------------*/
unsigned char CPA_State::mfn_ucGetReplay(void)
{
    return (fn_ucGetRepeatAnimationInState( GetStruct() )+1);
}

/*-----------------------------------------------------------------------------
 *  Description :
 *---------------------------------------------------------------------------*/
signed char CPA_State::mfn_cGetSpeed(void)
{
    return fn_scGetSpeedInState( GetStruct() );
}

// ----------------------------------------------------------------------------
// Description : init editor next state with engine next state
// ----------------------------------------------------------------------------
void CPA_State::mfn_vInitNextState(void)
{
    tdxHandleToState hState = fn_hGetNextStateInState( GetStruct() );

    if( !m_p_oNextState && hState)
    {
        m_p_oNextState = (CPA_State*)GetEditor() -> GetBaseObject( hState, C_szStateTypeName, mfn_p_oGetFamily() );
        if( m_p_oNextState )
            m_p_oNextState -> mfn_vAddAsNextStateOf( this );
    }
}

// ----------------------------------------------------------------------------
// Description : init editor next state with engine next state
// ----------------------------------------------------------------------------
void CPA_State::mfn_vInitMechanics(void)
{
    DNM_tdxHandleToMecIdentityCard hMeca = fn_hGetStateMechanicsIdCard( GetStruct() );

    if( !m_p_oMecaCard && hMeca )
        m_p_oMecaCard = (CPA_SaveObject*)GetMainWorld() -> fn_p_oFindObjectWithEngine( hMeca, C_szMecaCardTypeName );
}

// ----------------------------------------------------------------------------
// Description : init editor animation with engine animation
// ----------------------------------------------------------------------------
void CPA_State::mfn_vInitAnimation(void)
{
    struct tdstAnim3d_ *p_stAnim = fn_p_stGetAnimInState( GetStruct() );

    if( p_stAnim != NULL )
        m_p_oAnimation = (CPA_Animation*) GetEditor() -> GetMainWorld() -> fn_p_oFindObjectWithEngine( p_stAnim, C_szAnimationTypeName);
}

/*-----------------------------------------------------------------------------
 *  Description :
 *---------------------------------------------------------------------------*/
void CPA_State::mfn_vAddAsNextStateOf( CPA_State *_p_oState )
{
    if( fn_bIsValid() )
    {
        POSITION stPos = m_oListOfUsedAsNextState . Find ( _p_oState ) ;
        if( !stPos )
            m_oListOfUsedAsNextState . AddTail ( _p_oState ) ;
    }
}

/*-----------------------------------------------------------------------------
 *  Description :
 *---------------------------------------------------------------------------*/
void CPA_State::mfn_vDelAsNextStateOf( CPA_State *_p_oState )
{
    if( fn_bIsValid() )
    {
        POSITION stPos = m_oListOfUsedAsNextState . Find ( _p_oState ) ;
        if( stPos )
            m_oListOfUsedAsNextState . RemoveAt ( stPos ) ;
    }
}

/*-----------------------------------------------------------------------------
 *  Description :
 *---------------------------------------------------------------------------*/
void CPA_State::mfn_vAddAsTransitionalStateOf( CPA_State *_p_oState )
{
    if( fn_bIsValid() )
    {
        POSITION stPos = m_oListOfUsedAsTransitional . Find ( _p_oState ) ;
        if( !stPos )
            m_oListOfUsedAsTransitional . AddTail ( _p_oState ) ;
    }
}

/*-----------------------------------------------------------------------------
 *  Description :
 *---------------------------------------------------------------------------*/
void CPA_State::mfn_vDelAsTransitionalStateOf( CPA_State *_p_oState )
{
    if( fn_bIsValid() )
    {
        POSITION stPos = m_oListOfUsedAsTransitional . Find ( _p_oState ) ;
        if( stPos )
            m_oListOfUsedAsTransitional . RemoveAt ( stPos ) ;
    }
}

/*-----------------------------------------------------------------------------
 *  Description :
 *---------------------------------------------------------------------------*/
void CPA_State::mfn_vAddOnZAList( CPA_SaveObject *_p_oZAList, CPA_SaveObject *_p_oZA )
{
    if( fn_bIsValid() )
    {
        POSITION xPos = mfn_xGetPosOfZAListUsing( _p_oZAList );
        if ( xPos != NULL )
        {
            // update ZA
            tdstZAListInfo *p_stZAListInfo = m_oListOfUsedOnZAList . GetAt( xPos );
            p_stZAListInfo -> p_oZA = _p_oZA;
        }
        else
        {
            // add ZAList
            tdstZAListInfo *p_stZAListInfo = (tdstZAListInfo*) malloc( sizeof tdstZAListInfo );
            p_stZAListInfo -> p_oZAList = _p_oZAList;
            p_stZAListInfo -> p_oZA = _p_oZA;
            m_oListOfUsedOnZAList . AddTail( p_stZAListInfo );
        }
    }
}

/*-----------------------------------------------------------------------------
 *  Description :
 *---------------------------------------------------------------------------*/
void CPA_State::mfn_vDelOnZAList( CPA_SaveObject *_p_oZAList )
{
    if( fn_bIsValid() )
    {
        POSITION xPos = mfn_xGetPosOfZAListUsing( _p_oZAList );
        if ( xPos != NULL )
        {
            // delete
            tdstZAListInfo *p_stZAListInfo = m_oListOfUsedOnZAList . GetAt( xPos );
            m_oListOfUsedOnZAList . RemoveAt( xPos );
            free( p_stZAListInfo );
        }
    }
}

/*-----------------------------------------------------------------------------
 *  Description :
 *---------------------------------------------------------------------------*/
CPA_SaveObject *CPA_State::mfn_p_oGetZAFromZAList( CPA_SaveObject *_p_oZAList )
{
    POSITION xPos = mfn_xGetPosOfZAListUsing( _p_oZAList );
    if ( xPos != NULL )
    {
        tdstZAListInfo *p_stZAListInfo = m_oListOfUsedOnZAList . GetAt( xPos );
        return p_stZAListInfo -> p_oZA;
    }
    return NULL;
}

/*-----------------------------------------------------------------------------
 *  Description :
 *---------------------------------------------------------------------------*/
POSITION CPA_State::mfn_xGetPosOfZAListUsing( CPA_SaveObject *_p_oZAList )
{
    POSITION xPos = m_oListOfUsedOnZAList . GetHeadPosition();
    while ( xPos )
    {
        tdstZAListInfo *p_stZAListInfo = m_oListOfUsedOnZAList . GetAt( xPos );
        if( p_stZAListInfo -> p_oZAList == _p_oZAList )
            return xPos;
        m_oListOfUsedOnZAList . GetNext( xPos );
    }
    return NULL;
}

/*-----------------------------------------------------------------------------
 *  Description : return TRUE if _p_oState can be used as next state of 'this' state
 *---------------------------------------------------------------------------*/
BOOL CPA_State::mfn_bCanUseAsNextState(CPA_State *_p_oState)
{
	// no by default
	BOOL bResult = FALSE;

	// it is possible only if the target state belongs to the same action, and is valid of course...
	if( _p_oState && (_p_oState -> mfn_p_oGetAction() == mfn_p_oGetAction()) )
	{
		// if I am a transitional state
		if( mfn_bGetTransitional() )
		{
			// I cannot use myself as a next state
			if( _p_oState == this )
			{
				bResult = FALSE;
			}
			else if( _p_oState -> mfn_bGetTransitional() ) // if the target is transitional
			{
				// I can use it as next state if it doesn't chain to me, directly or indirectly
				CPA_List<CPA_State> oListOfStates;
				CPA_State *p_oDefaultState = mfn_p_oGetAction() ? mfn_p_oGetAction() -> mfn_p_oGetDefaultState() : NULL;
				BOOL bContinue = TRUE;
				CPA_State *p_oState = _p_oState;

				oListOfStates . AddTail( this );
				oListOfStates . AddTail( p_oState );
				while( bContinue )
				{
					p_oState = p_oState -> mfn_p_oGetNextState();
					POSITION xPos = oListOfStates . Find( p_oState );
					if( xPos || ( p_oState && !p_oState -> mfn_bGetTransitional() && (p_oState != p_oDefaultState) ) )
					{
						bContinue = FALSE;
						bResult = FALSE;
					}
					else if( !p_oState || (p_oState == p_oDefaultState) )
					{
						bContinue = FALSE;
						bResult = TRUE;
					}
					else
						oListOfStates . AddHead( p_oState );
				}
			}
			else // I am transitional, but the target isn't
			{
				// I can use the default state as next state
				bResult = mfn_p_oGetAction() && ( _p_oState == mfn_p_oGetAction() -> mfn_p_oGetDefaultState() );
				// if the target is not the default state, let's see if it does chain to it
				if ( !bResult )
				{
					CPA_State *p_oDefaultState = mfn_p_oGetAction() ? mfn_p_oGetAction() -> mfn_p_oGetDefaultState() : NULL;
					// we start with the target
					CPA_State *p_oState = _p_oState;
					for ( ;; )
					{
						// if I found the default state in the chain, I can use the target as a next state
						if ( p_oState == p_oDefaultState )
						{
							bResult = TRUE;
							break;
						}

						// I scanned all possible states: either the target loops to itself, or the chain ends
						if ( !p_oState )
							break;

						//go to the next in list
						p_oState = p_oState -> mfn_p_oGetNextState();

						// if it loops to itself at some point without using the default state in between
						// we break the loop, else the loop would be infinite
						// example of that case: the default state branches to the target, that loops to itself
						// -> it never encounters the default state in its own chain, but the chain doesn't end either...
						if ( p_oState == _p_oState )
							break;
					}
				}
			}
		}
		else // I am not a transitional state
		{
			// I can use the target as next state only if it is not transitional
			bResult = !_p_oState -> mfn_bGetTransitional();
		}
	}
	return bResult;
}

 //////////////////////////////////////////////////////////////////////////////////////////////////
 // new transision state info functions
 //////////////////////////////////////////////////////////////////////////////////////////////////

// ----------------------------------------------------------------------------
// Author      : Marc Trabucato               Creation : 17/11/97
// Description : set ucTransitionStatusFlag
// ----------------------------------------------------------------------------
void CPA_State::mfn_vSetProhibitedByDefault (BOOL _bProhibit /*=FALSE*/)
{
    fn_vSetTransitionStatusFlagInState( GetStruct(), _bProhibit ? C_ucProhibitedState : C_ucAllowedState );
}

// ----------------------------------------------------------------------------
// Author      : Marc Trabucato               Creation : 17/11/97
// Description : set the transition state of the given action
// ----------------------------------------------------------------------------
void CPA_State::mfn_vSetTransitionStateInfo(CPA_Action *_p_oAction, tdeTransitionState _eState, CPA_State *_p_oState /*=NULL*/, BOOL _bOnInit /*=FALSE*/)
{
    ASSERT( _p_oAction );

    tdstTransitionStateInfo *p_stTSI        = mfn_p_stGetTransitionStateInfo( _p_oAction );

//ANNECY CT 11/02/98{
    if( _eState == E_ts_Fluid )
    {
        // take account transition
        if( p_stTSI == NULL )
        {
            p_stTSI = (tdstTransitionStateInfo*) malloc( sizeof tdstTransitionStateInfo );
            p_stTSI -> p_oAction    = _p_oAction;
            p_stTSI -> p_oStateToGo = NULL;
            p_stTSI -> eState       = E_ts_Unknown;
            m_bMustRecomputeTransitions = !_bOnInit;
			m_oListOfTransitionStateInfo . AddTail( p_stTSI );
        }
        if( mfn_bIsProhibitedByDefault() || ( ( p_stTSI -> p_oStateToGo != _p_oState ) && ( _p_oState != _p_oAction -> mfn_p_oGetDefaultState() ) ) )
        {
            //
            if( p_stTSI -> p_oStateToGo )
                p_stTSI -> p_oStateToGo -> mfn_vDelAsTransitionalStateOf( this );

            p_stTSI -> p_oStateToGo = _p_oState;
            m_bMustRecomputeTransitions = !_bOnInit;
            //
            if( p_stTSI -> p_oStateToGo )
                p_stTSI -> p_oStateToGo -> mfn_vAddAsTransitionalStateOf( this );
        }
		//
		if( mfn_bIsProhibitedByDefault() )
		{
			p_stTSI -> p_oAction -> mfn_vInterruptState( this );
		}
		else
		{
			p_stTSI -> p_oAction -> mfn_vDontInterruptState( this );
		}
	}
	else
//ENDANNECY CT}
    if( _eState == E_ts_Allowed )
    {
        // take account transition
        if( p_stTSI == NULL )
        {
            p_stTSI = (tdstTransitionStateInfo*) malloc( sizeof tdstTransitionStateInfo );
            p_stTSI -> p_oAction    = _p_oAction;
            p_stTSI -> p_oStateToGo = NULL;
            p_stTSI -> eState       = E_ts_Unknown;
            m_bMustRecomputeTransitions = !_bOnInit;
			m_oListOfTransitionStateInfo . AddTail( p_stTSI );
        }

        if( mfn_bIsProhibitedByDefault() || ( ( p_stTSI -> p_oStateToGo != _p_oState ) && ( _p_oState != _p_oAction -> mfn_p_oGetDefaultState() ) ) )
        {
            //
            if( p_stTSI -> p_oStateToGo )
                p_stTSI -> p_oStateToGo -> mfn_vDelAsTransitionalStateOf( this );

            p_stTSI -> p_oStateToGo = _p_oState;
            m_bMustRecomputeTransitions = !_bOnInit;
            //
            if( p_stTSI -> p_oStateToGo )
                p_stTSI -> p_oStateToGo -> mfn_vAddAsTransitionalStateOf( this );
        }
		//
		if( mfn_bIsProhibitedByDefault() )
		{
			p_stTSI -> p_oAction -> mfn_vInterruptState( this );
		}
		else
		{
			p_stTSI -> p_oAction -> mfn_vDontInterruptState( this );
		}
    }
    else if( _eState == E_ts_Prohibited )
    {
        // take account transition
        if( p_stTSI == NULL )
        {
            p_stTSI = (tdstTransitionStateInfo*) malloc( sizeof tdstTransitionStateInfo );
            p_stTSI -> p_oAction    = _p_oAction;
            p_stTSI -> eState       = E_ts_Unknown;
			p_stTSI -> p_oStateToGo = NULL;
            m_bMustRecomputeTransitions = !_bOnInit;
			m_oListOfTransitionStateInfo . AddTail( p_stTSI );
        }

        if( p_stTSI -> p_oStateToGo )
            p_stTSI -> p_oStateToGo -> mfn_vDelAsTransitionalStateOf( this );
        p_stTSI -> p_oStateToGo = NULL;
		//
		if( mfn_bIsProhibitedByDefault() )
		{
			p_stTSI -> p_oAction -> mfn_vDontInterruptState( this );
		}
		else
		{
			p_stTSI -> p_oAction -> mfn_vInterruptState( this );
		}
    }
    else  // _eState == E_ts_Unknown
    {
		// 
		if( mfn_bIsProhibitedByDefault() && p_stTSI -> p_oAction )
		{
			p_stTSI -> p_oAction -> mfn_vDontInterruptState( this );
		}
    }
    // update state
    if( p_stTSI && ( p_stTSI -> eState != _eState ) )
    {
        p_stTSI -> eState = _eState;
        m_bMustRecomputeTransitions = !_bOnInit;
    }
}

// ----------------------------------------------------------------------------
// Author      : Marc Trabucato               Creation : 17/11/97
// Description : update engine transition list and engine prohibited list
// ----------------------------------------------------------------------------
BOOL CPA_State::mfn_bUpdateTransitionStateList( void )
{
    if( m_bMustRecomputeTransitions )
    {
        tdstTransitionStateInfo* p_stTSI = NULL;
        POSITION                 xPos;
        BOOL                     bProhibState = mfn_bIsProhibitedByDefault();

		// get first engine list element
		tdxHandleToProhibit		hFreeProhibit	= LST2_M_StaticGetFirstElement( & GetStruct() -> hForProhibitArray );
		tdxHandleToTransition   hFreeTransition = LST2_M_StaticGetFirstElement( & GetStruct() -> hForTransitionArray );
		//
		//
        M_ForEachElement( &m_oListOfTransitionStateInfo, p_stTSI, xPos )
        {
//ANNECY CT 11/02/98{
			unsigned char ucLink = C_ucStandardLink;
//ENDANNECY CT}
            switch( p_stTSI -> eState )
            {
//ANNECY CT 11/02/98{
            case E_ts_Fluid:
				ucLink = C_ucProportionalLink;
//ENDANNECY CT}
            case E_ts_Allowed:
                if( p_stTSI && p_stTSI -> p_oAction && p_stTSI -> p_oAction -> mfn_p_oGetDefaultState() )
                {
                    CPA_State *p_oTargetState = p_stTSI -> p_oAction -> mfn_p_oGetDefaultState();

                    // add on transitional states list ?
                    if( bProhibState ||  // only existing Transition must interrupt state
//ANNECY CT 11/02/98{
						(ucLink == C_ucProportionalLink) ||
//ENDANNECY CT}
                        p_stTSI -> p_oStateToGo )  // need Transition to precise state to go
                    {
						if( hFreeTransition == NULL )
						{
							hFreeTransition = fn_h_TransitionAlloc();
							LST2_M_StaticAddTail( & GetStruct() -> hForTransitionArray, hFreeTransition );
							fn_vSetTargetStateInTransition( hFreeTransition, p_oTargetState -> GetStruct() );
							fn_vSetStateToGoInTransition( hFreeTransition, p_stTSI -> p_oStateToGo ? p_stTSI -> p_oStateToGo -> GetStruct() : p_oTargetState -> GetStruct() );
//ANNECY CT 11/02/98{
							fn_vSetLinkingTypeInTransition(hFreeTransition,ucLink);
//ENDANNECY CT}
							hFreeTransition = NULL;
						}
						else
						{
							fn_vSetTargetStateInTransition( hFreeTransition, p_oTargetState -> GetStruct() );
							fn_vSetStateToGoInTransition( hFreeTransition, p_stTSI -> p_oStateToGo ? p_stTSI -> p_oStateToGo -> GetStruct() : p_oTargetState -> GetStruct() );
//ANNECY CT 11/02/98{
							fn_vSetLinkingTypeInTransition(hFreeTransition,ucLink);
//ENDANNECY CT}
							hFreeTransition = LST2_M_StaticGetNextElement( hFreeTransition );
						}
                    }
                }
                break;
            case E_ts_Prohibited:
                if( p_stTSI && p_stTSI -> p_oAction && p_stTSI -> p_oAction -> mfn_p_oGetDefaultState() )
                {
                    CPA_State *p_oTargetState = p_stTSI -> p_oAction -> mfn_p_oGetDefaultState();

                    // add on prohibited list ?
                    if( !bProhibState ) // only existing existing prohibited states are prohibited !!!
                    {
						if( hFreeProhibit == NULL )
                        {
                            hFreeProhibit = fn_h_ProhibitAlloc();
                            fn_vSetProhibitedStateInProhibit( hFreeProhibit, p_oTargetState -> GetStruct() );
                            LST2_M_StaticAddTail( & GetStruct() -> hForProhibitArray, hFreeProhibit );
							hFreeProhibit = NULL;
                        }
						else
						{
							fn_vSetProhibitedStateInProhibit( hFreeProhibit, p_oTargetState -> GetStruct() );
							hFreeProhibit = LST2_M_StaticGetNextElement( hFreeProhibit );
						}
                    }
                }
                break;
            case E_ts_Unknown:
                // nothing to do
                break;
            }
        }
		// clear unused hTransition
		if( hFreeTransition )
		{
			do
			{
				tdxHandleToTransition   hNextTransition = LST2_M_StaticGetNextElement( hFreeTransition );
				LST2_M_StaticIsolate( hFreeTransition );
				fn_h_TransitionFree( hFreeTransition );
				hFreeTransition = hNextTransition;
			} while( hFreeTransition );
		}
		// clear unused hProhibit
		if( hFreeProhibit )
		{
			do
			{
				tdxHandleToProhibit		hNextProhibit	= LST2_M_StaticGetNextElement( hFreeProhibit );
				LST2_M_StaticIsolate( hFreeProhibit );
				fn_h_ProhibitFree( hFreeProhibit );
				hFreeProhibit = hNextProhibit;
			} while( hFreeProhibit );
		}

    }
    m_bMustRecomputeTransitions = FALSE;

	return TRUE;
}

// ----------------------------------------------------------------------------
// Author      : Marc Trabucato               Creation : 17/11/97
// Description : fill transitionStateInfo list with engine transition list and engine prohibited list
// ----------------------------------------------------------------------------
void CPA_State::mfn_vFillTransitionStateList( void )
{
    tdxHandleToTransition   hTransition;
    tdxHandleToProhibit     hProhibit;
    int                     iIndex;

    // reset list
    mfn_vResetTransitionStateInfoList();
    // add transition list
    iIndex = 0;
    LST2_M_StaticForEachElementOf( & GetStruct() -> hForTransitionArray, hTransition, iIndex)
    {
        // get Target State and State To Go
        tdxHandleToState        hTargetState    = fn_hGetTargetStateInTransition( hTransition );
        tdxHandleToState        hStateToGo      = fn_hGetStateToGoInTransition( hTransition );
        CPA_State               *p_oTargetState = M_FindStateByEngineHandle( this, hTargetState, GetOwner() );
// Shaitan => state list in the level
		if (!p_oTargetState)
		{
			hTargetState = mfn_p_oGetAction()->mfn_hGetStateFromLinkTable((char *)hTargetState, (char *) (LPCSTR) mfn_p_oGetFamily()->GetName());
			fn_vSetTargetStateInTransition(hTransition, hTargetState);
			p_oTargetState = M_FindStateByEngineHandle( this, hTargetState, GetOwner() );		
		}
// End Shaitan => state list in the level
        CPA_State               *p_oStateToGo   = M_FindStateByEngineHandle( this, hStateToGo, GetOwner() );
// Shaitan => state list in the level
		if (!p_oStateToGo)
		{
			hStateToGo = mfn_p_oGetAction()->mfn_hGetStateFromLinkTable((char *)hStateToGo, (char *) (LPCSTR) mfn_p_oGetFamily()->GetName());
			if (hStateToGo)
			{
				fn_vSetTargetStateInTransition(hTransition, hStateToGo);
				p_oStateToGo = M_FindStateByEngineHandle( this, hStateToGo, GetOwner() );	
			}
		}
// End Shaitan => state list in the level
        ASSERT( p_oTargetState );
        CPA_Action              *p_oAction      = p_oTargetState -> mfn_p_oGetAction();
        //
//ANNECY CT 11/02/98{
		if (fn_ucGetLinkingTypeInTransition(hTransition) == C_ucProportionalLink) 
			mfn_vSetTransitionStateInfo( p_oAction, E_ts_Fluid, p_oStateToGo, TRUE );
		else
			mfn_vSetTransitionStateInfo( p_oAction, E_ts_Allowed, p_oStateToGo, TRUE );
//ENDANNECY CT}
    }
    // add prohibited states
    iIndex = 0;
    LST2_M_StaticForEachElementOf( & GetStruct() -> hForProhibitArray, hProhibit, iIndex)
    {
        // get State
		tdxHandleToState        hState      = fn_hGetProhibitedStateInProhibit( hProhibit );
        CPA_State               *p_oState   = M_FindStateByEngineHandle( this, hState, GetOwner() );
// Shaitan => state list in the level
		if (!p_oState)
		{
			hState = mfn_p_oGetAction()->mfn_hGetStateFromLinkTable((char *)hState, (char *) (LPCSTR) mfn_p_oGetFamily()->GetName());
			fn_vSetProhibitedStateInProhibit(hProhibit, hState);
			p_oState = M_FindStateByEngineHandle( this, hState, GetOwner() );		
		}
// End Shaitan => state list in the level
        ASSERT( p_oState );
        CPA_Action              *p_oAction  = p_oState -> mfn_p_oGetAction();
        //
        mfn_vSetTransitionStateInfo( p_oAction, E_ts_Prohibited, NULL, TRUE );
    }
}

// ----------------------------------------------------------------------------
// Author      : Marc Trabucato               Creation : 17/11/97
// Description : clear list
// ----------------------------------------------------------------------------
void CPA_State::mfn_vResetTransitionStateInfoList( void )
{
    while( ! m_oListOfTransitionStateInfo . IsEmpty() )
    {
		tdstTransitionStateInfo* p_stTSI = m_oListOfTransitionStateInfo . RemoveHead();
		//
		if( p_stTSI -> p_oAction )
			p_stTSI -> p_oAction -> mfn_vDontInterruptState( this );
		//
        if( p_stTSI -> p_oStateToGo )
            p_stTSI -> p_oStateToGo -> mfn_vDelAsTransitionalStateOf( this );
		//
        free( p_stTSI );
    }
}

// ----------------------------------------------------------------------------
// Author      : Marc Trabucato               Creation : 17/11/97
// Description : return tdstTransitionStateInfo struct associated with given
//             : action or NULL else
// ----------------------------------------------------------------------------
tdstTransitionStateInfo* CPA_State::mfn_p_stGetTransitionStateInfo( CPA_Action *_p_oAction )
{
    tdstTransitionStateInfo* p_stResult = NULL;
    POSITION                 xPos;

    M_ForEachElement( &m_oListOfTransitionStateInfo, p_stResult, xPos )
    {
        if( p_stResult -> p_oAction == _p_oAction )
            return p_stResult;
    }
    return NULL;
}

// ----------------------------------------------------------------------------
// Author      : Marc Trabucato               Creation : 17/11/97
// Description : remove given state from transition list
// ----------------------------------------------------------------------------
void CPA_State::mfn_vRemoveStateFromTransition( CPA_State *_p_oState )
{
    ASSERT( _p_oState );

    tdstTransitionStateInfo *p_stTSI = mfn_p_stGetTransitionStateInfo( _p_oState -> mfn_p_oGetAction() );

    if( p_stTSI )
    {
        if( _p_oState -> mfn_bGetTransitional() )
        {
            if( ( p_stTSI -> eState == E_ts_Allowed ) && ( p_stTSI -> p_oStateToGo == _p_oState ) )
            {
                mfn_vSetTransitionStateInfo( _p_oState -> mfn_p_oGetAction(), E_ts_Allowed, NULL );
            }
        }
    }
}

// ----------------------------------------------------------------------------
// Author      : Marc Trabucato               Creation : 17/11/97
// Description : remove TSI associated with given action
// ----------------------------------------------------------------------------
void CPA_State::mfn_vRemoveActionFromTransition( CPA_Action *_p_oAction )
{
    ASSERT( _p_oAction );

    tdstTransitionStateInfo *p_stTSI = NULL;
    POSITION                xPos = NULL;

    xPos = m_oListOfTransitionStateInfo . GetHeadPosition();

    while ( xPos )
    {
        p_stTSI = m_oListOfTransitionStateInfo . GetAt( xPos );
        if( p_stTSI -> p_oAction == _p_oAction )
        {
            m_oListOfTransitionStateInfo . RemoveAt( xPos );
            m_bMustRecomputeTransitions = TRUE;
            xPos = NULL;
        }
        else
            m_oListOfTransitionStateInfo . GetNext( xPos );
    }
}

// ----------------------------------------------------------------------------
// Author      : Marc Trabucato               Creation : 17/11/97
// Description : TRUE if the given action is allowed fir the current state
// ----------------------------------------------------------------------------
BOOL CPA_State::mfn_bIsActionProhibited( CPA_Action *_p_oAction )
{
	tdeTransitionState eState = mfn_eGetTransitionForAction( _p_oAction );

//ANNECY CT 11/02/98{
	//return ( ( mfn_bIsProhibitedByDefault() && (  eState != E_ts_Allowed ) ) || ( eState == E_ts_Prohibited ) );
	return ((mfn_bIsProhibitedByDefault() && 
		     !((eState == E_ts_Allowed) || (eState == E_ts_Fluid))) ||
			(eState == E_ts_Prohibited ));
//ENDANNECY CT}
}

// ----------------------------------------------------------------------------
// Author      : Marc Trabucato               Creation : 17/11/97
// Description : return the tdeTransitionState for given action on state
// ----------------------------------------------------------------------------
tdeTransitionState CPA_State::mfn_eGetTransitionForAction( CPA_Action *_p_oAction )
{
    ASSERT( _p_oAction );

	tdstTransitionStateInfo *p_stTSI = mfn_p_stGetTransitionStateInfo( _p_oAction );
	return ( p_stTSI ? p_stTSI -> eState : E_ts_Unknown );
}



#endif // ACTIVE_EDITOR
