#include "stdafx.h"
#include "AplGuiEx.h"

CaplCheckListCtrl::CaplCheckListCtrl() : m_bOnceChecked(false), m_bOnceRowChecked(false)
{
	CAplGuiExResourceHandleChange rc;

	CBitmap bm;

	bm.LoadBitmap(IDB_CHECK);
	m_il.Create(16, 16, ILC_COLOR24, 5, 5);
	m_il.Add(&bm, RGB(0,0,0));
	bm.DeleteObject();
}

BEGIN_MESSAGE_MAP(CaplCheckListCtrl, CaplListCtrl)
	ON_NOTIFY_REFLECT(NM_CLICK, OnNMClick)
	ON_WM_CREATE()
END_MESSAGE_MAP()

void CaplCheckListCtrl::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
	CDC dc;
	dc.Attach(lpDrawItemStruct->hDC);

	COLORREF oldTextColor;
	CRect rect;

	rect = lpDrawItemStruct->rcItem;
	if(lpDrawItemStruct->itemState&ODS_SELECTED)
	{
		if(IsWindowEnabled() && GetFocus()==this)
		{
			dc.FillSolidRect(rect, ::GetSysColor(COLOR_HIGHLIGHT));
			oldTextColor = dc.SetTextColor(::GetSysColor(COLOR_HIGHLIGHTTEXT));
		}
		else
		{
			dc.FillSolidRect(rect, ::GetSysColor(COLOR_MENU));
			oldTextColor = dc.SetTextColor(::GetSysColor(COLOR_WINDOWTEXT));
		}
	}
	else
	{
		dc.FillSolidRect(rect, ::GetSysColor(COLOR_WINDOW));
		oldTextColor = dc.SetTextColor(::GetSysColor(COLOR_WINDOWTEXT));
	}
	if(lpDrawItemStruct->itemState&ODS_FOCUS)
		dc.DrawFocusRect(rect);

	int i, cnt, j;
	for(j=0; j<m_items.GetSize(); j++)
	{
		if(m_items[j].m_Item==(int)lpDrawItemStruct->itemID && m_items[j].m_SubItem==-1)
			dc.FillSolidRect(rect, m_items[j].m_BkColor);
	}

	cnt = GetHeaderCtrl()->GetItemCount();
	for(i=0; i<cnt; i++)
	{
		GetSubItemRect(lpDrawItemStruct->itemID, i, LVIR_LABEL, rect);
		rect.DeflateRect(2, 0, 2, 0);

		if (IsCheck(lpDrawItemStruct->itemID, i))
		{
			aplCheckValue iCheck = GetCheck(lpDrawItemStruct->itemID, i);

			CImageList *pIm = GetImageList(LVSIL_SMALL);
			if (pIm==NULL)
			{
				SetImageList(&m_il, LVSIL_SMALL);
				pIm = GetImageList(LVSIL_SMALL);
			}
			if (iCheck==aplCheckSet)
			{
				if (pIm)
					pIm->DrawIndirect(&dc,0, CPoint((int)(.5*(rect.left+rect.right)),rect.top),CSize(16,16),CPoint(0,0));
			}
			else if (iCheck==aplCheckNo)
			{
				if (pIm)
					pIm->DrawIndirect(&dc,1, CPoint((int)(.5*(rect.left+rect.right)),rect.top),CSize(16,16),CPoint(0,0));
			}
			else if (iCheck==aplCheckEnabled)
			{
				if (pIm)
					pIm->DrawIndirect(&dc,2, CPoint((int)(.5*(rect.left+rect.right)),rect.top),CSize(16,16),CPoint(0,0));
			}
			else if (iCheck==aplCheckDisabled)
			{
				if (pIm)
					pIm->DrawIndirect(&dc,3, CPoint((int)(.5*(rect.left+rect.right)),rect.top),CSize(16,16),CPoint(0,0));
			}
			else if (iCheck==aplCheckEmpty)
			{
				if (pIm)
					pIm->DrawIndirect(&dc,4, CPoint((int)(.5*(rect.left+rect.right)),rect.top),CSize(16,16),CPoint(0,0));
			}
			rect.DeflateRect(18, 0, 0, 0);
		}
		for(j=0; j<m_items.GetSize(); j++)
		{
			if(m_items[j].m_Item==(int)lpDrawItemStruct->itemID && m_items[j].m_SubItem==i)
			{
				dc.FillSolidRect(rect, m_items[j].m_BkColor);
				break;
			}
		}
		dc.DrawText(GetItemText(lpDrawItemStruct->itemID, i), &rect, DT_LEFT);
	}
	dc.SetTextColor(oldTextColor);
	dc.Detach();
}

void CaplCheckListCtrl::OnNMClick(NMHDR *pNMHDR, LRESULT *pResult)
{
	LPNMITEMACTIVATE pNMItemActivate = reinterpret_cast<LPNMITEMACTIVATE>(pNMHDR);
	// TODO: Add your control notification handler code here
	int iItem = pNMItemActivate->iItem;
	if (iItem<0)
		return;
	int iSubItem = pNMItemActivate->iSubItem;
	if (iSubItem<0)
		return;

	if (IsCheck(iItem, iSubItem))
	{
		aplCheckValue iCheck = GetCheck(iItem, iSubItem);
		if (iCheck<=aplCheckSet)
		{
			iCheck = (iCheck==aplCheckSet)? aplCheckNo:aplCheckSet;
/*
			int nSelItem = GetNextItem(-1, LVNI_ALL|LVNI_SELECTED);
			while(nSelItem!=-1)
			{
				if (IsCheck(nSelItem, iSubItem))
					SetCheck(nSelItem, iSubItem, iCheck);
				nSelItem = GetNextItem(nSelItem, LVNI_ALL|LVNI_SELECTED);
			}
*/
			SetCheck(iItem, iSubItem, iCheck);
			if (m_bOnceChecked && iCheck==aplCheckSet)
			{
				for(int i=0; i<m_columns.GetSize(); ++i)
				{
					if (m_columns[i].nItem != iItem)
						continue;

					if (m_columns[i].nCol != iSubItem)
						m_columns[i].m_check =  aplCheckNo;
				}
			}
			if (m_bOnceRowChecked && iCheck==aplCheckSet)
			{
				for(int i=0; i<GetItemCount(); ++i)
				{
					if (i!=iItem)
						SetCheck(i, iSubItem, aplCheckNo);
				}
			}
		}
	}

	Invalidate();

	CWnd* pWnd = GetParent();
	if(pWnd && ::IsWindow(pWnd->m_hWnd))
	{
		NMLISTVIEW nmListView;
		memset(&nmListView, 0, sizeof(NMLISTVIEW));
		nmListView.hdr.idFrom = GetDlgCtrlID();
		nmListView.hdr.code = APL_LC_AFTER_END_EDIT_MESSAGE;
		nmListView.hdr.hwndFrom = m_hWnd;

		nmListView.iItem = m_EditItem;
		nmListView.iSubItem = m_EditCol;

		pWnd->SendMessage(WM_NOTIFY, (WPARAM)GetDlgCtrlID(), (LPARAM)&nmListView);
	}

	*pResult = 0;
}

void CaplCheckListCtrl::SetCheck(int iRow, int iCol, aplCheckValue iCheck/*=aplCheckNo*/)
{
	if (iRow<-1)
		return;
	if (iCol<0)
		return;
	for(int i=0; i<m_columns.GetSize(); ++i)
	{
		if (m_columns[i].nItem != iRow)
			continue;

		if (m_columns[i].nCol!=iCol)
			continue;

		m_columns[i].m_check = iCheck;
		return;
	}

	SetItemEditType(iRow, iCol, aplNone, NULL, NULL, iCheck);
}

aplCheckValue CaplCheckListCtrl::GetCheck(int iRow, int iCol)
{
	if (iRow<-1)
		return aplCheckEmpty;
	if (iCol<0)
		return aplCheckEmpty;
	for(int i=0; i<m_columns.GetSize(); ++i)
	{
		if (m_columns[i].nItem != iRow)
			continue;

		if (m_columns[i].nCol!=iCol)
			continue;

		return m_columns[i].m_check;
	}

	return aplCheckEmpty;
}

bool CaplCheckListCtrl::IsCheck(int iRow, int iCol)
{
	if (iRow<-1)
		return false;
	if (iCol<0)
		return false;
	for(int i=0; i<m_columns.GetSize(); ++i)
	{
		if (m_columns[i].nItem != iRow)
			continue;

		if (m_columns[i].nCol!=iCol)
			continue;

		return m_columns[i].m_check!=aplCheckEmpty;
	}

	return false;
}

int CaplCheckListCtrl::InsertItem(const LVITEM* pItem)
{
	SetCheck(pItem->iItem, -1);

	return CaplListCtrl::InsertItem(pItem);
}

int CaplCheckListCtrl::InsertItem(int nItem, LPCTSTR lpszItem)
{
	SetCheck(nItem, -1);

	return CaplListCtrl::InsertItem(nItem, lpszItem);
}

int CaplCheckListCtrl::InsertItem(int nItem, LPCTSTR lpszItem, int nImage)
{
	SetCheck(nItem, -1);

	return CaplListCtrl::InsertItem(nItem, lpszItem, nImage);
}

int CaplCheckListCtrl::InsertItem(UINT nMask, int nItem, LPCTSTR lpszItem, UINT nState,
			   UINT nStateMask, int nImage, LPARAM lParam)
{
	SetCheck(nItem, -1);

	return CaplListCtrl::InsertItem(nMask, nItem, lpszItem, nState, nStateMask, nImage, lParam);
}

//BOOL CaplCheckListCtrl::DeleteItem(int nItem)
//{
//	return CaplListCtrl::DeleteItem(nItem);
//}
