/*
 * 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-2011 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
 *    -- 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 "vssym32.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 IDs */
#define MC_TODAYUPDATETIMER     2

#define MC_CALENDAR_PADDING     6

#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)

enum CachedPen
{
    PenRed = 0,
    PenText,
    PenLast
};

enum CachedBrush
{
    BrushTitle = 0,
    BrushMonth,
    BrushBackground,
    BrushLast
};

/* 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];
    HBRUSH      brushes[BrushLast];
    HPEN        pens[PenLast];

    HFONT	hFont;
    HFONT	hBoldFont;
    int		textHeight;
    int		height_increment;
    int		width_increment;
    INT		delta;	/* scroll rate; # of months that the */
                        /* control moves when user clicks a scroll button */
    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 */

    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;
    SIZE dim;           /* [cx,cy] - dimensions of calendars matrix, row/column count */
} 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, /* wDayOfWeek */ 0, /* wDay */ 31 };
static const SYSTEMTIME min_allowed_date = { /* wYear */ 1752, /* wMonth */ 9,  /* wDayOfWeek */ 0, /* wDay */ 14 };

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

/* helper functions  */
static inline INT MONTHCAL_GetCalCount(const MONTHCAL_INFO *infoPtr)
{
   return infoPtr->dim.cx * infoPtr->dim.cy;
}

/* 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.stSelStart.wDayOfWeek = 0;
    if(infoPtr->dwStyle & MCS_MULTISELECT){
        nmsc.stSelEnd = infoPtr->maxSel;
        nmsc.stSelEnd.wDayOfWeek = 0;
    }
    else
        nmsc.stSelEnd = st_null;

    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.stSelStart.wDayOfWeek = 0;
    if(infoPtr->dwStyle & MCS_MULTISELECT){
        nmsc.stSelEnd = infoPtr->maxSel;
        nmsc.stSelEnd.wDayOfWeek = 0;
    }
    else
        nmsc.stSelEnd = st_null;

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

static inline int MONTHCAL_MonthDiff(const SYSTEMTIME *left, const SYSTEMTIME *right)
{
    return (right->wYear - left->wYear)*12 + right->wMonth - left->wMonth;
}

/* 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->wDay == 0 || 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, already validated values expected.
 */
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 within 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;
        }
     }

     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;
}

/* 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/subtract '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)
{
  MONTHCAL_GetMonth(date, 1);
}

/* properly updates date to point on prev month */
static inline void MONTHCAL_GetPrevMonth(SYSTEMTIME *date)
{
  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[MONTHCAL_GetCalCount(infoPtr)-1].month;
  INT first_day;

  *date = *lt_month;
  st = *lt_month;

  /* day of week of first day of current month */
  st.wDay = 1;
  first_day = MONTHCAL_CalculateDayOfWeek(&st, FALSE);

  MONTHCAL_GetNextMonth(date);
  MONTHCAL_GetPrevMonth(&st);

  /* last calendar starts with some date from previous month that not displayed */
  st.wDay = MONTHCAL_MonthLength(st.wMonth, st.wYear) +
             (infoPtr->firstDay - first_day) % 7 + 1;
  if (st.wDay > MONTHCAL_MonthLength(st.wMonth, st.wYear)) st.wDay -= 7;

  /* 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, column and day in the calendar,
   'day == 0' means the last day of the last month. */
static int MONTHCAL_GetDayFromPos(const MONTHCAL_INFO *infoPtr, POINT pt, INT calIdx)
{
  SYSTEMTIME st = infoPtr->calendars[calIdx].month;
  int firstDay, col, row;
  RECT client;

  GetClientRect(infoPtr->hwndSelf, &client);

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

  col = (pt.x - infoPtr->calendars[calIdx].days.left ) / infoPtr->width_increment;
  row = (pt.y - infoPtr->calendars[calIdx].days.top  ) / infoPtr->height_increment;

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

/* Get day position for given date and calendar
 *
 * PARAMETERS
 *
 *  [I] infoPtr : pointer to control data
 *  [I] date : date value
 *  [O] col : day column (zero based)
 *  [O] row : week column (zero based)
 *  [I] calIdx : calendar index
 */
static void MONTHCAL_GetDayPos(const MONTHCAL_INFO *infoPtr, const SYSTEMTIME *date,
    INT *col, INT *row, INT calIdx)
{
  SYSTEMTIME st = infoPtr->calendars[calIdx].month;
  INT first;

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

  if (calIdx == 0 || calIdx == MONTHCAL_GetCalCount(infoPtr)-1) {
      const SYSTEMTIME *cal = &infoPtr->calendars[calIdx].month;
      LONG cmp = MONTHCAL_CompareMonths(date, &st);

      /* previous month */
      if (cmp == -1) {
        *col = (first - MONTHCAL_MonthLength(date->wMonth, cal->wYear) + date->wDay) % 7;
        *row = 0;
        return;
      }

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

  *col = (date->wDay + first) % 7;
  *row = (date->wDay + first - *col) / 7;
}

/* returns bounding box for day in given position in given calendar */
static inline void MONTHCAL_GetDayRectI(const MONTHCAL_INFO *infoPtr, RECT *r,
  INT col, INT row, INT calIdx)
{
  r->left   = infoPtr->calendars[calIdx].days.left + col * infoPtr->width_increment;
  r->right  = r->left + infoPtr->width_increment;
  r->top    = infoPtr->calendars[calIdx].days.top  + row * infoPtr->height_increment;
  r->bottom = r->top + infoPtr->textHeight;
}

/* Returns bounding box for given date
 *
 * NOTE: when calendar index is unknown pass -1
 */
static BOOL MONTHCAL_GetDayRect(const MONTHCAL_INFO *infoPtr, const SYSTEMTIME *date, RECT *r, INT calIdx)
{
  INT col, row;

  if (!MONTHCAL_ValidateDate(date))
  {
      SetRectEmpty(r);
      return FALSE;
  }

  if (calIdx == -1)
  {
      INT cmp = MONTHCAL_CompareMonths(date, &infoPtr->calendars[0].month);

      if (cmp <= 0)
          calIdx = 0;
      else
      {
          cmp = MONTHCAL_CompareMonths(date, &infoPtr->calendars[MONTHCAL_GetCalCount(infoPtr)-1].month);
          if (cmp >= 0)
              calIdx = MONTHCAL_GetCalCount(infoPtr)-1;
          else
          {
              for (calIdx = 1; calIdx < MONTHCAL_GetCalCount(infoPtr)-1; calIdx++)
                  if (MONTHCAL_CompareMonths(date, &infoPtr->calendars[calIdx].month) == 0)
                      break;
          }
      }
  }

  MONTHCAL_GetDayPos(infoPtr, date, &col, &row, calIdx);
  MONTHCAL_GetDayRectI(infoPtr, r, col, row, calIdx);

  return TRUE;
}

static LRESULT
MONTHCAL_GetMonthRange(const MONTHCAL_INFO *infoPtr, DWORD flag, SYSTEMTIME *st)
{
  INT range;

  TRACE("flag=%d, st=%p\n", flag, st);

  switch (flag) {
  case GMR_VISIBLE:
  {
      if (st)
      {
          st[0] = infoPtr->calendars[0].month;
          st[1] = infoPtr->calendars[MONTHCAL_GetCalCount(infoPtr)-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);
      }

      range = MONTHCAL_GetCalCount(infoPtr);
      break;
  }
  case GMR_DAYSTATE:
  {
      if (st)
      {
          MONTHCAL_GetMinDate(infoPtr, &st[0]);
          MONTHCAL_GetMaxDate(infoPtr, &st[1]);
      }
      /* include two partially visible months */
      range = MONTHCAL_GetCalCount(infoPtr) + 2;
      break;
  }
  default:
      WARN("Unknown flag value, got %d\n", flag);
      range = 0;
  }

  return range;
}

/* 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 */
    if (MONTHCAL_GetDayRect(infoPtr, &infoPtr->focusedSel, &r, -1))
      InvalidateRect(infoPtr->hwndSelf, &r, FALSE);

    infoPtr->focusedSel = *st;
  }

  /* On set invalidates new day, on reset clears previous focused day. */
  if (MONTHCAL_GetDayRect(infoPtr, &infoPtr->focusedSel, &r, -1))
    InvalidateRect(infoPtr->hwndSelf, &r, FALSE);

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

  return TRUE;
}

/* draw today boundary box for specified rectangle */
static void MONTHCAL_Circle(const MONTHCAL_INFO *infoPtr, HDC hdc, const RECT *r)
{
  HPEN old_pen = SelectObject(hdc, infoPtr->pens[PenRed]);
  HBRUSH old_brush;

  old_brush = SelectObject(hdc, GetStockObject(NULL_BRUSH));
  Rectangle(hdc, r->left, r->top, r->right, r->bottom);

  SelectObject(hdc, old_brush);
  SelectObject(hdc, old_pen);
}

/* Draw today day mark rectangle
 *
 * [I] hdc  : context to draw in
 * [I] date : day to mark with rectangle
 *
 */
static void MONTHCAL_CircleDay(const MONTHCAL_INFO *infoPtr, HDC hdc,
                               const SYSTEMTIME *date)
{
  RECT r;

  MONTHCAL_GetDayRect(infoPtr, date, &r, -1);
  MONTHCAL_Circle(infoPtr, hdc, &r);
}

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;
  COLORREF oldCol = 0;
  COLORREF oldBk  = 0;
  INT old_bkmode, selection;

  /* no need to check styles: when selection is not valid, it is set to zero.
     1 < day < 31, so everything is OK */
  MONTHCAL_GetDayRect(infoPtr, st, &r, -1);
  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]);
    FillRect(hdc, &r, infoPtr->brushes[BrushTitle]);

    selection = 1;
  }
  else
    selection = 0;

  SelectObject(hdc, bold ? infoPtr->hBoldFont : infoPtr->hFont);

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

  if (selection)
  {
    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 mmmmW[] = {'M','M','M','M',0};
  static const WCHAR mmmW[] = {'M','M','M',0};
  static const WCHAR mmW[] = {'M','M',0};
  static const WCHAR fmtyearW[] = {'%','l','d',0};
  static const WCHAR fmtmmW[] = {'%','0','2','d',0};
  static const WCHAR fmtmW[] = {'%','d',0};
  RECT *title = &infoPtr->calendars[calIdx].title;
  const SYSTEMTIME *st = &infoPtr->calendars[calIdx].month;
  WCHAR monthW[80], strW[80], fmtW[80], yearW[6] /* valid year range is 1601-30827 */;
  int yearoffset, monthoffset, shiftX;
  SIZE sz;

  /* fill header box */
  FillRect(hdc, title, infoPtr->brushes[BrushTitle]);

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

  /* draw formatted date string */
  GetDateFormatW(LOCALE_USER_DEFAULT, DATE_YEARMONTH, st, NULL, strW, countof(strW));
  DrawTextW(hdc, strW, strlenW(strW), title, DT_CENTER | DT_VCENTER | DT_SINGLELINE);

  GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SYEARMONTH, fmtW, countof(fmtW));
  wsprintfW(yearW, fmtyearW, st->wYear);

  /* month is trickier as it's possible to have different format pictures, we'll
     test for M, MM, MMM, and MMMM */
  if (strstrW(fmtW, mmmmW))
    GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SMONTHNAME1+st->wMonth-1, monthW, countof(monthW));
  else if (strstrW(fmtW, mmmW))
    GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SABBREVMONTHNAME1+st->wMonth-1, monthW, countof(monthW));
  else if (strstrW(fmtW, mmW))
    wsprintfW(monthW, fmtmmW, st->wMonth);
  else
    wsprintfW(monthW, fmtmW, st->wMonth);

  /* update hit boxes */
  yearoffset = 0;
  while (strW[yearoffset])
  {
    if (!strncmpW(&strW[yearoffset], yearW, strlenW(yearW)))
        break;
    yearoffset++;
  }

  monthoffset = 0;
  while (strW[monthoffset])
  {
    if (!strncmpW(&strW[monthoffset], monthW, strlenW(monthW)))
        break;
    monthoffset++;
  }

  /* for left limits use offsets */
  sz.cx = 0;
  if (yearoffset)
    GetTextExtentPoint32W(hdc, strW, yearoffset, &sz);
  infoPtr->calendars[calIdx].titleyear.left = sz.cx;

  sz.cx = 0;
  if (monthoffset)
    GetTextExtentPoint32W(hdc, strW, monthoffset, &sz);
  infoPtr->calendars[calIdx].titlemonth.left = sz.cx;

  /* for right limits use actual string parts lengths */
  GetTextExtentPoint32W(hdc, &strW[yearoffset], strlenW(yearW), &sz);
  infoPtr->calendars[calIdx].titleyear.right = infoPtr->calendars[calIdx].titleyear.left + sz.cx;

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

  /* Finally translate rectangles to match center aligned string,
     hit rectangles are relative to title rectangle before translation. */
  GetTextExtentPoint32W(hdc, strW, strlenW(strW), &sz);
  shiftX = (title->right - title->left - sz.cx) / 2 + title->left;
  OffsetRect(&infoPtr->calendars[calIdx].titleyear, shiftX, 0);
  OffsetRect(&infoPtr->calendars[calIdx].titlemonth, shiftX, 0);
}

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];
  HPEN old_pen;
  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 countries?)
     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 */
  FillRect(hdc, &r, infoPtr->brushes[BrushMonth]);
  SetTextColor(hdc, infoPtr->colors[MCSC_TITLEBK]);

  /* 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 */
  old_pen = SelectObject(hdc, infoPtr->pens[PenText]);
  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);
  SelectObject(hdc, old_pen);
}

/* bottom today date */
static void MONTHCAL_PaintTodayTitle(const MONTHCAL_INFO *infoPtr, HDC hdc, const PAINTSTRUCT *ps)
{
  static const WCHAR fmt_todayW[] = { '%','s',' ','%','s',0 };
  WCHAR buf_todayW[30], buf_dateW[20], buf[80];
  RECT text_rect, box_rect;
  HFONT old_font;
  INT col;

  if(infoPtr->dwStyle & MCS_NOTODAY) return;

  LoadStringW(COMCTL32_hModule, IDM_TODAY, buf_todayW, countof(buf_todayW));
  col = infoPtr->dwStyle & MCS_NOTODAYCIRCLE ? 0 : 1;
  if (infoPtr->dwStyle & MCS_WEEKNUMBERS) col--;
  /* label is located below first calendar last row */
  MONTHCAL_GetDayRectI(infoPtr, &text_rect, col, 6, infoPtr->dim.cx * infoPtr->dim.cy - infoPtr->dim.cx);
  box_rect = text_rect;

  GetDateFormatW(LOCALE_USER_DEFAULT, DATE_SHORTDATE, &infoPtr->todaysDate, NULL,
                                                      buf_dateW, countof(buf_dateW));
  old_font = SelectObject(hdc, infoPtr->hBoldFont);
  SetTextColor(hdc, infoPtr->colors[MCSC_TEXT]);

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

  if(!(infoPtr->dwStyle & MCS_NOTODAYCIRCLE)) {
    OffsetRect(&box_rect, -infoPtr->width_increment, 0);
    MONTHCAL_Circle(infoPtr, hdc, &box_rect);
  }

  SelectObject(hdc, old_font);
}

/* today mark + focus */
static void MONTHCAL_PaintFocusAndCircle(const MONTHCAL_INFO *infoPtr, HDC hdc, const PAINTSTRUCT *ps)
{
  /* circle today date if only it's in fully visible month */
  if (!(infoPtr->dwStyle & MCS_NOTODAYCIRCLE))
  {
    INT i;

    for (i = 0; i < MONTHCAL_GetCalCount(infoPtr); i++)
      if (!MONTHCAL_CompareMonths(&infoPtr->todaysDate, &infoPtr->calendars[i].month))
      {
        MONTHCAL_CircleDay(infoPtr, hdc, &infoPtr->todaysDate);
        break;
      }
  }

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

/* months before first calendar month and after last calendar month */
static void MONTHCAL_PaintLeadTrailMonths(const MONTHCAL_INFO *infoPtr, HDC hdc, const PAINTSTRUCT *ps)
{
  INT mask, index;
  UINT length;
  SYSTEMTIME st_max, st;

  if (infoPtr->dwStyle & MCS_NOTRAILINGDATES) return;

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

  /* draw prev month */
  MONTHCAL_GetMinDate(infoPtr, &st);
  mask = 1 << (st.wDay-1);
  /* December and January both 31 days long, so no worries if wrapped */
  length = MONTHCAL_MonthLength(infoPtr->calendars[0].month.wMonth - 1,
                                infoPtr->calendars[0].month.wYear);
  index = 0;
  while(st.wDay <= length)
  {
      MONTHCAL_DrawDay(infoPtr, hdc, &st, infoPtr->monthdayState[index] & mask, ps);
      mask <<= 1;
      st.wDay++;
  }

  /* draw next month */
  st = infoPtr->calendars[MONTHCAL_GetCalCount(infoPtr)-1].month;
  st.wDay = 1;
  MONTHCAL_GetNextMonth(&st);
  MONTHCAL_GetMaxDate(infoPtr, &st_max);
  mask = 1;
  index = MONTHCAL_GetMonthRange(infoPtr, GMR_DAYSTATE, 0)-1;
  while(st.wDay <= st_max.wDay)
  {
      MONTHCAL_DrawDay(infoPtr, hdc, &st, infoPtr->monthdayState[index] & mask, ps);
      mask <<= 1;
      st.wDay++;
  }
}

static int get_localized_dayname(const MONTHCAL_INFO *infoPtr, unsigned int day, WCHAR *buff, unsigned int count)
{
  LCTYPE lctype;

  if (infoPtr->dwStyle & MCS_SHORTDAYSOFWEEK)
      lctype = LOCALE_SSHORTESTDAYNAME1 + day;
  else
      lctype = LOCALE_SABBREVDAYNAME1 + day;

  return GetLocaleInfoW(LOCALE_USER_DEFAULT, lctype, buff, count);
}

/* 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 i, j;
  UINT length;
  RECT r, fill_bk_rect;
  SYSTEMTIME st;
  WCHAR buf[80];
  HPEN old_pen;
  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);

  FillRect(hdc, &fill_bk_rect, infoPtr->brushes[BrushMonth]);

  /* draw line under day abbreviations */
  old_pen = SelectObject(hdc, infoPtr->pens[PenText]);
  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);
  SelectObject(hdc, old_pen);

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

  /* draw day abbreviations */
  SelectObject(hdc, infoPtr->hFont);
  SetBkColor(hdc, infoPtr->colors[MCSC_MONTHBK]);
  SetTextColor(hdc, infoPtr->colors[MCSC_TITLEBK]);
  /* 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++) {
    get_localized_dayname(infoPtr, (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);
  }

  /* draw 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[calIdx+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 < MONTHCAL_GetCalCount(infoPtr); 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);
  }

  /* partially visible months */
  MONTHCAL_PaintLeadTrailMonths(infoPtr, hdc, ps);

  /* 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)
{
  enum CachedBrush type;
  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;

  /* update cached brush */
  switch (index)
  {
  case MCSC_BACKGROUND:
    type = BrushBackground;
    break;
  case MCSC_TITLEBK:
    type = BrushTitle;
    break;
  case MCSC_MONTHBK:
    type = BrushMonth;
    break;
  default:
    type = BrushLast;
  }

  if (type != BrushLast)
  {
    DeleteObject(infoPtr->brushes[type]);
    infoPtr->brushes[type] = CreateSolidBrush(color);
  }

  /* update cached pen */
  if (index == MCSC_TEXT)
  {
    DeleteObject(infoPtr->pens[PenText]);
    infoPtr->pens[PenText] = CreatePen(PS_SOLID, 1, infoPtr->colors[index]);
  }

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

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

  if(infoPtr->delta)
    return infoPtr->delta;

  return MONTHCAL_GetMonthRange(infoPtr, GMR_VISIBLE, NULL);
}


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 defined (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_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;

    infoPtr->rangeValid = 0;
    infoPtr->minDate = infoPtr->maxDate = st_null;

    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 0;

  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 (!(infoPtr->dwStyle & MCS_DAYSTATE)) return 0;
  if (months != MONTHCAL_GetMonthRange(infoPtr, GMR_DAYSTATE, 0)) 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, selection;
  INT diff;
  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;

  selection = *curSel;
  selection.wHour = selection.wMinute = selection.wSecond = selection.wMilliseconds = 0;
  MONTHCAL_CalculateDayOfWeek(&selection, TRUE);

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

  /* scroll calendars only if we have to */
  diff = MONTHCAL_MonthDiff(&infoPtr->calendars[MONTHCAL_GetCalCount(infoPtr)-1].month, curSel);
  if (diff <= 0)
  {
    diff = MONTHCAL_MonthDiff(&infoPtr->calendars[0].month, curSel);
    if (diff > 0) diff = 0;
  }

  if (diff != 0)
  {
    INT i;

    for (i = 0; i < MONTHCAL_GetCalCount(infoPtr); i++)
      MONTHCAL_GetMonth(&infoPtr->calendars[i].month, diff);
  }

  /* we need to store time part as it is */
  selection = *curSel;
  MONTHCAL_CalculateDayOfWeek(&selection, TRUE);
  infoPtr->minSel = infoPtr->maxSel = selection;

  /* 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_GetDayRect(infoPtr, &prev, &r_prev, -1);
    MONTHCAL_GetDayRect(infoPtr, curSel, &r_new, -1);

    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)
{
  SYSTEMTIME old_range[2];
  INT diff;

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

  if(!range || !(infoPtr->dwStyle & MCS_MULTISELECT)) return FALSE;

  /* 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];
  }

  diff = MONTHCAL_MonthDiff(&infoPtr->calendars[MONTHCAL_GetCalCount(infoPtr)-1].month, &infoPtr->maxSel);
  if (diff < 0)
  {
    diff = MONTHCAL_MonthDiff(&infoPtr->calendars[0].month, &infoPtr->maxSel);
    if (diff > 0) diff = 0;
  }

  if (diff != 0)
  {
    INT i;

    for (i = 0; i < MONTHCAL_GetCalCount(infoPtr); i++)
      MONTHCAL_GetMonth(&infoPtr->calendars[i].month, diff);
  }

  /* 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;
}


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 rect;

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

    /* Invalidate old and new today day rectangle, and today label. */
    if (MONTHCAL_GetDayRect(infoPtr, &infoPtr->todaysDate, &rect, -1))
        InvalidateRect(infoPtr->hwndSelf, &rect, FALSE);

    if (MONTHCAL_GetDayRect(infoPtr, today, &rect, -1))
        InvalidateRect(infoPtr->hwndSelf, &rect, FALSE);

    infoPtr->todaysDate = *today;

    InvalidateRect(infoPtr->hwndSelf, &infoPtr->todayrect, FALSE);
    return TRUE;
}

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

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

  return 0;
}

/* 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 < MONTHCAL_GetCalCount(infoPtr); 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)
{
  MCHITTESTINFO htinfo;
  SYSTEMTIME *ht_month;
  INT day, calIdx;

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

  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);

  /* 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);
  }

  /* 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);
  }

  ht_month = &infoPtr->calendars[calIdx].month;
  /* days area (including week days and week numbers) */
  day = MONTHCAL_GetDayFromPos(infoPtr, lpht->pt, calIdx);
  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_GetDayPos(infoPtr, &htinfo.st, &htinfo.iCol, &htinfo.iRow, calIdx);
  }
  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.wDay = ht_month->wDay;
      htinfo.st.wYear  = ht_month->wYear;
      htinfo.st.wMonth = ht_month->wMonth;
      /* previous month only valid for first calendar */
      if (day < 1 && calIdx == 0)
      {
	  htinfo.uHit = MCHT_CALENDARDATEPREV;
	  MONTHCAL_GetPrevMonth(&htinfo.st);
	  htinfo.st.wDay = MONTHCAL_MonthLength(htinfo.st.wMonth, htinfo.st.wYear) + day;
      }
      /* next month only valid for last calendar */
      else if (day > MONTHCAL_MonthLength(ht_month->wMonth, ht_month->wYear) &&
               calIdx == MONTHCAL_GetCalCount(infoPtr)-1)
      {
	  htinfo.uHit = MCHT_CALENDARDATENEXT;
	  MONTHCAL_GetNextMonth(&htinfo.st);
	  htinfo.st.wDay = day - MONTHCAL_MonthLength(ht_month->wMonth, ht_month->wYear);
      }
      /* multiple calendars case - blank areas for previous/next month */
      else if (day < 1 || day > MONTHCAL_MonthLength(ht_month->wMonth, ht_month->wYear))
      {
          htinfo.uHit = MCHT_CALENDARBK;
      }
      else
      {
	htinfo.uHit = MCHT_CALENDARDATE;
	htinfo.st.wDay = day;
      }

      MONTHCAL_GetDayPos(infoPtr, &htinfo.st, &htinfo.iCol, &htinfo.iRow, calIdx);
      MONTHCAL_GetDayRectI(infoPtr, &htinfo.rc, htinfo.iCol, htinfo.iRow, calIdx);
      /* 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)
{
  MONTHDAYSTATE *state;
  NMDAYSTATE nmds;

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

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

  MONTHCAL_GetMinDate(infoPtr, &nmds.stStart);
  nmds.stStart.wDay = 1;

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

  Free(state);
}

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

  for(i = 0; i < MONTHCAL_GetCalCount(infoPtr); 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);
  }

  if (keep_selection)
    return;

  /* 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 : MONTHCAL_GetCalCount(infoPtr);
  BOOL keep_selection;
  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[MONTHCAL_GetCalCount(infoPtr)-1].month;
    MONTHCAL_GetMonth(&st, delta);
  }

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

  keep_selection = infoPtr->dwStyle & MCS_NOSELCHANGEONNAV;
  MONTHCAL_Scroll(infoPtr, direction == DIRECTION_BACKWARD ? -delta : delta, keep_selection);
  MONTHCAL_NotifyDayState(infoPtr);
  if (!keep_selection)
    MONTHCAL_NotifySelectionChange(infoPtr);
}

static LRESULT
MONTHCAL_RButtonUp(MONTHCAL_INFO *infoPtr, LPARAM lParam)
{
  HMENU hMenu;
  POINT menupoint;
  WCHAR buf[32];

  hMenu = CreatePopupMenu();
  LoadStringW(COMCTL32_hModule, IDM_GOTODAY, buf, countof(buf));
  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))
  {
      if (infoPtr->dwStyle & MCS_MULTISELECT)
      {
          SYSTEMTIME range[2];

          range[0] = range[1] = infoPtr->todaysDate;
          MONTHCAL_SetSelRange(infoPtr, range);
      }
      else
          MONTHCAL_SetCurSel(infoPtr, &infoPtr->todaysDate);

      MONTHCAL_NotifySelectionChange(infoPtr);
      MONTHCAL_NotifySelect(infoPtr);
  }

  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 %s\n", hit, wine_dbgstr_point(&ht.pt));

  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[MONTHCAL_GetCalCount(infoPtr)-1].month;
        MONTHCAL_GetMonth(&st, delta);

        if (MONTHCAL_IsDateInValidRange(infoPtr, &st, FALSE))
        {
            MONTHCAL_Scroll(infoPtr, delta, FALSE);
            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:
  {
    if (infoPtr->dwStyle & MCS_MULTISELECT)
    {
        SYSTEMTIME range[2];

        range[0] = range[1] = infoPtr->todaysDate;
        MONTHCAL_SetSelRange(infoPtr, range);
    }
    else
        MONTHCAL_SetCurSel(infoPtr, &infoPtr->todaysDate);

    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);
  ht.iOffset = -1;

  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_GetDayRect(infoPtr, &ht.st, &r, ht.iOffset);

  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)
{
  RECT rc;

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

  FillRect(hdc, &rc, infoPtr->brushes[BrushBackground]);

  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 };
  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;

  INT xdiv, dx, dy, i, j, x, y, c_dx, c_dy;
  WCHAR buff[80];
  TEXTMETRICW tm;
  INT day_width;
  RECT client;
  HFONT font;
  SIZE size;
  HDC hdc;

  GetClientRect(infoPtr->hwndSelf, &client);

  hdc = GetDC(infoPtr->hwndSelf);
  font = 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 widest day name for current locale and font */
  day_width = 0;
  for (i = 0; i < 7; i++)
  {
      SIZE sz;

      if (get_localized_dayname(infoPtr, i, buff, countof(buff)))
      {
          GetTextExtentPoint32W(hdc, buff, lstrlenW(buff), &sz);
          if (sz.cx > day_width) day_width = sz.cx;
      }
      else /* locale independent fallback on failure */
      {
          static const WCHAR sunW[] = { 'S','u','n' };
          GetTextExtentPoint32W(hdc, sunW, countof(sunW), &sz);
          day_width = sz.cx;
          break;
      }
  }

  day_width += 2;

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

  /* restore the originally selected font */
  SelectObject(hdc, font);
  ReleaseDC(infoPtr->hwndSelf, hdc);

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

  infoPtr->width_increment  = max(day_width, 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;

  /* week numbers */
  weeknumrect->left  = 0;
  weeknumrect->right = infoPtr->dwStyle & MCS_WEEKNUMBERS ? prev->right : 0;

  /* days abbreviated names */
  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;

  /* compute calendar count, update all calendars */
  x = (client.right  + MC_CALENDAR_PADDING) / (title->right - title->left + MC_CALENDAR_PADDING);
  /* today label affects whole height */
  if (infoPtr->dwStyle & MCS_NOTODAY)
    y = (client.bottom + MC_CALENDAR_PADDING) / (days->bottom - title->top + MC_CALENDAR_PADDING);
  else
    y = (client.bottom - todayrect->bottom + todayrect->top + MC_CALENDAR_PADDING) /
         (days->bottom - title->top + MC_CALENDAR_PADDING);

  /* TODO: ensure that count is properly adjusted to fit 12 months constraint */
  if (x == 0) x = 1;
  if (y == 0) y = 1;

  if (x*y != MONTHCAL_GetCalCount(infoPtr))
  {
      infoPtr->dim.cx = x;
      infoPtr->dim.cy = y;
      infoPtr->calendars = ReAlloc(infoPtr->calendars, MONTHCAL_GetCalCount(infoPtr)*sizeof(CALENDAR_INFO));

      infoPtr->monthdayState = ReAlloc(infoPtr->monthdayState,
          MONTHCAL_GetMonthRange(infoPtr, GMR_DAYSTATE, 0)*sizeof(MONTHDAYSTATE));
      MONTHCAL_NotifyDayState(infoPtr);

      /* update pointers that we'll need */
      title = &infoPtr->calendars[0].title;
      wdays = &infoPtr->calendars[0].wdays;
      days  = &infoPtr->calendars[0].days;
  }

  for (i = 1; i < MONTHCAL_GetCalCount(infoPtr); i++)
  {
      /* set months */
      infoPtr->calendars[i] = infoPtr->calendars[0];
      MONTHCAL_GetMonth(&infoPtr->calendars[i].month, i);
  }

  /* offset all rectangles to center in client area */
  c_dx = (client.right  - x * title->right - MC_CALENDAR_PADDING * (x-1)) / 2;
  c_dy = (client.bottom - y * todayrect->bottom - MC_CALENDAR_PADDING * (y-1)) / 2;

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

  for (i = 0; i < y; i++)
  {
      for (j = 0; j < x; j++)
      {
          dx = j*(title->right - title->left + MC_CALENDAR_PADDING) + c_dx;
          dy = i*(days->bottom - title->top  + MC_CALENDAR_PADDING) + c_dy;

          OffsetRect(&infoPtr->calendars[i*x+j].title, dx, dy);
          OffsetRect(&infoPtr->calendars[i*x+j].titlemonth, dx, dy);
          OffsetRect(&infoPtr->calendars[i*x+j].titleyear, dx, dy);
          OffsetRect(&infoPtr->calendars[i*x+j].wdays, dx, dy);
          OffsetRect(&infoPtr->calendars[i*x+j].weeknums, dx, dy);
          OffsetRect(&infoPtr->calendars[i*x+j].days, dx, dy);
      }
  }

  OffsetRect(prev, c_dx, c_dy);
  OffsetRect(next, (x-1)*(title->right - title->left + MC_CALENDAR_PADDING) + c_dx, c_dy);

  i = infoPtr->dim.cx * infoPtr->dim.cy - infoPtr->dim.cx;
  todayrect->left   = infoPtr->calendars[i].title.left;
  todayrect->right  = infoPtr->calendars[i].title.right;
  todayrect->top    = infoPtr->calendars[i].days.bottom;
  todayrect->bottom = infoPtr->calendars[i].days.bottom + infoPtr->height_increment;

  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(&client),
        wine_dbgstr_rect(title),
        wine_dbgstr_rect(wdays),
        wine_dbgstr_rect(days),
        wine_dbgstr_rect(todayrect));
}

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 | MCS_SHORTDAYSOFWEEK))
        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;
    }

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

    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->dim.cx = infoPtr->dim.cy = 1;
  infoPtr->calendars = Alloc(sizeof(CALENDAR_INFO));
  if (!infoPtr->calendars) goto fail;
  infoPtr->monthdayState = Alloc(3*sizeof(MONTHDAYSTATE));
  if (!infoPtr->monthdayState) goto fail;

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

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

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

  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->brushes[BrushBackground]  = CreateSolidBrush(infoPtr->colors[MCSC_BACKGROUND]);
  infoPtr->brushes[BrushTitle]       = CreateSolidBrush(infoPtr->colors[MCSC_TITLEBK]);
  infoPtr->brushes[BrushMonth]       = CreateSolidBrush(infoPtr->colors[MCSC_MONTHBK]);

  infoPtr->pens[PenRed]  = CreatePen(PS_SOLID, 1, RGB(255, 0, 0));
  infoPtr->pens[PenText] = CreatePen(PS_SOLID, 1, infoPtr->colors[MCSC_TEXT]);

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

  /* setup control layout and day state data */
  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)
{
  INT i;

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

  CloseThemeData (GetWindowTheme (infoPtr->hwndSelf));

  for (i = 0; i < BrushLast; i++) DeleteObject(infoPtr->brushes[i]);
  for (i = 0; i < PenLast; i++) DeleteObject(infoPtr->pens[i]);

  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, FALSE);
      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 MCM_GETCALENDARCOUNT:
    return MONTHCAL_GetCalCount(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);
}
