/*=========================================================================
* 
* 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/CPAdLbox.hpp"
#include "ITF/CPAdList.hpp"
#include "ITF/CPABaseO.hpp"
#include "ITF/CPAEditB.hpp"
#include "IncTUT.h"

#define C_uiHeaderEntry		 0
#define C_uiAutoAdjustEntry	 1

#define C_uiDrawStateEntry	 2
#define C_uiDrawIconEntry	 3
#define C_uiDrawTypeEntry	 4
#define C_uiDrawOwnerEntry	 5
#define C_uiDrawInfoEntry	 6

#define C_uiSortAlphaEntry   7
#define C_uiSortCommonEntry  8
#define C_uiSortEditedEntry  9

#define C_uiDisplayAllEntry 10

#define C_uiCustomEntryStart 20

BOOL g_bIsAdjusting = FALSE;
BOOL g_bIsBuildingList = FALSE;

//#################################################################################
// Sorted ListBox
//#################################################################################
BEGIN_MESSAGE_MAP(CPA_SortedListBox, CListCtrl)
	ON_NOTIFY_REFLECT(LVN_BEGINDRAG, OnBeginDrag)
	ON_NOTIFY_REFLECT(LVN_COLUMNCLICK, OnColumnClicked)
	ON_WM_LBUTTONUP()
	ON_WM_MOUSEMOVE()
	ON_WM_LBUTTONDBLCLK()
	ON_WM_RBUTTONDOWN()
	ON_WM_KEYDOWN()
	ON_WM_KEYUP()
	ON_WM_DRAWITEM()
	ON_WM_SIZE()
END_MESSAGE_MAP()

/*----------------------------------------
	Constructor
----------------------------------------*/
CPA_SortedListBox::CPA_SortedListBox (void)
{
	// init parameters
	m_pOwnerEditor = NULL;
	m_pParentDialog = NULL;
	m_pSortedList = NULL;
	m_pIconList = NULL;
	m_pStateList = NULL;
	// init styles
	m_eCurrentOrder = E_lo_Alpha;
	m_bDisplayGray = TRUE;
	m_lDrawStyle = C_lDrawNothing;
	m_lNbColumns = 0;
	m_bHeaders = TRUE;
	m_bAdjustSize = TRUE;
	// init permissions
	m_bCanChangeOrder = TRUE;
	m_bCanChangeDisplay = TRUE;
	m_bCanChangeDrawStyle = TRUE;
	m_bCanChangeHeaders = TRUE;
	m_bCanDragDrop = TRUE;
	// init state
	m_bIsSelecting = FALSE;
	m_iDraggedItem = -1;
	m_iTargetItem = -1;
}


/*----------------------------------------
	Set list
----------------------------------------*/
void CPA_SortedListBox::SetSortedList (CPA_BaseObjectList *pSortedList)
{
	m_pSortedList = pSortedList;
	fn_vReinitListObjects();
}

/*----------------------------------------
	Set icons
----------------------------------------*/
void CPA_SortedListBox::SetIconList (CImageList *pIconList, BOOL bUpdate)
{
	// user icon list
	m_pIconList = pIconList;
	SetImageList(pIconList, LVSIL_SMALL);

	if (bUpdate)
		fn_vReinitListObjects();
}

/*----------------------------------------
	Set icons
----------------------------------------*/
void CPA_SortedListBox::SetStateList (CImageList *pStateList, BOOL bUpdate)
{
	// user icon list
	m_pStateList = pStateList;
	SetImageList(pStateList, LVSIL_STATE);

	if (bUpdate)
		fn_vReinitListObjects();
}

/*----------------------------------------
	Set order
----------------------------------------*/
void CPA_SortedListBox::SetOrder (tdeListOrder eNewOrder, BOOL bCanChange, BOOL bUpdateList)
{
	// update order
	m_bCanChangeOrder = bCanChange;
	m_eCurrentOrder = eNewOrder;

	if (!bUpdateList)
		return;
	
	// update list
	if (m_pParentDialog)
	{
		m_pParentDialog->GetCurrentList()->SetOrder(eNewOrder);
		m_pParentDialog->fn_vInitListObjects();
	}
	else
		fn_vReinitListObjects();
}

/*----------------------------------------
	Set column headers
----------------------------------------*/
void CPA_SortedListBox::SetColumnHeaders (BOOL bHeaders, BOOL bCanChange, BOOL bUpdateList)
{
	if (bHeaders)
		ModifyStyle(LVS_NOCOLUMNHEADER, 0);
	else
		ModifyStyle(0, LVS_NOCOLUMNHEADER);

	m_bHeaders = bHeaders;
}

/*----------------------------------------
	Set draw style
----------------------------------------*/
void CPA_SortedListBox::SetDrawStyle (long lNewStyle, BOOL bCanChange, BOOL bUpdateList)
{
	int			iInd;
	
	// update flag
	m_bCanChangeDrawStyle = bCanChange;
	// update style
	if (lNewStyle != m_lDrawStyle)
	{
		// delete old colums
		for (iInd = 0; iInd < m_lNbColumns; iInd++)
			DeleteColumn(m_lNbColumns - iInd - 1);
		// update draw style
		m_lDrawStyle = lNewStyle;
		// init new columns
		iInd = 0;
		// state icon
		if ((m_lDrawStyle & C_lDrawState)&&(m_pStateList))
			InsertColumn(iInd++, "v", LVCFMT_LEFT, -1, -1);
		// item icon
		if ((m_lDrawStyle & C_lDrawIcon)&&(m_pIconList))
			InsertColumn(iInd++, "v", LVCFMT_LEFT, -1, -1);
		// name
		if (m_lDrawStyle & C_lDrawName)
			InsertColumn(iInd++, "v Name", LVCFMT_LEFT, -1, -1);
		// type
		if (m_lDrawStyle & C_lDrawType)
			InsertColumn(iInd++, "v Type", LVCFMT_LEFT, -1, 0);
		// owner
		if (m_lDrawStyle & C_lDrawOwner)
			InsertColumn(iInd++, "v Owner", LVCFMT_LEFT, -1, 1);
		// info
		if (m_lDrawStyle & C_lDrawInfo)
			InsertColumn(iInd++, "Info", LVCFMT_LEFT, -1, 2);
		// init nb of columns
		m_lNbColumns = iInd;
		// init columns size
		fn_vReinitColumnWidth();
	}

	// update list
	if (m_pParentDialog)
		m_pParentDialog->GetCurrentList()->SetStyle(lNewStyle);

	if (!bUpdateList)
		return;

	// update list
	if (m_pParentDialog)
		m_pParentDialog->fn_vInitListObjects();
	else
		fn_vReinitListObjects();
}

/*----------------------------------------
	Set draw style
----------------------------------------*/
void CPA_SortedListBox::SetDisplayGray (BOOL bNewDisplay, BOOL bCanChange, BOOL bUpdateList)
{
	// update style
	m_bCanChangeDisplay = bCanChange;
	m_bDisplayGray = bNewDisplay;

	if (!bUpdateList)
		return;

	// update list
	if (m_pParentDialog)
		m_pParentDialog->fn_vInitListObjects();
	else
		fn_vReinitListObjects();
}

/*----------------------------------------
	Columns 
----------------------------------------*/
void CPA_SortedListBox::fn_vReinitColumnWidth (void)
{
	RECT		rWindow;
	long		lSize, lWidth;
	long		lNbColumns = m_lNbColumns;
	long		lIconSize = 0;
	int			iInd = 0;

	// state column
	if ((m_lDrawStyle & C_lDrawState)&&(m_pStateList))
	{
		lIconSize += 20;
		SetColumnWidth(iInd++, 20);
	}
	// icon column
	if ((m_lDrawStyle & C_lDrawIcon)&&(m_pIconList))
	{
		lIconSize += 20;
		SetColumnWidth(iInd++, 20);
	}
	// init columns size
	GetWindowRect(&rWindow);
	lNbColumns = m_lNbColumns - iInd;
	// get minimal width
	lWidth = rWindow.right - rWindow.left - lIconSize - 2*lNbColumns - 5;
	if (GetCountPerPage() < GetItemCount())
		lWidth = lWidth - 15;
	// adust colums size
	lSize = (m_lNbColumns > 0) ? lWidth / lNbColumns : 0;
	while (iInd < m_lNbColumns)
		SetColumnWidth(iInd++, lSize);
}

/*----------------------------------------
	List 
----------------------------------------*/
void CPA_SortedListBox::fn_vReinitListObjects (void)
{
	CPA_BaseObject *pElem;
	BOOL			bRes;
	long			lIndex, lRealIndex;
	int				iPos = 0;

	// RAZ
	DeleteAllItems();
	if (!m_pSortedList)
		return;

	// update list in case of changes
//	m_pSortedList->fn_vUpdateSortedList();
	// for size
	g_bIsBuildingList = TRUE;

	// look for instances of selected descriptor
	for (lIndex = 0, lRealIndex = 0; lIndex < m_pSortedList->GetCount(); lIndex++)
	{
		pElem = m_pSortedList->GetObjectWithIndex(lRealIndex, GetOrder());
		// test function
		if (m_pParentDialog)
			bRes = m_pParentDialog->fn_bCanInsertElement(pElem);
		else
			bRes = ((pElem->fn_bIsAvailable())||(m_bDisplayGray));

		if ((bRes)&&(pElem->fn_bIsValid()))
		{
			// insert item
			iPos = InsertNewItem(iPos, pElem) + 1;
			lRealIndex++;
		}
		else if (GetOrder() == E_lo_Common)
			m_pSortedList->fn_bChangeObjectOrder(pElem, m_pSortedList->GetCount() - 1, E_lo_Common);
		else
			lRealIndex++;
	}
	// for size
	g_bIsBuildingList = FALSE;
}

/*----------------------------------------
	Insertion
----------------------------------------*/
int CPA_SortedListBox::InsertNewItem (int iNumItem, CPA_BaseObject *pElem)
{
	int			iNumIcon, iPos;

	// get icon
	iNumIcon = GetCorrespondingIcon(pElem);
	
	// insert item and set data
	iPos = InsertItem(iNumItem, pElem->GetNameToDraw(), iNumIcon);
	SetItemData(iPos, (DWORD) pElem);

	return iPos;
}

/*----------------------------------------
	Selection
----------------------------------------*/
void CPA_SortedListBox::SetSelectedItem (int iNumItem)
{
	int iInd;
	
	// set flag
	m_bIsSelecting = TRUE;
	
	// select item
	if (iNumItem != -1)
	{
		SetItemState(iNumItem, LVIS_SELECTED, LVIS_SELECTED);
		EnsureVisible(iNumItem, TRUE);
	}
	// unselect item
	else
	{
		iInd = GetNextItem(-1, LVNI_SELECTED);
		if (iInd != -1)
			SetItemState(iInd, 0, LVIS_SELECTED);
	}

	m_iSelectedItem = iNumItem;

	// update flag
	m_bIsSelecting = FALSE;
}
	
/*----------------------------------------
	Selection
----------------------------------------*/
int	CPA_SortedListBox::GetSelectedItem (void)
{
	return GetNextItem(-1, LVNI_SELECTED);
}


/*----------------------------------------
	Popup Menu
----------------------------------------*/
void CPA_SortedListBox::OnRButtonDown(UINT nFlags, CPoint point) 
{
	BOOL bEntry		= FALSE;
	BOOL bCustom	= FALSE;
	
	ClientToScreen( &point );
	// create popup menu	
	CMenu oMenu;
	oMenu.CreatePopupMenu();

	// Headers 
	if (m_bCanChangeHeaders)
	{
		oMenu.AppendMenu( MF_STRING | ((m_bHeaders)?MF_CHECKED:MF_UNCHECKED), C_uiHeaderEntry, "Headers");
		bEntry = TRUE;
	}
	// Auto Size
	if ((m_lNbColumns != 2) || (m_bCanChangeDrawStyle))
	{
		oMenu.AppendMenu( MF_STRING | ((m_bAdjustSize)?MF_CHECKED:MF_UNCHECKED), C_uiAutoAdjustEntry, "Adjust Size");
		bEntry = TRUE;
	}

	// Draw Style
	if (m_bCanChangeDrawStyle)
	{
		// separator
		if (bEntry)
			oMenu.AppendMenu(MF_SEPARATOR);
		// entries to change draw style
		if (m_pStateList)
			oMenu.AppendMenu( MF_STRING | ((m_lDrawStyle & C_lDrawState)?MF_CHECKED:MF_UNCHECKED), C_uiDrawStateEntry, "State");
		if (m_pIconList)
			oMenu.AppendMenu( MF_STRING | ((m_lDrawStyle & C_lDrawIcon)?MF_CHECKED:MF_UNCHECKED), C_uiDrawIconEntry, "Icon");
		oMenu.AppendMenu( MF_STRING | ((m_lDrawStyle & C_lDrawType)?MF_CHECKED:MF_UNCHECKED), C_uiDrawTypeEntry, "Type");
		oMenu.AppendMenu( MF_STRING | ((m_lDrawStyle & C_lDrawOwner)?MF_CHECKED:MF_UNCHECKED), C_uiDrawOwnerEntry, "Owner");
		oMenu.AppendMenu( MF_STRING | ((m_lDrawStyle & C_lDrawInfo)?MF_CHECKED:MF_UNCHECKED), C_uiDrawInfoEntry, "Info");
		bEntry = TRUE;
	}

	// Order
	if (m_bCanChangeOrder)
	{
		// separator
		if (bEntry)
			oMenu.AppendMenu(MF_SEPARATOR);
		// entries to change display order
		oMenu.AppendMenu( MF_STRING | ((m_eCurrentOrder == E_lo_Alpha)?MF_CHECKED:MF_UNCHECKED), C_uiSortAlphaEntry, "Alphabetic");
		oMenu.AppendMenu( MF_STRING | ((m_eCurrentOrder == E_lo_Common)?MF_CHECKED:MF_UNCHECKED), C_uiSortCommonEntry, "Common");
		oMenu.AppendMenu( MF_STRING | ((m_eCurrentOrder == E_lo_Edited)?MF_CHECKED:MF_UNCHECKED), C_uiSortEditedEntry, "Edited");
		bEntry = TRUE;
	}

	// Invalid Objects
	if (m_bCanChangeDisplay)
	{
		// separator
		if (bEntry)
			oMenu.AppendMenu(MF_SEPARATOR);
		// entry to change display mode
		oMenu.AppendMenu( MF_STRING | ((m_bDisplayGray)?MF_CHECKED:MF_UNCHECKED), C_uiDisplayAllEntry, "Display All");
	}

	// separator
	if (bEntry)
		oMenu.AppendMenu(MF_SEPARATOR);
	// Custom Entries
	if (m_pParentDialog)
		bCustom = m_pOwnerEditor->fn_bAddEntriesToListPopup(m_pParentDialog, m_pParentDialog->GetCurrentType(), &oMenu, C_uiCustomEntryStart);
	else
		bCustom = m_pOwnerEditor->fn_bAddEntriesToListPopup(this, m_pSortedList, &oMenu, C_uiCustomEntryStart);
	// no custom entries => remove separator
	if (!bCustom)
		oMenu.DeleteMenu(oMenu.GetMenuItemCount() - 1, MF_BYPOSITION); 
	
	// display & track popup menu
	if ((bEntry)||(bCustom))
    {
        TUT_M_vGetTutDll    ();
        TUT_M_vRegisterMenu (this -> m_hWnd , oMenu . m_hMenu , point . x , point . y);
		oMenu.TrackPopupMenu( TPM_LEFTALIGN | TPM_RIGHTBUTTON, point.x, point.y, this);
    }
	// destroy menus
	oMenu.DestroyMenu();
}

/*----------------------------------------
	Answer to Popup
----------------------------------------*/
BOOL CPA_SortedListBox::OnCommand( WPARAM wParam, LPARAM lParam )
{
	// command from a menu ?
	if (HIWORD(wParam) == 0) 
	{
		// ID of menu item ?
		switch (LOWORD(wParam)) 
		{
			// column headers
			case C_uiHeaderEntry:
				if (m_bHeaders)
					SetColumnHeaders(FALSE);
				else
					SetColumnHeaders(TRUE);
				break;

			case C_uiAutoAdjustEntry:
				SetAdjustSize(!m_bAdjustSize);
				break;

			// draw style
			case C_uiDrawStateEntry:
				if (m_lDrawStyle & C_lDrawState)
					SetDrawStyle(m_lDrawStyle - C_lDrawState);
				else
					SetDrawStyle(m_lDrawStyle + C_lDrawState);
				break;
			case C_uiDrawIconEntry:
				if (m_lDrawStyle & C_lDrawIcon)
					SetDrawStyle(m_lDrawStyle - C_lDrawIcon);
				else
					SetDrawStyle(m_lDrawStyle + C_lDrawIcon);
				break;
			case C_uiDrawTypeEntry:
				if (m_lDrawStyle & C_lDrawType)
					SetDrawStyle(m_lDrawStyle - C_lDrawType);
				else
					SetDrawStyle(m_lDrawStyle + C_lDrawType);
				break;
			case C_uiDrawOwnerEntry:
				if (m_lDrawStyle & C_lDrawOwner)
					SetDrawStyle(m_lDrawStyle - C_lDrawOwner);
				else
					SetDrawStyle(m_lDrawStyle + C_lDrawOwner);
				break;
			case C_uiDrawInfoEntry:
				if (m_lDrawStyle & C_lDrawInfo)
					SetDrawStyle(m_lDrawStyle - C_lDrawInfo);
				else
					SetDrawStyle(m_lDrawStyle + C_lDrawInfo);
				break;

			// list order
			case C_uiSortAlphaEntry:
				SetOrder(E_lo_Alpha);
				break;
			case C_uiSortCommonEntry:
				SetOrder(E_lo_Common);
				break;
			case C_uiSortEditedEntry:
				SetOrder(E_lo_Edited);
				break;

			// list order
			case C_uiDisplayAllEntry:
				SetDisplayGray(!m_bDisplayGray);
				break;
		}
		// custom entries
		if (LOWORD(wParam) >= C_uiCustomEntryStart) 
		{
			if (m_pParentDialog)
				m_pOwnerEditor->fn_vOnCommandInListPopup(m_pParentDialog, m_pParentDialog->GetCurrentType(), LOWORD(wParam) - C_uiCustomEntryStart);
			else
				m_pOwnerEditor->fn_vOnCommandInListPopup(this, m_pSortedList, LOWORD(wParam) - C_uiCustomEntryStart);
		}
	}
	return CListCtrl::OnCommand(wParam, lParam);
}

/*----------------------------------------
	Load
----------------------------------------*/
void CPA_SortedListBox::OnLButtonDblClk(UINT nFlags, CPoint point) 
{
	CPA_BaseObject	*pElem = NULL;
	BOOL			bRedraw;
	BOOL			bRes = FALSE;
	UINT			pFlag;
	int				iSelect;
	
	// get selected element
	iSelect = HitTest(point, &pFlag);
	if (iSelect != -1)
		pElem = (CPA_BaseObject *) GetItemData(iSelect);

	if (m_pParentDialog)
		bRes = m_pOwnerEditor->fn_bOnDblClkListObjects(m_pParentDialog, m_pParentDialog->GetCurrentType(), pElem);

	if ((bRes)||(!m_bDisplayGray))
	{
		CListCtrl::OnLButtonDblClk(nFlags, point);
		return;
	}

	// non available object => load
	if ((pElem)&&(!pElem->fn_bIsAvailable()))
	{
		bRedraw = pElem->GetEditor()->fn_bLoadBaseObject(pElem);
		if (bRedraw)
			SetSelectedItem(iSelect);		
	}
	else
		CListCtrl::OnLButtonDblClk(nFlags, point);
}

/*----------------------------------------
	Init Drag&Drop
----------------------------------------*/
void CPA_SortedListBox::OnBeginDrag (NMHDR* pNMHDR, LRESULT* pResult)
{
	LPNM_LISTVIEW	pNMListView = (LPNM_LISTVIEW)pNMHDR;
		
	if ((m_eCurrentOrder != E_lo_Edited)||(!m_bCanDragDrop))
		m_iDraggedItem = -1;
	else
		m_iDraggedItem = pNMListView->iItem;
}


/*----------------------------------------
	End Drag&Drop
----------------------------------------*/
void CPA_SortedListBox::OnLButtonUp (UINT nFlags, CPoint point)
{
	CPA_BaseObject	*pObjectToDrag;
	CPA_BaseObject	*pTarget;
	int				iOldIndex, iNewIndex;

	// no dragged item => no action
	if (m_iDraggedItem == -1)
	{
		CListCtrl::OnLButtonUp (nFlags, point);
		return;
	}

	// find target
	if ((m_iTargetItem > -1)&&(m_iTargetItem < GetItemCount()))
	{
		// find object current index
		pObjectToDrag = (CPA_BaseObject *) GetItemData(m_iDraggedItem);
		iOldIndex = m_pSortedList->GetIndexOfObject(pObjectToDrag, E_lo_Edited);
		// find target index
		pTarget = (CPA_BaseObject *) GetItemData(m_iTargetItem);
		iNewIndex = m_pSortedList->GetIndexOfObject(pTarget, E_lo_Edited);
		// update order
		m_pSortedList->fn_vChangeObjectOrder(iOldIndex, iNewIndex, E_lo_Edited);
	}

	// update state
	SetItemState(m_iTargetItem, 0, TVIS_DROPHILITED);
	m_iDraggedItem = -1;
	m_iTargetItem = -1;

	// update list
	if (m_pParentDialog)
		m_pParentDialog->fn_vInitListObjects();
	else
		fn_vReinitListObjects();
}



/*----------------------------------------
	Drag&Drop
----------------------------------------*/
void CPA_SortedListBox::OnMouseMove (UINT nFlags, CPoint point)
{
	int		iTarget;
	UINT	pFlag;

	if (m_iDraggedItem == -1)
	{
		CListCtrl::OnMouseMove (nFlags, point);
		return;
	}

	// find target
	iTarget = HitTest(point, &pFlag);
	if (iTarget != m_iTargetItem)
	{
		// update old target
		if (m_iTargetItem)
			SetItemState(m_iTargetItem, 0, TVIS_DROPHILITED);
		// update new target
		m_iTargetItem = iTarget;
		if (m_iTargetItem)
			SetItemState(m_iTargetItem, TVIS_DROPHILITED, TVIS_DROPHILITED);
	}
}

/*----------------------------------------
	KeyDown
----------------------------------------*/
void CPA_SortedListBox::OnKeyDown (UINT nChar, UINT nRepCnt, UINT nFlags)
{
	if (m_pParentDialog && !m_pParentDialog->fn_bOnKeyDownInControl(nChar, nRepCnt, nFlags))
		CListCtrl::OnKeyDown(nChar, nRepCnt, nFlags);
	else
		fn_vOnKeyDown(nChar, nRepCnt, nFlags);
}

/*----------------------------------------
	KeyUp
----------------------------------------*/
void CPA_SortedListBox::OnKeyUp (UINT nChar, UINT nRepCnt, UINT nFlags)
{
	if (m_pParentDialog && !m_pParentDialog->fn_bOnKeyUpInControl(nChar, nRepCnt, nFlags))
		CListCtrl::OnKeyUp(nChar, nRepCnt, nFlags);
}

/*----------------------------------------
	GetIndex
----------------------------------------*/
int CPA_SortedListBox::GetCorrespondingIndex (DWORD pElem)
{
	DWORD	pData;
	int		iIndex;

	for (iIndex = 0; iIndex < GetItemCount(); iIndex++)
	{
		pData = GetItemData(iIndex);
		if (pData == pElem)
			return iIndex;
	}
	return -1;
}


/*----------------------------------------
	Get Icon
----------------------------------------*/
int CPA_SortedListBox::GetCorrespondingIcon	(CPA_BaseObject *pObject)
{
	if (m_pParentDialog)
		return m_pOwnerEditor->GetIconForListItem(m_pParentDialog, m_pParentDialog->GetCurrentType(), pObject);
	else
		return m_pOwnerEditor->GetIconForListItem(this, m_pSortedList, pObject);
}

/*----------------------------------------
	Get State
----------------------------------------*/
int CPA_SortedListBox::GetCorrespondingState (CPA_BaseObject *pObject)
{
	if (m_pParentDialog)
		return m_pOwnerEditor->GetStateForListItem(m_pParentDialog, m_pParentDialog->GetCurrentType(), pObject);
	else
		return m_pOwnerEditor->GetStateForListItem(this, m_pSortedList, pObject);
}

/*----------------------------------------
	Get Colors
----------------------------------------*/
BOOL CPA_SortedListBox::GetCorrespondingColors (CPA_BaseObject *pObject, COLORREF *pRectColor, COLORREF *pTextColor) 
{
	if (m_pParentDialog)
		return m_pOwnerEditor->GetColorsForListItem(m_pParentDialog, m_pParentDialog->GetCurrentType(), 
													pObject, pRectColor, pTextColor);
	else
		return m_pOwnerEditor->GetColorsForListItem(this, m_pSortedList, pObject, pRectColor, pTextColor);
}

/*----------------------------------------
	Get Info
----------------------------------------*/
CString CPA_SortedListBox::GetCorrespondingInfo (CPA_BaseObject *pObject)
{
	if (m_pParentDialog)
		return m_pOwnerEditor->GetInfoForListItem(m_pParentDialog, m_pParentDialog->GetCurrentType(), pObject);
	else
		return m_pOwnerEditor->GetInfoForListItem(this, m_pSortedList, pObject);
}

/*----------------------------------------
	Owner Draw List
----------------------------------------*/
void CPA_SortedListBox::SetOwnerDrawStyle (BOOL bOwnerDraw)
{
	if (bOwnerDraw)
		ModifyStyle(0, LVS_OWNERDRAWFIXED);
	else
		ModifyStyle(LVS_OWNERDRAWFIXED, 0);
}


/*----------------------------------------
	Adjust colums width 
----------------------------------------*/
void CPA_SortedListBox::SetAdjustSize (BOOL bAdjust)
{
	m_bAdjustSize = bAdjust;

	if (m_bAdjustSize)
	{
		fn_vReinitColumnWidth();
		fn_vReinitListObjects();
		SetSelectedItem(m_iSelectedItem);
	}
}

/*----------------------------------------
	Adjust colums width when size changes
----------------------------------------*/
void CPA_SortedListBox::OnSize (UINT nType, int cx, int cy)
{
	if (!g_bIsBuildingList)
	{
		if ((m_bAdjustSize)&&(!g_bIsAdjusting))
		{
			g_bIsAdjusting = TRUE;
			fn_vReinitColumnWidth();
			fn_vReinitListObjects();
			SetSelectedItem(m_iSelectedItem);
			g_bIsAdjusting = FALSE;
		}
		else
			CListCtrl::OnSize(nType, cx, cy);
	}
}


/*----------------------------------------
	Disable Icon
----------------------------------------*/
void CPA_SortedListBox::fn_vDisableIcon (CDC *pDC, POINT pt, COLORREF cRectColor)
{
	int i, j;

	for (i = 0; i < 17; i+=2)
	{
		for (j = 0; j < 17 ; j+=2)
		{
			pDC->SetPixelV(pt.x + i, pt.y + j, cRectColor);
		}
	}
}

/*----------------------------------------
	Draw Item
----------------------------------------*/
void CPA_SortedListBox::DrawItem (LPDRAWITEMSTRUCT lpDIS)
{
	CPA_BaseObject	*pElem;
 	COLORREF		cTextColor;
	COLORREF		cRectColor;
	CString			csInfo;
	POINT			pt;
	RECT			rcItem;
	BOOL			bRes;
	CDC				*pDC;
	int				iNumIcon, iState, iInd = 0;

	// get element
	pElem = (CPA_BaseObject *) GetItemData(lpDIS->itemID);
	if (!pElem)
		return;

	// get icon
	if ((m_pIconList)&&(m_lDrawStyle & C_lDrawIcon))
		iNumIcon = GetCorrespondingIcon(pElem);
	// get state
	if ((m_pStateList)&&(m_lDrawStyle & C_lDrawState))
		iState = GetCorrespondingState(pElem);

	// get colors
	bRes = GetCorrespondingColors(pElem, &cRectColor, &cTextColor);
	if (!bRes)
	{
		if (lpDIS->itemState & ODS_SELECTED)
		{
			cRectColor = RGB (0, 0, 254);
			cTextColor = (pElem->fn_bIsAvailable()) ? RGB(254, 254, 254) : RGB(126, 126, 126);
		}
		else if ((int)lpDIS->itemID == m_iTargetItem)
		{
			cRectColor = RGB (0, 0, 0);
			cTextColor = (pElem->fn_bIsAvailable()) ? RGB(254, 254, 254) : RGB(126, 126, 126);
		}
		else
		{
			cRectColor = RGB (254, 254, 254);
			cTextColor = (pElem->fn_bIsAvailable()) ? RGB(0, 0, 0) : RGB(126, 126, 126);
		}
	}

    // drawing parameters
	pDC = CDC::FromHandle(lpDIS->hDC);
	pt.x = lpDIS->rcItem.left;
	pt.y = lpDIS->rcItem.top;
	// draw background
	pDC->FillSolidRect(&lpDIS->rcItem, cRectColor);
    pDC->SetBkMode(TRANSPARENT);
	pDC->SetTextColor(cTextColor);

	// if necessary, draw state icon
	if ((m_pStateList)&&(m_lDrawStyle & C_lDrawState))
	{
		m_pStateList->SetBkColor(cRectColor);
		m_pStateList->Draw(pDC, iState, pt, ILD_NORMAL);
		if (!pElem->fn_bIsAvailable())
			fn_vDisableIcon(pDC, pt, cRectColor);
		pt.x += 20;
		iInd++;
	}
	// draw icon
	if ((m_pIconList)&&(m_lDrawStyle & C_lDrawIcon))
	{
		m_pIconList->SetBkColor(cRectColor);
		m_pIconList->Draw(pDC, iNumIcon, pt, ILD_NORMAL);
		if (!pElem->fn_bIsAvailable())
			fn_vDisableIcon(pDC, pt, cRectColor);
		pt.x += 20;
		iInd++;
	}

	// draw name
	rcItem = lpDIS->rcItem;
	rcItem.left = pt.x;
	rcItem.right = rcItem.left + GetColumnWidth(iInd++) - 5;
	pDC->DrawText(pElem->GetNameToDraw(), &rcItem, DT_SINGLELINE | DT_LEFT | DT_VCENTER);

	// draw type
	if (m_lDrawStyle & C_lDrawType)
	{
		rcItem.left = rcItem.right + 5;
		rcItem.right = rcItem.left + GetColumnWidth(iInd++) - 5;
		pDC->DrawText(pElem->GetTypeToDraw(), &rcItem, DT_SINGLELINE | DT_LEFT | DT_VCENTER);
	}
	// owner
	if (m_lDrawStyle & C_lDrawOwner)
	{
		rcItem.left = rcItem.right + 5;
		rcItem.right = rcItem.left + GetColumnWidth(iInd++) - 5;
		pDC->DrawText(pElem->GetOwnerToDraw(), &rcItem, DT_SINGLELINE | DT_LEFT | DT_VCENTER);
	}
	// info
	if (m_lDrawStyle & C_lDrawInfo)
	{
		rcItem.left = rcItem.right + 5;
		rcItem.right = rcItem.left + GetColumnWidth(iInd++) - 5;
		csInfo = GetCorrespondingInfo(pElem);
		pDC->DrawText(csInfo, &rcItem, DT_SINGLELINE | DT_LEFT | DT_VCENTER);
	}
}


/*----------------------------------------
	Update order when column is clicked
----------------------------------------*/
void CPA_SortedListBox::OnColumnClicked (NMHDR* pNMHDR, LRESULT* pResult)
{
	LPNM_LISTVIEW	pNMListView = (LPNM_LISTVIEW)pNMHDR;
	tdeSortCriteria	eCriteria;
	int				iNumColumn;
		
	if (!m_bCanChangeOrder)
		return;
	
	if (pNMListView->iItem != -1)
		return;
	
	// get corresponding column
	iNumColumn = pNMListView->iSubItem;
	eCriteria = GetColumnType(iNumColumn);
	if (eCriteria == E_sc_None)
		return;

	// update list order
	fn_vSortListByCriteria(eCriteria);
	SetOrder(E_lo_Edited);
}

/*----------------------------------------
	Get Column Type from number
----------------------------------------*/
tdeSortCriteria CPA_SortedListBox::GetColumnType (int iNumColumn)
{
	int iInd = 0;

	// state ?
	if ((m_lDrawStyle & C_lDrawState)&&(m_pStateList))
	{
		if (iInd++ == iNumColumn)
			return E_sc_State;
	}
	// icon ?
	if ((m_lDrawStyle & C_lDrawIcon)&&(m_pIconList))
	{
		if (iInd++ == iNumColumn)
			return E_sc_Icon;
	}
	// name
	if (iInd++ == iNumColumn)
		return E_sc_Name;

	if (m_lDrawStyle & C_lDrawType)
	{
		if (iInd++ == iNumColumn)
			return E_sc_Type;
	}

	if (m_lDrawStyle & C_lDrawOwner)
	{
		if (iInd++ == iNumColumn)
			return E_sc_Owner;
	}

	return E_sc_None;
}

/*----------------------------------------
	Index By State To Draw
----------------------------------------*/
int CPA_SortedListBox::GetIndexByStateToDraw (CPA_BaseObject *pObject)
{
	CPA_BaseObject		*pElem;
	CString				csName, csNameRef;
	int					iState, iStateRef;
	int					iInd;

	iStateRef = GetCorrespondingState(pObject);
	csNameRef = pObject->GetNameToDraw();

	for (iInd = 0; iInd < m_pSortedList->GetCount(); iInd++)
	{
		pElem = m_pSortedList->GetObjectWithIndex(iInd, E_lo_Edited);
		// get icon
		csName = pElem->GetNameToDraw();
		iState = GetCorrespondingState(pElem);
	
		if (iState > iStateRef)
			return iInd;
		if ((iState == iStateRef)&&(csName >= csNameRef))
			return iInd;
	}

	return (m_pSortedList->GetCount() - 1);
}

/*----------------------------------------
	Index By Icon To Draw
----------------------------------------*/
int CPA_SortedListBox::GetIndexByIconToDraw (CPA_BaseObject *pObject)
{
	CPA_BaseObject		*pElem;
	CString				csName, csNameRef;
	int					iIcon, iIconRef;
	int					iInd;

	iIconRef = GetCorrespondingIcon(pObject);
	csNameRef = pObject->GetNameToDraw();

	for (iInd = 0; iInd < m_pSortedList->GetCount(); iInd++)
	{
		pElem = m_pSortedList->GetObjectWithIndex(iInd, E_lo_Edited);
		// get icon
		iIcon = GetCorrespondingIcon(pElem);
		csName = pElem->GetNameToDraw();
	
		if (iIcon > iIconRef)
			return iInd;
		if ((iIcon == iIconRef)&&(csName >= csNameRef))
			return iInd;
	}

	return (m_pSortedList->GetCount() - 1);
}

/*----------------------------------------
	Index By Name To Draw
----------------------------------------*/
int CPA_SortedListBox::GetIndexByNameToDraw (CPA_BaseObject *pObject)
{
	CPA_BaseObject		*pElem;
	CString				csName, csNameRef;
	int					iInd;

	csNameRef = pObject->GetNameToDraw();
	
	for (iInd = 0; iInd < m_pSortedList->GetCount(); iInd++)
	{
		pElem = m_pSortedList->GetObjectWithIndex(iInd, E_lo_Edited);
		csName = pElem->GetNameToDraw();
	
		if (csName >= csNameRef)
			return iInd;
	}
	return (m_pSortedList->GetCount() - 1);
}


/*----------------------------------------
	Index By Type To Draw
----------------------------------------*/
int CPA_SortedListBox::GetIndexByTypeToDraw (CPA_BaseObject *pObject)
{
	CPA_BaseObject		*pElem;
	CString				csType, csTypeRef;
	CString				csName, csNameRef;
	int					iInd;

	csTypeRef = pObject->GetTypeToDraw();
	csNameRef = pObject->GetNameToDraw();
	
	for (iInd = 0; iInd < m_pSortedList->GetCount(); iInd++)
	{
		pElem = m_pSortedList->GetObjectWithIndex(iInd, E_lo_Edited);
		csType = pElem->GetTypeToDraw();
		csName = pElem->GetNameToDraw();
	
		if (csType > csTypeRef)
			return iInd;
		if ((csType == csTypeRef)&&(csName >= csNameRef))
			return iInd;
	}

	return (m_pSortedList->GetCount() - 1);
}

/*----------------------------------------
	Index By Owner To Draw
----------------------------------------*/
int CPA_SortedListBox::GetIndexByOwnerToDraw (CPA_BaseObject *pObject)
{
	CPA_BaseObject		*pElem;
	CString				csOwner, csOwnerRef;
	CString				csName, csNameRef;
	int					iInd;

	csOwnerRef = pObject->GetOwnerToDraw();
	csNameRef = pObject->GetNameToDraw();
	
	for (iInd = 0; iInd < m_pSortedList->GetCount(); iInd++)
	{
		pElem = m_pSortedList->GetObjectWithIndex(iInd, E_lo_Edited);
		csOwner = pElem->GetOwnerToDraw();
		csName = pElem->GetNameToDraw();
	
		if (csOwner > csOwnerRef)
			return iInd;
		if ((csOwner == csOwnerRef)&&(csName >= csNameRef))
			return iInd;
	}

	return (m_pSortedList->GetCount() - 1);
}


/*----------------------------------------
	Resort List
----------------------------------------*/
void CPA_SortedListBox::fn_vSortListByCriteria(tdeSortCriteria eCriteria)
{
	CPA_BaseObject		*pElem;
	int					iInd, iNewInd;

	for (iInd = 0; iInd < m_pSortedList->GetCount(); iInd++)
	{
		pElem = m_pSortedList->GetObjectWithIndex(iInd, E_lo_Alpha);
		switch (eCriteria)
		{
			case E_sc_State:
				iNewInd = GetIndexByStateToDraw(pElem);
				break;
			case E_sc_Icon:
				iNewInd = GetIndexByIconToDraw(pElem);
				break;
			case E_sc_Name:
				iNewInd = GetIndexByNameToDraw(pElem);
				break;
			case E_sc_Type:
				iNewInd = GetIndexByTypeToDraw(pElem);
				break;
			case E_sc_Owner:
				iNewInd = GetIndexByOwnerToDraw(pElem);
				break;
		}
		m_pSortedList->fn_bChangeObjectOrder(pElem, iNewInd, E_lo_Edited);
	}
}



#endif // ACTIVE_EDITOR


