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

#include "stdafx.h"


#include "acp_base.h"
#include "ITF.h"

#include "TAC.h"
#include "TAn.h"

#include "DlgActCt.hpp"
#include "ACInterf.hpp"
#include "DlgNwSt.hpp"
#include "DlgInput.hpp"
#include "STModif.hpp"
#include "ACModif.hpp"

#include "..\Main\Inc\_EditID.h"
#include "TUT.h"

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

/*=============================================================================
 MACROS
=============================================================================*/
#define M_GetListFromID(nIDList)        ((CListBox *)GetDlgItem( nIDList ))
#define M_GetCurSel(nIDList)            (M_GetListFromID(nIDList)->GetCurSel())
#define M_GetItemData(nIDList,iItem)    (M_GetListFromID(nIDList)->GetItemData(iItem))

#define M_GetCurrentFamily()            (m_p_oParentDLL -> mfn_p_oGetCurrentFamily())
#define M_GetCurrentAction()            (m_p_oParentDLL -> mfn_p_oGetCurrentAction())
#define M_GetCurrentState()             (m_p_oParentDLL -> mfn_p_oGetCurrentState())

#define M_Enable( bEnable)                      ( (bEnable) ? MF_ENABLED : MF_GRAYED )
#define M_IsDefaultState(p_oAction,p_oState)    ( (p_oAction) && ( (p_oAction)->mfn_p_oGetDefaultState () == (p_oState) ) )

#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_MakeDo( p_oModif )               m_p_oParentDLL -> M_GetEditManager() -> AskFor ( p_oModif )

/*=============================================================================
 CONSTANTS
=============================================================================*/
// Popup Menu ID
#define C_uiPMDefault               2000
#define C_uiPMRename                (C_uiPMDefault + 1)
#define C_uiPMCopy                  (C_uiPMDefault + 2)
#define C_uiPMDel                   (C_uiPMDefault + 3)
#define C_uiPMDelAll                (C_uiPMDefault + 4)
#define C_uiPMNext                  (C_uiPMDefault + 5)
#define C_uiPMCreateNormal          (C_uiPMDefault + 6)
#define C_uiPMCreateTransitional    (C_uiPMDefault + 7)
#define C_uiPMList                  (C_uiPMDefault + 10)

#define C_iBorderSize   2

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

/*-----------------------------------------------------------------------------
 *  Description : constructor
 *---------------------------------------------------------------------------*/
CDlgActionContents::CDlgActionContents() : CFormView(CDlgActionContents::IDD)
{
// CPA_Ed_1 Mihaela Tancu begin
	m_bStateDrag = 0;
	m_iIndexListBox = LB_ERR;
// CPA_Ed_1 Mihaela Tancu end
	m_bFirstShow = TRUE;
    m_p_oStateUnderCursor = NULL;
    m_p_oParentDLL = NULL;
	//{{AFX_DATA_INIT(CDlgActionContents)
		// NOTE: the ClassWizard will add member initialization here
	//}}AFX_DATA_INIT

    // create bold font
    PLOGFONT plfBold = (PLOGFONT) LocalAlloc(LPTR, sizeof(LOGFONT));
    lstrcpy(plfBold->lfFaceName, "MS Sans Serif");
    plfBold->lfWeight = FW_BOLD ;
    plfBold->lfHeight = 8;
    plfBold->lfEscapement = 0;
    m_oBoldFont.CreateFontIndirect(plfBold);
    // create italic font
    PLOGFONT plfItalic = (PLOGFONT) LocalAlloc(LPTR, sizeof(LOGFONT));
    lstrcpy(plfItalic->lfFaceName, "MS Sans Serif");
    plfItalic->lfItalic = TRUE;
    plfItalic->lfWeight = FW_NORMAL ;
    plfItalic->lfHeight = 8;
    plfItalic->lfEscapement = 0;
    m_oItalicFont.CreateFontIndirect(plfItalic);
}

/*-----------------------------------------------------------------------------
 *  Description : destructor
 *---------------------------------------------------------------------------*/
CDlgActionContents::~CDlgActionContents()
{
    // delete bold font
    m_oBoldFont.DeleteObject();
    m_oItalicFont.DeleteObject();
}

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

/*-----------------------------------------------------------------------------
 *  Description : create & register controls for TUT module
 *---------------------------------------------------------------------------*/
BOOL CDlgActionContents::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_LIST_STATES,      "TAC_STM_STATESLIST_LIST",      TUT_e_ListBox );
    TUT_M_vRegisterControlID( IDC_BT_NEWSTATE,      "TAC_STM_STATESLIST_BTNEW",     TUT_e_Button );
    TUT_M_vRegisterControlID( IDC_BT_DEFAULTSTATE,  "TAC_STM_STATESLIST_BTDEFAULT", TUT_e_Button );
    TUT_M_vRegisterControlID( IDC_BT_DELSTATE,      "TAC_STM_STATESLIST_BTDELETE",  TUT_e_Button );
    TUT_M_vRegisterControlID( IDC_BT_DELALLSTATES,  "TAC_STM_STATESLIST_BTDELALL",  TUT_e_Button );
    TUT_M_vRegisterControlID( IDC_BT_COPYSTATE,     "TAC_STM_STATESLIST_BTCOPY",    TUT_e_Button );
    TUT_M_vRegisterControlID( IDC_BT_RENSTATE,      "TAC_STM_STATESLIST_BTRENAME",  TUT_e_Button );
    TUT_M_vRegisterControlID( IDC_BUTTON_UP,        "TAC_STM_STATESLIST_BTUP",		TUT_e_Button );
    TUT_M_vRegisterControlID( IDC_BUTTON_DOWN,      "TAC_STM_STATESLIST_BTDOWN",	TUT_e_Button );
    //
    return bResult;
}

/*-----------------------------------------------------------------------------
 *  Description : message map
 *---------------------------------------------------------------------------*/
BEGIN_MESSAGE_MAP(CDlgActionContents, CFormView)
	//{{AFX_MSG_MAP(CDlgActionContents)
    ON_WM_DESTROY()
	ON_BN_CLICKED(IDC_BT_DELSTATE, OnBtDelstate)
	ON_LBN_SELCHANGE(IDC_LIST_STATES, OnSelchangeListStates)
	ON_BN_CLICKED(IDC_BT_NEWSTATE, OnBtNewstate)
	ON_BN_CLICKED(IDC_BT_COPYSTATE, OnBtCopystate)
	ON_BN_CLICKED(IDC_BT_DEFAULTSTATE, OnBtDefaultstate)
	ON_BN_CLICKED(IDC_BT_DELALLSTATES, OnBtDelallstates)
	ON_BN_CLICKED(IDC_BT_RENSTATE, OnBtRenstate)
//  CPA_Ed_1 Mihaela Tancu begin
	ON_BN_CLICKED(IDC_BUTTON_UP, OnBtUp)
	ON_BN_CLICKED(IDC_BUTTON_DOWN, OnBtDown)
//  CPA_Ed_1 Mihaela Tancu end
	ON_WM_DRAWITEM()
	ON_WM_SIZE()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

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

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

/******************************************************************************
* CDlgActionContents message handlers
******************************************************************************/

/*-----------------------------------------------------------------------------
 *  Description : unregister control from TUT
 *---------------------------------------------------------------------------*/
void CDlgActionContents::OnDestroy()
{
    TUT_M_vGetTutDll();
    TUT_M_vUnregisterControlID( IDC_LIST_STATES );
    TUT_M_vUnregisterControlID( IDC_BT_NEWSTATE );
    TUT_M_vUnregisterControlID( IDC_BT_DEFAULTSTATE );
    TUT_M_vUnregisterControlID( IDC_BT_DELSTATE );
    TUT_M_vUnregisterControlID( IDC_BT_DELALLSTATES );
    TUT_M_vUnregisterControlID( IDC_BT_COPYSTATE );
    TUT_M_vUnregisterControlID( IDC_BT_RENSTATE );
    TUT_M_vUnregisterControlID( IDC_BUTTON_UP );
    TUT_M_vUnregisterControlID( IDC_BUTTON_DOWN );

    CFormView::OnDestroy();
}

/*-----------------------------------------------------------------------------
 *  Description : intercept the Rbutton Click on listbox
 *---------------------------------------------------------------------------*/
BOOL CDlgActionContents::PreTranslateMessage(MSG* pMsg)
{
    if( (M_GetCurSel(IDC_LIST_STATES) != LB_ERR) &&
        (pMsg->hwnd == GetDlgItem(IDC_LIST_STATES)->m_hWnd) )
    {
        if(pMsg->message == WM_RBUTTONDOWN)
        {
            // create and display the context popmenu
            OnRButtonDownStatesList(pMsg);
        }
        else if(pMsg->message == WM_KEYDOWN)
        {
            OnKeyDownStatesList(pMsg);
        }
//  CPA_Ed_1 Mihaela Tancu begin
        else if(pMsg->message == WM_LBUTTONDOWN)
        {
            OnLButtonDownStatesList(pMsg);
        }
        else if(pMsg->message == WM_LBUTTONUP)
        {
            OnLButtonUpStatesList(pMsg);
        }
        else if(pMsg->message == WM_MOUSEMOVE)
        {
            OnMouseMoveStatesList(pMsg);
        }
//  CPA_Ed_1 Mihaela Tancu end
    }
	return CFormView::PreTranslateMessage(pMsg);
}

/*-----------------------------------------------------------------------------
 *  Description : intercept the popup menu entry
 *---------------------------------------------------------------------------*/
BOOL CDlgActionContents::OnCommand(WPARAM wParam, LPARAM lParam)
{
	switch(LOWORD(wParam))
    {
    case C_uiPMDefault:             OnBtDefaultstate();                         break;
    case C_uiPMRename:              OnBtRenstate();                             break;
    case C_uiPMCopy:                OnBtCopystate();                            break;
    case C_uiPMDel:                 OnBtDelstate();                             break;
    case C_uiPMDelAll:              OnBtDelallstates();                         break;
    case C_uiPMNext:                fn_vSetAsNextState(m_p_oStateUnderCursor);  break;
    case C_uiPMCreateNormal:        OnBtCreateState( TRUE );                    break;
    case C_uiPMCreateTransitional:  OnBtCreateState( FALSE );                   break;
    default :
    	return CFormView::OnCommand(wParam, lParam);
    }

    return TRUE;
}

/*-----------------------------------------------------------------------------
 *  Description : handle function for message WM_DRAWITEM
 *---------------------------------------------------------------------------*/
void CDlgActionContents::OnDrawItem(int nIDCtl, LPDRAWITEMSTRUCT lpDIS)
{
    if ( (lpDIS->itemID != LB_ERR) &&
         (nIDCtl == IDC_LIST_STATES) &&
         (M_GetListFromID(IDC_LIST_STATES)->IsWindowEnabled() ) )
	{
		char		szText[100];
        CListBox    *pLB = M_GetListFromID(IDC_LIST_STATES);
		CBrush		oBrush;
		COLORREF	xTextColor;
		BOOL		bSelected = (lpDIS->itemState & ODS_SELECTED );
        CFont       *xFntPrev;
        CDC         *pDC = CDC::FromHandle(lpDIS->hDC);
        CString     oCst;
        BOOL        bFontChanged = FALSE;

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

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

        pLB->GetText( lpDIS->itemID, szText );

//  CPA_Ed_1 Mihaela Tancu begin
		CPA_State* p_oState=(CPA_State*)M_GetItemData(IDC_LIST_STATES,lpDIS->itemID);
//  CPA_Ed_1 Mihaela Tancu end

        // change font
        if ( p_oState == M_GetCurrentAction()->mfn_p_oGetDefaultState() )
        {
            xFntPrev = pDC->SelectObject( &m_oBoldFont );
            bFontChanged = TRUE;
            oCst . Format ( "%s" , szText );
        }
		else if ( p_oState->mfn_bGetTransitional() )
        {
            //xFntPrev = pDC->SelectObject(&m_oItalicFont);
            //bFontChanged = TRUE;
            xTextColor = bSelected ? GetSysColor( COLOR_HIGHLIGHTTEXT ) : RGB(255,0,0);
//  CPA_Ed_1 Mihaela Tancu begin
			p_oState->mfn_vObtainSpaceNumbers();  // get the number
			//of spaces to put before a transitional state, 0 if it points to the default state
			int iNb = p_oState->mfn_iGetSpaceNumbers();
			CString szSpaces = CString(' ', iNb);
			p_oState->mfn_vSetSpaceNumbers(0);  //reset the number of spaces
//  CPA_Ed_1 Mihaela Tancu end

            oCst . Format ( "[ %s ]" , szText );

//  CPA_Ed_1 Mihaela Tancu begin
			oCst = szSpaces+oCst;
//  CPA_Ed_1 Mihaela Tancu end
        }
        else
            oCst . Format ( "%s" , szText );

		pDC->SetBkMode( TRANSPARENT);
		pDC->SetTextColor( xTextColor );
        lpDIS->rcItem.left += 2;
		pDC->DrawText( oCst, &lpDIS->rcItem, DT_SINGLELINE | DT_LEFT | DT_VCENTER );
        // restore font
        if ( bFontChanged )
            pDC->SelectObject( xFntPrev );

		oBrush.DeleteObject();
	}
    else
        CFormView::OnDrawItem(nIDCtl, lpDIS);
}

/*-----------------------------------------------------------------------------
 *  Description : handle function for message WM_SIZE
 *---------------------------------------------------------------------------*/

void CDlgActionContents::OnSize(UINT nType, int cx, int cy)
{
    if(GetDlgItem(IDC_LIST_STATES))
    {
        CRect oRectDlg, oRectList, oRectBTDefault, oRectBTNew, oRectBTCopy, oRectBTDel, oRectBTRen, oRectBTDelAll ;
        int iSize;
		CRect oRectUp, oRectDown;

        // get pos
        M_GetClientRect( this, &oRectDlg );
        M_GetClientRectId( IDC_BT_DEFAULTSTATE, &oRectBTDefault );
        M_GetClientRectId( IDC_BT_NEWSTATE, &oRectBTNew );
        M_GetClientRectId( IDC_BT_COPYSTATE, &oRectBTCopy );
        M_GetClientRectId( IDC_BT_DELSTATE, &oRectBTDel );
        M_GetClientRectId( IDC_BT_RENSTATE, &oRectBTRen );
        M_GetClientRectId( IDC_BT_DELALLSTATES, &oRectBTDelAll );
        M_GetClientRectId( IDC_LIST_STATES, &oRectList );
//  CPA_Ed_1 Mihaela Tancu begin
        M_GetClientRectId( IDC_BUTTON_UP, &oRectUp );
        M_GetClientRectId( IDC_BUTTON_DOWN, &oRectDown );
//  CPA_Ed_1 Mihaela Tancu end

        // Left Align
        oRectBTNew . left = oRectBTDefault . left = oRectList . left = oRectDlg . left + C_iBorderSize;
        // Right Align
//        oRectBTDel . right = oRectBTDelAll . right = oRectList . right = oRectDlg . right - C_iBorderSize;
//  CPA_Ed_1 Mihaela Tancu begin
		oRectUp . right = oRectDown . right = oRectList . right = oRectDlg . right - C_iBorderSize;
//  CPA_Ed_1 Mihaela Tancu end
        // Bottom Align
        oRectList . bottom = max( oRectList . top, oRectDlg . bottom - C_iBorderSize );

        // BTs
//  CPA_Ed_1 Mihaela Tancu begin
        iSize = (oRectDlg . Width() - (C_iBorderSize<<2)) / 4;
//  CPA_Ed_1 Mihaela Tancu end

        oRectBTDefault . right  = oRectBTNew . right    = oRectBTNew . left + iSize;
//  CPA_Ed_1 Mihaela Tancu begin
		oRectUp . left    = oRectDown . left     = oRectUp . right - iSize ;
        oRectBTRen . left       = oRectBTCopy . left    = oRectBTNew . right + C_iBorderSize;
        oRectBTRen . right      = oRectBTCopy . right   = oRectBTCopy . left + iSize;
		oRectBTDelAll . left    = oRectBTDel . left     = oRectBTCopy . right + C_iBorderSize;
		oRectBTDelAll . right    = oRectBTDel . right     = oRectBTDel . left + iSize;
//  CPA_Ed_1 Mihaela Tancu end

        // set pos
        M_SetClientRectId( IDC_BT_DEFAULTSTATE, &oRectBTDefault );
        M_SetClientRectId( IDC_BT_NEWSTATE, &oRectBTNew );
        M_SetClientRectId( IDC_BT_COPYSTATE, &oRectBTCopy );
        M_SetClientRectId( IDC_BT_DELSTATE, &oRectBTDel );
        M_SetClientRectId( IDC_BT_RENSTATE, &oRectBTRen );
        M_SetClientRectId( IDC_BT_DELALLSTATES, &oRectBTDelAll );
//  CPA_Ed_1 Mihaela Tancu begin
        M_SetClientRectId( IDC_BUTTON_UP, &oRectUp );
        M_SetClientRectId( IDC_BUTTON_DOWN, &oRectDown );
//  CPA_Ed_1 Mihaela Tancu end
        M_SetClientRectId( IDC_LIST_STATES, &oRectList );
    }
}

/*-----------------------------------------------------------------------------
 *  Description : handle function for message LBN_SELCHANGE in State list
 *---------------------------------------------------------------------------*/
void CDlgActionContents::OnSelchangeListStates()
{
	int iItem = M_GetCurSel(IDC_LIST_STATES);

	if (iItem != LB_ERR)
    {
		m_p_oParentDLL->mfn_vChangeState( ((CPA_State *) M_GetItemData(IDC_LIST_STATES,iItem)) );
    }
	else
    {
		m_p_oParentDLL->mfn_vChangeState( NULL );
    }
}

/*-----------------------------------------------------------------------------
 *  Description :
 *---------------------------------------------------------------------------*/
void CDlgActionContents::OnBtNewstate()
{
    /*
    CDlgNewState *pDlgNewState = new CDlgNewState();
    RECT xRect;

    GetDlgItem(IDC_LIST_STATES)->GetWindowRect( &xRect ) ;
    CPoint oPoint( xRect.left , xRect.top ) ;
    // ask for type of state
    pDlgNewState -> SetPos ( &oPoint );
    if( pDlgNewState -> DoModal() == IDOK )
    {
        if( ! pDlgNewState -> csName . IsEmpty() )
        {
            State_New *p_oStateNew = new State_New ( m_p_oParentDLL, M_GetCurrentAction() , NULL, (char*)(LPCTSTR)(pDlgNewState -> csName), pDlgNewState -> bNormal, NULL ) ;
            M_MakeDo( p_oStateNew ) ;
        }
    }
    delete pDlgNewState;
    */
	CMenu oPopMenu;
    CRect oRect;

	GetDlgItem( IDC_BT_NEWSTATE ) -> GetWindowRect( oRect );
    // create popup
    oPopMenu . CreatePopupMenu () ;
	// fill menu
	oPopMenu . AppendMenu( MF_STRING , C_uiPMCreateNormal, "Normal States");
//  CPA_Ed_1 Mihaela Tancu begin
	if (!M_GetCurrentAction()->m_oListOfStates.IsEmpty())
//  CPA_Ed_1 Mihaela Tancu end
		oPopMenu . AppendMenu( MF_STRING , C_uiPMCreateTransitional, "Transitional States");
// ALX
    TUT_M_vGetTutDll    ();
    TUT_M_vRegisterMenu (this -> m_hWnd , oPopMenu . m_hMenu , oRect . left , oRect . bottom);
// ALX
    oPopMenu . TrackPopupMenu ( TPM_LEFTALIGN|TPM_RIGHTBUTTON, oRect . left, oRect.bottom , this);
    oPopMenu . DestroyMenu ();
}

/*-----------------------------------------------------------------------------
 *  Description : Create normal state
 *---------------------------------------------------------------------------*/
void CDlgActionContents::OnBtCreateState( BOOL _bNormal /*=TRUE*/)
{
    HINSTANCE hOldInst = AfxGetResourceHandle();
    AfxSetResourceHandle( m_p_oParentDLL -> GetDLLIdentity() -> hModule );

    CDlgInputText *p_oDlgInput = new CDlgInputText();
    CRect oRect;
    GetDlgItem(IDC_LIST_STATES)->GetWindowRect(&oRect);
    CPoint oPoint(oRect.left, oRect.top);

    p_oDlgInput->SetTitle( "Create normal state" );
    p_oDlgInput->SetMessage("New State Name :");
    p_oDlgInput->SetPos(&oPoint);
	p_oDlgInput->SetDefaultValue( C_szStateTypeName );
	p_oDlgInput->SetSelect( TRUE );
    if(p_oDlgInput->DoModal() == IDOK)
    {
		State_New *p_oStateNew = new State_New ( m_p_oParentDLL, M_GetCurrentAction() , NULL, p_oDlgInput -> GetInputText(), _bNormal, NULL ) ;
		M_MakeDo( p_oStateNew ) ;
    }
    delete p_oDlgInput;
    AfxSetResourceHandle( hOldInst );
}


//  CPA_Ed_1 Mihaela Tancu begin
/*-----------------------------------------------------------------------------
 *  Description : handle function for message BN_CLICKED on UpButton
 *   Author:	  Mihaela Tancu
 *---------------------------------------------------------------------------*/
void CDlgActionContents::OnBtUp()
{
	CPA_Action * p_oAction = M_GetCurrentAction();
	CPA_State *p_oPreviousState, *p_oPrevPrevState = NULL;
	CPA_List<CPA_State>* p_oListOfStates = &p_oAction->m_oListOfStates;
	POSITION stPos = p_oListOfStates->Find(M_GetCurrentState());

	if (stPos)  // the state have to be in the list with states
	{	p_oListOfStates->GetPrev(stPos);
		if (stPos) // before the current state is a state
		{	//determine the previous state (used for move the state) and its previous (in the list)
			p_oPreviousState = p_oListOfStates->GetAt(stPos);
			p_oListOfStates->GetPrev(stPos);
			if (stPos)
				p_oPrevPrevState = p_oListOfStates->GetAt(stPos);
		}
		else
			p_oPreviousState = NULL;
	}

	//determine the parameters for moving up a transitional or normal state
    State_Move *p_oStateMove = new State_Move ( m_p_oParentDLL,
									M_GetCurrentAction(),
									p_oPreviousState,
									M_GetCurrentState(),
									p_oPrevPrevState,
									p_oPreviousState,
									NULL, NULL, NULL, FALSE, FALSE) ;
    M_MakeDo( p_oStateMove ) ;
}

/*-----------------------------------------------------------------------------
 *  Description : handle function for message BN_CLICKED on DownButton
 *   Author:	  Mihaela Tancu
 *---------------------------------------------------------------------------*/
void CDlgActionContents::OnBtDown()
{
	CPA_Action * p_oAction = M_GetCurrentAction();
	CPA_State *p_oPreviousState;
	CPA_List<CPA_State>* p_oListOfStates = &p_oAction->m_oListOfStates;
	POSITION stPos = p_oListOfStates->Find(M_GetCurrentState());
	POSITION stPosNext = stPos;

	if (stPos)  // the state have to be in the list with states
	{	p_oListOfStates->GetPrev(stPos);
		if (stPos) // before the current state is a state
			p_oPreviousState = p_oListOfStates->GetAt(stPos);
		else
			p_oPreviousState = NULL;
	}

	CPA_State *p_oPreviousNextState, *p_oNextState=NULL;
	if (stPosNext)
	{	p_oListOfStates->GetNext(stPosNext);
		if (stPosNext) // before the current state is a state
		{	p_oPreviousNextState = p_oListOfStates->GetAt(stPosNext);
			p_oListOfStates->GetNext(stPosNext);
			if (stPosNext) // get the next of the next of the state in the list
				p_oNextState = p_oListOfStates->GetAt(stPosNext);
		}
		else
			p_oPreviousNextState = NULL;
	}

	//determine the parameters for moving down a transitional or normal state
	State_Move *p_oStateMove = new State_Move ( m_p_oParentDLL, M_GetCurrentAction(),
						p_oPreviousState, M_GetCurrentState(),
						p_oPreviousNextState, p_oNextState,
						NULL, NULL, NULL, FALSE, FALSE) ;
    M_MakeDo( p_oStateMove ) ;
}

//  CPA_Ed_1 Mihaela Tancu end

/*-----------------------------------------------------------------------------
 *  Description : handle function for message BN_CLICKED on Copystate button
 *---------------------------------------------------------------------------*/
void CDlgActionContents::OnBtCopystate()
{
    State_Copy *p_oStateCopy = new State_Copy ( m_p_oParentDLL, M_GetCurrentAction(), M_GetCurrentState() ) ;
    M_MakeDo( p_oStateCopy ) ;
}

/*-----------------------------------------------------------------------------
 *  Description : handle function for message BN_CLICKED on Defaultstate button
 *---------------------------------------------------------------------------*/
void CDlgActionContents::OnBtDefaultstate()
{
    CPA_Action * p_oAction = M_GetCurrentAction();
    CPA_State  * p_oState  = M_GetCurrentState();

    if( p_oAction && p_oState )
    {
        State_Default *p_oDefault = new State_Default ( m_p_oParentDLL, M_GetCurrentAction(), M_GetCurrentState() ) ;
        M_MakeDo( p_oDefault ) ;
    }
}

/*-----------------------------------------------------------------------------
 *  Description : handle function for message BN_CLICKED on Delstate button
 *---------------------------------------------------------------------------*/
void CDlgActionContents::OnBtDelstate()
{
    CPA_Action * p_oAction = M_GetCurrentAction();
    CPA_State  * p_oState  = M_GetCurrentState();

    if(p_oAction && p_oState)
    {
        char szText[100];

        sprintf(szText,"Do you really want to delete state \"%s\" ?",p_oState -> GetName() );
        if( MessageBox(szText,"WARNING", MB_ICONQUESTION+MB_YESNO) == IDYES )
        {
            State_Delete *p_oStateDelete = new State_Delete ( m_p_oParentDLL, M_GetCurrentAction(), M_GetCurrentState() ) ;
            M_MakeDo( p_oStateDelete ) ;
        }
    }
}

/*-----------------------------------------------------------------------------
 *  Description : handle function for message BN_CLICKED on DelAllstates button
 *---------------------------------------------------------------------------*/
void CDlgActionContents::OnBtDelallstates()
{
    CPA_Action * p_oAction = M_GetCurrentAction();

    if( (M_GetCurrentAction()) &&
        (MessageBox("Do you really want to delete all states ?", "WARNING", MB_ICONQUESTION+MB_YESNO) == IDYES ) )
    {
        Action_DelAllStates *p_oDelAllStates = new Action_DelAllStates ( m_p_oParentDLL, M_GetCurrentFamily(), M_GetCurrentAction() ) ;
        M_MakeDo( p_oDelAllStates ) ;
    }
}

/*-----------------------------------------------------------------------------
 *  Description : handle function for message BN_CLICKED on Renstate button
 *---------------------------------------------------------------------------*/
void CDlgActionContents::OnBtRenstate()
{
	int iItem = M_GetCurSel(IDC_LIST_STATES);

	if (iItem != LB_ERR)
    {
        HINSTANCE hOldInst = AfxGetResourceHandle();
        AfxSetResourceHandle( m_p_oParentDLL -> GetDLLIdentity() -> hModule );

        CDlgInputText *p_oDlgInput = new CDlgInputText();
        CRect oRect;
        char szTitle[200];
		char *szStateName = ((CPA_State *) M_GetItemData(IDC_LIST_STATES,iItem))->fn_p_szGetName();

        GetDlgItem(IDC_LIST_STATES)->GetWindowRect(&oRect);
        CPoint oPoint(oRect.left, oRect.top);
        sprintf(szTitle,"Rename state \"%s\"", szStateName );
        p_oDlgInput->SetTitle(szTitle);
        p_oDlgInput->SetMessage("New Name :");
        p_oDlgInput->SetPos(&oPoint);
		p_oDlgInput->SetDefaultValue( szStateName );
		p_oDlgInput->SetSelect( TRUE );
        if(p_oDlgInput->DoModal() == IDOK)
        {
            State_Rename *p_oStateRename = new State_Rename ( m_p_oParentDLL, M_GetCurrentAction() , M_GetCurrentState(), p_oDlgInput->GetInputText() ) ;
            M_MakeDo( p_oStateRename ) ;
        }
        delete p_oDlgInput;
        AfxSetResourceHandle( hOldInst );
    }
}


//  CPA_Ed_1 Mihaela Tancu begin
// ----------------------------------------------------------------------------
// Description : OnLButtonDownStatesList(MSG *pMsg)
// Handle function for message WM_LBUTTONDOWN on ListBox Action Contents
// Author : Mihaela Tancu
// ----------------------------------------------------------------------------
BOOL CDlgActionContents::OnLButtonDownStatesList(MSG *pMsg)
{
    CListBox    *pLB = M_GetListFromID(IDC_LIST_STATES);

    m_p_oStateUnderCursor = NULL;
	m_iIndexListBox = LB_ERR;
	m_bStateDrag = 0;

	if( pLB->GetCount() >0)
	{
		// find the State Under Cursor
		CPoint xPos;
		GetCursorPos(&xPos);
		pLB->ScreenToClient( &xPos);
		BOOL bOutside;
		int iIndex = pLB->ItemFromPoint(xPos, bOutside ) ; // the nearest state

		CRect oRect;
		pLB->GetItemRect(iIndex,&oRect);
		if(oRect.PtInRect(xPos))
		{
			// the cursor is indeed over this item...
			SetCapture();
			m_iIndexListBox = iIndex;
			m_p_oStateUnderCursor = (CPA_State*)pLB->GetItemData(iIndex);
			m_bStateDrag = 1;// ...and the item is draggable
		}
	}

    return 1;
}

// ----------------------------------------------------------------------------
// Description : OnMouseMoveStatesList(MSG *pMsg)
// Handle function for message WM_MOUSEMOVE on ListBox Action Contents
// Author : Mihaela Tancu
// ----------------------------------------------------------------------------
BOOL CDlgActionContents::OnMouseMoveStatesList(MSG *pMsg)
{
    if (pMsg->wParam & MK_LBUTTON) //if the mouse is moving and the left button is down
	{
		CListBox    *pLB = (CListBox *)GetDlgItem( IDC_LIST_STATES);
		pLB->SetRedraw(FALSE);
		if(m_bStateDrag)
		{
			m_bStateDrag = 1;
			// we are dragging something
			CPoint xPos;
			GetCursorPos(&xPos);
			CRect oRect;
			pLB -> GetClientRect( oRect );
			pLB -> ScreenToClient( &xPos);

			if(oRect.PtInRect(xPos))
			{
				BOOL bOutside;
				int iIndex = pLB->ItemFromPoint(xPos, bOutside ) ; // the nearest state
				//we can drag if is a normal state and is moving over a normal state
				if(!(m_p_oStateUnderCursor->mfn_bGetTransitional())
					&& (!((CPA_State*)pLB->GetItemData(iIndex))->mfn_bGetTransitional())) // ...the item is not a transitional state
					m_bStateDrag = 2; // we can drop (a normal state to a normal state) !
				//we can drag if is a transitional state and is moving over a transitional state
				if(m_p_oStateUnderCursor->mfn_bGetTransitional()
					&& (((CPA_State*)pLB->GetItemData(iIndex))->mfn_bGetTransitional())) // ...the item is not a transitional state
					m_bStateDrag = 2; // we can drop! (a transitional state to a transitional state)
				//we can drag if is a transitional state and is moving over the default state
				if ( m_p_oStateUnderCursor->mfn_bGetTransitional()
					 && (!((CPA_State*)pLB->GetItemData(iIndex))->mfn_bGetTransitional())
					 && ((CPA_State*)pLB->GetItemData(iIndex) == M_GetCurrentAction()->mfn_p_oGetDefaultState())) // ...the item is not a transitional state
					m_bStateDrag = 2; // we can drop! (a transitional state to the default state)
			}
		}

		if(m_bStateDrag == 2)
			SetCursor(M_GetMainApp()->LoadCursor(IDC_POINTER_CURSOR));  //modify the mouse cursor
		else
			SetCursor(M_GetMainApp()->LoadStandardCursor(IDC_NO)); //no dropping possible
	}

    return 1;
}


// ----------------------------------------------------------------------------
// Description : OnLButtonUpStatesList(MSG *pMsg)
// Handle function for message WM_LBUTTONUP on ListBox Action Contents
// Author : Mihaela Tancu
// -----------------------------------------------------------
BOOL CDlgActionContents::OnLButtonUpStatesList(MSG *pMsg)
{

	ReleaseCapture();   // Release the mouse capture established at
						// the beginning of the mouse drag.
	SetCursor(M_GetMainApp()->LoadStandardCursor(IDC_ARROW));
	//OnSelchangeListStates();
	// TODO: Add your message handler code here and/or call default
    CListBox    *pLB = M_GetListFromID(IDC_LIST_STATES);

	if(m_iIndexListBox != LB_ERR)
		pLB->SetCurSel(m_iIndexListBox);	// keep the previous selection

	pLB->SetRedraw(TRUE);					// allow drawing

	if(m_bStateDrag == 2)
	{
		m_bStateDrag = FALSE;
		// the dragging operation is possible
		BOOL bOutside;
		CPoint xPos;
		GetCursorPos(&xPos);
		pLB -> ScreenToClient( &xPos);
		int iIndex = pLB->ItemFromPoint(xPos, bOutside ) ; // the nearest state
		if(iIndex == m_iIndexListBox)
		{
			OnSelchangeListStates();
			return 1;
		}
		CRect oRect;
		pLB->GetItemRect(iIndex,&oRect);
		BOOL b_Before = oRect.PtInRect(xPos); // insert before an existing item
		if(b_Before && iIndex == m_iIndexListBox+1)
		{
			OnSelchangeListStates();
			return 1; // no need to move anything
		}

		CPA_State *p_oStateUnderCursor = (CPA_State*)pLB->GetItemData(iIndex); // obtain the target state
		CPA_State *p_oPrevStateToMove;
		CPA_State *p_oPrevStateTarget;

		if (m_iIndexListBox > 0) //if the state to move is at least the second in the list box
			p_oPrevStateToMove = (CPA_State*)pLB->GetItemData(m_iIndexListBox-1);
		else
			p_oPrevStateToMove = NULL;
		if(b_Before) // inserting before an item in the list box
		{
			if (iIndex > 0)
				p_oPrevStateTarget=(CPA_State*)pLB->GetItemData(iIndex-1);
			else
				p_oPrevStateTarget=NULL;
		}
		else // adding at the end of the list box
		{	p_oStateUnderCursor=NULL;
			p_oPrevStateTarget=(CPA_State*)pLB->GetItemData(pLB->GetCount()-1);
		}

		// move the normal or transitional state
	    State_Move *p_oStateMove = new State_Move ( m_p_oParentDLL, M_GetCurrentAction(),
													p_oPrevStateToMove, m_p_oStateUnderCursor,
													p_oPrevStateTarget, p_oStateUnderCursor,
													NULL, NULL, NULL, FALSE, FALSE) ;
		M_MakeDo( p_oStateMove ) ;

		m_p_oParentDLL->mfn_vChangeState( m_p_oStateUnderCursor);

	}
	else
		OnSelchangeListStates();

	m_bStateDrag = FALSE;
	return 1; // the cursor is outside the window - abort dragging

}
//  CPA_Ed_1 Mihaela Tancu end




/******************************************************************************
* CDlgActionContents specific functions
******************************************************************************/

/*-----------------------------------------------------------------------------
 *  Description : enable/disable buttons
 *---------------------------------------------------------------------------*/
void CDlgActionContents::fn_vUpdateButtons(CPA_State *_p_oState)
{
    CListBox *pLB = M_GetListFromID( IDC_LIST_STATES );

    if(_p_oState)
    {
        GetDlgItem(IDC_BT_COPYSTATE)->EnableWindow( TRUE );
//  CPA_Ed_1 Mihaela Tancu begin
        GetDlgItem(IDC_BT_DELSTATE)->EnableWindow( TRUE );
        if (_p_oState==M_GetCurrentAction()->mfn_p_oGetDefaultState())
        {
            CPA_List<CPA_State>* p_oListOfStates = &M_GetCurrentAction()->m_oListOfStates;
            POSITION stPosIni;
            CPA_State *p_oPreviousState;
            POSITION stPos = p_oListOfStates->Find(_p_oState);
            stPosIni = stPos;
            if (stPos)  // the state have to be in the list with states
            {
                p_oListOfStates->GetNext(stPosIni);
                if (stPosIni==NULL)
                {   //if in the list are no other normal states
                    p_oListOfStates->GetPrev(stPos);
                    if (stPos) // before the current state is a state transitional
                    {
                        p_oPreviousState = p_oListOfStates->GetAt(stPos);
                        if (p_oPreviousState->mfn_bGetTransitional()) // if it is a transitional state put it in front of its previous
                            GetDlgItem(IDC_BT_DELSTATE)->EnableWindow( FALSE );
                    }
                }
            }
        }
//  CPA_Ed_1 Mihaela Tancu end
        GetDlgItem(IDC_BT_DEFAULTSTATE)->EnableWindow( !_p_oState->mfn_bGetTransitional() && !M_IsDefaultState( M_GetCurrentAction(), _p_oState ) );
        GetDlgItem(IDC_BT_RENSTATE)->EnableWindow( TRUE );
//  CPA_Ed_1 Mihaela Tancu begin
        CPA_Action * p_oAction = M_GetCurrentAction();
        CPA_State *p_oPreviousState, *p_oNextState;
        CPA_List<CPA_State>* p_oListOfStates = &p_oAction->m_oListOfStates;
        POSITION stPosIni;
        POSITION stPos = p_oListOfStates->Find(_p_oState);
        stPosIni = stPos;
        if (stPos)  // the state have to be in the list with states
        {   p_oListOfStates->GetPrev(stPos);
            if (stPos) // before the current state is a state
            {
                p_oPreviousState = p_oListOfStates->GetAt(stPos);
                if (_p_oState->mfn_bGetTransitional()) // if it is a transitional state put it in front of its previous
                    GetDlgItem(IDC_BUTTON_UP)->EnableWindow( TRUE );
                else
                    if (p_oPreviousState->mfn_bGetTransitional())  //disable the Up button if the previous state is a transitional state
                        GetDlgItem(IDC_BUTTON_UP)->EnableWindow( FALSE );
                    else
                        //enable the button if the previous state is also a normal state
                        GetDlgItem(IDC_BUTTON_UP)->EnableWindow( TRUE );
            }
            else  // the current state is the first state in the list box
                GetDlgItem(IDC_BUTTON_UP)->EnableWindow( FALSE );
        }
        if (stPosIni)
        {
            p_oListOfStates->GetNext(stPosIni);  // test if after the current state is a state
            if (stPosIni)
            {
                p_oNextState = p_oListOfStates->GetAt(stPosIni);
                if (!_p_oState->mfn_bGetTransitional())  // if after is a normal state, the current state can be moved
                    GetDlgItem(IDC_BUTTON_DOWN)->EnableWindow( TRUE );
                else
                {   // if after the transitional state is also a transitional state this can be moved
                    if (p_oNextState->mfn_bGetTransitional())
                        GetDlgItem(IDC_BUTTON_DOWN)->EnableWindow( TRUE );
                    else   // cannot be moved if after the transitional state is a normal state
                        GetDlgItem(IDC_BUTTON_DOWN)->EnableWindow( FALSE );
                }
            }
            else
                GetDlgItem(IDC_BUTTON_DOWN)->EnableWindow( FALSE );

        }
//  CPA_Ed_1 Mihaela Tancu end
    }
    else
    {
        GetDlgItem(IDC_BT_COPYSTATE)->EnableWindow( FALSE );
        GetDlgItem(IDC_BT_DELSTATE)->EnableWindow( FALSE );
        GetDlgItem(IDC_BT_DEFAULTSTATE)->EnableWindow( FALSE );
        GetDlgItem(IDC_BT_RENSTATE)->EnableWindow( FALSE );
//  CPA_Ed_1 Mihaela Tancu begin
        GetDlgItem(IDC_BUTTON_UP)->EnableWindow( FALSE );
        GetDlgItem(IDC_BUTTON_DOWN)->EnableWindow( FALSE );
//  CPA_Ed_1 Mihaela Tancu end
    }
    GetDlgItem(IDC_BT_DELALLSTATES)->EnableWindow( pLB && pLB->GetCount () );
}

/*-----------------------------------------------------------------------------
 *  Description : change State list with the one in the given action
 *---------------------------------------------------------------------------*/
void CDlgActionContents::fn_vSetAction( CPA_Action *_p_oAction )
{
	CListBox *pLB = M_GetListFromID( IDC_LIST_STATES );

	// emptied state list
    pLB->ResetContent() ;

    fn_vUpdateButtons( NULL );
	// if no action specified (parameters is null, return now
	if (_p_oAction == NULL)
    {
        GetDlgItem(IDC_BT_NEWSTATE)->EnableWindow( FALSE );
		return;
    }
    GetDlgItem(IDC_BT_NEWSTATE)->EnableWindow( TRUE );
	// else get list of states of given action
	CPA_List<CPA_State>* p_oListOfStates = &_p_oAction->m_oListOfStates;
    // add each state of given action in list
    POSITION stPos = p_oListOfStates->GetHeadPosition ();
	int iIndex;

    while ( stPos )
    {
        CPA_State *p_oState = p_oListOfStates->GetNext ( stPos ) ;
		iIndex = pLB->AddString( p_oState->GetName() );
		if (iIndex != LB_ERR)
			pLB->SetItemData( iIndex, (DWORD) p_oState );
    }

    // select first state (if exists)
    if( pLB -> GetCount() > 0 )
        m_p_oParentDLL -> mfn_vSetCurrentState( (CPA_State*)pLB -> GetItemData( 0 ) );
    else
        m_p_oParentDLL -> mfn_vSetCurrentState( NULL );
}

/*-----------------------------------------------------------------------------
 *  Description : select given state
 *---------------------------------------------------------------------------*/
void CDlgActionContents::fn_vSetState( CPA_State *_p_oState )
{
	CListBox *pLB = M_GetListFromID( IDC_LIST_STATES );

    if(_p_oState)
    {
        int iIndex = pLB->FindStringExact( -1, _p_oState->GetName() );

        if( iIndex != LB_ERR )
        {
            pLB->SetCurSel( iIndex );
            fn_vUpdateButtons( _p_oState );
        }
        else
        {
            pLB->SetCurSel( -1 );
            fn_vUpdateButtons( NULL );
        }
    }
    else
    {
        pLB->SetCurSel( -1 );
        fn_vUpdateButtons( NULL );
    }

}

/*-----------------------------------------------------------------------------
 *  Description : change Next State  given state
 *---------------------------------------------------------------------------*/
void CDlgActionContents::fn_vSetAsNextState( CPA_State *_p_oNextState)
{
    State_ModifNextState *p_oNextState = new State_ModifNextState ( m_p_oParentDLL, M_GetCurrentState(), _p_oNextState ) ;
    M_MakeDo( p_oNextState ) ;
}

/*-----------------------------------------------------------------------------
 *  Description : fill menu with sequential states after given state
 *---------------------------------------------------------------------------*/
void CDlgActionContents::fn_vFillSequentialStateMenu( CMenu* _p_oMenu, CPA_Action *_p_oCurrentAction,
                                                      CPA_State *_p_oFirstState)
{
    CPA_List<CPA_State> m_oListOfMenuState ;
    CPA_State *p_oCurrentState = _p_oFirstState;
    int iNbState = 0;
    BOOL bContinue = TRUE;

    m_oListOfMenuState . RemoveAll () ;
    // add initial state
    _p_oMenu -> AppendMenu ( MF_STRING , C_uiPMList + iNbState , _p_oFirstState -> GetName() ) ;
    m_oListOfMenuState . AddTail( _p_oFirstState );
    iNbState = 1;
    // add next states
    do {
        // get current state
        p_oCurrentState = p_oCurrentState -> mfn_p_oGetNextState() ;
        bContinue = TRUE;

        if( p_oCurrentState )
        {
            // state already present ???
            BOOL bAlreadyInList = ( m_oListOfMenuState . Find( p_oCurrentState ) ? TRUE : FALSE );
            // state of other action
            BOOL bOtherAction = !bAlreadyInList && (p_oCurrentState -> mfn_p_oGetAction() != _p_oCurrentAction );
            // add state
            if(bAlreadyInList)
            {
                // add and stop
                _p_oMenu -> AppendMenu ( MF_STRING , C_uiPMList + iNbState , "return to \'" + p_oCurrentState -> GetName() + "\'" ) ;
                bContinue = FALSE;
            }
            else if(bOtherAction)
            {
                // add and stop
                _p_oMenu -> AppendMenu ( MF_STRING , C_uiPMList + iNbState , p_oCurrentState -> GetName() + " from " +  p_oCurrentState -> mfn_p_oGetAction() -> GetName() ) ;
                bContinue = FALSE;
            }
            else
            {
                // add and continue
                _p_oMenu -> AppendMenu ( MF_STRING , C_uiPMList + iNbState , p_oCurrentState -> GetName() ) ;
                m_oListOfMenuState . AddTail ( p_oCurrentState ) ;
                iNbState++;
            }
        }
        else
        {
            _p_oMenu -> AppendMenu ( MF_STRING , C_uiPMList + iNbState , "NONE" ) ;
            bContinue = FALSE;
        }
    } while (bContinue) ;
}

// ----------------------------------------------------------------------------
// Description :
// ----------------------------------------------------------------------------
void CDlgActionContents::OnRButtonDownStatesList(MSG *pMsg)
{
    // create and display the context popmenu
    CListBox    *pLB = M_GetListFromID(IDC_LIST_STATES);
    CMenu oPopMenu;
    CMenu oCreateMenu;
    CMenu oListMenu;
    POINT xPos;

    xPos.x = LOWORD(pMsg->lParam);
    xPos.y = HIWORD(pMsg->lParam);
    // update State Under Cursor
    CPoint oPoint(xPos);
    BOOL bOutside;
    int iIndex = pLB->ItemFromPoint(oPoint, bOutside ) ;
    if(bOutside)
    {
        m_p_oStateUnderCursor = NULL;
    }
    else
    {
        CRect oRect;

        pLB->GetItemRect(iIndex,&oRect);
        if(oRect.PtInRect(xPos))
            m_p_oStateUnderCursor = (CPA_State*)pLB->GetItemData(iIndex);
        else
            m_p_oStateUnderCursor = NULL;
    }
    // create popup
    oPopMenu . CreatePopupMenu () ;
    // create submenu 'Create'
    oCreateMenu . CreatePopupMenu () ;
    oCreateMenu . AppendMenu ( MF_STRING , C_uiPMCreateNormal , "Normal State" ) ;
    oCreateMenu . AppendMenu ( MF_STRING , C_uiPMCreateTransitional , "Transitional State" ) ;
    // add submenu 'Create'
    oPopMenu . AppendMenu ( MF_STRING|MF_POPUP|MF_ENABLED , (UINT)oCreateMenu.m_hMenu , "Create" ) ;
    // fill
    if( m_p_oStateUnderCursor )
    {
        if( !m_p_oStateUnderCursor->mfn_bGetTransitional() )
            oPopMenu . AppendMenu ( MF_STRING + M_Enable( !M_IsDefaultState(M_GetCurrentAction(),m_p_oStateUnderCursor) ),
                                    C_uiPMDefault , "Set as Default State" ) ;
        oPopMenu . AppendMenu ( MF_STRING + M_Enable(m_p_oStateUnderCursor) , C_uiPMRename  , "Rename State" ) ;
        oPopMenu . AppendMenu ( MF_STRING + M_Enable(m_p_oStateUnderCursor) , C_uiPMCopy    , "Copy State" ) ;
        oPopMenu . AppendMenu ( MF_STRING + M_Enable(m_p_oStateUnderCursor) , C_uiPMDel     , "Delete State" ) ;
    }
    oPopMenu . AppendMenu ( MF_STRING + M_Enable(pLB->GetCount()) , C_uiPMDelAll  , "Delete all States" ) ;
    if(m_p_oStateUnderCursor && M_GetCurrentState() && !M_GetCurrentState()->mfn_bGetTransitional() )
    {
        oPopMenu . AppendMenu ( MF_SEPARATOR ) ;
        oPopMenu . AppendMenu ( MF_STRING, C_uiPMNext, "Set \'" + m_p_oStateUnderCursor -> GetName () + "\' as Next State" ) ;
    }
    oPopMenu . AppendMenu ( MF_SEPARATOR ) ;
    //
    oListMenu . CreatePopupMenu () ;
    fn_vFillSequentialStateMenu ( &oListMenu , M_GetCurrentAction() , M_GetCurrentState() );
    oPopMenu . AppendMenu ( MF_STRING|MF_POPUP|MF_ENABLED , (UINT)oListMenu.m_hMenu , "Next Sequential States" ) ;
    pLB->ClientToScreen ( &xPos );
	// register for TUT module
    TUT_M_vGetTutDll    ();
    TUT_M_vRegisterMenu (this -> m_hWnd , oPopMenu . m_hMenu , xPos.x, xPos.y);
    // display
    oPopMenu . TrackPopupMenu ( TPM_LEFTALIGN|TPM_RIGHTBUTTON, xPos.x, xPos.y, this);
    oCreateMenu . Detach ();
    oListMenu . Detach () ;
    oPopMenu . DestroyMenu ();
}

// ----------------------------------------------------------------------------
// Description :
// ----------------------------------------------------------------------------
void CDlgActionContents::OnKeyDownStatesList(MSG *pMsg)
{
    int         nVirtKey    = (int)pMsg->wParam;
    CListBox    *pLB        = M_GetListFromID(IDC_LIST_STATES);
    int         iIndex      = pLB -> GetCurSel();

    if ( ( nVirtKey == VK_DELETE ) && ( iIndex != LB_ERR ) )
    {
        OnBtDelstate();
    }
}
