// DlgAnim.cpp : implementation file
//

///////////////////////////////////////////////////////////////////////////////
// INCLUDES
///////////////////////////////////////////////////////////////////////////////

//#undef _DEBUG
#include "stdafx.h"
//#define _DEBUG

#include "ACP_Base.h"
#include "ITF.h"

#include "TAC.h"
#include "TFa.h"
#include "OAc.h"

#include "ACInterf.hpp"
#include "DlgAnim.hpp"
#include "STModif.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_LBAnim()              ( (CListBox*) GetDlgItem( IDC_LB_ANIM ) )
#define M_BTCreate()            ( (CButton*) GetDlgItem( IDC_BT_CREATESTATES ) )
#define M_BTMore()              ( (CButton*) GetDlgItem( IDC_BT_MORE) )
#define M_CBFamily()            ( (CComboBox*) GetDlgItem( IDC_COMBO_FAMILY) )

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

#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_ShowControl( Id )                GetDlgItem( Id ) -> EnableWindow( TRUE ); GetDlgItem( Id ) -> ShowWindow( SW_SHOW );
#define M_HideControl( Id )                GetDlgItem( Id ) -> EnableWindow( FALSE ); GetDlgItem( Id ) -> ShowWindow( SW_HIDE );
#define M_MakeDo( p_oModif )               m_p_oParentDLL -> M_GetEditManager() -> AskFor ( p_oModif )

///////////////////////////////////////////////////////////////////////////////
// CONSTANTS
///////////////////////////////////////////////////////////////////////////////
#define C_iBorderSize   2
#define C_uiPMDefault       2000
#define C_uiPMCreateNormal          (C_uiPMDefault + 1)
#define C_uiPMCreateTransitional    (C_uiPMDefault + 2)
// CPA_Ed_1 Mihaela Tancu begin
#define C_uiPMCreateNormalMove      (C_uiPMDefault + 3)
#define C_uiPMCreateTransitionalMove    (C_uiPMDefault + 4)
// CPA_Ed_1 Mihaela Tancu end

/////////////////////////////////////////////////////////////////////////////
// CDlgAnimList
/////////////////////////////////////////////////////////////////////////////

IMPLEMENT_DYNCREATE(CDlgAnimList, CFormView)

CDlgAnimList::CDlgAnimList()
	: CFormView(CDlgAnimList::IDD)
{
	//{{AFX_DATA_INIT(CDlgAnimList)
		// NOTE: the ClassWizard will add member initialization here
	//}}AFX_DATA_INIT
    m_bAllFamilies = FALSE;
}

CDlgAnimList::~CDlgAnimList()
{
}

void CDlgAnimList::DoDataExchange(CDataExchange* pDX)
{
	CFormView::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CDlgAnimList)
		// NOTE: the ClassWizard will add DDX and DDV calls here
	//}}AFX_DATA_MAP
}


/*-----------------------------------------------------------------------------
 *  Description : create & register controls for TUT module
 *---------------------------------------------------------------------------*/
BOOL CDlgAnimList::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_LB_ANIM,          "TAC_STM_ANIMSLIST_LIST",       TUT_e_ListBox );
    TUT_M_vRegisterControlID( IDC_BT_CREATESTATES,  "TAC_STM_ANIMSLIST_BTCREATE",   TUT_e_Button );
    TUT_M_vRegisterControlID( IDC_COMBO_FAMILY,     "TAC_STM_ANIMSLIST_CBFAMILY",   TUT_e_ComboBox );
    TUT_M_vRegisterControlID( IDC_BT_MORE,          "TAC_STM_ANIMSLIST_BTMORE",     TUT_e_Button );
    //
    return bResult;
}

BEGIN_MESSAGE_MAP(CDlgAnimList, CFormView)
	//{{AFX_MSG_MAP(CDlgAnimList)
    ON_WM_DESTROY()
	ON_WM_SIZE()
	ON_BN_CLICKED(IDC_BT_CREATESTATES, OnBtCreatestates)
	ON_LBN_SELCHANGE(IDC_LB_ANIM, OnSelchangeLbAnim)
	ON_BN_CLICKED(IDC_BT_MORE, OnBtMore)
	ON_CBN_SELCHANGE(IDC_COMBO_FAMILY, OnSelchangeComboFamily)
	ON_WM_DRAWITEM()
//  CPA_Ed_1 Mihaela Tancu begin
	ON_WM_MOUSEMOVE()
//  CPA_Ed_1 Mihaela Tancu end
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CDlgAnimList diagnostics
/////////////////////////////////////////////////////////////////////////////

#ifdef _DEBUG
void CDlgAnimList::AssertValid() const
{
	CFormView::AssertValid();
}

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

/////////////////////////////////////////////////////////////////////////////
// CDlgAnimList message handlers
/////////////////////////////////////////////////////////////////////////////

// ----------------------------------------------------------------------------
// Description : handle function for msg WM_DESTROY : unregister controls for TUT
// ----------------------------------------------------------------------------
void CDlgAnimList::OnDestroy()
{
    TUT_M_vGetTutDll();
    TUT_M_vUnregisterControlID( IDC_LB_ANIM );
    TUT_M_vUnregisterControlID( IDC_BT_CREATESTATES );
    TUT_M_vUnregisterControlID( IDC_COMBO_FAMILY );
    TUT_M_vUnregisterControlID( IDC_BT_MORE );

    CFormView::OnDestroy();
}

// ----------------------------------------------------------------------------
// Description : handle function for msg WM_SIZE
// ----------------------------------------------------------------------------
void CDlgAnimList::OnSize(UINT nType, int cx, int cy)
{
    if(GetDlgItem(IDC_LB_ANIM))
    {
        CRect oRectDlg, oRectList, oRectBTCreate, oRectBTMore, oRectST, oRectCB;
        int iSize;

        // get pos
        M_GetClientRect( this, &oRectDlg );
        M_GetClientRectId( IDC_BT_CREATESTATES, &oRectBTCreate );
        M_GetClientRectId( IDC_ST_ANIM, &oRectST );
        M_GetClientRectId( IDC_LB_ANIM, &oRectList );
        M_GetClientRectId( IDC_COMBO_FAMILY, &oRectCB );
        M_GetClientRectId( IDC_BT_MORE, &oRectBTMore );

        // Left Align
        oRectCB . left = oRectList . left = oRectDlg . left + C_iBorderSize;
        // Right Align
        oRectCB . right = oRectList . right = oRectDlg . right - C_iBorderSize;
        // Bottom Align
        oRectList . bottom = max( oRectList . top, oRectDlg . bottom - C_iBorderSize );

        // BT
        iSize = oRectBTMore . Width();
        oRectBTMore . left = oRectST . right + C_iBorderSize;
        oRectBTMore . right = oRectBTMore . left + iSize;
        oRectBTCreate . left = oRectBTMore . right + C_iBorderSize;
        oRectBTCreate . right = min( oRectBTCreate . left + 85, oRectDlg . right - C_iBorderSize );

        // set pos
        M_SetClientRectId( IDC_BT_CREATESTATES, &oRectBTCreate );
        M_SetClientRectId( IDC_LB_ANIM, &oRectList );
        M_SetClientRectId( IDC_COMBO_FAMILY, &oRectCB );
        M_SetClientRectId( IDC_BT_MORE, &oRectBTMore );
    }
}

// -----------------------------------------------------------------------------
// Description : intercept the popup menu entry
// ---------------------------------------------------------------------------*/
BOOL CDlgAnimList::OnCommand(WPARAM wParam, LPARAM lParam)
{
	switch(LOWORD(wParam))
    {
    case C_uiPMCreateNormal:        mfn_vCreateStates( TRUE );  break;
    case C_uiPMCreateTransitional:  mfn_vCreateStates( FALSE ); break;
// CPA_Ed_1 Mihaela Tancu begin
    case C_uiPMCreateNormalMove:        mfn_vCreateStatesMove( TRUE );  break;
    case C_uiPMCreateTransitionalMove:  mfn_vCreateStatesMove( FALSE ); break;
// CPA_Ed_1 Mihaela Tancu end
    default :
    	return CFormView::OnCommand(wParam, lParam);
    }

    return TRUE;
}

// ----------------------------------------------------------------------------
// Description : Intercept all messages
// ----------------------------------------------------------------------------
BOOL CDlgAnimList::PreTranslateMessage(MSG* pMsg)
{
    if( ( pMsg->hwnd == GetDlgItem(IDC_LB_ANIM)->m_hWnd ) &&
        ( pMsg -> message == WM_RBUTTONDOWN ) )
    {
        return OnRButtonDownLbAnim( pMsg );
    }
    else if ( ( pMsg->hwnd == GetDlgItem(IDC_LB_ANIM)->m_hWnd ) &&
              ( pMsg -> message == WM_LBUTTONDOWN )
            )
    {
/*
        if( ( GetKeyState( VK_SHIFT ) & 0xff00) )
            return TRUE;
*/
        return OnLButtonDownLbAnim( pMsg );
    }
//  CPA_Ed_1 Mihaela Tancu begin
    else if (pMsg -> message == WM_LBUTTONUP )
    {
        return OnLButtonUpLbAnim( pMsg );
    }
//  CPA_Ed_1 Mihaela Tancu end
    return CFormView::PreTranslateMessage(pMsg);
}

// ----------------------------------------------------------------------------
//  Author      : MT
//  Creation    : 13/08/97
//
// Description :
// ----------------------------------------------------------------------------
void CDlgAnimList::OnDrawItem(int nIDCtl, LPDRAWITEMSTRUCT lpDIS)
{
    if ( ( nIDCtl == IDC_LB_ANIM ) &&
         ( M_LBAnim() -> IsWindowEnabled() ) &&
         ( lpDIS->itemID != LB_ERR) )
    {
        mfn_vOnDrawItemListBoxAnimation( lpDIS ) ;
    }
    else
		CFormView::OnDrawItem(nIDCtl, lpDIS);
}

// ----------------------------------------------------------------------------
// Description : handle function for msg CBN_SELCHANGE on CB Family
// ----------------------------------------------------------------------------
void CDlgAnimList::OnBtMore()
{
    if ( m_bAllFamilies )
    {
        int iIndex = M_CBFamily() -> GetCurSel();
        if( ( iIndex != CB_ERR ) && ( (CPA_Family*)M_CBFamily() -> GetItemData( iIndex ) != M_GetCurrentFamily() ) )
            return;
    }

    m_bAllFamilies = ! m_bAllFamilies;

    if( m_bAllFamilies )
    {
        // show Cb Family
        CRect oRectDlg, oRectList, oRectSTAnim, oRectCB;

        // get pos
        M_GetClientRect( this, &oRectDlg );
        M_GetClientRectId( IDC_ST_ANIM, &oRectSTAnim );
        M_GetClientRectId( IDC_LB_ANIM, &oRectList );
        M_GetClientRectId( IDC_COMBO_FAMILY, &oRectCB );

        M_HideControl( IDC_ST_ANIM );
        M_ShowControl( IDC_ST_FAMILY );
        M_ShowControl( IDC_COMBO_FAMILY );

        M_BTMore() -> SetWindowText( "-" );

        // top Align
        oRectList . top = oRectCB. bottom + C_iBorderSize;

        // set pos
        M_SetClientRectId( IDC_LB_ANIM, &oRectList );
        // select current family
        int iIndex = -1;
        if( M_GetCurrentFamily() )
        {
            iIndex = M_CBFamily() -> FindStringExact( -1, M_GetCurrentFamily() -> GetName() );
            if ( iIndex == CB_ERR )
                iIndex = -1;
        }
        M_CBFamily() -> SetCurSel( iIndex );
    }
    else
    {
        // hide Cb Family
        CRect oRectDlg, oRectList, oRectSTAnim, oRectCB;

        // get pos
        M_GetClientRect( this, &oRectDlg );
        M_GetClientRectId( IDC_ST_ANIM, &oRectSTAnim );
        M_GetClientRectId( IDC_LB_ANIM, &oRectList );
        M_GetClientRectId( IDC_COMBO_FAMILY, &oRectCB );

        M_ShowControl( IDC_ST_ANIM );
        M_HideControl( IDC_ST_FAMILY );
        M_HideControl( IDC_COMBO_FAMILY );
        M_BTMore() -> SetWindowText( "+" );

        // top Align
        oRectList . top = oRectCB. top;

        // set pos
        M_SetClientRectId( IDC_LB_ANIM, &oRectList );
    }
}

// ----------------------------------------------------------------------------
// Description : handle function for msg CBN_SELCHANGE on CB Family
// ----------------------------------------------------------------------------
void CDlgAnimList::OnSelchangeComboFamily()
{
    int iIndex = M_CBFamily() -> GetCurSel();

    if ( iIndex != CB_ERR )
    {
        mfn_vFillLBAnimations( (CPA_Family*) M_CBFamily() -> GetItemData( iIndex ) );
    }
}

// ----------------------------------------------------------------------------
// Description : handle function for msg WM_LBUTTONDOWN on ListBox
// ----------------------------------------------------------------------------
BOOL CDlgAnimList::OnLButtonDownLbAnim(MSG* pMsg)
{
    CListBox    *pLB        = M_LBAnim();
    BOOL         bCtrl      = ( ( GetKeyState( VK_CONTROL ) & 0xff00 ) != 0 );
    POINT        xPos;
    CRect        oRect;
    BOOL         bOutside;
    int          iIndex;

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

    iIndex = pLB -> ItemFromPoint ( xPos, bOutside ) ;
    pLB -> GetItemRect ( iIndex , &oRect ) ;
    if(oRect . PtInRect ( xPos ) )
    {
        // click on item
        BOOL bCtrl      = ( ( GetKeyState( VK_CONTROL ) & 0xff00 ) != 0 );
        BOOL bCurSel    = pLB -> GetSel( iIndex );

        if( bCurSel )
        {
            // item already selected, deselect it if CTRL
            if( bCtrl )
                pLB -> SetSel( iIndex, FALSE );
        }
        else
        {
            // item unselected, select it
            if( bCtrl )
                pLB -> SetSel( iIndex, TRUE );
            else
            {
                // unselect all
                pLB -> SelItemRange( FALSE, 0, pLB -> GetCount() );
                // select it
                pLB -> SetSel( iIndex, TRUE );
            }
        }
        OnSelchangeLbAnim();
        pLB -> Invalidate();
//  CPA_Ed_1 Mihaela Tancu begin
		SetCapture();
//  CPA_Ed_1 Mihaela Tancu end
        return TRUE;
    }
    return CFormView::PreTranslateMessage(pMsg);
}


//  CPA_Ed_1 Mihaela Tancu begin
// ----------------------------------------------------------------------------
// Description : handle function for msg WM_LBUTTONUP on ListBox
// Author: Mihaela Tancu
// ----------------------------------------------------------------------------
BOOL CDlgAnimList::OnLButtonUpLbAnim(MSG* pMsg)
{
	m_p_oParentDLL -> mfn_iSetIndexListBox( -1);
	m_p_oStatePrevious = NULL;
	m_p_oStateTarget   = NULL;

	if (GetCapture() != this)
		return FALSE; // If this window (view) didn't capture the mouse,
				// then the user isn't in this window.
	ReleaseCapture();   // Release the mouse capture established at
						// the beginning of the mouse drag.
	SetCursor(M_GetMainApp()->LoadStandardCursor(IDC_ARROW));


    CListBox    *pLB = (CListBox *)(CWnd::FromHandle(::GetDlgItem( m_p_oParentDLL->mfn_hGetDlgActionContentsHwnd(), IDC_LIST_STATES)));
    POINT xPos, sPos;

	GetCursorPos(&xPos);
	sPos = xPos;
	CRect oRect;
	pLB -> ScreenToClient(&xPos);
	pLB -> GetClientRect( oRect );
	m_p_oParentDLL -> mfn_iSetIndexListBox( -1);

	if( !oRect.PtInRect(xPos)) return 1;

	//test if the mouse cursor is on one item from the list box
    CPoint oPoint(xPos);
	BOOL bOutside;

	if (!M_GetCurrentAction()->m_oListOfStates.IsEmpty())
	{
		int iIndex = pLB->ItemFromPoint(oPoint, bOutside ) ;
		if (iIndex != LB_ERR)
			m_p_oParentDLL->mfn_vChangeState( ((CPA_State *) pLB->GetItemData(iIndex)) );
		else
			m_p_oParentDLL->mfn_vChangeState( NULL );

		if (iIndex > 0)
			m_p_oStatePrevious = (CPA_State *) pLB->GetItemData(iIndex-1);
		m_p_oStateTarget   = (CPA_State *) pLB->GetItemData(iIndex);

		CRect oRectItem;
		pLB->GetItemRect(iIndex,&oRectItem);

		//prepare the informations for creating the states from animations
		if(oRectItem.PtInRect(xPos))
			// if the mouse cursor is on one item from the list box
			// save the index of that item
		{	m_p_oParentDLL -> mfn_iSetIndexListBox( iIndex);
			if (iIndex > 0)
				m_p_oStatePrevious = (CPA_State *) pLB->GetItemData(iIndex-1);
			m_p_oStateTarget   = (CPA_State *) pLB->GetItemData(iIndex);
		}
		else
		{  // if the cursor is not on one item!!! (put the states on null)
			m_p_oStatePrevious = NULL;
			m_p_oStateTarget   = NULL;
		}
	}

	CMenu oPopMenu;
	// create popup on the mouse position
	oPopMenu . CreatePopupMenu () ;
	// fill menu
	oPopMenu . AppendMenu( MF_STRING , C_uiPMCreateNormalMove, "Normal States");
	if (!M_GetCurrentAction()->m_oListOfStates.IsEmpty())
		oPopMenu . AppendMenu( MF_STRING , C_uiPMCreateTransitionalMove, "Transitional States");
	// register for TUT module
    TUT_M_vGetTutDll    ();
    TUT_M_vRegisterMenu (this -> m_hWnd , oPopMenu . m_hMenu , sPos.x, sPos.y);
	oPopMenu . TrackPopupMenu ( TPM_LEFTALIGN|TPM_RIGHTBUTTON, sPos.x, sPos.y , this);
	oPopMenu . DestroyMenu ();

    return CFormView::PreTranslateMessage(pMsg);
}


// ----------------------------------------------------------------------------
// Description : handle function for msg WM_MOUSE on ListBox
// Author: Mihaela Tancu
// ----------------------------------------------------------------------------
void CDlgAnimList::OnMouseMove(UINT nFlags, CPoint pt)
{
	POINT point;
	GetCursorPos(&point);
    if (nFlags & MK_LBUTTON)
	{
	    CListBox    *pLB = (CListBox *)(CWnd::FromHandle(::GetDlgItem( m_p_oParentDLL->mfn_hGetDlgActionContentsHwnd(), IDC_LIST_STATES)));
		CRect oRect;
		pLB -> GetWindowRect( oRect );
		if(oRect.PtInRect(point))
			// change the mouse cursor if it is in the Action Contents list box rect
			SetCursor(M_GetMainApp()->LoadCursor(IDC_POINTER_CURSOR));
		else
			// change the mouse cursor if it is not in the Action Contents List box rect
			SetCursor(M_GetMainApp()->LoadStandardCursor(IDC_NO));
	}
}
//  CPA_Ed_1 Mihaela Tancu end
// ----------------------------------------------------------------------------
// Description : handle function for msg WM_RBUTTONDOWN on ListBox
// ----------------------------------------------------------------------------
BOOL CDlgAnimList::OnRButtonDownLbAnim(MSG* pMsg)
{
    CListBox    *pLB        = M_LBAnim();
    int         iNbSelected = pLB -> GetSelCount();
    BOOL        bCanCreate  = ( ( iNbSelected > 0 ) && ( M_GetCurrentAction() != NULL ) );
    POINT       xPos;
    CMenu       oPopupMenu ;

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

    // create popup menu
    oPopupMenu . CreatePopupMenu () ;
    // fill menu
    oPopupMenu . AppendMenu( MF_STRING + ( bCanCreate ? MF_ENABLED : MF_GRAYED) , C_uiPMCreateNormal , "Create Normal State(s)" ) ;
    oPopupMenu . AppendMenu( MF_STRING + ( bCanCreate ? MF_ENABLED : MF_GRAYED) , C_uiPMCreateTransitional , "Create Transitional State(s)" ) ;
    // display menu
    pLB->ClientToScreen(&xPos);
// ALX
    TUT_M_vGetTutDll    ();
    TUT_M_vRegisterMenu (this -> m_hWnd , oPopupMenu . m_hMenu , xPos . x , xPos . y);
// End ALX
    oPopupMenu . TrackPopupMenu ( TPM_LEFTALIGN|TPM_RIGHTBUTTON, xPos.x, xPos.y, this);
    oPopupMenu . DestroyMenu ();

    return CFormView::PreTranslateMessage(pMsg);
}

// ----------------------------------------------------------------------------
// Description : handle function for msg BN_CLICKED on BT Create
// ----------------------------------------------------------------------------
void CDlgAnimList::OnBtCreatestates()
{
	CMenu oPopMenu;
    CRect oRect;

	M_BTCreate() -> 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");
    TUT_M_vGetTutDll    ();
    TUT_M_vRegisterMenu (this -> m_hWnd , oPopMenu . m_hMenu , oRect . left, oRect . bottom);
    oPopMenu . TrackPopupMenu ( TPM_LEFTALIGN|TPM_RIGHTBUTTON, oRect . left, oRect . bottom , this);
    oPopMenu . DestroyMenu ();
}

// ----------------------------------------------------------------------------
// Description : handle function for msg LBN_SELCHANGE on ListBox
// ----------------------------------------------------------------------------
void CDlgAnimList::OnSelchangeLbAnim()
{
    CListBox *pLB = M_LBAnim();
    int iNbSelected = pLB -> GetSelCount();

    if ( iNbSelected < 2 )
    {
        // unselect all
        for ( int i=0 ; i<M_LBAnim()->GetCount() ; i++ )
            pLB -> SetItemData( i, 0 );

        if ( iNbSelected == 1 )
        {
            // select first
            int *a_iNewSelection = (int*) malloc( iNbSelected * sizeof( int ) );
            pLB -> GetSelItems( iNbSelected, a_iNewSelection );
            pLB -> SetItemData( *a_iNewSelection, 1 );
            free( a_iNewSelection );
        }
    }
    else
    {
        // one item has been select or unselect
        //
        for ( int i=0 ; i<M_LBAnim()->GetCount() ; i++ )
        {
            if( pLB -> GetSel( i ) && ( pLB -> GetItemData( i ) == 0 ) )
            {
                // new selection
                pLB -> SetItemData( i, iNbSelected );
                break;
            }
            else if ( !pLB -> GetSel( i ) && ( pLB -> GetItemData( i ) != 0 ) )
            {
                // unselect item
                DWORD dwLast = pLB -> GetItemData( i );
                // shift next items
                for ( int j=0 ; j<M_LBAnim()->GetCount() ; j++ )
                {
                    if( pLB -> GetItemData( j ) > dwLast )
                        pLB -> SetItemData( j, pLB -> GetItemData( j ) - 1 );
                }
                pLB -> SetItemData( i, 0 );
                break;
            }
        }
    }
    M_BTCreate() -> EnableWindow( (BOOL)iNbSelected && (BOOL)M_GetCurrentAction() );
}

// ----------------------------------------------------------------------------
//  Author      : MT
//  Creation    : 13/08/97
//
// Description :
// ----------------------------------------------------------------------------
void CDlgAnimList::mfn_vOnDrawItemListBoxAnimation(LPDRAWITEMSTRUCT lpDIS)
{
    CDC                 *pDC = CDC::FromHandle( lpDIS->hDC );
    char                szText[100];
    CListBox            *pLB = M_LBAnim();
    BOOL                bSelected = (lpDIS->itemState & ODS_SELECTED );
    int                 iIndex = (int)pLB -> GetItemData( lpDIS->itemID );

    pDC->FillSolidRect( &lpDIS->rcItem, GetSysColor( COLOR_WINDOW ));
    pDC->SetBkMode( TRANSPARENT);
    pDC->SetTextColor( GetSysColor( COLOR_WINDOWTEXT ) );

    // display animation name
    lpDIS->rcItem.left += 1;
    pLB->GetText( lpDIS->itemID, szText );
    pDC->DrawText( szText, strlen(szText), &lpDIS->rcItem, DT_SINGLELINE | DT_LEFT | DT_VCENTER );
    // display selected index
    if ( bSelected && iIndex )
    {
        itoa( iIndex, szText, 10 );
        lpDIS->rcItem.right -= 2;
        pDC->DrawText( szText, strlen(szText), &lpDIS->rcItem, DT_SINGLELINE | DT_RIGHT | DT_VCENTER );
        lpDIS->rcItem.right += 2;
        lpDIS->rcItem.left -= 1;
        pDC->InvertRect( &lpDIS->rcItem );
    }
}

// ----------------------------------------------------------------------------
// Description : Set Parent DLL
// ----------------------------------------------------------------------------
void CDlgAnimList::mfn_vSetParentDLL(TAction_Interface * _p_oDLL)
{
	m_p_oParentDLL = _p_oDLL;
}

// ----------------------------------------------------------------------------
// Description : Set Current Family
// ----------------------------------------------------------------------------
void CDlgAnimList::mfn_vSetFamily(CPA_Family * _p_oFamily)
{
	// GetCurrent FamilySelected
	int iCurrent = M_CBFamily() -> GetCurSel();
    // select current family
    int iIndex = -1;
    if( _p_oFamily )
    {
        iIndex = M_CBFamily() -> FindStringExact( -1, _p_oFamily -> GetName() );
        if ( iIndex == CB_ERR )
            iIndex = -1;
    }
	if( iIndex != iCurrent )
	{
	    M_CBFamily() -> SetCurSel( iIndex );
		OnSelchangeComboFamily();
	}
	else
		M_LBAnim() -> SetSel( -1, FALSE );
}

// ----------------------------------------------------------------------------
// Description : Fill ListBox Animation
// ----------------------------------------------------------------------------
void CDlgAnimList::mfn_vFillLBAnimations(CPA_Family * _p_oFamily)
{
    CListBox *pLB = M_LBAnim();

    pLB -> ResetContent();
    M_BTCreate() -> EnableWindow( FALSE );
    if( _p_oFamily )
    {
        CPA_List<CPA_BaseObject> oList;

        _p_oFamily -> GetMainWorld() -> fn_lFindObjects( &oList, "", C_szAnimationTypeName, (CPA_BaseObject*)_p_oFamily );
        POSITION xPos = oList . GetHeadPosition();
        while( xPos )
        {
            CPA_BaseObject *p_oAnim = oList . GetNext( xPos );
            int iIndex = pLB -> AddString( p_oAnim -> GetName() );
            if( iIndex != LB_ERR )
                pLB -> SetItemData( iIndex, (DWORD) 0);
        }
    }
    pLB -> SetSel( -1, FALSE );
}

// ----------------------------------------------------------------------------
// Description : fill ComboBox Families
// ----------------------------------------------------------------------------
void CDlgAnimList::mfn_vFillCBFamilies(void)
{
    CComboBox *pCB = M_CBFamily();

    pCB -> ResetContent();
    M_BTCreate() -> EnableWindow( FALSE );

    CPA_BaseObjectList *p_oList = m_p_oParentDLL -> GetMainWorld() -> fn_p_oGetOriginalObjectList( C_szFamilyTypeName );
    if( p_oList )
    {
        Position xPos = p_oList -> GetHeadPosition();
        while( xPos )
        {
            CPA_BaseObject *p_oFamily = p_oList -> GetNext( xPos );
            if( p_oFamily -> fn_bIsAvailable() )
            {
                int iIndex = pCB -> AddString( p_oFamily -> GetName() );
                if( iIndex != CB_ERR )
                    pCB -> SetItemData( iIndex, (DWORD) p_oFamily );
            }
        }
    }
    pCB -> SetCurSel( -1 );
}

// ----------------------------------------------------------------------------
// Description : Create new states
// ----------------------------------------------------------------------------
void CDlgAnimList::mfn_vCreateStates(BOOL _bNormal)
{
    CListBox *pLB = M_LBAnim();
    DWORD dwNbSelected = pLB -> GetSelCount();
    CPA_BaseObjectList *p_oAnimList;
    ASSERT( (BOOL) dwNbSelected );

    p_oAnimList = m_p_oParentDLL -> GetMainWorld() -> fn_p_oGetOriginalObjectList( C_szAnimationTypeName );

    int *a_iSelectedIndexes = (int*) malloc( dwNbSelected * sizeof(int));

    pLB -> GetSelItems( dwNbSelected, a_iSelectedIndexes );

    State_CreateFromAnims *p_oCreate = new State_CreateFromAnims( m_p_oParentDLL, M_GetCurrentAction() );

    if( M_GetCurrentState() )
        p_oCreate -> mfn_vSetMecaCard( M_GetCurrentState() -> mfn_p_oGetMecaCard() );

    p_oCreate -> mfn_vSetNormalState( _bNormal );

    for( DWORD dwNum = 1; dwNum < dwNbSelected+1; dwNum++ )
    {
        // search selected item with order iNum
        int dwJ = 0;
        while( ( dwJ < dwNbSelected+1 ) && ( pLB -> GetItemData( a_iSelectedIndexes[dwJ] ) != dwNum ) )
            dwJ++;
        ASSERT( dwJ < dwNbSelected );

        CString csAnim;

        pLB -> GetText( a_iSelectedIndexes[dwJ], csAnim );

        CPA_Animation *p_oAnimation = (CPA_Animation*) p_oAnimList -> fn_p_oFindObject( csAnim, C_szAnimationTypeName, M_GetCurrentFamily() );
        ASSERT( p_oAnimation );

        p_oCreate -> mfn_vAddAnim( p_oAnimation );
    }
    M_MakeDo( p_oCreate );

    free( a_iSelectedIndexes );

    pLB -> SetSel( -1, FALSE );
    M_BTCreate() -> EnableWindow( FALSE );
}

// CPA_Ed_1 Mihaela Tancu begin
// ----------------------------------------------------------------------------
// Description : Create new states by dragging an animation at one position
// Author: Mihaela Tancu
// ----------------------------------------------------------------------------
void CDlgAnimList::mfn_vCreateStatesMove(BOOL _bNormal)
{
    CListBox *pLB = M_LBAnim();
    DWORD dwNbSelected = pLB -> GetSelCount();
    CPA_BaseObjectList *p_oAnimList;
    ASSERT( (BOOL) dwNbSelected );

	// used  for invalidate the display of the list box
	M_LBAnim()->SetRedraw(FALSE);

    p_oAnimList = m_p_oParentDLL -> GetMainWorld() -> fn_p_oGetOriginalObjectList( C_szAnimationTypeName );

    int *a_iSelectedIndexes = (int*) malloc( dwNbSelected * sizeof(int));

    pLB -> GetSelItems( dwNbSelected, a_iSelectedIndexes );

    State_CreateFromAnimsMove *p_oCreate = new State_CreateFromAnimsMove( m_p_oParentDLL, M_GetCurrentAction(),
																		  m_p_oStatePrevious, m_p_oStateTarget,NULL);

    if( M_GetCurrentState() )
        p_oCreate -> mfn_vSetMecaCard( M_GetCurrentState() -> mfn_p_oGetMecaCard() );

    p_oCreate -> mfn_vSetNormalState( _bNormal );

    for( DWORD dwNum = 1; dwNum < dwNbSelected+1; dwNum++ )
    {
        // search selected item with order iNum
        int dwJ = 0;
        while( ( dwJ < dwNbSelected+1 ) && ( pLB -> GetItemData( a_iSelectedIndexes[dwJ] ) != dwNum ) )
            dwJ++;
        ASSERT( dwJ < dwNbSelected );

        CString csAnim;

        pLB -> GetText( a_iSelectedIndexes[dwJ], csAnim );

        CPA_Animation *p_oAnimation = (CPA_Animation*) p_oAnimList -> fn_p_oFindObject( csAnim, C_szAnimationTypeName, M_GetCurrentFamily() );
        ASSERT( p_oAnimation );

        p_oCreate -> mfn_vAddAnim( p_oAnimation );
    }
    M_MakeDo( p_oCreate );

    free( a_iSelectedIndexes );

	M_LBAnim()->SetRedraw(TRUE);

    pLB -> SetSel( -1, FALSE );
    M_BTCreate() -> EnableWindow( FALSE );
}

// CPA_Ed_1 Mihaela Tancu end
