// AsComboBox.cpp : implementation file
//
#include "stdafx.h"
#include "AsComboBox.h"
#include "MemDC.h"
#include "DrawUtils.h"
#include "resource.h"

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

CAsComboBox::CAsComboBox():
	hwndList_(NULL),
	droppedDown_(false),
	dropAreaHeight_(100),
	basicRect_(0,0,0,0)
{
	WNDCLASS wndcls;
    HINSTANCE hInst = AfxGetInstanceHandle();
    //HINSTANCE hInst = AfxGetResourceHandle();

    
	if (!(::GetClassInfo(hInst, _T("AsComboBox"), &wndcls)))
    {
        // otherwise we need to register a new class
        wndcls.style            = CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW;
        wndcls.lpfnWndProc      = ::DefWindowProc;
        wndcls.cbClsExtra       = wndcls.cbWndExtra = 0;
        wndcls.hInstance        = hInst;
        wndcls.hIcon            = NULL;
        wndcls.hCursor          = AfxGetApp()->LoadStandardCursor(IDC_ARROW);
        wndcls.hbrBackground    = (HBRUSH) (COLOR_3DFACE + 1);
        wndcls.lpszMenuName     = NULL;
        wndcls.lpszClassName    = _T("AsComboBox");

        if (!AfxRegisterClass(&wndcls))
        {
            AfxThrowResourceException();
            return;
        }
    }
}

CAsComboBox::~CAsComboBox()
{
}


BEGIN_MESSAGE_MAP(CAsComboBox, CComboBox)
	//{{AFX_MSG_MAP(CAsComboBox)
	ON_CONTROL_REFLECT(CBN_DROPDOWN, OnDropdown)
	ON_CONTROL_REFLECT(CBN_CLOSEUP, OnCloseup)
	ON_WM_CTLCOLOR()
	ON_WM_PAINT()
	ON_CONTROL_REFLECT(CBN_SELCHANGE, OnSelchange)
	ON_WM_KILLFOCUS()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CAsComboBox message handlers

void CAsComboBox::OnDropdown() 
{
	droppedDown_ = true;
	//MessageBox("DropDown");
}

void CAsComboBox::OnCloseup() 
{
	droppedDown_ = false;
}

void CAsComboBox::DrawComboButton(CDC* pDC, CRect clientRect)
{
	CSize bmpSize;
	CRect bmpRect;

	bmpSize = DrawUtils::GetBitmapSize(IDB_COMBO_BOX_NORMAL);

	bmpRect = clientRect;
	bmpRect.left = bmpRect.right - bmpSize.cx - 2;
	bmpRect.top = (bmpRect.Height() - bmpSize.cy) / 2;

	DrawUtils::DrawBitmap(pDC, IDB_COMBO_BOX_NORMAL, bmpRect.TopLeft(), DrawUtils::enBmp_AlignLeft);

	clientRect.DeflateRect(4,0,bmpRect.Width() + 2, 0);
	
	cmString tmp;

	tmp = GetSelString();
	DrawUtils::DrawString(pDC, tmp, clientRect, DT_LEFT | DT_VCENTER | DT_SINGLELINE | DT_NOPREFIX, ::GetSysColor(COLOR_BTNTEXT), GetFont());
}

BOOL CAsComboBox::Create(DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext) 
{
	BOOL ret;

	dwStyle |= (WS_CHILD | CBS_HASSTRINGS | CBS_NOINTEGRALHEIGHT | WS_TABSTOP | WS_VSCROLL | CBS_DROPDOWNLIST/* | CBS_OWNERDRAWFIXED*/);
	
	//ret = CWnd::Create("ComboBox", "Algostar Combo Box", dwStyle, rect, pParentWnd, nID, pContext);
	
	ret = CComboBox::Create(dwStyle, rect, pParentWnd, nID);
	
	if (ret)
		ModifyStyleEx(0, WS_EX_NOPARENTNOTIFY);

	return ret;	
}

HBRUSH CAsComboBox::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) 
{
	if (nCtlColor == CTLCOLOR_LISTBOX) {
		CRect rc;
		int height;

		GetWindowRect(rc);
		if (GetCount())
			height = min(10, sortKeyToValueMap_.size()) * (GetItemHeight(0) + 1);
		else
			height = 100;

		pWnd->SetWindowPos(&CWnd::wndTop, 0, 0, rc.Width(), height, SWP_SHOWWINDOW | SWP_NOMOVE); 
	}
	
	HBRUSH hbr = CComboBox::OnCtlColor(pDC, pWnd, nCtlColor);

	return hbr;
}

void CAsComboBox::Clear()
{
	sortKeyToValueMap_.clear();
	valueToSortKeyMap_.clear();

	ResetContent();
}

void CAsComboBox::AddItem(const cmString& s)
{
	AddItem(s, (long)sortKeyToValueMap_.size());
}

void CAsComboBox::AddItem(const cmString& s, double sortKey)
{
	TCHAR buf[100];

	wsprintf(buf, _T("%10.10f"), sortKey);

	AddItem(s, buf);
}

void CAsComboBox::AddItem(const cmString& s, int sortKey)
{
	TCHAR buf[100];

	wsprintf(buf, _T("%010d"), sortKey);

	AddItem(s, buf);
}

void CAsComboBox::AddItem(const cmString& s, const cmString& sortKey)
{
	sortKeyToValueMap_[sortKey] = s;
	valueToSortKeyMap_[s] = sortKey;

	BuildList();
}

void CAsComboBox::OnPaint() 
{
	CPaintDC dc(this); // device context for painting
	CRect rc;

	GetClientRect(rc);

	if (GetFocus() != this)
		DrawBackground(&dc, rc);
	DrawComboButton(&dc, rc);
}

void CAsComboBox::DrawBackground(CDC* pDC, CRect clientRect)
{
	// draw rect
	//
	CBrush h(::GetSysColor(COLOR_WINDOW));
	//CBrush h(RGB(255,0,0));
	clientRect.DeflateRect(0, 0, 1, 1);
	
	pDC->FillRect(clientRect, &h);
}

void CAsComboBox::BuildList()
{
	CString selString;
	map<cmString, cmString>::iterator it;

	if (GetCurSel() != CB_ERR) {
		GetLBText(GetCurSel(), selString);
	}

	ResetContent();

	for (it = sortKeyToValueMap_.begin(); it != sortKeyToValueMap_.end(); it++) {
		AddString(it->second);
	}
}

void CAsComboBox::SelectItem(double sortKey)
{
	TCHAR buf[100];

	wsprintf(buf, _T("%10.10f"), sortKey);

	SelectItem(buf);
}

void CAsComboBox::SelectItem(int sortKey)
{
	TCHAR buf[100];

	wsprintf(buf, _T("%010d"), sortKey);

	SelectItem(buf);
}

void CAsComboBox::SelectItem(const cmString& sortKey)
{
	map<cmString, cmString>::iterator it;

	it = sortKeyToValueMap_.find(sortKey);
	if (it != sortKeyToValueMap_.end())
		SelectString(-1, it->second);
}

bool CAsComboBox::GetSelKey(double& sortKey)
{
	bool ret;
	cmString s;

	ret = GetSelKey(s);
	sortKey = s;

	return ret;
}

bool CAsComboBox::GetSelKey(int& sortKey)
{
	bool ret;
	cmString s;

	ret = GetSelKey(s);
	sortKey = s;

	return ret;
}

bool CAsComboBox::GetSelKey(cmString& sortKey)
{
	if (GetCurSel() == CB_ERR)
		return false;

	cmString tmp;
	map<cmString, cmString>::iterator it;

	GetLBText(GetCurSel(), tmp);
	
	it = valueToSortKeyMap_.find(tmp);
	if (it != valueToSortKeyMap_.end()) {
		sortKey = it->second;	
		return true;
	}
	
	return false;
}

cmString CAsComboBox::GetSelString()
{
	if (GetCurSel() == CB_ERR)
		return _T("");

	cmString tmp;

	GetLBText(GetCurSel(), tmp);
	
	return tmp;
}

void CAsComboBox::Draw(CDC* pDC, CRect clientRect)
{
	DrawBackground(pDC, clientRect);
	DrawComboButton(pDC, clientRect);
}

void CAsComboBox::OnSelchange() 
{
	RedrawWindow();	
}

/*
void CAsComboBox::MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct)
{
	if (lpMeasureItemStruct->CtlType ==	ODT_COMBOBOX) {
		lpMeasureItemStruct->itemWidth = 100;
		lpMeasureItemStruct->itemHeight = 20;
	} else if (lpMeasureItemStruct->CtlType ==	ODT_LISTBOX) {
		lpMeasureItemStruct->itemWidth = 100;
		lpMeasureItemStruct->itemHeight = 20;
		MessageBox("PIPPO");
	} else {
		int i;

		i = 0;
	}
}

void CAsComboBox::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) 
{
	CDC dc;

	CMemDC memDC(dc.FromHandle(lpDrawItemStruct->hDC));
	
	switch (lpDrawItemStruct->CtlType) {
		case ODT_COMBOBOX:
			DrawComboButton(memDC, lpDrawItemStruct->rcItem);
			//DrawSingleItem(lpDrawItemStruct);		
			break;

		case ODT_LISTBOX:
			MessageBox("ODT_LISTBOX");
			//DrawSingleItem(lpDrawItemStruct);
			break;
	}

	CString tmp;

	switch (lpDrawItemStruct->CtlType) {
		case ODT_BUTTON:
			tmp = "Owner-drawn button";
			break;

		case ODT_COMBOBOX:
			tmp = "Owner-drawn combo box";
			break;

		case ODT_LISTBOX:   
			tmp = "Owner-drawn list box";
			break;

		case ODT_MENU:   
			tmp = "Owner-drawn menu";
			break;

		case ODT_LISTVIEW:
			tmp = "List view control";
			break;

		case ODT_STATIC:
			tmp = "Owner-drawn static control";
			break;

		case ODT_TAB:
			tmp = "Tab";
			break;

		default:
			tmp = "NIENTE!!!";

	}
	
	//MessageBox(tmp);
}

*/

void CAsComboBox::OnKillFocus(CWnd* pNewWnd) 
{
	if (pNewWnd)
		CComboBox::OnKillFocus(pNewWnd);
	
	// TODO: Add your message handler code here
	
}
