/* File: button.c -- Button type widgets
 *
 * Copyright (C) 1993 Johannes Ruscheinski
 * Copyright (C) 1993 David Metcalfe
 * Copyright (C) 1994 Alexandre Julliard
 */

#include "win.h"
#include "syscolor.h"
#include "graphics.h"
#include "button.h"

static void PB_Paint( WND *wndPtr, HDC32 hDC, WORD action );
static void PB_PaintGrayOnGray(HDC32 hDC,HFONT32 hFont,RECT32 *rc,char *text);
static void CB_Paint( WND *wndPtr, HDC32 hDC, WORD action );
static void GB_Paint( WND *wndPtr, HDC32 hDC, WORD action );
static void UB_Paint( WND *wndPtr, HDC32 hDC, WORD action );
static void OB_Paint( WND *wndPtr, HDC32 hDC, WORD action );
static void BUTTON_CheckAutoRadioButton( WND *wndPtr );

#define MAX_BTN_TYPE  12

static const WORD maxCheckState[MAX_BTN_TYPE] =
{
    BUTTON_UNCHECKED,   /* BS_PUSHBUTTON */
    BUTTON_UNCHECKED,   /* BS_DEFPUSHBUTTON */
    BUTTON_CHECKED,     /* BS_CHECKBOX */
    BUTTON_CHECKED,     /* BS_AUTOCHECKBOX */
    BUTTON_CHECKED,     /* BS_RADIOBUTTON */
    BUTTON_3STATE,      /* BS_3STATE */
    BUTTON_3STATE,      /* BS_AUTO3STATE */
    BUTTON_UNCHECKED,   /* BS_GROUPBOX */
    BUTTON_UNCHECKED,   /* BS_USERBUTTON */
    BUTTON_CHECKED,     /* BS_AUTORADIOBUTTON */
    BUTTON_UNCHECKED,   /* Not defined */
    BUTTON_UNCHECKED    /* BS_OWNERDRAW */
};

typedef void (*pfPaint)( WND *wndPtr, HDC32 hdc, WORD action );

static const pfPaint btnPaintFunc[MAX_BTN_TYPE] =
{
    PB_Paint,    /* BS_PUSHBUTTON */
    PB_Paint,    /* BS_DEFPUSHBUTTON */
    CB_Paint,    /* BS_CHECKBOX */
    CB_Paint,    /* BS_AUTOCHECKBOX */
    CB_Paint,    /* BS_RADIOBUTTON */
    CB_Paint,    /* BS_3STATE */
    CB_Paint,    /* BS_AUTO3STATE */
    GB_Paint,    /* BS_GROUPBOX */
    UB_Paint,    /* BS_USERBUTTON */
    CB_Paint,    /* BS_AUTORADIOBUTTON */
    NULL,        /* Not defined */
    OB_Paint     /* BS_OWNERDRAW */
};

#define PAINT_BUTTON(wndPtr,style,action) \
     if (btnPaintFunc[style]) { \
         HDC32 hdc = GetDC32( (wndPtr)->hwndSelf ); \
         (btnPaintFunc[style])(wndPtr,hdc,action); \
         ReleaseDC32( (wndPtr)->hwndSelf, hdc ); }

#define BUTTON_SEND_CTLCOLOR(wndPtr,hdc) \
    SendMessage32A( GetParent32((wndPtr)->hwndSelf), WM_CTLCOLORBTN, \
                    (hdc), (wndPtr)->hwndSelf )

static HBITMAP16 hbitmapCheckBoxes = 0;
static WORD checkBoxWidth = 0, checkBoxHeight = 0;


/***********************************************************************
 *           ButtonWndProc
 */
LRESULT ButtonWndProc(HWND32 hWnd, UINT32 uMsg, WPARAM32 wParam, LPARAM lParam)
{
    RECT16 rect;
    WND *wndPtr = WIN_FindWndPtr(hWnd);
    BUTTONINFO *infoPtr = (BUTTONINFO *)wndPtr->wExtra;
    LONG style = wndPtr->dwStyle & 0x0f;

    switch (uMsg)
    {
    case WM_GETDLGCODE:
        switch(style)
        {
        case BS_PUSHBUTTON:      return DLGC_BUTTON | DLGC_UNDEFPUSHBUTTON;
        case BS_DEFPUSHBUTTON:   return DLGC_BUTTON | DLGC_DEFPUSHBUTTON;
        case BS_RADIOBUTTON:
        case BS_AUTORADIOBUTTON: return DLGC_BUTTON | DLGC_RADIOBUTTON;
        default:                 return DLGC_BUTTON;
        }

    case WM_ENABLE:
        PAINT_BUTTON( wndPtr, style, ODA_DRAWENTIRE );
        break;

    case WM_CREATE:
        if (!hbitmapCheckBoxes)
        {
            BITMAP16 bmp;
            hbitmapCheckBoxes = LoadBitmap16(0, MAKEINTRESOURCE(OBM_CHECKBOXES));
            GetObject16( hbitmapCheckBoxes, sizeof(bmp), &bmp );
            checkBoxWidth  = bmp.bmWidth / 4;
            checkBoxHeight = bmp.bmHeight / 3;
        }
        if (style < 0L || style >= MAX_BTN_TYPE) return -1; /* abort */
        infoPtr->state = BUTTON_UNCHECKED;
        infoPtr->hFont = 0;
        return 0;

    case WM_ERASEBKGND:
        break;

    case WM_PAINT:
        if (btnPaintFunc[style])
        {
            PAINTSTRUCT32 ps;
            HDC32 hdc = BeginPaint32( hWnd, &ps );
            (btnPaintFunc[style])( wndPtr, hdc, ODA_DRAWENTIRE );
            EndPaint32( hWnd, &ps );
        }
        break;

    case WM_LBUTTONDOWN:
        SendMessage32A( hWnd, BM_SETSTATE32, TRUE, 0 );
        SetFocus32( hWnd );
        SetCapture32( hWnd );
        break;

    case WM_LBUTTONUP:
        ReleaseCapture();
        if (!(infoPtr->state & BUTTON_HIGHLIGHTED)) break;
        SendMessage32A( hWnd, BM_SETSTATE32, FALSE, 0 );
        GetClientRect16( hWnd, &rect );
        if (PtInRect16( &rect, MAKEPOINT16(lParam) ))
        {
            switch(style)
            {
            case BS_AUTOCHECKBOX:
                SendMessage32A( hWnd, BM_SETCHECK32,
                                !(infoPtr->state & BUTTON_CHECKED), 0 );
                break;
            case BS_AUTORADIOBUTTON:
                SendMessage32A( hWnd, BM_SETCHECK32, TRUE, 0 );
                break;
            case BS_AUTO3STATE:
                SendMessage32A( hWnd, BM_SETCHECK32,
                                (infoPtr->state & BUTTON_3STATE) ? 0 :
                                ((infoPtr->state & 3) + 1), 0 );
                break;
            }
            SendMessage32A( GetParent32(hWnd), WM_COMMAND,
                            MAKEWPARAM( wndPtr->wIDmenu, BN_CLICKED ), hWnd);
        }
        break;

    case WM_MOUSEMOVE:
        if (GetCapture32() == hWnd)
        {
            GetClientRect16( hWnd, &rect );
            SendMessage32A( hWnd, BM_SETSTATE32,
                            PtInRect16( &rect,MAKEPOINT16(lParam) ), 0 );
        }
        break;

    case WM_NCHITTEST:
        if(style == BS_GROUPBOX) return HTTRANSPARENT;
        return DefWindowProc32A( hWnd, uMsg, wParam, lParam );

    case WM_SETTEXT:
        DEFWND_SetText( wndPtr, (LPSTR)lParam );
        PAINT_BUTTON( wndPtr, style, ODA_DRAWENTIRE );
        return 0;

    case WM_SETFONT:
        infoPtr->hFont = (HFONT16)wParam;
        if (lParam) PAINT_BUTTON( wndPtr, style, ODA_DRAWENTIRE );
        break;

    case WM_GETFONT:
        return infoPtr->hFont;

    case WM_SETFOCUS:
        infoPtr->state |= BUTTON_HASFOCUS;
        PAINT_BUTTON( wndPtr, style, ODA_FOCUS );
        break;

    case WM_KILLFOCUS:
        infoPtr->state &= ~BUTTON_HASFOCUS;
	PAINT_BUTTON( wndPtr, style, ODA_FOCUS );
	InvalidateRect16( hWnd, NULL, TRUE );
        break;

    case WM_SYSCOLORCHANGE:
        InvalidateRect32( hWnd, NULL, FALSE );
        break;

    case BM_SETSTYLE16:
    case BM_SETSTYLE32:
        if ((wParam & 0x0f) >= MAX_BTN_TYPE) break;
        wndPtr->dwStyle = (wndPtr->dwStyle & 0xfffffff0) 
                           | (wParam & 0x0000000f);
        style = wndPtr->dwStyle & 0x0000000f;
        PAINT_BUTTON( wndPtr, style, ODA_DRAWENTIRE );
        break;

    case BM_GETCHECK16:
    case BM_GETCHECK32:
        return infoPtr->state & 3;

    case BM_SETCHECK16:
    case BM_SETCHECK32:
        if (wParam > maxCheckState[style]) wParam = maxCheckState[style];
        if ((infoPtr->state & 3) != wParam)
        {
            infoPtr->state = (infoPtr->state & ~3) | wParam;
            PAINT_BUTTON( wndPtr, style, ODA_SELECT );
        }
        if ((style == BS_AUTORADIOBUTTON) && (wParam == BUTTON_CHECKED))
            BUTTON_CheckAutoRadioButton( wndPtr );
        break;

    case BM_GETSTATE16:
    case BM_GETSTATE32:
        return infoPtr->state;

    case BM_SETSTATE16:
    case BM_SETSTATE32:
        if (wParam)
        {
            if (infoPtr->state & BUTTON_HIGHLIGHTED) break;
            infoPtr->state |= BUTTON_HIGHLIGHTED;
        }
        else
        {
            if (!(infoPtr->state & BUTTON_HIGHLIGHTED)) break;
            infoPtr->state &= ~BUTTON_HIGHLIGHTED;
        }
        PAINT_BUTTON( wndPtr, style, ODA_SELECT );
        break;

    default:
        return DefWindowProc32A(hWnd, uMsg, wParam, lParam);
    }
    return 0;
}


/**********************************************************************
 *       Push Button Functions
 */

static void PB_Paint( WND *wndPtr, HDC32 hDC, WORD action )
{
    RECT32 rc;
    HPEN32 hOldPen;
    HBRUSH32 hOldBrush;
    BUTTONINFO *infoPtr = (BUTTONINFO *)wndPtr->wExtra;

    GetClientRect32( wndPtr->hwndSelf, &rc );

      /* Send WM_CTLCOLOR to allow changing the font (the colors are fixed) */
    if (infoPtr->hFont) SelectObject32( hDC, infoPtr->hFont );
    BUTTON_SEND_CTLCOLOR( wndPtr, hDC );
    hOldPen = (HPEN32)SelectObject32(hDC, sysColorObjects.hpenWindowFrame);
    hOldBrush = (HBRUSH32)SelectObject32(hDC, sysColorObjects.hbrushBtnFace);
    SetBkMode32(hDC, TRANSPARENT);
    Rectangle32(hDC, rc.left, rc.top, rc.right, rc.bottom);
    if (action == ODA_DRAWENTIRE)
    {
        SetPixel32( hDC, rc.left, rc.top, GetSysColor32(COLOR_WINDOW) );
        SetPixel32( hDC, rc.left, rc.bottom-1, GetSysColor32(COLOR_WINDOW) );
        SetPixel32( hDC, rc.right-1, rc.top, GetSysColor32(COLOR_WINDOW) );
        SetPixel32( hDC, rc.right-1, rc.bottom-1, GetSysColor32(COLOR_WINDOW));
    }
    InflateRect32( &rc, -1, -1 );

    if ((wndPtr->dwStyle & 0x000f) == BS_DEFPUSHBUTTON)
    {
        Rectangle32(hDC, rc.left, rc.top, rc.right, rc.bottom);
        InflateRect32( &rc, -1, -1 );
    }

    if (infoPtr->state & BUTTON_HIGHLIGHTED)
    {
        /* draw button shadow: */
        SelectObject32(hDC, sysColorObjects.hbrushBtnShadow );
        PatBlt32(hDC, rc.left, rc.top, 1, rc.bottom-rc.top, PATCOPY );
        PatBlt32(hDC, rc.left, rc.top, rc.right-rc.left, 1, PATCOPY );
        rc.left += 2;  /* To position the text down and right */
        rc.top  += 2;
    }
    else GRAPH_DrawReliefRect( hDC, &rc, 2, 2, FALSE );
    
    /* draw button label, if any: */
    if (wndPtr->text && wndPtr->text[0])
    {
        LOGBRUSH16 lb;
        GetObject16( sysColorObjects.hbrushBtnFace, sizeof(lb), &lb );
        if (wndPtr->dwStyle & WS_DISABLED &&
            GetSysColor32(COLOR_GRAYTEXT)==lb.lbColor)
            /* don't write gray text on gray bkg */
            PB_PaintGrayOnGray(hDC,infoPtr->hFont,&rc,wndPtr->text);
        else
        {
            SetTextColor( hDC, (wndPtr->dwStyle & WS_DISABLED) ?
                                GetSysColor32(COLOR_GRAYTEXT) :
                                GetSysColor32(COLOR_BTNTEXT) );
            DrawText32A( hDC, wndPtr->text, -1, &rc,
                         DT_SINGLELINE | DT_CENTER | DT_VCENTER );
            /* do we have the focus? */
            if (infoPtr->state & BUTTON_HASFOCUS)
            {
                RECT32 r = { 0, 0, 0, 0 };
                INT32 xdelta, ydelta;

                DrawText32A( hDC, wndPtr->text, -1, &r,
                             DT_SINGLELINE | DT_CALCRECT );
                xdelta = ((rc.right - rc.left) - (r.right - r.left) - 1) / 2;
                ydelta = ((rc.bottom - rc.top) - (r.bottom - r.top) - 1) / 2;
                if (xdelta < 0) xdelta = 0;
                if (ydelta < 0) ydelta = 0;
                InflateRect32( &rc, -xdelta, -ydelta );
                DrawFocusRect32( hDC, &rc );
            }
        }   
    }

    SelectObject32( hDC, hOldPen );
    SelectObject32( hDC, hOldBrush );
}


/**********************************************************************
 *   Push Button sub function                               [internal]
 *   using a raster brush to avoid gray text on gray background
 */

void PB_PaintGrayOnGray(HDC32 hDC,HFONT32 hFont,RECT32 *rc,char *text)
{
    static int Pattern[] = {0xAA,0x55,0xAA,0x55,0xAA,0x55,0xAA,0x55};
    HBITMAP16 hbm  = CreateBitmap(8, 8, 1, 1, Pattern);
    HDC32 hdcMem = CreateCompatibleDC32(hDC);
    HBITMAP16 hbmMem;
    HBRUSH16 hBr;
    RECT32 rect,rc2;

    rect=*rc;
    DrawText32A( hDC, text, -1, &rect, DT_SINGLELINE | DT_CALCRECT);
    rc2=rect;
    rect.left=(rc->right-rect.right)/2;       /* for centering text bitmap */
    rect.top=(rc->bottom-rect.bottom)/2;
    hbmMem = CreateCompatibleBitmap( hDC,rect.right,rect.bottom);
    SelectObject32( hdcMem, hbmMem);
    hBr = SelectObject32( hdcMem, CreatePatternBrush32(hbm) );
    DeleteObject32( hbm );
    PatBlt32( hdcMem,0,0,rect.right,rect.bottom,WHITENESS);
    if (hFont) SelectObject32( hdcMem, hFont);
    DrawText32A( hdcMem, text, -1, &rc2, DT_SINGLELINE);  
    PatBlt32( hdcMem,0,0,rect.right,rect.bottom,0xFA0089);
    DeleteObject32( SelectObject32( hdcMem,hBr) );
    BitBlt32(hDC,rect.left,rect.top,rect.right,rect.bottom,hdcMem,0,0,0x990000);
    DeleteDC32( hdcMem);
    DeleteObject32( hbmMem );
}


/**********************************************************************
 *       Check Box & Radio Button Functions
 */

static void CB_Paint( WND *wndPtr, HDC32 hDC, WORD action )
{
    RECT16 rbox, rtext, client;
    HBRUSH16 hBrush;
    int textlen, delta;
    BUTTONINFO *infoPtr = (BUTTONINFO *)wndPtr->wExtra;

    textlen = 0;
    GetClientRect16(wndPtr->hwndSelf, &client);
    rbox = rtext = client;

    if (infoPtr->hFont) SelectObject32( hDC, infoPtr->hFont );
    hBrush = BUTTON_SEND_CTLCOLOR( wndPtr, hDC );
    if (wndPtr->dwStyle & BS_LEFTTEXT) 
    {
	/* magic +4 is what CTL3D expects */

        rtext.right -= checkBoxWidth + 4;
        rbox.left = rbox.right - checkBoxWidth;
    }
    else 
    {
        rtext.left += checkBoxWidth + 4;
        rbox.right = checkBoxWidth;
    }

      /* Draw the check-box bitmap */

    if (wndPtr->text) textlen = strlen( wndPtr->text );
    if (action == ODA_DRAWENTIRE || action == ODA_SELECT)
    { 
        int x = 0, y = 0;
        delta = (rbox.bottom - rbox.top - checkBoxHeight) >> 1;

        if (action == ODA_SELECT) FillRect16( hDC, &rbox, hBrush );
        else FillRect16( hDC, &client, hBrush );

        if (infoPtr->state & BUTTON_HIGHLIGHTED) x += 2 * checkBoxWidth;
        if (infoPtr->state & (BUTTON_CHECKED | BUTTON_3STATE)) x += checkBoxWidth;
        if (((wndPtr->dwStyle & 0x0f) == BS_RADIOBUTTON) ||
            ((wndPtr->dwStyle & 0x0f) == BS_AUTORADIOBUTTON)) y += checkBoxHeight;
        else if (infoPtr->state & BUTTON_3STATE) y += 2 * checkBoxHeight;

        GRAPH_DrawBitmap( hDC, hbitmapCheckBoxes, rbox.left, rbox.top + delta,
                          x, y, checkBoxWidth, checkBoxHeight );
        if( textlen && action != ODA_SELECT )
        {
            if (wndPtr->dwStyle & WS_DISABLED)
                SetTextColor( hDC, GetSysColor32(COLOR_GRAYTEXT) );
            DrawText16( hDC, wndPtr->text, textlen, &rtext,
                        DT_SINGLELINE | DT_VCENTER );
        }
    }

    if ((action == ODA_FOCUS) ||
        ((action == ODA_DRAWENTIRE) && (infoPtr->state & BUTTON_HASFOCUS)))
    {
	/* again, this is what CTL3D expects */

        SetRectEmpty16(&rbox);
        if( textlen )
            DrawText16( hDC, wndPtr->text, textlen, &rbox,
                        DT_SINGLELINE | DT_CALCRECT );
        textlen = rbox.bottom - rbox.top;
        delta = ((rtext.bottom - rtext.top) - textlen)/2;
        rbox.bottom = (rbox.top = rtext.top + delta - 1) + textlen + 2;
        textlen = rbox.right - rbox.left;
        rbox.right = (rbox.left += --rtext.left) + textlen + 2;
        IntersectRect16(&rbox, &rbox, &rtext);
        DrawFocusRect16( hDC, &rbox );
    }
}


/**********************************************************************
 *       BUTTON_CheckAutoRadioButton
 *
 * wndPtr is checked, uncheck every other auto radio button in group
 */
static void BUTTON_CheckAutoRadioButton( WND *wndPtr )
{
    HWND32 parent, sibling;
    if (!(wndPtr->dwStyle & WS_CHILD)) return;
    parent = wndPtr->parent->hwndSelf;
    for(sibling = GetNextDlgGroupItem32( parent, wndPtr->hwndSelf, FALSE );
        sibling != wndPtr->hwndSelf && sibling != 0;
        sibling = GetNextDlgGroupItem32( parent, sibling, FALSE ))
	    if((WIN_FindWndPtr(sibling)->dwStyle & 0x0f) == BS_AUTORADIOBUTTON)
		SendMessage32A( sibling, BM_SETCHECK32, BUTTON_UNCHECKED, 0 );
}


/**********************************************************************
 *       Group Box Functions
 */

static void GB_Paint( WND *wndPtr, HDC32 hDC, WORD action )
{
    RECT16 rc;
    BUTTONINFO *infoPtr = (BUTTONINFO *)wndPtr->wExtra;

    if (action != ODA_DRAWENTIRE) return;

    if (infoPtr->hFont) SelectObject32( hDC, infoPtr->hFont );
    BUTTON_SEND_CTLCOLOR( wndPtr, hDC );
    SelectObject32( hDC, sysColorObjects.hpenWindowFrame );

    GetClientRect16( wndPtr->hwndSelf, &rc);

    MoveTo( hDC, rc.left, rc.top+2 );
    LineTo32( hDC, rc.right-1, rc.top+2 );
    LineTo32( hDC, rc.right-1, rc.bottom-1 );
    LineTo32( hDC, rc.left, rc.bottom-1 );
    LineTo32( hDC, rc.left, rc.top+2 );

    if (!wndPtr->text) return;
    if (wndPtr->dwStyle & WS_DISABLED)
        SetTextColor( hDC, GetSysColor32(COLOR_GRAYTEXT) );
    rc.left += 10;
    DrawText16( hDC, wndPtr->text, -1, &rc, DT_SINGLELINE | DT_NOCLIP );
}


/**********************************************************************
 *       User Button Functions
 */

static void UB_Paint( WND *wndPtr, HDC32 hDC, WORD action )
{
    RECT16 rc;
    HBRUSH16 hBrush;
    BUTTONINFO *infoPtr = (BUTTONINFO *)wndPtr->wExtra;

    if (action == ODA_SELECT) return;

    GetClientRect16( wndPtr->hwndSelf, &rc);

    if (infoPtr->hFont) SelectObject32( hDC, infoPtr->hFont );
    hBrush = BUTTON_SEND_CTLCOLOR( wndPtr, hDC );
    FillRect16( hDC, &rc, hBrush );

    if ((action == ODA_FOCUS) ||
        ((action == ODA_DRAWENTIRE) && (infoPtr->state & BUTTON_HASFOCUS)))
        DrawFocusRect16( hDC, &rc );
}


/**********************************************************************
 *       Ownerdrawn Button Functions
 */

static void OB_Paint( WND *wndPtr, HDC32 hDC, WORD action )
{
    BUTTONINFO *infoPtr = (BUTTONINFO *)wndPtr->wExtra;
    DRAWITEMSTRUCT32 dis;

    dis.CtlType    = ODT_BUTTON;
    dis.CtlID      = wndPtr->wIDmenu;
    dis.itemID     = 0;
    dis.itemAction = action;
    dis.itemState  = ((infoPtr->state & BUTTON_HASFOCUS) ? ODS_FOCUS : 0) |
                     ((infoPtr->state & BUTTON_HIGHLIGHTED) ? ODS_SELECTED : 0) |
                     ((wndPtr->dwStyle & WS_DISABLED) ? ODS_DISABLED : 0);
    dis.hwndItem   = wndPtr->hwndSelf;
    dis.hDC        = hDC;
    dis.itemData   = 0;
    GetClientRect32( wndPtr->hwndSelf, &dis.rcItem );
    SendMessage32A( GetParent32(wndPtr->hwndSelf), WM_DRAWITEM,
                    wndPtr->wIDmenu, (LPARAM)&dis );
}
