/*=============================================================================
 *
 *  Filename:           DlgState.cpp : implementation file
 *  Version:            1.0
 *  Date:				02/01/97
 *  Author:             V.L.
 *
 *  Description:		implementation of a FormView Dialog class for animaction
 *						parameters
 *
 *===========================================================================*/

#include "stdafx.h"

#include "acp_base.h"
#include "ITF.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"
#include "DlgState.hpp"
#include "STModif.hpp"
#include "DlgSelect.hpp"

#include "TUT.h"

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

/*=============================================================================
* Constants
=============================================================================*/
#define C_iMinReplay       1
#define C_iMaxReplay     100
#define C_iMinSpeed       10
#define C_iMaxSpeed       60
#define C_iBorderSize      4

// PopupMenu IDs
#define C_uiPMActive			5000
#define C_uiPMExtendToFamily	(C_uiPMActive + 1)
#define C_uiPMExtendToAction	(C_uiPMActive + 2)
#define C_uiPMExtendToSelection	(C_uiPMActive + 3)
#define C_uiPMDisplayAll        (C_uiPMActive + 4)
#define C_uiPMDisplayAllowed    (C_uiPMActive + 5)
#define C_uiPMDisplayProhibited (C_uiPMActive + 6)
#define C_uiPMDefaultProhibited (C_uiPMActive + 7)
#define C_uiPMDefaultAllowed    (C_uiPMActive + 8)
#define C_uiPMActionAllows      (C_uiPMActive + 9)
#define C_uiPMActionProhibits   (C_uiPMActive + 10)
#define C_uiPMActionDefault		(C_uiPMActive + 11)
#define C_uiPMState             (C_uiPMActive + 12)  // must be the last one

/*=============================================================================
* Macro to acces current state or different dialog item
=============================================================================*/
#define M_p_oCurrentState()         (m_p_oParentDLL->mfn_p_oGetCurrentState())
#define M_p_oCurrentAction()         (m_p_oParentDLL->mfn_p_oGetCurrentAction())
#define M_p_oCurrentFamily()         (m_p_oParentDLL->mfn_p_oGetCurrentFamily())

#define M_p_oCBItem(nID)            ((CComboBox*)GetDlgItem(nID))
#define M_p_oComboFamily()          M_p_oCBItem(IDC_COMBO_FAMILY)
#define M_p_oComboAnimation()       M_p_oCBItem(IDC_COMBO_ANIMATION)
#define M_p_oComboNextState()       M_p_oCBItem(IDC_COMBO_NEXTSTATE)
#define M_p_oComboMeca()            M_p_oCBItem(IDC_COMBO_MECHANIC)
#define M_p_oComboInterruptState()  M_p_oCBItem(IDC_COMBO_INTERRUPTSTATE)
#define M_p_oListAction()           ((CListBox *)GetDlgItem(IDC_LIST_INTERRUPTACTION))
#define M_p_oBTID(nID)              ((CButton*)GetDlgItem(nID))
#define M_p_oSPSpeed()              ((CSpinButtonCtrl*) GetDlgItem(IDC_SPIN_SPEED))
#define M_p_oSPReplay()             ((CSpinButtonCtrl*) GetDlgItem(IDC_SPIN_REPLAY))
#define M_p_oEditItem(nID)            ((CEdit*)GetDlgItem(nID))
#define M_EnableID( nID, bEnable)   (GetDlgItem(nID)->EnableWindow(bEnable))


#define M_GetClientRect( pWnd, poRect )    (pWnd) -> GetWindowRect( poRect );ScreenToClient( poRect )
#define M_GetClientRectId( Id, poRect )    M_GetClientRect( GetDlgItem( Id ), poRect )
#define M_SetClientRect( pWnd, poRect )    (pWnd) -> MoveWindow( poRect )
#define M_SetClientRectId( Id, poRect )    M_SetClientRect( GetDlgItem( Id ), poRect )

#define M_MoveRectId( nID, x, y)\
{\
    CRect oRect;\
    \
    M_GetClientRectId( nID, &oRect );\
    oRect . OffsetRect( x, y );\
    M_SetClientRectId( nID, &oRect );\
}


#define M_MakeDo( p_oModif )               m_p_oParentDLL -> M_GetEditManager() -> AskFor ( p_oModif )

/*=============================================================================
* CDlgState class
=============================================================================*/
IMPLEMENT_DYNCREATE(CDlgState,CFormView)

/*-----------------------------------------------------------------------------
 *  Description : constructor
 *---------------------------------------------------------------------------*/
CDlgState::CDlgState(): CFormView(CDlgState::IDD)
{
    //{{AFX_DATA_INIT(CDlgState)
	//}}AFX_DATA_INIT
	m_bFirstShow = TRUE;
    // create Prohibited BMP
	m_oProhibitedDC.CreateCompatibleDC( NULL );
	m_oProhibitedBitmap.LoadBitmap( IDB_BITMAP_PROHIBITED );
	m_oProhibitedDC.SelectObject(m_oProhibitedBitmap);
    // create Allowed BMP
	m_oAllowedDC.CreateCompatibleDC( NULL );
	m_oAllowedBitmap.LoadBitmap( IDB_BITMAP_ALLOWED );
	m_oAllowedDC.SelectObject(m_oAllowedBitmap);
//ANNECY CT 11/02/98{
    // create Fluid BMP
	m_oFluidDC.CreateCompatibleDC( NULL );
	m_oFluidBitmap.LoadBitmap( IDB_BITMAP_FLUID );
	m_oFluidDC.SelectObject(m_oFluidBitmap);
//ENDANNECY CT}
    // create bold font
    PLOGFONT plf = (PLOGFONT) LocalAlloc(LPTR, sizeof(LOGFONT));
    lstrcpy(plf->lfFaceName, "MS Sans Serif");
    plf->lfWeight = FW_BOLD ;
    plf->lfHeight = 8;
    plf->lfEscapement = 0;
    m_oBoldFont.CreateFontIndirect(plf);
    //
    m_p_oParentDLL = NULL;
    m_bAllFamilies = FALSE;
}

/*-----------------------------------------------------------------------------
 *  Description : destructor
 *---------------------------------------------------------------------------*/
CDlgState::~CDlgState()
{
    m_oAllowedBitmap.DeleteObject();
    m_oAllowedDC.DeleteDC();
    m_oProhibitedBitmap.DeleteObject();
    m_oProhibitedDC.DeleteDC();
//ANNECY CT 11/02/98{
    m_oFluidBitmap.DeleteObject();
    m_oFluidDC.DeleteDC();
//ENDANNECY CT}
    m_oBoldFont.DeleteObject();
}

/*-----------------------------------------------------------------------------
 *  Description : data exchange
 *---------------------------------------------------------------------------*/
void CDlgState::DoDataExchange(CDataExchange* pDX)
{
	CFormView::DoDataExchange(pDX);
    //{{AFX_DATA_MAP(CDlgState)
	//}}AFX_DATA_MAP
}

BOOL CDlgState::Create( LPCTSTR lpszClassName, LPCTSTR lpszWindowName,
                        DWORD dwRequestedStyle, const RECT& rect, CWnd* pParentWnd, UINT nID,
                        CCreateContext* pContext )
{
    BOOL bResult = CFormView::Create( lpszClassName, lpszWindowName, dwRequestedStyle, rect, pParentWnd, nID, pContext );
    // register controls
    TUT_M_vGetTutDll();
    TUT_M_vRegisterControlID( IDC_COMBO_ANIMATION, "TAC_STM_STATECONTENTS_CBANIM", TUT_e_ComboBox );
    // TUT_M_vRegisterControlID( IDC_SPIN_REPLAY, "TAC_STM_STATECONTENTS_SPREPLAY", TUT_e_Spin );
    // TUT_M_vRegisterControlID( IDC_SPIN_SPEED, "TAC_STM_STATECONTENTS_SPSPEED", TUT_e_Spin );
    TUT_M_vRegisterControlID( IDC_COMBO_NEXTSTATE, "TAC_STM_STATECONTENTS_CBNEXTSTATE", TUT_e_ComboBox );
    TUT_M_vRegisterControlID( IDC_COMBO_MECHANIC, "TAC_STM_STATECONTENTS_CBMECA", TUT_e_ComboBox );
    TUT_M_vRegisterControlID( IDC_BT_DEFAULT, "TAC_STM_STATECONTENTS_BTDEFAULT", TUT_e_Button );
    TUT_M_vRegisterControlID( IDC_BT_DISPLAY, "TAC_STM_STATECONTENTS_BTDISPLAY", TUT_e_Button );
    TUT_M_vRegisterControlID( IDC_LIST_INTERRUPTACTION, "TAC_STM_STATECONTENTS_LBITACTION", TUT_e_ListBox );
    TUT_M_vRegisterControlID( IDC_COMBO_INTERRUPTSTATE, "TAC_STM_STATECONTENTS_CBITSTATE", TUT_e_ComboBox );
    TUT_M_vRegisterControlID( IDC_BT_MORE, "TAC_STM_STATECONTENTS_BTMORE", TUT_e_Button );
    TUT_M_vRegisterControlID( IDC_COMBO_FAMILY, "TAC_STM_STATECONTENTS_CBFAMILY", TUT_e_ComboBox );
    //
    return bResult;
}

/*-----------------------------------------------------------------------------
 *  Description : message map
 *---------------------------------------------------------------------------*/
BEGIN_MESSAGE_MAP(CDlgState, CFormView)
    //{{AFX_MSG_MAP(CDlgState)
    ON_WM_DESTROY()
	ON_WM_SHOWWINDOW()
	ON_WM_SIZE()
	ON_WM_DRAWITEM()
	ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN_REPLAY, OnDeltaposSpinReplay)
	ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN_SPEED, OnDeltaposSpinSpeed)
	ON_EN_KILLFOCUS(IDC_EDIT_REPLAY, OnChangeReplay)
	ON_EN_KILLFOCUS(IDC_EDIT_SPEED, OnChangeSpeed)
    ON_BN_CLICKED(IDC_BT_DEFAULT, OnCheckDefault)
    ON_BN_CLICKED(IDC_BT_DISPLAY, OnCheckDisplay)
	ON_BN_CLICKED(IDC_BT_MORE, OnBtMore)
	ON_CBN_SELCHANGE(IDC_COMBO_ANIMATION, OnSelchangeComboAnimation)
	ON_CBN_SELCHANGE(IDC_COMBO_INTERRUPTSTATE, OnSelchangeComboInterruptstate)
	ON_CBN_SELCHANGE(IDC_COMBO_NEXTSTATE, OnSelchangeComboNextstate)
	ON_CBN_SELCHANGE(IDC_COMBO_MECHANIC, OnSelchangeComboMechanic)
	ON_LBN_SELCHANGE(IDC_LIST_INTERRUPTACTION, OnSelchangeListInterruptaction)
	ON_CBN_SELCHANGE(IDC_COMBO_FAMILY, OnSelchangeComboFamily)
	ON_CONTROL_RANGE(BN_CLICKED,IDC_CHECK_CB1,IDC_CHECK_CB8, OnCBClicked)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/******************************************************************************
* CDlgActionContents diagnostics
******************************************************************************/
#ifdef _DEBUG
void CDlgState::AssertValid() const
{
	CFormView::AssertValid();
}

void CDlgState::Dump(CDumpContext& dc) const
{
	CFormView::Dump(dc);
}
#endif //_DEBUG

/******************************************************************************
* CDlgState message handlers
******************************************************************************/

void CDlgState::OnDestroy()
{
    // register controls
    TUT_M_vGetTutDll();
    TUT_M_vUnregisterControlID( IDC_COMBO_ANIMATION );
    // TUT_M_vUnregisterControlID( IDC_SPIN_REPLAY );
    // TUT_M_vUnregisterControlID( IDC_SPIN_SPEED );
    TUT_M_vUnregisterControlID( IDC_COMBO_NEXTSTATE );
    TUT_M_vUnregisterControlID( IDC_COMBO_MECHANIC );
    TUT_M_vUnregisterControlID( IDC_BT_DEFAULT );
    TUT_M_vUnregisterControlID( IDC_BT_DISPLAY );
    TUT_M_vUnregisterControlID( IDC_LIST_INTERRUPTACTION );
    TUT_M_vUnregisterControlID( IDC_COMBO_INTERRUPTSTATE );
    TUT_M_vUnregisterControlID( IDC_BT_MORE );
    TUT_M_vUnregisterControlID( IDC_COMBO_FAMILY );
    //
    CFormView::OnDestroy();
}

/*-----------------------------------------------------------------------------
 *  Description : intercept the popup menu entry
 *---------------------------------------------------------------------------*/
BOOL CDlgState::OnCommand(WPARAM wParam, LPARAM lParam)
{
	if( lParam != 0 )
		return CFormView::OnCommand(wParam, lParam);


    int iID = LOWORD(wParam);

    switch ( iID )
    {
    case C_uiPMExtendToFamily:      OnBtExtendfamily();                             break;
    case C_uiPMExtendToAction:      OnBtExtendaction();                             break;
    case C_uiPMExtendToSelection:   OnBtExtendselection();                          break;
    case C_uiPMDisplayAll:          mfn_vSetDisplayTransition( E_dt_All );          break;
    case C_uiPMDisplayAllowed:      mfn_vSetDisplayTransition( E_dt_Allowed );      break;
    case C_uiPMDisplayProhibited:   mfn_vSetDisplayTransition( E_dt_Prohibited );   break;
    case C_uiPMDefaultProhibited:
    case C_uiPMDefaultAllowed:      OnCheckDefault();                               break;
    case C_uiPMActionAllows:        mfn_vSetTransitions( E_ts_Allowed );            break;
    case C_uiPMActionProhibits:     mfn_vSetTransitions( E_ts_Prohibited );         break;
    case C_uiPMActionDefault:       mfn_vSetTransitions( E_ts_Unknown );            break;
    default:
        if( iID >= C_uiPMState && ( M_p_oListAction() -> GetSelCount() == 1 ) )
        {
            int iIndexState  = iID - C_uiPMState;
            CListBox    *pLB = M_p_oListAction();
            CComboBox   *pCB = M_p_oComboInterruptState();
            int iIndexAction = pLB->GetCurSel();

            if ( iIndexState < pLB->GetCount() )
            {
                State_ModifTransition   *p_oModifTransition = NULL;
                CPA_Action              *p_oAction          = NULL;
                CPA_State               *p_oState           = M_p_oCurrentState();

                // find current action
                if( mfn_bGetTSIAndActionFromIndex( iIndexAction, NULL, &p_oAction ) && ( ! p_oState -> mfn_bIsActionProhibited( p_oAction ) ) )
                {
                    // update state to go
                    p_oModifTransition = new State_ModifTransition( m_p_oParentDLL, p_oState, p_oAction, E_ts_Allowed, (CPA_State*) pCB -> GetItemData(iIndexState) );
                    M_MakeDo( p_oModifTransition );
                }
            }
        }
    }

	return CFormView::OnCommand(wParam, lParam);
}

/*-----------------------------------------------------------------------------
 *  Description : intercept the Rbutton Click on listbox
 *---------------------------------------------------------------------------*/
BOOL CDlgState::PreTranslateMessage(MSG* pMsg)
{
    CListBox    *pLB         = M_p_oListAction();
    BOOL        bResult      = FALSE;    // default

    if ( pMsg -> hwnd == GetDlgItem( IDC_LIST_INTERRUPTACTION ) -> m_hWnd )
    {
        switch ( pMsg->message )
        {
        case WM_RBUTTONDOWN:
            if ( ! ( GetKeyState( VK_LBUTTON ) & 0x8000 ) )
                bResult = mfn_bOnRButtonDownListBoxAction ( pMsg ) ;
            break;
        case WM_LBUTTONDOWN:
            bResult = mfn_bOnLButtonDownListBoxAction ( pMsg ) ;
            break;
        default:
            bResult = CFormView::PreTranslateMessage(pMsg);
        }
    }
    else
        bResult = CFormView::PreTranslateMessage(pMsg);

	return bResult;
}

/*-----------------------------------------------------------------------------
 *  Description : handle function for message WM_DRAWITEM
 *---------------------------------------------------------------------------*/
void CDlgState::OnDrawItem(int nIDCtl, LPDRAWITEMSTRUCT lpDIS)
{
    if ( (nIDCtl == IDC_LIST_INTERRUPTACTION) &&
         (M_p_oListAction()->IsWindowEnabled() ) &&
         (lpDIS->itemID != LB_ERR) )
    {   // Draw ListBox transitions
        mfn_vOnDrawItemListBoxAction ( lpDIS ) ;
    }
    else if ( (nIDCtl == IDC_COMBO_INTERRUPTSTATE) &&
              (M_p_oComboInterruptState()->IsWindowEnabled() ) &&
              (lpDIS->itemID != CB_ERR) )
    {   // Draw ComboBox Transitional States
        mfn_vOnDrawItemComboBoxInterruptState ( lpDIS ) ;
    }
    else if ( (nIDCtl == IDC_COMBO_NEXTSTATE) &&
              (M_p_oComboNextState()->IsWindowEnabled() ) &&
              (lpDIS->itemID != CB_ERR) )
    {   // Draw ComboBox NextState
        mfn_vOnDrawItemComboBoxNextState ( lpDIS ) ;
    }
    else
		CFormView::OnDrawItem(nIDCtl, lpDIS);
}

/*-----------------------------------------------------------------------------
 *  Description : handle function for message WM_SHOWWINDOW
 *					Initialize spinner value
 *---------------------------------------------------------------------------*/
void CDlgState::OnShowWindow(BOOL bShow, UINT nStatus)
{
	CFormView::OnShowWindow(bShow, nStatus);

    if(bShow && m_bFirstShow)
    {
		UDACCEL a3_udAccel[3] = { {0,1} , {1,5} , {2,15} };

        // replay value
		M_p_oSPReplay()->SetRange(C_iMinReplay,C_iMaxReplay);
		M_p_oSPReplay()->SetAccel(3,a3_udAccel);
        // speed value
        M_p_oSPSpeed()->SetRange(C_iMinSpeed,C_iMaxSpeed);
		M_p_oSPSpeed()->SetAccel(3,a3_udAccel);

		m_eTransitionTypeDisplay = E_dt_All;
        M_p_oBTID( IDC_BT_DISPLAY ) -> SetWindowText( "Show All" );
    }
    m_bFirstShow = FALSE;
}

/*-----------------------------------------------------------------------------
 *  Description : handle function for msg WM_SIZE
 *---------------------------------------------------------------------------*/
void CDlgState::OnSize(UINT nType, int cx, int cy)
{
    if( GetDlgItem( IDC_ST_BORDER ) )
    {
        CRect oRectDlg, oRectBorder, oRectLB, oRectTxt, oRectCB, oRectBTDefault, oRectBTDisplay;
        CSize oSize;

        // get positions
        M_GetClientRect( this, &oRectDlg );
        M_GetClientRectId( IDC_ST_BORDER, &oRectBorder );
        M_GetClientRectId( IDC_LIST_INTERRUPTACTION, &oRectLB );
        M_GetClientRectId( IDC_ST_TRST, &oRectTxt );
        M_GetClientRectId( IDC_COMBO_INTERRUPTSTATE, &oRectCB );
        M_GetClientRectId( IDC_BT_DEFAULT, &oRectBTDefault );
        M_GetClientRectId( IDC_BT_DISPLAY, &oRectBTDisplay );

        // minimum size
        if( cx < 500 ) oRectDlg . right = abs( oRectDlg . left ) + 500;
        if( cy < 190 ) oRectDlg . bottom = abs( oRectDlg . top ) + 190;
        // place Border
        oRectBorder . right = oRectDlg . right - C_iBorderSize;
        oRectBorder . bottom = oRectDlg . bottom - C_iBorderSize;
        // place BT Extend & All
        oRectBTDefault . left = oRectBorder . left + C_iBorderSize;
        oRectBTDisplay . right = oRectBorder . right - C_iBorderSize;
        oSize . cx = ( oRectBorder . Width() - (C_iBorderSize<<2) ) >> 1;
        oRectBTDefault . right = oRectBTDefault . left + oSize . cx;
        oRectBTDisplay . left = oRectBTDisplay . right - oSize . cx;
        // place Text
        oSize = oRectTxt . Size();
        oRectTxt . bottom = oRectBorder . bottom - (C_iBorderSize<<1);
        oRectTxt . top = oRectTxt . bottom - oSize . cy;
        // place CB
        oSize = oRectCB . Size();
        oRectCB . bottom = oRectBorder . bottom - C_iBorderSize;
        oRectCB . top = oRectCB . bottom - oSize . cy;
        oRectCB . right = oRectBorder . right - C_iBorderSize;
        // place LB
        oRectLB . right = oRectCB . right;
        oRectLB . bottom = oRectCB . top - (C_iBorderSize<<1);

        // set positions
        M_SetClientRectId( IDC_ST_BORDER, &oRectBorder );
        M_SetClientRectId( IDC_LIST_INTERRUPTACTION, &oRectLB );
        M_SetClientRectId( IDC_ST_TRST, &oRectTxt );
        M_SetClientRectId( IDC_COMBO_INTERRUPTSTATE, &oRectCB );
        M_SetClientRectId( IDC_BT_DEFAULT, &oRectBTDefault );
        M_SetClientRectId( IDC_BT_DISPLAY, &oRectBTDisplay );
    }
}

/*-----------------------------------------------------------------------------
 *  Description : handle function for msg UDN_DELTAPOS on replay spinner
 *---------------------------------------------------------------------------*/
void CDlgState::OnDeltaposSpinReplay(NMHDR* pNMHDR, LRESULT* pResult)
{
	NM_UPDOWN* pNMUpDown = (NM_UPDOWN*)pNMHDR;

    if(pNMUpDown->iDelta != 0)
    {
		// update current state replay value
        State_ModifReplay *p_oReplay = new State_ModifReplay( m_p_oParentDLL, M_p_oCurrentState(), (unsigned char)(pNMUpDown->iPos + pNMUpDown->iDelta) );
        M_MakeDo( p_oReplay ) ;
    }
	*pResult = 0;
}

/*-----------------------------------------------------------------------------
 *  Description : handle function for msg UDN_DELTAPOS on speed spinner
 *---------------------------------------------------------------------------*/
void CDlgState::OnDeltaposSpinSpeed(NMHDR* pNMHDR, LRESULT* pResult)
{
	NM_UPDOWN* pNMUpDown = (NM_UPDOWN*)pNMHDR;

    if(pNMUpDown->iDelta != 0)
    {
        // update current state speed value
        State_ModifSpeed *p_oSpeed = new State_ModifSpeed( m_p_oParentDLL, M_p_oCurrentState(), (signed char)(pNMUpDown->iPos + pNMUpDown->iDelta) );
        M_MakeDo( p_oSpeed ) ;
    }
	*pResult = 0;
}

/*-----------------------------------------------------------------------------
 *  Description : handle function for msg UDN_DELTAPOS on speed spinner
 *---------------------------------------------------------------------------*/
void CDlgState::OnChangeReplay() 
{
	char				szValue[5];

	if (M_p_oEditItem(IDC_EDIT_REPLAY)->GetModify())
	{
		// init names
		M_p_oEditItem(IDC_EDIT_REPLAY)->GetWindowText(szValue, 5);
		// update current state replay value
        State_ModifReplay *p_oReplay = new State_ModifReplay( m_p_oParentDLL, M_p_oCurrentState(), (unsigned char)atoi(szValue));
        M_MakeDo( p_oReplay ) ;
	}
}

/*-----------------------------------------------------------------------------
 *  Description : handle function for msg UDN_DELTAPOS on speed spinner
 *---------------------------------------------------------------------------*/
void CDlgState::OnChangeSpeed() 
{
	char				szValue[5];

	if (M_p_oEditItem(IDC_EDIT_SPEED)->GetModify())
	{
		// init names
		M_p_oEditItem(IDC_EDIT_SPEED)->GetWindowText(szValue, 5);
        // update current state speed value
        State_ModifSpeed *p_oSpeed = new State_ModifSpeed( m_p_oParentDLL, M_p_oCurrentState(), (signed char)atoi(szValue));
        M_MakeDo( p_oSpeed ) ;
	}
}

/*-----------------------------------------------------------------------------
 *  Description : msg BN_CLICKED on 'More' button
 *---------------------------------------------------------------------------*/
void CDlgState::OnBtMore()
{
    m_bAllFamilies = !m_bAllFamilies;

    CRect oRectDlg, oRectCBFamily, oRectCWnd;
    int iSize;

    // get positions
    M_GetClientRect( this, &oRectDlg );
    M_GetClientRectId( IDC_COMBO_FAMILY, &oRectCBFamily );

    if( m_bAllFamilies )
    {
        iSize = oRectCBFamily . Height() + (C_iBorderSize<<1);
        GetDlgItem( IDC_BT_MORE ) -> SetWindowText( "-" );
    }
    else
    {
        iSize = -( oRectCBFamily . Height() + (C_iBorderSize<<1) );
        GetDlgItem( IDC_BT_MORE ) -> SetWindowText( "+" );
    }

    M_MoveRectId( IDC_STATIC_ANIMATION, 0, iSize );
    M_MoveRectId( IDC_COMBO_ANIMATION, 0, iSize );

    M_MoveRectId( IDC_STATIC_REPLAY, 0, iSize );
    M_MoveRectId( IDC_EDIT_REPLAY, 0, iSize );
    M_MoveRectId( IDC_SPIN_REPLAY, 0, iSize );

    M_MoveRectId( IDC_STATIC_SPEED, 0, iSize );
    M_MoveRectId( IDC_EDIT_SPEED, 0, iSize );
    M_MoveRectId( IDC_SPIN_SPEED, 0, iSize );

    M_MoveRectId( IDC_STATIC_NEXTSTATE, 0, iSize );
    M_MoveRectId( IDC_COMBO_NEXTSTATE, 0, iSize );

    M_MoveRectId( IDC_STATIC_MECHANIC, 0, iSize );
    M_MoveRectId( IDC_COMBO_MECHANIC, 0, iSize );

    GetDlgItem( IDC_STATIC_FAMILY ) -> EnableWindow( m_bAllFamilies );
    GetDlgItem( IDC_COMBO_FAMILY ) -> EnableWindow( m_bAllFamilies );
    GetDlgItem( IDC_STATIC_FAMILY ) -> ShowWindow( m_bAllFamilies ? SW_SHOW : SW_HIDE  );
    GetDlgItem( IDC_COMBO_FAMILY ) -> ShowWindow( m_bAllFamilies ? SW_SHOW : SW_HIDE );

    Invalidate();

    if( M_p_oCurrentFamily() )
    {
        if( M_p_oCurrentState() )
        {
            SelectStringExact( M_p_oComboFamily(), M_p_oCurrentState() -> mfn_p_oGetAnimation() -> GetOwner() -> GetName() );
            mfn_vFillAnimationList( (CPA_Family*)M_p_oCurrentState() -> mfn_p_oGetAnimation() -> GetOwner() );
            SelectStringExact( M_p_oComboAnimation(), M_p_oCurrentState() -> mfn_p_oGetAnimation() -> GetName() );
        }
        else
        {
            SelectStringExact( M_p_oComboFamily(), M_p_oCurrentFamily() -> GetName() );
            mfn_vFillAnimationList( M_p_oCurrentFamily() );
        }
    }
    else
    {
        M_p_oComboFamily() -> SetCurSel( -1 );
        mfn_vFillAnimationList( NULL );
    }
}

/*-----------------------------------------------------------------------------
 *  Description : msg CBN_SELCHANGE on Families CB
 *---------------------------------------------------------------------------*/
void CDlgState::OnSelchangeComboFamily()
{
    int iIndex = M_p_oComboFamily() -> GetCurSel();
    if( iIndex != CB_ERR )
    {
        CPA_Family      *p_oFamily      = (CPA_Family*) M_p_oComboFamily() -> GetItemData( iIndex );
        CPA_State       *p_oState       = M_p_oCurrentState();
        CPA_Animation   *p_oAnimation   = ( p_oState ? p_oState -> mfn_p_oGetAnimation() : NULL );

        mfn_vFillAnimationList( p_oFamily );

        if( p_oAnimation && ((CPA_Family*)p_oAnimation -> GetOwner() == p_oFamily) )
            SelectStringExact( M_p_oComboAnimation(), p_oAnimation -> GetName() );
        else
            M_p_oComboAnimation() -> SetCurSel( -1 );
    }
}

/*-----------------------------------------------------------------------------
 *  Description : msg BN_CLICKED on button Default
 *---------------------------------------------------------------------------*/
void CDlgState::OnCheckDefault()
{
	if( M_p_oCurrentState() )
	{
		State_SwapDefaultTransitionStatus *p_oModif = new State_SwapDefaultTransitionStatus( m_p_oParentDLL, M_p_oCurrentState() );
		M_MakeDo( p_oModif );
	}
}

/*-----------------------------------------------------------------------------
 *  Description : msg BN_CLICKED on Display button
 *---------------------------------------------------------------------------*/
void CDlgState::OnCheckDisplay()
{
    switch ( m_eTransitionTypeDisplay )
    {
    case E_dt_Allowed:      mfn_vSetDisplayTransition( E_dt_Prohibited );   break;
    case E_dt_Prohibited:   mfn_vSetDisplayTransition( E_dt_All);           break;
    case E_dt_All:          mfn_vSetDisplayTransition( E_dt_Allowed );      break;
    }
}

/*-----------------------------------------------------------------------------
 *  Description : Update Animation of currentState with selected Animation
 *---------------------------------------------------------------------------*/
void CDlgState::OnSelchangeComboAnimation()
{
    int iIndex = M_p_oComboAnimation()->GetCurSel();

    if(iIndex != CB_ERR)
    {
        char szText[100];
        CPA_Animation *p_oAnim = (CPA_Animation*) M_p_oComboAnimation() -> GetItemData( iIndex );
        M_p_oComboAnimation() -> GetLBText ( iIndex , szText ) ;
        State_ModifAnim *p_oModifAnim = new State_ModifAnim ( m_p_oParentDLL, M_p_oCurrentState(), p_oAnim ) ;
        M_MakeDo( p_oModifAnim ) ;
    }
}

/*-----------------------------------------------------------------------------
 *  Description : msg CBN_SELCHANGED for Combo Mechanic
 *---------------------------------------------------------------------------*/
void CDlgState::OnSelchangeComboMechanic()
{
    int iIndex = M_p_oComboMeca() -> GetCurSel();

    if(iIndex != CB_ERR)
    {
        CPA_SaveObject *p_oMeca = (CPA_SaveObject*)M_p_oComboMeca() -> GetItemData( iIndex );
        State_ModifMechanic *p_oModifMeca = new State_ModifMechanic( m_p_oParentDLL, M_p_oCurrentState(), p_oMeca );
        M_MakeDo( p_oModifMeca ) ;

    }
}

/*-----------------------------------------------------------------------------
 *  Description : msg CBN_SELCHANGED for Combo Interrupt state
 *---------------------------------------------------------------------------*/
void CDlgState::OnSelchangeComboInterruptstate()
{
    int iActionIndex = ( M_p_oListAction() -> GetSelCount() == 1 ? M_p_oListAction()->GetCurSel() : LB_ERR );
    int iStateIndex  = M_p_oComboInterruptState()->GetCurSel();

    if( (iActionIndex != LB_ERR) && (iStateIndex != CB_ERR) )
    {
        CPA_Action *p_oAction = NULL;


        if( mfn_bGetTSIAndActionFromIndex( iActionIndex, NULL, &p_oAction ) )
        {
            State_ModifTransition *p_oModif = new State_ModifTransition( m_p_oParentDLL, M_p_oCurrentState(), p_oAction, E_ts_Allowed, (CPA_State*) M_p_oComboInterruptState() -> GetItemData(iStateIndex) );
            M_MakeDo( p_oModif ) ;
        }
    }
}

/*-----------------------------------------------------------------------------
 *  Description : Update Next State of current State with selected State
 *---------------------------------------------------------------------------*/
void CDlgState::OnSelchangeComboNextstate()
{
    int iIndex = M_p_oComboNextState()->GetCurSel();

    if(iIndex != CB_ERR)
    {
        CPA_State *p_oNextState = (CPA_State*)M_p_oComboNextState() -> GetItemData( iIndex );

        State_ModifNextState *p_oNextStateChange = new State_ModifNextState ( m_p_oParentDLL, M_p_oCurrentState(), p_oNextState ) ;
        M_MakeDo( p_oNextStateChange ) ;
    }
}

/*-----------------------------------------------------------------------------
 *  Description : msg LBN_SELCHANGE on interrupt action list
 *---------------------------------------------------------------------------*/
void CDlgState::OnSelchangeListInterruptaction()
{
    CComboBox   *pStateCB = M_p_oComboInterruptState();

    if ( M_p_oListAction()-> GetSelCount() == 1 )
    {
        int         iIndex = M_p_oListAction()->GetCurSel();
        POSITION    xPos;
        CPA_State   *p_oState;
        int         iItem;
		tdstTransitionStateInfo *p_stTSI;
		CPA_Action *p_oAction;

        // fill CB
	    //emptied combo
        pStateCB -> ResetContent() ;
		// recuperate interrupt data
//ANNECY CT 11/02/98{
        if( mfn_bGetTSIAndActionFromIndex( iIndex, &p_stTSI, &p_oAction ) && 
			((M_p_oCurrentState()->mfn_eGetTransitionForAction(p_oAction) == E_ts_Allowed) ||
			 (M_p_oCurrentState()->mfn_eGetTransitionForAction(p_oAction) == E_ts_Fluid ) ) )
//ENDANNECY CT}
        {
            // add 'DEFAULT' entry
            iItem = pStateCB->AddString( "DEFAULT" );
            if( iItem != CB_ERR )
                pStateCB->SetItemData( iItem, (DWORD) NULL );
            // fill list with state's action
            xPos = p_oAction -> m_oListOfStates . GetHeadPosition();
            while (xPos)
            {
                p_oState = p_oAction -> m_oListOfStates . GetNext(xPos);
                if( p_oState -> mfn_bGetTransitional() )
                {   // just add transitional state
                    iItem = pStateCB->AddString( p_oState->GetName() );
                    if (iItem != CB_ERR)
                        pStateCB->SetItemData( iItem, (DWORD) p_oState );
                }
            }
        }

        if(pStateCB->GetCount() > 0 )
        {
            pStateCB->EnableWindow( TRUE );
		    // set current state to the p_stInterrupt state if exist
			if( p_stTSI && (p_stTSI -> eState == E_ts_Allowed ) && (p_stTSI -> p_oStateToGo) )
			{
				SelectStringExact( pStateCB, p_stTSI -> p_oStateToGo -> GetName() );
			}
        }
        else
            pStateCB->EnableWindow( FALSE );
    }
    else
    {
        // empty CB
        pStateCB -> ResetContent() ;
        pStateCB -> EnableWindow( FALSE );
    }
}

/*-----------------------------------------------------------------------------
 *  Author      : MT
 *  Creation    : 25/08/97
 *
 *  Description : extend selected transitions to all states of family
 *---------------------------------------------------------------------------*/
void CDlgState::OnBtExtendfamily()
{
    int iNbSta = M_p_oCurrentFamily() -> m_oListOfStates . GetCount();

    if( iNbSta > 1 )
    {
        // fill list of states
        CPA_Family *p_oFamily = M_p_oCurrentFamily();
        POSITION xPos;

        State_ModifTransitionExtended *p_oModif = new State_ModifTransitionExtended( m_p_oParentDLL, M_p_oCurrentState() );

        xPos = p_oFamily -> m_oListOfStates . GetHeadPosition();
        while( xPos )
            p_oModif -> mfn_vAddState( p_oFamily -> m_oListOfStates . GetNext( xPos ) );

		// get actions and do
		fn_vExtendTransitions( p_oModif );
    }
}

/*-----------------------------------------------------------------------------
 *  Author      : MT
 *  Creation    : 25/08/97
 *
 *  Description : extend selected transitions to all states of action
 *---------------------------------------------------------------------------*/
void CDlgState::OnBtExtendaction()
{
    int iNbSta = M_p_oCurrentAction() -> m_oListOfStates . GetCount();

    if( iNbSta > 1 )
    {
        // fill list of states
        CPA_Action *p_oAction = M_p_oCurrentAction();
        POSITION xPos;
		State_ModifTransitionExtended *p_oModif = new State_ModifTransitionExtended( m_p_oParentDLL, M_p_oCurrentState() );

        xPos = p_oAction -> m_oListOfStates . GetHeadPosition();
        while( xPos )
            p_oModif -> mfn_vAddState( p_oAction -> m_oListOfStates . GetNext( xPos ) );

		// get actions and do
		fn_vExtendTransitions( p_oModif );
    }
}

/*-----------------------------------------------------------------------------
 *  Author      : MT
 *  Creation    : 25/08/97
 *
 *  Description : extend selected transitions to selected states
 *---------------------------------------------------------------------------*/
void CDlgState::OnBtExtendselection()
{
    HINSTANCE hOldInst = AfxGetResourceHandle();
    AfxSetResourceHandle( m_p_oParentDLL -> GetDLLIdentity() -> hModule );

    CDlgSelection *pDlg = new CDlgSelection();

    pDlg -> mfn_vSetFamily( M_p_oCurrentFamily() );

    if( pDlg -> DoModal() == IDOK )
    {
        POSITION xPos;
		State_ModifTransitionExtended *p_oModif = new State_ModifTransitionExtended( m_p_oParentDLL, M_p_oCurrentState() );

        // get states
        xPos = pDlg -> m_oListOfSelectedObjects . GetHeadPosition();
        while( xPos )
            p_oModif -> mfn_vAddState( (CPA_State*) pDlg -> m_oListOfSelectedObjects . GetNext( xPos ) );

		// get actions and do
		fn_vExtendTransitions( p_oModif );
    }
    delete pDlg;
    AfxSetResourceHandle( hOldInst );
}

/*-----------------------------------------------------------------------------
 *  Author      : MT
 *  Creation    : 24/10/98
 *
 *  Description :
 *---------------------------------------------------------------------------*/
void CDlgState::OnCBClicked(UINT nID)
{
	int iCBNumber = (nID - IDC_CHECK_CB1);

	assert( (iCBNumber>=0) & (iCBNumber<8) );

	State_ModifCustomBits *p_oModif = new State_ModifCustomBits( m_p_oParentDLL, M_p_oCurrentState(), (unsigned char)iCBNumber );

    M_MakeDo( p_oModif ) ;
}

/*-----------------------------------------------------------------------------
 *  Author      : MT
 *  Creation    : 25/08/97
 *
 *  Description :
 *---------------------------------------------------------------------------*/
void CDlgState::fn_vExtendTransitions(State_ModifTransitionExtended *_p_oModif)
{
    // get actions
    CListBox	   *pLB		= M_p_oListAction();
    int				iNbSel	= pLB -> GetSelCount();
	tdstTransitionStateInfo *p_stTSI;
	CPA_Action *p_oAction;
	CPA_State *p_oState = M_p_oCurrentState();

    if( iNbSel > 0 )
    {
        // use selected actions
        int *a_iSel = (int*) malloc( iNbSel * sizeof( int ) );
        pLB -> GetSelItems( iNbSel, a_iSel );

        for ( int iIndex = 0 ; iIndex < iNbSel ; iIndex++ )
        {
			if( mfn_bGetTSIAndActionFromIndex( a_iSel[iIndex], &p_stTSI, &p_oAction ) )
				_p_oModif -> mfn_vAddTransition( p_oAction, p_stTSI ? p_stTSI -> eState : E_ts_Unknown, p_stTSI ? p_stTSI -> p_oStateToGo : NULL );
        }
        free( a_iSel );
    }
    else
    {
        // use all actions
        for ( int iIndex = 0 ; iIndex < pLB -> GetCount() ; iIndex++ )
        {
			if( mfn_bGetTSIAndActionFromIndex( iIndex, &p_stTSI, &p_oAction ) )
				_p_oModif -> mfn_vAddTransition( p_oAction, p_stTSI ? p_stTSI -> eState : E_ts_Unknown, p_stTSI ? p_stTSI -> p_oStateToGo : NULL );
        }
    }
    _p_oModif -> mfn_vEndCreation();
    M_MakeDo( _p_oModif );
}

/******************************************************************************
*******************************************************************************
* CDlgState specific functions
******************************************************************************
******************************************************************************/

/*****************************************************************************
* function called by parent DLL when family/action/state change
******************************************************************************/

/*-----------------------------------------------------------------------------
 *  Description : display parameters of given animaction
 *---------------------------------------------------------------------------*/
void CDlgState::fn_vSetCurrentState( CPA_State *_p_oState )
{
	BOOL		bEnable         = _p_oState != NULL;
    CListBox    *pLB            = M_p_oListAction();
    CComboBox   *pAnimCombo     = M_p_oComboAnimation();
    CComboBox   *pNextStateCB   = M_p_oComboNextState();
    CComboBox   *pMecaCB        = M_p_oComboMeca();
    CComboBox   *pFamilyCB      = M_p_oComboFamily();
	char		szValue[10];

    // emptied list
	pAnimCombo->SetCurSel( -1 );
	pNextStateCB->SetCurSel( -1 );
    pMecaCB->SetCurSel( -1 );
	// disable / enable control
	pAnimCombo->EnableWindow( bEnable );
	pNextStateCB->EnableWindow( bEnable );

    M_EnableID( IDC_COMBO_FAMILY, bEnable );
	M_EnableID( IDC_EDIT_SPEED , bEnable );
	M_EnableID( IDC_EDIT_REPLAY , bEnable );
	M_EnableID( IDC_LIST_INTERRUPTACTION , bEnable );
	M_EnableID( IDC_COMBO_INTERRUPTSTATE , FALSE );
    M_EnableID( IDC_COMBO_NEXTSTATE , bEnable);
    M_EnableID( IDC_COMBO_MECHANIC , bEnable);
	M_EnableID( IDC_BT_DEFAULT, bEnable);
	M_EnableID( IDC_BT_DISPLAY, bEnable);
    // reset InterruptAction List

	mfn_vDisplayCustomBits( _p_oState );

	// return if current state is set to NULL
	if (!bEnable)
	{
		pLB -> ResetContent ();
		GetDlgItem( IDC_EDIT_SPEED )->SetWindowText( "" );
		GetDlgItem( IDC_EDIT_REPLAY )->SetWindowText( "" );
		return;
	}

    // default status changed
    if( _p_oState -> mfn_bIsProhibitedByDefault() )
        M_p_oBTID( IDC_BT_DEFAULT ) -> SetWindowText( "Prohibited by Default" );
    else
        M_p_oBTID( IDC_BT_DEFAULT ) -> SetWindowText( "Allowed by Default" );

	// update dialog interrupt list with current state interrupt action
	mfn_vSetDisplayTransition( m_eTransitionTypeDisplay );

    // set state animation
	if ( _p_oState->mfn_p_oGetAnimation() != NULL )
	{
        SelectStringExact( pFamilyCB, _p_oState->mfn_p_oGetAnimation()->GetOwner()->GetName() );
        SelectStringExact( pAnimCombo, _p_oState->mfn_p_oGetAnimation()->GetName() );
	}
    else
        pAnimCombo -> SetCurSel( -1 );

    // fill CB Next State
    mfn_vFillStateList( _p_oState );

	// set state next state

    if (_p_oState->mfn_p_oGetNextState() != NULL)
	{
        SelectStringExact( pNextStateCB, _p_oState->mfn_p_oGetNextState()->GetName() );
    }
    else if (!_p_oState->mfn_bGetTransitional())
    {
        SelectStringExact( pNextStateCB, "NONE" );
    }
	else
		pNextStateCB -> SetCurSel( -1 );

    // set mechanic
    if( _p_oState->mfn_p_oGetMecaCard() != NULL )
    {
        SelectStringExact( pMecaCB, _p_oState->mfn_p_oGetMecaCard()->GetName() );
    }
    else
        pMecaCB -> SetCurSel( -1 );

    // can edit speed ???????
    if( _p_oState->mfn_p_oGetAnimation() && _p_oState->mfn_p_oGetAnimation()-> fn_bIsAvailable() )
    {
        // can edit speed
        M_p_oSPSpeed()->SetRange(C_iMinSpeed,C_iMaxSpeed);
    }
    else
    {
        // can't edit speed
        M_p_oSPSpeed()->SetRange(0,0);
    }
    // set speed
    GetDlgItem( IDC_EDIT_SPEED )->SetWindowText( itoa(_p_oState->mfn_cGetSpeed(), szValue, 10) );
    M_p_oSPSpeed() -> SetPos( _p_oState->mfn_cGetSpeed() );
    // set replay
    GetDlgItem( IDC_EDIT_REPLAY )->SetWindowText( itoa(_p_oState->mfn_ucGetReplay(), szValue, 10) );
    M_p_oSPReplay() -> SetPos( _p_oState->mfn_ucGetReplay() );

}

/*-----------------------------------------------------------------------------
 *  Description : fill lists when family change
 *---------------------------------------------------------------------------*/
void CDlgState::mfn_vSetCurrentFamily( CPA_Family *_p_oFamily)
{
    mfn_vFillAnimationList(_p_oFamily);
	fn_vSetCurrentState( NULL );
    mfn_vFillMecaList();
    //
    if( _p_oFamily )
        int iIndex = SelectStringExact( M_p_oComboFamily(), _p_oFamily -> GetName() );
    else
        M_p_oComboFamily() -> SetCurSel( -1 );
}

/*-----------------------------------------------------------------------------
 *  Description : handle function for message WM_DRAWITEM on ListBox Action
 *---------------------------------------------------------------------------*/
void CDlgState::mfn_vOnDrawItemListBoxAction(LPDRAWITEMSTRUCT lpDIS)
{
    CDC                     *pDC            = CDC::FromHandle( lpDIS->hDC );
    CListBox                *pLB            = M_p_oListAction();
    BOOL                    bSelected       = (lpDIS->itemState & ODS_SELECTED );
    tdstTransitionStateInfo *p_stTSI        = NULL;
    CPA_State               *p_oState       = M_p_oCurrentState();
    BOOL                    bProhibit       = p_oState -> mfn_bIsProhibitedByDefault();
    CPA_Action              *p_oAction      = NULL;
    CString                 csActionName;
    tdeTransitionState      eState          = E_ts_Unknown;

    pLB -> GetText( lpDIS->itemID, csActionName );
	mfn_bGetTSIAndActionFromIndex( lpDIS->itemID, &p_stTSI, &p_oAction );
	if( p_stTSI )
		eState = p_stTSI -> eState;

    pDC->FillSolidRect( &lpDIS->rcItem, GetSysColor( COLOR_WINDOW ));
    // add BMP according to Transition State
	if( eState == E_ts_Prohibited )
		pDC->BitBlt( lpDIS->rcItem.left + 2, lpDIS->rcItem.top + 1, 12, 12, &m_oProhibitedDC, 0, 0, SRCAND );
	else if( eState == E_ts_Allowed )
		pDC->BitBlt( lpDIS->rcItem.left + 2, lpDIS->rcItem.top + 1, 12, 12, &m_oAllowedDC, 0, 0, SRCAND );
//ANNECY CT 11/02/98{
	else if( eState == E_ts_Fluid )
		pDC->BitBlt( lpDIS->rcItem.left + 2, lpDIS->rcItem.top + 1, 12, 12, &m_oFluidDC, 0, 0, SRCAND );
//ENDANNECY CT}

    pDC->SetBkMode( TRANSPARENT);
    pDC->SetTextColor( GetSysColor( COLOR_WINDOWTEXT ) );

    lpDIS->rcItem.left += 16;
    // add Action name
    pDC->DrawText( csActionName, &lpDIS->rcItem, DT_SINGLELINE | DT_LEFT | DT_VCENTER );
    // add transitional state used
//ANNECY CT 11/02/98{
    //if( p_stTSI && ( p_stTSI -> eState == E_ts_Allowed ) && ( p_stTSI -> p_oStateToGo ) )
	if( p_stTSI && (( p_stTSI -> eState == E_ts_Allowed ) || (p_stTSI->eState == E_ts_Fluid)) && ( p_stTSI -> p_oStateToGo ) )
//ENDANNECY CT}
    {
        lpDIS->rcItem.right -= 2;
        pDC->DrawText( p_stTSI -> p_oStateToGo -> GetName(), &lpDIS->rcItem, DT_SINGLELINE | DT_RIGHT | DT_VCENTER );
        lpDIS->rcItem.right += 2;
    }

    lpDIS->rcItem.left -= 1;
    if (bSelected)
        pDC->InvertRect( &lpDIS->rcItem );
}

/*-----------------------------------------------------------------------------
 *  Description : handle function for message WM_DRAWITEM on ComboBox Interrupt State
 *---------------------------------------------------------------------------*/
void CDlgState::mfn_vOnDrawItemComboBoxInterruptState(LPDRAWITEMSTRUCT lpDIS)
{
    char        szText[100];
    CComboBox   *pCB        = M_p_oComboInterruptState();
    CBrush      oBrush;
    COLORREF    xTextColor;
    BOOL        bSelected   = (lpDIS->itemState & ODS_SELECTED );
    CFont       *xFntPrev;
    CDC         *pDC        = CDC::FromHandle(lpDIS->hDC);
    BOOL        bUseBold    = FALSE;

    oBrush.CreateSolidBrush( GetSysColor( bSelected ? COLOR_HIGHLIGHT : COLOR_WINDOW) );
    xTextColor = GetSysColor( bSelected ? COLOR_HIGHLIGHTTEXT : COLOR_WINDOWTEXT);

    pDC->FillRect( &lpDIS->rcItem, &oBrush );

    // change font
    CPA_State *p_oState = (CPA_State*)pCB->GetItemData( lpDIS->itemID );
    bUseBold = (p_oState == NULL); // 'NONE' entry


    if (bUseBold)
        xFntPrev = pDC->SelectObject( &m_oBoldFont );

    pDC->SetBkMode(TRANSPARENT);
    pDC->SetTextColor(xTextColor);


    pCB->GetLBText( lpDIS->itemID, szText );
    lpDIS->rcItem.left += 2;
    pDC->DrawText( szText, strlen(szText), &lpDIS->rcItem, DT_SINGLELINE | DT_LEFT | DT_VCENTER );
    // restore font
    if (bUseBold)
        pDC->SelectObject( xFntPrev );

    oBrush.DeleteObject();
}

/*-----------------------------------------------------------------------------
 *  Description : handle function for message WM_DRAWITEM on ComboBox Interrupt State
 *---------------------------------------------------------------------------*/
void CDlgState::mfn_vOnDrawItemComboBoxNextState(LPDRAWITEMSTRUCT lpDIS)
{
    char        szText[100];
    CComboBox   *pCB        = M_p_oComboNextState();
    CBrush      oBrush;
    COLORREF    xTextColor;
    BOOL        bSelected   = (lpDIS->itemState & ODS_SELECTED );
    CFont       *xFntPrev;
    CDC         *pDC        = CDC::FromHandle(lpDIS->hDC);
    BOOL        bUseBold    = FALSE;

    oBrush.CreateSolidBrush( GetSysColor( bSelected ? COLOR_HIGHLIGHT : COLOR_WINDOW) );
    xTextColor = GetSysColor( bSelected ? COLOR_HIGHLIGHTTEXT : COLOR_WINDOWTEXT);

    pDC->FillRect( &lpDIS->rcItem, &oBrush );

    // change font
    CPA_State *p_oState = (CPA_State*)pCB->GetItemData( lpDIS->itemID );
    bUseBold = (M_p_oCurrentState() && M_p_oCurrentState()-> mfn_bGetTransitional() && p_oState && !p_oState -> mfn_bGetTransitional()); // Default state

    if (bUseBold)
        xFntPrev = pDC->SelectObject( &m_oBoldFont );

    pDC->SetBkMode(TRANSPARENT);
    pDC->SetTextColor(xTextColor);


    pCB->GetLBText( lpDIS->itemID, szText );
    lpDIS->rcItem.left += 2;
    pDC->DrawText( szText, strlen(szText), &lpDIS->rcItem, DT_SINGLELINE | DT_LEFT | DT_VCENTER );
    // restore font
    if (bUseBold)
        pDC->SelectObject( xFntPrev );

    oBrush.DeleteObject();
}

/*-----------------------------------------------------------------------------
 *  Description : handle function for message WM_RBUTTONDOWN on ListBox Action
 *---------------------------------------------------------------------------*/
BOOL CDlgState::mfn_bOnRButtonDownListBoxAction(MSG *pMsg)
{
    CPoint					 oPoint( LOWORD(pMsg->lParam), HIWORD(pMsg->lParam) );
    CListBox				*pLB		= M_p_oListAction();
	CPA_State				*p_oState	= M_p_oCurrentState();
    int						 iNbSel		= pLB -> GetSelCount();
    CComboBox				*pCB		= M_p_oComboInterruptState();
    CPA_Action				*p_oAction	= NULL;
    BOOL					 bProhibit	= p_oState -> mfn_bIsProhibitedByDefault();
    CMenu					 oPopupMenu ;
    char					 szText[100];

    // create popup menu
    oPopupMenu . CreatePopupMenu () ;
	// fill menu
	if( iNbSel == 1 )
	{
        tdeTransitionState	eState	= E_ts_Unknown;
        //int					*a_iSel = (int*) malloc( iNbSel * sizeof( int ) );

        //pLB -> GetSelItems( iNbSel, a_iSel );        
		//free( a_iSel );

		if( mfn_bGetTSIAndActionFromIndex( /*a_iSel[ 0 ]*/ pLB -> GetCurSel(), NULL, &p_oAction ) )
            eState = M_p_oCurrentState() -> mfn_eGetTransitionForAction( p_oAction );
        oPopupMenu . AppendMenu( MF_STRING + ( eState == E_ts_Allowed    ? MF_GRAYED : MF_ENABLED ), C_uiPMActionAllows, "Allows Selected Action" ) ;
		oPopupMenu . AppendMenu( MF_STRING + ( eState == E_ts_Prohibited ? MF_GRAYED : MF_ENABLED ), C_uiPMActionProhibits, "Prohibits Selected Action" ) ;
		oPopupMenu . AppendMenu( MF_STRING + ( eState == E_ts_Unknown    ? MF_GRAYED : MF_ENABLED ), C_uiPMActionDefault, "Set Default Selected Action" ) ;
		oPopupMenu . AppendMenu( MF_SEPARATOR ) ;
	}
	else if( iNbSel > 1 )
	{
        oPopupMenu . AppendMenu( MF_STRING, C_uiPMActionAllows, "Allows Selected Action(s)" ) ;
		oPopupMenu . AppendMenu( MF_STRING, C_uiPMActionProhibits, "Prohibits Selected Action(s)" ) ;
		oPopupMenu . AppendMenu( MF_STRING, C_uiPMActionDefault, "Set Default Selected Action(s)" ) ;
		oPopupMenu . AppendMenu( MF_SEPARATOR ) ;
	}
    // fill menu
    oPopupMenu . AppendMenu( MF_STRING + ( m_eTransitionTypeDisplay == E_dt_All        ? MF_GRAYED : MF_UNCHECKED ), C_uiPMDisplayAll , "Show All" ) ;
    oPopupMenu . AppendMenu( MF_STRING + ( m_eTransitionTypeDisplay == E_dt_Allowed    ? MF_GRAYED : MF_UNCHECKED ), C_uiPMDisplayAllowed , "Show Allwed" ) ;
    oPopupMenu . AppendMenu( MF_STRING + ( m_eTransitionTypeDisplay == E_dt_Prohibited ? MF_GRAYED : MF_UNCHECKED ), C_uiPMDisplayProhibited , "Show Prohibited" ) ;
    oPopupMenu . AppendMenu( MF_SEPARATOR ) ;
    oPopupMenu . AppendMenu( MF_STRING + (  bProhibit ? MF_GRAYED : MF_ENABLED) , C_uiPMDefaultProhibited , "Prohibited by Default" );
    oPopupMenu . AppendMenu( MF_STRING + ( !bProhibit ? MF_GRAYED : MF_ENABLED) , C_uiPMDefaultAllowed , "Allowed by Default" );
    oPopupMenu . AppendMenu( MF_SEPARATOR ) ;
    oPopupMenu . AppendMenu( MF_STRING , C_uiPMExtendToFamily, "Extend Transition(s) to Family" ) ;
	oPopupMenu . AppendMenu( MF_STRING , C_uiPMExtendToAction, "Extend Transition(s) to Action" ) ;
	oPopupMenu . AppendMenu( MF_STRING , C_uiPMExtendToSelection, "Extend Transition(s) to Selected State(s)" ) ;    
    // fill menu
    if( iNbSel == 1 )
    {
		if( pCB->GetCount() > 0 )
			oPopupMenu . AppendMenu( MF_SEPARATOR ) ;
        for ( int iIndex = 0 ; iIndex<pCB->GetCount() ; iIndex++ )
        {
            int iDx = pCB->GetLBText(iIndex,szText);
            if(iDx != CB_ERR)
            {
                oPopupMenu . AppendMenu( MF_STRING, C_uiPMState + iIndex, szText ) ;
            }
            else
                iIndex = pCB->GetCount();
        }
    }
    // display menu
    pLB->ClientToScreen(&oPoint);
    TUT_M_vGetTutDll    ();
    TUT_M_vRegisterMenu (this -> m_hWnd , oPopupMenu . m_hMenu , oPoint.x, oPoint.y);
	oPopupMenu . TrackPopupMenu ( TPM_LEFTALIGN|TPM_RIGHTBUTTON, oPoint.x, oPoint.y, this);
    oPopupMenu . DestroyMenu ();

    return CFormView::PreTranslateMessage(pMsg);
}

/*-----------------------------------------------------------------------------
 *  Description : handle function for message WM_RBUTTONDOWN on ListBox Action
 *---------------------------------------------------------------------------*/
BOOL CDlgState::mfn_bOnLButtonDownListBoxAction(MSG *pMsg)
{
    CListBox    *pLB = M_p_oListAction();
    POINT       xPos;
    CRect       oRect;
    BOOL        bOutside;
    int         iIndex;
	BOOL		bResult;

	
    xPos.x = LOWORD(pMsg->lParam);
    xPos.y = HIWORD(pMsg->lParam);

    iIndex = pLB -> ItemFromPoint ( xPos, bOutside ) ;
    pLB -> GetItemRect ( iIndex , &oRect ) ;
    if( (oRect . PtInRect ( xPos ) ) && ( xPos.x < 16 )  )
    {
        mfn_bOnChangeTransitions( iIndex );
    }
	else
		bResult = CFormView::PreTranslateMessage(pMsg);

    return bResult;
}

/*-----------------------------------------------------------------------------
 *  Description : handle function for message WM_RBUTTONDOWN on ListBox Action
 *---------------------------------------------------------------------------*/
void CDlgState::mfn_vFillInterruptActionList(void)
{
    CListBox            *pLB = M_p_oListAction();
    CPA_State           *p_oState = M_p_oCurrentState();
    BOOL                 bProhibited  = FALSE;
	int					 iTopIndex = pLB -> GetTopIndex();
	CString				 csTopAction = "";

	if( ( pLB -> GetCount() > 0 ) && ( iTopIndex != LB_ERR ) )
		pLB -> GetText( iTopIndex, csTopAction );

    pLB -> ResetContent () ;

    if( p_oState )
    {
        CPA_Family *p_oFamily = (CPA_Family*) p_oState -> GetOwner();
        POSITION xPos = p_oFamily -> m_oListOfActions . GetHeadPosition();

        bProhibited = p_oState -> mfn_bIsProhibitedByDefault();
        while ( xPos )
        {
            CPA_Action *p_oAction = p_oFamily -> m_oListOfActions . GetNext( xPos );
            tdstTransitionStateInfo *p_stTSI = p_oState -> mfn_p_stGetTransitionStateInfo( p_oAction );

            if( ( p_oAction -> mfn_p_oGetDefaultState() ) &&
                (   ( m_eTransitionTypeDisplay == E_dt_All ) ||  // show all
                  ( ( m_eTransitionTypeDisplay == E_dt_Prohibited ) && ( p_oState -> mfn_bIsActionProhibited( p_oAction ) ) ) ||  // show only prohibited
                  ( ( m_eTransitionTypeDisplay == E_dt_Allowed ) && ( ! p_oState -> mfn_bIsActionProhibited( p_oAction ) ) )  // show only allowed
                )
              )
            {
                int iIndex = pLB -> AddString ( p_oAction -> fn_p_szGetName() );
                if( iIndex != LB_ERR )
                    pLB -> SetItemData( iIndex, (DWORD)( p_stTSI ? p_stTSI : NULL ) );
            }
        }
		// reselect previously selected action
		if( ! csTopAction . IsEmpty() )
		{
			iTopIndex = pLB -> FindStringExact( -1, csTopAction );
			if( iTopIndex != LB_ERR )
			{
				pLB -> SetTopIndex( iTopIndex );
				OnSelchangeListInterruptaction();
			}
		}
    }
}

/*-----------------------------------------------------------------------------
 *  Description : fill Family combobox
 *---------------------------------------------------------------------------*/
void CDlgState::mfn_vFillFamilyList(void)
{
    CComboBox           *pCB        = M_p_oComboFamily();
    CPA_BaseObjectList  *p_oList    = m_p_oParentDLL -> GetMainWorld() -> fn_p_oGetOriginalObjectList( C_szFamilyTypeName );
    Position            lPos;
    CPA_Family          *p_oFamily;
    int                 iIndex;

    pCB -> ResetContent();
    if ( p_oList )
    {
        lPos = p_oList -> GetHeadPosition();
        while ( lPos )
        {
            p_oFamily = (CPA_Family*) p_oList -> GetNext( lPos );
            if( p_oFamily -> fn_bIsAvailable() )
            {
                iIndex = pCB -> AddString( p_oFamily -> GetName() );
                if( iIndex != CB_ERR )
                    pCB -> SetItemData( iIndex, (DWORD) p_oFamily );
            }
        }
    }
}

/*-----------------------------------------------------------------------------
 *  Description : fill Next State list with all states of family
 *---------------------------------------------------------------------------*/
void CDlgState::mfn_vFillStateList(CPA_State *_p_oState)
{
    CComboBox       *pStateCB = M_p_oComboNextState();
	POSITION		xPos;
    CPA_Action      *p_oAction = _p_oState ? _p_oState -> mfn_p_oGetAction() : NULL;
	CPA_State		*p_oState;
	// emptied state list
	pStateCB->ResetContent();

	// if family is null return
    if ( p_oAction )
    {
   	    // fill next state list with all family states
        xPos = p_oAction -> m_oListOfStates . GetHeadPosition ();
        while ( xPos )
        {
            p_oState = (CPA_State *)  p_oAction -> m_oListOfStates . GetNext ( xPos );
            if( _p_oState -> mfn_bCanUseAsNextState( p_oState ) )
            {
                int iIndex = pStateCB->AddString( p_oState -> GetName() );
                if( iIndex != CB_ERR )
                    pStateCB -> SetItemData( iIndex, (DWORD) p_oState );
            }
	    }
        // add "NONE" entry
        if( !_p_oState -> mfn_bGetTransitional() )
        {
            int iIndex = pStateCB -> AddString( "NONE" );
            if( iIndex != CB_ERR )
                pStateCB -> SetItemData( iIndex, (DWORD) NULL );
        }
    }
}

/*-----------------------------------------------------------------------------
 *  Description : fill Animation list with all animations of family
 *---------------------------------------------------------------------------*/
void CDlgState::mfn_vFillAnimationList(CPA_Family *_p_oFamily)
{
    CComboBox       *pAnimCB = M_p_oComboAnimation();
	POSITION		stPos;
	CPA_Animation	*p_oAnimation;
    int             iIndex;

	pAnimCB->ResetContent();

	// if family is null return
	if (_p_oFamily == NULL)
		return;

	// fill animation combo box
    stPos = _p_oFamily -> m_oListOfAnimations . GetHeadPosition ();
	// add NONE entry
	iIndex = pAnimCB->AddString( "NONE" );
    if(iIndex != CB_ERR)
        pAnimCB->SetItemData( iIndex, (DWORD) NULL);
	while ( stPos )
    {
        p_oAnimation = (CPA_Animation *) _p_oFamily -> m_oListOfAnimations . GetNext ( stPos );
		iIndex = pAnimCB->AddString( p_oAnimation->GetName() );
        if(iIndex != CB_ERR)
            pAnimCB->SetItemData( iIndex, (DWORD) p_oAnimation);
	}
}

/*-----------------------------------------------------------------------------
 *  Description : fill mechanics list with all mechanics
 *---------------------------------------------------------------------------*/
void CDlgState::mfn_vFillMecaList(void)
{
    CComboBox       *pCB        = M_p_oComboMeca();
    CPA_SaveObject  *p_oMeca    = NULL;
    int             iIndex      = 0;

    pCB -> ResetContent();
    iIndex = pCB -> AddString( "NONE" );
    if( iIndex != CB_ERR )
        pCB -> SetItemData( iIndex, (DWORD) NULL );

    CPA_BaseObjectList *p_oList = m_p_oParentDLL -> GetMainWorld() -> fn_p_oGetOriginalObjectList( C_szMecaCardTypeName );
    if( p_oList )
    {
        Position xPos = p_oList -> GetHeadPosition();
        while( xPos )
        {
            p_oMeca = (CPA_SaveObject*)p_oList -> GetNext( xPos );
            iIndex = pCB -> AddString( p_oMeca -> GetName() );
            if( iIndex != CB_ERR )
                pCB -> SetItemData( iIndex, (DWORD) p_oMeca );
        }
    }
}

/*-----------------------------------------------------------------------------
 *  Description : 
 *---------------------------------------------------------------------------*/
void CDlgState::mfn_vDisplayCustomBits( CPA_State  *_p_oState )
{
	int iCB;
	unsigned char ucCustomBits = (_p_oState ? _p_oState -> mfn_ucGetCustomBits() : 0);

	for( iCB = 0 ; iCB < 8 ; iCB++ )
	{
		if(ucCustomBits & (1<<iCB))
		{
			M_p_oBTID(IDC_CHECK_CB1 + iCB) -> SetCheck(1);
		}
		else
		{
			M_p_oBTID(IDC_CHECK_CB1 + iCB) -> SetCheck(0);
		}
		M_EnableID(IDC_CHECK_CB1 + iCB,(BOOL)_p_oState);
	}
}

/*-----------------------------------------------------------------------------
 *  Description : update display according to change type
 *---------------------------------------------------------------------------*/
void CDlgState::mfn_vStateChanged( CPA_State  *_p_oState , tdeChangingState _eChange)
{
    CComboBox *pCB ;
	CListBox *pLB;
    char szValue[10];
	int iTopIndex;

    ASSERT( _p_oState ) ;
    switch ( _eChange )
    {
        case C_iAnim:
            // anim changed
            pCB = M_p_oComboAnimation();
            if ( _p_oState->mfn_p_oGetAnimation() != NULL )
            {
                CPA_Animation *p_oAnim = _p_oState -> mfn_p_oGetAnimation();
                SelectStringExact( pCB, p_oAnim -> GetName() );
                if( p_oAnim -> fn_bIsAvailable() )
                {
                    M_p_oSPSpeed()->SetRange(C_iMinSpeed,C_iMaxSpeed);
                }
                else
                {
                    M_p_oSPSpeed()->SetRange(0,0);
                }
            }
            else
            {
                pCB -> SetCurSel( -1 );
                M_p_oSPSpeed()->SetRange(0,0);
            }
            M_p_oSPSpeed() -> SetPos( _p_oState->mfn_cGetSpeed() );
            GetDlgItem( IDC_EDIT_SPEED )->SetWindowText( itoa(_p_oState->mfn_cGetSpeed(), szValue, 10) );
            pCB -> Invalidate () ;
            break;
        case C_iSpeed:
            M_p_oSPSpeed() -> SetPos( _p_oState->mfn_cGetSpeed() );
        	GetDlgItem( IDC_EDIT_SPEED )->SetWindowText( itoa(_p_oState->mfn_cGetSpeed(), szValue, 10) );
        case C_iSpeedW:
            GetDlgItem( IDC_EDIT_SPEED )->Invalidate();
            break;
        case C_iReplay:
            M_p_oSPReplay() -> SetPos( _p_oState->mfn_ucGetReplay() );
	        GetDlgItem( IDC_EDIT_REPLAY )->SetWindowText( itoa(_p_oState->mfn_ucGetReplay(), szValue, 10) );
        case C_iReplayW:
            GetDlgItem( IDC_EDIT_REPLAY )->Invalidate();
            break;
        case C_iNextState:
            // next state changed
            pCB = M_p_oComboNextState();
            if (_p_oState->mfn_p_oGetNextState() != NULL )
                SelectStringExact( pCB, _p_oState->mfn_p_oGetNextState()->GetName() );
            else
                SelectStringExact( pCB, "NONE");
            pCB -> Invalidate () ;
            break;
        case C_iMeca:
            // mechanic changed
            pCB = M_p_oComboMeca();
            if( _p_oState->mfn_p_oGetMecaCard() != NULL )
                SelectStringExact( pCB, _p_oState->mfn_p_oGetMecaCard()->GetName() );
            else
                pCB -> SetCurSel( -1 );
            pCB -> Invalidate () ;
            break;
        case C_iInterruptState:
            // interrupt list changed
			pLB = M_p_oListAction();
			iTopIndex = pLB -> GetTopIndex();
			mfn_vFillInterruptActionList();
			if( ( iTopIndex != LB_ERR ) && ( iTopIndex < pLB -> GetCount() ) )
				pLB -> SetTopIndex( iTopIndex );
            M_p_oListAction() -> Invalidate () ;
            break;
        case C_iDefaultStatus:
            // default status changed
			// update button text
            if( _p_oState -> mfn_bIsProhibitedByDefault() )
                M_p_oBTID( IDC_BT_DEFAULT ) -> SetWindowText( "Prohibited by Default" );
            else
                M_p_oBTID( IDC_BT_DEFAULT ) -> SetWindowText( "Allowed by Default" );
            M_p_oBTID( IDC_BT_DEFAULT ) -> Invalidate();
			// fill && display InterruptActionList
			pLB = M_p_oListAction();
			iTopIndex = pLB -> GetTopIndex();
			mfn_vFillInterruptActionList();
			if( ( iTopIndex != LB_ERR ) && ( iTopIndex < pLB -> GetCount() ) )
				pLB -> SetTopIndex( iTopIndex );
            M_p_oListAction() -> Invalidate () ;
            break;
		case C_iCustomBits:
			// custom bits changed
			mfn_vDisplayCustomBits( _p_oState );
			break;
    }
}

/*-----------------------------------------------------------------------------
 *  Description : select exact given string on ComboBox
 *---------------------------------------------------------------------------*/
int CDlgState::SelectStringExact( CComboBox *_pCB, const CString _csEntry)
{
    // search string exact
    int iIndex = _pCB -> FindStringExact( -1, _csEntry );
    // select founded
    _pCB -> SetCurSel( ( iIndex != CB_ERR ) ? iIndex : -1 );
    // return position
    return iIndex;
}

// ----------------------------------------------------------------------------
// Author      : Marc Trabucato               Creation : 17/11/97
// Description : change transition state
// ----------------------------------------------------------------------------
BOOL CDlgState::mfn_bOnChangeTransitions( int _iIndex )
{
    CListBox	*pLB		= M_p_oListAction();
    CPA_State	*p_oState	= M_p_oCurrentState();
    BOOL		bResult		= FALSE;

	if( ( _iIndex != LB_ERR ) && ( _iIndex < pLB -> GetCount() ) )
    {
        State_ModifTransition   *p_oModifTransition = NULL;
        tdstTransitionStateInfo *p_stTSI            = NULL;
        CPA_Action              *p_oAction          = NULL;

        // find current action
		if( mfn_bGetTSIAndActionFromIndex( _iIndex, &p_stTSI, &p_oAction ) )
        {
            // swap state
			tdeTransitionState eState = p_oState -> mfn_eGetTransitionForAction( p_oAction );
			if( eState == E_ts_Allowed )
			{
//ANNECY CT 11/02/98{
				// swap to E_ts_Fluid
				p_oModifTransition = new State_ModifTransition( m_p_oParentDLL, p_oState, p_oAction, E_ts_Fluid,p_stTSI->p_oStateToGo);
//ENDANNECY CT}
			}
//ANNECY CT 11/02/98{
			else if( eState == E_ts_Fluid )
			{
				// swap to E_ts_Prohibited
				p_oModifTransition = new State_ModifTransition( m_p_oParentDLL, p_oState, p_oAction, E_ts_Prohibited );
			}
//ENDANNECY CT}
			else if( eState == E_ts_Prohibited )
			{
				// swap to E_ts_Unknown
				p_oModifTransition = new State_ModifTransition( m_p_oParentDLL, p_oState, p_oAction, E_ts_Unknown );
			}
			else /* e_State == E_ts_Unknown */
			{
				// swap to E_ts_Allowed
				p_oModifTransition = new State_ModifTransition( m_p_oParentDLL, p_oState, p_oAction, E_ts_Allowed, p_stTSI ? p_stTSI -> p_oStateToGo : NULL );
			}
			if( p_oModifTransition )
				M_MakeDo( p_oModifTransition );
			bResult = TRUE;
        }
    }
    return bResult;
}

// ----------------------------------------------------------------------------
// Author      : Marc Trabucato               Creation : 18/11/97
// Description : set transition
// ----------------------------------------------------------------------------
void CDlgState::mfn_vSetTransitions( tdeTransitionState _eNewState )
{
    CListBox *pLB = M_p_oListAction();
    int iNbSel = pLB -> GetSelCount();
    CPA_State *p_oState = M_p_oCurrentState();

    if( iNbSel > 0 )
    {
        int *a_iSel = (int*) malloc( iNbSel * sizeof( int ) );
        pLB -> GetSelItems( iNbSel, a_iSel );
        if ( iNbSel == 1 )
        {
            State_ModifTransition   *p_oModifTransition = NULL;
            tdstTransitionStateInfo *p_stTSI            = NULL;
            CPA_Action              *p_oAction          = NULL;

            // find current action
			
            if( mfn_bGetTSIAndActionFromIndex( a_iSel[0], &p_stTSI, &p_oAction ) )
            {
                // swap state
				tdeTransitionState eState = p_oState -> mfn_eGetTransitionForAction( p_oAction );
				if( eState != _eNewState )
				{
					p_oModifTransition = new State_ModifTransition( m_p_oParentDLL, p_oState, p_oAction, _eNewState, p_stTSI ? p_stTSI -> p_oStateToGo : NULL );
                    M_MakeDo( p_oModifTransition );
				}
            }
        }
        else
        {
            State_ModifTransitionExtended   *p_oModifExtended   = new State_ModifTransitionExtended( m_p_oParentDLL, p_oState );

			p_oModifExtended -> mfn_vAddState( p_oState );
            for ( int iIndex = 0 ; iIndex < iNbSel ; iIndex++ )
            {
                tdstTransitionStateInfo *p_stTSI            = NULL;
                CPA_Action              *p_oAction          = NULL;

                // find current action				
                if( mfn_bGetTSIAndActionFromIndex( a_iSel[iIndex], &p_stTSI, &p_oAction ) )
                {
					tdeTransitionState eState = p_oState -> mfn_eGetTransitionForAction( p_oAction);
					if( eState != _eNewState )
					{
						p_oModifExtended -> mfn_vAddTransition( p_oAction, _eNewState, p_stTSI ? p_stTSI -> p_oStateToGo : NULL );
					}
                }
            }
			p_oModifExtended -> mfn_vEndCreation();
            M_MakeDo( p_oModifExtended );
        }
        free( a_iSel );
    }
}

// ----------------------------------------------------------------------------
// Author      : Marc Trabucato               Creation : 18/11/97
// Description : set display state (all, prohibited or allowed)
// ----------------------------------------------------------------------------
void CDlgState::mfn_vSetDisplayTransition( tdeDisplayType _eDisplay )
{
    m_eTransitionTypeDisplay = _eDisplay;
    switch ( m_eTransitionTypeDisplay )
    {
    case E_dt_Prohibited:
        M_p_oBTID( IDC_BT_DISPLAY ) -> SetWindowText( "Show Prohibited" );
        break;
    case E_dt_All:
        M_p_oBTID( IDC_BT_DISPLAY ) -> SetWindowText( "Show All" );
        break;
    case E_dt_Allowed:
        M_p_oBTID( IDC_BT_DISPLAY ) -> SetWindowText( "Show Allowed" );
        break;
    }
    M_p_oBTID( IDC_BT_DISPLAY ) -> Invalidate();
    mfn_vFillInterruptActionList();
}

// ----------------------------------------------------------------------------
// Author      : Marc Trabucato               Creation : 20/11/97
// Description : Get TSI and Action with "action name" of given item on Transitions ListBox
// ----------------------------------------------------------------------------
BOOL CDlgState::mfn_bGetTSIAndActionFromIndex( int _iIndex, tdstTransitionStateInfo **_pp_stTSI, CPA_Action **_pp_oAction)
{
	CListBox *pLB		= M_p_oListAction();
	BOOL     bResult	= FALSE;

	if( ( _iIndex >= 0 ) && ( _iIndex < pLB -> GetCount() ) )
	{
		tdstTransitionStateInfo *p_stTSI = NULL;


		p_stTSI = (tdstTransitionStateInfo*) pLB -> GetItemData( _iIndex );

		if( p_stTSI )
		{
			// tdstTransitionStateInfo exists
			if( _pp_stTSI )		*_pp_stTSI = p_stTSI;
			if( _pp_oAction )	*_pp_oAction = p_stTSI -> p_oAction;
			bResult = TRUE;
		}
		else
		{   // tdstTransitionStateInfo not found, uses item text
			if( _pp_stTSI )		*_pp_stTSI = NULL;
			if( _pp_oAction )
			{
				CString csActionName;
				pLB -> GetText( _iIndex, csActionName );
				*_pp_oAction  = (CPA_Action*)m_p_oParentDLL -> GetBaseObject( csActionName, C_szActionTypeName, M_p_oCurrentFamily() );
				bResult = ( *_pp_oAction != NULL );
			}
		}
	}
	return bResult;
}

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