/*
 * Trackbar control
 *
 * Copyright 1998, 1999 Eric Kohl <ekohl@abo.rhein-zeitung.de>
 * Copyright 1998,1999 Alex Priem <alexp@sci.kun.nl>
 *
 *
 * TODO:
 *   - Some messages.
 *   - handle dragging slider better
 *   - better tic handling.
 *   - more notifications.
 *   
 */

/* known bugs:

   -TBM_SETRANGEMAX & TBM_SETRANGEMIN should only change the view of the
   trackbar, not the actual amount of tics in the list.
   -TBM_GETTIC & TBM_GETTICPOS shouldn't rely on infoPtr->tics being sorted.
*/


#include <stdio.h>

#include "winbase.h"
#include "commctrl.h"
#include "debugtools.h"

DEFAULT_DEBUG_CHANNEL(trackbar);

typedef struct
{
    INT  nRangeMin;
    INT  nRangeMax;
    INT  nLineSize;
    INT  nPageSize;
    INT  nSelMin;
    INT  nSelMax;
    INT  nPos;
    UINT uThumbLen;
    UINT uNumTics;
    UINT  uTicFreq;
    HWND hwndNotify;
    HWND hwndToolTip;
    HWND hwndBuddyLA;
    HWND hwndBuddyRB;
    INT  fLocation;
    COLORREF clrBk;
    INT  flags;
    BOOL bFocus;
    RECT rcChannel;
    RECT rcSelection;
    RECT rcThumb;
    INT  dragPos;
    LPLONG tics;
} TRACKBAR_INFO;

/* #define TB_REFRESH_TIMER       1 */
/* #define TB_REFRESH_DELAY       1 */

#define TRACKBAR_GetInfoPtr(wndPtr) ((TRACKBAR_INFO *)GetWindowLongA (hwnd,0))


/* Used by TRACKBAR_Refresh to find out which parts of the control 
   need to be recalculated */

#define TB_THUMBPOSCHANGED      1	
#define TB_THUMBSIZECHANGED     2
#define TB_THUMBCHANGED 	(TB_THUMBPOSCHANGED | TB_THUMBPOSCHANGED)
#define TB_SELECTIONCHANGED     4
#define TB_DRAG_MODE            16     /* we're dragging the slider */
#define TB_DRAGPOSVALID         32     /* current Position is in dragPos */
#define TB_SHOW_TOOLTIP         64     /* tooltip-style enabled and tooltip on */

/* helper defines for TRACKBAR_DrawTic */
#define TIC_LEFTEDGE            0x20
#define TIC_RIGHTEDGE           0x40
#define TIC_EDGE                (TIC_LEFTEDGE | TIC_RIGHTEDGE)
#define TIC_SELECTIONMARKMAX    0x80
#define TIC_SELECTIONMARKMIN    0x100
#define TIC_SELECTIONMARK       (TIC_SELECTIONMARKMAX | TIC_SELECTIONMARKMIN)

static BOOL TRACKBAR_SendNotify (HWND hwnd, UINT code);

static void TRACKBAR_RecalculateTics (TRACKBAR_INFO *infoPtr)
{
    int i,tic,nrTics;

    if (infoPtr->uTicFreq && infoPtr->nRangeMax >= infoPtr->nRangeMin) 
    	nrTics=(infoPtr->nRangeMax - infoPtr->nRangeMin)/infoPtr->uTicFreq;
    else {
        nrTics=0;
        COMCTL32_Free (infoPtr->tics);
        infoPtr->tics=NULL;
        infoPtr->uNumTics=0;
        return;
    }

    if (nrTics!=infoPtr->uNumTics) {
    	infoPtr->tics=COMCTL32_ReAlloc (infoPtr->tics, 
                                        (nrTics+1)*sizeof (DWORD));
    	infoPtr->uNumTics=nrTics;
    }
    infoPtr->uNumTics=nrTics;
    tic=infoPtr->nRangeMin+infoPtr->uTicFreq;
    for (i=0; i<nrTics; i++,tic+=infoPtr->uTicFreq)
        infoPtr->tics[i]=tic;
}


/* converts from physical (mouse) position to logical position 
   (in range of trackbar) */

static inline DOUBLE
TRACKBAR_ConvertPlaceToPosition (TRACKBAR_INFO *infoPtr, int place, 
                                 int vertical) 
{
    double range,width,pos;

    range=infoPtr->nRangeMax - infoPtr->nRangeMin;
    if (vertical) {
    	width=infoPtr->rcChannel.bottom - infoPtr->rcChannel.top;
        pos=(range*(place - infoPtr->rcChannel.top)) / width;
    } else {
    	width=infoPtr->rcChannel.right - infoPtr->rcChannel.left;
        pos=(range*(place - infoPtr->rcChannel.left)) / width;
    }
    pos+=infoPtr->nRangeMin;
    if (pos > infoPtr->nRangeMax)
        pos = infoPtr->nRangeMax;
    else if (pos < infoPtr->nRangeMin)
        pos = infoPtr->nRangeMin;

    TRACE("%.2f\n",pos);
    return pos;
}


static VOID
TRACKBAR_CalcChannel (HWND hwnd, TRACKBAR_INFO *infoPtr)
{
    DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
    INT cyChannel,offsettop,offsetedge;
    RECT lpRect,*channel = & infoPtr->rcChannel;

    GetClientRect (hwnd, &lpRect);

    if (dwStyle & TBS_ENABLESELRANGE)
        cyChannel = ((int)(infoPtr->uThumbLen/4.5)+1)*3;
    else
        cyChannel = 4;

    offsettop  = (int)(infoPtr->uThumbLen/4.5); 
    offsetedge = (int)(infoPtr->uThumbLen/4.5) + 3;

    if (dwStyle & TBS_VERT) {
        channel->top    = lpRect.top + offsetedge;
        channel->bottom = lpRect.bottom - offsetedge;

	if (dwStyle & (TBS_BOTH | TBS_LEFT)) {
            channel->left  = lpRect.left + offsettop + 8 ;
            channel->right = channel->left + cyChannel;
        }
        else { /* TBS_RIGHT */
            channel->left = lpRect.left + offsettop;
            channel->right = channel->left + cyChannel;
        }
    }
    else {
        channel->left = lpRect.left + offsetedge;
        channel->right = lpRect.right - offsetedge;

        if (dwStyle & (TBS_BOTH|TBS_TOP)) {
            channel->top	= lpRect.top + offsettop + 8 ;
            channel->bottom 	= channel->top + cyChannel;
        }
        else { /* TBS_BOTTOM */
            channel->top = lpRect.top + offsettop;
            channel->bottom   = channel->top + cyChannel;
        }
    }
}

static VOID
TRACKBAR_CalcThumb (HWND hwnd, TRACKBAR_INFO *infoPtr)
{
    RECT *thumb;
    int range, width, thumbdepth;
    DWORD dwStyle = GetWindowLongA(hwnd,GWL_STYLE);
	
    thumb=&infoPtr->rcThumb;
    range=infoPtr->nRangeMax - infoPtr->nRangeMin;
    thumbdepth = ((INT)((FLOAT)infoPtr->uThumbLen / 4.5) * 2) + 2;

    if (!range) return; /* FIXME: may this happen? */

    if (dwStyle & TBS_VERT) 
    {
    	width=infoPtr->rcChannel.bottom - infoPtr->rcChannel.top;

        if (dwStyle & (TBS_BOTH | TBS_LEFT))
          thumb->left = 10;
        else
          thumb-> left =2; 
        thumb->right = thumb -> left + infoPtr->uThumbLen;
        thumb->top = infoPtr->rcChannel.top +
                     (width*(infoPtr->nPos - infoPtr->nRangeMin))/range - 
                     thumbdepth/2;
        thumb->bottom = thumb->top + thumbdepth;
    } 
    else 
    {
    	width=infoPtr->rcChannel.right - infoPtr->rcChannel.left;

        thumb->left = infoPtr->rcChannel.left +
                      (width*(infoPtr->nPos - infoPtr->nRangeMin))/range - 
                      thumbdepth/2;
        thumb->right = thumb->left + thumbdepth;
        if (dwStyle & (TBS_BOTH | TBS_TOP))
          thumb->top = 10;
        else
          thumb->top = 2;
        thumb->bottom =  thumb -> top + infoPtr->uThumbLen;
    }
}

static VOID
TRACKBAR_CalcSelection (HWND hwnd, TRACKBAR_INFO *infoPtr)
{
    RECT *selection;
    int range, width;

    selection= & infoPtr->rcSelection;
    range=infoPtr->nRangeMax - infoPtr->nRangeMin;
    width=infoPtr->rcChannel.right - infoPtr->rcChannel.left;

    if (range <= 0) 
        SetRectEmpty (selection);
    else 
        if (GetWindowLongA (hwnd, GWL_STYLE) & TBS_VERT) {
            selection->left   = infoPtr->rcChannel.left +
                (width*infoPtr->nSelMin)/range;
            selection->right  = infoPtr->rcChannel.left +
                (width*infoPtr->nSelMax)/range;
            selection->top    = infoPtr->rcChannel.top + 2;
            selection->bottom = infoPtr->rcChannel.bottom - 2;
        } else {
            selection->top    = infoPtr->rcChannel.top +
                (width*infoPtr->nSelMin)/range;
            selection->bottom = infoPtr->rcChannel.top +
                (width*infoPtr->nSelMax)/range;
            selection->left   = infoPtr->rcChannel.left + 2;
            selection->right  = infoPtr->rcChannel.right - 2;
        }
}

/* Trackbar drawing code. I like my spaghetti done milanese.  */

/* ticPos is in tic-units, not in pixels */

static VOID
TRACKBAR_DrawHorizTic (TRACKBAR_INFO *infoPtr, HDC hdc, LONG ticPos, 
                       int flags, COLORREF clrTic)
{
    RECT rcChannel=infoPtr->rcChannel;
    int x,y,width,range,side;

    range=infoPtr->nRangeMax - infoPtr->nRangeMin;
    width=rcChannel.right - rcChannel.left;

    if (flags & TBS_TOP) {
	y=rcChannel.top-2;
	side=-1;
    } else {
  	y=rcChannel.bottom+2;
	side=1;
    }

    if (flags & TIC_SELECTIONMARK) {
  	if (flags & TIC_SELECTIONMARKMIN) 
            x=rcChannel.left + (width*(ticPos - infoPtr->nRangeMin))/range - 1;
	else 
            x=rcChannel.left + (width*(ticPos - infoPtr->nRangeMin))/range + 1;

   	SetPixel (hdc, x,y+6*side, clrTic);
   	SetPixel (hdc, x,y+7*side, clrTic);
	return;
    }

    if ((ticPos>infoPtr->nRangeMin) && (ticPos<infoPtr->nRangeMax)) {
   	x=rcChannel.left + (width*(ticPos - infoPtr->nRangeMin))/range;
   	SetPixel (hdc, x,y+5*side, clrTic);
   	SetPixel (hdc, x,y+6*side, clrTic);
   	SetPixel (hdc, x,y+7*side, clrTic);
    }

    if (flags & TIC_EDGE) {
	if (flags & TIC_LEFTEDGE)
            x=rcChannel.left;
	else 
            x=rcChannel.right;

   	SetPixel (hdc, x,y+5*side, clrTic);
   	SetPixel (hdc, x,y+6*side, clrTic);
   	SetPixel (hdc, x,y+7*side, clrTic);
	SetPixel (hdc, x,y+8*side, clrTic);
    }

}

static VOID
TRACKBAR_DrawVertTic (TRACKBAR_INFO *infoPtr, HDC hdc, LONG ticPos, 
                      int flags, COLORREF clrTic)
{
    RECT rcChannel=infoPtr->rcChannel;
    int x,y,width,range,side;

    range=infoPtr->nRangeMax - infoPtr->nRangeMin;
    width=rcChannel.bottom - rcChannel.top;

    if (flags & TBS_TOP) {
	x=rcChannel.left-2;
	side=-1;
    } else {
  	x=rcChannel.right+2;
	side=1;
    }


    if (flags & TIC_SELECTIONMARK) {
  	if (flags & TIC_SELECTIONMARKMIN) 
            y=rcChannel.top + (width*(ticPos - infoPtr->nRangeMin))/range - 1;
	else 
            y=rcChannel.top + (width*(ticPos - infoPtr->nRangeMin))/range + 1;

   	SetPixel (hdc, x+6*side, y, clrTic);
   	SetPixel (hdc, x+7*side, y, clrTic);
	return;
    }

    if ((ticPos>infoPtr->nRangeMin) && (ticPos<infoPtr->nRangeMax)) {
   	y=rcChannel.top + (width*(ticPos - infoPtr->nRangeMin))/range;
   	SetPixel (hdc, x+5*side, y, clrTic);
   	SetPixel (hdc, x+6*side, y, clrTic);
   	SetPixel (hdc, x+7*side, y, clrTic);
    }

    if (flags & TIC_EDGE) {
	if (flags & TIC_LEFTEDGE)
            y=rcChannel.top;
	else 
            y=rcChannel.bottom;

   	SetPixel (hdc, x+5*side, y, clrTic);
   	SetPixel (hdc, x+6*side, y, clrTic);
   	SetPixel (hdc, x+7*side, y, clrTic);
	SetPixel (hdc, x+8*side, y, clrTic);
    }

}


static VOID
TRACKBAR_DrawTics (TRACKBAR_INFO *infoPtr, HDC hdc, LONG ticPos, 
                   int flags, COLORREF clrTic)
{

    if (flags & TBS_VERT) {
        if ((flags & TBS_TOP) || (flags & TBS_BOTH)) 
            TRACKBAR_DrawVertTic (infoPtr, hdc, ticPos, 
                                  flags | TBS_TOP , clrTic);
        if (!(flags & TBS_TOP) || (flags & TBS_BOTH)) 
            TRACKBAR_DrawVertTic (infoPtr, hdc, ticPos, flags, clrTic);
        return;
    }

    if ((flags & TBS_TOP) || (flags & TBS_BOTH)) 
        TRACKBAR_DrawHorizTic (infoPtr, hdc, ticPos, flags | TBS_TOP , clrTic);

    if (!(flags & TBS_TOP) || (flags & TBS_BOTH)) 
        TRACKBAR_DrawHorizTic (infoPtr, hdc, ticPos, flags, clrTic);

}

static VOID
TRACKBAR_DrawThumb(TRACKBAR_INFO *infoPtr, HDC hdc, DWORD dwStyle)
{
    HBRUSH oldbr,hbr = GetSysColorBrush(COLOR_BTNFACE);
    HPEN  oldpen=(HPEN)NULL,hpn;
    RECT thumb = infoPtr->rcThumb;
    int BlackUntil=3;
    int PointCount=6;
    POINT points[6];

    static INT PointDepth = 4;

    oldbr = SelectObject (hdc, hbr);
    SetPolyFillMode (hdc,WINDING);
		
    if (dwStyle & TBS_BOTH) 
    {
       points[0].x=thumb.right;
       points[0].y=thumb.top;
       points[1].x=thumb.right;
       points[1].y=thumb.bottom;
       points[2].x=thumb.left;
       points[2].y=thumb.bottom;
       points[3].x=thumb.left;
       points[3].y=thumb.top;
       points[4].x=points[0].x;
       points[4].y=points[0].y;
       PointCount = 5;
       BlackUntil = 3;
    } 
    else 
    {
        if (dwStyle & TBS_VERT)
        {
          if (dwStyle & TBS_LEFT)
          {
            points[0].x=thumb.right;
            points[0].y=thumb.top;
            points[1].x=thumb.right;
            points[1].y=thumb.bottom;
            points[2].x=thumb.left + PointDepth;
            points[2].y=thumb.bottom;
            points[3].x=thumb.left;
            points[3].y=(thumb.bottom - thumb.top) / 2 + thumb.top;
            points[4].x=thumb.left + PointDepth;
            points[4].y=thumb.top;
            points[5].x=points[0].x;
            points[5].y=points[0].y;
            BlackUntil = 4;
          }
          else
          {
            points[0].x=thumb.right;
            points[0].y=(thumb.bottom - thumb.top) / 2 + thumb.top;
            points[1].x=thumb.right - PointDepth;
            points[1].y=thumb.bottom;
            points[2].x=thumb.left;
            points[2].y=thumb.bottom;
            points[3].x=thumb.left;
            points[3].y=thumb.top;
            points[4].x=thumb.right - PointDepth;
            points[4].y=thumb.top;
            points[5].x=points[0].x;
            points[5].y=points[0].y;
          }
        }
        else
        {
          if (dwStyle & TBS_TOP)
          {
            points[0].x=(thumb.right - thumb.left) / 2 + thumb.left ;
            points[0].y=thumb.top;
            points[1].x=thumb.right;
            points[1].y=thumb.top + PointDepth;
            points[2].x=thumb.right;
            points[2].y=thumb.bottom; 
            points[3].x=thumb.left;
            points[3].y=thumb.bottom;
            points[4].x=thumb.left;
            points[4].y=thumb.top + PointDepth;
            points[5].x=points[0].x;
            points[5].y=points[0].y;
            BlackUntil = 4;
          }
          else
          {
            points[0].x=thumb.right;
            points[0].y=thumb.top;
            points[1].x=thumb.right;
            points[1].y=thumb.bottom - PointDepth;
            points[2].x=(thumb.right - thumb.left) / 2 + thumb.left ;
            points[2].y=thumb.bottom;
            points[3].x=thumb.left;
            points[3].y=thumb.bottom - PointDepth;
            points[4].x=thumb.left;
            points[4].y=thumb.top;
            points[5].x=points[0].x;
            points[5].y=points[0].y;
          }
        }
        
    }

    /*
     * Fill the shape
     */
    Polygon (hdc, points, PointCount);

    /*
     * Draw the edge
     */
    hpn = GetStockObject(BLACK_PEN);
    oldpen = SelectObject(hdc,hpn);

    /*
     * Black part
     */	
    Polyline(hdc,points,BlackUntil);

    SelectObject(hdc,oldpen);
    hpn = GetStockObject(WHITE_PEN);
    SelectObject(hdc,hpn);
     
    /*
     * White Part
     */
    Polyline(hdc,&points[BlackUntil-1],PointCount+1-BlackUntil);

    /*
     * restore the brush and pen
     */
    SelectObject(hdc,oldbr);
    if (oldpen)
      SelectObject(hdc,oldpen);
}

static VOID
TRACKBAR_Refresh (HWND hwnd, HDC hdc)
{
    TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
    DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
    RECT rcClient, rcChannel, rcSelection;
    HBRUSH hBrush;
    int i;

    GetClientRect (hwnd, &rcClient);
    hBrush = CreateSolidBrush (infoPtr->clrBk);
    FillRect (hdc, &rcClient, hBrush);
    DeleteObject (hBrush);

    if (infoPtr->flags & TB_DRAGPOSVALID)  {
        infoPtr->nPos=infoPtr->dragPos;
        infoPtr->flags |= TB_THUMBPOSCHANGED;
    }
	
    if (infoPtr->flags & TB_THUMBCHANGED) {
        TRACKBAR_CalcThumb	(hwnd, infoPtr);
        if (infoPtr->flags & TB_THUMBSIZECHANGED) 
            TRACKBAR_CalcChannel (hwnd, infoPtr);
    }
    if (infoPtr->flags & TB_SELECTIONCHANGED)
        TRACKBAR_CalcSelection (hwnd, infoPtr);
    infoPtr->flags &= ~ (TB_THUMBCHANGED | TB_SELECTIONCHANGED | 
                         TB_DRAGPOSVALID);

    /* draw channel */

    rcChannel = infoPtr->rcChannel;
    rcSelection= infoPtr->rcSelection;
    DrawEdge (hdc, &rcChannel, EDGE_SUNKEN, BF_RECT | BF_ADJUST);

    if (dwStyle & TBS_ENABLESELRANGE) {		 /* fill the channel */
        HBRUSH hbr = CreateSolidBrush (RGB(255,255,255));
        FillRect (hdc, &rcChannel, hbr);
        if (((dwStyle & TBS_VERT) && 
             (rcSelection.left!=rcSelection.right)) || 
            ((!(dwStyle & TBS_VERT)) && 	
             (rcSelection.left!=rcSelection.right))) {
            hbr=CreateSolidBrush (COLOR_HIGHLIGHT); 
            FillRect (hdc, &rcSelection, hbr);
        }
        DeleteObject (hbr);
    }


    /* draw tics */

    if (!(dwStyle & TBS_NOTICKS)) {
        int ticFlags = dwStyle & 0x0f;
        COLORREF clrTic=GetSysColor (COLOR_3DDKSHADOW);

        for (i=0; i<infoPtr->uNumTics; i++) 
            TRACKBAR_DrawTics (infoPtr, hdc, infoPtr->tics[i], 
                               ticFlags, clrTic);

    	TRACKBAR_DrawTics (infoPtr, hdc, 0, ticFlags | TIC_LEFTEDGE, clrTic);
    	TRACKBAR_DrawTics (infoPtr, hdc, 0, ticFlags | TIC_RIGHTEDGE, clrTic);
          
        if ((dwStyle & TBS_ENABLESELRANGE) && 
            (rcSelection.left!=rcSelection.right)) {
            TRACKBAR_DrawTics (infoPtr, hdc, infoPtr->nSelMin, 
                               ticFlags | TIC_SELECTIONMARKMIN, clrTic);
            TRACKBAR_DrawTics (infoPtr, hdc, infoPtr->nSelMax, 
                               ticFlags | TIC_SELECTIONMARKMAX, clrTic);
        }
    }

    /* draw thumb */

    if (!(dwStyle & TBS_NOTHUMB)) 
    {
      TRACKBAR_DrawThumb(infoPtr,hdc,dwStyle);		
    }

    if (infoPtr->bFocus)
        DrawFocusRect (hdc, &rcClient);
}


static VOID
TRACKBAR_AlignBuddies (HWND hwnd, TRACKBAR_INFO *infoPtr)
{
    DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
    HWND hwndParent = GetParent (hwnd);
    RECT rcSelf, rcBuddy;
    INT x, y;

    GetWindowRect (hwnd, &rcSelf);
    MapWindowPoints (HWND_DESKTOP, hwndParent, (LPPOINT)&rcSelf, 2);

    /* align buddy left or above */
    if (infoPtr->hwndBuddyLA) {
	GetWindowRect (infoPtr->hwndBuddyLA, &rcBuddy);
	MapWindowPoints (HWND_DESKTOP, hwndParent, (LPPOINT)&rcBuddy, 2);

	if (dwStyle & TBS_VERT) {
	    x = (infoPtr->rcChannel.right + infoPtr->rcChannel.left) / 2 -
		(rcBuddy.right - rcBuddy.left) / 2 + rcSelf.left;
	    y = rcSelf.top - (rcBuddy.bottom - rcBuddy.top);
	}
	else {
	    x = rcSelf.left - (rcBuddy.right - rcBuddy.left);
	    y = (infoPtr->rcChannel.bottom + infoPtr->rcChannel.top) / 2 -
		(rcBuddy.bottom - rcBuddy.top) / 2 + rcSelf.top;
	}

	SetWindowPos (infoPtr->hwndBuddyLA, 0, x, y, 0, 0,
                      SWP_NOZORDER | SWP_NOSIZE);
    }


    /* align buddy right or below */
    if (infoPtr->hwndBuddyRB) {
	GetWindowRect (infoPtr->hwndBuddyRB, &rcBuddy);
	MapWindowPoints (HWND_DESKTOP, hwndParent, (LPPOINT)&rcBuddy, 2);

	if (dwStyle & TBS_VERT) {
	    x = (infoPtr->rcChannel.right + infoPtr->rcChannel.left) / 2 -
		(rcBuddy.right - rcBuddy.left) / 2 + rcSelf.left;
	    y = rcSelf.bottom;
	}
	else {
	    x = rcSelf.right;
	    y = (infoPtr->rcChannel.bottom + infoPtr->rcChannel.top) / 2 -
		(rcBuddy.bottom - rcBuddy.top) / 2 + rcSelf.top;
	}
	SetWindowPos (infoPtr->hwndBuddyRB, 0, x, y, 0, 0,
                      SWP_NOZORDER | SWP_NOSIZE);
    }
}


static LRESULT
TRACKBAR_ClearSel (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
    TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);

    infoPtr->nSelMin = 0;
    infoPtr->nSelMax = 0;
    infoPtr->flags |= TB_SELECTIONCHANGED;

    if ((BOOL)wParam) 
	InvalidateRect (hwnd, NULL, FALSE);

    return 0;
}


static LRESULT
TRACKBAR_ClearTics (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
    TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);

    if (infoPtr->tics) {
        COMCTL32_Free (infoPtr->tics);
        infoPtr->tics = NULL;
        infoPtr->uNumTics = 0;
    }

    if (wParam) 
        InvalidateRect (hwnd, NULL, FALSE);

    return 0;
}


static LRESULT
TRACKBAR_GetBuddy (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
    TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);

    if (wParam)  /* buddy is left or above */
        return (LRESULT)infoPtr->hwndBuddyLA;

    /* buddy is right or below */
    return (LRESULT) infoPtr->hwndBuddyRB;
}


static LRESULT
TRACKBAR_GetChannelRect (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
    TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
    LPRECT lprc = (LPRECT)lParam;

    if (lprc == NULL)
        return 0;

    lprc->left   = infoPtr->rcChannel.left;
    lprc->right  = infoPtr->rcChannel.right;
    lprc->bottom = infoPtr->rcChannel.bottom;
    lprc->top    = infoPtr->rcChannel.top;

    return 0;
}


static LRESULT
TRACKBAR_GetLineSize (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
    TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);

    return infoPtr->nLineSize;
}


static LRESULT
TRACKBAR_GetNumTics (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
    TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);

    if (GetWindowLongA (hwnd, GWL_STYLE) & TBS_NOTICKS)
        return 0;

    return infoPtr->uNumTics+2;
}


static LRESULT
TRACKBAR_GetPageSize (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
    TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);

    return infoPtr->nPageSize;
}


static LRESULT
TRACKBAR_GetPos (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
    TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);

    return infoPtr->nPos;
}


static LRESULT
TRACKBAR_GetRangeMax (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
    TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);

    return infoPtr->nRangeMax;
}


static LRESULT
TRACKBAR_GetRangeMin (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
    TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);

    return infoPtr->nRangeMin;
}


static LRESULT
TRACKBAR_GetSelEnd (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
    TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);

    return infoPtr->nSelMax;
}


static LRESULT
TRACKBAR_GetSelStart (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
    TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);

    return infoPtr->nSelMin;
}


static LRESULT
TRACKBAR_GetThumbLength (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
    TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);

    return infoPtr->uThumbLen;
}

static LRESULT
TRACKBAR_GetPTics (HWND hwnd)
{
    TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
    
    return (LRESULT) infoPtr->tics;
}

static LRESULT
TRACKBAR_GetThumbRect (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
    TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
    LPRECT lprc = (LPRECT)lParam;
    
    if (lprc == NULL)
        return 0; 
   
    lprc->left   = infoPtr->rcThumb.left;
    lprc->right  = infoPtr->rcThumb.right;
    lprc->bottom = infoPtr->rcThumb.bottom;
    lprc->top    = infoPtr->rcThumb.top;
   
    return 0;
}  


static LRESULT
TRACKBAR_GetTic (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
    TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
    INT iTic;

    iTic=(INT) wParam;
    if ((iTic<0) || (iTic>infoPtr->uNumTics)) 
	return -1;

    return (LRESULT) infoPtr->tics[iTic];

}


static LRESULT
TRACKBAR_GetTicPos (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
    TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
    INT iTic, range, width, pos;
 

    iTic=(INT ) wParam;
    if ((iTic<0) || (iTic>infoPtr->uNumTics)) 
	return -1;

    range=infoPtr->nRangeMax - infoPtr->nRangeMin;
    width=infoPtr->rcChannel.right - infoPtr->rcChannel.left;
    pos=infoPtr->rcChannel.left + (width * infoPtr->tics[iTic]) / range;


    return (LRESULT) pos;
}


static LRESULT
TRACKBAR_GetToolTips (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
    TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);

    if (GetWindowLongA (hwnd, GWL_STYLE) & TBS_TOOLTIPS)
        return (LRESULT)infoPtr->hwndToolTip;
    return 0;
}


/*	case TBM_GETUNICODEFORMAT: */


static LRESULT
TRACKBAR_SetBuddy (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
    TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
    HWND hwndTemp;

    if (wParam) {
	/* buddy is left or above */
	hwndTemp = infoPtr->hwndBuddyLA;
	infoPtr->hwndBuddyLA = (HWND)lParam;

	FIXME("move buddy!\n");
    }
    else {
        /* buddy is right or below */
        hwndTemp = infoPtr->hwndBuddyRB;
        infoPtr->hwndBuddyRB = (HWND)lParam;

        FIXME("move buddy!\n");
    }

    TRACKBAR_AlignBuddies (hwnd, infoPtr);

    return (LRESULT)hwndTemp;
}


static LRESULT
TRACKBAR_SetLineSize (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
    TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
    INT nTemp = infoPtr->nLineSize;

    infoPtr->nLineSize = (INT)lParam;

    return nTemp;
}


static LRESULT
TRACKBAR_SetPageSize (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
    TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
    INT nTemp = infoPtr->nPageSize;

    infoPtr->nPageSize = (INT)lParam;

    return nTemp;
}


static LRESULT
TRACKBAR_SetPos (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
    TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);

    infoPtr->nPos = (INT)lParam;

    if (infoPtr->nPos < infoPtr->nRangeMin)
	infoPtr->nPos = infoPtr->nRangeMin;

    if (infoPtr->nPos > infoPtr->nRangeMax)
	infoPtr->nPos = infoPtr->nRangeMax;
    infoPtr->flags |= TB_THUMBPOSCHANGED;

    if (wParam) 
        InvalidateRect (hwnd, NULL, FALSE);

    return 0;
}


static LRESULT
TRACKBAR_SetRange (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
    TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
    infoPtr->nRangeMin = (INT)LOWORD(lParam);
    infoPtr->nRangeMax = (INT)HIWORD(lParam);

    if (infoPtr->nPos < infoPtr->nRangeMin) {
        infoPtr->nPos = infoPtr->nRangeMin;
        infoPtr->flags |=TB_THUMBPOSCHANGED;
    }

    if (infoPtr->nPos > infoPtr->nRangeMax) {
        infoPtr->nPos = infoPtr->nRangeMax;
        infoPtr->flags |=TB_THUMBPOSCHANGED;
    }

    infoPtr->nPageSize=(infoPtr->nRangeMax -  infoPtr->nRangeMin)/5;
    if (infoPtr->nPageSize == 0)
        infoPtr->nPageSize = 1;
    TRACKBAR_RecalculateTics (infoPtr);

    if (wParam)
        InvalidateRect (hwnd, NULL, FALSE);

    return 0;
}


static LRESULT
TRACKBAR_SetRangeMax (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
    TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);

    infoPtr->nRangeMax = (INT)lParam;
    if (infoPtr->nPos > infoPtr->nRangeMax) {
        infoPtr->nPos = infoPtr->nRangeMax;
        infoPtr->flags |=TB_THUMBPOSCHANGED;
    }

    infoPtr->nPageSize=(infoPtr->nRangeMax -  infoPtr->nRangeMin)/5;
    if (infoPtr->nPageSize == 0)
        infoPtr->nPageSize = 1;
    TRACKBAR_RecalculateTics (infoPtr);

    if (wParam) 
        InvalidateRect (hwnd, NULL, FALSE);

    return 0;
}


static LRESULT
TRACKBAR_SetRangeMin (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
    TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);

    infoPtr->nRangeMin = (INT)lParam;
    if (infoPtr->nPos < infoPtr->nRangeMin) {
        infoPtr->nPos = infoPtr->nRangeMin;
        infoPtr->flags |=TB_THUMBPOSCHANGED;
    }

    infoPtr->nPageSize=(infoPtr->nRangeMax -  infoPtr->nRangeMin)/5;
    if (infoPtr->nPageSize == 0)
        infoPtr->nPageSize = 1;
    TRACKBAR_RecalculateTics (infoPtr);

    if (wParam)
        InvalidateRect (hwnd, NULL, FALSE);

    return 0;
}


static LRESULT
TRACKBAR_SetTicFreq (HWND hwnd, WPARAM wParam)
{
    TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
	
    if (GetWindowLongA (hwnd, GWL_STYLE) & TBS_AUTOTICKS)
        infoPtr->uTicFreq=(UINT) wParam; 
	
    TRACKBAR_RecalculateTics (infoPtr);

    InvalidateRect (hwnd, NULL, FALSE);

    return 0;
}   


static LRESULT
TRACKBAR_SetSel (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
    TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);

    infoPtr->nSelMin = (INT)LOWORD(lParam);
    infoPtr->nSelMax = (INT)HIWORD(lParam);
    infoPtr->flags |=TB_SELECTIONCHANGED;

    if (!GetWindowLongA (hwnd, GWL_STYLE) & TBS_ENABLESELRANGE)
        return 0;

    if (infoPtr->nSelMin < infoPtr->nRangeMin)
        infoPtr->nSelMin = infoPtr->nRangeMin;
    if (infoPtr->nSelMax > infoPtr->nRangeMax)
        infoPtr->nSelMax = infoPtr->nRangeMax;

    if (wParam) 
        InvalidateRect (hwnd, NULL, FALSE);


    return 0;
}


static LRESULT
TRACKBAR_SetSelEnd (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
    TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);

    if (!GetWindowLongA (hwnd, GWL_STYLE) & TBS_ENABLESELRANGE)
	return 0;

    infoPtr->nSelMax = (INT)lParam;
    infoPtr->flags |= TB_SELECTIONCHANGED;
	
    if (infoPtr->nSelMax > infoPtr->nRangeMax)
        infoPtr->nSelMax = infoPtr->nRangeMax;

    if (wParam) 
        InvalidateRect (hwnd, NULL, FALSE);

    return 0;
}


static LRESULT
TRACKBAR_SetSelStart (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
    TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);

    if (!GetWindowLongA (hwnd, GWL_STYLE) & TBS_ENABLESELRANGE)
	return 0;

    infoPtr->nSelMin = (INT)lParam;
    infoPtr->flags  |=TB_SELECTIONCHANGED;

    if (infoPtr->nSelMin < infoPtr->nRangeMin)
        infoPtr->nSelMin = infoPtr->nRangeMin;

    if (wParam) 
        InvalidateRect (hwnd, NULL, FALSE);

    return 0;
}


static LRESULT
TRACKBAR_SetThumbLength (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
    TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);

    if (GetWindowLongA (hwnd, GWL_STYLE) & TBS_FIXEDLENGTH)
        infoPtr->uThumbLen = (UINT)wParam;

    infoPtr->flags |= TB_THUMBSIZECHANGED;

    InvalidateRect (hwnd, NULL, FALSE);

    return 0;
}


static LRESULT
TRACKBAR_SetTic (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
    TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
    INT nPos = (INT)lParam;

    if ((nPos < infoPtr->nRangeMin) || (nPos> infoPtr->nRangeMax))
        return FALSE;

    infoPtr->uNumTics++;
    infoPtr->tics=COMCTL32_ReAlloc( infoPtr->tics,
                                    (infoPtr->uNumTics)*sizeof (DWORD));
    infoPtr->tics[infoPtr->uNumTics-1]=nPos;

    InvalidateRect (hwnd, NULL, FALSE);

    return TRUE;
}


static LRESULT
TRACKBAR_SetTipSide (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
    TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
    INT fTemp = infoPtr->fLocation;

    infoPtr->fLocation = (INT)wParam;
	
    return fTemp;
}


static LRESULT
TRACKBAR_SetToolTips (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
    TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);

    infoPtr->hwndToolTip = (HWND)wParam;

    return 0;
}


/*	case TBM_SETUNICODEFORMAT: */


static LRESULT
TRACKBAR_InitializeThumb (HWND hwnd)
{
    TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);

    infoPtr->uThumbLen = 23;   /* initial thumb length */

    TRACKBAR_CalcChannel (hwnd,infoPtr);
    TRACKBAR_CalcThumb (hwnd, infoPtr);
    infoPtr->flags &= ~TB_SELECTIONCHANGED;

    return 0;
}


static LRESULT
TRACKBAR_Create (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
    TRACKBAR_INFO *infoPtr;

    infoPtr = (TRACKBAR_INFO *)COMCTL32_Alloc (sizeof(TRACKBAR_INFO));
    SetWindowLongA (hwnd, 0, (DWORD)infoPtr);

    /* set default values */
    infoPtr->nRangeMin = 0;
    infoPtr->nRangeMax = 100;
    infoPtr->nLineSize = 1;
    infoPtr->nPageSize = 20;
    infoPtr->nSelMin   = 0;
    infoPtr->nSelMax   = 0;
    infoPtr->nPos      = 0;

    infoPtr->uNumTics  = 0;    /* start and end tic are not included in count*/
    infoPtr->uTicFreq  = 1;
    infoPtr->tics	   = NULL;
    infoPtr->clrBk	   = GetSysColor (COLOR_BTNFACE);
    infoPtr->hwndNotify = GetParent (hwnd);

    TRACKBAR_InitializeThumb (hwnd);

    /* Create tooltip control */
    if (GetWindowLongA (hwnd, GWL_STYLE) & TBS_TOOLTIPS) {
        TTTOOLINFOA ti;

    	infoPtr->hwndToolTip =
            CreateWindowExA (0, TOOLTIPS_CLASSA, NULL, 0,
                             CW_USEDEFAULT, CW_USEDEFAULT,
                             CW_USEDEFAULT, CW_USEDEFAULT,
                             hwnd, 0, 0, 0);

        /* Send NM_TOOLTIPSCREATED notification */
    	if (infoPtr->hwndToolTip) {
            NMTOOLTIPSCREATED nmttc;

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

            SendMessageA (GetParent (hwnd), WM_NOTIFY,
                          (WPARAM)nmttc.hdr.idFrom, (LPARAM)&nmttc);
    	}

        ZeroMemory (&ti, sizeof(TTTOOLINFOA));
        ti.cbSize   = sizeof(TTTOOLINFOA);
     	ti.uFlags   = TTF_IDISHWND | TTF_TRACK;
	ti.hwnd     = hwnd;
        ti.uId      = 0;
        ti.lpszText = "Test"; /* LPSTR_TEXTCALLBACK */
        SetRectEmpty (&ti.rect);

        SendMessageA (infoPtr->hwndToolTip, TTM_ADDTOOLA, 0, (LPARAM)&ti);
    }

    return 0;
}


static LRESULT
TRACKBAR_Destroy (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
    TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);

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

    COMCTL32_Free (infoPtr);
    SetWindowLongA (hwnd, 0, 0);
    return 0;
}


static LRESULT
TRACKBAR_KillFocus (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
    TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);

    TRACE("\n");

    infoPtr->bFocus = FALSE;
    infoPtr->flags &= ~TB_DRAG_MODE;

    InvalidateRect (hwnd, NULL, FALSE);

    return 0;
}


static LRESULT
TRACKBAR_LButtonDown (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
    TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
    DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
    POINT clickPoint;

    SetFocus (hwnd);

    clickPoint.y = HIWORD(lParam);
    clickPoint.x = LOWORD(lParam);

    if (PtInRect(&(infoPtr->rcThumb),clickPoint))
    {
        infoPtr->flags |= TB_DRAG_MODE;
        if (dwStyle & TBS_TOOLTIPS) {  /* enable tooltip */
            TTTOOLINFOA ti;
            POINT pt;

            GetCursorPos (&pt);
            SendMessageA (infoPtr->hwndToolTip, TTM_TRACKPOSITION, 0,
                          (LPARAM)MAKELPARAM(pt.x, pt.y));

            ti.cbSize   = sizeof(TTTOOLINFOA);
            ti.uId      = 0;
            ti.hwnd     = (UINT)hwnd;

            infoPtr->flags |= TB_SHOW_TOOLTIP;
            SetCapture (hwnd);
            SendMessageA (infoPtr->hwndToolTip, TTM_TRACKACTIVATE, 
                          (WPARAM)TRUE, (LPARAM)&ti);
        }
        return 0;
    }
    else if (PtInRect(&(infoPtr->rcChannel),clickPoint))
    {
        int clickPlace,prevPos,vertical;
        DOUBLE clickPos;

        vertical = (dwStyle & TBS_VERT) ? 1 : 0;
        if (vertical)
            clickPlace=(INT)HIWORD(lParam);
        else
            clickPlace=(INT)LOWORD(lParam);

       clickPos = TRACKBAR_ConvertPlaceToPosition(infoPtr, clickPlace, 
                                                   vertical);
        prevPos = infoPtr->nPos;
        if (clickPos > (int)prevPos)
        {  /* similar to VK_NEXT */
            infoPtr->nPos += infoPtr->nPageSize;
            if (infoPtr->nPos > infoPtr->nRangeMax)
                infoPtr->nPos = infoPtr->nRangeMax;
            TRACKBAR_SendNotify (hwnd, TB_PAGEUP);  
        } 
        else 
        {
            infoPtr->nPos -= infoPtr->nPageSize;  /* similar to VK_PRIOR */
            if (infoPtr->nPos < infoPtr->nRangeMin)
                infoPtr->nPos = infoPtr->nRangeMin;
            TRACKBAR_SendNotify (hwnd, TB_PAGEDOWN);
        }
	
        if (prevPos!=infoPtr->nPos) {
            infoPtr->flags |= TB_THUMBPOSCHANGED;
            InvalidateRect (hwnd, NULL, FALSE);
        }
    }
	
    return 0;
}


static LRESULT
TRACKBAR_LButtonUp (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
    TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);

    TRACKBAR_SendNotify (hwnd, TB_ENDTRACK);

    if (infoPtr->flags & TB_DRAG_MODE)
    {
        infoPtr->flags &= ~TB_DRAG_MODE;
        ReleaseCapture ();
    }

    if (GetWindowLongA (hwnd, GWL_STYLE) & TBS_TOOLTIPS) {  /* disable tooltip */
    	TTTOOLINFOA ti;

        ti.cbSize   = sizeof(TTTOOLINFOA);
        ti.uId      = 0;
        ti.hwnd     = (UINT)hwnd;

        infoPtr->flags &= ~TB_SHOW_TOOLTIP;
        SendMessageA (infoPtr->hwndToolTip, TTM_TRACKACTIVATE,
                      (WPARAM)FALSE, (LPARAM)&ti);
    }
    
    InvalidateRect (hwnd, NULL, FALSE);

    return 0;
}


static LRESULT
TRACKBAR_CaptureChanged (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
    TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
	
    if (infoPtr->flags & TB_DRAGPOSVALID) {
        infoPtr->nPos=infoPtr->dragPos;
        InvalidateRect (hwnd, NULL, FALSE);
    }
	
    infoPtr->flags &= ~ TB_DRAGPOSVALID;

    TRACKBAR_SendNotify (hwnd, TB_ENDTRACK);
    return 0;
}


static LRESULT
TRACKBAR_Paint (HWND hwnd, WPARAM wParam)
{
    HDC hdc;
    PAINTSTRUCT ps;

    hdc = wParam==0 ? BeginPaint (hwnd, &ps) : (HDC)wParam;
    TRACKBAR_Refresh (hwnd, hdc);
    if(!wParam)
	EndPaint (hwnd, &ps);
    return 0;
}


static LRESULT
TRACKBAR_SetFocus (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
    TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);

    TRACE("\n");
    infoPtr->bFocus = TRUE;

    InvalidateRect (hwnd, NULL, FALSE);

    return 0;
}


static LRESULT
TRACKBAR_Size (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
    TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);

    TRACKBAR_CalcChannel (hwnd, infoPtr);
    TRACKBAR_AlignBuddies (hwnd, infoPtr);

    return 0;
}


static BOOL
TRACKBAR_SendNotify (HWND hwnd, UINT code)
{
    TRACE("%x\n",code);

    if (GetWindowLongA (hwnd, GWL_STYLE) & TBS_VERT) 
    	return (BOOL) SendMessageA (GetParent (hwnd), 
                                    WM_VSCROLL, (WPARAM)code, (LPARAM)hwnd);

    return (BOOL) SendMessageA (GetParent (hwnd), 
                                WM_HSCROLL, (WPARAM)code, (LPARAM)hwnd);
}


static LRESULT
TRACKBAR_MouseMove (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
    TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
    DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
    SHORT clickPlace;
    DOUBLE dragPos;
    char buf[80];
			
    TRACE("%x\n",wParam);

    if (dwStyle & TBS_VERT)
        clickPlace=(SHORT)HIWORD(lParam);
    else
        clickPlace=(SHORT)LOWORD(lParam);

    if (!(infoPtr->flags & TB_DRAG_MODE))
	return TRUE;

    SetCapture (hwnd);
    dragPos = TRACKBAR_ConvertPlaceToPosition (infoPtr, clickPlace, 
                                               dwStyle & TBS_VERT);
    if (dragPos > ((INT)dragPos) + 0.5)
        infoPtr->dragPos = dragPos + 1;
    else
        infoPtr->dragPos = dragPos;

    infoPtr->flags |= TB_DRAGPOSVALID;
    TRACKBAR_SendNotify (hwnd, TB_THUMBTRACK | (infoPtr->nPos<<16));

    if (infoPtr->flags & TB_SHOW_TOOLTIP) {
        POINT pt;
    	TTTOOLINFOA ti;
	
    	ti.cbSize = sizeof(TTTOOLINFOA);
	ti.hwnd = hwnd;
    	ti.uId = 0;
        ti.hinst=0;
        sprintf (buf,"%d",infoPtr->nPos);
    	ti.lpszText = (LPSTR) buf;
        GetCursorPos (&pt);
		
	if (dwStyle & TBS_VERT) {
            SendMessageA (infoPtr->hwndToolTip, TTM_TRACKPOSITION, 
                          0, (LPARAM)MAKELPARAM(pt.x+5, pt.y+15));
        } else {
            SendMessageA (infoPtr->hwndToolTip, TTM_TRACKPOSITION, 
                          0, (LPARAM)MAKELPARAM(pt.x+15, pt.y+5));
        }
    	SendMessageA (infoPtr->hwndToolTip, TTM_UPDATETIPTEXTA,
                      0, (LPARAM)&ti);
    }

    InvalidateRect (hwnd, NULL, FALSE);
    UpdateWindow (hwnd);

    return TRUE;
}


static LRESULT
TRACKBAR_KeyDown (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
    TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
    INT pos;

    TRACE("%x\n",wParam);

    pos=infoPtr->nPos;
    switch (wParam) {
    case VK_LEFT:
    case VK_UP: 
        if (infoPtr->nPos == infoPtr->nRangeMin) return FALSE;
        infoPtr->nPos -= infoPtr->nLineSize;
        if (infoPtr->nPos < infoPtr->nRangeMin) 
            infoPtr->nPos = infoPtr->nRangeMin;
        TRACKBAR_SendNotify (hwnd, TB_LINEUP);
        break;
    case VK_RIGHT:
    case VK_DOWN: 
        if (infoPtr->nPos == infoPtr->nRangeMax) return FALSE;
        infoPtr->nPos += infoPtr->nLineSize;
        if (infoPtr->nPos > infoPtr->nRangeMax) 
            infoPtr->nPos = infoPtr->nRangeMax;
        TRACKBAR_SendNotify (hwnd, TB_LINEDOWN);
        break;
    case VK_NEXT:
        if (infoPtr->nPos == infoPtr->nRangeMax) return FALSE;
        infoPtr->nPos += infoPtr->nPageSize;
        if (infoPtr->nPos > infoPtr->nRangeMax) 
            infoPtr->nPos = infoPtr->nRangeMax;
        TRACKBAR_SendNotify (hwnd, TB_PAGEUP);
        break;
    case VK_PRIOR:
        if (infoPtr->nPos == infoPtr->nRangeMin) return FALSE;
        infoPtr->nPos -= infoPtr->nPageSize;
        if (infoPtr->nPos < infoPtr->nRangeMin) 
            infoPtr->nPos = infoPtr->nRangeMin;
        TRACKBAR_SendNotify (hwnd, TB_PAGEDOWN);
        break;
    case VK_HOME: 
        if (infoPtr->nPos == infoPtr->nRangeMin) return FALSE;
        infoPtr->nPos = infoPtr->nRangeMin;
        TRACKBAR_SendNotify (hwnd, TB_TOP);
        break;
    case VK_END: 
        if (infoPtr->nPos == infoPtr->nRangeMax) return FALSE;
        infoPtr->nPos = infoPtr->nRangeMax;
        TRACKBAR_SendNotify (hwnd, TB_BOTTOM);
        break;
    }

    if (pos!=infoPtr->nPos) { 
	infoPtr->flags |=TB_THUMBPOSCHANGED;
	InvalidateRect (hwnd, NULL, FALSE);
    }

    return TRUE;
}


static LRESULT
TRACKBAR_KeyUp (HWND hwnd, WPARAM wParam)
{
    switch (wParam) {
    case VK_LEFT:
    case VK_UP: 
    case VK_RIGHT:
    case VK_DOWN: 
    case VK_NEXT:
    case VK_PRIOR:
    case VK_HOME: 
    case VK_END:
        TRACKBAR_SendNotify (hwnd, TB_ENDTRACK);
    }
    return TRUE;
}


static LRESULT WINAPI
TRACKBAR_WindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    TRACE("hwnd=%x msg=%x wparam=%x lparam=%lx\n", hwnd, uMsg, wParam, lParam);
    if (!TRACKBAR_GetInfoPtr (hwnd) && (uMsg != WM_CREATE))
        return DefWindowProcA (hwnd, uMsg, wParam, lParam);
    switch (uMsg)
    {
    case TBM_CLEARSEL:
        return TRACKBAR_ClearSel (hwnd, wParam, lParam);

    case TBM_CLEARTICS:
        return TRACKBAR_ClearTics (hwnd, wParam, lParam);

    case TBM_GETBUDDY:
        return TRACKBAR_GetBuddy (hwnd, wParam, lParam);

    case TBM_GETCHANNELRECT:
        return TRACKBAR_GetChannelRect (hwnd, wParam, lParam);

    case TBM_GETLINESIZE:
        return TRACKBAR_GetLineSize (hwnd, wParam, lParam);

    case TBM_GETNUMTICS:
        return TRACKBAR_GetNumTics (hwnd, wParam, lParam);

    case TBM_GETPAGESIZE:
        return TRACKBAR_GetPageSize (hwnd, wParam, lParam);

    case TBM_GETPOS:
        return TRACKBAR_GetPos (hwnd, wParam, lParam);

    case TBM_GETPTICS:
        return TRACKBAR_GetPTics (hwnd);

    case TBM_GETRANGEMAX:
        return TRACKBAR_GetRangeMax (hwnd, wParam, lParam);

    case TBM_GETRANGEMIN:
        return TRACKBAR_GetRangeMin (hwnd, wParam, lParam);

    case TBM_GETSELEND:
        return TRACKBAR_GetSelEnd (hwnd, wParam, lParam);

    case TBM_GETSELSTART:
        return TRACKBAR_GetSelStart (hwnd, wParam, lParam);

    case TBM_GETTHUMBLENGTH:
        return TRACKBAR_GetThumbLength (hwnd, wParam, lParam);

    case TBM_GETTHUMBRECT:
        return TRACKBAR_GetThumbRect (hwnd, wParam, lParam);

    case TBM_GETTIC:
        return TRACKBAR_GetTic (hwnd, wParam, lParam);
 
    case TBM_GETTICPOS:
        return TRACKBAR_GetTicPos (hwnd, wParam, lParam);
 
    case TBM_GETTOOLTIPS:
        return TRACKBAR_GetToolTips (hwnd, wParam, lParam);

/*	case TBM_GETUNICODEFORMAT: */

    case TBM_SETBUDDY:
        return TRACKBAR_SetBuddy (hwnd, wParam, lParam);

    case TBM_SETLINESIZE:
        return TRACKBAR_SetLineSize (hwnd, wParam, lParam);

    case TBM_SETPAGESIZE:
        return TRACKBAR_SetPageSize (hwnd, wParam, lParam);

    case TBM_SETPOS:
        return TRACKBAR_SetPos (hwnd, wParam, lParam);

    case TBM_SETRANGE:
        return TRACKBAR_SetRange (hwnd, wParam, lParam);

    case TBM_SETRANGEMAX:
        return TRACKBAR_SetRangeMax (hwnd, wParam, lParam);

    case TBM_SETRANGEMIN:
        return TRACKBAR_SetRangeMin (hwnd, wParam, lParam);

    case TBM_SETSEL:
        return TRACKBAR_SetSel (hwnd, wParam, lParam);

    case TBM_SETSELEND:
        return TRACKBAR_SetSelEnd (hwnd, wParam, lParam);

    case TBM_SETSELSTART:
        return TRACKBAR_SetSelStart (hwnd, wParam, lParam);

    case TBM_SETTHUMBLENGTH:
        return TRACKBAR_SetThumbLength (hwnd, wParam, lParam);

    case TBM_SETTIC:
        return TRACKBAR_SetTic (hwnd, wParam, lParam);

    case TBM_SETTICFREQ:
        return TRACKBAR_SetTicFreq (hwnd, wParam);

    case TBM_SETTIPSIDE:
        return TRACKBAR_SetTipSide (hwnd, wParam, lParam);

    case TBM_SETTOOLTIPS:
        return TRACKBAR_SetToolTips (hwnd, wParam, lParam);

/*	case TBM_SETUNICODEFORMAT: */


    case WM_CAPTURECHANGED:
        return TRACKBAR_CaptureChanged (hwnd, wParam, lParam);

    case WM_CREATE:
        return TRACKBAR_Create (hwnd, wParam, lParam);

    case WM_DESTROY:
        return TRACKBAR_Destroy (hwnd, wParam, lParam);

/*	case WM_ENABLE: */

/*	case WM_ERASEBKGND: */
/*	    return 0; */

    case WM_GETDLGCODE:
        return DLGC_WANTARROWS;

    case WM_KEYDOWN:
        return TRACKBAR_KeyDown (hwnd, wParam, lParam);
        
    case WM_KEYUP:
        return TRACKBAR_KeyUp (hwnd, wParam);

    case WM_KILLFOCUS:
        return TRACKBAR_KillFocus (hwnd, wParam, lParam);

    case WM_LBUTTONDOWN:
        return TRACKBAR_LButtonDown (hwnd, wParam, lParam);

    case WM_LBUTTONUP:
        return TRACKBAR_LButtonUp (hwnd, wParam, lParam);

    case WM_MOUSEMOVE:
        return TRACKBAR_MouseMove (hwnd, wParam, lParam);

    case WM_PAINT:
        return TRACKBAR_Paint (hwnd, wParam);

    case WM_SETFOCUS:
        return TRACKBAR_SetFocus (hwnd, wParam, lParam);

    case WM_SIZE:
        return TRACKBAR_Size (hwnd, wParam, lParam);

    case WM_WININICHANGE:
        return TRACKBAR_InitializeThumb (hwnd);

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


VOID
TRACKBAR_Register (void)
{
    WNDCLASSA wndClass;

    ZeroMemory (&wndClass, sizeof(WNDCLASSA));
    wndClass.style         = CS_GLOBALCLASS;
    wndClass.lpfnWndProc   = (WNDPROC)TRACKBAR_WindowProc;
    wndClass.cbClsExtra    = 0;
    wndClass.cbWndExtra    = sizeof(TRACKBAR_INFO *);
    wndClass.hCursor       = LoadCursorA (0, IDC_ARROWA);
    wndClass.hbrBackground = (HBRUSH)(COLOR_3DFACE + 1);
    wndClass.lpszClassName = TRACKBAR_CLASSA;
 
    RegisterClassA (&wndClass);
}


VOID
TRACKBAR_Unregister (void)
{
    UnregisterClassA (TRACKBAR_CLASSA, (HINSTANCE)NULL);
}

