/*
 * Date and time picker control
 *
 * Copyright 1998, 1999 Eric Kohl
 * Copyright 1999, 2000 Alex Priem <alexp@sci.kun.nl>
 * Copyright 2000 Chris Morgan <cmorgan@wpi.edu>
 *
 * 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 Oct. 20, 2004, 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:
 *    -- DTS_APPCANPARSE
 *    -- DTS_SHORTDATECENTURYFORMAT
 *    -- DTN_FORMAT
 *    -- DTN_FORMATQUERY
 *    -- DTN_USERSTRING
 *    -- DTN_WMKEYDOWN
 *    -- FORMATCALLBACK
 */

#include <math.h>
#include <string.h>
#include <stdarg.h>
#include <stdio.h>
#include <limits.h>

#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "winuser.h"
#include "winnls.h"
#include "commctrl.h"
#include "comctl32.h"
#include "wine/debug.h"
#include "wine/unicode.h"

WINE_DEFAULT_DEBUG_CHANNEL(datetime);

typedef struct
{
    HWND hwndSelf;
    HWND hMonthCal;
    HWND hwndNotify;
    HWND hUpdown;
    DWORD dwStyle;
    SYSTEMTIME date;
    BOOL dateValid;
    HWND hwndCheckbut;
    RECT rcClient; /* rect around the edge of the window */
    RECT rcDraw; /* rect inside of the border */
    RECT checkbox;  /* checkbox allowing the control to be enabled/disabled */
    RECT calbutton; /* button that toggles the dropdown of the monthcal control */
    BOOL bCalDepressed; /* TRUE = cal button is depressed */
    int  bDropdownEnabled;
    int  select;
    HFONT hFont;
    int nrFieldsAllocated;
    int nrFields;
    int haveFocus;
    int *fieldspec;
    RECT *fieldRect;
    int  *buflen;
    WCHAR textbuf[256];
    POINT monthcal_pos;
    int pendingUpdown;
} DATETIME_INFO, *LPDATETIME_INFO;

/* in monthcal.c */
extern int MONTHCAL_MonthLength(int month, int year);
extern int MONTHCAL_CalculateDayOfWeek(SYSTEMTIME *date, BOOL inplace);

/* this list of defines is closely related to `allowedformatchars' defined
 * in datetime.c; the high nibble indicates the `base type' of the format
 * specifier.
 * Do not change without first reading DATETIME_UseFormat.
 *
 */

#define DT_END_FORMAT      0
#define ONEDIGITDAY   	0x01
#define TWODIGITDAY   	0x02
#define THREECHARDAY  	0x03
#define FULLDAY         0x04
#define ONEDIGIT12HOUR  0x11
#define TWODIGIT12HOUR  0x12
#define ONEDIGIT24HOUR  0x21
#define TWODIGIT24HOUR  0x22
#define ONEDIGITMINUTE  0x31
#define TWODIGITMINUTE  0x32
#define ONEDIGITMONTH   0x41
#define TWODIGITMONTH   0x42
#define THREECHARMONTH  0x43
#define FULLMONTH       0x44
#define ONEDIGITSECOND  0x51
#define TWODIGITSECOND  0x52
#define ONELETTERAMPM   0x61
#define TWOLETTERAMPM   0x62
#define ONEDIGITYEAR    0x71
#define TWODIGITYEAR    0x72
#define INVALIDFULLYEAR 0x73      /* FIXME - yyy is not valid - we'll treat it as yyyy */
#define FULLYEAR        0x74
#define FORMATCALLBACK  0x81      /* -> maximum of 0x80 callbacks possible */
#define FORMATCALLMASK  0x80
#define DT_STRING 	0x0100

#define DTHT_DATEFIELD  0xff      /* for hit-testing */

#define DTHT_NONE       0x1000
#define DTHT_CHECKBOX   0x2000  /* these should end at '00' , to make */
#define DTHT_MCPOPUP    0x3000  /* & DTHT_DATEFIELD 0 when DATETIME_KeyDown */
#define DTHT_GOTFOCUS   0x4000  /* tests for date-fields */
#define DTHT_NODATEMASK 0xf000  /* to mask check and drop down from others */

static BOOL DATETIME_SendSimpleNotify (const DATETIME_INFO *infoPtr, UINT code);
static BOOL DATETIME_SendDateTimeChangeNotify (const DATETIME_INFO *infoPtr);
extern void MONTHCAL_CopyTime(const SYSTEMTIME *from, SYSTEMTIME *to);
static const WCHAR allowedformatchars[] = {'d', 'h', 'H', 'm', 'M', 's', 't', 'y', 'X', 0};
static const int maxrepetition [] = {4,2,2,2,4,2,2,4,-1};


static DWORD
DATETIME_GetSystemTime (const DATETIME_INFO *infoPtr, SYSTEMTIME *systime)
{
    if (!systime) return GDT_NONE;

    if ((infoPtr->dwStyle & DTS_SHOWNONE) &&
        (SendMessageW (infoPtr->hwndCheckbut, BM_GETCHECK, 0, 0) == BST_UNCHECKED))
        return GDT_NONE;

    *systime = infoPtr->date;

    return GDT_VALID;
}


static BOOL
DATETIME_SetSystemTime (DATETIME_INFO *infoPtr, DWORD flag, const SYSTEMTIME *systime)
{
    if (!systime) return 0;

    TRACE("%04d/%02d/%02d %02d:%02d:%02d\n",
          systime->wYear, systime->wMonth, systime->wDay,
          systime->wHour, systime->wMinute, systime->wSecond);

    if (flag == GDT_VALID) {
      if (systime->wYear < 1601 || systime->wYear > 30827 ||
          systime->wMonth < 1 || systime->wMonth > 12 ||
          systime->wDay < 1 || systime->wDay > 31 ||
          systime->wHour > 23 ||
          systime->wMinute > 59 ||
          systime->wSecond > 59 ||
          systime->wMilliseconds > 999
          )
        return FALSE;

        infoPtr->dateValid = TRUE;
        infoPtr->date = *systime;
        /* always store a valid day of week */
        MONTHCAL_CalculateDayOfWeek(&infoPtr->date, TRUE);

        SendMessageW (infoPtr->hMonthCal, MCM_SETCURSEL, 0, (LPARAM)(&infoPtr->date));
        SendMessageW (infoPtr->hwndCheckbut, BM_SETCHECK, BST_CHECKED, 0);
    } else if ((infoPtr->dwStyle & DTS_SHOWNONE) && (flag == GDT_NONE)) {
        infoPtr->dateValid = FALSE;
        SendMessageW (infoPtr->hwndCheckbut, BM_SETCHECK, BST_UNCHECKED, 0);
    }
    else
        return FALSE;

    InvalidateRect(infoPtr->hwndSelf, NULL, TRUE);
    return TRUE;
}


/***
 * Split up a formattxt in actions.
 * See ms documentation for the meaning of the letter codes/'specifiers'.
 *
 * Notes:
 * *'dddddd' is handled as 'dddd' plus 'dd'.
 * *unrecognized formats are strings (here given the type DT_STRING;
 * start of the string is encoded in lower bits of DT_STRING.
 * Therefore, 'string' ends finally up as '<show seconds>tring'.
 *
 */
static void
DATETIME_UseFormat (DATETIME_INFO *infoPtr, LPCWSTR formattxt)
{
    unsigned int i;
    int j, k, len;
    BOOL inside_literal = FALSE; /* inside '...' */
    int *nrFields = &infoPtr->nrFields;

    *nrFields = 0;
    infoPtr->fieldspec[*nrFields] = 0;
    len = strlenW(allowedformatchars);
    k = 0;

    for (i = 0; formattxt[i]; i++)  {
	TRACE ("\n%d %c:", i, formattxt[i]);
	if (!inside_literal) {
	    for (j = 0; j < len; j++) {
	        if (allowedformatchars[j]==formattxt[i]) {
                    TRACE ("%c[%d,%x]", allowedformatchars[j], *nrFields, infoPtr->fieldspec[*nrFields]);
                    if ((*nrFields==0) && (infoPtr->fieldspec[*nrFields]==0)) {
                        infoPtr->fieldspec[*nrFields] = (j<<4) + 1;
                        break;
                    }
                    if (infoPtr->fieldspec[*nrFields] >> 4 != j) {
                        (*nrFields)++;
                        infoPtr->fieldspec[*nrFields] = (j<<4) + 1;
                        break;
                    }
                    if ((infoPtr->fieldspec[*nrFields] & 0x0f) == maxrepetition[j]) {
                        (*nrFields)++;
                        infoPtr->fieldspec[*nrFields] = (j<<4) + 1;
                        break;
		    }
                    infoPtr->fieldspec[*nrFields]++;
                    break;
                }   /* if allowedformatchar */
            } /* for j */
        }
        else
            j = len;

        if (formattxt[i] == '\'')
        {
            inside_literal = !inside_literal;
            continue;
        }

	/* char is not a specifier: handle char like a string */
	if (j == len) {
	    if ((*nrFields==0) && (infoPtr->fieldspec[*nrFields]==0)) {
		infoPtr->fieldspec[*nrFields] = DT_STRING + k;
		infoPtr->buflen[*nrFields] = 0;
            } else if ((infoPtr->fieldspec[*nrFields] & DT_STRING) != DT_STRING)  {
		(*nrFields)++;
		infoPtr->fieldspec[*nrFields] = DT_STRING + k;
		infoPtr->buflen[*nrFields] = 0;
	    }
	    infoPtr->textbuf[k] = formattxt[i];
	    k++;
	    infoPtr->buflen[*nrFields]++;
	}   /* if j=len */

	if (*nrFields == infoPtr->nrFieldsAllocated) {
	    FIXME ("out of memory; should reallocate. crash ahead.\n");
	}
    } /* for i */

    TRACE("\n");

    if (infoPtr->fieldspec[*nrFields] != 0) (*nrFields)++;
}


static BOOL
DATETIME_SetFormatW (DATETIME_INFO *infoPtr, LPCWSTR lpszFormat)
{
    if (!lpszFormat) {
	WCHAR format_buf[80];
	DWORD format_item;

	if (infoPtr->dwStyle & DTS_LONGDATEFORMAT)
	    format_item = LOCALE_SLONGDATE;
	else if ((infoPtr->dwStyle & DTS_TIMEFORMAT) == DTS_TIMEFORMAT)
	    format_item = LOCALE_STIMEFORMAT;
        else /* DTS_SHORTDATEFORMAT */
	    format_item = LOCALE_SSHORTDATE;
	GetLocaleInfoW( GetSystemDefaultLCID(), format_item, format_buf, sizeof(format_buf)/sizeof(format_buf[0]));
	lpszFormat = format_buf;
    }

    DATETIME_UseFormat (infoPtr, lpszFormat);
    InvalidateRect (infoPtr->hwndSelf, NULL, TRUE);

    return 1;
}


static BOOL
DATETIME_SetFormatA (DATETIME_INFO *infoPtr, LPCSTR lpszFormat)
{
    if (lpszFormat) {
	BOOL retval;
	INT len = MultiByteToWideChar(CP_ACP, 0, lpszFormat, -1, NULL, 0);
	LPWSTR wstr = Alloc(len * sizeof(WCHAR));
	if (wstr) MultiByteToWideChar(CP_ACP, 0, lpszFormat, -1, wstr, len);
	retval = DATETIME_SetFormatW (infoPtr, wstr);
	Free (wstr);
	return retval;
    }
    else
	return DATETIME_SetFormatW (infoPtr, 0);

}


static void
DATETIME_ReturnTxt (const DATETIME_INFO *infoPtr, int count, LPWSTR result, int resultSize)
{
    static const WCHAR fmt_dW[] = { '%', 'd', 0 };
    static const WCHAR fmt__2dW[] = { '%', '.', '2', 'd', 0 };
    static const WCHAR fmt__3sW[] = { '%', '.', '3', 's', 0 };
    SYSTEMTIME date = infoPtr->date;
    int spec;
    WCHAR buffer[80];

    *result=0;
    TRACE ("%d,%d\n", infoPtr->nrFields, count);
    if (count>infoPtr->nrFields || count < 0) {
	WARN ("buffer overrun, have %d want %d\n", infoPtr->nrFields, count);
	return;
    }

    if (!infoPtr->fieldspec) return;

    spec = infoPtr->fieldspec[count];
    if (spec & DT_STRING) {
	int txtlen = infoPtr->buflen[count];

        if (txtlen > resultSize)
            txtlen = resultSize - 1;
	memcpy (result, infoPtr->textbuf + (spec &~ DT_STRING), txtlen * sizeof(WCHAR));
	result[txtlen] = 0;
	TRACE ("arg%d=%x->[%s]\n", count, infoPtr->fieldspec[count], debugstr_w(result));
	return;
    }


    switch (spec) {
	case DT_END_FORMAT:
	    *result = 0;
	    break;
	case ONEDIGITDAY:
	    wsprintfW (result, fmt_dW, date.wDay);
	    break;
	case TWODIGITDAY:
	    wsprintfW (result, fmt__2dW, date.wDay);
	    break;
	case THREECHARDAY:
	    GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SABBREVDAYNAME1+(date.wDayOfWeek+6)%7, result, 4);
	    /*wsprintfW (result,"%.3s",days[date.wDayOfWeek]);*/
	    break;
	case FULLDAY:
	    GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SDAYNAME1+(date.wDayOfWeek+6)%7, result, resultSize);
	    break;
	case ONEDIGIT12HOUR:
	    if (date.wHour == 0) {
	        result[0] = '1';
	        result[1] = '2';
	        result[2] = 0;
	    }
	    else
	        wsprintfW (result, fmt_dW, date.wHour - (date.wHour > 12 ? 12 : 0));
	    break;
	case TWODIGIT12HOUR:
	    if (date.wHour == 0) {
	        result[0] = '1';
	        result[1] = '2';
	        result[2] = 0;
	    }
	    else
	        wsprintfW (result, fmt__2dW, date.wHour - (date.wHour > 12 ? 12 : 0));
	    break;
	case ONEDIGIT24HOUR:
	    wsprintfW (result, fmt_dW, date.wHour);
	    break;
	case TWODIGIT24HOUR:
	    wsprintfW (result, fmt__2dW, date.wHour);
	    break;
	case ONEDIGITSECOND:
	    wsprintfW (result, fmt_dW, date.wSecond);
	    break;
	case TWODIGITSECOND:
	    wsprintfW (result, fmt__2dW, date.wSecond);
	    break;
	case ONEDIGITMINUTE:
	    wsprintfW (result, fmt_dW, date.wMinute);
	    break;
	case TWODIGITMINUTE:
	    wsprintfW (result, fmt__2dW, date.wMinute);
	    break;
	case ONEDIGITMONTH:
	    wsprintfW (result, fmt_dW, date.wMonth);
	    break;
	case TWODIGITMONTH:
	    wsprintfW (result, fmt__2dW, date.wMonth);
	    break;
	case THREECHARMONTH:
	    GetLocaleInfoW(GetSystemDefaultLCID(), LOCALE_SMONTHNAME1+date.wMonth -1, 
			   buffer, sizeof(buffer)/sizeof(buffer[0]));
	    wsprintfW (result, fmt__3sW, buffer);
	    break;
	case FULLMONTH:
	    GetLocaleInfoW(GetSystemDefaultLCID(),LOCALE_SMONTHNAME1+date.wMonth -1,
                           result, resultSize);
	    break;
	case ONELETTERAMPM:
	    result[0] = (date.wHour < 12 ? 'A' : 'P');
	    result[1] = 0;
	    break;
	case TWOLETTERAMPM:
	    result[0] = (date.wHour < 12 ? 'A' : 'P');
	    result[1] = 'M';
	    result[2] = 0;
	    break;
	case FORMATCALLBACK:
	    FIXME ("Not implemented\n");
	    result[0] = 'x';
	    result[1] = 0;
	    break;
	case ONEDIGITYEAR:
	    wsprintfW (result, fmt_dW, date.wYear-10* (int) floor(date.wYear/10));
	    break;
	case TWODIGITYEAR:
	    wsprintfW (result, fmt__2dW, date.wYear-100* (int) floor(date.wYear/100));
	    break;
        case INVALIDFULLYEAR:
	case FULLYEAR:
	    wsprintfW (result, fmt_dW, date.wYear);
	    break;
    }

    TRACE ("arg%d=%x->[%s]\n", count, infoPtr->fieldspec[count], debugstr_w(result));
}

static int wrap(int val, int delta, int minVal, int maxVal)
{
    val += delta;
    if (delta == INT_MIN || val < minVal) return maxVal;
    if (delta == INT_MAX || val > maxVal) return minVal;
    return val;
}

static void
DATETIME_IncreaseField (DATETIME_INFO *infoPtr, int number, int delta)
{
    SYSTEMTIME *date = &infoPtr->date;

    TRACE ("%d\n", number);
    if ((number > infoPtr->nrFields) || (number < 0)) return;

    if ((infoPtr->fieldspec[number] & DTHT_DATEFIELD) == 0) return;

    switch (infoPtr->fieldspec[number]) {
	case ONEDIGITYEAR:
	case TWODIGITYEAR:
	case FULLYEAR:
	    date->wYear = wrap(date->wYear, delta, 1752, 9999);
	    MONTHCAL_CalculateDayOfWeek(date, TRUE);
	    break;
	case ONEDIGITMONTH:
	case TWODIGITMONTH:
	case THREECHARMONTH:
	case FULLMONTH:
	    date->wMonth = wrap(date->wMonth, delta, 1, 12);
	    MONTHCAL_CalculateDayOfWeek(date, TRUE);
	    delta = 0;
	    /* fall through */
	case ONEDIGITDAY:
	case TWODIGITDAY:
	case THREECHARDAY:
	case FULLDAY:
	    date->wDay = wrap(date->wDay, delta, 1, MONTHCAL_MonthLength(date->wMonth, date->wYear));
	    MONTHCAL_CalculateDayOfWeek(date, TRUE);
	    break;
	case ONELETTERAMPM:
	case TWOLETTERAMPM:
	    delta *= 12;
	    /* fall through */
	case ONEDIGIT12HOUR:
	case TWODIGIT12HOUR:
	case ONEDIGIT24HOUR:
	case TWODIGIT24HOUR:
	    date->wHour = wrap(date->wHour, delta, 0, 23);
	    break;
	case ONEDIGITMINUTE:
	case TWODIGITMINUTE:
	    date->wMinute = wrap(date->wMinute, delta, 0, 59);
	    break;
	case ONEDIGITSECOND:
	case TWODIGITSECOND:
	    date->wSecond = wrap(date->wSecond, delta, 0, 59);
	    break;
	case FORMATCALLBACK:
	    FIXME ("Not implemented\n");
	    break;
    }

    /* FYI: On 1752/9/14 the calendar changed and England and the
     * American colonies changed to the Gregorian calendar. This change
     * involved having September 14th follow September 2nd. So no date
     * algorithm works before that date.
     */
    if (10000 * date->wYear + 100 * date->wMonth + date->wDay < 17520914) {
	date->wYear = 1752;
    	date->wMonth = 9;
	date->wDay = 14;
	date->wSecond = 0;
	date->wMinute = 0;
	date->wHour = 0;
    }
}


static void
DATETIME_ReturnFieldWidth (const DATETIME_INFO *infoPtr, HDC hdc, int count, SHORT *width)
{
    /* fields are a fixed width, determined by the largest possible string */
    /* presumably, these widths should be language dependent */
    static const WCHAR fld_d1W[] = { '2', 0 };
    static const WCHAR fld_d2W[] = { '2', '2', 0 };
    static const WCHAR fld_d4W[] = { '2', '2', '2', '2', 0 };
    static const WCHAR fld_am1[] = { 'A', 0 };
    static const WCHAR fld_am2[] = { 'A', 'M', 0 };
    int spec;
    WCHAR buffer[80];
    LPCWSTR bufptr;
    SIZE size;

    TRACE ("%d,%d\n", infoPtr->nrFields, count);
    if (count>infoPtr->nrFields || count < 0) {
	WARN ("buffer overrun, have %d want %d\n", infoPtr->nrFields, count);
	return;
    }

    if (!infoPtr->fieldspec) return;

    spec = infoPtr->fieldspec[count];
    if (spec & DT_STRING) {
	int txtlen = infoPtr->buflen[count];

        if (txtlen > 79)
            txtlen = 79;
	memcpy (buffer, infoPtr->textbuf + (spec &~ DT_STRING), txtlen * sizeof(WCHAR));
	buffer[txtlen] = 0;
	bufptr = buffer;
    }
    else {
        switch (spec) {
	    case ONEDIGITDAY:
	    case ONEDIGIT12HOUR:
	    case ONEDIGIT24HOUR:
	    case ONEDIGITSECOND:
	    case ONEDIGITMINUTE:
	    case ONEDIGITMONTH:
	    case ONEDIGITYEAR:
	        /* these seem to use a two byte field */
	    case TWODIGITDAY:
	    case TWODIGIT12HOUR:
	    case TWODIGIT24HOUR:
	    case TWODIGITSECOND:
	    case TWODIGITMINUTE:
	    case TWODIGITMONTH:
	    case TWODIGITYEAR:
	        bufptr = fld_d2W;
	        break;
            case INVALIDFULLYEAR:
	    case FULLYEAR:
	        bufptr = fld_d4W;
	        break;
	    case THREECHARMONTH:
	    case FULLMONTH:
	    case THREECHARDAY:
	    case FULLDAY:
	    {
		static const WCHAR fld_day[] = {'W','e','d','n','e','s','d','a','y',0};
		static const WCHAR fld_abbrday[] = {'W','e','d',0};
		static const WCHAR fld_mon[] = {'S','e','p','t','e','m','b','e','r',0};
		static const WCHAR fld_abbrmon[] = {'D','e','c',0};

		const WCHAR *fall;
		LCTYPE lctype;
		INT i, max_count;
		LONG cx;

		/* choose locale data type and fallback string */
		switch (spec) {
		case THREECHARDAY:
		    fall   = fld_abbrday;
		    lctype = LOCALE_SABBREVDAYNAME1;
		    max_count = 7;
		    break;
		case FULLDAY:
		    fall   = fld_day;
		    lctype = LOCALE_SDAYNAME1;
		    max_count = 7;
		    break;
		case THREECHARMONTH:
		    fall   = fld_abbrmon;
		    lctype = LOCALE_SABBREVMONTHNAME1;
		    max_count = 12;
		    break;
		case FULLMONTH:
		    fall   = fld_mon;
		    lctype = LOCALE_SMONTHNAME1;
		    max_count = 12;
		    break;
		}

		cx = 0;
		for (i = 0; i < max_count; i++)
		{
		    if(GetLocaleInfoW(LOCALE_USER_DEFAULT, lctype + i,
			buffer, lstrlenW(buffer)))
		    {
			GetTextExtentPoint32W(hdc, buffer, lstrlenW(buffer), &size);
			if (size.cx > cx) cx = size.cx;
		    }
		    else /* locale independent fallback on failure */
		    {
		        GetTextExtentPoint32W(hdc, fall, lstrlenW(fall), &size);
			cx = size.cx;
		        break;
		    }
		}
		*width = cx;
		return;
	    }
	    case ONELETTERAMPM:
	        bufptr = fld_am1;
	        break;
	    case TWOLETTERAMPM:
	        bufptr = fld_am2;
	        break;
	    default:
	        bufptr = fld_d1W;
	        break;
        }
    }
    GetTextExtentPoint32W (hdc, bufptr, strlenW(bufptr), &size);
    *width = size.cx;
}

static void 
DATETIME_Refresh (DATETIME_INFO *infoPtr, HDC hdc)
{
    TRACE("\n");

    if (infoPtr->dateValid) {
        int i, prevright;
        RECT *field;
        RECT *rcDraw = &infoPtr->rcDraw;
        SIZE size;
        COLORREF oldTextColor;
        SHORT fieldWidth = 0;
        HFONT oldFont = SelectObject (hdc, infoPtr->hFont);
        INT oldBkMode = SetBkMode (hdc, TRANSPARENT);
        WCHAR txt[80];

        DATETIME_ReturnTxt (infoPtr, 0, txt, sizeof(txt)/sizeof(txt[0]));
        GetTextExtentPoint32W (hdc, txt, strlenW(txt), &size);
        rcDraw->bottom = size.cy + 2;

        prevright = infoPtr->checkbox.right = ((infoPtr->dwStyle & DTS_SHOWNONE) ? 18 : 2);

        for (i = 0; i < infoPtr->nrFields; i++) {
            DATETIME_ReturnTxt (infoPtr, i, txt, sizeof(txt)/sizeof(txt[0]));
            GetTextExtentPoint32W (hdc, txt, strlenW(txt), &size);
            DATETIME_ReturnFieldWidth (infoPtr, hdc, i, &fieldWidth);
            field = &infoPtr->fieldRect[i];
            field->left   = prevright;
            field->right  = prevright + fieldWidth;
            field->top    = rcDraw->top;
            field->bottom = rcDraw->bottom;
            prevright = field->right;

            if (infoPtr->dwStyle & WS_DISABLED)
                oldTextColor = SetTextColor (hdc, comctl32_color.clrGrayText);
            else if ((infoPtr->haveFocus) && (i == infoPtr->select)) {
                RECT selection;

                /* fill if focused */
                HBRUSH hbr = CreateSolidBrush (comctl32_color.clrActiveCaption);

                selection.left   = 0;
                selection.top    = 0;
                selection.right  = size.cx;
                selection.bottom = size.cy;
                /* center rectangle */
                OffsetRect(&selection, (field->right  + field->left - size.cx)/2,
                                       (field->bottom - size.cy)/2);

                FillRect(hdc, &selection, hbr);
                DeleteObject (hbr);
                oldTextColor = SetTextColor (hdc, comctl32_color.clrWindow);
            }
            else
                oldTextColor = SetTextColor (hdc, comctl32_color.clrWindowText);

            /* draw the date text using the colour set above */
            DrawTextW (hdc, txt, strlenW(txt), field, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
            SetTextColor (hdc, oldTextColor);
        }
        SetBkMode (hdc, oldBkMode);
        SelectObject (hdc, oldFont);
    }

    if (!(infoPtr->dwStyle & DTS_UPDOWN)) {
        DrawFrameControl(hdc, &infoPtr->calbutton, DFC_SCROLL,
                         DFCS_SCROLLDOWN | (infoPtr->bCalDepressed ? DFCS_PUSHED : 0) |
                         (infoPtr->dwStyle & WS_DISABLED ? DFCS_INACTIVE : 0) );
    }
}


static INT
DATETIME_HitTest (const DATETIME_INFO *infoPtr, POINT pt)
{
    int i;

    TRACE ("%d, %d\n", pt.x, pt.y);

    if (PtInRect (&infoPtr->calbutton, pt)) return DTHT_MCPOPUP;
    if (PtInRect (&infoPtr->checkbox, pt)) return DTHT_CHECKBOX;

    for (i = 0; i < infoPtr->nrFields; i++) {
        if (PtInRect (&infoPtr->fieldRect[i], pt)) return i;
    }

    return DTHT_NONE;
}

/* Returns index of a closest date field from given counting to left
   or -1 if there's no such fields at left */
static int DATETIME_GetPrevDateField(const DATETIME_INFO *infoPtr, int i)
{
    for(--i; i >= 0; i--)
    {
        if (infoPtr->fieldspec[i] & DTHT_DATEFIELD) return i;
    }
    return -1;
}

static LRESULT
DATETIME_LButtonDown (DATETIME_INFO *infoPtr, INT x, INT y)
{
    POINT pt;
    int old, new;

    pt.x = x;
    pt.y = y;
    old = infoPtr->select;
    new = DATETIME_HitTest (infoPtr, pt);

    SetFocus(infoPtr->hwndSelf);

    if (!(new & DTHT_NODATEMASK) || (new == DTHT_NONE))
    {
        if (new == DTHT_NONE)
            new = infoPtr->nrFields - 1;
        else
        {
            /* hitting string part moves selection to next date field to left */
            if (infoPtr->fieldspec[new] & DT_STRING)
            {
                new = DATETIME_GetPrevDateField(infoPtr, new);
                if (new == -1) return 0;
            }
            /* never select full day of week */
            if (infoPtr->fieldspec[new] == FULLDAY) return 0;
        }
    }
    infoPtr->select = new;

    if (infoPtr->select == DTHT_MCPOPUP) {
        RECT rcMonthCal;
        SendMessageW(infoPtr->hMonthCal, MCM_GETMINREQRECT, 0, (LPARAM)&rcMonthCal);

        /* FIXME: button actually is only depressed during dropdown of the */
        /* calendar control and when the mouse is over the button window */
        infoPtr->bCalDepressed = TRUE;

        /* recalculate the position of the monthcal popup */
        if(infoPtr->dwStyle & DTS_RIGHTALIGN)
            infoPtr->monthcal_pos.x = infoPtr->calbutton.left - 
                (rcMonthCal.right - rcMonthCal.left);
        else
            /* FIXME: this should be after the area reserved for the checkbox */
            infoPtr->monthcal_pos.x = infoPtr->rcDraw.left;

        infoPtr->monthcal_pos.y = infoPtr->rcClient.bottom;
        ClientToScreen (infoPtr->hwndSelf, &(infoPtr->monthcal_pos));
        SetWindowPos(infoPtr->hMonthCal, 0, infoPtr->monthcal_pos.x,
            infoPtr->monthcal_pos.y, rcMonthCal.right - rcMonthCal.left,
            rcMonthCal.bottom - rcMonthCal.top, 0);

        if(IsWindowVisible(infoPtr->hMonthCal)) {
            ShowWindow(infoPtr->hMonthCal, SW_HIDE);
            infoPtr->bDropdownEnabled = FALSE;
            DATETIME_SendSimpleNotify (infoPtr, DTN_CLOSEUP);
        } else {
            const SYSTEMTIME *lprgSysTimeArray = &infoPtr->date;
            TRACE("update calendar %04d/%02d/%02d\n", 
            lprgSysTimeArray->wYear, lprgSysTimeArray->wMonth, lprgSysTimeArray->wDay);
            SendMessageW(infoPtr->hMonthCal, MCM_SETCURSEL, 0, (LPARAM)(&infoPtr->date));

            if (infoPtr->bDropdownEnabled) {
                ShowWindow(infoPtr->hMonthCal, SW_SHOW);
                DATETIME_SendSimpleNotify (infoPtr, DTN_DROPDOWN);
            }
            infoPtr->bDropdownEnabled = TRUE;
        }

        TRACE ("dt:%p mc:%p mc parent:%p, desktop:%p\n",
               infoPtr->hwndSelf, infoPtr->hMonthCal, infoPtr->hwndNotify, GetDesktopWindow ());
    }

    InvalidateRect(infoPtr->hwndSelf, NULL, TRUE);

    return 0;
}


static LRESULT
DATETIME_LButtonUp (DATETIME_INFO *infoPtr)
{
    if(infoPtr->bCalDepressed) {
        infoPtr->bCalDepressed = FALSE;
        InvalidateRect(infoPtr->hwndSelf, &(infoPtr->calbutton), TRUE);
    }

    return 0;
}


static LRESULT
DATETIME_Paint (DATETIME_INFO *infoPtr, HDC hdc)
{
    if (!hdc) {
	PAINTSTRUCT ps;
        hdc = BeginPaint (infoPtr->hwndSelf, &ps);
        DATETIME_Refresh (infoPtr, hdc);
        EndPaint (infoPtr->hwndSelf, &ps);
    } else {
        DATETIME_Refresh (infoPtr, hdc);
    }

    /* Not a click on the dropdown box, enabled it */
    infoPtr->bDropdownEnabled = TRUE;

    return 0;
}


static LRESULT
DATETIME_Button_Command (DATETIME_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
{
    if( HIWORD(wParam) == BN_CLICKED) {
        DWORD state = SendMessageW((HWND)lParam, BM_GETCHECK, 0, 0);
        infoPtr->dateValid = (state == BST_CHECKED);
        InvalidateRect(infoPtr->hwndSelf, NULL, TRUE);
    }
    return 0;
}
          
        
        
static LRESULT
DATETIME_Command (DATETIME_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
{
    TRACE("hwndbutton = %p\n", infoPtr->hwndCheckbut);
    if(infoPtr->hwndCheckbut == (HWND)lParam)
        return DATETIME_Button_Command(infoPtr, wParam, lParam);
    return 0;
}


static LRESULT
DATETIME_Enable (DATETIME_INFO *infoPtr, BOOL bEnable)
{
    TRACE("%p %s\n", infoPtr, bEnable ? "TRUE" : "FALSE");
    if (bEnable)
        infoPtr->dwStyle &= ~WS_DISABLED;
    else
        infoPtr->dwStyle |= WS_DISABLED;

    InvalidateRect(infoPtr->hwndSelf, NULL, TRUE);

    return 0;
}


static LRESULT
DATETIME_EraseBackground (const DATETIME_INFO *infoPtr, HDC hdc)
{
    HBRUSH hBrush, hSolidBrush = NULL;
    RECT   rc;

    if (infoPtr->dwStyle & WS_DISABLED)
        hBrush = hSolidBrush = CreateSolidBrush(comctl32_color.clrBtnFace);
    else
    {
        hBrush = (HBRUSH)SendMessageW(infoPtr->hwndNotify, WM_CTLCOLOREDIT,
                                      (WPARAM)hdc, (LPARAM)infoPtr->hwndSelf);
        if (!hBrush)
            hBrush = hSolidBrush = CreateSolidBrush(comctl32_color.clrWindow);
    }

    GetClientRect (infoPtr->hwndSelf, &rc);

    FillRect (hdc, &rc, hBrush);

    if (hSolidBrush)
        DeleteObject(hSolidBrush);

    return -1;
}


static LRESULT
DATETIME_Notify (DATETIME_INFO *infoPtr, const NMHDR *lpnmh)
{
    TRACE ("Got notification %x from %p\n", lpnmh->code, lpnmh->hwndFrom);
    TRACE ("info: %p %p %p\n", infoPtr->hwndSelf, infoPtr->hMonthCal, infoPtr->hUpdown);

    if (lpnmh->code == MCN_SELECT) {
        ShowWindow(infoPtr->hMonthCal, SW_HIDE);
        infoPtr->dateValid = TRUE;
        SendMessageW (infoPtr->hMonthCal, MCM_GETCURSEL, 0, (LPARAM)&infoPtr->date);
        TRACE("got from calendar %04d/%02d/%02d day of week %d\n", 
        infoPtr->date.wYear, infoPtr->date.wMonth, infoPtr->date.wDay, infoPtr->date.wDayOfWeek);
        SendMessageW (infoPtr->hwndCheckbut, BM_SETCHECK, BST_CHECKED, 0);
        InvalidateRect(infoPtr->hwndSelf, NULL, TRUE);
        DATETIME_SendDateTimeChangeNotify (infoPtr);
        DATETIME_SendSimpleNotify(infoPtr, DTN_CLOSEUP);
    }
    if ((lpnmh->hwndFrom == infoPtr->hUpdown) && (lpnmh->code == UDN_DELTAPOS)) {
        LPNMUPDOWN lpnmud = (LPNMUPDOWN)lpnmh;
        TRACE("Delta pos %d\n", lpnmud->iDelta);
        infoPtr->pendingUpdown = lpnmud->iDelta;
    }
    return 0;
}


static LRESULT
DATETIME_KeyDown (DATETIME_INFO *infoPtr, DWORD vkCode)
{
    int fieldNum = infoPtr->select & DTHT_DATEFIELD;
    int wrap = 0;

    if (!(infoPtr->haveFocus)) return 0;
    if ((fieldNum==0) && (infoPtr->select)) return 0;

    if (infoPtr->select & FORMATCALLMASK) {
	FIXME ("Callbacks not implemented yet\n");
    }

    switch (vkCode) {
	case VK_ADD:
    	case VK_UP:
	    DATETIME_IncreaseField (infoPtr, fieldNum, 1);
	    DATETIME_SendDateTimeChangeNotify (infoPtr);
	    break;
	case VK_SUBTRACT:
	case VK_DOWN:
	    DATETIME_IncreaseField (infoPtr, fieldNum, -1);
	    DATETIME_SendDateTimeChangeNotify (infoPtr);
	    break;
	case VK_HOME:
	    DATETIME_IncreaseField (infoPtr, fieldNum, INT_MIN);
	    DATETIME_SendDateTimeChangeNotify (infoPtr);
	    break;
	case VK_END:
	    DATETIME_IncreaseField (infoPtr, fieldNum, INT_MAX);
	    DATETIME_SendDateTimeChangeNotify (infoPtr);
	    break;
	case VK_LEFT:
	    do {
		if (infoPtr->select == 0) {
		    infoPtr->select = infoPtr->nrFields - 1;
		    wrap++;
		} else {
		    infoPtr->select--;
		}
	    } while ((infoPtr->fieldspec[infoPtr->select] & DT_STRING) && (wrap<2));
	    break;
	case VK_RIGHT:
	    do {
		infoPtr->select++;
		if (infoPtr->select==infoPtr->nrFields) {
		    infoPtr->select = 0;
		    wrap++;
		}
	    } while ((infoPtr->fieldspec[infoPtr->select] & DT_STRING) && (wrap<2));
	    break;
    }

    InvalidateRect(infoPtr->hwndSelf, NULL, TRUE);

    return 0;
}


static LRESULT
DATETIME_Char (DATETIME_INFO *infoPtr, WPARAM vkCode)
{
    int fieldNum = infoPtr->select & DTHT_DATEFIELD;

    if (vkCode >= '0' && vkCode <= '9') {
        int num = vkCode-'0';
        int newDays;

        /* this is a somewhat simplified version of what Windows does */
        SYSTEMTIME *date = &infoPtr->date;
        switch (infoPtr->fieldspec[fieldNum]) {
            case ONEDIGITYEAR:
            case TWODIGITYEAR:
                date->wYear = date->wYear - (date->wYear%100) +
                        (date->wYear%10)*10 + num;
                MONTHCAL_CalculateDayOfWeek(date, TRUE);
                DATETIME_SendDateTimeChangeNotify (infoPtr);
                break;
            case INVALIDFULLYEAR:
            case FULLYEAR:
                /* reset current year initialy */
                date->wYear = ((date->wYear/1000) ? 0 : 1)*(date->wYear%1000)*10 + num;
                MONTHCAL_CalculateDayOfWeek(date, TRUE);
                DATETIME_SendDateTimeChangeNotify (infoPtr);
                break;
            case ONEDIGITMONTH:
            case TWODIGITMONTH:
                if ((date->wMonth%10) > 1 || num > 2)
                    date->wMonth = num;
                else
                    date->wMonth = (date->wMonth%10)*10+num;
                MONTHCAL_CalculateDayOfWeek(date, TRUE);
                DATETIME_SendDateTimeChangeNotify (infoPtr);
                break;
            case ONEDIGITDAY:
            case TWODIGITDAY:
                newDays = (date->wDay%10)*10+num;
                if (newDays > MONTHCAL_MonthLength(date->wMonth, date->wYear))
                    date->wDay = num;
                else
                    date->wDay = newDays;
                MONTHCAL_CalculateDayOfWeek(date, TRUE);
                DATETIME_SendDateTimeChangeNotify (infoPtr);
                break;
            case ONEDIGIT12HOUR:
            case TWODIGIT12HOUR:
                if ((date->wHour%10) > 1 || num > 2)
                    date->wHour = num;
                else
                    date->wHour = (date->wHour%10)*10+num;
                DATETIME_SendDateTimeChangeNotify (infoPtr);
                break;
            case ONEDIGIT24HOUR:
            case TWODIGIT24HOUR:
                if ((date->wHour%10) > 2)
                    date->wHour = num;
                else if ((date->wHour%10) == 2 && num > 3)
                    date->wHour = num;
                else
                    date->wHour = (date->wHour%10)*10+num;
                DATETIME_SendDateTimeChangeNotify (infoPtr);
                break;
            case ONEDIGITMINUTE:
            case TWODIGITMINUTE:
                if ((date->wMinute%10) > 5)
                    date->wMinute = num;
                else
                    date->wMinute = (date->wMinute%10)*10+num;
                DATETIME_SendDateTimeChangeNotify (infoPtr);
                break;
            case ONEDIGITSECOND:
            case TWODIGITSECOND:
                if ((date->wSecond%10) > 5)
                    date->wSecond = num;
                else
                    date->wSecond = (date->wSecond%10)*10+num;
                DATETIME_SendDateTimeChangeNotify (infoPtr);
                break;
        }
    }
    return 0;
}


static LRESULT
DATETIME_VScroll (DATETIME_INFO *infoPtr, WORD wScroll)
{
    int fieldNum = infoPtr->select & DTHT_DATEFIELD;

    if ((SHORT)LOWORD(wScroll) != SB_THUMBPOSITION) return 0;
    if (!(infoPtr->haveFocus)) return 0;
    if ((fieldNum==0) && (infoPtr->select)) return 0;

    if (infoPtr->pendingUpdown >= 0) {
	DATETIME_IncreaseField (infoPtr, fieldNum, 1);
	DATETIME_SendDateTimeChangeNotify (infoPtr);
    }
    else {
	DATETIME_IncreaseField (infoPtr, fieldNum, -1);
	DATETIME_SendDateTimeChangeNotify (infoPtr);
    }

    InvalidateRect(infoPtr->hwndSelf, NULL, TRUE);

    return 0;
}


static LRESULT
DATETIME_KillFocus (DATETIME_INFO *infoPtr, HWND lostFocus)
{
    TRACE("lost focus to %p\n", lostFocus);

    if (infoPtr->haveFocus) {
	DATETIME_SendSimpleNotify (infoPtr, NM_KILLFOCUS);
	infoPtr->haveFocus = 0;
    }

    InvalidateRect (infoPtr->hwndSelf, NULL, TRUE);

    return 0;
}


static LRESULT
DATETIME_NCCreate (HWND hwnd, const CREATESTRUCTW *lpcs)
{
    DWORD dwExStyle = GetWindowLongW(hwnd, GWL_EXSTYLE);
    /* force control to have client edge */
    dwExStyle |= WS_EX_CLIENTEDGE;
    SetWindowLongW(hwnd, GWL_EXSTYLE, dwExStyle);

    return DefWindowProcW(hwnd, WM_NCCREATE, 0, (LPARAM)lpcs);
}


static LRESULT
DATETIME_SetFocus (DATETIME_INFO *infoPtr, HWND lostFocus)
{
    TRACE("got focus from %p\n", lostFocus);

    /* if monthcal is open and it loses focus, close monthcal */
    if (infoPtr->hMonthCal && (lostFocus == infoPtr->hMonthCal) &&
        IsWindowVisible(infoPtr->hMonthCal))
    {
        ShowWindow(infoPtr->hMonthCal, SW_HIDE);
        DATETIME_SendSimpleNotify(infoPtr, DTN_CLOSEUP);
        /* note: this get triggered even if monthcal loses focus to a dropdown
         * box click, which occurs without an intermediate WM_PAINT call
         */
        infoPtr->bDropdownEnabled = FALSE;
        return 0;
    }

    if (infoPtr->haveFocus == 0) {
	DATETIME_SendSimpleNotify (infoPtr, NM_SETFOCUS);
	infoPtr->haveFocus = DTHT_GOTFOCUS;
    }

    InvalidateRect(infoPtr->hwndSelf, NULL, FALSE);

    return 0;
}


static BOOL
DATETIME_SendDateTimeChangeNotify (const DATETIME_INFO *infoPtr)
{
    NMDATETIMECHANGE dtdtc;

    dtdtc.nmhdr.hwndFrom = infoPtr->hwndSelf;
    dtdtc.nmhdr.idFrom   = GetWindowLongPtrW(infoPtr->hwndSelf, GWLP_ID);
    dtdtc.nmhdr.code     = DTN_DATETIMECHANGE;

    dtdtc.dwFlags = infoPtr->dateValid ? GDT_VALID : GDT_NONE;

    dtdtc.st = infoPtr->date;
    return (BOOL) SendMessageW (infoPtr->hwndNotify, WM_NOTIFY,
                                dtdtc.nmhdr.idFrom, (LPARAM)&dtdtc);
}


static BOOL
DATETIME_SendSimpleNotify (const DATETIME_INFO *infoPtr, UINT code)
{
    NMHDR nmhdr;

    TRACE("%x\n", code);
    nmhdr.hwndFrom = infoPtr->hwndSelf;
    nmhdr.idFrom   = GetWindowLongPtrW(infoPtr->hwndSelf, GWLP_ID);
    nmhdr.code     = code;

    return (BOOL) SendMessageW (infoPtr->hwndNotify, WM_NOTIFY,
                                nmhdr.idFrom, (LPARAM)&nmhdr);
}

static LRESULT
DATETIME_Size (DATETIME_INFO *infoPtr, INT width, INT height)
{
    /* set size */
    infoPtr->rcClient.bottom = height;
    infoPtr->rcClient.right = width;

    TRACE("Height=%d, Width=%d\n", infoPtr->rcClient.bottom, infoPtr->rcClient.right);

    infoPtr->rcDraw = infoPtr->rcClient;
    
    if (infoPtr->dwStyle & DTS_UPDOWN) {
        SetWindowPos(infoPtr->hUpdown, NULL,
            infoPtr->rcClient.right-14, 0,
            15, infoPtr->rcClient.bottom - infoPtr->rcClient.top,
            SWP_NOACTIVATE | SWP_NOZORDER);
    }
    else {
        /* set the size of the button that drops the calendar down */
        /* FIXME: account for style that allows button on left side */
        infoPtr->calbutton.top   = infoPtr->rcDraw.top;
        infoPtr->calbutton.bottom= infoPtr->rcDraw.bottom;
        infoPtr->calbutton.left  = infoPtr->rcDraw.right-15;
        infoPtr->calbutton.right = infoPtr->rcDraw.right;
    }

    /* set enable/disable button size for show none style being enabled */
    /* FIXME: these dimensions are completely incorrect */
    infoPtr->checkbox.top = infoPtr->rcDraw.top;
    infoPtr->checkbox.bottom = infoPtr->rcDraw.bottom;
    infoPtr->checkbox.left = infoPtr->rcDraw.left;
    infoPtr->checkbox.right = infoPtr->rcDraw.left + 10;

    InvalidateRect(infoPtr->hwndSelf, NULL, FALSE);

    return 0;
}

static LRESULT
DATETIME_StyleChanging(DATETIME_INFO *infoPtr, WPARAM wStyleType, STYLESTRUCT *lpss)
{
    TRACE("(styletype=%lx, styleOld=0x%08x, styleNew=0x%08x)\n",
          wStyleType, lpss->styleOld, lpss->styleNew);

    /* block DTS_SHOWNONE change */
    if ((lpss->styleNew ^ lpss->styleOld) & DTS_SHOWNONE)
    {
        if (lpss->styleOld & DTS_SHOWNONE)
            lpss->styleNew |= DTS_SHOWNONE;
        else
            lpss->styleNew &= ~DTS_SHOWNONE;
    }

    return 0;
}

static LRESULT 
DATETIME_StyleChanged(DATETIME_INFO *infoPtr, WPARAM wStyleType, const STYLESTRUCT *lpss)
{
    TRACE("(styletype=%lx, styleOld=0x%08x, styleNew=0x%08x)\n",
          wStyleType, lpss->styleOld, lpss->styleNew);

    if (wStyleType != GWL_STYLE) return 0;
  
    infoPtr->dwStyle = lpss->styleNew;

    if ( !(lpss->styleOld & DTS_SHOWNONE) && (lpss->styleNew & DTS_SHOWNONE) ) {
        infoPtr->hwndCheckbut = CreateWindowExW (0, WC_BUTTONW, 0, WS_CHILD | WS_VISIBLE | BS_AUTOCHECKBOX,
         					 2, 2, 13, 13, infoPtr->hwndSelf, 0, 
						(HINSTANCE)GetWindowLongPtrW (infoPtr->hwndSelf, GWLP_HINSTANCE), 0);
        SendMessageW (infoPtr->hwndCheckbut, BM_SETCHECK, 1, 0);
    }
    if ( (lpss->styleOld & DTS_SHOWNONE) && !(lpss->styleNew & DTS_SHOWNONE) ) {
        DestroyWindow(infoPtr->hwndCheckbut);
        infoPtr->hwndCheckbut = 0;
    }
    if ( !(lpss->styleOld & DTS_UPDOWN) && (lpss->styleNew & DTS_UPDOWN) ) {
	infoPtr->hUpdown = CreateUpDownControl (WS_CHILD | WS_BORDER | WS_VISIBLE, 120, 1, 20, 20, 
						infoPtr->hwndSelf, 1, 0, 0, UD_MAXVAL, UD_MINVAL, 0);
    }
    if ( (lpss->styleOld & DTS_UPDOWN) && !(lpss->styleNew & DTS_UPDOWN) ) {
	DestroyWindow(infoPtr->hUpdown);
	infoPtr->hUpdown = 0;
    }

    InvalidateRect(infoPtr->hwndSelf, NULL, TRUE);
    return 0;
}


static LRESULT
DATETIME_SetFont (DATETIME_INFO *infoPtr, HFONT font, BOOL repaint)
{
    infoPtr->hFont = font;
    if (repaint) InvalidateRect(infoPtr->hwndSelf, NULL, TRUE);
    return 0;
}


static LRESULT
DATETIME_Create (HWND hwnd, const CREATESTRUCTW *lpcs)
{
    DATETIME_INFO *infoPtr = Alloc (sizeof(DATETIME_INFO));
    STYLESTRUCT ss = { 0, lpcs->style };

    if (!infoPtr) return -1;

    infoPtr->hwndSelf = hwnd;
    infoPtr->dwStyle = lpcs->style;

    infoPtr->nrFieldsAllocated = 32;
    infoPtr->fieldspec = Alloc (infoPtr->nrFieldsAllocated * sizeof(int));
    infoPtr->fieldRect = Alloc (infoPtr->nrFieldsAllocated * sizeof(RECT));
    infoPtr->buflen = Alloc (infoPtr->nrFieldsAllocated * sizeof(int));
    infoPtr->hwndNotify = lpcs->hwndParent;
    infoPtr->select = -1; /* initially, nothing is selected */
    infoPtr->bDropdownEnabled = TRUE;

    DATETIME_StyleChanged(infoPtr, GWL_STYLE, &ss);
    DATETIME_SetFormatW (infoPtr, 0);

    /* create the monthcal control */
    infoPtr->hMonthCal = CreateWindowExW (0, MONTHCAL_CLASSW, 0, WS_BORDER | WS_POPUP | WS_CLIPSIBLINGS,
					  0, 0, 0, 0, infoPtr->hwndSelf, 0, 0, 0);

    /* initialize info structure */
    GetLocalTime (&infoPtr->date);
    infoPtr->dateValid = TRUE;
    infoPtr->hFont = GetStockObject(DEFAULT_GUI_FONT);

    SetWindowLongPtrW (hwnd, 0, (DWORD_PTR)infoPtr);

    return 0;
}



static LRESULT
DATETIME_Destroy (DATETIME_INFO *infoPtr)
{
    if (infoPtr->hwndCheckbut)
	DestroyWindow(infoPtr->hwndCheckbut);
    if (infoPtr->hUpdown)
	DestroyWindow(infoPtr->hUpdown);
    if (infoPtr->hMonthCal) 
        DestroyWindow(infoPtr->hMonthCal);
    SetWindowLongPtrW( infoPtr->hwndSelf, 0, 0 ); /* clear infoPtr */
    Free (infoPtr->buflen);
    Free (infoPtr->fieldRect);
    Free (infoPtr->fieldspec);
    Free (infoPtr);
    return 0;
}


static INT
DATETIME_GetText (DATETIME_INFO *infoPtr, INT count, LPWSTR dst)
{
    WCHAR buf[80];
    int i;

    if (!dst || (count <= 0)) return 0;

    dst[0] = 0;
    for (i = 0; i < infoPtr->nrFields; i++)
    {
        DATETIME_ReturnTxt(infoPtr, i, buf, sizeof(buf)/sizeof(buf[0]));
        if ((strlenW(dst) + strlenW(buf)) < count)
            strcatW(dst, buf);
        else break;
    }
    return strlenW(dst);
}


static LRESULT WINAPI
DATETIME_WindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    DATETIME_INFO *infoPtr = ((DATETIME_INFO *)GetWindowLongPtrW (hwnd, 0));
    LRESULT ret;

    TRACE ("%x, %lx, %lx\n", uMsg, wParam, lParam);

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

    switch (uMsg) {

    case DTM_GETSYSTEMTIME:
        return DATETIME_GetSystemTime (infoPtr, (SYSTEMTIME *) lParam);

    case DTM_SETSYSTEMTIME:
	return DATETIME_SetSystemTime (infoPtr, wParam, (SYSTEMTIME *) lParam);

    case DTM_GETRANGE:
	ret = SendMessageW (infoPtr->hMonthCal, MCM_GETRANGE, wParam, lParam);
	return ret ? ret : 1; /* bug emulation */

    case DTM_SETRANGE:
	return SendMessageW (infoPtr->hMonthCal, MCM_SETRANGE, wParam, lParam);

    case DTM_SETFORMATA:
        return DATETIME_SetFormatA (infoPtr, (LPCSTR)lParam);

    case DTM_SETFORMATW:
        return DATETIME_SetFormatW (infoPtr, (LPCWSTR)lParam);

    case DTM_GETMONTHCAL:
	return (LRESULT)infoPtr->hMonthCal;

    case DTM_SETMCCOLOR:
	return SendMessageW (infoPtr->hMonthCal, MCM_SETCOLOR, wParam, lParam);

    case DTM_GETMCCOLOR:
        return SendMessageW (infoPtr->hMonthCal, MCM_GETCOLOR, wParam, 0);

    case DTM_SETMCFONT:
	return SendMessageW (infoPtr->hMonthCal, WM_SETFONT, wParam, lParam);

    case DTM_GETMCFONT:
	return SendMessageW (infoPtr->hMonthCal, WM_GETFONT, wParam, lParam);

    case WM_NOTIFY:
	return DATETIME_Notify (infoPtr, (LPNMHDR)lParam);

    case WM_ENABLE:
        return DATETIME_Enable (infoPtr, (BOOL)wParam);

    case WM_ERASEBKGND:
        return DATETIME_EraseBackground (infoPtr, (HDC)wParam);

    case WM_GETDLGCODE:
        return DLGC_WANTARROWS | DLGC_WANTCHARS;

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

    case WM_KEYDOWN:
        return DATETIME_KeyDown (infoPtr, wParam);

    case WM_CHAR:
        return DATETIME_Char (infoPtr, wParam);

    case WM_KILLFOCUS:
        return DATETIME_KillFocus (infoPtr, (HWND)wParam);

    case WM_NCCREATE:
        return DATETIME_NCCreate (hwnd, (LPCREATESTRUCTW)lParam);

    case WM_SETFOCUS:
        return DATETIME_SetFocus (infoPtr, (HWND)wParam);

    case WM_SIZE:
        return DATETIME_Size (infoPtr, (SHORT)LOWORD(lParam), (SHORT)HIWORD(lParam));

    case WM_LBUTTONDOWN:
        return DATETIME_LButtonDown (infoPtr, (SHORT)LOWORD(lParam), (SHORT)HIWORD(lParam));

    case WM_LBUTTONUP:
        return DATETIME_LButtonUp (infoPtr);

    case WM_VSCROLL:
        return DATETIME_VScroll (infoPtr, (WORD)wParam);

    case WM_CREATE:
	return DATETIME_Create (hwnd, (LPCREATESTRUCTW)lParam);

    case WM_DESTROY:
	return DATETIME_Destroy (infoPtr);

    case WM_COMMAND:
        return DATETIME_Command (infoPtr, wParam, lParam);

    case WM_STYLECHANGING:
        return DATETIME_StyleChanging(infoPtr, wParam, (LPSTYLESTRUCT)lParam);

    case WM_STYLECHANGED:
        return DATETIME_StyleChanged(infoPtr, wParam, (LPSTYLESTRUCT)lParam);

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

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

    case WM_GETTEXT:
        return (LRESULT) DATETIME_GetText(infoPtr, wParam, (LPWSTR)lParam);

    case WM_SETTEXT:
        return CB_ERR;

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


void
DATETIME_Register (void)
{
    WNDCLASSW wndClass;

    ZeroMemory (&wndClass, sizeof(WNDCLASSW));
    wndClass.style         = CS_GLOBALCLASS;
    wndClass.lpfnWndProc   = DATETIME_WindowProc;
    wndClass.cbClsExtra    = 0;
    wndClass.cbWndExtra    = sizeof(DATETIME_INFO *);
    wndClass.hCursor       = LoadCursorW (0, (LPCWSTR)IDC_ARROW);
    wndClass.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
    wndClass.lpszClassName = DATETIMEPICK_CLASSW;

    RegisterClassW (&wndClass);
}


void
DATETIME_Unregister (void)
{
    UnregisterClassW (DATETIMEPICK_CLASSW, NULL);
}
