#include <precomp.h>


LRESULT WINAPI
FlatComboProc(HWND hwnd,
              UINT msg,
              WPARAM wParam,
              LPARAM lParam)
{
    HDC hdc;
    PAINTSTRUCT    ps;
    RECT rect, rect2;
    POINT pt;

    WNDPROC OldComboProc = (WNDPROC)GetWindowLong(hwnd, GWL_USERDATA);

    static BOOL fMouseDown  = FALSE;
    static BOOL fButtonDown = FALSE;

    switch(msg)
    {
        case WM_PAINT:
        {
            if(wParam == 0) hdc = BeginPaint(hwnd, &ps);
            else hdc = (HDC)wParam;

            /* mask off the borders and draw ComboBox normally */
            GetClientRect(hwnd, &rect);

            InflateRect(&rect,
                        -GetSystemMetrics(SM_CXEDGE)*2,
                        -GetSystemMetrics(SM_CYEDGE)*2);

            rect.right -= GetSystemMetrics(SM_CXVSCROLL);

            IntersectClipRect(hdc,
                              rect.left,
                              rect.top,
                              rect.right,
                              rect.bottom);

            /* Draw the ComboBox */
            CallWindowProc(OldComboProc,
                           hwnd,
                           msg,
                           (WPARAM)hdc,
                           lParam);

            /* Now mask off inside and draw the borders */
            SelectClipRgn(hdc,
                          NULL);
            rect.right += GetSystemMetrics(SM_CXVSCROLL);

            ExcludeClipRect(hdc,
                            rect.left,
                            rect.top,
                            rect.right,
                            rect.bottom);

            /* draw borders */
            GetClientRect(hwnd,
                          &rect2);
            FillRect(hdc,
                     &rect2,
                     //CreateSolidBrush(RGB(0,0,0)));
                     GetSysColorBrush(COLOR_3DFACE));

            /* now draw the button */
            SelectClipRgn(hdc,
                          NULL);
            rect.left = rect.right - GetSystemMetrics(SM_CXVSCROLL);

            if(fButtonDown)
            {
                HBRUSH oldBrush;
                HPEN oldPen;
                POINT pt[3];

                FillRect(hdc, &rect, CreateSolidBrush(RGB(182,189,210)));
                rect.top -= 1;
                rect.bottom += 1;
                FrameRect(hdc, &rect, GetStockBrush(WHITE_BRUSH));

                pt[0].x = rect.right - ((GetSystemMetrics(SM_CXVSCROLL) / 2) + 2);
                pt[0].y = rect.bottom / 2;
                pt[1].x = pt[0].x + 4;
                pt[1].y = pt[0].y;
                pt[2].x = pt[1].x - 2;
                pt[2].y = pt[1].y + 2;

                oldPen = (HPEN) SelectObject(hdc, GetStockPen(WHITE_PEN));
                oldBrush = (HBRUSH) SelectObject(hdc, GetStockBrush(WHITE_BRUSH));
                Polygon(hdc, pt, 3);

                SelectObject(hdc, oldPen);
                SelectObject(hdc, oldBrush);
            }
            else
            {
                HBRUSH oldBrush;
                POINT pt[3];

                FillRect(hdc, &rect, GetSysColorBrush(COLOR_3DFACE));
                rect.top -= 1;
                rect.bottom += 1;
                FrameRect(hdc, &rect, GetStockBrush(WHITE_BRUSH));

                pt[0].x = rect.right - ((GetSystemMetrics(SM_CXVSCROLL) / 2) + 2);
                pt[0].y = rect.bottom / 2;
                pt[1].x = pt[0].x + 4;
                pt[1].y = pt[0].y;
                pt[2].x = pt[1].x - 2;
                pt[2].y = pt[1].y + 2;

                oldBrush = (HBRUSH) SelectObject(hdc, GetStockBrush(BLACK_BRUSH));
                Polygon(hdc, pt, 3);

                SelectObject(hdc, oldBrush);
            }


            if(wParam == 0)
                EndPaint(hwnd, &ps);

            return 0;
        }

        /* check if mouse is within drop-arrow area, toggle
         * a flag to say if the mouse is up/down. Then invalidate
         * the window so it redraws to show the changes. */
        case WM_LBUTTONDBLCLK:
        case WM_LBUTTONDOWN:
        {

            pt.x = (short)LOWORD(lParam);
            pt.y = (short)HIWORD(lParam);

            GetClientRect(hwnd, &rect);

            InflateRect(&rect,
                        -GetSystemMetrics(SM_CXEDGE),
                        -GetSystemMetrics(SM_CYEDGE));
            rect.left = rect.right - GetSystemMetrics(SM_CXVSCROLL);

            if(PtInRect(&rect, pt))
            {
                /* we *should* call SetCapture, but the ComboBox does it for us */
                fMouseDown = TRUE;
                fButtonDown = TRUE;
                InvalidateRect(hwnd, 0, 0);
            }
        }
        break;

        /* mouse has moved. Check to see if it is in/out of the drop-arrow */
        case WM_MOUSEMOVE:
        {

            pt.x = (short)LOWORD(lParam);
            pt.y = (short)HIWORD(lParam);

            if(fMouseDown && (wParam & MK_LBUTTON))
            {
                GetClientRect(hwnd, &rect);

                InflateRect(&rect, -GetSystemMetrics(SM_CXEDGE), -GetSystemMetrics(SM_CYEDGE));
                rect.left = rect.right - GetSystemMetrics(SM_CXVSCROLL);

                if(fButtonDown != PtInRect(&rect, pt))
                {
                    fButtonDown = PtInRect(&rect, pt);
                    InvalidateRect(hwnd, 0, 0);
                }
            }
        }
        break;

        case WM_LBUTTONUP:
        {

            if(fMouseDown)
            {
                /* No need to call ReleaseCapture, the ComboBox does it for us */
                fMouseDown = FALSE;
                fButtonDown = FALSE;
                InvalidateRect(hwnd, 0, 0);
            }
        }
        break;
    }

    return CallWindowProc(OldComboProc,
                          hwnd,
                          msg,
                          wParam,
                          lParam);
}

VOID MakeFlatCombo(HWND hwndCombo)
{
    LONG OldComboProc;

    /* Remember old window procedure */
    OldComboProc = GetWindowLongPtr(hwndCombo, GWL_WNDPROC);
    SetWindowLongPtr(hwndCombo,
                     GWL_USERDATA,
                     OldComboProc);

    /* Perform the subclass */
    SetWindowLongPtr(hwndCombo,
                     GWL_WNDPROC,
                     (LONG_PTR)FlatComboProc);
}
