/*		
 * Updown control
 *
 * Copyright 1997 Dimitrie O. Paun
 *
 * TODO:
 *   - subclass the buddy window (in UPDOWN_SetBuddy) to process the
 *     arrow keys
 *   - I am not sure about the default values for the Min, Max, Pos
 *     (in the UPDOWN_INFO the fields: MinVal, MaxVal, CurVal)
 *   - I think I do not handle correctly the WS_BORDER style.
 * Testing:
 *   Not much. The following  have not been tested at all:
 *     - horizontal arrows
 *     - listbox as buddy window
 *     - acceleration
 *     - base 16
 *     - UDS_ALIGNLEFT, ~UDS_WRAP
 *     - integers with thousand separators.
 *   Even though the above list seems rather large, the control seems to
 *   behave very well so I am confident it does work in most (all) of the
 *   untested cases.
 * Problems:
 *   I do not like the arrows yet, I'll work more on them later on.
 */

#include <stdlib.h>
#include <assert.h>
#include <string.h>
#include "windows.h"
#include "winnls.h"
#include "sysmetrics.h"
#include "updown.h"
#include "graphics.h"
#include "heap.h"
#include "win.h"
#include "debug.h"

/* Control configuration constants */

#define INITIAL_DELAY    500 /* initial timer until auto-increment kicks in */
#define REPEAT_DELAY     50  /* delay between auto-increments */

#define DEFAULT_WIDTH    14  /* default width of the ctrl */
#define DEFAULT_XSEP      0  /* default separation between buddy and crtl */
#define DEFAULT_ADDTOP    0  /* amount to extend above the buddy window */
#define DEFAULT_ADDBOT    0  /* amount to extend below the buddy window */


/* Work constants */

#define FLAG_INCR        0x01
#define FLAG_DECR        0x02
#define FLAG_MOUSEIN     0x04
#define FLAG_CLICKED     (FLAG_INCR | FLAG_DECR)

#define TIMERID1         1
#define TIMERID2         2

static int accelIndex = -1;

#define UNKNOWN_PARAM(msg, wParam, lParam) WARN(updown, \
        "UpDown Ctrl: Unknown parameter(s) for message " #msg     \
	"(%04x): wp=%04x lp=%08lx\n", msg, wParam, lParam);

#define UPDOWN_GetInfoPtr(wndPtr) ((UPDOWN_INFO *)wndPtr->wExtra)

/***********************************************************************
 *           UPDOWN_InBounds
 * Tests if a given value 'val' is between the Min&Max limits
 */
static BOOL32 UPDOWN_InBounds(WND *wndPtr, int val)
{
  UPDOWN_INFO *infoPtr = UPDOWN_GetInfoPtr(wndPtr);

  if(infoPtr->MaxVal > infoPtr->MinVal)
    return (infoPtr->MinVal <= val) && (val <= infoPtr->MaxVal);
  else
    return (infoPtr->MaxVal <= val) && (val <= infoPtr->MinVal);
}

/***********************************************************************
 *           UPDOWN_OffsetVal
 * Tests if we can change the current value by delta. If so, it changes
 * it and returns TRUE. Else, it leaves it unchanged and returns FALSE.
 */
static BOOL32 UPDOWN_OffsetVal(WND *wndPtr, int delta)
{
  UPDOWN_INFO *infoPtr = UPDOWN_GetInfoPtr(wndPtr);

  /* check if we can do the modification first */
  if(!UPDOWN_InBounds(wndPtr, infoPtr->CurVal+delta)){
    if(wndPtr->dwStyle & UDS_WRAP)
      delta += (delta < 0 ? -1 : 1) *
	(infoPtr->MaxVal < infoPtr->MinVal ? -1 : 1) *
	(infoPtr->MinVal - infoPtr->MaxVal) +
	(delta < 0 ? 1 : -1);
    else
      return FALSE;
  }

  infoPtr->CurVal += delta;
  return TRUE;
}

/***********************************************************************
 *           UPDOWN_GetArrowRect
 * wndPtr   - pointer to the up-down wnd
 * rect     - will hold the rectangle
 * incr     - TRUE  get the "increment" rect (up or right)
 *            FALSE get the "decrement" rect (down or left)
 *          
 */
static void UPDOWN_GetArrowRect(WND *wndPtr, RECT32 *rect, BOOL32 incr)
{
  int len; /* will hold the width or height */

  GetClientRect32(wndPtr->hwndSelf, rect);

  if (wndPtr->dwStyle & UDS_HORZ) {
    len = rect->right - rect->left; /* compute the width */
    if (incr)
      rect->left = len/2+1; 
    else
      rect->right = len/2;
  }
  else {
    len = rect->bottom - rect->top; /* compute the height */
    if (incr)
      rect->bottom = len/2;
    else
      rect->top = len/2+1;
  }
}

/***********************************************************************
 *           UPDOWN_GetArrowFromPoint
 * Returns the rectagle (for the up or down arrow) that contains pt.
 * If it returns the up rect, it returns TRUE.
 * If it returns the down rect, it returns FALSE.
 */
static int UPDOWN_GetArrowFromPoint(WND *wndPtr, RECT32 *rect, POINT32 pt)
{
  UPDOWN_GetArrowRect(wndPtr, rect, TRUE);
  if(PtInRect32(rect, pt))
    return TRUE;

  UPDOWN_GetArrowRect(wndPtr, rect, FALSE);
  return FALSE;
}


/***********************************************************************
 *           UPDOWN_GetThousandSep
 * Returns the thousand sep. If an error occurs, it returns ','.
 */
static char UPDOWN_GetThousandSep()
{
  char sep[2];

  if(GetLocaleInfo32A(LOCALE_USER_DEFAULT, LOCALE_STHOUSAND, 
		      sep, sizeof(sep)) != 1)
    return ',';

  return sep[0];
}

/***********************************************************************
 *           UPDOWN_GetBuddyInt
 * Tries to read the pos from the buddy window and if it succeeds,
 * it stores it in the control's CurVal
 * returns:
 *   TRUE  - if it read the integer from the buddy successfully
 *   FALSE - if an error occured
 */
static BOOL32 UPDOWN_GetBuddyInt(WND *wndPtr)
{
  UPDOWN_INFO *infoPtr = UPDOWN_GetInfoPtr(wndPtr);
  char txt[20], sep, *src, *dst;
  int newVal;

  if (!IsWindow32(infoPtr->Buddy))
    return FALSE;

  /*if the buddy is a list window, we must set curr index */
  if(WIDGETS_IsControl32(WIN_FindWndPtr(infoPtr->Buddy), BIC32_LISTBOX)){
    newVal = SendMessage32A(infoPtr->Buddy, LB_GETCARETINDEX32, 0, 0);
    if(newVal < 0)
      return FALSE;
  }
  else{
    /* we have a regural window, so will get the text */
    if (!GetWindowText32A(infoPtr->Buddy, txt, sizeof(txt)))
      return FALSE;

    sep = UPDOWN_GetThousandSep(); 

    /* now get rid of the separators */
    for(src = dst = txt; *src; src++)
      if(*src != sep)
	*dst++ = *src;
    *dst = 0;

    /* try to convert the number and validate it */
    newVal = strtol(txt, &src, infoPtr->Base);
    if(*src || !UPDOWN_InBounds(wndPtr, newVal)) 
      return FALSE;

    TRACE(updown, "new value(%d) read from buddy (old=%d)\n", 
		 newVal, infoPtr->CurVal);
  }
  
  infoPtr->CurVal = newVal;
  return TRUE;
}


/***********************************************************************
 *           UPDOWN_SetBuddyInt
 * Tries to set the pos to the buddy window based on current pos
 * returns:
 *   TRUE  - if it set the caption of the  buddy successfully
 *   FALSE - if an error occured
 */
static BOOL32 UPDOWN_SetBuddyInt(WND *wndPtr)
{
  UPDOWN_INFO *infoPtr = UPDOWN_GetInfoPtr(wndPtr);
  char txt1[20], sep;
  int len;

  if (!IsWindow32(infoPtr->Buddy)) 
    return FALSE;

  TRACE(updown, "set new value(%d) to buddy.\n",
	       infoPtr->CurVal);

  /*if the buddy is a list window, we must set curr index */
  if(WIDGETS_IsControl32(WIN_FindWndPtr(infoPtr->Buddy), BIC32_LISTBOX)){
    SendMessage32A(infoPtr->Buddy, LB_SETCURSEL32, infoPtr->CurVal, 0);
  }
  else{ /* Regural window, so set caption to the number */
    len = sprintf(txt1, (infoPtr->Base==16) ? "%X" : "%d", infoPtr->CurVal);

    sep = UPDOWN_GetThousandSep(); 

    if (!(wndPtr->dwStyle & UDS_NOTHOUSANDS)) {
      char txt2[20], *src = txt1, *dst = txt2;
      if(len%3 > 0){
	strncpy(dst, src, len%3);
	dst += len%3;
	src += len%3;
      }
      for(len=0; *src; len++,src++){
	if(len%3==0)
	  *dst++ = sep;
	*dst++ = *src++;
      }
      *dst = 0;           /* null terminate it */
      strcpy(txt1, txt2); /* move it to the proper place */
    }
    SetWindowText32A(infoPtr->Buddy, txt1);
  }

  return TRUE;
} 

/***********************************************************************
 *           UPDOWN_Paint
 * Draw the arrows. The background need not be erased.
 */
static void UPDOWN_Paint(WND *wndPtr)
{
  UPDOWN_INFO *infoPtr = UPDOWN_GetInfoPtr(wndPtr);
  PAINTSTRUCT32 ps;
  BOOL32 prssed;
  RECT32 rect;
  HDC32 hdc;
  
  /* start painting the button */
  hdc = BeginPaint32( wndPtr->hwndSelf, &ps );

  /* Draw the incr button */
  UPDOWN_GetArrowRect(wndPtr, &rect, TRUE);
  prssed = (infoPtr->Flags & FLAG_INCR) && (infoPtr->Flags & FLAG_MOUSEIN);
  DrawFrameControl32(hdc, &rect, DFC_SCROLL, 
	(wndPtr->dwStyle & UDS_HORZ ? DFCS_SCROLLLEFT : DFCS_SCROLLUP) |
	(prssed ? DFCS_PUSHED : 0) |
	(wndPtr->dwStyle&WS_DISABLED ? DFCS_INACTIVE : 0) );

  /* Draw the space between the buttons */
  rect.top = rect.bottom; rect.bottom++;
  DrawEdge32(hdc, &rect, 0, BF_MIDDLE);
		    
  /* Draw the decr button */
  UPDOWN_GetArrowRect(wndPtr, &rect, FALSE);
  prssed = (infoPtr->Flags & FLAG_DECR) && (infoPtr->Flags & FLAG_MOUSEIN);
  DrawFrameControl32(hdc, &rect, DFC_SCROLL, 
	(wndPtr->dwStyle & UDS_HORZ ? DFCS_SCROLLRIGHT : DFCS_SCROLLDOWN) |
	(prssed ? DFCS_PUSHED : 0) |
	(wndPtr->dwStyle&WS_DISABLED ? DFCS_INACTIVE : 0) );


  /* clean-up */  
  EndPaint32( wndPtr->hwndSelf, &ps );
}

/***********************************************************************
 *           UPDOWN_SetBuddy
 * Tests if 'hwndBud' is a valid window handle. If not, returns FALSE.
 * Else, sets it as a new Buddy.
 * Then, it should subclass the buddy 
 * If window has the UDS_ARROWKEYS, it subcalsses the buddy window to
 * process the UP/DOWN arrow keys.
 * If window has the UDS_ALIGNLEFT or UDS_ALIGNRIGHT style
 * the size/pos of the buddy and the control are adjusted accordingly.
 */
static BOOL32 UPDOWN_SetBuddy(WND *wndPtr, HWND32 hwndBud)
{
  UPDOWN_INFO *infoPtr = UPDOWN_GetInfoPtr(wndPtr); 
  RECT32 budRect; /* new coord for the buddy */
  int x;          /* new x position and width for the up-down */
 	  
  /* Is is a valid bud? */
  if(!IsWindow32(hwndBud))
    return FALSE;

  if(wndPtr->dwStyle & UDS_ARROWKEYS){
    FIXME(updown, "we need to subclass the buddy to process the arrow keys.\n");
  }

  /* do we need to do any adjustments? */
  if(!(wndPtr->dwStyle & (UDS_ALIGNLEFT | UDS_ALIGNRIGHT)))
    return TRUE;

  /* Get the rect of the buddy relative to its parent */
  GetWindowRect32(infoPtr->Buddy, &budRect);
  MapWindowPoints32(HWND_DESKTOP, GetParent32(infoPtr->Buddy),
		  (POINT32 *)(&budRect.left), 2);
	  
  /* now do the positioning */
  if(wndPtr->dwStyle & UDS_ALIGNRIGHT){
    budRect.right -= DEFAULT_WIDTH+DEFAULT_XSEP;
    x  = budRect.right+DEFAULT_XSEP;
  }
  else{ /* UDS_ALIGNLEFT */
    x  = budRect.left;
    budRect.left += DEFAULT_WIDTH+DEFAULT_XSEP;
  }

  /* first adjust the buddy to accomodate the up/down */
  SetWindowPos32(infoPtr->Buddy, 0, budRect.left, budRect.top,
	       budRect.right  - budRect.left, budRect.bottom - budRect.top, 
	       SWP_NOACTIVATE|SWP_NOZORDER);

  /* now position the up/down */
  /* Since the UDS_ALIGN* flags were used, */
  /* we will pick the position and size of the window. */
  SetWindowPos32(wndPtr->hwndSelf,0,x,budRect.top-DEFAULT_ADDTOP,DEFAULT_WIDTH,
		 (budRect.bottom-budRect.top)+DEFAULT_ADDTOP+DEFAULT_ADDBOT,
		 SWP_NOACTIVATE|SWP_NOZORDER); 

  return TRUE;
}	  

/***********************************************************************
 *           UPDOWN_DoAction
 *
 * This function increments/decrements the CurVal by the 
 * 'delta' amount according to the 'incr' flag
 * It notifies the parent as required.
 * It handles wraping and non-wraping correctly.
 * It is assumed that delta>0
 */
static void UPDOWN_DoAction(WND *wndPtr, int delta, BOOL32 incr)
{
  UPDOWN_INFO *infoPtr = UPDOWN_GetInfoPtr(wndPtr); 
  int old_val = infoPtr->CurVal;
  NM_UPDOWN ni;

  TRACE(updown, "%s by %d\n", incr ? "inc" : "dec", delta);

  /* check if we can do the modification first */
  delta *= (incr ? 1 : -1) * (infoPtr->MaxVal < infoPtr->MinVal ? -1 : 1);
  if(!UPDOWN_OffsetVal(wndPtr, delta))
    return;

  /* so, if we can do the change, recompute delta and restore old value */
  delta = infoPtr->CurVal - old_val;
  infoPtr->CurVal = old_val;

  /* We must notify parent now to obtain permission */
  ni.iPos = infoPtr->CurVal;
  ni.iDelta = delta;
  ni.hdr.hwndFrom = wndPtr->hwndSelf;
  ni.hdr.idFrom = wndPtr->wIDmenu;
  ni.hdr.code = UDN_DELTAPOS; 
  if(SendMessage32A(wndPtr->parent->hwndSelf, 
		    WM_NOTIFY, wndPtr->wIDmenu, (LPARAM)&ni))
    return; /* we are not allowed to change */
  
  /* Now adjust value with (maybe new) delta */
  if(!UPDOWN_OffsetVal(wndPtr, ni.iDelta))
    return;

  /* Now take care about our buddy */
  if(!IsWindow32(infoPtr->Buddy)) 
    return; /* Nothing else to do */


  if(wndPtr->dwStyle & UDS_SETBUDDYINT)
    UPDOWN_SetBuddyInt(wndPtr);

  /* Also, notify it */
  /* FIXME: do we need to send the notification only if
            we do not have the UDS_SETBUDDYINT style set? */
  SendMessage32A(infoPtr->Buddy, 
		 wndPtr->dwStyle & UDS_HORZ ? WM_HSCROLL : WM_VSCROLL, 
		 MAKELONG(incr ? SB_LINEUP : SB_LINEDOWN, infoPtr->CurVal),
		 wndPtr->hwndSelf);
}

/***********************************************************************
 *           UPDOWN_IsEnabled
 *
 * Returns TRUE if it is enabled as well as its buddy (if any)
 *         FALSE otherwise
 */
static BOOL32 UPDOWN_IsEnabled(WND *wndPtr)
{
  UPDOWN_INFO *infoPtr = UPDOWN_GetInfoPtr(wndPtr);

  if(wndPtr->dwStyle & WS_DISABLED)
    return FALSE;
  return IsWindowEnabled32(infoPtr->Buddy);
}

/***********************************************************************
 *           UPDOWN_CancelMode
 *
 * Deletes any timers, releases the mouse and does  redraw if necessary.
 * If the control is not in "capture" mode, it does nothing.
 * If the control was not in cancel mode, it returns FALSE. 
 * If the control was in cancel mode, it returns TRUE.
 */
static BOOL32 UPDOWN_CancelMode(WND *wndPtr)
{
  UPDOWN_INFO *infoPtr = UPDOWN_GetInfoPtr(wndPtr);
 
  /* if not in 'capture' mode, do nothing */
  if(!(infoPtr->Flags & FLAG_CLICKED))
    return FALSE;

  KillTimer32(wndPtr->hwndSelf, TIMERID1); /* kill all possible timers */
  KillTimer32(wndPtr->hwndSelf, TIMERID2);
  
  if(GetCapture32() == wndPtr->hwndSelf)   /* let the mouse go         */
    ReleaseCapture();          /* if we still have it      */  
  
  infoPtr->Flags = 0;          /* get rid of any flags     */
  UPDOWN_Paint(wndPtr);        /* redraw the control just in case */
  
  return TRUE;
}

/***********************************************************************
 *           UPDOWN_HandleMouseEvent
 *
 * Handle a mouse event for the updown.
 * 'pt' is the location of the mouse event in client or
 * windows coordinates. 
 */
static void UPDOWN_HandleMouseEvent(WND *wndPtr, UINT32 msg, POINT32 pt)
{
  UPDOWN_INFO *infoPtr = UPDOWN_GetInfoPtr(wndPtr);
  RECT32 rect;
  int temp;

  switch(msg)
    {
    case WM_LBUTTONDOWN:  /* Initialise mouse tracking */
      /* If we are already in the 'clicked' mode, then nothing to do */
      if(infoPtr->Flags & FLAG_CLICKED)
	return;

      /* If the buddy is an edit, will set focus to it */
      if(WIDGETS_IsControl32(WIN_FindWndPtr(infoPtr->Buddy), BIC32_EDIT))
	SetFocus32(infoPtr->Buddy);

      /* Now see which one is the 'active' arrow */
      temp = UPDOWN_GetArrowFromPoint(wndPtr, &rect, pt);

      /* Update the CurVal if necessary */
      if(wndPtr->dwStyle & UDS_SETBUDDYINT)
	UPDOWN_GetBuddyInt(wndPtr);
	
      /* Before we proceed, see if we can spin... */
      if(!(wndPtr->dwStyle & UDS_WRAP))
	if(( temp && infoPtr->CurVal==infoPtr->MaxVal) ||
	   (!temp && infoPtr->CurVal==infoPtr->MinVal))
	  return;

      /* Set up the correct flags */
      infoPtr->Flags  = 0; 
      infoPtr->Flags |= temp ? FLAG_INCR : FLAG_DECR;
      infoPtr->Flags |= FLAG_MOUSEIN;
      
      /* repaint the control */
      UPDOWN_Paint(wndPtr);

      /* process the click */
      UPDOWN_DoAction(wndPtr, 1, infoPtr->Flags & FLAG_INCR);

      /* now capture all mouse messages */
      SetCapture32(wndPtr->hwndSelf);

      /* and startup the first timer */
      SetTimer32(wndPtr->hwndSelf, TIMERID1, INITIAL_DELAY, 0); 
      break;

    case WM_MOUSEMOVE:
      /* If we are not in the 'clicked' mode, then nothing to do */
      if(!(infoPtr->Flags & FLAG_CLICKED))
	return;

      /* save the flags to see if any got modified */
      temp = infoPtr->Flags;

      /* Now get the 'active' arrow rectangle */
      if (infoPtr->Flags & FLAG_INCR)
	UPDOWN_GetArrowRect(wndPtr, &rect, TRUE);
      else
	UPDOWN_GetArrowRect(wndPtr, &rect, FALSE);

      /* Update the flags if we are in/out */
      if(PtInRect32(&rect, pt))
	infoPtr->Flags |=  FLAG_MOUSEIN;
      else{
	infoPtr->Flags &= ~FLAG_MOUSEIN;
	if(accelIndex != -1) /* if we have accel info */
	  accelIndex = 0;    /* reset it              */
      }
      /* If state changed, redraw the control */
      if(temp != infoPtr->Flags)
	UPDOWN_Paint(wndPtr);
      break;

      default:
	ERR(updown, "Impossible case!\n");
    }

}

/***********************************************************************
 *           UpDownWndProc
 */
LRESULT WINAPI UpDownWindowProc(HWND32 hwnd, UINT32 message, WPARAM32 wParam,
				LPARAM lParam)
{
  WND *wndPtr = WIN_FindWndPtr(hwnd);
  UPDOWN_INFO *infoPtr = UPDOWN_GetInfoPtr(wndPtr); 
  int temp;

  switch(message)
    {
    case WM_CREATE:
      /* get rid of border, if any */
      wndPtr->dwStyle &= ~WS_BORDER;

      /* initialize the info struct */
      infoPtr->AccelCount=0; infoPtr->AccelVect=0; 
      infoPtr->CurVal=0; infoPtr->MinVal=0; infoPtr->MaxVal=100; /*FIXME*/
      infoPtr->Base  = 10; /* Default to base 10  */
      infoPtr->Buddy = 0;  /* No buddy window yet */
      infoPtr->Flags = 0;  /* And no flags        */

      /* Do we pick the buddy win ourselves? */
      if(wndPtr->dwStyle & UDS_AUTOBUDDY)
	UPDOWN_SetBuddy(wndPtr, GetWindow32(wndPtr->hwndSelf, GW_HWNDPREV));
	
      TRACE(updown, "UpDown Ctrl creation, hwnd=%04x\n", hwnd);
      break;
    
    case WM_DESTROY:
      if(infoPtr->AccelVect)
	free(infoPtr->AccelVect);
      TRACE(updown, "UpDown Ctrl destruction, hwnd=%04x\n", hwnd);
      break;
	
    case WM_ENABLE:
      if(wndPtr->dwStyle & WS_DISABLED)
	UPDOWN_CancelMode(wndPtr);
      UPDOWN_Paint(wndPtr);
      break;

    case WM_TIMER:
      /* if initial timer, kill it and start the repeat timer */
      if(wParam == TIMERID1){
	KillTimer32(hwnd, TIMERID1);
	/* if no accel info given, used default timer */
	if(infoPtr->AccelCount==0 || infoPtr->AccelVect==0){
	  accelIndex = -1;
	  temp = REPEAT_DELAY;
	}
	else{
	  accelIndex = 0; /* otherwise, use it */
	  temp = infoPtr->AccelVect[accelIndex].nSec * 1000 + 1;
	}
	SetTimer32(hwnd, TIMERID2, temp, 0);
      }

      /* now, if the mouse is above us, do the thing...*/
      if(infoPtr->Flags & FLAG_MOUSEIN){
	temp = accelIndex==-1 ? 1 : infoPtr->AccelVect[accelIndex].nInc;
	UPDOWN_DoAction(wndPtr, temp, infoPtr->Flags & FLAG_INCR);
	
	if(accelIndex!=-1 && accelIndex < infoPtr->AccelCount-1){
	  KillTimer32(hwnd, TIMERID2);
	  accelIndex++; /* move to the next accel info */
	  temp = infoPtr->AccelVect[accelIndex].nSec * 1000 + 1;
	  /* make sure we have at least 1ms intervals */
	  SetTimer32(hwnd, TIMERID2, temp, 0);	    
	}
      }
      break;

    case WM_CANCELMODE:
      UPDOWN_CancelMode(wndPtr);
      break;

    case WM_LBUTTONUP:
      if(!UPDOWN_CancelMode(wndPtr))
	break;
      /*If we released the mouse and our buddy is an edit */
      /* we must select all text in it.                   */
      if(WIDGETS_IsControl32(WIN_FindWndPtr(infoPtr->Buddy), BIC32_EDIT))
	SendMessage32A(infoPtr->Buddy, EM_SETSEL32, 0, MAKELONG(0, -1));
      break;
      
    case WM_LBUTTONDOWN:
    case WM_MOUSEMOVE:
      if(UPDOWN_IsEnabled(wndPtr)){
	POINT32 pt;
	CONV_POINT16TO32( (POINT16 *)&lParam, &pt );
	UPDOWN_HandleMouseEvent( wndPtr, message, pt );
      }
    break;

    case WM_KEYDOWN:
      if((wndPtr->dwStyle & UDS_ARROWKEYS) && UPDOWN_IsEnabled(wndPtr)){
	switch(wParam){
	case VK_UP:  
	case VK_DOWN:
	  UPDOWN_GetBuddyInt(wndPtr);
	  UPDOWN_DoAction(wndPtr, 1, wParam==VK_UP);
	  break;
	}
      }
      break;
      
    case WM_PAINT:
      UPDOWN_Paint(wndPtr);
      break;
    
    case UDM_GETACCEL:
      if (wParam==0 && lParam==0)    /*if both zero, */
	return infoPtr->AccelCount;  /*just return the accel count*/
      if (wParam || lParam){
	UNKNOWN_PARAM(UDM_GETACCEL, wParam, lParam);
	return 0;
      }
      temp = MIN(infoPtr->AccelCount, wParam);
      memcpy((void *)lParam, infoPtr->AccelVect, temp*sizeof(UDACCEL));
      return temp;

    case UDM_SETACCEL:
      TRACE(updown, "UpDown Ctrl new accel info, hwnd=%04x\n", hwnd);
      if(infoPtr->AccelVect){
	free(infoPtr->AccelVect);
	infoPtr->AccelCount = 0;
	infoPtr->AccelVect  = 0;
      }
      if(wParam==0)
	return TRUE;
      infoPtr->AccelVect = malloc(wParam*sizeof(UDACCEL));
      if(infoPtr->AccelVect==0)
	return FALSE;
      memcpy(infoPtr->AccelVect, (void*)lParam, wParam*sizeof(UDACCEL));
      return TRUE;

    case UDM_GETBASE:
      if (wParam || lParam)
	UNKNOWN_PARAM(UDM_GETBASE, wParam, lParam);
      return infoPtr->Base;

    case UDM_SETBASE:
      TRACE(updown, "UpDown Ctrl new base(%d), hwnd=%04x\n", 
		     wParam, hwnd);
      if ( !(wParam==10 || wParam==16) || lParam)
	UNKNOWN_PARAM(UDM_SETBASE, wParam, lParam);
      if (wParam==10 || wParam==16){
	temp = infoPtr->Base;
	infoPtr->Base = wParam;
	return temp;       /* return the prev base */
      }
      break;

    case UDM_GETBUDDY:
      if (wParam || lParam)
	UNKNOWN_PARAM(UDM_GETBUDDY, wParam, lParam);
      return infoPtr->Buddy;

    case UDM_SETBUDDY:
      if (lParam)
	UNKNOWN_PARAM(UDM_SETBUDDY, wParam, lParam);
      temp = infoPtr->Buddy;
      infoPtr->Buddy = wParam;
      UPDOWN_SetBuddy(wndPtr, wParam);
      TRACE(updown, "UpDown Ctrl new buddy(%04x), hwnd=%04x\n", 
		     infoPtr->Buddy, hwnd);
      return temp;

    case UDM_GETPOS:
      if (wParam || lParam)
	UNKNOWN_PARAM(UDM_GETPOS, wParam, lParam);
      temp = UPDOWN_GetBuddyInt(wndPtr);
      return MAKELONG(infoPtr->CurVal, temp ? 0 : 1);

    case UDM_SETPOS:
      if (wParam || HIWORD(lParam))
	UNKNOWN_PARAM(UDM_GETPOS, wParam, lParam);
      temp = SLOWORD(lParam);
      TRACE(updown, "UpDown Ctrl new value(%d), hwnd=%04x\n",
		     temp, hwnd);
      if(!UPDOWN_InBounds(wndPtr, temp)){
	if(temp < infoPtr->MinVal)  
	  temp = infoPtr->MinVal;
	if(temp > infoPtr->MaxVal)
	  temp = infoPtr->MaxVal;
      }
      wParam = infoPtr->CurVal; /* save prev value   */
      infoPtr->CurVal = temp;   /* set the new value */
      if(wndPtr->dwStyle & UDS_SETBUDDYINT)
	UPDOWN_SetBuddyInt(wndPtr);
      return wParam;            /* return prev value */
      
    case UDM_GETRANGE:
      if (wParam || lParam)
	UNKNOWN_PARAM(UDM_GETRANGE, wParam, lParam);
      return MAKELONG(infoPtr->MaxVal, infoPtr->MinVal);

    case UDM_SETRANGE:
      if (wParam)
	UNKNOWN_PARAM(UDM_SETRANGE, wParam, lParam); /* we must have:     */
      infoPtr->MaxVal = SLOWORD(lParam); /* UD_MINVAL <= Max <= UD_MAXVAL */
      infoPtr->MinVal = SHIWORD(lParam); /* UD_MINVAL <= Min <= UD_MAXVAL */
                                         /* |Max-Min| <= UD_MAXVAL        */
      TRACE(updown, "UpDown Ctrl new range(%d to %d), hwnd=%04x\n", 
		     infoPtr->MinVal, infoPtr->MaxVal, hwnd);
      break;                             

    case UDM_GETRANGE32:
      if (wParam)
	*(LPINT32)wParam = infoPtr->MinVal;
      if (lParam)
	*(LPINT32)lParam = infoPtr->MaxVal;
      break;

    case UDM_SETRANGE32:
      infoPtr->MinVal = (INT32)wParam;
      infoPtr->MaxVal = (INT32)lParam;
      if (infoPtr->MaxVal <= infoPtr->MinVal)
	infoPtr->MaxVal = infoPtr->MinVal + 1;
      TRACE(updown, "UpDown Ctrl new range(%d to %d), hwnd=%04x\n", 
		     infoPtr->MinVal, infoPtr->MaxVal, hwnd);
      break;

    default: 
      if (message >= WM_USER) 
	WARN(updown, "unknown msg %04x wp=%04x lp=%08lx\n", 
		     message, wParam, lParam );
      return DefWindowProc32A( hwnd, message, wParam, lParam ); 
    } 

    return 0;
}

/***********************************************************************
 *           UPDOWN_Register [Internal]
 *
 * Registers the updown window class.
 */
void UPDOWN_Register(void)
{
    WNDCLASS32A wndClass;

    if( GlobalFindAtom32A( UPDOWN_CLASS32A ) ) return;

    ZeroMemory( &wndClass, sizeof( WNDCLASS32A ) );
    wndClass.style         = CS_GLOBALCLASS | CS_DBLCLKS | CS_VREDRAW;
    wndClass.lpfnWndProc   = (WNDPROC32)UpDownWindowProc;
    wndClass.cbClsExtra    = 0;
    wndClass.cbWndExtra    = sizeof(UPDOWN_INFO);
    wndClass.hCursor       = LoadCursor32A( 0, IDC_ARROW32A );
    wndClass.hbrBackground = (HBRUSH32)(COLOR_3DFACE + 1);
    wndClass.lpszClassName = UPDOWN_CLASS32A;
 
    RegisterClass32A( &wndClass );
}

