// ColorPicker.cpp : implementation file
//

#include "stdafx.h"
#include "leocad.h"
#include "ClrPopup.h"
#include "ClrPick.h"
#include "globals.h"

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

/*
void AFXAPI DDX_ColorPicker(CDataExchange *pDX, int nIDC, COLORREF& crColor)
{
    HWND hWndCtrl = pDX->PrepareCtrl(nIDC);
    ASSERT (hWndCtrl != NULL);                
    
    CColorPicker* pColorPicker = (CColorPicker*) CWnd::FromHandle(hWndCtrl);
    if (pDX->m_bSaveAndValidate)
    {
        crColor = pColorPicker->GetColor();
    }
    else // initializing
    {
        pColorPicker->SetColor(crColor);
    }
}
*/
/////////////////////////////////////////////////////////////////////////////
// CColorPicker

CColorPicker::CColorPicker()
{
    m_bActive = FALSE;
	m_bDefaultText = FALSE;
	m_bCustomText = FALSE;
    m_crColor = GetSysColor(COLOR_3DFACE);
	SetColorIndex (-1);
}

CColorPicker::~CColorPicker()
{
}

IMPLEMENT_DYNCREATE(CColorPicker, CButton)

BEGIN_MESSAGE_MAP(CColorPicker, CButton)
    //{{AFX_MSG_MAP(CColorPicker)
    ON_CONTROL_REFLECT_EX(BN_CLICKED, OnClicked)
    ON_WM_CREATE()
    //}}AFX_MSG_MAP
    ON_MESSAGE(CPN_SELENDOK, OnSelEndOK)
    ON_MESSAGE(CPN_SELENDCANCEL, OnSelEndCancel)
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CColorPicker message handlers

LONG CColorPicker::OnSelEndOK(UINT /*lParam*/, LONG wParam)
{
	m_bActive = FALSE;
	SetColorIndex(wParam);

	CWnd *pParent = GetParent();
	if (pParent)
		pParent->SendMessage(CPN_SELENDOK, wParam, (LPARAM)GetDlgCtrlID());

	return TRUE;
}

LONG CColorPicker::OnSelEndCancel(UINT /*lParam*/, LONG wParam)
{
    m_bActive = FALSE;

    CWnd *pParent = GetParent();
    if (pParent)
		pParent->SendMessage(CPN_SELENDCANCEL, (WPARAM)wParam, (LPARAM)GetDlgCtrlID());

    return TRUE;
}

int CColorPicker::OnCreate(LPCREATESTRUCT lpCreateStruct) 
{
    if (CButton::OnCreate(lpCreateStruct) == -1)
        return -1;

    SetWindowSize();    // resize appropriately
	return 0;
}

// On mouse click, create and show a CColorPopup window for colour selection
BOOL CColorPicker::OnClicked()
{
    m_bActive = TRUE;
    CRect rect;
    GetWindowRect(rect);
    new CColorPopup(CPoint(rect.left, rect.bottom), m_crColor, 
					this, m_bDefaultText, m_bCustomText);

	return TRUE;
}

void CColorPicker::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) 
{
    ASSERT(lpDrawItemStruct);
    
    CDC*    pDC     = CDC::FromHandle(lpDrawItemStruct->hDC);
    CRect   rect    = lpDrawItemStruct->rcItem;
    UINT    state   = lpDrawItemStruct->itemState;
    DWORD   dwStyle = GetStyle();
    CString m_strText;

    CSize Margins(::GetSystemMetrics(SM_CXEDGE), ::GetSystemMetrics(SM_CYEDGE));

    // Draw arrow
    if (m_bActive) state |= ODS_SELECTED;
    pDC->DrawFrameControl(&m_ArrowRect, DFC_SCROLL, DFCS_SCROLLDOWN  | 
                          ((state & ODS_SELECTED) ? DFCS_PUSHED : 0) |
                          ((state & ODS_DISABLED) ? DFCS_INACTIVE : 0));

    pDC->DrawEdge(rect, EDGE_SUNKEN, BF_RECT);

    // Must reduce the size of the "client" area of the button due to edge thickness.
    rect.DeflateRect(Margins.cx, Margins.cy);
	rect.bottom +=1;

    // Fill remaining area with colour
    rect.right -= m_ArrowRect.Width()-1;

    CBrush brush( ((state & ODS_DISABLED) || m_crColor == CLR_DEFAULT)? 
                  ::GetSysColor(COLOR_3DFACE) : m_crColor);
    CBrush* pOldBrush = (CBrush*) pDC->SelectObject(&brush);
	pDC->SelectStockObject(NULL_PEN);
    pDC->Rectangle(rect);
    pDC->SelectObject(pOldBrush);

	if (GetColorIndex() > 13 && GetColorIndex() < 22)
	{
		for (int x = rect.left; x < rect.right; x++)
		{
			for (int y = rect.top; y < rect.bottom; y+=4)
			{
				if (y == rect.top) y += x%4;
				pDC->SetPixel (x,y,RGB(255,255,255));
			}
			for (y = rect.bottom; y > rect.top; y-=4)
			{
				if (y == rect.bottom) y-= x%4;
				pDC->SetPixel (x,y,RGB(255,255,255));
			}
		}
	}

    // Draw focus rect
    if (state & ODS_FOCUS) 
    {
        rect.DeflateRect(1,1);
        pDC->DrawFocusRect(rect);
    }
}

/////////////////////////////////////////////////////////////////////////////
// CColorPicker overrides

void CColorPicker::PreSubclassWindow() 
{
    ModifyStyle(0, BS_OWNERDRAW);        // Make it owner drawn
    CButton::PreSubclassWindow();
    SetWindowSize();                     // resize appropriately
}

/////////////////////////////////////////////////////////////////////////////
// CColorPicker attributes

int CColorPicker::GetColorIndex()
{
	return m_nColor;
}

void CColorPicker::SetColorIndex(int nColor)
{
	if (nColor != -1)
		m_crColor = RGB(FlatColorArray[nColor][0], FlatColorArray[nColor][1], FlatColorArray[nColor][2]);

	if (m_nColor != nColor)
	{
		m_nColor = nColor;
		if (IsWindow(m_hWnd))
			RedrawWindow();
	}
}

/////////////////////////////////////////////////////////////////////////////
// CColorPicker implementation

void CColorPicker::SetWindowSize()
{
    // Get size dimensions of edges
    CSize MarginSize(::GetSystemMetrics(SM_CXEDGE), ::GetSystemMetrics(SM_CYEDGE));

    // Get size of dropdown arrow
    int nArrowWidth = max(::GetSystemMetrics(SM_CXHTHUMB), 5*MarginSize.cx);
    int nArrowHeight = max(::GetSystemMetrics(SM_CYVTHUMB), 5*MarginSize.cy);
    CSize ArrowSize(max(nArrowWidth, nArrowHeight), max(nArrowWidth, nArrowHeight));

    // Get window size
    CRect rect;
    GetWindowRect(rect);

    CWnd* pParent = GetParent();
    if (pParent)
        pParent->ScreenToClient(rect);

    // Set window size at least as wide as 2 arrows, and as high as arrow + margins
    int nWidth = max(rect.Width(), 2*ArrowSize.cx + 2*MarginSize.cx);
    int nHeight = max(rect.Height(), ArrowSize.cy + 2*MarginSize.cy);
    MoveWindow(rect.left, rect.top, nWidth, nHeight, TRUE);

    // Get the new coords of this window
    GetWindowRect(rect);
    ScreenToClient(rect);

    // Get the rect where the arrow goes, and convert to client coords.
    m_ArrowRect.SetRect(rect.right - ArrowSize.cx - MarginSize.cx, 
                        rect.top + MarginSize.cy, rect.right - MarginSize.cx,
                        rect.bottom - MarginSize.cy);
}
