// DlgZALst.cpp : implementation file
//

//#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 "DlgInput.hpp"
#include "DlgZALst.hpp"
#include "DlgZA.hpp"
#include "ZAModif.hpp"
#include "FAModif.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_BT( nID )             ( (CButton*) GetDlgItem( nID ) )
#define M_BTExtAction()         M_BT( IDC_BT_EXTENDACTION )
#define M_BTExtFamily()         M_BT( IDC_BT_EXTENDFAMILY )
//#define M_BTAction()			M_BT( IDC_BT_ACT )

#define M_LBStates()              ( (CListBox*) GetDlgItem( IDC_LB_STATES ) )

#define M_Enable( 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_MakeDo( p_oModif )               m_p_oDLL -> M_GetEditManager() -> AskFor ( p_oModif )

// Popup Menu ID
#define C_uiPMDefault       2000
#define C_uiPMExtendAction  (C_uiPMDefault + 1)
#define C_uiPMExtendFamily  (C_uiPMDefault + 2)
#define C_uiPMZA            (C_uiPMDefault + 10)    // must be the greater

#define C_iBorderSize       4

/////////////////////////////////////////////////////////////////////////////
// CDlgZAList dialog

IMPLEMENT_DYNCREATE(CDlgZAList, CFormView)

// ----------------------------------------------------------------------------
// Description : constructor
// ----------------------------------------------------------------------------
CDlgZAList::CDlgZAList()
	: CFormView(CDlgZAList::IDD)
{
	//{{AFX_DATA_INIT(CDlgZAList)
		// NOTE: the ClassWizard will add member initialization here
	//}}AFX_DATA_INIT
    m_p_oDLL                = NULL;
    m_p_oCurrentZAList      = NULL;
    m_p_oCurrentZA          = NULL;
	m_bFirstShow			= TRUE;
    m_p_oDlgZA              = NULL;
    m_p_oCurrentAction      = NULL;
    m_oListOfSelectedStates . RemoveAll();
    //
    m_oListOfZA . RemoveAll();
}


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

BOOL CDlgZAList::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_STATES, "TAC_ZAM_ZALISTCONTENTS_LIST", TUT_e_ListBox );
    TUT_M_vRegisterControlID( IDC_BT_EXTENDACTION, "TAC_ZAM_ZALISTCONTENTS_BTEXTENDACTION", TUT_e_Button );
    TUT_M_vRegisterControlID( IDC_BT_EXTENDFAMILY, "TAC_ZAM_ZALISTCONTENTS_BTEXTENDFAMILY", TUT_e_Button );
    //
    return bResult;
}

BEGIN_MESSAGE_MAP(CDlgZAList, CFormView)
	//{{AFX_MSG_MAP(CDlgZAList)
    ON_WM_DESTROY()
	ON_BN_CLICKED(IDC_BT_EXTENDACTION, OnBtExtendaction)
	ON_BN_CLICKED(IDC_BT_EXTENDFAMILY, OnBtExtendfamily)
	ON_WM_SHOWWINDOW()
	ON_WM_SIZE()
	ON_WM_DRAWITEM()
	ON_LBN_SELCHANGE(IDC_LB_STATES, OnSelchangeLbStates)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CDlgZAList message handlers

void CDlgZAList::OnDestroy()
{
    // register controls
    TUT_M_vGetTutDll();
    TUT_M_vUnregisterControlID( IDC_LB_STATES );
    TUT_M_vUnregisterControlID( IDC_BT_EXTENDACTION );
    TUT_M_vUnregisterControlID( IDC_BT_EXTENDFAMILY );
    //
    CFormView::OnDestroy();
}

// -----------------------------------------------------------------------------
// Description : intercept the popup menu entry
// ---------------------------------------------------------------------------*/
BOOL CDlgZAList::OnCommand(WPARAM wParam, LPARAM lParam)
{
    int iIndexZA;
    POSITION xPos;

	switch(LOWORD(wParam))
    {
    case C_uiPMExtendAction:
        OnBtExtendaction();
        break;
    case C_uiPMExtendFamily:
        OnBtExtendfamily();
        break;
    default :
        iIndexZA = LOWORD(wParam) - C_uiPMZA;
        if( ( iIndexZA >= 0 ) && ( iIndexZA < m_oListOfZA . GetCount() ) )
        {
            xPos = m_oListOfZA . FindIndex( iIndexZA );
            if( xPos )
                mfn_vSetZA( (CPA_ZonesActivating*)m_oListOfZA . GetAt( xPos ), TRUE );
        }
        else
    	    return CFormView::OnCommand(wParam, lParam);
    }

    return TRUE;
}

// ----------------------------------------------------------------------------
// Description : handle function for msg WM_SHOWWINDOW
// ----------------------------------------------------------------------------
void CDlgZAList::OnShowWindow(BOOL bShow, UINT nStatus)
{
	CFormView::OnShowWindow(bShow, nStatus);
    /*
    if(bShow && m_bFirstShow)
    {
        mfn_vSetCurrentNamesList( NULL );
        mfn_vAddAction( NULL, TRUE );
    }
    m_bFirstShow = FALSE;
    */
}

// ----------------------------------------------------------------------------
// Description : handle function for msg WM_SIZE
// ----------------------------------------------------------------------------
void CDlgZAList::OnSize(UINT nType, int cx, int cy)
{
    if( M_LBStates() )
    {
        CRect oRectDlg, oRectLB, oRectBTExtendAction, oRectBTExtendFamily;
        CSize oSize;

        // get current pos
        M_GetClientRect( this, &oRectDlg );
        M_GetClientRectId( IDC_LB_STATES, &oRectLB );
        M_GetClientRectId( IDC_BT_EXTENDACTION, &oRectBTExtendAction );
        M_GetClientRectId( IDC_BT_EXTENDFAMILY, &oRectBTExtendFamily );

        // place BTs Extend
        oSize = oRectBTExtendAction . Size();
        oSize . cx = (oRectDlg . Width() - C_iBorderSize * 3) / 2;

        oRectBTExtendAction . bottom = oRectBTExtendFamily . bottom = oRectDlg . bottom - C_iBorderSize;
        oRectBTExtendAction . top = oRectBTExtendFamily . top = oRectBTExtendFamily . bottom - oSize . cy;

        oRectBTExtendAction . left = oRectDlg . left + C_iBorderSize;
        oRectBTExtendFamily . right = oRectDlg . right - C_iBorderSize;

        oRectBTExtendAction . right = oRectBTExtendAction . left + oSize . cx;
        oRectBTExtendFamily . left = oRectBTExtendFamily . right - oSize . cx;

        // place LB
        oRectLB . right = oRectBTExtendFamily . right;
        oRectLB . bottom = max( oRectLB . top, oRectBTExtendAction . top - (C_iBorderSize<<1) );

        // set current pos
        M_SetClientRectId( IDC_LB_STATES, &oRectLB );
        M_SetClientRectId( IDC_BT_EXTENDACTION, &oRectBTExtendAction );
        M_SetClientRectId( IDC_BT_EXTENDFAMILY, &oRectBTExtendFamily );
    }
}

// ----------------------------------------------------------------------------
// Description : Translate all messages
// ----------------------------------------------------------------------------
BOOL CDlgZAList::PreTranslateMessage(MSG* pMsg)
{
    if( ( pMsg->hwnd == GetDlgItem(IDC_LB_STATES)->m_hWnd ) &&
        ( pMsg -> message == WM_RBUTTONDOWN ) )
    {
        return OnRButtonDownLbStates( pMsg );
    }

	return CFormView::PreTranslateMessage(pMsg);
}

// ----------------------------------------------------------------------------
// Description : handle function for msg WM_DRAWITEM
// ----------------------------------------------------------------------------
void CDlgZAList::OnDrawItem(int nIDCtl, LPDRAWITEMSTRUCT lpDIS)
{
    if ( (nIDCtl == IDC_LB_STATES) &&
         (M_LBStates()->IsWindowEnabled() ) &&
         (lpDIS->itemID != LB_ERR) )
    {
        OnDrawListItem( lpDIS );
    }
    else
        CFormView::OnDrawItem(nIDCtl, lpDIS);
}

// ----------------------------------------------------------------------------
// Description : handle function for msg WM_RBUTTONDOWN on ListBox
// ----------------------------------------------------------------------------
BOOL CDlgZAList::OnRButtonDownLbStates(MSG* pMsg)
{
    UINT        nFlags      = MF_STRING + ( (m_p_oCurrentZAList != NULL) && !m_oListOfSelectedStates . IsEmpty() ? MF_ENABLED : MF_GRAYED );
    POINT       xPoint;
    CMenu       oPopupMenu ;
    POSITION    xPos;
    int         iIndex;

    // fill list of ZA
    m_oListOfZA . RemoveAll();
    if( m_p_oCurrentZAList != NULL )
    {
        m_p_oDLL -> fn_lFindObjects (&m_oListOfZA, "", C_szZATypeName, (CPA_BaseObject*)m_p_oCurrentZAList->GetOwner() );
    }
    // fill Menu
    xPoint.x = LOWORD(pMsg->lParam);
    xPoint.y = HIWORD(pMsg->lParam);

    // create popup menu
    oPopupMenu . CreatePopupMenu () ;
    // fill menu
    oPopupMenu . AppendMenu( MF_STRING + (M_BTExtAction() -> IsWindowEnabled() ? MF_ENABLED : MF_GRAYED ), C_uiPMExtendAction, "Extend To Action" );
    oPopupMenu . AppendMenu( MF_STRING + (M_BTExtFamily() -> IsWindowEnabled() ? MF_ENABLED : MF_GRAYED ), C_uiPMExtendFamily, "Extend To Family" );
    if( m_oListOfZA . GetCount() > 0 )
        oPopupMenu . AppendMenu( MF_SEPARATOR );
    xPos = m_oListOfZA . GetHeadPosition();
    iIndex = 0;
    while( xPos )
    {
        CPA_BaseObject *p_oZA = m_oListOfZA . GetNext( xPos );
        oPopupMenu . AppendMenu( nFlags , C_uiPMZA + iIndex , (char*)(LPCTSTR)p_oZA -> GetName() ) ;
        iIndex++;
    }
    // display menu
    M_LBStates() -> ClientToScreen(&xPoint);
// ALX
    TUT_M_vGetTutDll    ();
    TUT_M_vRegisterMenu (this -> m_hWnd , oPopupMenu . m_hMenu , xPoint . x , xPoint . y);
// End ALX
    oPopupMenu . TrackPopupMenu ( TPM_LEFTALIGN|TPM_RIGHTBUTTON, xPoint.x, xPoint.y, this);
    oPopupMenu . DestroyMenu ();

    return CFormView::PreTranslateMessage(pMsg);
}

// ----------------------------------------------------------------------------
// Description : handle function for msg BN_CLICKED on Bt 'Extend to Action'
// ----------------------------------------------------------------------------
void CDlgZAList::OnBtExtendaction()
{
    if ( (m_p_oCurrentZA != NULL) && (m_p_oCurrentAction != NULL) )
    {
        ZAList_ExtendToAction *p_oZAAction = new ZAList_ExtendToAction( m_p_oDLL, m_p_oCurrentAction, m_p_oCurrentZAList, m_p_oCurrentZA, &m_oListOfSelectedStates );
        M_MakeDo( p_oZAAction ) ;
    }
}

// ----------------------------------------------------------------------------
// Description : handle function for msg BN_CLICKED on Bt 'Extend to Family'
// ----------------------------------------------------------------------------
void CDlgZAList::OnBtExtendfamily()
{
    if ( m_p_oCurrentZA != NULL )
    {
        ZAList_ExtendToFamily *p_oZAFamily = new ZAList_ExtendToFamily( m_p_oDLL, m_p_oCurrentZAList, m_p_oCurrentZA, &m_oListOfSelectedStates );
        M_MakeDo( p_oZAFamily ) ;
    }
}

// ----------------------------------------------------------------------------
// Description : handle function for msg CBN_SELCHANGE on CB 'Names List'
// ----------------------------------------------------------------------------
void CDlgZAList::OnSelchangeLbStates()
{
    CListBox *pLB = M_LBStates();
    int iNbSel = pLB -> GetSelCount();

    // update list of selected states
    m_oListOfSelectedStates . RemoveAll();
    if( iNbSel > 0 )
    {
        int *a_iIdxSel = (int*) malloc( iNbSel * sizeof( int ) );
        pLB -> GetSelItems( iNbSel, a_iIdxSel );
        // first State, init Action and ZA
        CPA_State* p_oState = (CPA_State*) pLB -> GetItemData( a_iIdxSel[0] );
        m_oListOfSelectedStates . AddTail( p_oState );
        m_p_oCurrentAction = p_oState -> mfn_p_oGetAction();
        if( m_p_oCurrentZAList )
            m_p_oCurrentZA = m_p_oCurrentZAList -> mfn_p_oGetZAFromState( p_oState );
        // next states
        for( int i=1 ; i< iNbSel ; i++ )
        {
            CPA_State* p_oState = (CPA_State*) pLB -> GetItemData( a_iIdxSel[i] );
            m_oListOfSelectedStates . AddTail( p_oState );
            if( p_oState -> mfn_p_oGetAction() != m_p_oCurrentAction )
                m_p_oCurrentAction = NULL;
            if( m_p_oCurrentZAList && (m_p_oCurrentZA != m_p_oCurrentZAList -> mfn_p_oGetZAFromState( p_oState )) )
                m_p_oCurrentZA = NULL;
        }
    }
    // update display
    if( m_p_oDlgZA )
        m_p_oDlgZA -> mfn_vUpdateDisplay( m_p_oCurrentZA, 0 );

    mfn_vUpdateButtons();
}

/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
// CDlgZAList owner functions

// ----------------------------------------------------------------------------
// Description : fill LB of States
// ----------------------------------------------------------------------------
void CDlgZAList::mfn_vFillLBStates(CPA_Action *_p_oAction, BOOL _bReplace /*=FALSE*/)
{
    CListBox *pLB = M_LBStates();

    if(_bReplace)
        pLB -> ResetContent();

    if( _p_oAction )
    {
        POSITION stPos = _p_oAction -> m_oListOfStates . GetHeadPosition();
        while( stPos )
        {
            CPA_State *p_oState = _p_oAction -> m_oListOfStates . GetNext( stPos );
            int iIndex = pLB -> AddString( p_oState -> GetName() );
            if( iIndex != LB_ERR )
                pLB -> SetItemData( iIndex, (DWORD) p_oState );
        }
    }
    pLB -> SetCurSel( -1 );
    m_oListOfSelectedStates . RemoveAll();
    m_p_oCurrentAction = NULL;
    m_p_oCurrentZA = NULL;
    mfn_vUpdateButtons();
}

// ----------------------------------------------------------------------------
// Description : Set Current Names List
// ----------------------------------------------------------------------------
void CDlgZAList::mfn_vSetCurrentNamesList( CPA_tdoNameList *_p_oNameList)
{
    //m_p_oCurrentZAList = NULL;
    //m_p_oCurrentZA = NULL;
    mfn_vUpdateStates( &m_oListOfSelectedStates );
    //
    mfn_vUpdateButtons();
}


// ----------------------------------------------------------------------------
// Description : Set Current ZAList
// ----------------------------------------------------------------------------
void CDlgZAList::mfn_vSetCurrentZAList( CPA_ZonesActivatingList *_p_oZAList )
{
    m_p_oCurrentZAList = _p_oZAList;
    mfn_vUpdateStates( &m_oListOfSelectedStates );
    mfn_vUpdateButtons();
}

// ----------------------------------------------------------------------------
// Description :
// ----------------------------------------------------------------------------
void CDlgZAList::mfn_vSetZA(CPA_ZonesActivating * _p_oZA, BOOL _bApply /*=TRUE*/ )
{
    m_p_oCurrentZA = _p_oZA;
    if( _bApply && ( m_oListOfSelectedStates . GetCount() > 0 ) && m_p_oCurrentZAList && _p_oZA )
    {
        ZAList_SetZAToState *p_oZAState = new ZAList_SetZAToState( m_p_oDLL, m_p_oCurrentZAList, &m_oListOfSelectedStates);
        //
        POSITION xPos = m_oListOfSelectedStates . GetHeadPosition();
        // first State, init Action
        CPA_State *p_oState = m_oListOfSelectedStates . GetNext( xPos );
        p_oZAState -> mfn_vAddZAToState( _p_oZA, p_oState );
        m_p_oCurrentAction = p_oState -> mfn_p_oGetAction();
        while( xPos )
        {
            // next states
            p_oState = m_oListOfSelectedStates . GetNext( xPos );
            p_oZAState -> mfn_vAddZAToState( _p_oZA, p_oState );
            if( p_oState -> mfn_p_oGetAction() != m_p_oCurrentAction )
                m_p_oCurrentAction = NULL;
        }
        if( m_p_oDlgZA )
            m_p_oDlgZA -> mfn_vUpdateDisplay( _p_oZA, 0);

        M_MakeDo( p_oZAState ) ;
    }
    else
    {
        OnSelchangeLbStates();
        M_LBStates() -> Invalidate();
    }
}

// ----------------------------------------------------------------------------
// Description :
// ----------------------------------------------------------------------------
void CDlgZAList::mfn_vUpdateStates(CPA_List<CPA_State> *_p_oListOfStates)
{
    CListBox *pLB = M_LBStates();
    int iIdx = pLB -> GetCount();
    CPA_State *p_oState;

    // unselect all
    if( iIdx == 1 )
        pLB -> SetCurSel( -1 );
    else if( iIdx > 0 )
        pLB -> SelItemRange( FALSE, 0, iIdx - 1 );
    m_p_oCurrentZA = NULL;
    // select
    if( _p_oListOfStates -> GetCount() > 0 )
    {
        // update LB States
        POSITION xPos = _p_oListOfStates -> GetHeadPosition();
        // init current ZA
        if( xPos && m_p_oCurrentZAList )
            m_p_oCurrentZA = m_p_oCurrentZAList -> mfn_p_oGetZAFromState( _p_oListOfStates -> GetHead() );
        // select states and update current ZA
        while( xPos )
        {
            p_oState = _p_oListOfStates -> GetNext( xPos );
            mfn_iSelectStringExact( pLB, p_oState -> GetName () );
            // get ZA from state
            if( m_p_oCurrentZAList && ( m_p_oCurrentZA != m_p_oCurrentZAList -> mfn_p_oGetZAFromState( p_oState ) ) )
                m_p_oCurrentZA = NULL;
        }
        // update DlgZA
        if( m_p_oDlgZA && m_p_oCurrentZAList )
            m_p_oDlgZA -> mfn_vUpdateDisplay( m_p_oCurrentZA, 0 );
        //
    }
    mfn_vUpdateButtons();
    M_LBStates() -> Invalidate();
}

// ----------------------------------------------------------------------------
// Description : handle function for message WM_DRAWITEM on List box
// ----------------------------------------------------------------------------
void CDlgZAList::OnDrawListItem( LPDRAWITEMSTRUCT lpDIS )
{
    CDC                 *pDC = CDC::FromHandle( lpDIS->hDC );
    char                szText[100];
    CListBox            *pLB = M_LBStates();
    BOOL                bSelected = (lpDIS->itemState & ODS_SELECTED );
    CPA_State           *p_oState = (CPA_State*) pLB->GetItemData( lpDIS->itemID );

    pDC->FillSolidRect( &lpDIS->rcItem, GetSysColor( COLOR_WINDOW ));

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

    // write state
    pLB -> GetText(lpDIS->itemID, szText ) ;
    lpDIS->rcItem.left += 1;
    pDC->DrawText( szText, strlen(szText), &lpDIS->rcItem, DT_SINGLELINE | DT_LEFT | DT_VCENTER );
    // write ZA
    if( m_p_oCurrentZAList )
    {
        CPA_ZonesActivating *p_oZA = m_p_oCurrentZAList -> mfn_p_oGetZAFromState( p_oState );
        if( p_oZA )
        {
            lpDIS->rcItem.right -= 2;
            pDC->DrawText( p_oZA -> GetName(), &lpDIS->rcItem, DT_SINGLELINE | DT_RIGHT | DT_VCENTER );
            lpDIS->rcItem.right += 2;
        }
    }

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

// ----------------------------------------------------------------------------
// Description :
// ----------------------------------------------------------------------------
void CDlgZAList::mfn_vAddAction( CPA_Action *_p_oAction, BOOL _bReplace /*=FALSE*/ )
{
    mfn_vFillLBStates( _p_oAction, _bReplace );
    M_LBStates() -> Invalidate();
}

// ----------------------------------------------------------------------------
// Description :
// ----------------------------------------------------------------------------
int CDlgZAList::mfn_iSelectStringExact(CListBox *_pLB, CString _csEntry)
{
    int iIndex = _pLB -> FindStringExact( -1, _csEntry );
    if( iIndex != LB_ERR )
        _pLB -> SetSel( iIndex, TRUE );
    return iIndex;
}

// ----------------------------------------------------------------------------
// Description :
// ----------------------------------------------------------------------------
void CDlgZAList::mfn_vUpdateButtons()
{
    M_BTExtAction() -> EnableWindow( (m_p_oCurrentZAList != NULL) && (m_p_oCurrentAction != NULL) && (m_p_oCurrentZA != NULL) );
    M_BTExtFamily() -> EnableWindow( (m_p_oCurrentZAList != NULL) && (m_p_oCurrentZA != NULL) );
}
