/*
 * Progress control
 *
 * Copyright 1997, 2002 Dimitrie O. Paun
 * Copyright 1998, 1999 Eric Kohl
 *
 * 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. 9, 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:
 *
 * Styles:
 *    -- PBS_SMOOTHREVERSE
 *
 */

#include <stdarg.h>
#include <string.h>
#include "windef.h"
#include "winbase.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(progress);

typedef struct
{
    HWND      Self;         /* The window handle for this control */
    INT       CurVal;       /* Current progress value */
    INT       MinVal;       /* Minimum progress value */
    INT       MaxVal;       /* Maximum progress value */
    INT       Step;         /* Step to use on PMB_STEPIT */
    INT       MarqueePos;   /* Marquee animation position */
    BOOL      Marquee;      /* Whether the marquee animation is enabled */
    COLORREF  ColorBar;     /* Bar color */
    COLORREF  ColorBk;      /* Background color */
    HFONT     Font;         /* Handle to font (not unused) */
} PROGRESS_INFO;

/* Control configuration constants */

#define LED_GAP           2
#define MARQUEE_LEDS      5
#define ID_MARQUEE_TIMER  1

/* Helper to obtain size of a progress bar chunk ("led"). */
static inline int get_led_size ( const PROGRESS_INFO *infoPtr, LONG style,
                                 const RECT* rect )
{
    HTHEME theme = GetWindowTheme (infoPtr->Self);
    if (theme)
    {
        int chunkSize;
        if (SUCCEEDED( GetThemeInt( theme, 0, 0, TMT_PROGRESSCHUNKSIZE, &chunkSize )))
            return chunkSize;
    }

    if (style & PBS_VERTICAL)
        return MulDiv (rect->right - rect->left, 2, 3);
    else
        return MulDiv (rect->bottom - rect->top, 2, 3);
}

/* Helper to obtain gap between progress bar chunks */
static inline int get_led_gap ( const PROGRESS_INFO *infoPtr )
{
    HTHEME theme = GetWindowTheme (infoPtr->Self);
    if (theme)
    {
        int spaceSize;
        if (SUCCEEDED( GetThemeInt( theme, 0, 0, TMT_PROGRESSSPACESIZE, &spaceSize )))
            return spaceSize;
    }

    return LED_GAP;
}

/* Get client rect. Takes into account that theming needs no adjustment. */
static inline void get_client_rect (HWND hwnd, RECT* rect)
{
    HTHEME theme = GetWindowTheme (hwnd);
    GetClientRect (hwnd, rect);
    if (!theme)
        InflateRect(rect, -1, -1);
    else
    {
        DWORD dwStyle = GetWindowLongW (hwnd, GWL_STYLE);
        int part = (dwStyle & PBS_VERTICAL) ? PP_BARVERT : PP_BAR;
        GetThemeBackgroundContentRect (theme, 0, part, 0, rect, rect);
    }
}

/* Compute the extend of the bar */
static inline int get_bar_size( LONG style, const RECT* rect )
{
    if (style & PBS_VERTICAL)
        return rect->bottom - rect->top;
    else
        return rect->right - rect->left;
}

/* Compute the pixel position of a progress value */
static inline int get_bar_position( const PROGRESS_INFO *infoPtr, LONG style,
                                    const RECT* rect, INT value )
{
    return MulDiv (value - infoPtr->MinVal, get_bar_size (style, rect),
                      infoPtr->MaxVal - infoPtr->MinVal);
}

/***********************************************************************
 * PROGRESS_Invalidate
 *
 * Don't be too clever about invalidating the progress bar.
 * InstallShield depends on this simple behaviour.
 */
static void PROGRESS_Invalidate( const PROGRESS_INFO *infoPtr, INT old, INT new )
{
    InvalidateRect( infoPtr->Self, NULL, old > new );
}

/* Information for a progress bar drawing helper */
typedef struct tagProgressDrawInfo
{
    HDC hdc;
    RECT rect;
    HBRUSH hbrBar;
    HBRUSH hbrBk;
    int ledW, ledGap;
    HTHEME theme;
    RECT bgRect;
} ProgressDrawInfo;

typedef void (*ProgressDrawProc)(const ProgressDrawInfo* di, int start, int end);

/* draw solid horizontal bar from 'start' to 'end' */
static void draw_solid_bar_H (const ProgressDrawInfo* di, int start, int end)
{
    RECT r;
    r.left = di->rect.left + start;
    r.top = di->rect.top;
    r.right = di->rect.left + end;
    r.bottom = di->rect.bottom;
    FillRect (di->hdc, &r, di->hbrBar);
}

/* draw solid horizontal background from 'start' to 'end' */
static void draw_solid_bkg_H (const ProgressDrawInfo* di, int start, int end)
{
    RECT r;
    r.left = di->rect.left + start;
    r.top = di->rect.top;
    r.right = di->rect.left + end;
    r.bottom = di->rect.bottom;
    FillRect (di->hdc, &r, di->hbrBk);
}

/* draw solid vertical bar from 'start' to 'end' */
static void draw_solid_bar_V (const ProgressDrawInfo* di, int start, int end)
{
    RECT r;
    r.left = di->rect.left;
    r.top = di->rect.bottom - end;
    r.right = di->rect.right;
    r.bottom = di->rect.bottom - start;
    FillRect (di->hdc, &r, di->hbrBar);
}

/* draw solid vertical background from 'start' to 'end' */
static void draw_solid_bkg_V (const ProgressDrawInfo* di, int start, int end)
{
    RECT r;
    r.left = di->rect.left;
    r.top = di->rect.bottom - end;
    r.right = di->rect.right;
    r.bottom = di->rect.bottom - start;
    FillRect (di->hdc, &r, di->hbrBk);
}

/* draw chunky horizontal bar from 'start' to 'end' */
static void draw_chunk_bar_H (const ProgressDrawInfo* di, int start, int end)
{
    RECT r;
    int right = di->rect.left + end;
    r.left = di->rect.left + start;
    r.top = di->rect.top;
    r.bottom = di->rect.bottom;
    while (r.left < right)
    {
        r.right = min (r.left + di->ledW, right);
        FillRect (di->hdc, &r, di->hbrBar);
        r.left = r.right;
        r.right = min (r.left + di->ledGap, right);
        FillRect (di->hdc, &r, di->hbrBk);
        r.left = r.right;
    }
}

/* draw chunky vertical bar from 'start' to 'end' */
static void draw_chunk_bar_V (const ProgressDrawInfo* di, int start, int end)
{
    RECT r;
    int top = di->rect.bottom - end;
    r.left = di->rect.left;
    r.right = di->rect.right;
    r.bottom = di->rect.bottom - start;
    while (r.bottom > top)
    {
        r.top = max (r.bottom - di->ledW, top);
        FillRect (di->hdc, &r, di->hbrBar);
        r.bottom = r.top;
        r.top = max (r.bottom - di->ledGap, top);
        FillRect (di->hdc, &r, di->hbrBk);
        r.bottom = r.top;
    }
}

/* drawing functions for "classic" style */
static const ProgressDrawProc drawProcClassic[8] = {
  /* Smooth */
    /* Horizontal */
    draw_solid_bar_H, draw_solid_bkg_H,
    /* Vertical */
    draw_solid_bar_V, draw_solid_bkg_V,
  /* Chunky */
    /* Horizontal */
    draw_chunk_bar_H, draw_solid_bkg_H,
    /* Vertical */
    draw_chunk_bar_V, draw_solid_bkg_V,
};

/* draw themed horizontal bar from 'start' to 'end' */
static void draw_theme_bar_H (const ProgressDrawInfo* di, int start, int end)
{
    RECT r;
    r.left = di->rect.left + start;
    r.top = di->rect.top;
    r.bottom = di->rect.bottom;
    r.right = di->rect.left + end;
    DrawThemeBackground (di->theme, di->hdc, PP_CHUNK, 0, &r, NULL);
}

/* draw themed vertical bar from 'start' to 'end' */
static void draw_theme_bar_V (const ProgressDrawInfo* di, int start, int end)
{
    RECT r;
    r.left = di->rect.left;
    r.right = di->rect.right;
    r.bottom = di->rect.bottom - start;
    r.top = di->rect.bottom - end;
    DrawThemeBackground (di->theme, di->hdc, PP_CHUNKVERT, 0, &r, NULL);
}

/* draw themed horizontal background from 'start' to 'end' */
static void draw_theme_bkg_H (const ProgressDrawInfo* di, int start, int end)
{
    RECT r;
    r.left = di->rect.left + start;
    r.top = di->rect.top;
    r.right = di->rect.left + end;
    r.bottom = di->rect.bottom;
    DrawThemeBackground (di->theme, di->hdc, PP_BAR, 0, &di->bgRect, &r);
}

/* draw themed vertical background from 'start' to 'end' */
static void draw_theme_bkg_V (const ProgressDrawInfo* di, int start, int end)
{
    RECT r;
    r.left = di->rect.left;
    r.top = di->rect.bottom - end;
    r.right = di->rect.right;
    r.bottom = di->rect.bottom - start;
    DrawThemeBackground (di->theme, di->hdc, PP_BARVERT, 0, &di->bgRect, &r);
}

/* drawing functions for themed style */
static const ProgressDrawProc drawProcThemed[8] = {
  /* Smooth */
    /* Horizontal */
    draw_theme_bar_H, draw_theme_bkg_H,
    /* Vertical */
    draw_theme_bar_V, draw_theme_bkg_V,
  /* Chunky */
    /* Horizontal */
    draw_theme_bar_H, draw_theme_bkg_H,
    /* Vertical */
    draw_theme_bar_V, draw_theme_bkg_V,
};

/***********************************************************************
 * PROGRESS_Draw
 * Draws the progress bar.
 */
static LRESULT PROGRESS_Draw (PROGRESS_INFO *infoPtr, HDC hdc)
{
    int barSize;
    DWORD dwStyle;
    BOOL barSmooth;
    const ProgressDrawProc* drawProcs;
    ProgressDrawInfo pdi;

    TRACE("(infoPtr=%p, hdc=%p)\n", infoPtr, hdc);

    pdi.hdc = hdc;
    pdi.theme = GetWindowTheme (infoPtr->Self);

    /* get the required bar brush */
    if (infoPtr->ColorBar == CLR_DEFAULT)
        pdi.hbrBar = GetSysColorBrush(COLOR_HIGHLIGHT);
    else
        pdi.hbrBar = CreateSolidBrush (infoPtr->ColorBar);

    if (infoPtr->ColorBk == CLR_DEFAULT)
        pdi.hbrBk = GetSysColorBrush(COLOR_3DFACE);
    else
        pdi.hbrBk = CreateSolidBrush(infoPtr->ColorBk);

    /* get the window style */
    dwStyle = GetWindowLongW (infoPtr->Self, GWL_STYLE);

    /* get client rectangle */
    GetClientRect (infoPtr->Self, &pdi.rect);
    if (!pdi.theme) {
        FrameRect( hdc, &pdi.rect, pdi.hbrBk );
        InflateRect(&pdi.rect, -1, -1);
    }
    else
    {
        RECT cntRect;
        int part = (dwStyle & PBS_VERTICAL) ? PP_BARVERT : PP_BAR;
        
        GetThemeBackgroundContentRect (pdi.theme, hdc, part, 0, &pdi.rect, 
            &cntRect);
        
        /* Exclude content rect - content background will be drawn later */
        ExcludeClipRect (hdc, cntRect.left, cntRect.top, 
            cntRect.right, cntRect.bottom);
        if (IsThemeBackgroundPartiallyTransparent (pdi.theme, part, 0))
            DrawThemeParentBackground (infoPtr->Self, hdc, NULL);
        DrawThemeBackground (pdi.theme, hdc, part, 0, &pdi.rect, NULL);
        SelectClipRgn (hdc, NULL);
        CopyRect (&pdi.rect, &cntRect);
    }

    /* compute some drawing parameters */
    barSmooth = (dwStyle & PBS_SMOOTH) && !pdi.theme;
    drawProcs = &((pdi.theme ? drawProcThemed : drawProcClassic)[(barSmooth ? 0 : 4)
        + ((dwStyle & PBS_VERTICAL) ? 2 : 0)]);
    barSize = get_bar_size( dwStyle, &pdi.rect );
    if (pdi.theme)
    {
        GetWindowRect( infoPtr->Self, &pdi.bgRect );
        MapWindowPoints( infoPtr->Self, 0, (POINT*)&pdi.bgRect, 2 );
    }

    if (!barSmooth)
        pdi.ledW = get_led_size( infoPtr, dwStyle, &pdi.rect);
    pdi.ledGap = get_led_gap( infoPtr );

    if (dwStyle & PBS_MARQUEE)
    {
        const int ledW = !barSmooth ? (pdi.ledW + pdi.ledGap) : 1;
        const int leds = (barSize + ledW - 1) / ledW;
        const int ledMEnd = infoPtr->MarqueePos + MARQUEE_LEDS;

        if (ledMEnd > leds)
        {
            /* case 1: the marquee bar extends over the end and wraps around to 
             * the start */
            const int gapStart = max((ledMEnd - leds) * ledW, 0);
            const int gapEnd = min(infoPtr->MarqueePos * ledW, barSize);

            drawProcs[0]( &pdi, 0, gapStart);
            drawProcs[1]( &pdi, gapStart, gapEnd);
            drawProcs[0]( &pdi, gapEnd, barSize);
        }
        else
        {
            /* case 2: the marquee bar is between start and end */
            const int barStart = infoPtr->MarqueePos * ledW;
            const int barEnd = min (ledMEnd * ledW, barSize);

            drawProcs[1]( &pdi, 0, barStart);
            drawProcs[0]( &pdi, barStart, barEnd);
            drawProcs[1]( &pdi, barEnd, barSize);
        }
    }
    else
    {
        int barEnd = get_bar_position( infoPtr, dwStyle, &pdi.rect,
            infoPtr->CurVal);
        if (!barSmooth)
        {
            const int ledW = pdi.ledW + pdi.ledGap;
            barEnd = min (((barEnd + ledW - 1) / ledW) * ledW, barSize);
        }
        drawProcs[0]( &pdi, 0, barEnd);
        drawProcs[1]( &pdi, barEnd, barSize);
    }

    /* delete bar brush */
    if (infoPtr->ColorBar != CLR_DEFAULT) DeleteObject (pdi.hbrBar);
    if (infoPtr->ColorBk != CLR_DEFAULT) DeleteObject (pdi.hbrBk);

    return 0;
}

/***********************************************************************
 * PROGRESS_Paint
 * Draw the progress bar. The background need not be erased.
 * If dc!=0, it draws on it
 */
static LRESULT PROGRESS_Paint (PROGRESS_INFO *infoPtr, HDC hdc)
{
    PAINTSTRUCT ps;
    if (hdc) return PROGRESS_Draw (infoPtr, hdc);
    hdc = BeginPaint (infoPtr->Self, &ps);
    PROGRESS_Draw (infoPtr, hdc);
    EndPaint (infoPtr->Self, &ps);
    return 0;
}


/***********************************************************************
 * PROGRESS_Timer
 * Handle the marquee timer messages
 */
static LRESULT PROGRESS_Timer (PROGRESS_INFO *infoPtr, INT idTimer)
{
    if(idTimer == ID_MARQUEE_TIMER)
    {
        LONG style = GetWindowLongW (infoPtr->Self, GWL_STYLE);
        RECT rect;
        int ledWidth, leds;
        HTHEME theme = GetWindowTheme (infoPtr->Self);
        BOOL barSmooth = (style & PBS_SMOOTH) && !theme;

        get_client_rect (infoPtr->Self, &rect);

        if(!barSmooth)
            ledWidth = get_led_size( infoPtr, style, &rect ) + 
                get_led_gap( infoPtr );
        else
            ledWidth = 1;

        leds = (get_bar_size( style, &rect ) + ledWidth - 1) / 
            ledWidth;

        /* increment the marquee progress */
        if(++infoPtr->MarqueePos >= leds)
        {
            infoPtr->MarqueePos = 0;
        }

        InvalidateRect(infoPtr->Self, &rect, FALSE);
        UpdateWindow(infoPtr->Self);
    }
    return 0;
}


/***********************************************************************
 *           PROGRESS_CoercePos
 * Makes sure the current position (CurVal) is within bounds.
 */
static void PROGRESS_CoercePos(PROGRESS_INFO *infoPtr)
{
    if(infoPtr->CurVal < infoPtr->MinVal)
        infoPtr->CurVal = infoPtr->MinVal;
    if(infoPtr->CurVal > infoPtr->MaxVal)
        infoPtr->CurVal = infoPtr->MaxVal;
}


/***********************************************************************
 *           PROGRESS_SetFont
 * Set new Font for progress bar
 */
static HFONT PROGRESS_SetFont (PROGRESS_INFO *infoPtr, HFONT hFont, BOOL bRedraw)
{
    HFONT hOldFont = infoPtr->Font;
    infoPtr->Font = hFont;
    /* Since infoPtr->Font is not used, there is no need for repaint */
    return hOldFont;
}

static DWORD PROGRESS_SetRange (PROGRESS_INFO *infoPtr, int low, int high)
{
    DWORD res = MAKELONG(LOWORD(infoPtr->MinVal), LOWORD(infoPtr->MaxVal));

    /* if nothing changes, simply return */
    if(infoPtr->MinVal == low && infoPtr->MaxVal == high) return res;

    infoPtr->MinVal = low;
    infoPtr->MaxVal = high;
    PROGRESS_CoercePos(infoPtr);
    InvalidateRect(infoPtr->Self, NULL, TRUE);
    return res;
}

/***********************************************************************
 *           ProgressWindowProc
 */
static LRESULT WINAPI ProgressWindowProc(HWND hwnd, UINT message,
                                         WPARAM wParam, LPARAM lParam)
{
    PROGRESS_INFO *infoPtr;
    static const WCHAR themeClass[] = {'P','r','o','g','r','e','s','s',0};
    HTHEME theme;

    TRACE("hwnd=%p msg=%04x wparam=%lx lParam=%lx\n", hwnd, message, wParam, lParam);

    infoPtr = (PROGRESS_INFO *)GetWindowLongPtrW(hwnd, 0);

    if (!infoPtr && message != WM_CREATE)
        return DefWindowProcW( hwnd, message, wParam, lParam );

    switch(message) {
    case WM_CREATE:
    {
	DWORD dwExStyle = GetWindowLongW (hwnd, GWL_EXSTYLE);
        
        theme = OpenThemeData (hwnd, themeClass);

	dwExStyle &= ~(WS_EX_CLIENTEDGE | WS_EX_WINDOWEDGE);
	if (!theme) dwExStyle |= WS_EX_STATICEDGE;
        SetWindowLongW (hwnd, GWL_EXSTYLE, dwExStyle);
	/* Force recalculation of a non-client area */
	SetWindowPos(hwnd, 0, 0, 0, 0, 0,
	    SWP_FRAMECHANGED | SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE);

        /* allocate memory for info struct */
        infoPtr = Alloc (sizeof(PROGRESS_INFO));
        if (!infoPtr) return -1;
        SetWindowLongPtrW (hwnd, 0, (DWORD_PTR)infoPtr);

        /* initialize the info struct */
        infoPtr->Self = hwnd;
        infoPtr->MinVal = 0;
        infoPtr->MaxVal = 100;
        infoPtr->CurVal = 0;
        infoPtr->Step = 10;
        infoPtr->MarqueePos = 0;
        infoPtr->Marquee = FALSE;
        infoPtr->ColorBar = CLR_DEFAULT;
        infoPtr->ColorBk = CLR_DEFAULT;
        infoPtr->Font = 0;

        TRACE("Progress Ctrl creation, hwnd=%p\n", hwnd);
        return 0;
    }

    case WM_DESTROY:
        TRACE("Progress Ctrl destruction, hwnd=%p\n", hwnd);
        Free (infoPtr);
        SetWindowLongPtrW(hwnd, 0, 0);
        theme = GetWindowTheme (hwnd);
        CloseThemeData (theme);
        return 0;

    case WM_ERASEBKGND:
        return 1;

    case WM_GETFONT:
        return (LRESULT)infoPtr->Font;

    case WM_SETFONT:
        return (LRESULT)PROGRESS_SetFont(infoPtr, (HFONT)wParam, (BOOL)lParam);

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

    case WM_TIMER:
        return PROGRESS_Timer (infoPtr, (INT)wParam);

    case WM_THEMECHANGED:
    {
        DWORD dwExStyle = GetWindowLongW (hwnd, GWL_EXSTYLE);
        
        theme = GetWindowTheme (hwnd);
        CloseThemeData (theme);
        theme = OpenThemeData (hwnd, themeClass);
        
        /* WS_EX_STATICEDGE disappears when the control is themed */
        if (theme)
            dwExStyle &= ~WS_EX_STATICEDGE;
        else
            dwExStyle |= WS_EX_STATICEDGE;
        SetWindowLongW (hwnd, GWL_EXSTYLE, dwExStyle);
        
        InvalidateRect (hwnd, NULL, FALSE);
        return 0;
    }

    case PBM_DELTAPOS:
    {
	INT oldVal;
        oldVal = infoPtr->CurVal;
        if(wParam != 0) {
	    infoPtr->CurVal += (INT)wParam;
	    PROGRESS_CoercePos (infoPtr);
	    TRACE("PBM_DELTAPOS: current pos changed from %d to %d\n", oldVal, infoPtr->CurVal);
            PROGRESS_Invalidate( infoPtr, oldVal, infoPtr->CurVal );
            UpdateWindow( infoPtr->Self );
        }
        return oldVal;
    }

    case PBM_SETPOS:
    {
        UINT oldVal;
        oldVal = infoPtr->CurVal;
        if(oldVal != wParam) {
	    infoPtr->CurVal = (INT)wParam;
	    PROGRESS_CoercePos(infoPtr);
	    TRACE("PBM_SETPOS: current pos changed from %d to %d\n", oldVal, infoPtr->CurVal);
            PROGRESS_Invalidate( infoPtr, oldVal, infoPtr->CurVal );
            UpdateWindow( infoPtr->Self );
        }
        return oldVal;
    }

    case PBM_SETRANGE:
        return PROGRESS_SetRange (infoPtr, (int)LOWORD(lParam), (int)HIWORD(lParam));

    case PBM_SETSTEP:
    {
	INT oldStep;
        oldStep = infoPtr->Step;
        infoPtr->Step = (INT)wParam;
        return oldStep;
    }

    case PBM_GETSTEP:
        return infoPtr->Step;

    case PBM_STEPIT:
    {
	INT oldVal;
        oldVal = infoPtr->CurVal;
        infoPtr->CurVal += infoPtr->Step;
        if(infoPtr->CurVal > infoPtr->MaxVal)
	    infoPtr->CurVal = infoPtr->MinVal;
        if(oldVal != infoPtr->CurVal)
	{
	    TRACE("PBM_STEPIT: current pos changed from %d to %d\n", oldVal, infoPtr->CurVal);
            PROGRESS_Invalidate( infoPtr, oldVal, infoPtr->CurVal );
            UpdateWindow( infoPtr->Self );
	}
        return oldVal;
    }

    case PBM_SETRANGE32:
        return PROGRESS_SetRange (infoPtr, (int)wParam, (int)lParam);

    case PBM_GETRANGE:
        if (lParam) {
            ((PPBRANGE)lParam)->iLow = infoPtr->MinVal;
            ((PPBRANGE)lParam)->iHigh = infoPtr->MaxVal;
        }
        return wParam ? infoPtr->MinVal : infoPtr->MaxVal;

    case PBM_GETPOS:
        return infoPtr->CurVal;

    case PBM_SETBARCOLOR:
        infoPtr->ColorBar = (COLORREF)lParam;
	InvalidateRect(hwnd, NULL, TRUE);
	return 0;

    case PBM_GETBARCOLOR:
	return infoPtr->ColorBar;

    case PBM_SETBKCOLOR:
        infoPtr->ColorBk = (COLORREF)lParam;
	InvalidateRect(hwnd, NULL, TRUE);
	return 0;

    case PBM_GETBKCOLOR:
	return infoPtr->ColorBk;

    case PBM_SETSTATE:
        if(wParam != PBST_NORMAL)
            FIXME("state %04lx not yet handled\n", wParam);
        return PBST_NORMAL;

    case PBM_GETSTATE:
        return PBST_NORMAL;

    case PBM_SETMARQUEE:
	if(wParam != 0)
        {
            infoPtr->Marquee = TRUE;
            SetTimer(infoPtr->Self, ID_MARQUEE_TIMER, (UINT)lParam, NULL);
        }
        else
        {
            infoPtr->Marquee = FALSE;
            KillTimer(infoPtr->Self, ID_MARQUEE_TIMER);
        }
	return infoPtr->Marquee;

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


/***********************************************************************
 * PROGRESS_Register [Internal]
 *
 * Registers the progress bar window class.
 */
void PROGRESS_Register (void)
{
    WNDCLASSW wndClass;

    ZeroMemory (&wndClass, sizeof(wndClass));
    wndClass.style         = CS_GLOBALCLASS | CS_VREDRAW | CS_HREDRAW;
    wndClass.lpfnWndProc   = (WNDPROC)ProgressWindowProc;
    wndClass.cbClsExtra    = 0;
    wndClass.cbWndExtra    = sizeof (PROGRESS_INFO *);
    wndClass.hCursor       = LoadCursorW (0, (LPWSTR)IDC_ARROW);
    wndClass.lpszClassName = PROGRESS_CLASSW;

    RegisterClassW (&wndClass);
}


/***********************************************************************
 * PROGRESS_Unregister [Internal]
 *
 * Unregisters the progress bar window class.
 */
void PROGRESS_Unregister (void)
{
    UnregisterClassW (PROGRESS_CLASSW, NULL);
}
