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

static char Copyright[] = "Copyright  David W. Metcalfe, 1993";

#include <windows.h>
#include "win.h"
#include "user.h"

LONG StaticWndProc(HWND hWnd, WORD uMsg, WORD wParam, LONG lParam);

static LONG PaintTextfn(HWND hwnd);
static LONG PaintRectfn(HWND hwnd);
static LONG PaintFramefn(HWND hwnd);
static LONG PaintIconfn(HWND hwnd);


static COLORREF color_windowframe, color_background, color_window,
                                                     color_windowtext;

#define NOTIFY_PARENT(hWndCntrl, wNotifyCode) \
	SendMessage(GetParent(hWndCntrl), WM_COMMAND, \
		    GetDlgCtrlID(hWndCntrl), MAKELPARAM(hWndCntrl, wNotifyCode));
#define DIM(array)	((sizeof array)/(sizeof array[0]))

typedef struct
{
    LONG (*paintfn)();
} STATICFN;

#define MAX_STATIC_TYPE  12

static STATICFN staticfn[MAX_STATIC_TYPE] =
{
    { (LONG(*)())PaintTextfn },                    /* SS_LEFT */
    { (LONG(*)())PaintTextfn },                    /* SS_CENTER */
    { (LONG(*)())PaintTextfn },                    /* SS_RIGHT */
    { (LONG(*)())PaintIconfn },                    /* SS_ICON */
    { (LONG(*)())PaintRectfn },                    /* SS_BLACKRECT */
    { (LONG(*)())PaintRectfn },                    /* SS_GRAYRECT */
    { (LONG(*)())PaintRectfn },                    /* SS_WHITERECT */
    { (LONG(*)())PaintFramefn },                   /* SS_BLACKFRAME */
    { (LONG(*)())PaintFramefn },                   /* SS_GRAYFRAME */
    { (LONG(*)())PaintFramefn },                   /* SS_WHITEFRAME */
    { (LONG(*)())PaintTextfn },                    /* SS_SIMPLE */
    { (LONG(*)())PaintTextfn }                     /* SS_LEFTNOWORDWRAP */
};


LONG StaticWndProc(HWND hWnd, WORD uMsg, WORD wParam, LONG lParam)
{
	LONG lResult = 0;
	HDC hDC;
	RECT rc;
	LPSTR textPtr;

	WND *wndPtr = WIN_FindWndPtr(hWnd);
	LONG style = wndPtr->dwStyle & 0x0000000F;

	switch (uMsg) {
	case WM_ENABLE:
	    InvalidateRect(hWnd, NULL, FALSE);
	    break;

	case WM_CREATE:
	    if (style < 0L || style >= (LONG)DIM(staticfn)) {
		lResult = -1L;
		break;
		}
	    /* initialise colours */
	    color_windowframe  = GetSysColor(COLOR_WINDOWFRAME);
	    color_background   = GetSysColor(COLOR_BACKGROUND);
	    color_window       = GetSysColor(COLOR_WINDOW);
	    color_windowtext   = GetSysColor(COLOR_WINDOWTEXT);
	    lResult = 0L;
	    if (style == SS_ICON) {
/*
		SetWindowPos(hWnd, (HWND)NULL, 0, 0, 32, 32,
				SWP_NOZORDER | SWP_NOMOVE);
*/
		}
	    break;

	case WM_PAINT:
	    if (staticfn[style].paintfn)
		(staticfn[style].paintfn)(hWnd);
	    break;

	case WM_SYSCOLORCHANGE:
	    color_windowframe  = GetSysColor(COLOR_WINDOWFRAME);
	    color_background   = GetSysColor(COLOR_BACKGROUND);
	    color_window       = GetSysColor(COLOR_WINDOW);
	    color_windowtext   = GetSysColor(COLOR_WINDOWTEXT);
	    InvalidateRect(hWnd, NULL, TRUE);
	    break;

	case WM_SETTEXT:
	    if (wndPtr->hText)
		USER_HEAP_FREE(wndPtr->hText);

	    wndPtr->hText = USER_HEAP_ALLOC(GMEM_MOVEABLE, 
					    strlen((LPSTR)lParam) + 1);
	    textPtr = (LPSTR)USER_HEAP_ADDR(wndPtr->hText);
	    strcpy(textPtr, (LPSTR)lParam);
	    InvalidateRect(hWnd, NULL, TRUE);
	    break;

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

	GlobalUnlock(hWnd);
	return lResult;
}


static LONG PaintTextfn(HWND hwnd)
{
    PAINTSTRUCT ps;
    RECT rc;
    HDC hdc;
    HBRUSH hBrush;
    HANDLE hText;
    char *text;
    int textlen;
    WORD wFormat;

    WND *wndPtr = WIN_FindWndPtr(hwnd);
    LONG style = wndPtr->dwStyle;

    hdc = BeginPaint(hwnd, &ps);
    GetClientRect(hwnd, &rc);

    textlen = GetWindowTextLength(hwnd);
    hText = LocalAlloc(LMEM_MOVEABLE, textlen+1);
    text = LocalLock(hText);
    GetWindowText(hwnd, text, textlen+1);

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

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

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

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

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

    if (style & SS_NOPREFIX)
	wFormat |= DT_NOPREFIX;

    hBrush = SendMessage(GetParent(hwnd), WM_CTLCOLOR, (WORD)hdc,
		    MAKELONG(hwnd, CTLCOLOR_STATIC));
    if (hBrush == (HBRUSH)NULL) hBrush = GetStockObject(WHITE_BRUSH);
    FillRect(hdc, &rc, hBrush);
    DrawText(hdc, text, textlen, &rc, wFormat);

    LocalUnlock(hText);
    LocalFree(hText);
    GlobalUnlock(hwnd);
    EndPaint(hwnd, &ps);
}

static LONG PaintRectfn(HWND hwnd)
{
    PAINTSTRUCT ps;
    RECT rc;
    HDC hdc;
    HPEN hOldPen, hPen;
    HBRUSH hOldBrush, hBrush;

    WND *wndPtr = WIN_FindWndPtr(hwnd);

    hdc = BeginPaint(hwnd, &ps);
    GetClientRect(hwnd, &rc);
    
    switch (wndPtr->dwStyle & 0x0000000F)
    {
    case SS_BLACKRECT:
	hPen = CreatePen(PS_SOLID, 1, color_windowframe);
	hBrush = CreateSolidBrush(color_windowframe);
	break;

    case SS_GRAYRECT:
	hPen = CreatePen(PS_SOLID, 1, color_background);
	hBrush = CreateSolidBrush(color_background);
	break;

    case SS_WHITERECT:
	hPen = CreatePen(PS_SOLID, 1, color_window);
	hBrush = CreateSolidBrush(color_window);
	break;
    }

    hOldPen = (HPEN)SelectObject(hdc, (HANDLE)hPen);
    hOldBrush = (HBRUSH)SelectObject(hdc, (HANDLE)hBrush);
    Rectangle(hdc, rc.left, rc.top, rc.right, rc.bottom);

    SelectObject(hdc, (HANDLE)hOldPen);
    SelectObject(hdc, (HANDLE)hOldBrush);
    DeleteObject((HANDLE)hPen);
    DeleteObject((HANDLE)hBrush);

    GlobalUnlock(hwnd);
    EndPaint(hwnd, &ps);
}

static LONG PaintFramefn(HWND hwnd)
{
    PAINTSTRUCT ps;
    RECT rc;
    HDC hdc;
    HPEN hOldPen, hPen;
    HBRUSH hOldBrush, hBrush;

    WND *wndPtr = WIN_FindWndPtr(hwnd);

    hdc = BeginPaint(hwnd, &ps);
    GetClientRect(hwnd, &rc);
    
    switch (wndPtr->dwStyle & 0x0000000F)
    {
    case SS_BLACKFRAME:
	hPen = CreatePen(PS_SOLID, 1, color_windowframe);
	break;

    case SS_GRAYFRAME:
	hPen = CreatePen(PS_SOLID, 1, color_background);
	break;

    case SS_WHITEFRAME:
	hPen = CreatePen(PS_SOLID, 1, color_window);
	break;
    }

    hBrush = CreateSolidBrush(color_window);
    hOldPen = (HPEN)SelectObject(hdc, (HANDLE)hPen);
    hOldBrush = (HBRUSH)SelectObject(hdc, (HANDLE)hBrush);
    Rectangle(hdc, rc.left, rc.top, rc.right, rc.bottom);

    SelectObject(hdc, (HANDLE)hOldPen);
    SelectObject(hdc, (HANDLE)hOldBrush);
    DeleteObject((HANDLE)hPen);
    DeleteObject((HANDLE)hBrush);

    GlobalUnlock(hwnd);
    EndPaint(hwnd, &ps);
}


static LONG PaintIconfn(HWND hwnd)
{
    WND 	*wndPtr;
    PAINTSTRUCT ps;
    RECT 	rc;
    HDC 	hdc;
    LPSTR	textPtr;
    HICON	hIcon;

    wndPtr = WIN_FindWndPtr(hwnd);
    hdc = BeginPaint(hwnd, &ps);
    GetClientRect(hwnd, &rc);
    FillRect(hdc, &rc, GetStockObject(WHITE_BRUSH));
    textPtr = (LPSTR)USER_HEAP_ADDR(wndPtr->hText);
    printf("SS_ICON : textPtr='%s' / left=%d top=%d right=%d bottom=%d \n", 
    		textPtr, rc.left, rc.top, rc.right, rc.bottom);
/*
    SetWindowPos(hwnd, (HWND)NULL, 0, 0, 32, 32,
		SWP_NOZORDER | SWP_NOMOVE);
    GetClientRect(hwnd, &rc);
    printf("SS_ICON : textPtr='%s' / left=%d top=%d right=%d bottom=%d \n", 
    		textPtr, rc.left, rc.top, rc.right, rc.bottom);
*/
    hIcon = LoadIcon(wndPtr->hInstance, textPtr);
    DrawIcon(hdc, rc.left, rc.top, hIcon);
    EndPaint(hwnd, &ps);
    GlobalUnlock(hwnd);
}