/*
 * Interface code to StatusWindow widget/control
 *
 * Copyright 1996 Bruce Milner
 * Copyright 1998, 1999 Eric Kohl
 * Copyright 2002 Dimitrie O. Paun
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 * FIXME:
 * 1) Implement all CCS_* styles.
 * 2) Send WM_QUERYFORMAT
 * 3) Use DrawEdge to draw the SizeGrip
 * 4) Implement DrawStatusText and use it.
 *
 */

#include <string.h>

#include "winbase.h"
#include "wine/unicode.h"
#include "commctrl.h"
#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(statusbar);

typedef struct
{
    INT 	x;
    INT 	style;
    RECT	bound;
    LPWSTR	text;
    HICON       hIcon;
} STATUSWINDOWPART;

typedef struct
{
    HWND              Self;
    WORD              numParts;
    UINT              height;
    BOOL              simple;
    HWND              hwndToolTip;
    HFONT             hFont;
    HFONT             hDefaultFont;
    COLORREF          clrBk;		/* background color */
    BOOL              bUnicode;		/* unicode flag */
    STATUSWINDOWPART  part0;		/* simple window */
    STATUSWINDOWPART* parts;
} STATUSWINDOWINFO;

/*
 * Run tests using Waite Group Windows95 API Bible Vol. 1&2
 * The second cdrom contains executables drawstat.exe, gettext.exe,
 * simple.exe, getparts.exe, setparts.exe, statwnd.exe
 */

#define HORZ_BORDER 0
#define VERT_BORDER 2
#define HORZ_GAP    2

#define STATUSBAR_GetInfoPtr(hwnd) ((STATUSWINDOWINFO *)GetWindowLongW (hwnd, 0))

/* prototype */
static void
STATUSBAR_SetPartBounds (STATUSWINDOWINFO *infoPtr);

static inline LPCSTR debugstr_t(LPCWSTR text, BOOL isW)
{
  return isW ? debugstr_w(text) : debugstr_a((LPCSTR)text);
}

static void
STATUSBAR_DrawSizeGrip (HDC hdc, LPRECT lpRect)
{
    HPEN hOldPen;
    POINT pt;
    INT i;

    TRACE("draw size grip %d,%d - %d,%d\n", lpRect->left, lpRect->top, lpRect->right, lpRect->bottom);

    //FIXME: use DrawEdge to draw this
    pt.x = lpRect->right - 1;
    pt.y = lpRect->bottom - 1;

    hOldPen = SelectObject (hdc, GetSysColorPen (COLOR_3DFACE));
    MoveToEx (hdc, pt.x - 12, pt.y, NULL);
    LineTo (hdc, pt.x, pt.y);
    LineTo (hdc, pt.x, pt.y - 12);

    pt.x--;
    pt.y--;

    SelectObject (hdc, GetSysColorPen (COLOR_3DSHADOW));
    for (i = 1; i < 11; i += 4) {
	MoveToEx (hdc, pt.x - i, pt.y, NULL);
	LineTo (hdc, pt.x, pt.y - i);

	MoveToEx (hdc, pt.x - i-1, pt.y, NULL);
	LineTo (hdc, pt.x, pt.y - i-1);
    }

    SelectObject (hdc, GetSysColorPen (COLOR_3DHIGHLIGHT));
    for (i = 3; i < 13; i += 4) {
	MoveToEx (hdc, pt.x - i, pt.y, NULL);
	LineTo (hdc, pt.x, pt.y - i);
    }

    SelectObject (hdc, hOldPen);
}


static void 
STATUSBAR_DrawPart (HDC hdc, STATUSWINDOWPART *part)
{
    RECT r = part->bound;
    UINT border = BDR_SUNKENOUTER;

    TRACE("part bound %d,%d - %d,%d\n", r.left, r.top, r.right, r.bottom);
    if (part->style & SBT_POPOUT)
        border = BDR_RAISEDOUTER;
    else if (part->style & SBT_NOBORDERS)
        border = 0;

    DrawEdge(hdc, &r, border, BF_RECT|BF_ADJUST);

    /* draw the icon */
    if (part->hIcon) {
	INT cy = r.bottom - r.top;

	r.left += 2;
	DrawIconEx (hdc, r.left, r.top, part->hIcon, cy, cy, 0, 0, DI_NORMAL);
	r.left += cy;
    }

    /* now draw text */
    if (part->text) {
        int oldbkmode = SetBkMode(hdc, TRANSPARENT);
        LPWSTR p = (LPWSTR)part->text;
        UINT align = DT_LEFT;
        if (*p == L'\t') {
	    p++;
	    align = DT_CENTER;

	    if (*p == L'\t') {
	        p++;
	        align = DT_RIGHT;
	    }
        }
        r.left += 3;
        TRACE("%s at %d,%d - %d,%d\n", debugstr_w(p), r.left, r.top, r.right, r.bottom);
        DrawTextW (hdc, p, -1, &r, align|DT_VCENTER|DT_SINGLELINE);
	SetBkMode(hdc, oldbkmode);
    }
}


static void
STATUSBAR_RefreshPart (STATUSWINDOWINFO *infoPtr, STATUSWINDOWPART *part, HDC hdc, int itemID)
{
    HBRUSH hbrBk;
    HFONT  hOldFont;

    TRACE("item %d\n", itemID);
    if (!IsWindowVisible (infoPtr->Self))
        return;

    if (part->bound.right < part->bound.left) return;

    if (infoPtr->clrBk != CLR_DEFAULT)
	hbrBk = CreateSolidBrush (infoPtr->clrBk);
    else
	hbrBk = GetSysColorBrush (COLOR_3DFACE);
    FillRect(hdc, &part->bound, hbrBk);

    hOldFont = SelectObject (hdc, infoPtr->hFont ? infoPtr->hFont : infoPtr->hDefaultFont);

    if (part->style & SBT_OWNERDRAW) {
	DRAWITEMSTRUCT dis;

	dis.CtlID = GetWindowLongW (infoPtr->Self, GWL_ID);
	dis.itemID = itemID;
	dis.hwndItem = infoPtr->Self;
	dis.hDC = hdc;
	dis.rcItem = part->bound;
	dis.itemData = (INT)part->text;
	SendMessageW (GetParent (infoPtr->Self), WM_DRAWITEM,
		(WPARAM)dis.CtlID, (LPARAM)&dis);
    } else
	STATUSBAR_DrawPart (hdc, part);

    SelectObject (hdc, hOldFont);

    if (infoPtr->clrBk != CLR_DEFAULT)
	DeleteObject (hbrBk);

    if (GetWindowLongW (infoPtr->Self, GWL_STYLE) & SBARS_SIZEGRIP) {
	RECT rect;

	GetClientRect (infoPtr->Self, &rect);
	STATUSBAR_DrawSizeGrip (hdc, &rect);
    }
}


static LRESULT
STATUSBAR_Refresh (STATUSWINDOWINFO *infoPtr, HDC hdc)
{
    int      i;
    RECT   rect;
    HBRUSH hbrBk;
    HFONT  hOldFont;

    TRACE("\n");
    if (!IsWindowVisible(infoPtr->Self))
        return 0;

    STATUSBAR_SetPartBounds(infoPtr);

    GetClientRect (infoPtr->Self, &rect);

    if (infoPtr->clrBk != CLR_DEFAULT)
	hbrBk = CreateSolidBrush (infoPtr->clrBk);
    else
	hbrBk = GetSysColorBrush (COLOR_3DFACE);
    FillRect(hdc, &rect, hbrBk);

    hOldFont = SelectObject (hdc, infoPtr->hFont ? infoPtr->hFont : infoPtr->hDefaultFont);

    if (infoPtr->simple) {
	STATUSBAR_RefreshPart (infoPtr, &infoPtr->part0, hdc, 0);
    } else {
	for (i = 0; i < infoPtr->numParts; i++) {
	    if (infoPtr->parts[i].style & SBT_OWNERDRAW) {
		DRAWITEMSTRUCT dis;

		dis.CtlID = GetWindowLongW (infoPtr->Self, GWL_ID);
		dis.itemID = i;
		dis.hwndItem = infoPtr->Self;
		dis.hDC = hdc;
		dis.rcItem = infoPtr->parts[i].bound;
		dis.itemData = (INT)infoPtr->parts[i].text;
		SendMessageW (GetParent (infoPtr->Self), WM_DRAWITEM,
			(WPARAM)dis.CtlID, (LPARAM)&dis);
	    } else
		STATUSBAR_RefreshPart (infoPtr, &infoPtr->parts[i], hdc, i);
	}
    }

    SelectObject (hdc, hOldFont);

    if (infoPtr->clrBk != CLR_DEFAULT)
	DeleteObject (hbrBk);

    if (GetWindowLongW (infoPtr->Self, GWL_STYLE) & SBARS_SIZEGRIP)
	STATUSBAR_DrawSizeGrip (hdc, &rect);

    return 0;
}


static void
STATUSBAR_SetPartBounds (STATUSWINDOWINFO *infoPtr)
{
    STATUSWINDOWPART *part;
    RECT rect, *r;
    int	i;

    /* get our window size */
    GetClientRect (infoPtr->Self, &rect);
    TRACE("client wnd size is %d,%d - %d,%d\n", rect.left, rect.top, rect.right, rect.bottom);

    rect.top += VERT_BORDER;

    /* set bounds for simple rectangle */
    infoPtr->part0.bound = rect;

    /* set bounds for non-simple rectangles */
    for (i = 0; i < infoPtr->numParts; i++) {
	part = &infoPtr->parts[i];
	r = &infoPtr->parts[i].bound;
	r->top = rect.top;
	r->bottom = rect.bottom;
	if (i == 0)
	    r->left = 0;
	else
	    r->left = infoPtr->parts[i-1].bound.right + HORZ_GAP;
	if (part->x == -1)
	    r->right = rect.right;
	else
	    r->right = part->x;

	if (infoPtr->hwndToolTip) {
	    TTTOOLINFOW ti;

	    ti.cbSize = sizeof(TTTOOLINFOW);
	    ti.hwnd = infoPtr->Self;
	    ti.uId = i;
	    ti.rect = *r;
	    SendMessageW (infoPtr->hwndToolTip, TTM_NEWTOOLRECTW,
			    0, (LPARAM)&ti);
	}
    }
}


static LRESULT
STATUSBAR_Relay2Tip (STATUSWINDOWINFO *infoPtr, UINT uMsg,
		     WPARAM wParam, LPARAM lParam)
{
    MSG msg;

    msg.hwnd = infoPtr->Self;
    msg.message = uMsg;
    msg.wParam = wParam;
    msg.lParam = lParam;
    msg.time = GetMessageTime ();
    msg.pt.x = LOWORD(GetMessagePos ());
    msg.pt.y = HIWORD(GetMessagePos ());

    return SendMessageW (infoPtr->hwndToolTip, TTM_RELAYEVENT, 0, (LPARAM)&msg);
}


static BOOL
STATUSBAR_GetBorders (INT out[])
{
    TRACE("\n");
    out[0] = HORZ_BORDER; /* horizontal border width */
    out[1] = VERT_BORDER; /* vertical border width */
    out[2] = HORZ_GAP; /* width of border between rectangles */

    return TRUE;
}


static HICON
STATUSBAR_GetIcon (STATUSWINDOWINFO *infoPtr, INT nPart)
{
    TRACE("%d\n", nPart);
    if ((nPart < -1) || (nPart >= infoPtr->numParts))
	return 0;

    if (nPart == -1)
        return (infoPtr->part0.hIcon);
    else
        return (infoPtr->parts[nPart].hIcon);
}


static INT
STATUSBAR_GetParts (STATUSWINDOWINFO *infoPtr, INT num_parts, INT parts[])
{
    INT   i;

    TRACE("(%d)\n", num_parts);
    if (parts) {
	for (i = 0; i < num_parts; i++) {
	    parts[i] = infoPtr->parts[i].x;
	}
    }
    return infoPtr->numParts;
}


static BOOL
STATUSBAR_GetRect (STATUSWINDOWINFO *infoPtr, INT nPart, LPRECT rect)
{
    TRACE("part %d\n", nPart);
    if (infoPtr->simple)
	*rect = infoPtr->part0.bound;
    else
	*rect = infoPtr->parts[nPart].bound;
    return TRUE;
}


static LRESULT
STATUSBAR_GetTextA (STATUSWINDOWINFO *infoPtr, INT nPart, LPSTR buf)
{
    STATUSWINDOWPART *part;
    LRESULT result;

    TRACE("part %d\n", nPart);
    if (infoPtr->simple)
	part = &infoPtr->part0;
    else
	part = &infoPtr->parts[nPart];

    if (part->style & SBT_OWNERDRAW)
	result = (LRESULT)part->text;
    else {
        DWORD len = part->text ? WideCharToMultiByte( CP_ACP, 0, part->text, -1,
                                                      NULL, 0, NULL, NULL ) - 1 : 0;
        result = MAKELONG( len, part->style );
        if (part->text && buf)
            WideCharToMultiByte( CP_ACP, 0, part->text, -1, buf, len+1, NULL, NULL );
    }
    return result;
}


static LRESULT
STATUSBAR_GetTextW (STATUSWINDOWINFO *infoPtr, INT nPart, LPWSTR buf)
{
    STATUSWINDOWPART *part;
    LRESULT result;

    TRACE("part %d\n", nPart);
    if (infoPtr->simple)
	part = &infoPtr->part0;
    else
	part = &infoPtr->parts[nPart];

    if (part->style & SBT_OWNERDRAW)
	result = (LRESULT)part->text;
    else {
	result = part->text ? strlenW (part->text) : 0;
	result |= (part->style << 16);
	if (part->text && buf)
	    strcpyW (buf, part->text);
    }
    return result;
}


static LRESULT
STATUSBAR_GetTextLength (STATUSWINDOWINFO *infoPtr, INT nPart)
{
    STATUSWINDOWPART *part;
    DWORD result;

    TRACE("part %d\n", nPart);
    if (infoPtr->simple)
	part = &infoPtr->part0;
    else
	part = &infoPtr->parts[nPart];

    if (part->text)
	result = strlenW(part->text);
    else
	result = 0;

    result |= (part->style << 16);
    return result;
}

static LRESULT
STATUSBAR_GetTipTextA (STATUSWINDOWINFO *infoPtr, INT id, LPSTR tip, INT size)
{
    TRACE("\n");
    if (tip) {
        CHAR buf[INFOTIPSIZE];
        buf[0]='\0';

        if (infoPtr->hwndToolTip) {
            TTTOOLINFOA ti;
            ti.cbSize = sizeof(TTTOOLINFOA);
            ti.hwnd = infoPtr->Self;
            ti.uId = id;
            ti.lpszText = buf;
            SendMessageA (infoPtr->hwndToolTip, TTM_GETTEXTA, 0, (LPARAM)&ti);
        }
        lstrcpynA (tip, buf, size);
    }
    return 0;
}


static LRESULT
STATUSBAR_GetTipTextW (STATUSWINDOWINFO *infoPtr, INT id, LPWSTR tip, INT size)
{
    TRACE("\n");
    if (tip) {
        WCHAR buf[INFOTIPSIZE];
        buf[0]=0;

	if (infoPtr->hwndToolTip) {
	    TTTOOLINFOW ti;
	    ti.cbSize = sizeof(TTTOOLINFOW);
	    ti.hwnd = infoPtr->Self;
	    ti.uId = id;
            ti.lpszText = buf;
	    SendMessageW(infoPtr->hwndToolTip, TTM_GETTEXTW, 0, (LPARAM)&ti);
	}
	lstrcpynW(tip, buf, size);
    }

    return 0;
}


static COLORREF
STATUSBAR_SetBkColor (STATUSWINDOWINFO *infoPtr, COLORREF color)
{
    COLORREF oldBkColor;

    oldBkColor = infoPtr->clrBk;
    infoPtr->clrBk = color;
    InvalidateRect(infoPtr->Self, NULL, FALSE);

    TRACE("CREF: %08lx -> %08lx\n", oldBkColor, infoPtr->clrBk);
    return oldBkColor;
}


static BOOL
STATUSBAR_SetIcon (STATUSWINDOWINFO *infoPtr, INT nPart, HICON hIcon)
{
    if ((nPart < -1) || (nPart >= infoPtr->numParts))
	return FALSE;

    TRACE("setting part %d\n", nPart);

    if (nPart == -1) {
	if (infoPtr->part0.hIcon == hIcon) /* same as - no redraw */
	    return TRUE;
	infoPtr->part0.hIcon = hIcon;
	if (infoPtr->simple)
            InvalidateRect(infoPtr->Self, &infoPtr->part0.bound, FALSE);
    } else {
	if (infoPtr->parts[nPart].hIcon == hIcon) /* same as - no redraw */
	    return TRUE;

	infoPtr->parts[nPart].hIcon = hIcon;
	if (!(infoPtr->simple))
            InvalidateRect(infoPtr->Self, &infoPtr->parts[nPart].bound, FALSE);
    }
    return TRUE;
}


static BOOL
STATUSBAR_SetMinHeight (STATUSWINDOWINFO *infoPtr, INT height)
{

    TRACE("(height=%d)\n", height);
    if (IsWindowVisible (infoPtr->Self)) {
	INT  width, x, y;
	RECT parent_rect;

	GetClientRect (GetParent (infoPtr->Self), &parent_rect);
	infoPtr->height = height + VERT_BORDER;
	width = parent_rect.right - parent_rect.left;
	x = parent_rect.left;
	y = parent_rect.bottom - infoPtr->height;
	MoveWindow (infoPtr->Self, parent_rect.left,
		      parent_rect.bottom - infoPtr->height,
		      width, infoPtr->height, TRUE);
	STATUSBAR_SetPartBounds (infoPtr);
    }

    return TRUE;
}


static BOOL
STATUSBAR_SetParts (STATUSWINDOWINFO *infoPtr, INT count, LPINT parts)
{
    STATUSWINDOWPART *tmp;
    int	i, oldNumParts;

    TRACE("(%d,%p)\n", count, parts);

    if (infoPtr->simple)
	infoPtr->simple = FALSE;

    oldNumParts = infoPtr->numParts;
    infoPtr->numParts = count;
    if (oldNumParts > infoPtr->numParts) {
	for (i = infoPtr->numParts ; i < oldNumParts; i++) {
	    if (infoPtr->parts[i].text && !(infoPtr->parts[i].style & SBT_OWNERDRAW))
		COMCTL32_Free (infoPtr->parts[i].text);
	}
    } else if (oldNumParts < infoPtr->numParts) {
	tmp = COMCTL32_Alloc (sizeof(STATUSWINDOWPART) * infoPtr->numParts);
	if (!tmp) return FALSE;
	for (i = 0; i < oldNumParts; i++) {
	    tmp[i] = infoPtr->parts[i];
	}
	if (infoPtr->parts)
	    COMCTL32_Free (infoPtr->parts);
	infoPtr->parts = tmp;
    }
    if (oldNumParts == infoPtr->numParts) {
	for (i=0; i < oldNumParts; i++)
	    if (infoPtr->parts[i].x != parts[i])
		break;
	if (i==oldNumParts) /* Unchanged? no need to redraw! */
	    return TRUE;
    }
    
    for (i = 0; i < infoPtr->numParts; i++)
	infoPtr->parts[i].x = parts[i];

    if (infoPtr->hwndToolTip) {
	INT nTipCount, i;
	TTTOOLINFOW ti;

	ZeroMemory (&ti, sizeof(TTTOOLINFOW));
	ti.cbSize = sizeof(TTTOOLINFOW);
	ti.hwnd = infoPtr->Self;

	nTipCount = SendMessageW (infoPtr->hwndToolTip, TTM_GETTOOLCOUNT, 0, 0);
	if (nTipCount < infoPtr->numParts) {
	    /* add tools */
	    for (i = nTipCount; i < infoPtr->numParts; i++) {
		TRACE("add tool %d\n", i);
		ti.uId = i;
		SendMessageW (infoPtr->hwndToolTip, TTM_ADDTOOLW,
				0, (LPARAM)&ti);
	    }
	}
	else if (nTipCount > infoPtr->numParts) {
	    /* delete tools */
	    for (i = nTipCount - 1; i >= infoPtr->numParts; i--) {
		TRACE("delete tool %d\n", i);
		ti.uId = i;
		SendMessageW (infoPtr->hwndToolTip, TTM_DELTOOLW,
				0, (LPARAM)&ti);
	    }
	}
    }
    STATUSBAR_SetPartBounds (infoPtr);
    InvalidateRect(infoPtr->Self, NULL, FALSE);
    return TRUE;
}


static BOOL
STATUSBAR_SetTextT (STATUSWINDOWINFO *infoPtr, INT nPart, WORD style, 
		    LPCWSTR text, BOOL isW)
{
    STATUSWINDOWPART *part=NULL;
    BOOL changed = FALSE;

    TRACE("part %d, text %s\n", nPart, debugstr_t(text, isW));

    if (nPart == 0x00ff)
	part = &infoPtr->part0;
    else if (!infoPtr->simple && infoPtr->parts)
	part = &infoPtr->parts[nPart];
    if (!part) return FALSE;

    if (part->style != style)
	changed = TRUE;

    part->style = style;
    if (style & SBT_OWNERDRAW) {
	if (part->text == text)
	    return TRUE;
	part->text = (LPWSTR)text;
    } else {
	LPWSTR ntext;

	if (text && !isW) {
	    LPCSTR atxt = (LPCSTR)text;
            DWORD len = MultiByteToWideChar( CP_ACP, 0, atxt, -1, NULL, 0 );
	    ntext = COMCTL32_Alloc( (len + 1)*sizeof(WCHAR) );
	    if (!ntext) return FALSE;
            MultiByteToWideChar( CP_ACP, 0, atxt, -1, ntext, len );
	} else if (text) {
	    ntext = COMCTL32_Alloc( (strlenW(text) + 1)*sizeof(WCHAR) );
	    if (!ntext) return FALSE;
	    strcpyW (ntext, text);
	} else ntext = 0;

	/* check if text is unchanged -> no need to redraw */
	if (text) {
	    if (!changed && part->text && !lstrcmpW(ntext, part->text)) {
		if (!isW) COMCTL32_Free(ntext);
		return TRUE;
	    }
	} else {
	    if (!changed && !part->text) 
		return TRUE;
	}

	if (part->text)
	    COMCTL32_Free (part->text);
	part->text = ntext;
    }
    InvalidateRect(infoPtr->Self, &part->bound, FALSE);

    return TRUE;
}


static LRESULT
STATUSBAR_SetTipTextA (STATUSWINDOWINFO *infoPtr, INT id, LPSTR text)
{
    TRACE("part %d: \"%s\"\n", id, text);
    if (infoPtr->hwndToolTip) {
	TTTOOLINFOA ti;
	ti.cbSize = sizeof(TTTOOLINFOA);
	ti.hwnd = infoPtr->Self;
	ti.uId = id;
	ti.hinst = 0;
	ti.lpszText = text;
	SendMessageA (infoPtr->hwndToolTip, TTM_UPDATETIPTEXTA,
			0, (LPARAM)&ti);
    }

    return 0;
}


static LRESULT
STATUSBAR_SetTipTextW (STATUSWINDOWINFO *infoPtr, INT id, LPWSTR text)
{
    TRACE("part %d: \"%s\"\n", id, debugstr_w(text));
    if (infoPtr->hwndToolTip) {
	TTTOOLINFOW ti;
	ti.cbSize = sizeof(TTTOOLINFOW);
	ti.hwnd = infoPtr->Self;
	ti.uId = id;
	ti.hinst = 0;
	ti.lpszText = text;
	SendMessageW (infoPtr->hwndToolTip, TTM_UPDATETIPTEXTW,
			0, (LPARAM)&ti);
    }

    return 0;
}


inline static LRESULT
STATUSBAR_SetUnicodeFormat (STATUSWINDOWINFO *infoPtr, BOOL bUnicode)
{
    BOOL bOld = infoPtr->bUnicode;

    TRACE("(0x%x)\n", bUnicode);
    infoPtr->bUnicode = bUnicode;

    return bOld;
}


static BOOL
STATUSBAR_Simple (STATUSWINDOWINFO *infoPtr, BOOL simple)
{
    NMHDR  nmhdr;

    TRACE("(simple=%d)\n", simple);
    if (infoPtr->simple == simple) /* no need to change */
	return TRUE;

    infoPtr->simple = simple;

    /* send notification */
    nmhdr.hwndFrom = infoPtr->Self;
    nmhdr.idFrom = GetWindowLongW (infoPtr->Self, GWL_ID);
    nmhdr.code = SBN_SIMPLEMODECHANGE;
    SendMessageW (GetParent (infoPtr->Self), WM_NOTIFY, 0, (LPARAM)&nmhdr);
    InvalidateRect(infoPtr->Self, NULL, FALSE);
    return TRUE;
}


static LRESULT
STATUSBAR_WMDestroy (STATUSWINDOWINFO *infoPtr)
{
    int	i;

    TRACE("\n");
    for (i = 0; i < infoPtr->numParts; i++) {
	if (infoPtr->parts[i].text && !(infoPtr->parts[i].style & SBT_OWNERDRAW))
	    COMCTL32_Free (infoPtr->parts[i].text);
    }
    if (infoPtr->part0.text && !(infoPtr->part0.style & SBT_OWNERDRAW))
	COMCTL32_Free (infoPtr->part0.text);
    COMCTL32_Free (infoPtr->parts);

    /* delete default font */
    if (infoPtr->hDefaultFont)
	DeleteObject (infoPtr->hDefaultFont);

    /* delete tool tip control */
    if (infoPtr->hwndToolTip)
	DestroyWindow (infoPtr->hwndToolTip);

    COMCTL32_Free (infoPtr);
    SetWindowLongW(infoPtr->Self, 0, 0);
    return 0;
}


static LRESULT
STATUSBAR_WMCreate (HWND hwnd, LPCREATESTRUCTA lpCreate)
{
    STATUSWINDOWINFO *infoPtr;
    NONCLIENTMETRICSW nclm;
    DWORD dwStyle;
    RECT rect;
    int	width, len, textHeight = 0;
    HDC	hdc;

    TRACE("\n");
    infoPtr = (STATUSWINDOWINFO*)COMCTL32_Alloc (sizeof(STATUSWINDOWINFO));
    if (!infoPtr) goto create_fail;
    SetWindowLongW (hwnd, 0, (DWORD)infoPtr);

    infoPtr->Self = hwnd;
    infoPtr->numParts = 1;
    infoPtr->parts = 0;
    infoPtr->simple = FALSE;
    infoPtr->clrBk = CLR_DEFAULT;
    infoPtr->hFont = 0;

    /* FIXME: send unicode parent notification query (WM_QUERYFORMAT) here */

    GetClientRect (hwnd, &rect);
    InvalidateRect (hwnd, &rect, 0);
    UpdateWindow(hwnd);

    ZeroMemory (&nclm, sizeof(nclm));
    nclm.cbSize = sizeof(nclm);
    SystemParametersInfoW (SPI_GETNONCLIENTMETRICS, nclm.cbSize, &nclm, 0);
    infoPtr->hDefaultFont = CreateFontIndirectW (&nclm.lfStatusFont);

    /* initialize simple case */
    infoPtr->part0.bound = rect;
    infoPtr->part0.text = 0;
    infoPtr->part0.x = 0;
    infoPtr->part0.style = 0;
    infoPtr->part0.hIcon = 0;

    /* initialize first part */
    infoPtr->parts = COMCTL32_Alloc (sizeof(STATUSWINDOWPART));
    if (!infoPtr->parts) goto create_fail;
    infoPtr->parts[0].bound = rect;
    infoPtr->parts[0].text = 0;
    infoPtr->parts[0].x = -1;
    infoPtr->parts[0].style = 0;
    infoPtr->parts[0].hIcon = 0;

    if (IsWindowUnicode (hwnd)) {
	infoPtr->bUnicode = TRUE;
	if (lpCreate->lpszName &&
	    (len = strlenW ((LPCWSTR)lpCreate->lpszName))) {
	    infoPtr->parts[0].text = COMCTL32_Alloc ((len + 1)*sizeof(WCHAR));
	    if (!infoPtr->parts[0].text) goto create_fail;
	    strcpyW (infoPtr->parts[0].text, (LPCWSTR)lpCreate->lpszName);
	}
    }
    else {
	if (lpCreate->lpszName &&
	    (len = strlen((LPCSTR)lpCreate->lpszName))) {
            DWORD lenW = MultiByteToWideChar( CP_ACP, 0, (LPCSTR)lpCreate->lpszName, -1, NULL, 0 );
	    infoPtr->parts[0].text = COMCTL32_Alloc (lenW*sizeof(WCHAR));
	    if (!infoPtr->parts[0].text) goto create_fail;
            MultiByteToWideChar( CP_ACP, 0, (LPCSTR)lpCreate->lpszName, -1,
                                 infoPtr->parts[0].text, lenW );
	}
    }

    dwStyle = GetWindowLongW (hwnd, GWL_STYLE);

    /* statusbars on managed windows should not have SIZEGRIP style */
    if ((dwStyle & SBARS_SIZEGRIP) && lpCreate->hwndParent)
        if (GetWindowLongW (lpCreate->hwndParent, GWL_EXSTYLE) & WS_EX_MANAGED)
            SetWindowLongW (hwnd, GWL_STYLE, dwStyle & ~SBARS_SIZEGRIP);

    if ((hdc = GetDC (0))) {
	TEXTMETRICW tm;
	HFONT hOldFont;

	hOldFont = SelectObject (hdc, infoPtr->hDefaultFont);
	GetTextMetricsW (hdc, &tm);
	textHeight = tm.tmHeight;
	SelectObject (hdc, hOldFont);
	ReleaseDC (0, hdc);
    }
    TRACE("    textHeight=%d\n", textHeight);

    if (dwStyle & SBT_TOOLTIPS) {
	infoPtr->hwndToolTip =
	    CreateWindowExW (0, TOOLTIPS_CLASSW, NULL, 0,
			       CW_USEDEFAULT, CW_USEDEFAULT,
			       CW_USEDEFAULT, CW_USEDEFAULT,
			     hwnd, 0,
			     GetWindowLongW (hwnd, GWL_HINSTANCE), NULL);

	if (infoPtr->hwndToolTip) {
	    NMTOOLTIPSCREATED nmttc;

	    nmttc.hdr.hwndFrom = hwnd;
	    nmttc.hdr.idFrom = GetWindowLongW (hwnd, GWL_ID);
	    nmttc.hdr.code = NM_TOOLTIPSCREATED;
	    nmttc.hwndToolTips = infoPtr->hwndToolTip;

	    SendMessageW (lpCreate->hwndParent, WM_NOTIFY,
			    (WPARAM)nmttc.hdr.idFrom, (LPARAM)&nmttc);
	} 
    }

    if (!(dwStyle & CCS_NORESIZE)) { /* don't resize wnd if it doesn't want it ! */
        GetClientRect (GetParent (hwnd), &rect);
        width = rect.right - rect.left;
        infoPtr->height = textHeight + 4 + VERT_BORDER;
        SetWindowPos(hwnd, 0, lpCreate->x, lpCreate->y - 1,
			width, infoPtr->height, SWP_NOZORDER);
        STATUSBAR_SetPartBounds (infoPtr);
    }

    return 0;
    
create_fail:
    TRACE("    failed!\n");
    if (infoPtr) STATUSBAR_WMDestroy(infoPtr);
    return -1;
}


/* in contrast to SB_GETTEXT*, WM_GETTEXT handles the text
 * of the first part only (usual behaviour) */
static INT
STATUSBAR_WMGetText (STATUSWINDOWINFO *infoPtr, INT size, LPWSTR buf)
{
    INT len;

    TRACE("\n");
    if (!(infoPtr->parts[0].text))
        return 0;
    if (infoPtr->bUnicode)
        len = strlenW (infoPtr->parts[0].text);
    else
        len = WideCharToMultiByte( CP_ACP, 0, infoPtr->parts[0].text, -1, NULL, 0, NULL, NULL )-1;

    if (size > len) {
	if (infoPtr->bUnicode)
	    strcpyW (buf, infoPtr->parts[0].text);
	else
            WideCharToMultiByte( CP_ACP, 0, infoPtr->parts[0].text, -1,
                                 (LPSTR)buf, len+1, NULL, NULL );
	return len;
    }

    return -1;
}


static BOOL
STATUSBAR_WMNCHitTest (STATUSWINDOWINFO *infoPtr, INT x, INT y)
{
    if (GetWindowLongW (infoPtr->Self, GWL_STYLE) & SBARS_SIZEGRIP) {
	RECT  rect;
	POINT pt;

	GetClientRect (infoPtr->Self, &rect);

	pt.x = x;
	pt.y = y;
	ScreenToClient (infoPtr->Self, &pt);

	rect.left = rect.right - 13;
	rect.top += 2;

	if (PtInRect (&rect, pt))
	    return HTBOTTOMRIGHT;
    }

    return HTERROR;
}


static LRESULT
STATUSBAR_WMPaint (STATUSWINDOWINFO *infoPtr, HDC hdc)
{
    PAINTSTRUCT ps;

    TRACE("\n");
    if (hdc) return STATUSBAR_Refresh (infoPtr, hdc);
    hdc = BeginPaint (infoPtr->Self, &ps);
    STATUSBAR_Refresh (infoPtr, hdc);
    EndPaint (infoPtr->Self, &ps);

    return 0;
}


static LRESULT
STATUSBAR_WMSetFont (STATUSWINDOWINFO *infoPtr, HFONT font, BOOL redraw)
{
    infoPtr->hFont = font;
    TRACE("%04x\n", infoPtr->hFont);
    if (redraw)
        InvalidateRect(infoPtr->Self, NULL, FALSE);

    return 0;
}


static BOOL
STATUSBAR_WMSetText (STATUSWINDOWINFO *infoPtr, LPCSTR text)
{
    STATUSWINDOWPART *part;
    int len;

    TRACE("\n");
    if (infoPtr->numParts == 0)
	return FALSE;

    part = &infoPtr->parts[0];
    /* duplicate string */
    if (part->text)
        COMCTL32_Free (part->text);
    part->text = 0;
    if (infoPtr->bUnicode) {
	if (text && (len = strlenW((LPCWSTR)text))) {
	    part->text = COMCTL32_Alloc ((len+1)*sizeof(WCHAR));
	    if (!part->text) return FALSE;
	    strcpyW (part->text, (LPCWSTR)text);
	}
    }
    else {
	if (text && (len = lstrlenA(text))) {
            DWORD lenW = MultiByteToWideChar( CP_ACP, 0, text, -1, NULL, 0 );
            part->text = COMCTL32_Alloc (lenW*sizeof(WCHAR));
	    if (!part->text) return FALSE;
            MultiByteToWideChar( CP_ACP, 0, text, -1, part->text, lenW );
	}
    }

    InvalidateRect(infoPtr->Self, &part->bound, FALSE);

    return TRUE;
}


static BOOL
STATUSBAR_WMSize (STATUSWINDOWINFO *infoPtr, WORD flags)
{
    INT  width, x, y;
    RECT parent_rect;

    /* Need to resize width to match parent */
    TRACE("flags %04x\n", flags);

    if (flags != SIZE_RESTORED) {
	WARN("flags MUST be SIZE_RESTORED\n");
	return FALSE;
    }
    if (GetWindowLongW(infoPtr->Self, GWL_STYLE) & CCS_NORESIZE) return FALSE;
    
    /* width and height don't apply */
    GetClientRect (GetParent(infoPtr->Self), &parent_rect);
    width = parent_rect.right - parent_rect.left;
    x = parent_rect.left;
    y = parent_rect.bottom - infoPtr->height;
    MoveWindow (infoPtr->Self, parent_rect.left, 
		parent_rect.bottom - infoPtr->height,
		width, infoPtr->height, TRUE);
    STATUSBAR_SetPartBounds (infoPtr);
    return TRUE;
}


static LRESULT
STATUSBAR_SendNotify (HWND hwnd, UINT code)
{
    NMHDR  nmhdr;

    TRACE("code %04x\n", code);
    nmhdr.hwndFrom = hwnd;
    nmhdr.idFrom = GetWindowLongW (hwnd, GWL_ID);
    nmhdr.code = code;
    SendMessageW (GetParent (hwnd), WM_NOTIFY, 0, (LPARAM)&nmhdr);
    return 0;
}



static LRESULT WINAPI
StatusWindowProc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    STATUSWINDOWINFO *infoPtr = STATUSBAR_GetInfoPtr(hwnd);
    INT nPart = ((INT) wParam) & 0x00ff;
    LRESULT res;

    TRACE("hwnd=%x msg=%x wparam=%x lparam=%lx\n", hwnd, msg, wParam, lParam);
    if (!infoPtr && msg != WM_CREATE)
        return DefWindowProcW (hwnd, msg, wParam, lParam);

    switch (msg) {
	case SB_GETBORDERS:
	    return STATUSBAR_GetBorders ((INT *)lParam);

	case SB_GETICON:
	    return STATUSBAR_GetIcon (infoPtr, nPart);

	case SB_GETPARTS:
	    return STATUSBAR_GetParts (infoPtr, (INT)wParam, (INT *)lParam);

	case SB_GETRECT:
	    return STATUSBAR_GetRect (infoPtr, nPart, (LPRECT)lParam);

	case SB_GETTEXTA:
	    return STATUSBAR_GetTextA (infoPtr, nPart, (LPSTR)lParam);

	case SB_GETTEXTW:
	    return STATUSBAR_GetTextW (infoPtr, nPart, (LPWSTR)lParam);

	case SB_GETTEXTLENGTHA:
	case SB_GETTEXTLENGTHW:
	    return STATUSBAR_GetTextLength (infoPtr, nPart);

	case SB_GETTIPTEXTA:
	    return STATUSBAR_GetTipTextA (infoPtr,  LOWORD(wParam), (LPSTR)lParam,  HIWORD(wParam));

	case SB_GETTIPTEXTW:
	    return STATUSBAR_GetTipTextW (infoPtr,  LOWORD(wParam), (LPWSTR)lParam,  HIWORD(wParam));

	case SB_GETUNICODEFORMAT:
	    return infoPtr->bUnicode;

	case SB_ISSIMPLE:
	    return infoPtr->simple;

	case SB_SETBKCOLOR:
	    return STATUSBAR_SetBkColor (infoPtr, (COLORREF)lParam);

	case SB_SETICON:
	    return STATUSBAR_SetIcon (infoPtr, nPart, (HICON)lParam);

	case SB_SETMINHEIGHT:
	    return STATUSBAR_SetMinHeight (infoPtr, (INT)wParam);

	case SB_SETPARTS:	
	    return STATUSBAR_SetParts (infoPtr, (INT)wParam, (LPINT)lParam);

	case SB_SETTEXTA:
	    return STATUSBAR_SetTextT (infoPtr, nPart, wParam & 0xff00, (LPCWSTR)lParam, FALSE);

	case SB_SETTEXTW:
	    return STATUSBAR_SetTextT (infoPtr, nPart, wParam & 0xff00, (LPCWSTR)lParam, TRUE);

	case SB_SETTIPTEXTA:
	    return STATUSBAR_SetTipTextA (infoPtr, (INT)wParam, (LPSTR)lParam);

	case SB_SETTIPTEXTW:
	    return STATUSBAR_SetTipTextW (infoPtr, (INT)wParam, (LPWSTR)lParam);

	case SB_SETUNICODEFORMAT:
	    return STATUSBAR_SetUnicodeFormat (infoPtr, (BOOL)wParam);

	case SB_SIMPLE:
	    return STATUSBAR_Simple (infoPtr, (BOOL)wParam);

	case WM_CREATE:
	    return STATUSBAR_WMCreate (hwnd, (LPCREATESTRUCTA)lParam);

	case WM_DESTROY:
	    return STATUSBAR_WMDestroy (infoPtr);

	case WM_GETFONT:
	    return infoPtr->hFont? infoPtr->hFont : infoPtr->hDefaultFont;

	case WM_GETTEXT:
            return STATUSBAR_WMGetText (infoPtr, (INT)wParam, (LPWSTR)lParam);

	case WM_GETTEXTLENGTH:
	    return STATUSBAR_GetTextLength (infoPtr, 0);

	case WM_LBUTTONDBLCLK:
            return STATUSBAR_SendNotify (hwnd, NM_DBLCLK);

	case WM_LBUTTONUP:
	    return STATUSBAR_SendNotify (hwnd, NM_CLICK);

	case WM_MOUSEMOVE:
	    return STATUSBAR_Relay2Tip (infoPtr, msg, wParam, lParam);

	case WM_NCHITTEST:
	    res = STATUSBAR_WMNCHitTest(infoPtr, (INT)LOWORD(lParam),
			                (INT)HIWORD(lParam));
	    if (res != HTERROR) return res;
	    return DefWindowProcW (hwnd, msg, wParam, lParam);

	case WM_NCLBUTTONUP:
	case WM_NCLBUTTONDOWN:
    	    PostMessageW (GetParent (hwnd), msg, wParam, lParam);
	    return 0;

	case WM_PAINT:
	    return STATUSBAR_WMPaint (infoPtr, (HDC)wParam);

	case WM_RBUTTONDBLCLK:
	    return STATUSBAR_SendNotify (hwnd, NM_RDBLCLK);

	case WM_RBUTTONUP:
	    return STATUSBAR_SendNotify (hwnd, NM_RCLICK);

	case WM_SETFONT:
	    return STATUSBAR_WMSetFont (infoPtr, (HFONT)wParam, LOWORD(lParam));

	case WM_SETTEXT:
	    return STATUSBAR_WMSetText (infoPtr, (LPCSTR)lParam);


	case WM_SIZE:
	    if (STATUSBAR_WMSize (infoPtr, (WORD)wParam)) return 0;
            return DefWindowProcW (hwnd, msg, wParam, lParam);

	default:
	    if (msg >= WM_USER)
		ERR("unknown msg %04x wp=%04x lp=%08lx\n",
		     msg, wParam, lParam);
	    return DefWindowProcW (hwnd, msg, wParam, lParam);
    }
    return 0;
}


/***********************************************************************
 * STATUS_Register [Internal]
 *
 * Registers the status window class.
 */

void
STATUS_Register (void)
{
    WNDCLASSW wndClass;

    ZeroMemory (&wndClass, sizeof(WNDCLASSW));
    wndClass.style         = CS_GLOBALCLASS | CS_DBLCLKS | CS_VREDRAW;
    wndClass.lpfnWndProc   = (WNDPROC)StatusWindowProc;
    wndClass.cbClsExtra    = 0;
    wndClass.cbWndExtra    = sizeof(STATUSWINDOWINFO *);
    wndClass.hCursor       = LoadCursorW (0, IDC_ARROWW);
    wndClass.hbrBackground = (HBRUSH)(COLOR_3DFACE + 1);
    wndClass.lpszClassName = STATUSCLASSNAMEW;
 
    RegisterClassW (&wndClass);
}


/***********************************************************************
 * STATUS_Unregister [Internal]
 *
 * Unregisters the status window class.
 */

void
STATUS_Unregister (void)
{
    UnregisterClassW (STATUSCLASSNAMEW, (HINSTANCE)NULL);
}

