/*
 * Static control
 *
 * Copyright  David W. Metcalfe, 1993
 *
 */

#include "wine/winuser16.h"
#include "win.h"
#include "bitmap.h"
#include "cursoricon.h"
#include "static.h"
#include "heap.h"
#include "debug.h"
#include "tweak.h"

static void STATIC_PaintTextfn( WND *wndPtr, HDC32 hdc );
static void STATIC_PaintRectfn( WND *wndPtr, HDC32 hdc );
static void STATIC_PaintIconfn( WND *wndPtr, HDC32 hdc );
static void STATIC_PaintBitmapfn( WND *wndPtr, HDC32 hdc );
static void STATIC_PaintEtchedfn( WND *wndPtr, HDC32 hdc );

static COLORREF color_windowframe, color_background, color_window;


typedef void (*pfPaint)( WND *, HDC32 );

static pfPaint staticPaintFunc[SS_TYPEMASK+1] =
{
    STATIC_PaintTextfn,      /* SS_LEFT */
    STATIC_PaintTextfn,      /* SS_CENTER */
    STATIC_PaintTextfn,      /* SS_RIGHT */
    STATIC_PaintIconfn,      /* SS_ICON */
    STATIC_PaintRectfn,      /* SS_BLACKRECT */
    STATIC_PaintRectfn,      /* SS_GRAYRECT */
    STATIC_PaintRectfn,      /* SS_WHITERECT */
    STATIC_PaintRectfn,      /* SS_BLACKFRAME */
    STATIC_PaintRectfn,      /* SS_GRAYFRAME */
    STATIC_PaintRectfn,      /* SS_WHITEFRAME */
    NULL,                    /* Not defined */
    STATIC_PaintTextfn,      /* SS_SIMPLE */
    STATIC_PaintTextfn,      /* SS_LEFTNOWORDWRAP */
    NULL,                    /* SS_OWNERDRAW */
    STATIC_PaintBitmapfn,    /* SS_BITMAP */
    NULL,                    /* SS_ENHMETAFILE */
    STATIC_PaintEtchedfn,    /* SS_ETCHEDHORIZ */
    STATIC_PaintEtchedfn,    /* SS_ETCHEDVERT */
    STATIC_PaintEtchedfn,    /* SS_ETCHEDFRAME */
};


/***********************************************************************
 *           STATIC_SetIcon
 *
 * Set the icon for an SS_ICON control.
 */
static HICON16 STATIC_SetIcon( WND *wndPtr, HICON16 hicon )
{
    HICON16 prevIcon;
    STATICINFO *infoPtr = (STATICINFO *)wndPtr->wExtra;
    CURSORICONINFO *info = hicon?(CURSORICONINFO *) GlobalLock16( hicon ):NULL;

    if ((wndPtr->dwStyle & SS_TYPEMASK) != SS_ICON) return 0;
    if (hicon && !info) {
	ERR(static, "huh? hicon!=0, but info=0???\n");
    	return 0;
    }
    prevIcon = infoPtr->hIcon;
    infoPtr->hIcon = hicon;
    if (hicon)
    {
        SetWindowPos32( wndPtr->hwndSelf, 0, 0, 0, info->nWidth, info->nHeight,
                        SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOZORDER );
        GlobalUnlock16( hicon );
    }
    return prevIcon;
}

/***********************************************************************
 *           STATIC_SetBitmap
 *
 * Set the bitmap for an SS_BITMAP control.
 */
static HICON16 STATIC_SetBitmap( WND *wndPtr, HICON16 hicon )
{
    HICON16 prevIcon;
    STATICINFO *infoPtr = (STATICINFO *)wndPtr->wExtra;
    BITMAPOBJ *info = (BITMAPOBJ *)GDI_HEAP_LOCK(hicon);

    if ((wndPtr->dwStyle & SS_TYPEMASK) != SS_BITMAP) return 0;
    if (hicon && !info) {
	ERR(static, "huh? hicon!=0, but info=0???\n");
    	return 0;
    }
    prevIcon = infoPtr->hIcon;
    infoPtr->hIcon = hicon;
    if (hicon)
    {
        SetWindowPos32( wndPtr->hwndSelf, 0, 0, 0, info->bitmap.bmWidth, info->bitmap.bmHeight,
                        SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOZORDER );
    }
    GDI_HEAP_UNLOCK( hicon );
    return prevIcon;
}


/***********************************************************************
 *           STATIC_LoadIcon
 *
 * Load the icon for an SS_ICON control.
 */
static HICON16 STATIC_LoadIcon( WND *wndPtr, LPCSTR name )
{
    HICON16 hicon;

    if (wndPtr->flags & WIN_ISWIN32)
    {
	if (!HIWORD(wndPtr->hInstance)) {
	    LPSTR segname = SEGPTR_STRDUP(name);
	    hicon = LoadIcon16( wndPtr->hInstance, SEGPTR_GET(segname) );
	    SEGPTR_FREE(segname);
	} else
	    hicon = LoadIcon32A( wndPtr->hInstance, name );
    } else {
        LPSTR segname = SEGPTR_STRDUP(name);

	if (HIWORD(wndPtr->hInstance))
		FIXME(static,"win16 window class, but win32 hinstance??\n");
        hicon = LoadIcon16( wndPtr->hInstance, SEGPTR_GET(segname) );
        SEGPTR_FREE(segname);
    }
    if (!hicon)
	hicon = LoadIcon32A( 0, name );
    return hicon;
}

/***********************************************************************
 *           STATIC_LoadBitmap
 *
 * Load the bitmap for an SS_BITMAP control.
 */
static HBITMAP16 STATIC_LoadBitmap( WND *wndPtr, LPCSTR name )
{
    HBITMAP16 hbitmap;

    if (wndPtr->flags & WIN_ISWIN32)
    {
        hbitmap = LoadBitmap32A( wndPtr->hInstance, name );
        if (!hbitmap)  /* Try OEM icon (FIXME: is this right?) */
            hbitmap = LoadBitmap32A( 0, name );
    }
    else
    {
        LPSTR segname = SEGPTR_STRDUP(name);
        hbitmap = LoadBitmap16( wndPtr->hInstance, SEGPTR_GET(segname) );
        if (!hbitmap)  /* Try OEM icon (FIXME: is this right?) */
            hbitmap = LoadBitmap32A( 0, segname );
        SEGPTR_FREE(segname);
    }
    return hbitmap;
}


/***********************************************************************
 *           StaticWndProc
 */
LRESULT WINAPI StaticWndProc( HWND32 hWnd, UINT32 uMsg, WPARAM32 wParam,
                              LPARAM lParam )
{
    LRESULT lResult = 0;
    WND *wndPtr = WIN_FindWndPtr(hWnd);
    LONG style = wndPtr->dwStyle & SS_TYPEMASK;
    STATICINFO *infoPtr = (STATICINFO *)wndPtr->wExtra;

    switch (uMsg)
    {
    case WM_NCCREATE: {
        CREATESTRUCT32A *cs = (CREATESTRUCT32A *)lParam;

	if ((TWEAK_WineLook > WIN31_LOOK) && (wndPtr->dwStyle & SS_SUNKEN))
	    wndPtr->dwExStyle |= WS_EX_STATICEDGE;

        if (style == SS_ICON)
        {
            if (cs->lpszName) {
	    	if (!HIWORD(cs->lpszName) || cs->lpszName[0])
		    STATIC_SetIcon( wndPtr,
                                STATIC_LoadIcon( wndPtr, cs->lpszName ));
	    }
            return 1;
        }
	if (style == SS_BITMAP)
	{
            if (cs->lpszName)
                STATIC_SetBitmap( wndPtr,
                                STATIC_LoadBitmap( wndPtr, cs->lpszName ));
	    WARN(static, "style SS_BITMAP, dwStyle is 0x%08lx\n",
			wndPtr->dwStyle);
            return 1;
	}
	if (!HIWORD(cs->lpszName) && (cs->lpszName)) {
		FIXME(static,"windowName is 0x%04x, not doing DefWindowProc\n",
		    LOWORD(cs->lpszName)
		);
		return 1;
	}
        return DefWindowProc32A( hWnd, uMsg, wParam, lParam );
    }
    case WM_CREATE:
        if (style < 0L || style > SS_TYPEMASK)
        {
            ERR(static, "Unknown style 0x%02lx\n", style );
            lResult = -1L;
            break;
        }
        /* initialise colours */
        color_windowframe  = GetSysColor32(COLOR_WINDOWFRAME);
        color_background   = GetSysColor32(COLOR_BACKGROUND);
        color_window       = GetSysColor32(COLOR_WINDOW);
        break;

    case WM_NCDESTROY:
        if (style == SS_ICON) {
/*
 * FIXME
 *           DestroyIcon32( STATIC_SetIcon( wndPtr, 0 ) );
 * 
 * We don't want to do this yet because DestroyIcon32 is broken. If the icon
 * had already been loaded by the application the last thing we want to do is
 * GlobalFree16 the handle.
 */
        } else {
            lResult = DefWindowProc32A( hWnd, uMsg, wParam, lParam );
	}
        break;

    case WM_PAINT:
        {
            PAINTSTRUCT32 ps;
            BeginPaint32( hWnd, &ps );
            if (staticPaintFunc[style])
                (staticPaintFunc[style])( wndPtr, ps.hdc );
            EndPaint32( hWnd, &ps );
        }
        break;

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

    case WM_SYSCOLORCHANGE:
        color_windowframe  = GetSysColor32(COLOR_WINDOWFRAME);
        color_background   = GetSysColor32(COLOR_BACKGROUND);
        color_window       = GetSysColor32(COLOR_WINDOW);
        InvalidateRect32( hWnd, NULL, TRUE );
        break;

    case WM_SETTEXT:
        if (style == SS_ICON)
            /* FIXME : should we also return the previous hIcon here ??? */
            STATIC_SetIcon( wndPtr, STATIC_LoadIcon( wndPtr, (LPCSTR)lParam ));
        else if (style == SS_BITMAP) 
            STATIC_SetBitmap(wndPtr,STATIC_LoadBitmap(wndPtr,(LPCSTR)lParam ));
	else
            DEFWND_SetText( wndPtr, (LPCSTR)lParam );
        InvalidateRect32( hWnd, NULL, FALSE );
        UpdateWindow32( hWnd );
        break;

    case WM_SETFONT:
        if (style == SS_ICON) return 0;
        if (style == SS_BITMAP) return 0;
        infoPtr->hFont = (HFONT16)wParam;
        if (LOWORD(lParam))
        {
            InvalidateRect32( hWnd, NULL, FALSE );
            UpdateWindow32( hWnd );
        }
        break;

    case WM_GETFONT:
        return infoPtr->hFont;

    case WM_NCHITTEST:
        return HTTRANSPARENT;

    case WM_GETDLGCODE:
        return DLGC_STATIC;

    case STM_GETIMAGE:
    case STM_GETICON16:
    case STM_GETICON32:
        return infoPtr->hIcon;

    case STM_SETIMAGE:
    	/* FIXME: handle wParam */
        lResult = STATIC_SetBitmap( wndPtr, (HBITMAP32)lParam );
        InvalidateRect32( hWnd, NULL, FALSE );
        UpdateWindow32( hWnd );
	break;

    case STM_SETICON16:
    case STM_SETICON32:
        lResult = STATIC_SetIcon( wndPtr, (HICON16)wParam );
        InvalidateRect32( hWnd, NULL, FALSE );
        UpdateWindow32( hWnd );
        break;

    default:
        lResult = DefWindowProc32A(hWnd, uMsg, wParam, lParam);
        break;
    }
    
    return lResult;
}


static void STATIC_PaintTextfn( WND *wndPtr, HDC32 hdc )
{
    RECT32 rc;
    HBRUSH32 hBrush;
    WORD wFormat;

    LONG style = wndPtr->dwStyle;
    STATICINFO *infoPtr = (STATICINFO *)wndPtr->wExtra;

    GetClientRect32( wndPtr->hwndSelf, &rc);

    switch (style & SS_TYPEMASK)
    {
    case SS_LEFT:
	wFormat = DT_LEFT | DT_EXPANDTABS | DT_WORDBREAK | DT_NOCLIP;
	break;

    case SS_CENTER:
	wFormat = DT_CENTER | DT_EXPANDTABS | DT_WORDBREAK | DT_NOCLIP;
	break;

    case SS_RIGHT:
	wFormat = DT_RIGHT | DT_EXPANDTABS | DT_WORDBREAK | DT_NOCLIP;
	break;

    case SS_SIMPLE:
	wFormat = DT_LEFT | DT_SINGLELINE | DT_VCENTER | DT_NOCLIP;
	break;

    case SS_LEFTNOWORDWRAP:
	wFormat = DT_LEFT | DT_SINGLELINE | DT_EXPANDTABS | DT_VCENTER | DT_NOCLIP;
	break;

    default:
        return;
    }

    if (style & SS_NOPREFIX)
	wFormat |= DT_NOPREFIX;

    if (infoPtr->hFont) SelectObject32( hdc, infoPtr->hFont );
    hBrush = SendMessage32A( GetParent32(wndPtr->hwndSelf), WM_CTLCOLORSTATIC,
                             hdc, wndPtr->hwndSelf );
    if (!hBrush) hBrush = GetStockObject32(WHITE_BRUSH);
    FillRect32( hdc, &rc, hBrush );
    if (wndPtr->text) DrawText32A( hdc, wndPtr->text, -1, &rc, wFormat );
}

static void STATIC_PaintRectfn( WND *wndPtr, HDC32 hdc )
{
    RECT32 rc;
    HBRUSH32 hBrush;

    GetClientRect32( wndPtr->hwndSelf, &rc);
    
    switch (wndPtr->dwStyle & SS_TYPEMASK)
    {
    case SS_BLACKRECT:
	hBrush = CreateSolidBrush32(color_windowframe);
        FillRect32( hdc, &rc, hBrush );
	break;
    case SS_GRAYRECT:
	hBrush = CreateSolidBrush32(color_background);
        FillRect32( hdc, &rc, hBrush );
	break;
    case SS_WHITERECT:
	hBrush = CreateSolidBrush32(color_window);
        FillRect32( hdc, &rc, hBrush );
	break;
    case SS_BLACKFRAME:
	hBrush = CreateSolidBrush32(color_windowframe);
        FrameRect32( hdc, &rc, hBrush );
	break;
    case SS_GRAYFRAME:
	hBrush = CreateSolidBrush32(color_background);
        FrameRect32( hdc, &rc, hBrush );
	break;
    case SS_WHITEFRAME:
	hBrush = CreateSolidBrush32(color_window);
        FrameRect32( hdc, &rc, hBrush );
	break;
    default:
        return;
    }
    DeleteObject32( hBrush );
}


static void STATIC_PaintIconfn( WND *wndPtr, HDC32 hdc )
{
    RECT32 rc;
    HBRUSH32 hbrush;
    STATICINFO *infoPtr = (STATICINFO *)wndPtr->wExtra;

    GetClientRect32( wndPtr->hwndSelf, &rc );
    hbrush = SendMessage32A( GetParent32(wndPtr->hwndSelf), WM_CTLCOLORSTATIC,
                             hdc, wndPtr->hwndSelf );
    FillRect32( hdc, &rc, hbrush );
    if (infoPtr->hIcon) DrawIcon32( hdc, rc.left, rc.top, infoPtr->hIcon );
}

static void STATIC_PaintBitmapfn(WND *wndPtr, HDC32 hdc )
{
    RECT32 rc;
    HBRUSH32 hbrush;
    STATICINFO *infoPtr = (STATICINFO *)wndPtr->wExtra;
    HDC32 hMemDC;
    HBITMAP32 oldbitmap;

    GetClientRect32( wndPtr->hwndSelf, &rc );
    hbrush = SendMessage32A( GetParent32(wndPtr->hwndSelf), WM_CTLCOLORSTATIC,
                             hdc, wndPtr->hwndSelf );
    FillRect32( hdc, &rc, hbrush );
    if (infoPtr->hIcon) {
        BITMAPOBJ *bmp = (BITMAPOBJ *) GDI_HEAP_LOCK( infoPtr->hIcon );

	if (!bmp) return;
        if (!(hMemDC = CreateCompatibleDC32( hdc ))) return;

	oldbitmap = SelectObject32(hMemDC,infoPtr->hIcon);
	BitBlt32(hdc,bmp->size.cx,bmp->size.cy,bmp->bitmap.bmWidth,bmp->bitmap.bmHeight,hMemDC,0,0,SRCCOPY);
	DeleteDC32(hMemDC);
        GDI_HEAP_UNLOCK(infoPtr->hIcon);
    }
}


static void STATIC_PaintEtchedfn( WND *wndPtr, HDC32 hdc )
{
    RECT32 rc;
    HBRUSH32 hbrush;
    HPEN32 hpen;

    if (TWEAK_WineLook == WIN31_LOOK)
	return;

    GetClientRect32( wndPtr->hwndSelf, &rc );
    hbrush = SendMessage32A( GetParent32(wndPtr->hwndSelf), WM_CTLCOLORSTATIC,
                             hdc, wndPtr->hwndSelf );
    FillRect32( hdc, &rc, hbrush );

    switch (wndPtr->dwStyle & SS_TYPEMASK)
    {
	case SS_ETCHEDHORZ:
	    hpen = SelectObject32 (hdc, GetSysColorPen32 (COLOR_3DSHADOW));
	    MoveToEx32 (hdc, rc.left, rc.bottom / 2 - 1, NULL);
	    LineTo32 (hdc, rc.right - 1, rc.bottom / 2 - 1);
	    SelectObject32 (hdc, GetSysColorPen32 (COLOR_3DHIGHLIGHT));
	    MoveToEx32 (hdc, rc.left, rc.bottom / 2, NULL);
	    LineTo32 (hdc, rc.right, rc.bottom / 2);
	    LineTo32 (hdc, rc.right, rc.bottom / 2 - 1);
	    SelectObject32 (hdc, hpen);
	    break;

	case SS_ETCHEDVERT:
	    hpen = SelectObject32 (hdc, GetSysColorPen32 (COLOR_3DSHADOW));
	    MoveToEx32 (hdc, rc.right / 2 - 1, rc.top, NULL);
	    LineTo32 (hdc, rc.right / 2 - 1, rc.bottom - 1);
	    SelectObject32 (hdc, GetSysColorPen32 (COLOR_3DHIGHLIGHT));
	    MoveToEx32 (hdc, rc.right / 2, rc.top, NULL);
	    LineTo32 (hdc, rc.right / 2, rc.bottom);
	    LineTo32 (hdc, rc.right / 2 -1 , rc.bottom);
	    SelectObject32 (hdc, hpen); 
	    break;

	case SS_ETCHEDFRAME:
	    DrawEdge32 (hdc, &rc, EDGE_ETCHED, BF_RECT);
	    break;
    }
}

