/*
 * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 *
 * NOTE
 * 
 * This code was audited for completeness against the documented features
 * of Comctl32.dll version 6.0 on Sep. 24, 2002, by Dimitrie O. Paun.
 * 
 * Unless otherwise noted, we believe this code to be complete, as per
 * the specification mentioned above.
 * If you discover missing features, or bugs, please note them below.
 * 
 * TODO:
 * 	-- CCS_BOTTOM (default)
 * 	-- CCS_LEFT
 * 	-- CCS_NODIVIDER
 * 	-- CCS_NOMOVEX
 * 	-- CCS_NOMOVEY
 * 	-- CCS_NOPARENTALIGN
 * 	-- CCS_RIGHT
 * 	-- CCS_TOP
 * 	-- CCS_VERT (defaults to RIGHT)
 */

#include <stdarg.h>
#include <string.h>

#include "windef.h"
#include "winbase.h"
#include "wine/unicode.h"
#include "wingdi.h"
#include "winuser.h"
#include "winnls.h"
#include "commctrl.h"
#include "comctl32.h"
#include "uxtheme.h"
#include "tmschema.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;
    HWND              Notify;
    WORD              numParts;
    UINT              height;
    UINT              minHeight;        /* at least MIN_PANE_HEIGHT, can be increased by SB_SETMINHEIGHT */
    BOOL              simple;
    HWND              hwndToolTip;
    HFONT             hFont;
    HFONT             hDefaultFont;
    COLORREF          clrBk;		/* background color */
    BOOL              bUnicode;         /* notify format. TRUE if notifies in Unicode */
    STATUSWINDOWPART  part0;		/* simple window */
    STATUSWINDOWPART* parts;
    INT               horizontalBorder;
    INT               verticalBorder;
    INT               horizontalGap;
} STATUS_INFO;

/*
 * 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

static const WCHAR themeClass[] = { 'S','t','a','t','u','s',0 };

/* prototype */
static void
STATUSBAR_SetPartBounds (STATUS_INFO *infoPtr);
static LRESULT
STATUSBAR_NotifyFormat (STATUS_INFO *infoPtr, HWND from, INT cmd);

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

static UINT
STATUSBAR_ComputeHeight(STATUS_INFO *infoPtr)
{
    HTHEME theme;
    UINT height;
    TEXTMETRICW tm;
    int margin;

    COMCTL32_GetFontMetrics(infoPtr->hFont ? infoPtr->hFont : infoPtr->hDefaultFont, &tm);
    margin = (tm.tmInternalLeading ? tm.tmInternalLeading : 2);
    height = max(tm.tmHeight + margin + 2*GetSystemMetrics(SM_CYBORDER), infoPtr->minHeight) + infoPtr->verticalBorder;

    if ((theme = GetWindowTheme(infoPtr->Self)))
    {
        /* Determine bar height from theme such that the content area is
         * textHeight pixels large */
        HDC hdc = GetDC(infoPtr->Self);
        RECT r;
        memset (&r, 0, sizeof (r));
        r.bottom = max(infoPtr->minHeight, tm.tmHeight);
        if (SUCCEEDED(GetThemeBackgroundExtent(theme, hdc, SP_PANE, 0, &r, &r)))
        {
            height = r.bottom - r.top;
        }
        ReleaseDC(infoPtr->Self, hdc);
    }

    TRACE("    textHeight=%d+%d, final height=%d\n", tm.tmHeight, tm.tmInternalLeading, height);
    return height;
}

static void
STATUSBAR_DrawSizeGrip (HTHEME theme, HDC hdc, LPRECT lpRect)
{
    HPEN hPenFace, hPenShadow, hPenHighlight, hOldPen;
    POINT pt;
    INT i;

    TRACE("draw size grip %s\n", wine_dbgstr_rect(lpRect));

    if (theme)
    {
        RECT gripperRect;
        SIZE gripperSize;
        gripperRect = *lpRect;
        if (SUCCEEDED (GetThemePartSize (theme, hdc, SP_GRIPPER, 0, lpRect, 
            TS_DRAW, &gripperSize)))
        {
            gripperRect.left = gripperRect.right - gripperSize.cx;
            gripperRect.top = gripperRect.bottom - gripperSize.cy;
            if (SUCCEEDED (DrawThemeBackground(theme, hdc, SP_GRIPPER, 0, &gripperRect, NULL)))
                return;
        }
    }

    pt.x = lpRect->right - 1;
    pt.y = lpRect->bottom - 1;

    hPenFace = CreatePen( PS_SOLID, 1, GetSysColor( COLOR_3DFACE ));
    hOldPen = SelectObject( hdc, hPenFace );
    MoveToEx (hdc, pt.x - 12, pt.y, NULL);
    LineTo (hdc, pt.x, pt.y);
    LineTo (hdc, pt.x, pt.y - 13);

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

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

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

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

    SelectObject (hdc, hOldPen);
    DeleteObject( hPenFace );
    DeleteObject( hPenShadow );
    DeleteObject( hPenHighlight );
}


static void
STATUSBAR_DrawPart (const STATUS_INFO *infoPtr, HDC hdc, const STATUSWINDOWPART *part, int itemID)
{
    RECT r = part->bound;
    UINT border = BDR_SUNKENOUTER;
    HTHEME theme = GetWindowTheme (infoPtr->Self);
    int themePart = SP_PANE;

    TRACE("part bound %s\n", wine_dbgstr_rect(&r));
    if (part->style & SBT_POPOUT)
        border = BDR_RAISEDOUTER;
    else if (part->style & SBT_NOBORDERS)
        border = 0;

    if (theme)
    {
        if ((GetWindowLongW (infoPtr->Self, GWL_STYLE) & SBARS_SIZEGRIP)
            && (infoPtr->simple || (itemID == (infoPtr->numParts-1))))
            themePart = SP_GRIPPERPANE;
        DrawThemeBackground(theme, hdc, themePart, 0, &r, NULL);
    }
    else
        DrawEdge(hdc, &r, border, BF_RECT|BF_ADJUST);

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

	dis.CtlID = GetWindowLongPtrW (infoPtr->Self, GWLP_ID);
	dis.itemID = itemID;
	dis.hwndItem = infoPtr->Self;
	dis.hDC = hdc;
	dis.rcItem = r;
	dis.itemData = (ULONG_PTR)part->text;
	SendMessageW (infoPtr->Notify, WM_DRAWITEM, (WPARAM)dis.CtlID, (LPARAM)&dis);
    } else {
	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;
	}
        DrawStatusTextW (hdc, &r, part->text, SBT_NOBORDERS);
    }
}


static void
STATUSBAR_RefreshPart (const STATUS_INFO *infoPtr, HDC hdc, const STATUSWINDOWPART *part, int itemID)
{
    HBRUSH hbrBk;
    HTHEME theme;

    TRACE("item %d\n", itemID);

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

    if (!RectVisible(hdc, &part->bound))
        return;

    if ((theme = GetWindowTheme (infoPtr->Self)))
    {
        RECT cr;
        GetClientRect (infoPtr->Self, &cr);
        DrawThemeBackground(theme, hdc, 0, 0, &cr, &part->bound);
    }
    else
    {
        if (infoPtr->clrBk != CLR_DEFAULT)
                hbrBk = CreateSolidBrush (infoPtr->clrBk);
        else
                hbrBk = GetSysColorBrush (COLOR_3DFACE);
        FillRect(hdc, &part->bound, hbrBk);
        if (infoPtr->clrBk != CLR_DEFAULT)
                DeleteObject (hbrBk);
    }

    STATUSBAR_DrawPart (infoPtr, hdc, part, itemID);
}


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

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

    STATUSBAR_SetPartBounds(infoPtr);

    GetClientRect (infoPtr->Self, &rect);

    if ((theme = GetWindowTheme (infoPtr->Self)))
    {
        DrawThemeBackground(theme, hdc, 0, 0, &rect, NULL);
    }
    else
    {
        if (infoPtr->clrBk != CLR_DEFAULT)
            hbrBk = CreateSolidBrush (infoPtr->clrBk);
        else
            hbrBk = GetSysColorBrush (COLOR_3DFACE);
        FillRect(hdc, &rect, hbrBk);
        if (infoPtr->clrBk != CLR_DEFAULT)
            DeleteObject (hbrBk);
    }

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

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

    SelectObject (hdc, hOldFont);

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

    return 0;
}


static int
STATUSBAR_InternalHitTest(const STATUS_INFO *infoPtr, const LPPOINT pt)
{
    int i;
    if (infoPtr->simple)
        return 255;

    for (i = 0; i < infoPtr->numParts; i++)
        if (pt->x >= infoPtr->parts[i].bound.left && pt->x <= infoPtr->parts[i].bound.right)
            return i;
    return -2;
}


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

    /* get our window size */
    GetClientRect (infoPtr->Self, &rect);
    TRACE("client wnd size is %s\n", wine_dbgstr_rect(&rect));

    rect.left += infoPtr->horizontalBorder;
    rect.top += infoPtr->verticalBorder;

    /* 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 + infoPtr->horizontalGap;
	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 (const STATUS_INFO *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 = (short)LOWORD(GetMessagePos ());
    msg.pt.y = (short)HIWORD(GetMessagePos ());

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


static BOOL
STATUSBAR_GetBorders (const STATUS_INFO *infoPtr, INT out[])
{
    TRACE("\n");
    out[0] = infoPtr->horizontalBorder;
    out[1] = infoPtr->verticalBorder;
    out[2] = infoPtr->horizontalGap;

    return TRUE;
}


static BOOL
STATUSBAR_SetBorders (STATUS_INFO *infoPtr, const INT in[])
{
    TRACE("\n");
    infoPtr->horizontalBorder = in[0];
    infoPtr->verticalBorder = in[1];
    infoPtr->horizontalGap = in[2];
    InvalidateRect(infoPtr->Self, NULL, FALSE);

    return TRUE;
}


static HICON
STATUSBAR_GetIcon (const STATUS_INFO *infoPtr, INT nPart)
{
    TRACE("%d\n", nPart);
    /* MSDN says: "simple parts are indexed with -1" */
    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 (const STATUS_INFO *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 (const STATUS_INFO *infoPtr, INT nPart, LPRECT rect)
{
    TRACE("part %d\n", nPart);
    if(nPart >= infoPtr->numParts || nPart < 0)
      return FALSE;
    if (infoPtr->simple)
	*rect = infoPtr->part0.bound;
    else
	*rect = infoPtr->parts[nPart].bound;
    return TRUE;
}


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

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

    /* MSDN says: "simple parts use index of 0", so this check is ok. */
    if (nPart < 0 || nPart >= infoPtr->numParts) return 0;

    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 (STATUS_INFO *infoPtr, INT nPart, LPWSTR buf)
{
    STATUSWINDOWPART *part;
    LRESULT result;

    TRACE("part %d\n", nPart);
    if (nPart < 0 || nPart >= infoPtr->numParts) return 0;

    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 (STATUS_INFO *infoPtr, INT nPart)
{
    STATUSWINDOWPART *part;
    DWORD result;

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

    /* MSDN says: "simple parts use index of 0", so this check is ok. */
    if (nPart < 0 || nPart >= infoPtr->numParts) return 0;

    if (infoPtr->simple)
	part = &infoPtr->part0;
    else
	part = &infoPtr->parts[nPart];

    if ((~part->style & SBT_OWNERDRAW) && part->text)
	result = strlenW(part->text);
    else
	result = 0;

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

static LRESULT
STATUSBAR_GetTipTextA (const STATUS_INFO *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 (const STATUS_INFO *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 (STATUS_INFO *infoPtr, COLORREF color)
{
    COLORREF oldBkColor;

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

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


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

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

    /* FIXME: MSDN says "if nPart is -1, the status bar is assumed simple" */
    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 (STATUS_INFO *infoPtr, INT height)
{
    DWORD ysize = GetSystemMetrics(SM_CYSIZE);
    if (ysize & 1) ysize--;
    infoPtr->minHeight = max(height, ysize);
    infoPtr->height = STATUSBAR_ComputeHeight(infoPtr);
    /* like native, don't resize the control */
    return TRUE;
}


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

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

    oldNumParts = infoPtr->numParts;
    infoPtr->numParts = count;
    if (oldNumParts > infoPtr->numParts) {
	for (i = infoPtr->numParts ; i < oldNumParts; i++) {
	    if (!(infoPtr->parts[i].style & SBT_OWNERDRAW))
		Free (infoPtr->parts[i].text);
	}
    } else if (oldNumParts < infoPtr->numParts) {
	tmp = Alloc (sizeof(STATUSWINDOWPART) * infoPtr->numParts);
	if (!tmp) return FALSE;
	for (i = 0; i < oldNumParts; i++) {
	    tmp[i] = infoPtr->parts[i];
	}
        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) {
	UINT nTipCount;
	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 (STATUS_INFO *infoPtr, INT nPart, WORD style,
		    LPCWSTR text, BOOL isW)
{
    STATUSWINDOWPART *part=NULL;
    BOOL changed = FALSE;
    INT  oldStyle;

    if (style & SBT_OWNERDRAW) {
         TRACE("part %d, text %p\n",nPart,text);
    }
    else TRACE("part %d, text %s\n", nPart, debugstr_t(text, isW));

    /* MSDN says: "If the parameter is set to SB_SIMPLEID (255), the status
     * window is assumed to be a simple window */

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

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

    oldStyle = part->style;
    part->style = style;
    if (style & SBT_OWNERDRAW) {
        if (!(oldStyle & SBT_OWNERDRAW))
            Free (part->text);
        else 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 = Alloc( (len + 1)*sizeof(WCHAR) );
	    if (!ntext) return FALSE;
            MultiByteToWideChar( CP_ACP, 0, atxt, -1, ntext, len );
	} else if (text) {
	    ntext = 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)) {
		Free(ntext);
		return TRUE;
	    }
	} else {
	    if (!changed && !part->text)
		return TRUE;
	}

	if (!(oldStyle & SBT_OWNERDRAW))
	    Free (part->text);
	part->text = ntext;
    }
    InvalidateRect(infoPtr->Self, &part->bound, FALSE);
    UpdateWindow(infoPtr->Self);

    return TRUE;
}


static LRESULT
STATUSBAR_SetTipTextA (const STATUS_INFO *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 (const STATUS_INFO *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;
}


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

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

    return bOld;
}


static BOOL
STATUSBAR_Simple (STATUS_INFO *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 = GetWindowLongPtrW (infoPtr->Self, GWLP_ID);
    nmhdr.code = SBN_SIMPLEMODECHANGE;
    SendMessageW (infoPtr->Notify, WM_NOTIFY, 0, (LPARAM)&nmhdr);
    InvalidateRect(infoPtr->Self, NULL, FALSE);
    return TRUE;
}


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

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

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

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

    CloseThemeData (GetWindowTheme (infoPtr->Self));

    SetWindowLongPtrW(infoPtr->Self, 0, 0);
    Free (infoPtr);
    return 0;
}


static LRESULT
STATUSBAR_WMCreate (HWND hwnd, const CREATESTRUCTA *lpCreate)
{
    STATUS_INFO *infoPtr;
    NONCLIENTMETRICSW nclm;
    DWORD dwStyle;
    RECT rect;
    int	len;

    TRACE("\n");
    infoPtr = Alloc (sizeof(STATUS_INFO));
    if (!infoPtr) goto create_fail;
    SetWindowLongPtrW (hwnd, 0, (DWORD_PTR)infoPtr);

    infoPtr->Self = hwnd;
    infoPtr->Notify = lpCreate->hwndParent;
    infoPtr->numParts = 1;
    infoPtr->parts = 0;
    infoPtr->simple = FALSE;
    infoPtr->clrBk = CLR_DEFAULT;
    infoPtr->hFont = 0;
    infoPtr->horizontalBorder = HORZ_BORDER;
    infoPtr->verticalBorder = VERT_BORDER;
    infoPtr->horizontalGap = HORZ_GAP;
    infoPtr->minHeight = GetSystemMetrics(SM_CYSIZE);
    if (infoPtr->minHeight & 1) infoPtr->minHeight--;

    STATUSBAR_NotifyFormat(infoPtr, infoPtr->Notify, NF_REQUERY);

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

    GetClientRect (hwnd, &rect);

    /* 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 = 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;
    
    OpenThemeData (hwnd, themeClass);

    if (lpCreate->lpszName && (len = strlenW ((LPCWSTR)lpCreate->lpszName)))
    {
        infoPtr->parts[0].text = Alloc ((len + 1)*sizeof(WCHAR));
        if (!infoPtr->parts[0].text) goto create_fail;
        strcpyW (infoPtr->parts[0].text, (LPCWSTR)lpCreate->lpszName);
    }

    dwStyle = GetWindowLongW (hwnd, GWL_STYLE);
    /* native seems to clear WS_BORDER, too */
    dwStyle &= ~WS_BORDER;
    SetWindowLongW (hwnd, GWL_STYLE, dwStyle);

    infoPtr->height = STATUSBAR_ComputeHeight(infoPtr);

    if (dwStyle & SBT_TOOLTIPS) {
	infoPtr->hwndToolTip =
	    CreateWindowExW (0, TOOLTIPS_CLASSW, NULL, WS_POPUP | TTS_ALWAYSTIP,
			     CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
			     CW_USEDEFAULT, hwnd, 0,
			     (HINSTANCE)GetWindowLongPtrW(hwnd, GWLP_HINSTANCE), NULL);

	if (infoPtr->hwndToolTip) {
	    NMTOOLTIPSCREATED nmttc;

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

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

    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 (const STATUS_INFO *infoPtr, INT size, LPWSTR buf)
{
    INT len;

    TRACE("\n");
    if (!(infoPtr->parts[0].text))
        return 0;

    len = strlenW (infoPtr->parts[0].text);

    if (size > len) {
        strcpyW (buf, infoPtr->parts[0].text);
	return len;
    }

    return -1;
}


static BOOL
STATUSBAR_WMNCHitTest (const STATUS_INFO *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 (STATUS_INFO *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 (STATUS_INFO *infoPtr, HFONT font, BOOL redraw)
{
    infoPtr->hFont = font;
    TRACE("%p\n", infoPtr->hFont);

    infoPtr->height = STATUSBAR_ComputeHeight(infoPtr);
    SendMessageW(infoPtr->Self, WM_SIZE, 0, 0);  /* update size */
    if (redraw)
        InvalidateRect(infoPtr->Self, NULL, FALSE);

    return 0;
}


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

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

    part = &infoPtr->parts[0];
    /* duplicate string */
    Free (part->text);
    part->text = 0;

    if (text && (len = strlenW((LPCWSTR)text))) {
        part->text = Alloc ((len+1)*sizeof(WCHAR));
        if (!part->text) return FALSE;
        strcpyW (part->text, (LPCWSTR)text);
    }

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

    return TRUE;
}


static BOOL
STATUSBAR_WMSize (STATUS_INFO *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 && flags != SIZE_MAXIMIZED) {
	WARN("flags MUST be SIZE_RESTORED or SIZE_MAXIMIZED\n");
	return FALSE;
    }

    if (GetWindowLongW(infoPtr->Self, GWL_STYLE) & CCS_NORESIZE) return FALSE;

    /* width and height don't apply */
    if (!GetClientRect (infoPtr->Notify, &parent_rect))
        return FALSE;

    width = parent_rect.right - parent_rect.left;
    x = parent_rect.left;
    y = parent_rect.bottom - infoPtr->height;
    MoveWindow (infoPtr->Self, x, y, width, infoPtr->height, TRUE);
    STATUSBAR_SetPartBounds (infoPtr);
    return TRUE;
}


/* update theme after a WM_THEMECHANGED message */
static LRESULT theme_changed (const STATUS_INFO* infoPtr)
{
    HTHEME theme = GetWindowTheme (infoPtr->Self);
    CloseThemeData (theme);
    OpenThemeData (infoPtr->Self, themeClass);
    return 0;
}


static LRESULT
STATUSBAR_NotifyFormat (STATUS_INFO *infoPtr, HWND from, INT cmd)
{
    if (cmd == NF_REQUERY) {
	INT i = SendMessageW(from, WM_NOTIFYFORMAT, (WPARAM)infoPtr->Self, NF_QUERY);
	infoPtr->bUnicode = (i == NFR_UNICODE);
    }
    return infoPtr->bUnicode ? NFR_UNICODE : NFR_ANSI;
}


static LRESULT
STATUSBAR_SendMouseNotify(const STATUS_INFO *infoPtr, UINT code, LPARAM lParam)
{
    NMMOUSE  nm;

    TRACE("code %04x, lParam=%lx\n", code, lParam);
    nm.hdr.hwndFrom = infoPtr->Self;
    nm.hdr.idFrom = GetWindowLongPtrW(infoPtr->Self, GWLP_ID);
    nm.hdr.code = code;
    nm.pt.x = (short)LOWORD(lParam);
    nm.pt.y = (short)HIWORD(lParam);
    nm.dwItemSpec = STATUSBAR_InternalHitTest(infoPtr, &nm.pt);
    nm.dwItemData = 0;
    nm.dwHitInfo = 0x30000;     /* seems constant */
    SendMessageW(infoPtr->Notify, WM_NOTIFY, 0, (LPARAM)&nm);
    return 0;
}



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

    TRACE("hwnd=%p msg=%x wparam=%lx 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 (infoPtr, (INT *)lParam);

	case SB_GETICON:
	    return (LRESULT)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_SETBORDERS:
	    return STATUSBAR_SetBorders (infoPtr, (INT *)lParam);

	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 (LRESULT)(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_SendMouseNotify(infoPtr, NM_DBLCLK, lParam);

	case WM_LBUTTONUP:
	    return STATUSBAR_SendMouseNotify(infoPtr, NM_CLICK, lParam);

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

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

	case WM_NCLBUTTONUP:
	case WM_NCLBUTTONDOWN:
    	    PostMessageW (infoPtr->Notify, msg, wParam, lParam);
	    return 0;

	case WM_NOTIFYFORMAT:
	    return STATUSBAR_NotifyFormat(infoPtr, (HWND)wParam, (INT)lParam);

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

	case WM_RBUTTONDBLCLK:
	    return STATUSBAR_SendMouseNotify(infoPtr, NM_RDBLCLK, lParam);

	case WM_RBUTTONUP:
	    return STATUSBAR_SendMouseNotify(infoPtr, NM_RCLICK, lParam);

	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);

        case WM_THEMECHANGED:
            return theme_changed (infoPtr);

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


/***********************************************************************
 * 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   = StatusWindowProc;
    wndClass.cbClsExtra    = 0;
    wndClass.cbWndExtra    = sizeof(STATUS_INFO *);
    wndClass.hCursor       = LoadCursorW (0, (LPWSTR)IDC_ARROW);
    wndClass.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);
    wndClass.lpszClassName = STATUSCLASSNAMEW;

    RegisterClassW (&wndClass);
}


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

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