// DlgVwCt.h : implementation file
//

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

// ALX
#include "ACP_Base.h"
#define HieFriend
#include "incGam.h"
#include "Itf.h"
/*
#include "ACP_Base.h"
#include "CPALib.h"
*/
// End ALX
#include "DlgVwCt.h"

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

/////////////////////////////////////////////////////////////////////////////
// MACROS
/////////////////////////////////////////////////////////////////////////////
#define M_LBContent()     ((CListBox*) GetDlgItem(IDC_LIST_CONTENT) )
#define M_LBChoice()      ((CListBox*) GetDlgItem(IDC_LIST_CHOICE) )
#define M_CBType()        ((CComboBox*) GetDlgItem(IDC_COMBO_TYPE) )
#define M_CTChoice()      ((CTreeCtrl*) GetDlgItem(IDC_TREE_HIERARCHY) )

#define M_ClientRect( pWnd, poRect )    \
    (pWnd) -> GetWindowRect( poRect );  \
    ScreenToClient( poRect );

/////////////////////////////////////////////////////////////////////////////
// MACROS
/////////////////////////////////////////////////////////////////////////////
#define C_iBorderSize     10

/////////////////////////////////////////////////////////////////////////////
// CDlgViewerContent dialog


CDlgViewerContent::CDlgViewerContent(CPA_MainWorld *_p_oMainWorld, CPA_List<tdst_VW_ObjInfo> *_p_oListOfInitialObjects,CWnd* pParent /*=NULL*/)
	: CDialog(CDlgViewerContent::IDD, pParent)
{
	//{{AFX_DATA_INIT(CDlgViewerContent)
		// NOTE: the ClassWizard will add member initialization here
	//}}AFX_DATA_INIT
    m_p_oMainWorld = _p_oMainWorld;
    m_p_oListOfInitialObjects = _p_oListOfInitialObjects;
    m_ocstTreeName = "";
    m_bTreeUsed = FALSE;
    //
    m_oBmpEdNoObject.LoadBitmap( IDB_EDIT_NOOBJECT );
    m_oBmpEdSupObj.LoadBitmap( IDB_EDIT_SUPOBJ );
    m_oBmpNoEdNoObject.LoadBitmap( IDB_NOEDIT_NOOBJECT );
    m_oBmpNoEdSupObj.LoadBitmap( IDB_NOEDIT_SUPOBJ );
    m_oBmpPEdNoObject.LoadBitmap( IDB_PEDIT_NOOBJECT );
    m_oBmpPEdSupObj.LoadBitmap( IDB_PEDIT_SUPOBJ );
    m_oBmpPNoEdNoObject.LoadBitmap( IDB_PNOEDIT_NOOBJECT );
    m_oBmpPNoEdSupObj.LoadBitmap( IDB_PNOEDIT_SUPOBJ );
}

CDlgViewerContent::~CDlgViewerContent()
{
    m_oBmpEdNoObject.DeleteObject();
    m_oBmpEdSupObj.DeleteObject();
    m_oBmpNoEdNoObject.DeleteObject();
    m_oBmpNoEdSupObj.DeleteObject();
    m_oBmpPEdNoObject.DeleteObject();
    m_oBmpPEdSupObj.DeleteObject();
    m_oBmpPNoEdNoObject.DeleteObject();
    m_oBmpPNoEdSupObj.DeleteObject();
}

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


BEGIN_MESSAGE_MAP(CDlgViewerContent, CDialog)
	//{{AFX_MSG_MAP(CDlgViewerContent)
    ON_WM_SIZE()
    ON_WM_GETMINMAXINFO()
	ON_BN_CLICKED(ID_BT_DELETE, OnBtdelete)
    ON_BN_CLICKED(ID_BT_ADD, OnBtadd)
    ON_CBN_SELCHANGE(IDC_COMBO_TYPE, OnSelchangeComboType)
    ON_LBN_DBLCLK(IDC_LIST_CHOICE, OnDblClkListObjects)
	ON_LBN_DBLCLK(IDC_LIST_CONTENT, OnDblclkListContent)
	ON_BN_CLICKED(ID_BT_OPEN, OnBtOpen)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CDlgViewerContent message handlers

//--------------------------------------------------------------------------------
// Description :
//--------------------------------------------------------------------------------
BOOL CDlgViewerContent::OnInitDialog()
{
	CDialog::OnInitDialog();

    CListBox *pLB = M_LBContent();

    pLB -> ResetContent();
    // fill Content ListBox
    POSITION stPos = m_p_oListOfInitialObjects -> GetHeadPosition();
    while ( stPos )
    {
        tdst_VW_ObjInfo *p_stVWOI   = m_p_oListOfInitialObjects -> GetNext ( stPos );
        CPA_SuperObject *p_oSprObj  = p_stVWOI -> m_p_oSuperObject;
        CPA_BaseObject  *p_oObject  = p_oSprObj -> GetObject();

        int iIndex = pLB -> AddString ( p_oObject -> GetName() ) ;  // Object Name
        if( iIndex != LB_ERR )
            pLB -> SetItemData ( iIndex, (DWORD) p_oSprObj ) ;  // Super_Object pointer
    }
    GetDlgItem( ID_BT_OPEN ) -> EnableWindow( pLB -> GetCount() );

    // fill Type ComboBox & Choice ListBox
    M_CBType() -> ResetContent();
    // add Actor Type
    mfn_vAddListOfType( "Actor", "Actors" );
    // add Geometric type
    mfn_vAddListOfType( "Geometric", "Geometric Objects" );
    // add Hierarchy Tree
    mfn_vAddHierarchyTree( "Hierarchy" );

    // select hierarchy
    if( M_CBType() -> SelectString( -1, "Hierarchy" ) != LB_ERR )
        mfn_vShowHierarchyTree();
    else
        M_CBType() -> SetCurSel( -1 );

    return TRUE;  // return TRUE unless you set the focus to a control
	              // EXCEPTION: OCX Property Pages should return FALSE
}

// ----------------------------------------------------------------------------
// Description :
// ----------------------------------------------------------------------------
BOOL CDlgViewerContent::PreTranslateMessage(MSG* pMsg)
{
    if( pMsg->message == WM_KEYDOWN )
    {
        CListBox *pLBChoice  = M_LBChoice();
        CListBox *pLBContent = M_LBContent();
        CTreeCtrl *pTree = M_CTChoice();
        HTREEITEM hCurItem = pTree -> GetSelectedItem();

        if( ( ( (int)pMsg -> wParam) == VK_INSERT ) && 
            ( ( ( pLBChoice -> GetSelCount() > 0 ) && ( pMsg->hwnd == pLBChoice -> m_hWnd ) ) ||
              ( ( pTree -> GetSelectedItem() ) && ( pMsg->hwnd == pTree -> m_hWnd ) )
            )
          )
        {
            OnBtadd();
        }
        else if ( ( ((int)pMsg -> wParam) == VK_DELETE ) && ( pLBContent -> GetSelCount() > 0 ) && ( pMsg->hwnd == pLBContent -> m_hWnd ) )
        {
            OnBtdelete();
        }
    }
    return CDialog::PreTranslateMessage(pMsg);
}

// ----------------------------------------------------------------------------
// Description : handle function for msg WM_SIZE
// ----------------------------------------------------------------------------
void CDlgViewerContent::OnSize(UINT nType, int cx, int cy)
{
    CDialog::OnSize(nType, cx, cy);

    if(GetDlgItem(IDC_LIST_CHOICE))
    {
        CRect oRectDlg, oRectLBContent, oRectLBChoice, oRectCT, oRectCB;
        CRect oRectBTAdd, oRectBTOK, oRectBTDel, oRectBTCancel, oRectBTOpen;
        CSize oSize;

        // get size and position
        GetClientRect( &oRectDlg );

        M_ClientRect( M_LBChoice(), &oRectLBChoice );
        M_ClientRect( M_CTChoice(), &oRectCT );
        M_ClientRect( M_LBContent(), &oRectLBContent );
        M_ClientRect( M_CBType(), &oRectCB );
        M_ClientRect( GetDlgItem( ID_BT_ADD ), &oRectBTAdd );
        M_ClientRect( GetDlgItem( ID_BT_DELETE ), &oRectBTDel );
        M_ClientRect( GetDlgItem( IDOK ), &oRectBTOK );
        M_ClientRect( GetDlgItem( IDCANCEL ), &oRectBTCancel );
        M_ClientRect( GetDlgItem( ID_BT_OPEN ), &oRectBTOpen );

        // resize
        // place BT 'Cancel' 'Delete' & 'OK'
        oSize = oRectBTCancel . Size();
        oRectBTCancel . bottom = oRectDlg . bottom - C_iBorderSize;
        oRectBTCancel . top = oRectBTCancel . bottom - oSize . cy;
        oRectBTOK . bottom = oRectBTOpen . bottom = oRectBTCancel . bottom;
        oRectBTOK . top = oRectBTOpen . top = oRectBTCancel . top;
        oSize = oRectBTCancel . Size();
        oRectBTCancel . right = oRectDlg . right - C_iBorderSize;
        oRectBTCancel . left = oRectBTCancel . right - oSize.cx;
        oSize = oRectBTOpen . Size();
        oRectBTOpen . left = ( oRectBTCancel . left + oRectBTOK . left ) >> 1;
        oRectBTOpen . right = oRectBTOpen . left + oSize.cx;
        // translate LBContent
        oSize = oRectLBContent . Size();
        oRectLBContent . right = oRectDlg . right - C_iBorderSize;
        oRectLBContent . left = oRectLBContent . right - oSize.cx;
        oRectLBContent . bottom = oRectDlg . bottom - oRectBTOK . Height() - (C_iBorderSize << 1);
        // place BTAdd
        oSize = oRectBTAdd . Size();
        int iHeight = oRectLBContent . Height();
        oRectBTDel . right = oRectBTAdd . right = oRectLBContent . left - C_iBorderSize;
        oRectBTDel . left = oRectBTAdd . left = oRectBTAdd . right - oSize.cx;
        oRectBTAdd . top = oRectLBContent . top + (iHeight>>1) - oSize.cy - C_iBorderSize;
        oRectBTAdd . bottom = oRectBTAdd . top + oSize.cy;
        oRectBTDel . top = oRectBTAdd . bottom + (C_iBorderSize>>1);
        oRectBTDel . bottom = oRectBTDel . top + oSize.cy;
        // resize LBChoice & CTree
        oRectLBChoice . right = oRectBTAdd . left - C_iBorderSize;
        oRectLBChoice . bottom = oRectLBContent . bottom;
        oRectCT . right = oRectLBChoice . right;
        oRectCT . bottom = oRectLBChoice . bottom;
        // resize CB
        oRectCB . right = oRectCT . right;

        // move windows
        M_LBChoice() -> MoveWindow ( &oRectLBChoice ) ;
        M_CTChoice() -> MoveWindow ( &oRectCT ) ;
        M_LBContent() -> MoveWindow ( &oRectLBContent ) ;
        M_CBType() -> MoveWindow ( &oRectCB ) ;
        GetDlgItem( ID_BT_ADD ) -> MoveWindow ( &oRectBTAdd ) ;
        GetDlgItem( ID_BT_DELETE ) -> MoveWindow ( &oRectBTDel ) ;
        GetDlgItem( IDOK ) -> MoveWindow ( &oRectBTOK ) ;
        GetDlgItem( IDCANCEL ) -> MoveWindow ( &oRectBTCancel ) ;
        GetDlgItem( ID_BT_OPEN ) -> MoveWindow ( &oRectBTOpen ) ;
    }
}

// ----------------------------------------------------------------------------
// Description : handle function for msg WM_GETMINMAXINFO
// ----------------------------------------------------------------------------
void CDlgViewerContent::OnGetMinMaxInfo( MINMAXINFO FAR* lpMMI )
{
    // limit min size
    lpMMI -> ptMinTrackSize . x = 412;
    lpMMI -> ptMinTrackSize . y = 257;

    CDialog::OnGetMinMaxInfo( lpMMI );
}

//--------------------------------------------------------------------------------
// Description : handle function for msg BN_CLICKED on button OK
//--------------------------------------------------------------------------------
void CDlgViewerContent::OnOK()
{
    mfn_vUpdateList();
	CDialog::OnOK();
}

//--------------------------------------------------------------------------------
// Description : handle function for msg BN_CLICKED on button OPEN
//--------------------------------------------------------------------------------
void CDlgViewerContent::OnBtOpen() 
{
    mfn_vUpdateList();
    CDialog::EndDialog(C_OPENVIEWER);
}

//--------------------------------------------------------------------------------
// Description : handle function for msg BN_CLICKER on button Delete
//--------------------------------------------------------------------------------
void CDlgViewerContent::OnBtdelete()
{
    // multiple selection list
    CListBox *pLB = M_LBContent();
    int iNbSel = pLB -> GetSelCount();

    if ( iNbSel > 0 )
    {
        int *pa_iIndexes = (int*)malloc( iNbSel * sizeof(int));

        pLB -> GetSelItems( iNbSel, pa_iIndexes );

        for ( int iIdx=iNbSel-1 ; iIdx>=0 ; iIdx-- )
        {
            pLB -> DeleteString ( pa_iIndexes[iIdx] ) ;
        }
        free(pa_iIndexes);
    }
    GetDlgItem( ID_BT_OPEN ) -> EnableWindow( pLB -> GetCount() );
}

//--------------------------------------------------------------------------------
// Description : handle function for msg BN_CLICKER on button Add
//--------------------------------------------------------------------------------
void CDlgViewerContent::OnBtadd()
{
    CComboBox *pCB = M_CBType();
    int iIndex = pCB -> GetCurSel();

    if( iIndex != CB_ERR )
    {
        CString ocstChoiceName;

        pCB -> GetLBText( iIndex , ocstChoiceName );
        if ( ocstChoiceName == m_ocstTreeName )
            mfn_vAddSelectionFromTree();
        else
            mfn_vAddSelectionFromList();
    }
}

//--------------------------------------------------------------------------------
// Description : handle function for msg CBN_SELCHANGE on combo type
//--------------------------------------------------------------------------------
void CDlgViewerContent::OnSelchangeComboType()
{
    CComboBox *pCB = M_CBType();
    int iIndex = pCB -> GetCurSel();

    if( iIndex != CB_ERR )
    {
        CString ocstChoiceName;

        pCB -> GetLBText( iIndex , ocstChoiceName );
        if ( ocstChoiceName == m_ocstTreeName )
            mfn_vShowHierarchyTree();
        else
            mfn_vFillChoiceList( (CPA_List<CPA_SuperObject>*) pCB -> GetItemData( iIndex ) );
    }
}

//--------------------------------------------------------------------------------
// Description : handle function for msg LBN_DBLCLK on choice list
//--------------------------------------------------------------------------------
void CDlgViewerContent::OnDblclkListContent()
{
    CListBox *pLBContent = M_LBContent();
    int iIndex = pLBContent -> GetCurSel();

    if( iIndex != LB_ERR )
    {
        pLBContent -> DeleteString( iIndex );
    }
    GetDlgItem( ID_BT_OPEN ) -> EnableWindow( pLBContent -> GetCount() );
}

//--------------------------------------------------------------------------------
// Description : handle function for msg LBN_DBLCLK on choice list
//--------------------------------------------------------------------------------
void CDlgViewerContent::OnDblClkListObjects()
{
    CListBox *pLBChoice  = M_LBChoice();
    CListBox *pLBContent = M_LBContent();
    int iIndex = pLBChoice -> GetCurSel();

    if( iIndex != LB_ERR && (pLBContent -> GetCount() < (MAX_DEVICE-1)) )
    {
        CPA_SuperObject *p_oSprObj = (CPA_SuperObject*)pLBChoice -> GetItemData( iIndex );
        CPA_BaseObject  *p_oObject = p_oSprObj -> GetObject();

        int iIdx = pLBContent -> AddString( p_oObject -> GetName() );   // object name
        if( iIdx != LB_ERR )
            pLBContent -> SetItemData ( iIdx , (DWORD) p_oSprObj );     // super object pointer
    }
    GetDlgItem( ID_BT_OPEN ) -> EnableWindow( pLBContent -> GetCount() );
}

//--------------------------------------------------------------------------------
// Description : fill Choice list with selected list on Type Combo
//--------------------------------------------------------------------------------
void CDlgViewerContent::mfn_vFillChoiceList(CPA_List<CPA_SuperObject> *_p_oList)
{
    CListBox  *pLB = M_LBChoice();
    CTreeCtrl *pTree = M_CTChoice();

    pTree -> EnableWindow( FALSE );
    pTree -> ShowWindow( SW_HIDE );

    pLB -> EnableWindow( TRUE );
    pLB -> ShowWindow( SW_SHOW );
    pLB -> ResetContent();

    if( _p_oList )
    {
        // fill list
        POSITION stPos = _p_oList -> GetHeadPosition();

        while ( stPos )
        {
            CPA_SuperObject *p_oSprObj  = _p_oList -> GetNext( stPos );
            CPA_BaseObject  *p_oObj     = p_oSprObj -> GetObject() ;

            int iIdx = pLB -> AddString ( p_oObj -> GetName() );    // object name
            if( iIdx != LB_ERR )
                pLB -> SetItemData ( iIdx, (DWORD)p_oSprObj );      // super object pointer
        }
    }
}

//--------------------------------------------------------------------------------
// Description : show heirarchy tree
//--------------------------------------------------------------------------------
void CDlgViewerContent::mfn_vShowHierarchyTree()
{
    CListBox  *pLB = M_LBChoice();
    CTreeCtrl *pTree = M_CTChoice();

    pLB -> EnableWindow( FALSE );
    pLB -> ShowWindow( SW_HIDE );

    pTree -> EnableWindow( TRUE );
    pTree -> ShowWindow( SW_SHOW );
}

//--------------------------------------------------------------------------------
// Description : add a list on Type Combo
//--------------------------------------------------------------------------------
void CDlgViewerContent::mfn_vAddListOfType(CString _csTypeName, CString _csListName)
{
    CComboBox *pCB  = M_CBType();
    CPA_List<CPA_SuperObject> *p_oList = m_p_oMainWorld -> GetInterface() -> GetObjectListByType (_csTypeName);

    if( p_oList )
    {
        int iIndex = pCB -> AddString ( _csListName ) ;
        if ( iIndex != CB_ERR )
            pCB -> SetItemData( iIndex , (DWORD) p_oList ) ;
    }
}

//--------------------------------------------------------------------------------
// Description : add hierarchy on Tree
//--------------------------------------------------------------------------------
void CDlgViewerContent::mfn_vAddHierarchyTree(CString _csListName)
{
    CComboBox *pCB  = M_CBType();

    // only one tree
    if( m_bTreeUsed )
        return ;

    m_ocstTreeName = _csListName ;
    m_bTreeUsed = TRUE;
    pCB -> AddString ( _csListName ) ;

	// init icons for hierarchy tree
	m_stImageList.Create(16, 16, FALSE, 0, 9);
    /*
	m_stImageList.Add(M_GetMainApp()->LoadIcon(EDT_IDI_EDIT_NOOBJECT));
	m_stImageList.Add(M_GetMainApp()->LoadIcon(EDT_IDI_EDIT_SUPOBJ));
	m_stImageList.Add(M_GetMainApp()->LoadIcon(EDT_IDI_NOEDIT_NOOBJECT));
	m_stImageList.Add(M_GetMainApp()->LoadIcon(EDT_IDI_NOEDIT_SUPOBJ));
	m_stImageList.Add(M_GetMainApp()->LoadIcon(EDT_IDI_PEDIT_NOOBJECT));
	m_stImageList.Add(M_GetMainApp()->LoadIcon(EDT_IDI_PEDIT_SUPOBJ));
	m_stImageList.Add(M_GetMainApp()->LoadIcon(EDT_IDI_PNOEDIT_NOOBJECT));
	m_stImageList.Add(M_GetMainApp()->LoadIcon(EDT_IDI_PNOEDIT_SUPOBJ));
    */
	m_stImageList.Add(&m_oBmpEdNoObject,(CBitmap*)NULL);
	m_stImageList.Add(&m_oBmpEdSupObj,(CBitmap*)NULL);
	m_stImageList.Add(&m_oBmpNoEdNoObject,(CBitmap*)NULL);
	m_stImageList.Add(&m_oBmpNoEdSupObj,(CBitmap*)NULL);
	m_stImageList.Add(&m_oBmpPEdNoObject,(CBitmap*)NULL);
	m_stImageList.Add(&m_oBmpPEdSupObj,(CBitmap*)NULL);
	m_stImageList.Add(&m_oBmpPNoEdNoObject,(CBitmap*)NULL);
	m_stImageList.Add(&m_oBmpPNoEdSupObj,(CBitmap*)NULL);

    M_CTChoice() -> SetImageList(&m_stImageList, TVSIL_NORMAL);

    // fill tree
    mfn_vFillHierarchyTree( m_p_oMainWorld -> GetWorld() -> GetRoot() , TVI_ROOT);
}

//--------------------------------------------------------------------------------
// Description : add a list on Type Combo
//--------------------------------------------------------------------------------
void CDlgViewerContent::mfn_vFillHierarchyTree (CPA_SuperObject *pEdParent, HTREEITEM hTreeParent)
{
    CTreeCtrl *pTree = M_CTChoice();
	CPA_SuperObject *pEdChild;
	HTREEITEM		hTreeChild;
	int				iNumImage;

	if (!pEdParent)
		return;

	for (pEdChild = pEdParent->GetSuperObjectFirstChild(); pEdChild;
		 pEdChild = pEdParent->GetSuperObjectNextChild(pEdChild))
	{
		// find good icon
		iNumImage = 0;
		if (pEdChild->GetSuperObjectOwner())
			iNumImage += 4;
		if (pEdChild->fn_bIsEditProtected())
			iNumImage += 2;
		if (pEdChild->GetObjectType() != HIE_C_ulSuperObject)
			iNumImage += 1;
		// create item
        if( pEdChild->GetObject() )
            hTreeChild = pTree -> InsertItem( pEdChild->GetObject()->GetName(), iNumImage, iNumImage, hTreeParent, TVI_LAST );  // object name
        else
            hTreeChild = pTree -> InsertItem( pEdChild->GetName(), iNumImage, iNumImage, hTreeParent, TVI_LAST );   // object name
        pTree -> SetItemData( hTreeChild, (DWORD) pEdChild );  // super object pointer
		// next level
        mfn_vFillHierarchyTree( pEdChild, hTreeChild );
	}
}

//--------------------------------------------------------------------------------
// Description : add selection from list
//--------------------------------------------------------------------------------
void CDlgViewerContent::mfn_vAddSelectionFromList()
{
    // multiple selection
    CListBox *pLBChoice  = M_LBChoice();
    CListBox *pLBContent = M_LBContent();
    int iNbSel = pLBChoice -> GetSelCount();

    if ( iNbSel != LB_ERR )
    {
        int *pa_iIndexes = (int*)malloc( iNbSel * sizeof(int));
        pLBChoice -> GetSelItems( iNbSel, pa_iIndexes );
        for ( int iIndex=0 ; (iIndex<iNbSel && (pLBContent -> GetCount() < (MAX_DEVICE-1)) ) ; iIndex++ )
        {
            CPA_SuperObject *p_oSprObj = (CPA_SuperObject*)pLBChoice -> GetItemData( pa_iIndexes[iIndex] );
            CPA_BaseObject  *p_oObject = p_oSprObj -> GetObject();

            int iIdxCnt = pLBContent -> FindStringExact( -1, p_oObject -> GetName() );
            if( iIdxCnt == LB_ERR )
            {
                // new object
                int iIdx = pLBContent -> AddString( p_oObject -> GetName() );       // object name
                if( iIdx != LB_ERR )
                    pLBContent -> SetItemData ( iIdx , (DWORD) p_oSprObj );         // super object pointer
            }
        }
        free(pa_iIndexes);
    }
    GetDlgItem( ID_BT_OPEN ) -> EnableWindow( pLBContent -> GetCount() );
}

//--------------------------------------------------------------------------------
// Description : add selection from tree
//--------------------------------------------------------------------------------
void CDlgViewerContent::mfn_vAddSelectionFromTree()
{
    CTreeCtrl *pTree = M_CTChoice();
    HTREEITEM hCurItem = pTree -> GetSelectedItem();

    if( hCurItem )
    {
        CPA_SuperObject *p_oSprObj = (CPA_SuperObject *) pTree -> GetItemData(hCurItem);
        CPA_BaseObject  *p_oObject = p_oSprObj -> GetObject();

        CListBox *pLBContent = M_LBContent();
        if(p_oObject && (pLBContent -> GetCount() < (MAX_DEVICE-1)) )
        {
            int iIdxCnt = pLBContent -> FindStringExact( -1, p_oObject -> GetName() );
            if( iIdxCnt == LB_ERR )
            {
                // new object
                int iIdx = pLBContent -> AddString( p_oObject -> GetName() );   // object name
                if( iIdx != LB_ERR )
                    pLBContent -> SetItemData ( iIdx , (DWORD) p_oSprObj );     // super object pointer
            }
        }
        GetDlgItem( ID_BT_OPEN ) -> EnableWindow( pLBContent -> GetCount() );
    }
}

//--------------------------------------------------------------------------------
// Description : update global list with selected objects
//--------------------------------------------------------------------------------
void CDlgViewerContent::mfn_vUpdateList()
{
    CListBox *pLB = M_LBContent();

    CList<DWORD,DWORD> m_oListOfWord;
    for( int iIndex = 0 ; iIndex < pLB -> GetCount() ; iIndex++ )
    {
        DWORD dwValue = pLB->GetItemData( iIndex );
        if ( dwValue != LB_ERR )
        {
            m_oListOfWord . AddTail ( dwValue );
        }
    }
    //
    POSITION stPos = m_p_oListOfInitialObjects -> GetHeadPosition();    
    while( stPos )
    {
        POSITION        stCurPos        = stPos;
        tdst_VW_ObjInfo *p_stObjInfo    = m_p_oListOfInitialObjects -> GetNext( stPos );

        DWORD dwValue = (DWORD) p_stObjInfo -> m_p_oSuperObject;
        
        POSITION stP = m_oListOfWord . Find( dwValue );
        
        if( stP )
            m_oListOfWord . RemoveAt( stP );
        else
        {
            free( p_stObjInfo );
            m_p_oListOfInitialObjects -> RemoveAt( stCurPos );
        }
    }
    //
    stPos = m_oListOfWord . GetHeadPosition();
    while( stPos )
    {
        tdst_VW_ObjInfo *p_stObjInfo = (tdst_VW_ObjInfo*) malloc( sizeof (tdst_VW_ObjInfo ) );
        p_stObjInfo -> m_p_oSuperObject = (CPA_SuperObject*) m_oListOfWord . GetNext( stPos );
        p_stObjInfo -> m_bUsePos = FALSE;
		POS_fn_vSetIdentityMatrix(&p_stObjInfo -> stMatrix);
        m_p_oListOfInitialObjects -> AddTail( p_stObjInfo );
    }
}