/*
 * Month calendar control
 *
 * Copyright 1998, 1999 Eric Kohl (ekohl@abo.rhein-zeitung.de)
 * Copyright 1999 Alex Priem (alexp@sci.kun.nl)
 * Copyright 1999 Chris Morgan <cmorgan@wpi.edu> and
 *		  James Abbatiello <abbeyj@wpi.edu>
 * Copyright 2000 Uwe Bonnes <bon@elektron.ikp.physik.tu-darmstadt.de>
 * Copyright 2009, 2010 Nikolay Sivov
 *
 * 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:
 *    -- MCM_[GS]ETUNICODEFORMAT
 *    -- MONTHCAL_GetMonthRange
 *    -- handle resources better (doesn't work now); 
 *    -- take care of internationalization.
 *    -- keyboard handling.
 *    -- search for FIXME
 */

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

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

WINE_DEFAULT_DEBUG_CHANNEL(monthcal);

#define MC_SEL_LBUTUP	    1	/* Left button released */
#define MC_SEL_LBUTDOWN	    2	/* Left button pressed in calendar */
#define MC_PREVPRESSED      4   /* Prev month button pressed */
#define MC_NEXTPRESSED      8   /* Next month button pressed */
#define MC_PREVNEXTMONTHDELAY   350	/* when continuously pressing `next/prev
					   month', wait 350 ms before going
					   to the next/prev month */
#define MC_TODAYUPDATEDELAY 120000 /* time between today check for update (2 min) */

#define MC_PREVNEXTMONTHTIMER   1	/* Timer ID's */
#define MC_TODAYUPDATETIMER     2

#define countof(arr) (sizeof(arr)/sizeof(arr[0]))

/* convert from days to 100 nanoseconds unit - used as FILETIME unit */
#define DAYSTO100NSECS(days) (((ULONGLONG)(days))*24*60*60*10000000)

/* single calendar data */
typedef struct _CALENDAR_INFO
{
    RECT title;      /* rect for the header above the calendar */
    RECT titlemonth; /* the 'month name' text in the header */
    RECT titleyear;  /* the 'year number' text in the header */
    RECT wdays;      /* week days at top */
    RECT days;       /* calendar area */
    RECT weeknums;   /* week numbers at left side */

    SYSTEMTIME month;/* contains calendar main month/year */
} CALENDAR_INFO;

typedef struct
{
    HWND	hwndSelf;
    DWORD	dwStyle; /* cached GWL_STYLE */

    COLORREF    colors[MCSC_TRAILINGTEXT+1];

    HFONT	hFont;
    HFONT	hBoldFont;
    int		textHeight;
    int		textWidth;
    int		height_increment;
    int		width_increment;
    INT		delta;	/* scroll rate; # of months that the */
                        /* control moves when user clicks a scroll button */
    int		visible;	/* # of months visible */
    int		firstDay;	/* Start month calendar with firstDay's day,
				   stored in SYSTEMTIME format */
    BOOL	firstDaySet;    /* first week day differs from locale defined */

    BOOL	isUnicode;      /* value set with MCM_SETUNICODE format */

    int		monthRange;
    MONTHDAYSTATE *monthdayState;
    SYSTEMTIME	todaysDate;
    BOOL	todaySet;       /* Today was forced with MCM_SETTODAY */
    int		status;		/* See MC_SEL flags */
    SYSTEMTIME	firstSel;	/* first selected day */
    INT		maxSelCount;
    SYSTEMTIME	minSel;         /* contains single selection when used without MCS_MULTISELECT */
    SYSTEMTIME	maxSel;
    SYSTEMTIME  focusedSel;     /* date currently focused with mouse movement */
    DWORD	rangeValid;
    SYSTEMTIME	minDate;
    SYSTEMTIME	maxDate;

    RECT titlebtnnext;	/* the `next month' button in the header */
    RECT titlebtnprev;  /* the `prev month' button in the header */
    RECT todayrect;	/* `today: xx/xx/xx' text rect */
    HWND hwndNotify;    /* Window to receive the notifications */
    HWND hWndYearEdit;  /* Window Handle of edit box to handle years */
    HWND hWndYearUpDown;/* Window Handle of updown box to handle years */
    WNDPROC EditWndProc;  /* original Edit window procedure */

    CALENDAR_INFO *calendars;
    INT            cal_num;
} MONTHCAL_INFO, *LPMONTHCAL_INFO;

static const WCHAR themeClass[] = { 'S','c','r','o','l','l','b','a','r',0 };

/* empty SYSTEMTIME const */
static const SYSTEMTIME st_null;
/* valid date limits */
static const SYSTEMTIME max_allowed_date = { .wYear = 9999, .wMonth = 12, .wDay = 31 };
static const SYSTEMTIME min_allowed_date = { .wYear = 1752, .wMonth = 9,  .wDay = 14 };

/* Prev/Next buttons */
enum nav_direction
{
    DIRECTION_BACKWARD,
    DIRECTION_FORWARD
};

/* helper functions  */

/* send a single MCN_SELCHANGE notification */
static inline void MONTHCAL_NotifySelectionChange(const MONTHCAL_INFO *infoPtr)
{
    NMSELCHANGE nmsc;

    nmsc.nmhdr.hwndFrom = infoPtr->hwndSelf;
    nmsc.nmhdr.idFrom   = GetWindowLongPtrW(infoPtr->hwndSelf, GWLP_ID);
    nmsc.nmhdr.code     = MCN_SELCHANGE;
    nmsc.stSelStart     = infoPtr->minSel;
    nmsc.stSelEnd       = infoPtr->maxSel;
    SendMessageW(infoPtr->hwndNotify, WM_NOTIFY, nmsc.nmhdr.idFrom, (LPARAM)&nmsc);
}

/* send a single MCN_SELECT notification */
static inline void MONTHCAL_NotifySelect(const MONTHCAL_INFO *infoPtr)
{
    NMSELCHANGE nmsc;

    nmsc.nmhdr.hwndFrom = infoPtr->hwndSelf;
    nmsc.nmhdr.idFrom   = GetWindowLongPtrW(infoPtr->hwndSelf, GWLP_ID);
    nmsc.nmhdr.code     = MCN_SELECT;
    nmsc.stSelStart     = infoPtr->minSel;
    nmsc.stSelEnd       = infoPtr->maxSel;

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

/* returns the number of days in any given month, checking for leap days */
/* january is 1, december is 12 */
int MONTHCAL_MonthLength(int month, int year)
{
  const int mdays[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
  /* Wrap around, this eases handling. Getting length only we shouldn't care
     about year change here cause January and December have
     the same day quantity */
  if(month == 0)
    month = 12;
  else if(month == 13)
    month = 1;

  /* special case for calendar transition year */
  if(month == min_allowed_date.wMonth && year == min_allowed_date.wYear) return 19;

  /* if we have a leap year add 1 day to February */
  /* a leap year is a year either divisible by 400 */
  /* or divisible by 4 and not by 100 */
  if(month == 2) { /* February */
    return mdays[month - 1] + ((year%400 == 0) ? 1 : ((year%100 != 0) &&
     (year%4 == 0)) ? 1 : 0);
  }
  else {
    return mdays[month - 1];
  }
}

/* compares timestamps using date part only */
static inline BOOL MONTHCAL_IsDateEqual(const SYSTEMTIME *first, const SYSTEMTIME *second)
{
  return (first->wYear == second->wYear) && (first->wMonth == second->wMonth) &&
         (first->wDay  == second->wDay);
}

/* make sure that date fields are valid */
static BOOL MONTHCAL_ValidateDate(const SYSTEMTIME *time)
{
  if(time->wMonth < 1 || time->wMonth > 12 ) return FALSE;
  if(time->wDayOfWeek > 6) return FALSE;
  if(time->wDay > MONTHCAL_MonthLength(time->wMonth, time->wYear))
	  return FALSE;

  return TRUE;
}

/* Copies timestamp part only.
 *
 * PARAMETERS
 *
 *  [I] from : source date
 *  [O] to   : dest date
 */
static void MONTHCAL_CopyTime(const SYSTEMTIME *from, SYSTEMTIME *to)
{
  to->wHour   = from->wHour;
  to->wMinute = from->wMinute;
  to->wSecond = from->wSecond;
}

/* Copies date part only.
 *
 * PARAMETERS
 *
 *  [I] from : source date
 *  [O] to   : dest date
 */
static void MONTHCAL_CopyDate(const SYSTEMTIME *from, SYSTEMTIME *to)
{
  to->wYear  = from->wYear;
  to->wMonth = from->wMonth;
  to->wDay   = from->wDay;
  to->wDayOfWeek = from->wDayOfWeek;
}

/* Compares two dates in SYSTEMTIME format
 *
 * PARAMETERS
 *
 *  [I] first  : pointer to valid first date data to compare
 *  [I] second : pointer to valid second date data to compare
 *
 * RETURN VALUE
 *
 *  -1 : first <  second
 *   0 : first == second
 *   1 : first >  second
 *
 *  Note that no date validation performed, alreadt validated values expected.
 */
static LONG MONTHCAL_CompareSystemTime(const SYSTEMTIME *first, const SYSTEMTIME *second)
{
  FILETIME ft_first, ft_second;

  SystemTimeToFileTime(first, &ft_first);
  SystemTimeToFileTime(second, &ft_second);

  return CompareFileTime(&ft_first, &ft_second);
}

static LONG MONTHCAL_CompareMonths(const SYSTEMTIME *first, const SYSTEMTIME *second)
{
  SYSTEMTIME st_first, st_second;

  st_first = st_second = st_null;
  MONTHCAL_CopyDate(first, &st_first);
  MONTHCAL_CopyDate(second, &st_second);
  st_first.wDay = st_second.wDay = 1;

  return MONTHCAL_CompareSystemTime(&st_first, &st_second);
}

static LONG MONTHCAL_CompareDate(const SYSTEMTIME *first, const SYSTEMTIME *second)
{
  SYSTEMTIME st_first, st_second;

  st_first = st_second = st_null;
  MONTHCAL_CopyDate(first, &st_first);
  MONTHCAL_CopyDate(second, &st_second);

  return MONTHCAL_CompareSystemTime(&st_first, &st_second);
}

/* Checks largest possible date range and configured one
 *
 * PARAMETERS
 *
 *  [I] infoPtr : valid pointer to control data
 *  [I] date    : pointer to valid date data to check
 *  [I] fix     : make date fit valid range
 *
 * RETURN VALUE
 *
 *  TRUE  - date whithin largest and configured range
 *  FALSE - date is outside largest or configured range
 */
static BOOL MONTHCAL_IsDateInValidRange(const MONTHCAL_INFO *infoPtr,
                                        SYSTEMTIME *date, BOOL fix)
{
  const SYSTEMTIME *fix_st = NULL;

  if(MONTHCAL_CompareSystemTime(date, &max_allowed_date) == 1) {
     fix_st = &max_allowed_date;
  }
  else if(MONTHCAL_CompareSystemTime(date, &min_allowed_date) == -1) {
     fix_st = &min_allowed_date;
  }
  else if(infoPtr->rangeValid & GDTR_MAX) {
     if((MONTHCAL_CompareSystemTime(date, &infoPtr->maxDate) == 1)) {
       fix_st = &infoPtr->maxDate;
     }
  }
  else if(infoPtr->rangeValid & GDTR_MIN) {
     if((MONTHCAL_CompareSystemTime(date, &infoPtr->minDate) == -1)) {
       fix_st = &infoPtr->minDate;
     }
  }

  if (fix && fix_st) {
    date->wYear  = fix_st->wYear;
    date->wMonth = fix_st->wMonth;
  }

  return fix_st ? FALSE : TRUE;
}

/* Checks passed range width with configured maximum selection count
 *
 * PARAMETERS
 *
 *  [I] infoPtr : valid pointer to control data
 *  [I] range0  : pointer to valid date data (requested bound)
 *  [I] range1  : pointer to valid date data (primary bound)
 *  [O] adjust  : returns adjusted range bound to fit maximum range (optional)
 *
 *  Adjust value computed basing on primary bound and current maximum selection
 *  count. For simple range check (without adjusted value required) (range0, range1)
 *  relation means nothing.
 *
 * RETURN VALUE
 *
 *  TRUE  - range is shorter or equal to maximum
 *  FALSE - range is larger than maximum
 */
static BOOL MONTHCAL_IsSelRangeValid(const MONTHCAL_INFO *infoPtr,
                                     const SYSTEMTIME *range0,
                                     const SYSTEMTIME *range1,
                                     SYSTEMTIME *adjust)
{
  ULARGE_INTEGER ul_range0, ul_range1, ul_diff;
  FILETIME ft_range0, ft_range1;
  LONG cmp;

  SystemTimeToFileTime(range0, &ft_range0);
  SystemTimeToFileTime(range1, &ft_range1);

  ul_range0.u.LowPart  = ft_range0.dwLowDateTime;
  ul_range0.u.HighPart = ft_range0.dwHighDateTime;
  ul_range1.u.LowPart  = ft_range1.dwLowDateTime;
  ul_range1.u.HighPart = ft_range1.dwHighDateTime;

  cmp = CompareFileTime(&ft_range0, &ft_range1);

  if(cmp == 1)
     ul_diff.QuadPart = ul_range0.QuadPart - ul_range1.QuadPart;
  else
     ul_diff.QuadPart = -ul_range0.QuadPart + ul_range1.QuadPart;

  if(ul_diff.QuadPart >= DAYSTO100NSECS(infoPtr->maxSelCount)) {

     if(adjust) {
       if(cmp == 1)
          ul_range0.QuadPart = ul_range1.QuadPart + DAYSTO100NSECS(infoPtr->maxSelCount - 1);
       else
          ul_range0.QuadPart = ul_range1.QuadPart - DAYSTO100NSECS(infoPtr->maxSelCount - 1);

       ft_range0.dwLowDateTime  = ul_range0.u.LowPart;
       ft_range0.dwHighDateTime = ul_range0.u.HighPart;
       FileTimeToSystemTime(&ft_range0, adjust);
     }

     return FALSE;
  }
  else return TRUE;
}

/* Used in MCM_SETRANGE/MCM_SETSELRANGE to determine resulting time part.
   Milliseconds are intentionally not validated. */
static BOOL MONTHCAL_ValidateTime(const SYSTEMTIME *time)
{
  if((time->wHour > 24) || (time->wMinute > 59) || (time->wSecond > 59))
    return FALSE;
  else
    return TRUE;
}

/* Note:Depending on DST, this may be offset by a day.
   Need to find out if we're on a DST place & adjust the clock accordingly.
   Above function assumes we have a valid data.
   Valid for year>1752;  1 <= d <= 31, 1 <= m <= 12.
   0 = Sunday.
*/

/* Returns the day in the week
 *
 * PARAMETERS
 *  [i] date    : input date
 *  [I] inplace : set calculated value back to date structure
 *
 * RETURN VALUE
 *   day of week in SYSTEMTIME format: (0 == sunday,..., 6 == saturday)
 */
int MONTHCAL_CalculateDayOfWeek(SYSTEMTIME *date, BOOL inplace)
{
  SYSTEMTIME st = st_null;
  FILETIME ft;

  MONTHCAL_CopyDate(date, &st);

  SystemTimeToFileTime(&st, &ft);
  FileTimeToSystemTime(&ft, &st);

  if (inplace) date->wDayOfWeek = st.wDayOfWeek;

  return st.wDayOfWeek;
}

/* add/substract 'months' from date */
static inline void MONTHCAL_GetMonth(SYSTEMTIME *date, INT months)
{
  INT length, m = date->wMonth + months;

  date->wYear += m > 0 ? (m - 1) / 12 : m / 12 - 1;
  date->wMonth = m > 0 ? (m - 1) % 12 + 1 : 12 + m % 12;
  /* fix moving from last day in a month */
  length = MONTHCAL_MonthLength(date->wMonth, date->wYear);
  if(date->wDay > length) date->wDay = length;
  MONTHCAL_CalculateDayOfWeek(date, TRUE);
}

/* properly updates date to point on next month */
static inline void MONTHCAL_GetNextMonth(SYSTEMTIME *date)
{
  return MONTHCAL_GetMonth(date, 1);
}

/* properly updates date to point on prev month */
static inline void MONTHCAL_GetPrevMonth(SYSTEMTIME *date)
{
  return MONTHCAL_GetMonth(date, -1);
}

/* Returns full date for a first currently visible day */
static void MONTHCAL_GetMinDate(const MONTHCAL_INFO *infoPtr, SYSTEMTIME *date)
{
  /* zero indexed calendar has the earliest date */
  SYSTEMTIME st_first = infoPtr->calendars[0].month;
  INT firstDay;

  st_first.wDay = 1;
  firstDay = MONTHCAL_CalculateDayOfWeek(&st_first, FALSE);

  *date = infoPtr->calendars[0].month;
  MONTHCAL_GetPrevMonth(date);

  date->wDay = MONTHCAL_MonthLength(date->wMonth, date->wYear) +
               (infoPtr->firstDay - firstDay) % 7 + 1;

  if(date->wDay > MONTHCAL_MonthLength(date->wMonth, date->wYear))
    date->wDay -= 7;

  /* fix day of week */
  MONTHCAL_CalculateDayOfWeek(date, TRUE);
}

/* Returns full date for a last currently visible day */
static void MONTHCAL_GetMaxDate(const MONTHCAL_INFO *infoPtr, SYSTEMTIME *date)
{
  /* the latest date is in latest calendar */
  SYSTEMTIME st, lt_month = infoPtr->calendars[infoPtr->cal_num-1].month;

  *date = lt_month;
  MONTHCAL_GetNextMonth(date);

  MONTHCAL_GetMinDate(infoPtr, &st);
  /* Use month length to get max day. 42 means max day count in calendar area */
  date->wDay = 42 - (MONTHCAL_MonthLength(st.wMonth, st.wYear) - st.wDay + 1) -
                     MONTHCAL_MonthLength(lt_month.wMonth, lt_month.wYear);

  /* fix day of week */
  MONTHCAL_CalculateDayOfWeek(date, TRUE);
}

/* From a given point, calculate the row (weekpos), column(daypos)
   and day in the calendar. day== 0 mean the last day of tha last month
*/
static int MONTHCAL_CalcDayFromPos(const MONTHCAL_INFO *infoPtr, int x, int y,
				   int *daypos, int *weekpos)
{
  int retval, firstDay;
  RECT rcClient;
  SYSTEMTIME st = infoPtr->minSel;

  GetClientRect(infoPtr->hwndSelf, &rcClient);

  /* if the point is outside the x bounds of the window put
  it at the boundary */
  if (x > rcClient.right)
    x = rcClient.right;

  *daypos  = (x - infoPtr->calendars[0].days.left ) / infoPtr->width_increment;
  *weekpos = (y - infoPtr->calendars[0].days.top ) / infoPtr->height_increment;

  st.wDay = 1;
  firstDay = (MONTHCAL_CalculateDayOfWeek(&st, FALSE) + 6 - infoPtr->firstDay) % 7;
  retval = *daypos + (7 * *weekpos) - firstDay;
  return retval;
}

/* Sets the RECT struct r to the rectangle around the date
 *
 * PARAMETERS
 *
 *  [I] infoPtr : pointer to control data
 *  [I] date : date value
 *  [O] x : day column (zero based)
 *  [O] y : week column (zero based)
 */
static void MONTHCAL_CalcDayXY(const MONTHCAL_INFO *infoPtr,
                               const SYSTEMTIME *date, INT *x, INT *y)
{
  SYSTEMTIME st = infoPtr->minSel;
  LONG cmp;
  int first;

  st.wDay = 1;
  first = (MONTHCAL_CalculateDayOfWeek(&st, FALSE) + 6 - infoPtr->firstDay) % 7;

  cmp = MONTHCAL_CompareMonths(date, &infoPtr->minSel);

  /* previous month */
  if(cmp == -1) {
    *x = (first - MONTHCAL_MonthLength(date->wMonth, infoPtr->minSel.wYear) + date->wDay) % 7;
    *y = 0;
    return;
  }

  /* next month calculation is same as for current,
     just add current month length */
  if(cmp == 1) {
    first += MONTHCAL_MonthLength(infoPtr->minSel.wMonth, infoPtr->minSel.wYear);
  }

  *x = (date->wDay + first) % 7;
  *y = (date->wDay + first - *x) / 7;
}


/* x: column(day), y: row(week) */
static inline void MONTHCAL_CalcDayRect(const MONTHCAL_INFO *infoPtr, RECT *r, int x, int y)
{
  r->left = infoPtr->calendars[0].days.left + x * infoPtr->width_increment;
  r->right = r->left + infoPtr->width_increment;
  r->top  = infoPtr->calendars[0].days.top  + y * infoPtr->height_increment;
  r->bottom = r->top + infoPtr->textHeight;
}


/* Sets the RECT struct r to the rectangle around the date */
static inline void MONTHCAL_CalcPosFromDay(const MONTHCAL_INFO *infoPtr,
                                           const SYSTEMTIME *date, RECT *r)
{
  int x, y;

  MONTHCAL_CalcDayXY(infoPtr, date, &x, &y);
  MONTHCAL_CalcDayRect(infoPtr, r, x, y);
}

/* Focused day helper:

   - set focused date to given value;
   - reset to zero value if NULL passed;
   - invalidate previous and new day rectangle only if needed.

   Returns TRUE if focused day changed, FALSE otherwise.
*/
static BOOL MONTHCAL_SetDayFocus(MONTHCAL_INFO *infoPtr, const SYSTEMTIME *st)
{
  RECT r;

  if(st)
  {
    /* there's nothing to do if it's the same date,
       mouse move within same date rectangle case */
    if(MONTHCAL_IsDateEqual(&infoPtr->focusedSel, st)) return FALSE;

    /* invalidate old focused day */
    MONTHCAL_CalcPosFromDay(infoPtr, &infoPtr->focusedSel, &r);
    InvalidateRect(infoPtr->hwndSelf, &r, FALSE);

    infoPtr->focusedSel = *st;
  }

  MONTHCAL_CalcPosFromDay(infoPtr, &infoPtr->focusedSel, &r);

  if(!st && MONTHCAL_ValidateDate(&infoPtr->focusedSel))
    infoPtr->focusedSel = st_null;

  /* on set invalidates new day, on reset clears previous focused day */
  InvalidateRect(infoPtr->hwndSelf, &r, FALSE);

  return TRUE;
}

/* Draw today day mark rectangle
 *
 * [I] hdc : context to draw in
 * [I] day : day to mark with rectangle
 *
 */
static void MONTHCAL_CircleDay(const MONTHCAL_INFO *infoPtr, HDC hdc,
                               const SYSTEMTIME *date)
{
  HPEN hRedPen = CreatePen(PS_SOLID, 1, RGB(255, 0, 0));
  HPEN hOldPen2 = SelectObject(hdc, hRedPen);
  HBRUSH hOldBrush;
  RECT day_rect;

  MONTHCAL_CalcPosFromDay(infoPtr, date, &day_rect);

  hOldBrush = SelectObject(hdc, GetStockObject(NULL_BRUSH));
  Rectangle(hdc, day_rect.left, day_rect.top, day_rect.right, day_rect.bottom);

  SelectObject(hdc, hOldBrush);
  DeleteObject(hRedPen);
  SelectObject(hdc, hOldPen2);
}

static void MONTHCAL_DrawDay(const MONTHCAL_INFO *infoPtr, HDC hdc, const SYSTEMTIME *st,
                             int bold, const PAINTSTRUCT *ps)
{
  static const WCHAR fmtW[] = { '%','d',0 };
  WCHAR buf[10];
  RECT r, r_temp;
  static BOOL bold_selected;
  BOOL selected_day = FALSE;
  HBRUSH hbr;
  COLORREF oldCol = 0;
  COLORREF oldBk  = 0;

/* No need to check styles: when selection is not valid, it is set to zero.
 * 1<day<31, so everything is OK.
 */

  MONTHCAL_CalcPosFromDay(infoPtr, st, &r);
  if(!IntersectRect(&r_temp, &(ps->rcPaint), &r)) return;

  if ((MONTHCAL_CompareDate(st, &infoPtr->minSel) >= 0) &&
      (MONTHCAL_CompareDate(st, &infoPtr->maxSel) <= 0)) {

    TRACE("%d %d %d\n", st->wDay, infoPtr->minSel.wDay, infoPtr->maxSel.wDay);
    TRACE("%s\n", wine_dbgstr_rect(&r));
    oldCol = SetTextColor(hdc, infoPtr->colors[MCSC_MONTHBK]);
    oldBk = SetBkColor(hdc, infoPtr->colors[MCSC_TRAILINGTEXT]);
    hbr = GetSysColorBrush(COLOR_HIGHLIGHT);
    FillRect(hdc, &r, hbr);

    selected_day = TRUE;
  }

  if(bold && !bold_selected) {
    SelectObject(hdc, infoPtr->hBoldFont);
    bold_selected = TRUE;
  }
  if(!bold && bold_selected) {
    SelectObject(hdc, infoPtr->hFont);
    bold_selected = FALSE;
  }

  SetBkMode(hdc,TRANSPARENT);
  wsprintfW(buf, fmtW, st->wDay);
  DrawTextW(hdc, buf, -1, &r, DT_CENTER | DT_VCENTER | DT_SINGLELINE );

  if(selected_day) {
    SetTextColor(hdc, oldCol);
    SetBkColor(hdc, oldBk);
  }
}


static void MONTHCAL_PaintButton(MONTHCAL_INFO *infoPtr, HDC hdc, enum nav_direction button)
{
    HTHEME theme = GetWindowTheme (infoPtr->hwndSelf);
    RECT *r = button == DIRECTION_FORWARD ? &infoPtr->titlebtnnext : &infoPtr->titlebtnprev;
    BOOL pressed = button == DIRECTION_FORWARD ? infoPtr->status & MC_NEXTPRESSED :
                                                 infoPtr->status & MC_PREVPRESSED;
    if (theme)
    {
        static const int states[] = {
            /* Prev button */
            ABS_LEFTNORMAL,  ABS_LEFTPRESSED,  ABS_LEFTDISABLED,
            /* Next button */
            ABS_RIGHTNORMAL, ABS_RIGHTPRESSED, ABS_RIGHTDISABLED
        };
        int stateNum = button == DIRECTION_FORWARD ? 3 : 0;
        if (pressed)
            stateNum += 1;
        else
        {
            if (infoPtr->dwStyle & WS_DISABLED) stateNum += 2;
        }
        DrawThemeBackground (theme, hdc, SBP_ARROWBTN, states[stateNum], r, NULL);
    }
    else
    {
        int style = button == DIRECTION_FORWARD ? DFCS_SCROLLRIGHT : DFCS_SCROLLLEFT;
        if (pressed)
            style |= DFCS_PUSHED;
        else
        {
            if (infoPtr->dwStyle & WS_DISABLED) style |= DFCS_INACTIVE;
        }
        
        DrawFrameControl(hdc, r, DFC_SCROLL, style);
    }
}
/* paint a title with buttons and month/year string */
static void MONTHCAL_PaintTitle(MONTHCAL_INFO *infoPtr, HDC hdc, const PAINTSTRUCT *ps, INT calIdx)
{
  static const WCHAR fmt_monthW[] = { '%','s',' ','%','l','d',0 };
  RECT *title = &infoPtr->calendars[calIdx].title;
  const SYSTEMTIME *st = &infoPtr->calendars[calIdx].month;
  WCHAR buf_month[80], buf_fmt[80];
  HBRUSH hbr;
  SIZE sz;

  /* fill header box */
  hbr = CreateSolidBrush(infoPtr->colors[MCSC_TITLEBK]);
  FillRect(hdc, title, hbr);
  DeleteObject(hbr);

  /* month/year string */
  SetBkColor(hdc, infoPtr->colors[MCSC_TITLEBK]);
  SetTextColor(hdc, infoPtr->colors[MCSC_TITLETEXT]);
  SelectObject(hdc, infoPtr->hBoldFont);

  GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SMONTHNAME1 + st->wMonth - 1,
                 buf_month, countof(buf_month));

  wsprintfW(buf_fmt, fmt_monthW, buf_month, st->wYear);
  DrawTextW(hdc, buf_fmt, strlenW(buf_fmt), title,
                      DT_CENTER | DT_VCENTER | DT_SINGLELINE);

  /* update title rectangles with current month - used while testing hits */
  GetTextExtentPoint32W(hdc, buf_fmt, strlenW(buf_fmt), &sz);
  infoPtr->calendars[calIdx].titlemonth.left = title->right / 2 + title->left / 2 - sz.cx / 2;
  infoPtr->calendars[calIdx].titleyear.right = title->right / 2 + title->left / 2 + sz.cx / 2;

  GetTextExtentPoint32W(hdc, buf_month, strlenW(buf_month), &sz);
  infoPtr->calendars[calIdx].titlemonth.right = infoPtr->calendars[calIdx].titlemonth.left + sz.cx;
  infoPtr->calendars[calIdx].titleyear.left   = infoPtr->calendars[calIdx].titlemonth.right;
}

static void MONTHCAL_PaintWeeknumbers(const MONTHCAL_INFO *infoPtr, HDC hdc, const PAINTSTRUCT *ps, INT calIdx)
{
  const SYSTEMTIME *date = &infoPtr->calendars[calIdx].month;
  static const WCHAR fmt_weekW[] = { '%','d',0 };
  INT mindays, weeknum, weeknum1, startofprescal;
  INT i, prev_month;
  SYSTEMTIME st;
  WCHAR buf[80];
  HBRUSH hbr;
  RECT r;

  if (!(infoPtr->dwStyle & MCS_WEEKNUMBERS)) return;

  MONTHCAL_GetMinDate(infoPtr, &st);
  startofprescal = st.wDay;
  st = *date;

  prev_month = date->wMonth - 1;
  if(prev_month == 0) prev_month = 12;

  /*
     Rules what week to call the first week of a new year:
     LOCALE_IFIRSTWEEKOFYEAR == 0 (e.g US?):
     The week containing Jan 1 is the first week of year
     LOCALE_IFIRSTWEEKOFYEAR == 2 (e.g. Germany):
     First week of year must contain 4 days of the new year
     LOCALE_IFIRSTWEEKOFYEAR == 1  (what contries?)
     The first week of the year must contain only days of the new year
  */
  GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_IFIRSTWEEKOFYEAR, buf, countof(buf));
  weeknum = atoiW(buf);
  switch (weeknum)
  {
    case 1: mindays = 6;
	break;
    case 2: mindays = 3;
	break;
    case 0: mindays = 0;
        break;
    default:
        WARN("Unknown LOCALE_IFIRSTWEEKOFYEAR value %d, defaulting to 0\n", weeknum);
	mindays = 0;
  }

  if (date->wMonth == 1)
  {
    /* calculate all those exceptions for january */
    st.wDay = st.wMonth = 1;
    weeknum1 = MONTHCAL_CalculateDayOfWeek(&st, FALSE);
    if ((infoPtr->firstDay - weeknum1) % 7 > mindays)
	weeknum = 1;
    else
    {
	weeknum = 0;
	for(i = 0; i < 11; i++)
	   weeknum += MONTHCAL_MonthLength(i+1, date->wYear - 1);

	weeknum  += startofprescal + 7;
	weeknum  /= 7;
	st.wYear -= 1;
	weeknum1  = MONTHCAL_CalculateDayOfWeek(&st, FALSE);
	if ((infoPtr->firstDay - weeknum1) % 7 > mindays) weeknum++;
    }
  }
  else
  {
    weeknum = 0;
    for(i = 0; i < prev_month - 1; i++)
	weeknum += MONTHCAL_MonthLength(i+1, date->wYear);

    weeknum += startofprescal + 7;
    weeknum /= 7;
    st.wDay = st.wMonth = 1;
    weeknum1 = MONTHCAL_CalculateDayOfWeek(&st, FALSE);
    if ((infoPtr->firstDay - weeknum1) % 7 > mindays) weeknum++;
  }

  r = infoPtr->calendars[calIdx].weeknums;

  /* erase whole week numbers area */
  hbr = CreateSolidBrush(infoPtr->colors[MCSC_MONTHBK]);
  FillRect(hdc, &r, hbr);
  DeleteObject(hbr);

  /* reduce rectangle to one week number */
  r.bottom = r.top + infoPtr->height_increment;

  for(i = 0; i < 6; i++) {
    if((i == 0) && (weeknum > 50))
    {
        wsprintfW(buf, fmt_weekW, weeknum);
        weeknum = 0;
    }
    else if((i == 5) && (weeknum > 47))
    {
	wsprintfW(buf, fmt_weekW, 1);
    }
    else
	wsprintfW(buf, fmt_weekW, weeknum + i);

    DrawTextW(hdc, buf, -1, &r, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
    OffsetRect(&r, 0, infoPtr->height_increment);
  }

  /* line separator for week numbers column */
  MoveToEx(hdc, infoPtr->calendars[calIdx].weeknums.right, infoPtr->calendars[calIdx].weeknums.top + 3 , NULL);
  LineTo(hdc,   infoPtr->calendars[calIdx].weeknums.right, infoPtr->calendars[calIdx].weeknums.bottom);
}

/* bottom today date */
static void MONTHCAL_PaintTodayTitle(const MONTHCAL_INFO *infoPtr, HDC hdc, const PAINTSTRUCT *ps)
{
  if(!(infoPtr->dwStyle & MCS_NOTODAY))  {
    static const WCHAR todayW[] = { 'T','o','d','a','y',':',0 };
    static const WCHAR fmt_todayW[] = { '%','s',' ','%','s',0 };
    WCHAR buf_todayW[30], buf_dateW[20], buf[80];
    RECT rtoday;

    if(!(infoPtr->dwStyle & MCS_NOTODAYCIRCLE)) {
      SYSTEMTIME fake_st;

      MONTHCAL_GetMaxDate(infoPtr, &fake_st);
      /* this is always safe cause next month will never fully fit calendar */
      fake_st.wDay += 1;
      MONTHCAL_CircleDay(infoPtr, hdc, &fake_st);
    }
    if (!LoadStringW(COMCTL32_hModule, IDM_TODAY, buf_todayW, countof(buf_todayW)))
    {
	WARN("Can't load resource\n");
	strcpyW(buf_todayW, todayW);
    }
    MONTHCAL_CalcDayRect(infoPtr, &rtoday, 1, 6);
    GetDateFormatW(LOCALE_USER_DEFAULT, DATE_SHORTDATE, &infoPtr->todaysDate, NULL,
                                                        buf_dateW, countof(buf_dateW));
    SelectObject(hdc, infoPtr->hBoldFont);

    wsprintfW(buf, fmt_todayW, buf_todayW, buf_dateW);
    DrawTextW(hdc, buf, -1, &rtoday, DT_CALCRECT | DT_LEFT | DT_VCENTER | DT_SINGLELINE);
    DrawTextW(hdc, buf, -1, &rtoday, DT_LEFT | DT_VCENTER | DT_SINGLELINE);

    SelectObject(hdc, infoPtr->hFont);
  }
}

/* today mark + focus */
static void MONTHCAL_PaintFocusAndCircle(const MONTHCAL_INFO *infoPtr, HDC hdc, const PAINTSTRUCT *ps)
{
  if((infoPtr->minSel.wMonth == infoPtr->todaysDate.wMonth) &&
     (infoPtr->minSel.wYear  == infoPtr->todaysDate.wYear) &&
    !(infoPtr->dwStyle & MCS_NOTODAYCIRCLE))
  {
    MONTHCAL_CircleDay(infoPtr, hdc, &infoPtr->todaysDate);
  }

  if(!MONTHCAL_IsDateEqual(&infoPtr->focusedSel, &st_null))
  {
    RECT r;
    MONTHCAL_CalcPosFromDay(infoPtr, &infoPtr->focusedSel, &r);
    DrawFocusRect(hdc, &r);
  }
}

/* paint a calendar area */
static void MONTHCAL_PaintCalendar(const MONTHCAL_INFO *infoPtr, HDC hdc, const PAINTSTRUCT *ps, INT calIdx)
{
  const SYSTEMTIME *date = &infoPtr->calendars[calIdx].month;
  INT prev_month, i, j, length;
  RECT r, fill_bk_rect;
  SYSTEMTIME st;
  WCHAR buf[80];
  HBRUSH hbr;
  int mask;

  /* fill whole days area - from week days area to today note rectangle */
  fill_bk_rect = infoPtr->calendars[calIdx].wdays;
  fill_bk_rect.bottom = infoPtr->calendars[calIdx].days.bottom +
                          (infoPtr->todayrect.bottom - infoPtr->todayrect.top);

  hbr = CreateSolidBrush(infoPtr->colors[MCSC_MONTHBK]);
  FillRect(hdc, &fill_bk_rect, hbr);
  DeleteObject(hbr);

  /* draw line under day abbreviations */
  MoveToEx(hdc, infoPtr->calendars[calIdx].days.left + 3,
                infoPtr->calendars[calIdx].title.bottom + infoPtr->textHeight + 1, NULL);
  LineTo(hdc, infoPtr->calendars[calIdx].days.right - 3,
              infoPtr->calendars[calIdx].title.bottom + infoPtr->textHeight + 1);

  prev_month = date->wMonth - 1;
  if (prev_month == 0) prev_month = 12;

  infoPtr->calendars[calIdx].wdays.left = infoPtr->calendars[calIdx].days.left =
      infoPtr->calendars[calIdx].weeknums.right;

  /* 1. draw day abbreviations */
  SelectObject(hdc, infoPtr->hFont);
  SetBkColor(hdc, infoPtr->colors[MCSC_MONTHBK]);
  SetTextColor(hdc, infoPtr->colors[MCSC_TRAILINGTEXT]);
  /* rectangle to draw a single day abbreviation within */
  r = infoPtr->calendars[calIdx].wdays;
  r.right = r.left + infoPtr->width_increment;

  i = infoPtr->firstDay;
  for(j = 0; j < 7; j++) {
    GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SABBREVDAYNAME1 + (i+j+6)%7, buf, countof(buf));
    DrawTextW(hdc, buf, strlenW(buf), &r, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
    OffsetRect(&r, infoPtr->width_increment, 0);
  }

  /* 2. previous and next months */
  if (!(infoPtr->dwStyle & MCS_NOTRAILINGDATES) && (calIdx == 0 || calIdx == infoPtr->cal_num - 1))
  {
    SYSTEMTIME st_max;

    SetTextColor(hdc, infoPtr->colors[MCSC_TRAILINGTEXT]);

    /* draw prev month */
    if (calIdx == 0)
    {
      MONTHCAL_GetMinDate(infoPtr, &st);
      mask = 1 << (st.wDay-1);
      length = MONTHCAL_MonthLength(prev_month, date->wYear);

      while(st.wDay <= length)
      {
        MONTHCAL_DrawDay(infoPtr, hdc, &st, infoPtr->monthdayState[0] & mask, ps);
        mask <<= 1;
        st.wDay++;
      }
    }

    /* draw next month */
    if (calIdx == infoPtr->cal_num - 1)
    {
      st = *date;
      st.wDay = 1;
      MONTHCAL_GetNextMonth(&st);
      MONTHCAL_GetMaxDate(infoPtr, &st_max);
      mask = 1;

      while(st.wDay <= st_max.wDay)
      {
        MONTHCAL_DrawDay(infoPtr, hdc, &st, infoPtr->monthdayState[2] & mask, ps);
        mask <<= 1;
        st.wDay++;
      }
    }
  }

  /* 3. current month */
  SetTextColor(hdc, infoPtr->colors[MCSC_TEXT]);
  st = *date;
  st.wDay = 1;
  mask = 1;
  length = MONTHCAL_MonthLength(date->wMonth, date->wYear);
  while(st.wDay <= length)
  {
    MONTHCAL_DrawDay(infoPtr, hdc, &st, infoPtr->monthdayState[1] & mask, ps);
    mask <<= 1;
    st.wDay++;
  }
}

static void MONTHCAL_Refresh(MONTHCAL_INFO *infoPtr, HDC hdc, const PAINTSTRUCT *ps)
{
  COLORREF old_text_clr, old_bk_clr;
  HFONT old_font;
  INT i;

  old_text_clr = SetTextColor(hdc, comctl32_color.clrWindowText);
  old_bk_clr   = GetBkColor(hdc);
  old_font     = GetCurrentObject(hdc, OBJ_FONT);

  for (i = 0; i < infoPtr->cal_num; i++)
  {
    RECT *title = &infoPtr->calendars[i].title;
    RECT r;

    /* draw title, redraw all its elements */
    if (IntersectRect(&r, &(ps->rcPaint), title))
        MONTHCAL_PaintTitle(infoPtr, hdc, ps, i);

    /* draw calendar area */
    UnionRect(&r, &infoPtr->calendars[i].wdays, &infoPtr->todayrect);
    if (IntersectRect(&r, &(ps->rcPaint), &r))
        MONTHCAL_PaintCalendar(infoPtr, hdc, ps, i);

    /* week numbers */
    MONTHCAL_PaintWeeknumbers(infoPtr, hdc, ps, i);
  }

  /* focus and today rectangle */
  MONTHCAL_PaintFocusAndCircle(infoPtr, hdc, ps);

  /* today at the bottom left */
  MONTHCAL_PaintTodayTitle(infoPtr, hdc, ps);

  /* navigation buttons */
  MONTHCAL_PaintButton(infoPtr, hdc, DIRECTION_BACKWARD);
  MONTHCAL_PaintButton(infoPtr, hdc, DIRECTION_FORWARD);

  /* restore context */
  SetBkColor(hdc, old_bk_clr);
  SelectObject(hdc, old_font);
  SetTextColor(hdc, old_text_clr);
}

static LRESULT
MONTHCAL_GetMinReqRect(const MONTHCAL_INFO *infoPtr, RECT *rect)
{
  TRACE("rect %p\n", rect);

  if(!rect) return FALSE;

  *rect = infoPtr->calendars[0].title;
  rect->bottom = infoPtr->calendars[0].days.bottom + infoPtr->todayrect.bottom -
                 infoPtr->todayrect.top;

  AdjustWindowRect(rect, infoPtr->dwStyle, FALSE);

  /* minimal rectangle is zero based */
  OffsetRect(rect, -rect->left, -rect->top);

  TRACE("%s\n", wine_dbgstr_rect(rect));

  return TRUE;
}

static COLORREF
MONTHCAL_GetColor(const MONTHCAL_INFO *infoPtr, UINT index)
{
  TRACE("%p, %d\n", infoPtr, index);

  if (index > MCSC_TRAILINGTEXT) return -1;
  return infoPtr->colors[index];
}

static LRESULT
MONTHCAL_SetColor(MONTHCAL_INFO *infoPtr, UINT index, COLORREF color)
{
  COLORREF prev;

  TRACE("%p, %d: color %08x\n", infoPtr, index, color);

  if (index > MCSC_TRAILINGTEXT) return -1;

  prev = infoPtr->colors[index];
  infoPtr->colors[index] = color;

  InvalidateRect(infoPtr->hwndSelf, NULL, index == MCSC_BACKGROUND ? TRUE : FALSE);
  return prev;
}

static LRESULT
MONTHCAL_GetMonthDelta(const MONTHCAL_INFO *infoPtr)
{
  TRACE("\n");

  if(infoPtr->delta)
    return infoPtr->delta;
  else
    return infoPtr->visible;
}


static LRESULT
MONTHCAL_SetMonthDelta(MONTHCAL_INFO *infoPtr, INT delta)
{
  INT prev = infoPtr->delta;

  TRACE("delta %d\n", delta);

  infoPtr->delta = delta;
  return prev;
}


static inline LRESULT
MONTHCAL_GetFirstDayOfWeek(const MONTHCAL_INFO *infoPtr)
{
  int day;

  /* convert from SYSTEMTIME to locale format */
  day = (infoPtr->firstDay >= 0) ? (infoPtr->firstDay+6)%7 : infoPtr->firstDay;

  return MAKELONG(day, infoPtr->firstDaySet);
}


/* Sets the first day of the week that will appear in the control
 *
 *
 * PARAMETERS:
 *  [I] infoPtr : valid pointer to control data
 *  [I] day : day number to set as new first day (0 == Monday,...,6 == Sunday)
 *
 *
 * RETURN VALUE:
 *  Low word contains previous first day,
 *  high word indicates was first day forced with this message before or is
 *  locale difined (TRUE - was forced, FALSE - wasn't).
 *
 * FIXME: this needs to be implemented properly in MONTHCAL_Refresh()
 * FIXME: we need more error checking here
 */
static LRESULT
MONTHCAL_SetFirstDayOfWeek(MONTHCAL_INFO *infoPtr, INT day)
{
  LRESULT prev = MONTHCAL_GetFirstDayOfWeek(infoPtr);
  int new_day;

  TRACE("%d\n", day);

  if(day == -1)
  {
    WCHAR buf[80];

    GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_IFIRSTDAYOFWEEK, buf, countof(buf));
    TRACE("%s %d\n", debugstr_w(buf), strlenW(buf));

    new_day = atoiW(buf);

    infoPtr->firstDaySet = FALSE;
  }
  else if(day >= 7)
  {
    new_day = 6; /* max first day allowed */
    infoPtr->firstDaySet = TRUE;
  }
  else
  {
    /* Native behaviour for that case is broken: invalid date number >31
       got displayed at (0,0) position, current month starts always from
       (1,0) position. Should be implemented here as well only if there's
       nothing else to do. */
    if (day < -1)
      FIXME("No bug compatibility for day=%d\n", day);

    new_day = day;
    infoPtr->firstDaySet = TRUE;
  }

  /* convert from locale to SYSTEMTIME format */
  infoPtr->firstDay = (new_day >= 0) ? (++new_day) % 7 : new_day;

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

  return prev;
}


static LRESULT
MONTHCAL_GetMonthRange(const MONTHCAL_INFO *infoPtr, DWORD flag, SYSTEMTIME *st)
{
  TRACE("flag=%d, st=%p\n", flag, st);

  if(st)
  {
    switch (flag) {
    case GMR_VISIBLE:
    {
        st[0] = infoPtr->calendars[0].month;
        st[1] = infoPtr->calendars[infoPtr->cal_num-1].month;

        if (st[0].wMonth == min_allowed_date.wMonth &&
            st[0].wYear  == min_allowed_date.wYear)
        {
            st[0].wDay = min_allowed_date.wDay;
        }
        else
            st[0].wDay = 1;
        MONTHCAL_CalculateDayOfWeek(&st[0], TRUE);

        st[1].wDay = MONTHCAL_MonthLength(st[1].wMonth, st[1].wYear);
        MONTHCAL_CalculateDayOfWeek(&st[1], TRUE);

        return infoPtr->cal_num;
    }
    case GMR_DAYSTATE:
    {
        /*FIXME: currently multicalendar feature isn't implemented,
                 min date from previous month and max date from next one returned */
        MONTHCAL_GetMinDate(infoPtr, &st[0]);
        MONTHCAL_GetMaxDate(infoPtr, &st[1]);
        break;
    }
    default:
        WARN("Unknown flag value, got %d\n", flag);
    }
  }

  return infoPtr->monthRange;
}


static LRESULT
MONTHCAL_GetMaxTodayWidth(const MONTHCAL_INFO *infoPtr)
{
  return(infoPtr->todayrect.right - infoPtr->todayrect.left);
}


static LRESULT
MONTHCAL_SetRange(MONTHCAL_INFO *infoPtr, SHORT limits, SYSTEMTIME *range)
{
    FILETIME ft_min, ft_max;

    TRACE("%x %p\n", limits, range);

    if ((limits & GDTR_MIN && !MONTHCAL_ValidateDate(&range[0])) ||
        (limits & GDTR_MAX && !MONTHCAL_ValidateDate(&range[1])))
        return FALSE;

    if (limits & GDTR_MIN)
    {
        if (!MONTHCAL_ValidateTime(&range[0]))
            MONTHCAL_CopyTime(&infoPtr->todaysDate, &range[0]);

        infoPtr->minDate = range[0];
        infoPtr->rangeValid |= GDTR_MIN;
    }
    if (limits & GDTR_MAX)
    {
        if (!MONTHCAL_ValidateTime(&range[1]))
            MONTHCAL_CopyTime(&infoPtr->todaysDate, &range[1]);

        infoPtr->maxDate = range[1];
        infoPtr->rangeValid |= GDTR_MAX;
    }

    /* Only one limit set - we are done */
    if ((infoPtr->rangeValid & (GDTR_MIN | GDTR_MAX)) != (GDTR_MIN | GDTR_MAX))
        return TRUE;

    SystemTimeToFileTime(&infoPtr->maxDate, &ft_max);
    SystemTimeToFileTime(&infoPtr->minDate, &ft_min);

    if (CompareFileTime(&ft_min, &ft_max) >= 0)
    {
        if ((limits & (GDTR_MIN | GDTR_MAX)) == (GDTR_MIN | GDTR_MAX))
        {
            /* Native swaps limits only when both limits are being set. */
            SYSTEMTIME st_tmp = infoPtr->minDate;
            infoPtr->minDate  = infoPtr->maxDate;
            infoPtr->maxDate  = st_tmp;
        }
        else
        {
            /* reset the other limit */
            if (limits & GDTR_MIN) infoPtr->maxDate = st_null;
            if (limits & GDTR_MAX) infoPtr->minDate = st_null;
            infoPtr->rangeValid &= limits & GDTR_MIN ? ~GDTR_MAX : ~GDTR_MIN;
        }
    }

    return TRUE;
}


static LRESULT
MONTHCAL_GetRange(const MONTHCAL_INFO *infoPtr, SYSTEMTIME *range)
{
  TRACE("%p\n", range);

  if(!range) return FALSE;

  range[1] = infoPtr->maxDate;
  range[0] = infoPtr->minDate;

  return infoPtr->rangeValid;
}


static LRESULT
MONTHCAL_SetDayState(const MONTHCAL_INFO *infoPtr, INT months, MONTHDAYSTATE *states)
{
  TRACE("%p %d %p\n", infoPtr, months, states);
  if(months != infoPtr->monthRange) return 0;

  memcpy(infoPtr->monthdayState, states, months*sizeof(MONTHDAYSTATE));

  return 1;
}

static LRESULT
MONTHCAL_GetCurSel(const MONTHCAL_INFO *infoPtr, SYSTEMTIME *curSel)
{
  TRACE("%p\n", curSel);
  if(!curSel) return FALSE;
  if(infoPtr->dwStyle & MCS_MULTISELECT) return FALSE;

  *curSel = infoPtr->minSel;
  TRACE("%d/%d/%d\n", curSel->wYear, curSel->wMonth, curSel->wDay);
  return TRUE;
}

static LRESULT
MONTHCAL_SetCurSel(MONTHCAL_INFO *infoPtr, SYSTEMTIME *curSel)
{
  SYSTEMTIME prev = infoPtr->minSel;
  WORD day;

  TRACE("%p\n", curSel);
  if(!curSel) return FALSE;
  if(infoPtr->dwStyle & MCS_MULTISELECT) return FALSE;

  if(!MONTHCAL_ValidateDate(curSel)) return FALSE;
  /* exit earlier if selection equals current */
  if (MONTHCAL_IsDateEqual(&infoPtr->minSel, curSel)) return TRUE;

  if(!MONTHCAL_IsDateInValidRange(infoPtr, curSel, FALSE)) return FALSE;

  infoPtr->calendars[0].month = *curSel;
  infoPtr->minSel = *curSel;
  infoPtr->maxSel = *curSel;

  /* if selection is still in current month, reduce rectangle */
  day = prev.wDay;
  prev.wDay = curSel->wDay;
  if (MONTHCAL_IsDateEqual(&prev, curSel))
  {
    RECT r_prev, r_new;

    prev.wDay = day;
    MONTHCAL_CalcPosFromDay(infoPtr, &prev, &r_prev);
    MONTHCAL_CalcPosFromDay(infoPtr, curSel, &r_new);

    InvalidateRect(infoPtr->hwndSelf, &r_prev, FALSE);
    InvalidateRect(infoPtr->hwndSelf, &r_new,  FALSE);
  }
  else
    InvalidateRect(infoPtr->hwndSelf, NULL, FALSE);

  return TRUE;
}


static LRESULT
MONTHCAL_GetMaxSelCount(const MONTHCAL_INFO *infoPtr)
{
  return infoPtr->maxSelCount;
}


static LRESULT
MONTHCAL_SetMaxSelCount(MONTHCAL_INFO *infoPtr, INT max)
{
  TRACE("%d\n", max);

  if(!(infoPtr->dwStyle & MCS_MULTISELECT)) return FALSE;
  if(max <= 0) return FALSE;

  infoPtr->maxSelCount = max;

  return TRUE;
}


static LRESULT
MONTHCAL_GetSelRange(const MONTHCAL_INFO *infoPtr, SYSTEMTIME *range)
{
  TRACE("%p\n", range);

  if(!range) return FALSE;

  if(infoPtr->dwStyle & MCS_MULTISELECT)
  {
    range[1] = infoPtr->maxSel;
    range[0] = infoPtr->minSel;
    TRACE("[min,max]=[%d %d]\n", infoPtr->minSel.wDay, infoPtr->maxSel.wDay);
    return TRUE;
  }

  return FALSE;
}


static LRESULT
MONTHCAL_SetSelRange(MONTHCAL_INFO *infoPtr, SYSTEMTIME *range)
{
  TRACE("%p\n", range);

  if(!range) return FALSE;

  if(infoPtr->dwStyle & MCS_MULTISELECT)
  {
    SYSTEMTIME old_range[2];

    /* adjust timestamps */
    if(!MONTHCAL_ValidateTime(&range[0]))
      MONTHCAL_CopyTime(&infoPtr->todaysDate, &range[0]);
    if(!MONTHCAL_ValidateTime(&range[1]))
      MONTHCAL_CopyTime(&infoPtr->todaysDate, &range[1]);

    /* maximum range exceeded */
    if(!MONTHCAL_IsSelRangeValid(infoPtr, &range[0], &range[1], NULL)) return FALSE;

    old_range[0] = infoPtr->minSel;
    old_range[1] = infoPtr->maxSel;

    /* swap if min > max */
    if(MONTHCAL_CompareSystemTime(&range[0], &range[1]) <= 0)
    {
      infoPtr->minSel = range[0];
      infoPtr->maxSel = range[1];
    }
    else
    {
      infoPtr->minSel = range[1];
      infoPtr->maxSel = range[0];
    }
    infoPtr->calendars[0].month = infoPtr->minSel;

    /* update day of week */
    MONTHCAL_CalculateDayOfWeek(&infoPtr->minSel, TRUE);
    MONTHCAL_CalculateDayOfWeek(&infoPtr->maxSel, TRUE);

    /* redraw if bounds changed */
    /* FIXME: no actual need to redraw everything */
    if(!MONTHCAL_IsDateEqual(&old_range[0], &range[0]) ||
       !MONTHCAL_IsDateEqual(&old_range[1], &range[1]))
    {
       InvalidateRect(infoPtr->hwndSelf, NULL, FALSE);
    }

    TRACE("[min,max]=[%d %d]\n", infoPtr->minSel.wDay, infoPtr->maxSel.wDay);
    return TRUE;
  }

  return FALSE;
}


static LRESULT
MONTHCAL_GetToday(const MONTHCAL_INFO *infoPtr, SYSTEMTIME *today)
{
  TRACE("%p\n", today);

  if(!today) return FALSE;
  *today = infoPtr->todaysDate;
  return TRUE;
}

/* Internal helper for MCM_SETTODAY handler and auto update timer handler
 *
 * RETURN VALUE
 *
 *  TRUE  - today date changed
 *  FALSE - today date isn't changed
 */
static BOOL
MONTHCAL_UpdateToday(MONTHCAL_INFO *infoPtr, const SYSTEMTIME *today)
{
  RECT new_r, old_r;

  if(MONTHCAL_IsDateEqual(today, &infoPtr->todaysDate)) return FALSE;

  MONTHCAL_CalcPosFromDay(infoPtr, &infoPtr->todaysDate, &old_r);
  MONTHCAL_CalcPosFromDay(infoPtr, today, &new_r);

  infoPtr->todaysDate = *today;

  /* only two days need redrawing */
  InvalidateRect(infoPtr->hwndSelf, &old_r, FALSE);
  InvalidateRect(infoPtr->hwndSelf, &new_r, FALSE);
  return TRUE;
}

/* MCM_SETTODAT handler */
static LRESULT
MONTHCAL_SetToday(MONTHCAL_INFO *infoPtr, const SYSTEMTIME *today)
{
  TRACE("%p\n", today);

  if(!today) return FALSE;

  /* remember if date was set successfully */
  if(MONTHCAL_UpdateToday(infoPtr, today)) infoPtr->todaySet = TRUE;

  return TRUE;
}

/* returns calendar index containing specified point, or -1 if it's background */
static INT MONTHCAL_GetCalendarFromPoint(const MONTHCAL_INFO *infoPtr, const POINT *pt)
{
  RECT r;
  INT i;

  for (i = 0; i < infoPtr->cal_num; i++)
  {
     /* whole bounding rectangle allows some optimization to compute */
     r.left   = infoPtr->calendars[i].title.left;
     r.top    = infoPtr->calendars[i].title.top;
     r.bottom = infoPtr->calendars[i].days.bottom;
     r.right  = infoPtr->calendars[i].days.right;

     if (PtInRect(&r, *pt)) return i;
  }

  return -1;
}

static inline UINT fill_hittest_info(const MCHITTESTINFO *src, MCHITTESTINFO *dest)
{
  dest->uHit = src->uHit;
  dest->st = src->st;

  if (dest->cbSize == sizeof(MCHITTESTINFO))
    memcpy(&dest->rc, &src->rc, sizeof(MCHITTESTINFO) - MCHITTESTINFO_V1_SIZE);

  return src->uHit;
}

static LRESULT
MONTHCAL_HitTest(const MONTHCAL_INFO *infoPtr, MCHITTESTINFO *lpht)
{
  INT day, wday, wnum, calIdx;
  MCHITTESTINFO htinfo;
  SYSTEMTIME ht_month;
  UINT x, y;

  if(!lpht || lpht->cbSize < MCHITTESTINFO_V1_SIZE) return -1;

  x = lpht->pt.x;
  y = lpht->pt.y;

  htinfo.st = st_null;

  /* we should preserve passed fields if hit area doesn't need them */
  if (lpht->cbSize == sizeof(MCHITTESTINFO))
    memcpy(&htinfo.rc, &lpht->rc, sizeof(MCHITTESTINFO) - MCHITTESTINFO_V1_SIZE);

  /* Comment in for debugging...
  TRACE("%d %d wd[%d %d %d %d] d[%d %d %d %d] t[%d %d %d %d] wn[%d %d %d %d]\n", x, y,
	infoPtr->wdays.left, infoPtr->wdays.right,
	infoPtr->wdays.top, infoPtr->wdays.bottom,
	infoPtr->days.left, infoPtr->days.right,
	infoPtr->days.top, infoPtr->days.bottom,
	infoPtr->todayrect.left, infoPtr->todayrect.right,
	infoPtr->todayrect.top, infoPtr->todayrect.bottom,
	infoPtr->weeknums.left, infoPtr->weeknums.right,
	infoPtr->weeknums.top, infoPtr->weeknums.bottom);
  */

  /* guess in what calendar we are */
  calIdx = MONTHCAL_GetCalendarFromPoint(infoPtr, &lpht->pt);
  if (calIdx == -1)
  {
    if (PtInRect(&infoPtr->todayrect, lpht->pt))
    {
      htinfo.uHit = MCHT_TODAYLINK;
      htinfo.rc = infoPtr->todayrect;
    }
    else
      /* outside of calendar area? What's left must be background :-) */
      htinfo.uHit = MCHT_CALENDARBK;

    return fill_hittest_info(&htinfo, lpht);
  }

  ht_month = infoPtr->calendars[calIdx].month;

  /* are we in the header? */
  if (PtInRect(&infoPtr->calendars[calIdx].title, lpht->pt)) {
    /* FIXME: buttons hittesting could be optimized cause maximum
              two calendars have buttons */
    if (calIdx == 0 && PtInRect(&infoPtr->titlebtnprev, lpht->pt))
    {
      htinfo.uHit = MCHT_TITLEBTNPREV;
      htinfo.rc = infoPtr->titlebtnprev;
    }
    else if (PtInRect(&infoPtr->titlebtnnext, lpht->pt))
    {
      htinfo.uHit = MCHT_TITLEBTNNEXT;
      htinfo.rc = infoPtr->titlebtnnext;
    }
    else if (PtInRect(&infoPtr->calendars[calIdx].titlemonth, lpht->pt))
    {
      htinfo.uHit = MCHT_TITLEMONTH;
      htinfo.rc = infoPtr->calendars[calIdx].titlemonth;
      htinfo.iOffset = calIdx;
    }
    else if (PtInRect(&infoPtr->calendars[calIdx].titleyear, lpht->pt))
    {
      htinfo.uHit = MCHT_TITLEYEAR;
      htinfo.rc = infoPtr->calendars[calIdx].titleyear;
      htinfo.iOffset = calIdx;
    }
    else
    {
      htinfo.uHit = MCHT_TITLE;
      htinfo.rc = infoPtr->calendars[calIdx].title;
      htinfo.iOffset = calIdx;
    }

    return fill_hittest_info(&htinfo, lpht);
  }

  /* days area (including week days and week numbers */
  day = MONTHCAL_CalcDayFromPos(infoPtr, x, y, &wday, &wnum);
  if (PtInRect(&infoPtr->calendars[calIdx].wdays, lpht->pt))
  {
    htinfo.uHit = MCHT_CALENDARDAY;
    htinfo.iOffset = calIdx;
    htinfo.st.wYear  = ht_month.wYear;
    htinfo.st.wMonth = (day < 1) ? ht_month.wMonth -1 : ht_month.wMonth;
    htinfo.st.wDay   = (day < 1) ?
      MONTHCAL_MonthLength(ht_month.wMonth-1, ht_month.wYear) - day : day;

    MONTHCAL_CalcDayXY(infoPtr, &htinfo.st, &htinfo.iCol, &htinfo.iRow);
  }
  else if(PtInRect(&infoPtr->calendars[calIdx].weeknums, lpht->pt))
  {
    htinfo.uHit = MCHT_CALENDARWEEKNUM;
    htinfo.st.wYear  = ht_month.wYear;
    htinfo.iOffset = calIdx;

    if (day < 1)
    {
      htinfo.st.wMonth = ht_month.wMonth - 1;
      htinfo.st.wDay = MONTHCAL_MonthLength(ht_month.wMonth-1, ht_month.wYear) - day;
    }
    else if (day > MONTHCAL_MonthLength(ht_month.wMonth, ht_month.wYear))
    {
      htinfo.st.wMonth = ht_month.wMonth + 1;
      htinfo.st.wDay = day - MONTHCAL_MonthLength(ht_month.wMonth, ht_month.wYear);
    }
    else
    {
      htinfo.st.wMonth = ht_month.wMonth;
      htinfo.st.wDay = day;
    }
  }
  else if(PtInRect(&infoPtr->calendars[calIdx].days, lpht->pt))
  {
      htinfo.iOffset = calIdx;
      htinfo.st.wYear  = ht_month.wYear;
      htinfo.st.wMonth = ht_month.wMonth;
      if (day < 1)
      {
	  htinfo.uHit = MCHT_CALENDARDATEPREV;
	  MONTHCAL_GetPrevMonth(&htinfo.st);
	  htinfo.st.wDay = MONTHCAL_MonthLength(lpht->st.wMonth, lpht->st.wYear) + day;
      }
      else if (day > MONTHCAL_MonthLength(ht_month.wMonth, ht_month.wYear))
      {
	  htinfo.uHit = MCHT_CALENDARDATENEXT;
	  MONTHCAL_GetNextMonth(&htinfo.st);
	  htinfo.st.wDay = day - MONTHCAL_MonthLength(ht_month.wMonth, ht_month.wYear);
      }
      else
      {
	htinfo.uHit = MCHT_CALENDARDATE;
	htinfo.st.wDay = day;
      }

      MONTHCAL_CalcDayXY(infoPtr, &htinfo.st, &htinfo.iCol, &htinfo.iRow);
      MONTHCAL_CalcDayRect(infoPtr, &htinfo.rc, htinfo.iCol, htinfo.iRow);
      /* always update day of week */
      MONTHCAL_CalculateDayOfWeek(&htinfo.st, TRUE);
  }

  return fill_hittest_info(&htinfo, lpht);
}

/* MCN_GETDAYSTATE notification helper */
static void MONTHCAL_NotifyDayState(MONTHCAL_INFO *infoPtr)
{
  if(infoPtr->dwStyle & MCS_DAYSTATE) {
    NMDAYSTATE nmds;

    nmds.nmhdr.hwndFrom = infoPtr->hwndSelf;
    nmds.nmhdr.idFrom   = GetWindowLongPtrW(infoPtr->hwndSelf, GWLP_ID);
    nmds.nmhdr.code     = MCN_GETDAYSTATE;
    nmds.cDayState	= infoPtr->monthRange;
    nmds.prgDayState	= Alloc(infoPtr->monthRange * sizeof(MONTHDAYSTATE));

    nmds.stStart = infoPtr->todaysDate;
    nmds.stStart.wYear  = infoPtr->minSel.wYear;
    nmds.stStart.wMonth = infoPtr->minSel.wMonth;
    nmds.stStart.wDay = 1;

    SendMessageW(infoPtr->hwndNotify, WM_NOTIFY, nmds.nmhdr.idFrom, (LPARAM)&nmds);
    memcpy(infoPtr->monthdayState, nmds.prgDayState, infoPtr->monthRange*sizeof(MONTHDAYSTATE));

    Free(nmds.prgDayState);
  }
}

/* no valid range check performed */
static void MONTHCAL_Scroll(MONTHCAL_INFO *infoPtr, INT delta)
{
  INT i, selIdx = -1;

  for(i = 0; i < infoPtr->cal_num; i++)
  {
    /* save selection position to shift it later */
    if (selIdx == -1 && MONTHCAL_CompareMonths(&infoPtr->minSel, &infoPtr->calendars[i].month) == 0)
      selIdx = i;

    MONTHCAL_GetMonth(&infoPtr->calendars[i].month, delta);
  }

  /* selection is always shifted to first calendar */
  if(infoPtr->dwStyle & MCS_MULTISELECT)
  {
    SYSTEMTIME range[2];

    MONTHCAL_GetSelRange(infoPtr, range);
    MONTHCAL_GetMonth(&range[0], delta - selIdx);
    MONTHCAL_GetMonth(&range[1], delta - selIdx);
    MONTHCAL_SetSelRange(infoPtr, range);
  }
  else
  {
    SYSTEMTIME st = infoPtr->minSel;

    MONTHCAL_GetMonth(&st, delta - selIdx);
    MONTHCAL_SetCurSel(infoPtr, &st);
  }
}

static void MONTHCAL_GoToMonth(MONTHCAL_INFO *infoPtr, enum nav_direction direction)
{
  INT delta = infoPtr->delta ? infoPtr->delta : infoPtr->cal_num;
  SYSTEMTIME st;

  TRACE("%s\n", direction == DIRECTION_BACKWARD ? "back" : "fwd");

  /* check if change allowed by range set */
  if(direction == DIRECTION_BACKWARD)
  {
    st = infoPtr->calendars[0].month;
    MONTHCAL_GetMonth(&st, -delta);
  }
  else
  {
    st = infoPtr->calendars[infoPtr->cal_num-1].month;
    MONTHCAL_GetMonth(&st, delta);
  }

  if(!MONTHCAL_IsDateInValidRange(infoPtr, &st, FALSE)) return;

  MONTHCAL_Scroll(infoPtr, direction == DIRECTION_BACKWARD ? -delta : delta);
  MONTHCAL_NotifyDayState(infoPtr);
  MONTHCAL_NotifySelectionChange(infoPtr);
}

static LRESULT
MONTHCAL_RButtonUp(MONTHCAL_INFO *infoPtr, LPARAM lParam)
{
  static const WCHAR todayW[] = { 'G','o',' ','t','o',' ','T','o','d','a','y',':',0 };
  HMENU hMenu;
  POINT menupoint;
  WCHAR buf[32];

  hMenu = CreatePopupMenu();
  if (!LoadStringW(COMCTL32_hModule, IDM_GOTODAY, buf, countof(buf)))
  {
      WARN("Can't load resource\n");
      strcpyW(buf, todayW);
  }
  AppendMenuW(hMenu, MF_STRING|MF_ENABLED, 1, buf);
  menupoint.x = (short)LOWORD(lParam);
  menupoint.y = (short)HIWORD(lParam);
  ClientToScreen(infoPtr->hwndSelf, &menupoint);
  if( TrackPopupMenu(hMenu, TPM_RIGHTBUTTON | TPM_NONOTIFY | TPM_RETURNCMD,
		     menupoint.x, menupoint.y, 0, infoPtr->hwndSelf, NULL))
  {
      infoPtr->calendars[0].month = infoPtr->todaysDate;
      infoPtr->minSel = infoPtr->todaysDate;
      infoPtr->maxSel = infoPtr->todaysDate;
      InvalidateRect(infoPtr->hwndSelf, NULL, FALSE);
  }

  return 0;
}

/***
 * DESCRIPTION:
 * Subclassed edit control windproc function
 *
 * PARAMETER(S):
 * [I] hwnd : the edit window handle
 * [I] uMsg : the message that is to be processed
 * [I] wParam : first message parameter
 * [I] lParam : second message parameter
 *
 */
static LRESULT CALLBACK EditWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    MONTHCAL_INFO *infoPtr = (MONTHCAL_INFO *)GetWindowLongPtrW(GetParent(hwnd), 0);

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

    switch (uMsg)
    {
	case WM_GETDLGCODE:
	  return DLGC_WANTARROWS | DLGC_WANTALLKEYS;

	case WM_DESTROY:
	{
	    WNDPROC editProc = infoPtr->EditWndProc;
	    infoPtr->EditWndProc = NULL;
	    SetWindowLongPtrW(hwnd, GWLP_WNDPROC, (DWORD_PTR)editProc);
	    return CallWindowProcW(editProc, hwnd, uMsg, wParam, lParam);
	}

	case WM_KILLFOCUS:
	    break;

	case WM_KEYDOWN:
	    if ((VK_ESCAPE == (INT)wParam) || (VK_RETURN == (INT)wParam))
		break;

	default:
	    return CallWindowProcW(infoPtr->EditWndProc, hwnd, uMsg, wParam, lParam);
    }

    SendMessageW(infoPtr->hWndYearUpDown, WM_CLOSE, 0, 0);
    SendMessageW(hwnd, WM_CLOSE, 0, 0);
    return 0;
}

/* creates updown control and edit box */
static void MONTHCAL_EditYear(MONTHCAL_INFO *infoPtr, INT calIdx)
{
    RECT *rc = &infoPtr->calendars[calIdx].titleyear;
    RECT *title = &infoPtr->calendars[calIdx].title;

    infoPtr->hWndYearEdit =
	CreateWindowExW(0, WC_EDITW, 0, WS_VISIBLE | WS_CHILD | ES_READONLY,
			rc->left + 3, (title->bottom + title->top - infoPtr->textHeight) / 2,
			rc->right - rc->left + 4,
			infoPtr->textHeight, infoPtr->hwndSelf,
			NULL, NULL, NULL);

    SendMessageW(infoPtr->hWndYearEdit, WM_SETFONT, (WPARAM)infoPtr->hBoldFont, TRUE);

    infoPtr->hWndYearUpDown =
	CreateWindowExW(0, UPDOWN_CLASSW, 0,
			WS_VISIBLE | WS_CHILD | UDS_SETBUDDYINT | UDS_NOTHOUSANDS | UDS_ARROWKEYS,
			rc->right + 7, (title->bottom + title->top - infoPtr->textHeight) / 2,
			18, infoPtr->textHeight, infoPtr->hwndSelf,
			NULL, NULL, NULL);

    /* attach edit box */
    SendMessageW(infoPtr->hWndYearUpDown, UDM_SETRANGE, 0,
                 MAKELONG(max_allowed_date.wYear, min_allowed_date.wYear));
    SendMessageW(infoPtr->hWndYearUpDown, UDM_SETBUDDY, (WPARAM)infoPtr->hWndYearEdit, 0);
    SendMessageW(infoPtr->hWndYearUpDown, UDM_SETPOS, 0, infoPtr->calendars[calIdx].month.wYear);

    /* subclass edit box */
    infoPtr->EditWndProc = (WNDPROC)SetWindowLongPtrW(infoPtr->hWndYearEdit,
                                  GWLP_WNDPROC, (DWORD_PTR)EditWndProc);

    SetFocus(infoPtr->hWndYearEdit);
}

static LRESULT
MONTHCAL_LButtonDown(MONTHCAL_INFO *infoPtr, LPARAM lParam)
{
  MCHITTESTINFO ht;
  DWORD hit;

  /* Actually we don't need input focus for calendar, this is used to kill
     year updown and its buddy edit box */
  if (IsWindow(infoPtr->hWndYearUpDown))
  {
      SetFocus(infoPtr->hwndSelf);
      return 0;
  }

  SetCapture(infoPtr->hwndSelf);

  ht.cbSize = sizeof(MCHITTESTINFO);
  ht.pt.x = (short)LOWORD(lParam);
  ht.pt.y = (short)HIWORD(lParam);

  hit = MONTHCAL_HitTest(infoPtr, &ht);

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

  switch(hit)
  {
  case MCHT_TITLEBTNNEXT:
    MONTHCAL_GoToMonth(infoPtr, DIRECTION_FORWARD);
    infoPtr->status = MC_NEXTPRESSED;
    SetTimer(infoPtr->hwndSelf, MC_PREVNEXTMONTHTIMER, MC_PREVNEXTMONTHDELAY, 0);
    InvalidateRect(infoPtr->hwndSelf, NULL, FALSE);
    return 0;

  case MCHT_TITLEBTNPREV:
    MONTHCAL_GoToMonth(infoPtr, DIRECTION_BACKWARD);
    infoPtr->status = MC_PREVPRESSED;
    SetTimer(infoPtr->hwndSelf, MC_PREVNEXTMONTHTIMER, MC_PREVNEXTMONTHDELAY, 0);
    InvalidateRect(infoPtr->hwndSelf, NULL, FALSE);
    return 0;

  case MCHT_TITLEMONTH:
  {
    HMENU hMenu = CreatePopupMenu();
    WCHAR buf[32];
    POINT menupoint;
    INT i;

    for (i = 0; i < 12; i++)
    {
	GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SMONTHNAME1+i, buf, countof(buf));
	AppendMenuW(hMenu, MF_STRING|MF_ENABLED, i + 1, buf);
    }
    menupoint.x = ht.pt.x;
    menupoint.y = ht.pt.y;
    ClientToScreen(infoPtr->hwndSelf, &menupoint);
    i = TrackPopupMenu(hMenu,TPM_LEFTALIGN | TPM_NONOTIFY | TPM_RIGHTBUTTON | TPM_RETURNCMD,
		       menupoint.x, menupoint.y, 0, infoPtr->hwndSelf, NULL);

    if ((i > 0) && (i < 13) && infoPtr->calendars[ht.iOffset].month.wMonth != i)
    {
        INT delta = i - infoPtr->calendars[ht.iOffset].month.wMonth;
        SYSTEMTIME st;

        /* check if change allowed by range set */
        st = delta < 0 ? infoPtr->calendars[0].month :
                         infoPtr->calendars[infoPtr->cal_num-1].month;
        MONTHCAL_GetMonth(&st, delta);

        if (MONTHCAL_IsDateInValidRange(infoPtr, &st, FALSE))
        {
            MONTHCAL_Scroll(infoPtr, delta);
            MONTHCAL_NotifyDayState(infoPtr);
            MONTHCAL_NotifySelectionChange(infoPtr);
            InvalidateRect(infoPtr->hwndSelf, NULL, FALSE);
        }
    }
    return 0;
  }
  case MCHT_TITLEYEAR:
  {
    MONTHCAL_EditYear(infoPtr, ht.iOffset);
    return 0;
  }
  case MCHT_TODAYLINK:
  {
    infoPtr->calendars[0].month = infoPtr->todaysDate;
    infoPtr->minSel = infoPtr->todaysDate;
    infoPtr->maxSel = infoPtr->todaysDate;
    InvalidateRect(infoPtr->hwndSelf, NULL, FALSE);

    MONTHCAL_NotifySelectionChange(infoPtr);
    MONTHCAL_NotifySelect(infoPtr);
    return 0;
  }
  case MCHT_CALENDARDATENEXT:
  case MCHT_CALENDARDATEPREV:
  case MCHT_CALENDARDATE:
  {
    SYSTEMTIME st[2];

    MONTHCAL_CopyDate(&ht.st, &infoPtr->firstSel);

    st[0] = st[1] = ht.st;
    /* clear selection range */
    MONTHCAL_SetSelRange(infoPtr, st);

    infoPtr->status = MC_SEL_LBUTDOWN;
    MONTHCAL_SetDayFocus(infoPtr, &ht.st);
    return 0;
  }
  }

  return 1;
}


static LRESULT
MONTHCAL_LButtonUp(MONTHCAL_INFO *infoPtr, LPARAM lParam)
{
  NMHDR nmhdr;
  MCHITTESTINFO ht;
  DWORD hit;

  TRACE("\n");

  if(infoPtr->status & (MC_PREVPRESSED | MC_NEXTPRESSED)) {
    RECT *r;

    KillTimer(infoPtr->hwndSelf, MC_PREVNEXTMONTHTIMER);
    r = infoPtr->status & MC_PREVPRESSED ? &infoPtr->titlebtnprev : &infoPtr->titlebtnnext;
    infoPtr->status &= ~(MC_PREVPRESSED | MC_NEXTPRESSED);

    InvalidateRect(infoPtr->hwndSelf, r, FALSE);
  }

  ReleaseCapture();

  /* always send NM_RELEASEDCAPTURE notification */
  nmhdr.hwndFrom = infoPtr->hwndSelf;
  nmhdr.idFrom   = GetWindowLongPtrW(infoPtr->hwndSelf, GWLP_ID);
  nmhdr.code     = NM_RELEASEDCAPTURE;
  TRACE("Sent notification from %p to %p\n", infoPtr->hwndSelf, infoPtr->hwndNotify);

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

  if(!(infoPtr->status & MC_SEL_LBUTDOWN)) return 0;

  ht.cbSize = sizeof(MCHITTESTINFO);
  ht.pt.x = (short)LOWORD(lParam);
  ht.pt.y = (short)HIWORD(lParam);
  hit = MONTHCAL_HitTest(infoPtr, &ht);

  infoPtr->status = MC_SEL_LBUTUP;
  MONTHCAL_SetDayFocus(infoPtr, NULL);

  if((hit & MCHT_CALENDARDATE) == MCHT_CALENDARDATE)
  {
    SYSTEMTIME sel = infoPtr->minSel;

    /* will be invalidated here */
    MONTHCAL_SetCurSel(infoPtr, &ht.st);

    /* send MCN_SELCHANGE only if new date selected */
    if (!MONTHCAL_IsDateEqual(&sel, &ht.st))
        MONTHCAL_NotifySelectionChange(infoPtr);

    MONTHCAL_NotifySelect(infoPtr);
  }

  return 0;
}


static LRESULT
MONTHCAL_Timer(MONTHCAL_INFO *infoPtr, WPARAM id)
{
  TRACE("%ld\n", id);

  switch(id) {
  case MC_PREVNEXTMONTHTIMER:
    if(infoPtr->status & MC_NEXTPRESSED) MONTHCAL_GoToMonth(infoPtr, DIRECTION_FORWARD);
    if(infoPtr->status & MC_PREVPRESSED) MONTHCAL_GoToMonth(infoPtr, DIRECTION_BACKWARD);
    InvalidateRect(infoPtr->hwndSelf, NULL, FALSE);
    break;
  case MC_TODAYUPDATETIMER:
  {
    SYSTEMTIME st;

    if(infoPtr->todaySet) return 0;

    GetLocalTime(&st);
    MONTHCAL_UpdateToday(infoPtr, &st);

    /* notification sent anyway */
    MONTHCAL_NotifySelectionChange(infoPtr);

    return 0;
  }
  default:
    ERR("got unknown timer %ld\n", id);
    break;
  }

  return 0;
}


static LRESULT
MONTHCAL_MouseMove(MONTHCAL_INFO *infoPtr, LPARAM lParam)
{
  MCHITTESTINFO ht;
  SYSTEMTIME st_ht;
  INT hit;
  RECT r;

  if(!(infoPtr->status & MC_SEL_LBUTDOWN)) return 0;

  ht.cbSize = sizeof(MCHITTESTINFO);
  ht.pt.x = (short)LOWORD(lParam);
  ht.pt.y = (short)HIWORD(lParam);

  hit = MONTHCAL_HitTest(infoPtr, &ht);

  /* not on the calendar date numbers? bail out */
  TRACE("hit:%x\n",hit);
  if((hit & MCHT_CALENDARDATE) != MCHT_CALENDARDATE)
  {
    MONTHCAL_SetDayFocus(infoPtr, NULL);
    return 0;
  }

  st_ht = ht.st;

  /* if pointer is over focused day still there's nothing to do */
  if(!MONTHCAL_SetDayFocus(infoPtr, &ht.st)) return 0;

  MONTHCAL_CalcPosFromDay(infoPtr, &ht.st, &r);

  if(infoPtr->dwStyle & MCS_MULTISELECT) {
    SYSTEMTIME st[2];

    MONTHCAL_GetSelRange(infoPtr, st);

    /* If we're still at the first selected date and range is empty, return.
       If range isn't empty we should change range to a single firstSel */
    if(MONTHCAL_IsDateEqual(&infoPtr->firstSel, &st_ht) &&
       MONTHCAL_IsDateEqual(&st[0], &st[1])) goto done;

    MONTHCAL_IsSelRangeValid(infoPtr, &st_ht, &infoPtr->firstSel, &st_ht);

    st[0] = infoPtr->firstSel;
    /* we should overwrite timestamp here */
    MONTHCAL_CopyDate(&st_ht, &st[1]);

    /* bounds will be swapped here if needed */
    MONTHCAL_SetSelRange(infoPtr, st);

    return 0;
  }

done:

  /* FIXME: this should specify a rectangle containing only the days that changed
     using InvalidateRect */
  InvalidateRect(infoPtr->hwndSelf, NULL, FALSE);

  return 0;
}


static LRESULT
MONTHCAL_Paint(MONTHCAL_INFO *infoPtr, HDC hdc_paint)
{
  HDC hdc;
  PAINTSTRUCT ps;

  if (hdc_paint)
  {
    GetClientRect(infoPtr->hwndSelf, &ps.rcPaint);
    hdc = hdc_paint;
  }
  else
    hdc = BeginPaint(infoPtr->hwndSelf, &ps);

  MONTHCAL_Refresh(infoPtr, hdc, &ps);
  if (!hdc_paint) EndPaint(infoPtr->hwndSelf, &ps);
  return 0;
}

static LRESULT
MONTHCAL_EraseBkgnd(const MONTHCAL_INFO *infoPtr, HDC hdc)
{
  HBRUSH hbr;
  RECT rc;

  if (!GetClipBox(hdc, &rc)) return FALSE;

  /* fill background */
  hbr = CreateSolidBrush (infoPtr->colors[MCSC_BACKGROUND]);
  FillRect(hdc, &rc, hbr);
  DeleteObject(hbr);

  return TRUE;
}

static LRESULT
MONTHCAL_PrintClient(MONTHCAL_INFO *infoPtr, HDC hdc, DWORD options)
{
  FIXME("Partial Stub: (hdc=%p options=0x%08x)\n", hdc, options);

  if ((options & PRF_CHECKVISIBLE) && !IsWindowVisible(infoPtr->hwndSelf))
      return 0;

  if (options & PRF_ERASEBKGND)
      MONTHCAL_EraseBkgnd(infoPtr, hdc);

  if (options & PRF_CLIENT)
      MONTHCAL_Paint(infoPtr, hdc);

  return 0;
}

static LRESULT
MONTHCAL_SetFocus(const MONTHCAL_INFO *infoPtr)
{
  TRACE("\n");

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

  return 0;
}

/* sets the size information */
static void MONTHCAL_UpdateSize(MONTHCAL_INFO *infoPtr)
{
  static const WCHAR O0W[] = { '0','0',0 };
  HDC hdc = GetDC(infoPtr->hwndSelf);
  RECT *title=&infoPtr->calendars[0].title;
  RECT *prev=&infoPtr->titlebtnprev;
  RECT *next=&infoPtr->titlebtnnext;
  RECT *titlemonth=&infoPtr->calendars[0].titlemonth;
  RECT *titleyear=&infoPtr->calendars[0].titleyear;
  RECT *wdays=&infoPtr->calendars[0].wdays;
  RECT *weeknumrect=&infoPtr->calendars[0].weeknums;
  RECT *days=&infoPtr->calendars[0].days;
  RECT *todayrect=&infoPtr->todayrect;
  SIZE size, sz;
  TEXTMETRICW tm;
  HFONT currentFont;
  INT xdiv, dx, dy, i;
  RECT rcClient;
  WCHAR buff[80];

  GetClientRect(infoPtr->hwndSelf, &rcClient);

  currentFont = SelectObject(hdc, infoPtr->hFont);

  /* get the height and width of each day's text */
  GetTextMetricsW(hdc, &tm);
  infoPtr->textHeight = tm.tmHeight + tm.tmExternalLeading + tm.tmInternalLeading;

  /* find largest abbreviated day name for current locale */
  size.cx = sz.cx = 0;
  for (i = 0; i < 7; i++)
  {
      if(GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SABBREVDAYNAME1 + i,
                        buff, countof(buff)))
      {
          GetTextExtentPoint32W(hdc, buff, lstrlenW(buff), &sz);
          if (sz.cx > size.cx) size.cx = sz.cx;
      }
      else /* locale independent fallback on failure */
      {
          static const WCHAR SunW[] = { 'S','u','n',0 };

          GetTextExtentPoint32W(hdc, SunW, lstrlenW(SunW), &size);
          break;
      }
  }

  infoPtr->textWidth = size.cx + 2;

  /* recalculate the height and width increments and offsets */
  GetTextExtentPoint32W(hdc, O0W, 2, &size);

  xdiv = (infoPtr->dwStyle & MCS_WEEKNUMBERS) ? 8 : 7;

  infoPtr->width_increment  = size.cx * 2 + 4;
  infoPtr->height_increment = infoPtr->textHeight;

  /* calculate title area */
  title->top    = 0;
  title->bottom = 3 * infoPtr->height_increment / 2;
  title->left   = 0;
  title->right  = infoPtr->width_increment * xdiv;

  /* set the dimensions of the next and previous buttons and center */
  /* the month text vertically */
  prev->top    = next->top    = title->top + 4;
  prev->bottom = next->bottom = title->bottom - 4;
  prev->left   = title->left + 4;
  prev->right  = prev->left + (title->bottom - title->top);
  next->right  = title->right - 4;
  next->left   = next->right - (title->bottom - title->top);

  /* titlemonth->left and right change based upon the current month */
  /* and are recalculated in refresh as the current month may change */
  /* without the control being resized */
  titlemonth->top    = titleyear->top    = title->top    + (infoPtr->height_increment)/2;
  titlemonth->bottom = titleyear->bottom = title->bottom - (infoPtr->height_increment)/2;

  /* setup the dimensions of the rectangle we draw the names of the */
  /* days of the week in */
  weeknumrect->left = 0;

  if(infoPtr->dwStyle & MCS_WEEKNUMBERS)
    weeknumrect->right = prev->right;
  else
    weeknumrect->right = weeknumrect->left;

  wdays->left   = days->left   = weeknumrect->right;
  wdays->right  = days->right  = wdays->left + 7 * infoPtr->width_increment;
  wdays->top    = title->bottom;
  wdays->bottom = wdays->top + infoPtr->height_increment;

  days->top    = weeknumrect->top = wdays->bottom;
  days->bottom = weeknumrect->bottom = days->top + 6 * infoPtr->height_increment;

  todayrect->left   = 0;
  todayrect->right  = title->right;
  todayrect->top    = days->bottom;
  todayrect->bottom = days->bottom + infoPtr->height_increment;

  /* offset all rectangles to center in client area */
  dx = (rcClient.right  - title->right) / 2;
  dy = (rcClient.bottom - todayrect->bottom) / 2;

  /* if calendar doesn't fit client area show it at left/top bounds */
  if (title->left + dx < 0) dx = 0;
  if (title->top  + dy < 0) dy = 0;

  if (dx != 0 || dy != 0)
  {
    OffsetRect(title, dx, dy);
    OffsetRect(prev,  dx, dy);
    OffsetRect(next,  dx, dy);
    OffsetRect(titlemonth, dx, dy);
    OffsetRect(titleyear, dx, dy);
    OffsetRect(wdays, dx, dy);
    OffsetRect(weeknumrect, dx, dy);
    OffsetRect(days, dx, dy);
    OffsetRect(todayrect, dx, dy);
  }

  TRACE("dx=%d dy=%d client[%s] title[%s] wdays[%s] days[%s] today[%s]\n",
	infoPtr->width_increment,infoPtr->height_increment,
        wine_dbgstr_rect(&rcClient),
        wine_dbgstr_rect(title),
        wine_dbgstr_rect(wdays),
        wine_dbgstr_rect(days),
        wine_dbgstr_rect(todayrect));

  /* restore the originally selected font */
  SelectObject(hdc, currentFont);

  ReleaseDC(infoPtr->hwndSelf, hdc);
}

static LRESULT MONTHCAL_Size(MONTHCAL_INFO *infoPtr, int Width, int Height)
{
  TRACE("(width=%d, height=%d)\n", Width, Height);

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

  return 0;
}

static LRESULT MONTHCAL_GetFont(const MONTHCAL_INFO *infoPtr)
{
    return (LRESULT)infoPtr->hFont;
}

static LRESULT MONTHCAL_SetFont(MONTHCAL_INFO *infoPtr, HFONT hFont, BOOL redraw)
{
    HFONT hOldFont;
    LOGFONTW lf;

    if (!hFont) return 0;

    hOldFont = infoPtr->hFont;
    infoPtr->hFont = hFont;

    GetObjectW(infoPtr->hFont, sizeof(lf), &lf);
    lf.lfWeight = FW_BOLD;
    infoPtr->hBoldFont = CreateFontIndirectW(&lf);

    MONTHCAL_UpdateSize(infoPtr);

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

    return (LRESULT)hOldFont;
}

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

static INT MONTHCAL_StyleChanged(MONTHCAL_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;

    /* make room for week numbers */
    if ((lpss->styleNew ^ lpss->styleOld) & MCS_WEEKNUMBERS)
        MONTHCAL_UpdateSize(infoPtr);

    return 0;
}

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

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

    return 0;
}

/* FIXME: check whether dateMin/dateMax need to be adjusted. */
static LRESULT
MONTHCAL_Create(HWND hwnd, LPCREATESTRUCTW lpcs)
{
  MONTHCAL_INFO *infoPtr;

  /* allocate memory for info structure */
  infoPtr = Alloc(sizeof(MONTHCAL_INFO));
  SetWindowLongPtrW(hwnd, 0, (DWORD_PTR)infoPtr);

  if (infoPtr == NULL) {
    ERR("could not allocate info memory!\n");
    return 0;
  }

  infoPtr->hwndSelf = hwnd;
  infoPtr->hwndNotify = lpcs->hwndParent;
  infoPtr->dwStyle  = GetWindowLongW(hwnd, GWL_STYLE);
  infoPtr->calendars = Alloc(sizeof(CALENDAR_INFO));
  if (!infoPtr->calendars) goto fail;

  infoPtr->cal_num = 1;

  MONTHCAL_SetFont(infoPtr, GetStockObject(DEFAULT_GUI_FONT), FALSE);

  /* initialize info structure */
  /* FIXME: calculate systemtime ->> localtime(substract timezoneinfo) */

  GetLocalTime(&infoPtr->todaysDate);
  MONTHCAL_SetFirstDayOfWeek(infoPtr, -1);

  infoPtr->maxSelCount   = (infoPtr->dwStyle & MCS_MULTISELECT) ? 7 : 1;
  infoPtr->monthRange    = 3;

  infoPtr->monthdayState = Alloc(infoPtr->monthRange * sizeof(MONTHDAYSTATE));
  if (!infoPtr->monthdayState) goto fail;

  infoPtr->colors[MCSC_BACKGROUND]   = comctl32_color.clrWindow;
  infoPtr->colors[MCSC_TEXT]         = comctl32_color.clrWindowText;
  infoPtr->colors[MCSC_TITLEBK]      = comctl32_color.clrActiveCaption;
  infoPtr->colors[MCSC_TITLETEXT]    = comctl32_color.clrWindow;
  infoPtr->colors[MCSC_MONTHBK]      = comctl32_color.clrWindow;
  infoPtr->colors[MCSC_TRAILINGTEXT] = comctl32_color.clrGrayText;

  infoPtr->minSel = infoPtr->todaysDate;
  infoPtr->maxSel = infoPtr->todaysDate;
  infoPtr->calendars[0].month = infoPtr->todaysDate;
  infoPtr->isUnicode = TRUE;

  /* call MONTHCAL_UpdateSize to set all of the dimensions */
  /* of the control */
  MONTHCAL_UpdateSize(infoPtr);

  /* today auto update timer, to be freed only on control destruction */
  SetTimer(infoPtr->hwndSelf, MC_TODAYUPDATETIMER, MC_TODAYUPDATEDELAY, 0);

  OpenThemeData (infoPtr->hwndSelf, themeClass);

  return 0;

fail:
  Free(infoPtr->monthdayState);
  Free(infoPtr->calendars);
  Free(infoPtr);
  return 0;
}

static LRESULT
MONTHCAL_Destroy(MONTHCAL_INFO *infoPtr)
{
  /* free month calendar info data */
  Free(infoPtr->monthdayState);
  Free(infoPtr->calendars);
  SetWindowLongPtrW(infoPtr->hwndSelf, 0, 0);

  CloseThemeData (GetWindowTheme (infoPtr->hwndSelf));
  
  Free(infoPtr);
  return 0;
}

/*
 * Handler for WM_NOTIFY messages
 */
static LRESULT
MONTHCAL_Notify(MONTHCAL_INFO *infoPtr, NMHDR *hdr)
{
  /* notification from year edit updown */
  if (hdr->code == UDN_DELTAPOS)
  {
    NMUPDOWN *nmud = (NMUPDOWN*)hdr;

    if (hdr->hwndFrom == infoPtr->hWndYearUpDown && nmud->iDelta)
    {
      /* year value limits are set up explicitly after updown creation */
      MONTHCAL_Scroll(infoPtr, 12 * nmud->iDelta);
      MONTHCAL_NotifyDayState(infoPtr);
      MONTHCAL_NotifySelectionChange(infoPtr);
    }
  }
  return 0;
}

static inline BOOL
MONTHCAL_SetUnicodeFormat(MONTHCAL_INFO *infoPtr, BOOL isUnicode)
{
  BOOL prev = infoPtr->isUnicode;
  infoPtr->isUnicode = isUnicode;
  return prev;
}

static inline BOOL
MONTHCAL_GetUnicodeFormat(const MONTHCAL_INFO *infoPtr)
{
  return infoPtr->isUnicode;
}

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

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

  if (!infoPtr && (uMsg != WM_CREATE))
    return DefWindowProcW(hwnd, uMsg, wParam, lParam);
  switch(uMsg)
  {
  case MCM_GETCURSEL:
    return MONTHCAL_GetCurSel(infoPtr, (LPSYSTEMTIME)lParam);

  case MCM_SETCURSEL:
    return MONTHCAL_SetCurSel(infoPtr, (LPSYSTEMTIME)lParam);

  case MCM_GETMAXSELCOUNT:
    return MONTHCAL_GetMaxSelCount(infoPtr);

  case MCM_SETMAXSELCOUNT:
    return MONTHCAL_SetMaxSelCount(infoPtr, wParam);

  case MCM_GETSELRANGE:
    return MONTHCAL_GetSelRange(infoPtr, (LPSYSTEMTIME)lParam);

  case MCM_SETSELRANGE:
    return MONTHCAL_SetSelRange(infoPtr, (LPSYSTEMTIME)lParam);

  case MCM_GETMONTHRANGE:
    return MONTHCAL_GetMonthRange(infoPtr, wParam, (SYSTEMTIME*)lParam);

  case MCM_SETDAYSTATE:
    return MONTHCAL_SetDayState(infoPtr, (INT)wParam, (LPMONTHDAYSTATE)lParam);

  case MCM_GETMINREQRECT:
    return MONTHCAL_GetMinReqRect(infoPtr, (LPRECT)lParam);

  case MCM_GETCOLOR:
    return MONTHCAL_GetColor(infoPtr, wParam);

  case MCM_SETCOLOR:
    return MONTHCAL_SetColor(infoPtr, wParam, (COLORREF)lParam);

  case MCM_GETTODAY:
    return MONTHCAL_GetToday(infoPtr, (LPSYSTEMTIME)lParam);

  case MCM_SETTODAY:
    return MONTHCAL_SetToday(infoPtr, (LPSYSTEMTIME)lParam);

  case MCM_HITTEST:
    return MONTHCAL_HitTest(infoPtr, (PMCHITTESTINFO)lParam);

  case MCM_GETFIRSTDAYOFWEEK:
    return MONTHCAL_GetFirstDayOfWeek(infoPtr);

  case MCM_SETFIRSTDAYOFWEEK:
    return MONTHCAL_SetFirstDayOfWeek(infoPtr, (INT)lParam);

  case MCM_GETRANGE:
    return MONTHCAL_GetRange(infoPtr, (LPSYSTEMTIME)lParam);

  case MCM_SETRANGE:
    return MONTHCAL_SetRange(infoPtr, (SHORT)wParam, (LPSYSTEMTIME)lParam);

  case MCM_GETMONTHDELTA:
    return MONTHCAL_GetMonthDelta(infoPtr);

  case MCM_SETMONTHDELTA:
    return MONTHCAL_SetMonthDelta(infoPtr, wParam);

  case MCM_GETMAXTODAYWIDTH:
    return MONTHCAL_GetMaxTodayWidth(infoPtr);

  case MCM_SETUNICODEFORMAT:
    return MONTHCAL_SetUnicodeFormat(infoPtr, (BOOL)wParam);

  case MCM_GETUNICODEFORMAT:
    return MONTHCAL_GetUnicodeFormat(infoPtr);

  case WM_GETDLGCODE:
    return DLGC_WANTARROWS | DLGC_WANTCHARS;

  case WM_RBUTTONUP:
    return MONTHCAL_RButtonUp(infoPtr, lParam);

  case WM_LBUTTONDOWN:
    return MONTHCAL_LButtonDown(infoPtr, lParam);

  case WM_MOUSEMOVE:
    return MONTHCAL_MouseMove(infoPtr, lParam);

  case WM_LBUTTONUP:
    return MONTHCAL_LButtonUp(infoPtr, lParam);

  case WM_PAINT:
    return MONTHCAL_Paint(infoPtr, (HDC)wParam);

  case WM_PRINTCLIENT:
    return MONTHCAL_PrintClient(infoPtr, (HDC)wParam, (DWORD)lParam);

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

  case WM_SETFOCUS:
    return MONTHCAL_SetFocus(infoPtr);

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

  case WM_NOTIFY:
    return MONTHCAL_Notify(infoPtr, (NMHDR*)lParam);

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

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

  case WM_GETFONT:
    return MONTHCAL_GetFont(infoPtr);

  case WM_TIMER:
    return MONTHCAL_Timer(infoPtr, wParam);
    
  case WM_THEMECHANGED:
    return theme_changed (infoPtr);

  case WM_DESTROY:
    return MONTHCAL_Destroy(infoPtr);

  case WM_SYSCOLORCHANGE:
    COMCTL32_RefreshSysColors();
    return 0;

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

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

  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
MONTHCAL_Register(void)
{
  WNDCLASSW wndClass;

  ZeroMemory(&wndClass, sizeof(WNDCLASSW));
  wndClass.style         = CS_GLOBALCLASS;
  wndClass.lpfnWndProc   = MONTHCAL_WindowProc;
  wndClass.cbClsExtra    = 0;
  wndClass.cbWndExtra    = sizeof(MONTHCAL_INFO *);
  wndClass.hCursor       = LoadCursorW(0, (LPWSTR)IDC_ARROW);
  wndClass.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
  wndClass.lpszClassName = MONTHCAL_CLASSW;

  RegisterClassW(&wndClass);
}


void
MONTHCAL_Unregister(void)
{
    UnregisterClassW(MONTHCAL_CLASSW, NULL);
}
