/*=========================================================================
* 
* CPAdList.cpp :  Lists - Implementation file
* 
*
* Version			1.0
* Creation date		
* Revision date
*
* Shaitan
*=======================================================================*/
#include "stdafx.h"
#ifdef ACTIVE_EDITOR
#include "acp_base.h"
#include "itf/CPAdList.hpp"
#include "itf/CPAProj.hpp"
#include "itf/DEVMul3D.hpp"
#include "itf/DEVVp3D.hpp"


// positions for the OnSize message
#define C_ComboPy 5
#define C_ComboCx 150
#define C_ComboCy 120

#define C_ButtonPx 5
#define C_ButtonPy 30
#define C_ButtonCy 20

#define C_ListPx 5
#define C_ListPy 55

//#################################################################################
// CPA_ListForDialog
//#################################################################################

/*----------------------------------------
	Constructor for Hierarchy Mode
----------------------------------------*/
CPA_ListForDialog::CPA_ListForDialog (CString csName, CPA_BaseObject *pTreeRoot, 
									  CImageList *pIconList, CImageList *pStateList)
{
	// hierarchy mode
	m_eDrawMode = E_ldm_Tree;
	// init name
	m_csName = csName;
	// init list of icons
	m_pIconList = pIconList;
	m_pStateList = pStateList;
	// init hierarchy
	m_pTreeRoot = pTreeRoot;
	// no list of objects
	m_pSortedList = NULL;
}

/*----------------------------------------
	Constructor for List Mode
----------------------------------------*/
CPA_ListForDialog::CPA_ListForDialog (CString csName, CPA_BaseObjectList *pListObjects, 
									  CImageList *pIconList, CImageList *pStateList,
									  tdeListOrder eDefaultOrder, BOOL bCanChangeOrder,
									  long lDefaultStyle, BOOL bCanChangeStyle)
{
	// list mode
	m_eDrawMode = E_ldm_List;
	// init name
	m_csName = csName;
	// init list of objects
	m_pSortedList = pListObjects;
	// init list of icons
	m_pIconList = pIconList;
	m_pStateList = pStateList;
	// no hierarchy
	m_pTreeRoot = NULL;
	// init order
	m_eListOrder = eDefaultOrder;
	m_bCanChangeOrder = bCanChangeOrder;
	// init style
	m_lDrawStyle = lDefaultStyle;
	m_bCanChangeStyle = bCanChangeStyle;
}

/*----------------------------------------
	Destructor
----------------------------------------*/
CPA_ListForDialog::~CPA_ListForDialog ()
{

}


/*----------------------------------------
	Order
----------------------------------------*/
void CPA_ListForDialog::SetOrder (tdeListOrder eOrder)
{
	if (m_bCanChangeOrder)
		m_eListOrder = eOrder;
}


/*----------------------------------------
	Style
----------------------------------------*/
void CPA_ListForDialog::SetStyle (long lStyle)
{
	if (m_bCanChangeStyle)
		m_lDrawStyle = lStyle;
}


//#################################################################################
// CPA_DialogList dialog
//#################################################################################

/*----------------------------------------
----------------------------------------*/
CPA_DialogList::CPA_DialogList(CWnd* pParent)
	: CFormView(CPA_DialogList::IDD)
{
	//{{AFX_DATA_INIT(CPA_DialogList)
	//}}AFX_DATA_INIT
}



/*----------------------------------------
----------------------------------------*/
void CPA_DialogList::DoDataExchange(CDataExchange* pDX)
{
	CFormView::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CPA_DialogList)
	DDX_Control(pDX, CPA_IDC_COMBOTYPE, m_cComboType);
	DDX_Control(pDX, CPA_IDC_LISTOBJECTS, m_cListObjects);
	DDX_Control(pDX, CPA_IDC_HIERARCHY, m_cHierarchy);
	DDX_Control(pDX, CPA_IDC_BUTTONTEST, m_cButtonTest);
	//}}AFX_DATA_MAP
}


/*----------------------------------------
----------------------------------------*/
BEGIN_MESSAGE_MAP(CPA_DialogList, CFormView)
	//{{AFX_MSG_MAP(CPA_DialogList)
// combo
	ON_CBN_SELCHANGE(CPA_IDC_COMBOTYPE, OnSelchangeComboType)
// button
	ON_BN_CLICKED(CPA_IDC_BUTTONTEST, OnButtonTest)
// list objects
	ON_NOTIFY(LVN_ITEMCHANGED, CPA_IDC_LISTOBJECTS, OnSelchangeListObjects)
	ON_NOTIFY(NM_DBLCLK, CPA_IDC_LISTOBJECTS, OnDblClkListObjects)
// hierarchy tree
	ON_NOTIFY(TVN_SELCHANGED, CPA_IDC_HIERARCHY, OnSelchangeHierarchy)
	ON_NOTIFY(TVN_BEGINDRAG, CPA_IDC_HIERARCHY, OnBeginDragHierarchy)
	ON_NOTIFY(NM_DBLCLK, CPA_IDC_HIERARCHY, OnDblClkHierarchy)
// general
	ON_WM_DRAWITEM()
	ON_WM_SIZE()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()


//#################################################################################
// CPA_DialogList Inits
//#################################################################################

/*===========================================================================
*		Description:	Init dialog
*		Creation date:	
*		Author:			Shaitan
*---------------------------------------------------------------------------
*		Revision date:                                      Author:         
*=========================================================================*/
void CPA_DialogList::fn_vInitDialog (CPA_EditorBase *pOwnerEditor, CWnd *pParent)
{
	// create the dialog
	m_bInitialised = FALSE;
	m_pOwnerEditor = pOwnerEditor;
	CFormView::Create(NULL, "", WS_VISIBLE|WS_CHILD/*AFX_WS_DEFAULT_VIEW*/, CRect(0,0,120,180), pParent, AFX_IDW_PANE_FIRST, NULL);
	m_pSelectedObject = NULL;
	m_pSelectedParent = NULL;
	m_pClickedObject = NULL;
	m_pClickedParent = NULL;
	m_pCurrentList = NULL;

	// init data for dialog
	CFormView::UpdateData(FALSE);
	m_cListObjects.SetParentDialog(this);
	m_cListObjects.SetOwnerEditor(m_pOwnerEditor);
	m_cHierarchy.SetParentDialog(this);
	m_cHierarchy.SetOwnerEditor(m_pOwnerEditor);

}


/*===========================================================================
*		Description:	Init the lists
*		Creation date:	
*		Author:			Shaitan
*---------------------------------------------------------------------------
*		Revision date:                                      Author:         
*=========================================================================*/
void CPA_DialogList::fn_vInitAllLists (void)
{
	// RAZ
	m_stListOfListObjects.RemoveAll();
	m_pCurrentList = NULL;
	m_csTestName.Empty();
	m_csTypeName.Empty();
	m_bButtonState = FALSE;
	m_bTestEnabled = FALSE;

	// ask for the lists
	m_pOwnerEditor->GetListsForDialog(this);
	m_pOwnerEditor->fn_vInitDefaultParameters(this);

	m_pCurrentList = GetListFromName(m_csTypeName);
	m_bInitialised = TRUE;

}

/*===========================================================================
*		Description:	init the combo box  
*		Creation date:	
*		Author:			Shaitan
*---------------------------------------------------------------------------
*		Revision date:                      Author:         
*=========================================================================*/
void CPA_DialogList::fn_vInitComboType (void)
{
	CPA_ListForDialog	*pListDialog;
	POSITION			pos;
	int					iIndex;

	// RAZ
	m_cComboType.ResetContent();

	// fill the list of the combo with the available types
	for (pListDialog = m_stListOfListObjects.GetHeadElement(pos); pListDialog; 
		 pListDialog = m_stListOfListObjects.GetNextElement(pos))
			m_cComboType.AddString(pListDialog->GetName());
	// set the current selection 
	iIndex = m_cComboType.FindStringExact(-1, m_csTypeName);
	m_cComboType.SetCurSel(iIndex);

	// ask for a new test
	m_pOwnerEditor->fn_vSetANewTest(this, m_csTypeName);
}


/*===========================================================================
*		Description:	reinit dialog when select mode has changed 
*		Creation date:	
*		Author:			Shaitan
*---------------------------------------------------------------------------
*		Revision date:           Author:         
*=========================================================================*/
void CPA_DialogList::fn_vReinitDialog (void)
{	
	int iInd;
	
	// init the combo box
	fn_vInitComboType();

	// find current selection in combo
	if (!m_pCurrentList)
	{
		m_cHierarchy.fn_vDeleteHierarchyTree();
		m_cHierarchy.ShowWindow(SW_HIDE);
		m_cListObjects.DeleteAllItems();
		m_cListObjects.ShowWindow(SW_HIDE);
		return;
	}

	// View Mode List
	if (m_pCurrentList->GetMode() == E_ldm_List)
	{
		// enable listbox
		m_cHierarchy.ShowWindow(SW_HIDE);
		m_cHierarchy.EnableWindow(FALSE);
		m_cListObjects.ShowWindow(SW_SHOW);
		m_cListObjects.EnableWindow(TRUE);
		// init controls
		iInd = m_cComboType.FindStringExact(-1, m_csTypeName);
		m_cComboType.SetCurSel(iInd);
		fn_vInitButtonTest(m_csTestName, m_bButtonState, m_bTestEnabled);
		// reinit the list
		fn_vReinitPosition(&m_cListObjects, &m_cListObjects, E_lcp_AdjustAll);
		fn_vInitListObjects();
	}
	// DrawMode Tree
	else
	{
		// init tree control
		m_cListObjects.ShowWindow(SW_HIDE);
		m_cListObjects.EnableWindow(FALSE);
		m_cHierarchy.ShowWindow(SW_SHOW);
		m_cHierarchy.EnableWindow(TRUE);
		// init controls
		iInd = m_cComboType.FindStringExact(-1, m_csTypeName);
		m_cComboType.SetCurSel(iInd);
		fn_vInitButtonTest(m_csTestName, m_bButtonState, m_bTestEnabled);
		// reinit hierarchy
		fn_vReinitPosition(&m_cHierarchy, &m_cHierarchy, E_lcp_AdjustAll);
		fn_vInitHierarchy();
	}
}


/*===========================================================================
*		Description:	Init Test Function and Button
*		Creation date:	
*		Author:			Shaitan
*---------------------------------------------------------------------------
*		Revision date:                                      Author:         
*=========================================================================*/
void CPA_DialogList::fn_vInitButtonTest (CString csName, BOOL bState, BOOL bEnabled)
{
	// set text on the button
	m_csTestName = csName;
	m_cButtonTest.SetWindowText(m_csTestName);
	// set button state
	m_bButtonState = bState;
	m_cButtonTest.EnableWindow(m_bButtonState);
	// enable / disable test
	m_bTestEnabled = bEnabled;
}
	

/*===========================================================================
*		Description:	reinit position when resized 
*		Creation date:	
*		Author:			Shaitan
*---------------------------------------------------------------------------
*		Revision date:           Author:         
*=========================================================================*/
void CPA_DialogList::fn_vReinitPosition (CWnd *pControl, CWnd *pRef, tdeListControlPos ePos)
{
//	RECT AbsolutePosition;
	RECT WindowPosition;
	int px, py, cx, cy, crx, cry;

	GetWindowRect(&WindowPosition);
//	pRef->GetWindowRect(&AbsolutePosition);

	// calculate relative position
	cx = WindowPosition.right - WindowPosition.left;
	cy = WindowPosition.bottom - WindowPosition.top;

	if (pRef == &m_cComboType)
	{
		px = 0; 
		py = C_ComboPy;
		crx = C_ComboCx;
		cry = C_ComboCy;
	}
	else if (pRef == &m_cButtonTest)
	{
		px = C_ButtonPx; 
		py = C_ButtonPy;
		crx = 0;
		cry = C_ButtonCy;
	}
	else 
	{
		px = C_ListPx; 
		py = C_ListPy;
		crx = 0;
		cry = 0;
	}

//	px = AbsolutePosition.left - WindowPosition.left; 
//	py = AbsolutePosition.top - WindowPosition.top;
//	crx = AbsolutePosition.right - AbsolutePosition.left;
//	cry = AbsolutePosition.bottom - AbsolutePosition.top;
	crx = (crx < cx) ? crx : cx - 10;

	// move control accoring to its type
	if (ePos == E_lcp_Center)
		pControl->MoveWindow((cx-crx)/2, py, crx, cry);
	else if (ePos == E_lcp_AdjustWidth)
		pControl->MoveWindow(px, py, cx - 2*px, cry);
	else
		pControl->MoveWindow(px, py, cx - 2*px, cy - py - 5);
}



/*===========================================================================
*		Description:	fill the hierarchy tree
*		Creation date:	
*		Author:			Shaitan
*---------------------------------------------------------------------------
*		Revision date:           Author:         
*=========================================================================*/
void CPA_DialogList::fn_vInitHierarchy (void)
{
	HTREEITEM		hElem;
	HTREEITEM		hExpItem, hFatItem;
	CPA_TreeItem	*pExpItem = NULL;
	CPA_TreeItem	*pFatItem = NULL;
	CPA_BaseObject	*pExpObj = NULL;
	CPA_BaseObject	*pFatObj = NULL;
	
	// keep expand state
	if (m_pSelectedObject)
	{
		hElem = m_cHierarchy.GetCorrespondingItem(m_pSelectedObject, m_pSelectedParent, NULL);
		// get item to expand
		hExpItem = (hElem)	  ?	m_cHierarchy.GetParentItem(hElem)					: NULL;
		pExpItem = (hExpItem) ?	(CPA_TreeItem *) m_cHierarchy.GetItemData(hExpItem) : NULL;
		pExpObj  = (pExpItem) ?	pExpItem->GetObject()								: NULL;
		// get father of item to expand
		hFatItem = (hExpItem) ? m_cHierarchy.GetParentItem(hExpItem)				: NULL;
		pFatItem = (hFatItem) ? (CPA_TreeItem *) m_cHierarchy.GetItemData(hFatItem) : NULL;
		pFatObj  = (pFatItem) ? pFatItem->GetObject()								: NULL;
	}
	// RAZ
	m_cHierarchy.fn_vDeleteHierarchyTree();
	m_pSelectedObject	= NULL;
	m_pSelectedParent	= NULL;
	m_pClickedObject	= NULL;
	hElem				= NULL;

	// check current list
	if ((!m_pCurrentList)||(m_pCurrentList->GetMode() != E_ldm_Tree))
	{
		m_cHierarchy.SetTreeRoot(NULL);
		m_cHierarchy.SetIconList(NULL, FALSE);
		m_cHierarchy.SetStateList(NULL, FALSE);
		return;
	}
	
	// new hierarchy
	m_cHierarchy.SetIconList(m_pCurrentList->GetIconList(), FALSE);
	m_cHierarchy.SetStateList(m_pCurrentList->GetStateList(), FALSE);
	m_cHierarchy.SetTreeRoot(m_pCurrentList->GetRoot());

	// find the current selection
	m_pSelectedObject = m_pOwnerEditor->GetDialogSelection(this, m_csTypeName, E_ldm_Tree);
	m_pSelectedParent = m_pOwnerEditor->GetDialogParentSelection(this, m_csTypeName);
	m_pClickedObject = m_pSelectedObject;
	m_pClickedParent = m_pSelectedParent;

	// find corresponding item
	if (m_pSelectedObject)
		hElem = m_cHierarchy.GetCorrespondingItem(m_pSelectedObject, m_pSelectedParent, NULL);
	
	// if there is a current selection, expand it
	if (hElem)
	{
		m_cHierarchy.Expand(hElem, TVE_EXPAND);
		m_cHierarchy.SelectItem(hElem);
	}
	// else try to keep previous expand
	else if (pExpObj)
	{
		hExpItem = m_cHierarchy.GetCorrespondingItem(pExpObj, pFatObj, NULL);
		hElem = m_cHierarchy.GetChildItem(hExpItem);
		if (hElem)
			m_cHierarchy.EnsureVisible(hElem);
		else
			m_cHierarchy.EnsureVisible(hExpItem);
	}
	// else no selection
	else
		m_cHierarchy.SelectItem(NULL);
}


/*===========================================================================
*		Description:	fill the list box with the names of all the
*						objects of the current type 
*		Creation date:	
*		Author:			Shaitan
*---------------------------------------------------------------------------
*		Revision date:           Author:         
*=========================================================================*/
void CPA_DialogList::fn_vInitListObjects (void)
{
	int iInd;
	
	// RAZ
	m_pSelectedObject	= NULL;
	
	// find the corresponding list
	if ((!m_pCurrentList)||(m_pCurrentList->GetMode() != E_ldm_List)||(!m_pCurrentList->GetSortedList()))
	{
		m_cListObjects.SetSortedList(NULL);
		m_cListObjects.SetIconList(NULL, FALSE);
		m_cListObjects.SetStateList(NULL, FALSE);
		return;
	}

	// reset the list
	m_cListObjects.SetSortedList(NULL);
	// update parameters
	m_cListObjects.SetIconList(m_pCurrentList->GetIconList(), FALSE);
	m_cListObjects.SetStateList(m_pCurrentList->GetStateList(), FALSE);
	m_cListObjects.SetOrder(m_pCurrentList->GetOrder(), m_pCurrentList->fn_bCanChangeOrder(), FALSE);
	m_cListObjects.SetDrawStyle(m_pCurrentList->GetStyle(), m_pCurrentList->fn_bCanChangeStyle(), FALSE);
	// set new list
	m_cListObjects.SetSortedList(m_pCurrentList->GetSortedList());
	m_cListObjects.OnSize(SIZE_RESTORED, 0, 0);
	// find the current selection
	m_pSelectedObject = m_pOwnerEditor->GetDialogSelection(this, m_csTypeName, E_ldm_List);

	// set selection
	if (m_pSelectedObject)
	{
		iInd = m_cListObjects.GetCorrespondingIndex((DWORD) m_pSelectedObject);
		m_cListObjects.SetSelectedItem(iInd);
	}
	else
		m_cListObjects.SetSelectedItem(-1);
}


/*===========================================================================
*		Description:	fill the list box with the names of all the
*						objects of the current type 
*		Creation date:	
*		Author:			Shaitan
*---------------------------------------------------------------------------
*		Revision date:           Author:         
*=========================================================================*/
BOOL CPA_DialogList::fn_bCanInsertElement (CPA_BaseObject *pElem)
{
	BOOL bRes;
	
	// test function
	bRes = ((!m_bTestEnabled)||(m_pOwnerEditor->fn_bTestFunction(m_csTypeName, m_csTestName, pElem)));
	if (bRes)
		bRes = ((pElem->fn_bIsAvailable())||(m_cListObjects.GetDisplayGray()));
	return bRes;
}

/*===========================================================================
*		Description:	update dialog when selection changes  
*		Creation date:	
*		Author:			Shaitan
*---------------------------------------------------------------------------
*		Revision date:                      Author:         
*=========================================================================*/
void CPA_DialogList::fn_vUpdateSelection (tdeListReinitMode eType)
{
	CPA_ListForDialog	*pListDialog;
	HTREEITEM			hElem = NULL;
	HTREEITEM			hSelected;
	int					iInd;
	
	// type of update
	switch (eType)
	{
	// update all objects
	case E_lrm_ReinitList:
		if (!m_pCurrentList)
		{
			m_cHierarchy.fn_vDeleteHierarchyTree();
			m_cListObjects.DeleteAllItems();
			return;
		}
		// update button
		fn_vInitButtonTest(m_csTestName, m_bButtonState, m_bTestEnabled);
		// update list or tree
		if (m_pCurrentList->GetMode() == E_ldm_List)
			fn_vInitListObjects();
		else
			fn_vInitHierarchy();
		break;

	case E_lrm_ChangeSelection:
		// find the current selection
		if (!m_pCurrentList)
			m_pSelectedObject = NULL;
		else
		{
			m_pSelectedObject = m_pOwnerEditor->GetDialogSelection(this, m_csTypeName, m_pCurrentList->GetMode());
			if (m_pCurrentList->GetMode() == E_ldm_Tree)
				m_pSelectedParent = m_pOwnerEditor->GetDialogParentSelection(this, m_csTypeName);
		}
		// no selection => no update
		if (!m_pSelectedObject)
		{
			m_cListObjects.SetSelectedItem(-1);
			return;
		}
		// set list selection
		if (m_pCurrentList->GetMode() == E_ldm_List)
		{
			m_pCurrentList->GetSortedList()->fn_bChangeObjectOrder(m_pSelectedObject, 0, E_lo_Common);
			if (m_cListObjects.GetOrder() == E_lo_Common)
			{
				iInd = m_cListObjects.GetCorrespondingIndex((DWORD) m_pSelectedObject);
				m_cListObjects.DeleteItem(iInd);
				iInd = m_cListObjects.InsertNewItem(0, m_pSelectedObject);
			}
			else
			{
				iInd = m_cListObjects.GetCorrespondingIndex((DWORD) m_pSelectedObject);
				m_cListObjects.SetSelectedItem(iInd);
			}
		}
		// set tree selection
		else
		{
			hElem = m_cHierarchy.GetCorrespondingItem(m_pSelectedObject, m_pSelectedParent, NULL);
			if (hElem)
				m_cHierarchy.Expand(hElem, TVE_EXPAND);
			m_cHierarchy.SelectItem(hElem);
		}
		break;
	
	case E_lrm_GoToChild:
	case E_lrm_GoToParent:
		// reinit viewmode
		pListDialog = GetListFromName("Hierarchy");
		if ((!pListDialog)||(pListDialog->GetMode() != E_ldm_Tree))
		{
			m_cHierarchy.fn_vDeleteHierarchyTree();
			m_cListObjects.DeleteAllItems();
			return;
		}
		SetCurrentType("Hierarchy");
		// find selected item
		hSelected = m_cHierarchy.GetCorrespondingItem(m_pSelectedObject, m_pSelectedParent, NULL);
		if (eType == E_lrm_GoToChild)
			hElem = hSelected;
		else
			hElem = m_cHierarchy.GetParentItem(hSelected);
		// expand node (object or parent)
		if (hElem)
			m_cHierarchy.Expand(hElem, TVE_EXPAND);
		// set current selection
		m_cHierarchy.SelectItem(hSelected);
		break;
	}
}


//#################################################################################
// CPA_DialogList Functions
//#################################################################################

/*===========================================================================
*		Description:	add a list or a tree to the dialog
*		Creation date:	
*		Author:			Shaitan
*---------------------------------------------------------------------------
*		Revision date:                                      Author:         
*=========================================================================*/
void CPA_DialogList::fn_vAddANewTree (CString csName, CPA_BaseObject *pTreeRoot, 
									  CImageList *pIconList, CImageList *pStateList)
{
	m_stListOfListObjects.AddTail(new CPA_ListForDialog(csName, pTreeRoot, pIconList, pStateList));
}

void CPA_DialogList::fn_vAddANewList (CString csName, CPA_BaseObjectList *pListObjects, 
									  CImageList *pIconList, CImageList *pStateList,
									  tdeListOrder eDefaultOrder, BOOL bCanChangeOrder,
									  long lDefaultStyle, BOOL bCanChangeStyle)
{
	m_stListOfListObjects.AddTail(new CPA_ListForDialog(csName, pListObjects, pIconList, pStateList,
														eDefaultOrder, bCanChangeOrder, lDefaultStyle,bCanChangeStyle));
}


/*===========================================================================
*		Description:	remove a list of the dialog
*		Creation date:	
*		Author:			Shaitan
*---------------------------------------------------------------------------
*		Revision date:                                      Author:         
*=========================================================================*/
void CPA_DialogList::fn_vDeleteAList (CString csName)
{
	CPA_ListForDialog *pListDialog;
	POSITION pos = NULL;

	pListDialog = GetListFromName(csName);

	if (pListDialog)
		pos = m_stListOfListObjects.Find(pListDialog, NULL);
	if (pos)
	{
		m_stListOfListObjects.RemoveAt(pos);
		delete pListDialog;
	}
}


/*===========================================================================
*		Description:	Find current list
*		Creation date:	
*		Author:			Shaitan
*---------------------------------------------------------------------------
*		Revision date:                                      Author:         
*=========================================================================*/
CPA_ListForDialog * CPA_DialogList::GetListFromName (CString csName)
{
	CPA_ListForDialog *pListDialog;
	POSITION pos;

	// check all the lists of dialog
	for (pListDialog = m_stListOfListObjects.GetHeadElement(pos); pListDialog;
		 pListDialog = m_stListOfListObjects.GetNextElement(pos))
	{
		if (csName == pListDialog->GetName())
			return pListDialog;
	}

	// list was not found
	return NULL;
}


/*===========================================================================
*		Description:	change the type and update dialog
*		Creation date:	
*		Author:			Shaitan
*---------------------------------------------------------------------------
*		Revision date:           Author:         
*=========================================================================*/
void CPA_DialogList::SetCurrentType (CString csName)
{
	BOOL bRes;
	int iInd;

	// update parameters
	m_csTypeName = csName;
	m_pCurrentList = GetListFromName(m_csTypeName);
	// update combo
	iInd = m_cComboType.FindStringExact(-1, csName);
	m_cComboType.SetCurSel(iInd);
	
	// tell owner
	bRes = m_pOwnerEditor->fn_bOnSelChangeComboList(this, m_csTypeName);
	
	// default handling
	if (!bRes)
		fn_vReinitDialog();
}



/*===========================================================================
*		Description:	change the type and update dialog
*		Creation date:	
*		Author:			Shaitan
*---------------------------------------------------------------------------
*		Revision date:           Author:         
*=========================================================================*/
void CPA_DialogList::fn_vRedrawElement (CPA_BaseObject *pObject, BOOL bEnsureVisible)
{
	int iInd;
	
	// check current list
	if ((!m_pCurrentList)||(m_pCurrentList->GetMode() != E_ldm_List))
		return;

	// find current object
	iInd = m_cListObjects.GetCorrespondingIndex((DWORD) pObject);
	if (iInd == -1)
		return;

	// redraw item
	m_cListObjects.RedrawItems(iInd, iInd);
	// if necessary, ensure visible
	if (bEnsureVisible)
		m_cListObjects.EnsureVisible(iInd, TRUE);
}

//#################################################################################
// CPA_DialogList message handlers
//#################################################################################

/*----------------------------------------
----------------------------------------*/
void CPA_DialogList::OnSelchangeComboType() 
{
	BOOL bRes;
	
	// find new selection
	m_cComboType.GetLBText(m_cComboType.GetCurSel(), m_csTypeName);
	m_pCurrentList = GetListFromName(m_csTypeName);

	// tell owner
	bRes = m_pOwnerEditor->fn_bOnSelChangeComboList(this, m_csTypeName);
	
	// default handling
	if (!bRes)
		fn_vReinitDialog();
}


/*----------------------------------------
----------------------------------------*/
void CPA_DialogList::OnButtonTest (void)
{
	BOOL bRes;

	// find current selection in combo
	if (!m_pCurrentList)
		return;

	// ask owner
	bRes = m_pOwnerEditor->fn_bOnButtonTest(this, m_csTypeName, m_pCurrentList->GetMode());
	if (!bRes)
		fn_vUpdateSelection(E_lrm_ReinitList);
}



//#################################################################################
// CPA_DialogList message handlers (ListObjects) 
//#################################################################################

/*----------------------------------------
----------------------------------------*/
void CPA_DialogList::OnSelchangeListObjects(NMHDR* pNMHDR, LRESULT* pResult) 
{
	LPNM_LISTVIEW	pNMListView = (LPNM_LISTVIEW)pNMHDR;
	BOOL			bRes;
	BOOL			bOldSelect, bNewSelect;				
	int				iInd;
	
	*pResult = 0;

	if ((pNMListView->uChanged != LVIF_STATE)||(m_cListObjects.fn_bIsSelecting()))
		return;

	bOldSelect = (pNMListView->uOldState & LVIS_SELECTED);
	bNewSelect = (pNMListView->uNewState & LVIS_SELECTED);

	if (bOldSelect != bNewSelect)
	{
		// find corresponding object 
		iInd = pNMListView->iItem;
		m_pClickedObject = (iInd == -1) ? NULL : (CPA_BaseObject *) m_cListObjects.GetItemData(iInd);
		// deselection
		m_pSelectedObject = NULL;
		m_cListObjects.SetSelectedItem(-1);

		// tell owner
		bRes = m_pOwnerEditor->fn_bOnSelChangeListObjects(this, m_csTypeName, m_pClickedObject, !bNewSelect);

		// default handling
		if (!bRes)
		{
			// set current selection
			if ((bNewSelect)&&(m_pClickedObject))
			{
				m_pSelectedObject = m_pClickedObject;
				iInd = m_cListObjects.GetCorrespondingIndex((DWORD) m_pClickedObject);
				m_cListObjects.SetSelectedItem(iInd);
			}
			// update common order
			if ((m_cListObjects.GetOrder() == E_lo_Common)&&(m_pClickedObject))
			{
				m_pCurrentList->GetSortedList()->fn_bChangeObjectOrder(m_pSelectedObject, 0, E_lo_Common);
				iInd = m_cListObjects.GetCorrespondingIndex((DWORD) m_pClickedObject);
				m_cListObjects.DeleteItem(iInd);
				iInd = m_cListObjects.InsertNewItem(0, m_pClickedObject);
			}
		}
	}
}

/*----------------------------------------
----------------------------------------*/
void CPA_DialogList::OnDblClkListObjects(NMHDR* pNMHDR, LRESULT* pResult) 
{
	LPNM_LISTVIEW	pNMListView = (LPNM_LISTVIEW)pNMHDR;
	BOOL			bRes;

	if (pNMListView->uChanged)
	{
		if (m_pClickedObject)
		{
			// tell owner
			bRes = m_pOwnerEditor->fn_bOnDblClkListObjects(this, m_csTypeName, m_pClickedObject);
			// default handling
			if (!bRes)
				m_pSelectedObject = m_pClickedObject;
			else
			{
				m_pSelectedObject = NULL;
				m_cListObjects.SetSelectedItem(-1);
			}
		}
	}
	*pResult = 0;
}

//#################################################################################
// CPA_DialogList message handlers (Hierarchy) 
//#################################################################################


/*----------------------------------------
----------------------------------------*/
void CPA_DialogList::OnSelchangeHierarchy (NMHDR* pNMHDR, LRESULT* pResult)
{
	CPA_TreeItem	*pItem;
	HTREEITEM		hCurItem, hFatItem;
	BOOL			bRes;

	LPNM_TREEVIEW pNMTreeView = (LPNM_TREEVIEW)pNMHDR;

	if (pNMTreeView->action)
	{
		hCurItem = m_cHierarchy.GetSelectedItem();
		// select the object corresponding to the choice in the list box
		if (hCurItem != NULL)
		{
			pItem = (CPA_TreeItem *) m_cHierarchy.GetItemData(hCurItem);
			m_pClickedObject = pItem->GetObject();
			hFatItem = m_cHierarchy.GetParentItem(hCurItem);
			if (hFatItem != NULL)
			{
				pItem = (CPA_TreeItem *) m_cHierarchy.GetItemData(hFatItem);
				m_pClickedParent = (pItem) ? pItem->GetObject() : NULL;
			}
		}

		if (m_pClickedObject)
		{
			// tell owner
			bRes = m_pOwnerEditor->fn_bOnSelChangeHierarchyTree(this, m_csTypeName, m_pClickedObject, m_pClickedParent);
			// default handling
			if (!bRes)
			{
				m_pSelectedObject = m_pClickedObject;
				m_pSelectedParent = m_pClickedParent;
			}
			else
				m_cHierarchy.SetItemState(hCurItem, 0, TVIS_SELECTED);
		}
	}

	*pResult = 0;
}



/*----------------------------------------
----------------------------------------*/
void CPA_DialogList::OnDblClkHierarchy(NMHDR* pNMHDR, LRESULT* pResult) 
{
	LPNM_TREEVIEW	pNMTreeView = (LPNM_TREEVIEW)pNMHDR;
	BOOL			bRes;

	if (pNMTreeView->action)
	{
		if (m_pClickedObject)
		{
			// tell owner
			bRes = m_pOwnerEditor->fn_bOnDblClkHierarchyTree(this, m_csTypeName, m_pClickedObject, m_pClickedParent);
			// default handling
			if (!bRes)
			{
				m_pSelectedObject = m_pClickedObject;
				m_pSelectedParent = m_pClickedParent;
			}
		}
	}
	*pResult = 0;
}

/*----------------------------------------
----------------------------------------*/
void CPA_DialogList::OnBeginDragHierarchy (NMHDR* pNMHDR, LRESULT* pResult)
{
	CPA_BaseObject		*pObjectToDrag = NULL;
	CPA_BaseObject		*pParentToDrag = NULL;
	CPA_TreeItem		*pItem;
	HTREEITEM			hItemToDrag = NULL;
	HTREEITEM			hParentToDrag = NULL;
	BOOL				bRes;
		
	// get current list
	if ((!m_pCurrentList)||(m_pCurrentList->GetMode() != E_ldm_Tree))
	{
		m_cHierarchy.SetDraggedItem(NULL);
		return;
	}

	// get item & object to drag
	LPNM_TREEVIEW pNMTreeView = (LPNM_TREEVIEW)pNMHDR;
	hItemToDrag = pNMTreeView->itemNew.hItem;
	if (hItemToDrag)
	{
		pItem = (CPA_TreeItem *) m_cHierarchy.GetItemData(hItemToDrag);
		pObjectToDrag = pItem->GetObject();
		hParentToDrag = m_cHierarchy.GetParentItem(hItemToDrag);
		if (hParentToDrag)
		{
			pItem = (CPA_TreeItem *) m_cHierarchy.GetItemData(hParentToDrag);
			pParentToDrag = pItem->GetObject();
		}
	}
	// selected ?
	if (pObjectToDrag && (pObjectToDrag != m_pSelectedObject))
	{
		// tell owner
		bRes = m_pOwnerEditor->fn_bOnSelChangeHierarchyTree(this, m_csTypeName, pObjectToDrag, pParentToDrag);
		// default handling
		if (!bRes)
		{
			m_pSelectedObject = pObjectToDrag;
			m_pSelectedParent = pParentToDrag;
		}
	}
	if ((!pObjectToDrag)||(pObjectToDrag != m_pSelectedObject))
	{
		m_cHierarchy.SetDraggedItem(NULL);
		return;
	}
	// ask permission to dialog owner
	bRes = m_pOwnerEditor->fn_bCanDragItemInHierarchyTree(this, m_csTypeName, pObjectToDrag);
	// init drag&drop
	if (bRes)
		m_cHierarchy.SetDraggedItem(hItemToDrag);
	else
		m_cHierarchy.SetDraggedItem(NULL);
}


/*----------------------------------------
----------------------------------------*/
void CPA_DialogList::fn_vOnDragDropEndHierarchy (void)
{
	CPA_BaseObject		*pObjectToDrag, *pTarget;
	CPA_TreeItem		*pItem;
	HTREEITEM			hItemToDrag, hTarget;
	BOOL				bRes = FALSE;

	// get dragged object
	hItemToDrag = m_cHierarchy.GetDraggedItem();
	pItem = (CPA_TreeItem *) m_cHierarchy.GetItemData(hItemToDrag);
	pObjectToDrag = pItem->GetObject();
	// get target object
	hTarget = m_cHierarchy.GetDropTarget();
	pItem = (CPA_TreeItem *) m_cHierarchy.GetItemData(hTarget);
	pTarget = pItem->GetObject();
	// ask permission to dialog owner
	if (m_pOwnerEditor->fn_bCanDropItemInHierarchyTree(this, m_csTypeName, pObjectToDrag, pTarget))
		bRes = m_pOwnerEditor->fn_bOnDragDropInHierarchyTree(this, m_csTypeName, pObjectToDrag, pTarget);
	// reinit tree
	if (bRes)
		fn_vInitHierarchy();
}

/*----------------------------------------
----------------------------------------*/
BOOL CPA_DialogList::fn_bAcceptAsDragDropTarget (HTREEITEM hTarget)
{
	CPA_BaseObject		*pObjectToDrag, *pTarget;
	CPA_TreeItem		*pItem;
	HTREEITEM			hItemToDrag;

	// no target => no drop
	if (!hTarget)
		return FALSE;
	// get dragged object
	hItemToDrag = m_cHierarchy.GetDraggedItem();
	pItem = (CPA_TreeItem *) m_cHierarchy.GetItemData(hItemToDrag);
	pObjectToDrag = pItem->GetObject();
	// get target object
	pItem = (CPA_TreeItem *) m_cHierarchy.GetItemData(hTarget);
	pTarget = pItem->GetObject();
	// ask permission to dialog owner
	return m_pOwnerEditor->fn_bCanDropItemInHierarchyTree(this, m_csTypeName, pObjectToDrag, pTarget);
}

/*----------------------------------------
----------------------------------------*/
void CPA_DialogList::fn_vOnDblClkHierarchyTree (void)
{
	BOOL			bRes;

	if (m_pClickedObject)
	{
		// tell owner
		bRes = m_pOwnerEditor->fn_bOnDblClkHierarchyTree(this, m_csTypeName, m_pClickedObject, m_pClickedParent);
		// default handling
		if (!bRes)
		{
			m_pSelectedObject = m_pClickedObject;
			m_pSelectedParent = m_pClickedParent;
		}
	}
}


//#################################################################################
// CPA_DialogList message handlers (General) 
//#################################################################################

/*----------------------------------------
----------------------------------------*/
BOOL CPA_DialogList::fn_bOnKeyDownInControl (UINT nChar, UINT nRepCnt, UINT nFlags)
{
	// tell owner
	return m_pOwnerEditor->fn_bOnKeyDownInDialog(this, m_csTypeName, m_pCurrentList->GetMode(),
										m_pSelectedObject, nChar, nRepCnt, nFlags);
}

/*----------------------------------------
----------------------------------------*/
BOOL CPA_DialogList::fn_bOnKeyUpInControl (UINT nChar, UINT nRepCnt, UINT nFlags)
{
	return m_pOwnerEditor->fn_bOnKeyUpInDialog(this, m_csTypeName, m_pCurrentList->GetMode(),
										m_pSelectedObject, nChar, nRepCnt, nFlags);
}


/*----------------------------------------
----------------------------------------*/
void CPA_DialogList::OnSize (UINT nFlags, int cx, int cy)
{
	if (m_bInitialised)
	{
		// update size and position of controls
		fn_vReinitPosition(&m_cComboType, &m_cComboType, E_lcp_Center);
		fn_vReinitPosition(&m_cButtonTest, &m_cButtonTest, E_lcp_AdjustWidth);
		// get current mode
		if (!m_pCurrentList)
			return;
		// update size and position of the corresponding control
		if (m_pCurrentList->GetMode() == E_ldm_List)
			fn_vReinitPosition(&m_cListObjects, &m_cListObjects, E_lcp_AdjustAll);
		else
			fn_vReinitPosition(&m_cHierarchy, &m_cHierarchy, E_lcp_AdjustAll);
	}
}


//#################################################################################
// CPA_DialogList list attributes
//#################################################################################

/*----------------------------------------
----------------------------------------*/
void CPA_DialogList::SetPermanentOrder (tdeListOrder ePermanentOrder)
{
	m_cListObjects.SetOrder(ePermanentOrder, FALSE, FALSE);
}

/*----------------------------------------
----------------------------------------*/
void CPA_DialogList::SetPermanentStyle (long lPermanentStyle)
{
	m_cListObjects.SetDrawStyle(lPermanentStyle, FALSE, FALSE);
}

/*----------------------------------------
----------------------------------------*/
void CPA_DialogList::SetPermanentDisplay (BOOL bPermanentDisplay)
{
	m_cListObjects.SetDisplayGray(bPermanentDisplay, FALSE, FALSE);
}


/*----------------------------------------
----------------------------------------*/
void CPA_DialogList::SetPermanentHeaders (BOOL bPermanentHeaders)
{
	m_cListObjects.SetColumnHeaders(bPermanentHeaders, FALSE, FALSE);
}

/*----------------------------------------
----------------------------------------*/
void CPA_DialogList::SetDefaultOrder (tdeListOrder eDefaultOrder)
{
	m_cListObjects.SetOrder(eDefaultOrder, TRUE, FALSE);
}

/*----------------------------------------
----------------------------------------*/
void CPA_DialogList::SetDefaultStyle (long lDefaultStyle)
{
	m_cListObjects.SetDrawStyle(lDefaultStyle, TRUE, FALSE);
}

/*----------------------------------------
----------------------------------------*/
void CPA_DialogList::SetDefaultDisplay (BOOL bDefaultDisplay)
{
	m_cListObjects.SetDisplayGray(bDefaultDisplay, TRUE, FALSE);
}

/*----------------------------------------
----------------------------------------*/
void CPA_DialogList::SetDefaultHeaders (BOOL bDefaultHeaders)
{
	m_cListObjects.SetColumnHeaders(bDefaultHeaders, TRUE, FALSE);
}

/*----------------------------------------
----------------------------------------*/
void CPA_DialogList::SetItemInfo (CString csListName, CPA_BaseObject *pObject, CPA_BaseObject *pParent, void *pInfo)
{
	// change only in current list
	if (csListName != m_csTypeName)
		return;
	if ((!m_pCurrentList)||(m_pCurrentList->GetMode() != E_ldm_Tree))
		return;
	// change info
	m_cHierarchy.SetItemInfo(pObject, pParent, pInfo);

}

/*----------------------------------------
----------------------------------------*/
void * CPA_DialogList::GetItemInfo (CString csListName, CPA_BaseObject *pObject, CPA_BaseObject *pParent)
{
	// get only in current list
	if (csListName != m_csTypeName)
		return NULL;
	if ((!m_pCurrentList)||(m_pCurrentList->GetMode() != E_ldm_Tree))
		return NULL;
	// get info
	return m_cHierarchy.GetItemInfo(pObject, pParent);
}


/*----------------------------------------
----------------------------------------*/
void CPA_DialogList::SetItemIcon (CString csListName, CPA_BaseObject *pObject, CPA_BaseObject *pParent, int iIcon)
{
	// change only in current list
	if (csListName != m_csTypeName)
		return;
	if ((!m_pCurrentList)||(m_pCurrentList->GetMode() != E_ldm_Tree))
		return;
	// change icon
	m_cHierarchy.SetItemIcon(pObject, pParent, iIcon);

}

/*----------------------------------------
----------------------------------------*/
int CPA_DialogList::GetItemIcon (CString csListName, CPA_BaseObject *pObject, CPA_BaseObject *pParent)
{
	// get only in current list
	if (csListName != m_csTypeName)
		return -1;
	if ((!m_pCurrentList)||(m_pCurrentList->GetMode() != E_ldm_Tree))
		return -1;
	// get icon
	return m_cHierarchy.GetItemIcon(pObject, pParent);
}

/*----------------------------------------
----------------------------------------*/
void CPA_DialogList::SetItemState (CString csListName, CPA_BaseObject *pObject, CPA_BaseObject *pParent, int iState)
{
	// change only in current list
	if (csListName != m_csTypeName)
		return;
	if ((!m_pCurrentList)||(m_pCurrentList->GetMode() != E_ldm_Tree))
		return;
	// change state
	m_cHierarchy.SetItemStateI(pObject, pParent, iState);

}

/*----------------------------------------
----------------------------------------*/
int CPA_DialogList::GetItemState (CString csListName, CPA_BaseObject *pObject, CPA_BaseObject *pParent)
{
	// get only in current list
	if (csListName != m_csTypeName)
		return -1;
	if ((!m_pCurrentList)||(m_pCurrentList->GetMode() != E_ldm_Tree))
		return -1;
	// get state
	return m_cHierarchy.GetItemStateI(pObject, pParent);
}

#endif // ACTIVE_EDITOR


