/* 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>
 *
 * TODO:
 *   - Notifications.
 *
 *
 *  FIXME: handle resources better (doesn't work now); also take care
           of internationalization. 
 *  FIXME: keyboard handling.
 */

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

#include "winbase.h"
#include "windef.h"
#include "wingdi.h"
#include "winuser.h"
#include "winnls.h"
#include "commctrl.h"
#include "comctl32.h"
#include "debugtools.h"

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_NEXTMONTHDELAY   350	/* when continuously pressing `next */
										/* month', wait 500 ms before going */
										/* to the next month */
#define MC_NEXTMONTHTIMER   1			/* Timer ID's */
#define MC_PREVMONTHTIMER   2			

typedef struct
{
    COLORREF	bk;
    COLORREF	txt;
    COLORREF	titlebk;
    COLORREF	titletxt;
    COLORREF	monthbk;
    COLORREF	trailingtxt;
    HFONT	hFont;
    HFONT	hBoldFont;
    int		textHeight;
    int		textWidth;
    int		height_increment;
    int		width_increment;
    int		left_offset;
    int		top_offset;
    int		firstDayplace; /* place of the first day of the current month */
    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 */
    int		monthRange;
    MONTHDAYSTATE *monthdayState;
    SYSTEMTIME	todaysDate;
    DWORD	currentMonth;
    DWORD	currentYear;
    int		status;		/* See MC_SEL flags */
    int		curSelDay;	/* current selected day */
    int		firstSelDay;	/* first selected day */
    int		maxSelCount;
    SYSTEMTIME	minSel;
    SYSTEMTIME	maxSel;
    DWORD	rangeValid;
    SYSTEMTIME	minDate;
    SYSTEMTIME	maxDate;
		
    RECT rcClient;	/* rect for whole client area */
    RECT rcDraw;	/* rect for drawable portion of client area */
    RECT title;		/* rect for the header above the calendar */
    RECT titlebtnnext;	/* the `next month' button in the header */
    RECT titlebtnprev;  /* the `prev month' button in the header */	
    RECT titlemonth;	/* the `month name' txt in the header */
    RECT titleyear;	/* the `year number' txt in the header */
    RECT wdays;		/* week days at top */
    RECT days;		/* calendar area */
    RECT weeknums;	/* week numbers at left side */
    RECT todayrect;	/* `today: xx/xx/xx' text rect */
    HWND hWndYearEdit;  /* Window Handle of edit box to handle years */
    HWND hWndYearUpDown;/* Window Handle of updown box to handle years */
} MONTHCAL_INFO, *LPMONTHCAL_INFO;


/* Offsets of days in the week to the weekday of  january 1. */
static const int DayOfWeekTable[] = {0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4};


#define MONTHCAL_GetInfoPtr(hwnd) ((MONTHCAL_INFO *)GetWindowLongA(hwnd, 0))

/* helper functions  */

/* 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, 0};
  /*Wrap around, this eases handleing*/
  if(month == 0)
    month = 12;
  if(month == 13)
    month = 1;

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


/* make sure that time is valid */
static int MONTHCAL_ValidateTime(SYSTEMTIME time) 
{
  if(time.wMonth > 12) return FALSE;
  if(time.wDayOfWeek > 6) return FALSE;
  if(time.wDay > MONTHCAL_MonthLength(time.wMonth, time.wYear))
	  return FALSE;
  if(time.wHour > 23) return FALSE;
  if(time.wMinute > 59) return FALSE;
  if(time.wSecond > 59) return FALSE;
  if(time.wMilliseconds > 999) return FALSE;

  return TRUE;
}


void MONTHCAL_CopyTime(const SYSTEMTIME *from, SYSTEMTIME *to) 
{
  to->wYear = from->wYear;
  to->wMonth = from->wMonth;
  to->wDayOfWeek = from->wDayOfWeek;
  to->wDay = from->wDay;
  to->wHour = from->wHour;
  to->wMinute = from->wMinute;
  to->wSecond = from->wSecond;
  to->wMilliseconds = from->wMilliseconds;
}


/* 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 = Monday.
*/

/* returns the day in the week(0 == monday, 6 == sunday) */
/* day(1 == 1st, 2 == 2nd... etc), year is the  year value */
static int MONTHCAL_CalculateDayOfWeek(DWORD day, DWORD month, DWORD year)
{
  year-=(month < 3);

  return((year + year/4 - year/100 + year/400 + 
         DayOfWeekTable[month-1] + day - 1 ) % 7);
}

/* 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(MONTHCAL_INFO *infoPtr, int x, int y, 
				   int *daypos,int *weekpos) 
{
  int retval, firstDay;

  /* if the point is outside the x bounds of the window put
  it at the boundry */
  if(x > infoPtr->rcClient.right) {
    x = infoPtr->rcClient.right ;
  }

  *daypos = (x - infoPtr->days.left ) / infoPtr->width_increment;
  *weekpos = (y - infoPtr->days.top ) / infoPtr->height_increment;
    
  firstDay = (MONTHCAL_CalculateDayOfWeek(1, infoPtr->currentMonth, infoPtr->currentYear)+6 - infoPtr->firstDay)%7;
  retval = *daypos + (7 * *weekpos) - firstDay;
  return retval;
}

/* day is the day of the month, 1 == 1st day of the month */
/* sets x and y to be the position of the day */
/* x == day, y == week where(0,0) == firstDay, 1st week */
static void MONTHCAL_CalcDayXY(MONTHCAL_INFO *infoPtr, int day, int month, 
                                 int *x, int *y)
{
  int firstDay, prevMonth;

  firstDay = (MONTHCAL_CalculateDayOfWeek(1, infoPtr->currentMonth, infoPtr->currentYear) +6 - infoPtr->firstDay)%7;

  if(month==infoPtr->currentMonth) {
    *x = (day + firstDay) % 7;
    *y = (day + firstDay - *x) / 7;
    return;
  }
  if(month < infoPtr->currentMonth) {
    prevMonth = month - 1;
    if(prevMonth==0)
       prevMonth = 12;
   
    *x = (MONTHCAL_MonthLength(prevMonth, infoPtr->currentYear) - firstDay) % 7;
    *y = 0;
    return;
  }

  *y = MONTHCAL_MonthLength(month, infoPtr->currentYear - 1) / 7;
  *x = (day + firstDay + MONTHCAL_MonthLength(month,
       infoPtr->currentYear)) % 7;
}


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


/* sets the RECT struct r to the rectangle around the day and month */
/* day is the day value of the month(1 == 1st), month is the month */
/* value(january == 1, december == 12) */
static inline void MONTHCAL_CalcPosFromDay(MONTHCAL_INFO *infoPtr, 
                                            int day, int month, RECT *r)
{
  int x, y;

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


/* day is the day in the month(1 == 1st of the month) */
/* month is the month value(1 == january, 12 == december) */
static void MONTHCAL_CircleDay(HDC hdc, MONTHCAL_INFO *infoPtr, int day,
int month)
{
  HPEN hRedPen = CreatePen(PS_SOLID, 2, RGB(255, 0, 0));
  HPEN hOldPen2 = SelectObject(hdc, hRedPen);
  POINT points[13];
  int x, y;
  RECT day_rect;


  MONTHCAL_CalcPosFromDay(infoPtr, day, month, &day_rect);

  x = day_rect.left;
  y = day_rect.top;
	
  points[0].x = x;
  points[0].y = y - 1;
  points[1].x = x + 0.8 * infoPtr->width_increment;
  points[1].y = y - 1;
  points[2].x = x + 0.9 * infoPtr->width_increment;
  points[2].y = y;
  points[3].x = x + infoPtr->width_increment;
  points[3].y = y + 0.5 * infoPtr->height_increment;
	
  points[4].x = x + infoPtr->width_increment;
  points[4].y = y + 0.9 * infoPtr->height_increment;
  points[5].x = x + 0.6 * infoPtr->width_increment;
  points[5].y = y + 0.9 * infoPtr->height_increment;
  points[6].x = x + 0.5 * infoPtr->width_increment;
  points[6].y = y + 0.9 * infoPtr->height_increment; /* bring the bottom up just
				a hair to fit inside the day rectangle */
	
  points[7].x = x + 0.2 * infoPtr->width_increment;
  points[7].y = y + 0.8 * infoPtr->height_increment;
  points[8].x = x + 0.1 * infoPtr->width_increment;
  points[8].y = y + 0.8 * infoPtr->height_increment;
  points[9].x = x;
  points[9].y = y + 0.5 * infoPtr->height_increment;

  points[10].x = x + 0.1 * infoPtr->width_increment;
  points[10].y = y + 0.2 * infoPtr->height_increment;
  points[11].x = x + 0.2 * infoPtr->width_increment;
  points[11].y = y + 0.3 * infoPtr->height_increment;
  points[12].x = x + 0.4 * infoPtr->width_increment;
  points[12].y = y + 0.2 * infoPtr->height_increment;
  
  PolyBezier(hdc, points, 13);
  DeleteObject(hRedPen);
  SelectObject(hdc, hOldPen2);
}


static void MONTHCAL_DrawDay(HDC hdc, MONTHCAL_INFO *infoPtr, int day, int month,
                             int x, int y, int bold)
{
  char buf[10];
  RECT r;
  static int haveBoldFont, haveSelectedDay = FALSE;
  HBRUSH hbr;
  HPEN hNewPen, hOldPen = 0;
  COLORREF oldCol = 0;
  COLORREF oldBk = 0;

  sprintf(buf, "%d", day);

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

  MONTHCAL_CalcDayRect(infoPtr, &r, x, y);

  if((day>=infoPtr->minSel.wDay) && (day<=infoPtr->maxSel.wDay)
       && (month==infoPtr->currentMonth)) {
    HRGN hrgn;
    RECT r2;

    TRACE("%d %d %d\n",day, infoPtr->minSel.wDay, infoPtr->maxSel.wDay);
    TRACE("%d %d %d %d\n", r.left, r.top, r.right, r.bottom);
    oldCol = SetTextColor(hdc, infoPtr->monthbk);
    oldBk = SetBkColor(hdc, infoPtr->trailingtxt);
    hbr = GetSysColorBrush(COLOR_GRAYTEXT);
    hrgn = CreateEllipticRgn(r.left, r.top, r.right, r.bottom);
    FillRgn(hdc, hrgn, hbr);

    /* FIXME: this may need to be changed now b/c of the other
	drawing changes 11/3/99 CMM */
    r2.left   = r.left - 0.25 * infoPtr->textWidth;
    r2.top    = r.top;
    r2.right  = r.left + 0.5 * infoPtr->textWidth;
    r2.bottom = r.bottom;
    if(haveSelectedDay) FillRect(hdc, &r2, hbr);
      haveSelectedDay = TRUE;
  } else {
    haveSelectedDay = FALSE;
  }

  /* need to add some code for multiple selections */

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

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

  SetBkMode(hdc,TRANSPARENT);
  DrawTextA(hdc, buf, -1, &r, DT_CENTER | DT_VCENTER | DT_SINGLELINE );

  /* draw a rectangle around the currently selected days text */
  if((day==infoPtr->curSelDay) && (month==infoPtr->currentMonth)) {
    hNewPen = CreatePen(PS_ALTERNATE, 0, GetSysColor(COLOR_WINDOWTEXT) );
    hbr = GetSysColorBrush(COLOR_WINDOWTEXT);
    FrameRect(hdc, &r, hbr);
    SelectObject(hdc, hOldPen);
  }
}


/* CHECKME: For `todays date', do we need to check the locale?*/
static void MONTHCAL_Refresh(HWND hwnd, HDC hdc, PAINTSTRUCT* ps) 
{
  MONTHCAL_INFO *infoPtr=MONTHCAL_GetInfoPtr(hwnd);
  RECT *rcClient=&infoPtr->rcClient;
  RECT *rcDraw=&infoPtr->rcDraw;
  RECT *title=&infoPtr->title;
  RECT *prev=&infoPtr->titlebtnprev;
  RECT *next=&infoPtr->titlebtnnext;
  RECT *titlemonth=&infoPtr->titlemonth;
  RECT *titleyear=&infoPtr->titleyear;
  RECT dayrect;
  RECT *days=&dayrect;
  RECT rtoday;
  int i, j, m, mask, day, firstDay, weeknum, weeknum1,prevMonth;
  int textHeight = infoPtr->textHeight, textWidth = infoPtr->textWidth;
  SIZE size;
  HBRUSH hbr;
  HFONT currentFont;
  /* LOGFONTA logFont; */
  char buf[20];
  char buf1[20];
  char buf2[32];
  COLORREF oldTextColor, oldBkColor;
  DWORD dwStyle = GetWindowLongA(hwnd, GWL_STYLE);
  RECT rcTemp;
  RECT rcDay; /* used in MONTHCAL_CalcDayRect() */
  SYSTEMTIME localtime;
  int startofprescal;

  oldTextColor = SetTextColor(hdc, GetSysColor(COLOR_WINDOWTEXT));


  /* fill background */
  hbr = CreateSolidBrush (infoPtr->bk);
  FillRect(hdc, rcClient, hbr);
  DeleteObject(hbr);       

  /* draw header */
  if(IntersectRect(&rcTemp, &(ps->rcPaint), title))
  {
    hbr =  CreateSolidBrush(infoPtr->titlebk);
    FillRect(hdc, title, hbr);
    DeleteObject(hbr);
  }
	
  /* if the previous button is pressed draw it depressed */
  if(IntersectRect(&rcTemp, &(ps->rcPaint), prev))
  {  
    if((infoPtr->status & MC_PREVPRESSED))
        DrawFrameControl(hdc, prev, DFC_SCROLL,
  	   DFCS_SCROLLLEFT | DFCS_PUSHED |
          (dwStyle & WS_DISABLED ? DFCS_INACTIVE : 0));
    else /* if the previous button is pressed draw it depressed */
      DrawFrameControl(hdc, prev, DFC_SCROLL,
	   DFCS_SCROLLLEFT |(dwStyle & WS_DISABLED ? DFCS_INACTIVE : 0));
  }

  /* if next button is depressed draw it depressed */	
  if(IntersectRect(&rcTemp, &(ps->rcPaint), next))
  {
    if((infoPtr->status & MC_NEXTPRESSED))
      DrawFrameControl(hdc, next, DFC_SCROLL,
    	   DFCS_SCROLLRIGHT | DFCS_PUSHED |
           (dwStyle & WS_DISABLED ? DFCS_INACTIVE : 0));
    else /* if the next button is pressed draw it depressed */
      DrawFrameControl(hdc, next, DFC_SCROLL,
           DFCS_SCROLLRIGHT |(dwStyle & WS_DISABLED ? DFCS_INACTIVE : 0));
  }

  oldBkColor = SetBkColor(hdc, infoPtr->titlebk);
  SetTextColor(hdc, infoPtr->titletxt);
  currentFont = SelectObject(hdc, infoPtr->hBoldFont);

  /* titlemonth->left and right are set in MONTHCAL_UpdateSize */
  titlemonth->left   = title->left;
  titlemonth->right  = title->right;
 
  GetLocaleInfoA( LOCALE_USER_DEFAULT,LOCALE_SMONTHNAME1+infoPtr->currentMonth -1,
		  buf1,sizeof(buf1));
  sprintf(buf, "%s %ld", buf1, infoPtr->currentYear);
 
  if(IntersectRect(&rcTemp, &(ps->rcPaint), titlemonth))
  {
    DrawTextA(hdc, buf, strlen(buf), titlemonth, 
                        DT_CENTER | DT_VCENTER | DT_SINGLELINE);
  }

  SelectObject(hdc, infoPtr->hFont);

/* titlemonth left/right contained rect for whole titletxt('June  1999')
  * MCM_HitTestInfo wants month & year rects, so prepare these now.
  *(no, we can't draw them separately; the whole text is centered) 
  */
  GetTextExtentPoint32A(hdc, buf, strlen(buf), &size);
  titlemonth->left = title->right / 2 - size.cx / 2;
  titleyear->right = title->right / 2 + size.cx / 2;
  GetTextExtentPoint32A(hdc, buf1, strlen(buf1), &size);
  titlemonth->right = titlemonth->left + size.cx;
  titleyear->left = titlemonth->right;
 
  /* draw month area */
  rcTemp.top=infoPtr->wdays.top;
  rcTemp.left=infoPtr->wdays.left;
  rcTemp.bottom=infoPtr->todayrect.bottom;
  rcTemp.right =infoPtr->todayrect.right;
  if(IntersectRect(&rcTemp, &(ps->rcPaint), &rcTemp))
  {
    hbr =  CreateSolidBrush(infoPtr->monthbk);
    FillRect(hdc, &rcTemp, hbr);
    DeleteObject(hbr);
  }
	
/* draw line under day abbreviatons */

  MoveToEx(hdc, infoPtr->days.left + 3, title->bottom + textHeight + 1, NULL);
     
  LineTo(hdc, rcDraw->right - 3, title->bottom + textHeight + 1);
  
  prevMonth = infoPtr->currentMonth - 1;
  if(prevMonth == 0) /* if currentMonth is january(1) prevMonth is */
    prevMonth = 12;    /* december(12) of the previous year */

  infoPtr->wdays.left   = infoPtr->days.left   = infoPtr->weeknums.right;
/* draw day abbreviations */

  SetBkColor(hdc, infoPtr->monthbk);
  SetTextColor(hdc, infoPtr->trailingtxt);

  /* copy this rect so we can change the values without changing */
  /* the original version */
  days->left = infoPtr->wdays.left;
  days->right = days->left + infoPtr->width_increment;
  days->top = infoPtr->wdays.top;
  days->bottom = infoPtr->wdays.bottom;

  i = infoPtr->firstDay;

  for(j=0; j<7; j++) {
    GetLocaleInfoA( LOCALE_USER_DEFAULT,LOCALE_SABBREVDAYNAME1 + (i +j)%7,
		    buf,sizeof(buf));
    DrawTextA(hdc, buf, strlen(buf), days,
                         DT_CENTER | DT_VCENTER | DT_SINGLELINE );
    days->left+=infoPtr->width_increment;
    days->right+=infoPtr->width_increment;
  }

/* draw day numbers; first, the previous month */
  
  firstDay = MONTHCAL_CalculateDayOfWeek(1, infoPtr->currentMonth, infoPtr->currentYear);
  
  day = MONTHCAL_MonthLength(prevMonth, infoPtr->currentYear)  + 
    (infoPtr->firstDay + 7  - firstDay)%7 + 1;
  if (day > MONTHCAL_MonthLength(prevMonth, infoPtr->currentYear))
    day -=7;
  startofprescal = day;
  mask = 1<<(day-1);

  i = 0;
  m = 0;
  while(day <= MONTHCAL_MonthLength(prevMonth, infoPtr->currentYear)) {
    MONTHCAL_CalcDayRect(infoPtr, &rcDay, i, 0);
    if(IntersectRect(&rcTemp, &(ps->rcPaint), &rcDay))
    {
      MONTHCAL_DrawDay(hdc, infoPtr, day, prevMonth, i, 0, 
          infoPtr->monthdayState[m] & mask);
    }

    mask<<=1;
    day++;
    i++;
  }

/* draw `current' month  */

  day = 1; /* start at the beginning of the current month */

  infoPtr->firstDayplace = i;
  SetTextColor(hdc, infoPtr->txt);
  m++;
  mask = 1;

  /* draw the first week of the current month */
  while(i<7) {
    MONTHCAL_CalcDayRect(infoPtr, &rcDay, i, 0);
    if(IntersectRect(&rcTemp, &(ps->rcPaint), &rcDay))
    {

      MONTHCAL_DrawDay(hdc, infoPtr, day, infoPtr->currentMonth, i, 0, 
	infoPtr->monthdayState[m] & mask);

      if((infoPtr->currentMonth==infoPtr->todaysDate.wMonth) &&
          (day==infoPtr->todaysDate.wDay) &&
	  (infoPtr->currentYear == infoPtr->todaysDate.wYear)) {
        if(!(dwStyle & MCS_NOTODAYCIRCLE))
	  MONTHCAL_CircleDay(hdc, infoPtr, day, infoPtr->currentMonth);
      }
    }

    mask<<=1;
    day++;
    i++;
  }

  j = 1; /* move to the 2nd week of the current month */
  i = 0; /* move back to sunday */
  while(day <= MONTHCAL_MonthLength(infoPtr->currentMonth, infoPtr->currentYear)) {	
    MONTHCAL_CalcDayRect(infoPtr, &rcDay, i, j);
    if(IntersectRect(&rcTemp, &(ps->rcPaint), &rcDay))
    {
      MONTHCAL_DrawDay(hdc, infoPtr, day, infoPtr->currentMonth, i, j,
          infoPtr->monthdayState[m] & mask);

      if((infoPtr->currentMonth==infoPtr->todaysDate.wMonth) &&
          (day==infoPtr->todaysDate.wDay) &&
          (infoPtr->currentYear == infoPtr->todaysDate.wYear)) 
        if(!(dwStyle & MCS_NOTODAYCIRCLE))  
	  MONTHCAL_CircleDay(hdc, infoPtr, day, infoPtr->currentMonth);
    }
    mask<<=1;
    day++;
    i++;
    if(i>6) { /* past saturday, goto the next weeks sunday */
      i = 0;
      j++;
    }
  }

/*  draw `next' month */

  day = 1; /* start at the first day of the next month */
  m++;
  mask = 1;

  SetTextColor(hdc, infoPtr->trailingtxt);
  while((i<7) &&(j<6)) {
    MONTHCAL_CalcDayRect(infoPtr, &rcDay, i, j);
    if(IntersectRect(&rcTemp, &(ps->rcPaint), &rcDay))
    {   
      MONTHCAL_DrawDay(hdc, infoPtr, day, infoPtr->currentMonth + 1, i, j,
		infoPtr->monthdayState[m] & mask);
    }

    mask<<=1;
    day++;
    i++;	
    if(i==7) { /* past saturday, go to next week's sunday */
      i = 0;
      j++;
    }
  }
  SetTextColor(hdc, infoPtr->txt);


/* draw `today' date if style allows it, and draw a circle before today's
 * date if necessary */

  if(!(dwStyle & MCS_NOTODAY))  {
    int offset = 0;
    if(!(dwStyle & MCS_NOTODAYCIRCLE))  {
      /*day is the number of days from nextmonth we put on the calendar */
      MONTHCAL_CircleDay(hdc, infoPtr, 
			 day+MONTHCAL_MonthLength(infoPtr->currentMonth,infoPtr->currentYear), 
			 infoPtr->currentMonth);
      offset+=textWidth;
    }
    if (!LoadStringA(COMCTL32_hModule,IDM_TODAY,buf1,sizeof(buf1)))
      {
	WARN("Can't load resource\n");
	strcpy(buf1,"Today:");
      }
    MONTHCAL_CalcDayRect(infoPtr, &rtoday, 1, 6);
    MONTHCAL_CopyTime(&infoPtr->todaysDate,&localtime);
    GetDateFormatA(LOCALE_USER_DEFAULT,DATE_SHORTDATE,&localtime,NULL,buf2,sizeof(buf2));
    sprintf(buf, "%s %s", buf1,buf2);
    SelectObject(hdc, infoPtr->hBoldFont);

    if(IntersectRect(&rcTemp, &(ps->rcPaint), &rtoday))
    {
      DrawTextA(hdc, buf, -1, &rtoday, DT_CALCRECT | DT_LEFT | DT_VCENTER | DT_SINGLELINE);
      DrawTextA(hdc, buf, -1, &rtoday, DT_LEFT | DT_VCENTER | DT_SINGLELINE);
    }
    SelectObject(hdc, infoPtr->hFont);
  }

/*eventually draw week numbers*/   
  if(dwStyle & MCS_WEEKNUMBERS)  {
    /* display weeknumbers*/
    int mindays;

    /* 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
    */
    GetLocaleInfoA(LOCALE_USER_DEFAULT, LOCALE_IFIRSTWEEKOFYEAR,
		     buf, sizeof(buf));
    sscanf(buf, "%d", &weeknum);
    switch (weeknum)
      {
      case 1: mindays = 6;
	break;
      case 2: mindays = 3;
	break;
      case 0:
      default:
	mindays = 0;
      }
    if (infoPtr->currentMonth < 2)
      {
	/* calculate all those exceptions for january */
	weeknum1=MONTHCAL_CalculateDayOfWeek(1,1,infoPtr->currentYear);
	if ((infoPtr->firstDay +7 - weeknum1)%7 > mindays) 
	    weeknum =1;
	else
	  {
	    weeknum = 0;
	    for(i=0; i<11; i++) 
	      weeknum+=MONTHCAL_MonthLength(i+1, infoPtr->currentYear-1);
	    weeknum +=startofprescal+ 7;
	    weeknum /=7;
	    weeknum1=MONTHCAL_CalculateDayOfWeek(1,1,infoPtr->currentYear-1);
	    if ((infoPtr->firstDay + 7 - weeknum1)%7 > mindays)
	      weeknum++;
	  }
      }
    else
      {
	weeknum = 0;
	for(i=0; i<prevMonth-1; i++) 
	  weeknum+=MONTHCAL_MonthLength(i+1, infoPtr->currentYear);
	weeknum +=startofprescal+ 7;
	weeknum /=7;
	weeknum1=MONTHCAL_CalculateDayOfWeek(1,1,infoPtr->currentYear);
	if ((infoPtr->firstDay + 7 - weeknum1)%7 > mindays)
	  weeknum++;
      }
    days->left = infoPtr->weeknums.left;
    days->right = infoPtr->weeknums.right;
    days->top = infoPtr->weeknums.top;
    days->bottom = days->top +infoPtr->height_increment;
    for(i=0; i<6; i++) {
      if((i==0)&&(weeknum>50))
	{
	  sprintf(buf, "%d", weeknum);
	  weeknum=0;
	}
      else if((i==5)&&(weeknum>47))
	{
	  sprintf(buf, "%d", 1);
	}
      else
	sprintf(buf, "%d", weeknum + i);
      DrawTextA(hdc, buf, -1, days, DT_CENTER | DT_VCENTER | DT_SINGLELINE );
      days->top+=infoPtr->height_increment;
      days->bottom+=infoPtr->height_increment;
    }
			
    MoveToEx(hdc, infoPtr->weeknums.right, infoPtr->weeknums.top + 3 , NULL);
    LineTo(hdc,   infoPtr->weeknums.right, infoPtr->weeknums.bottom );
		
  }
  /* currentFont was font at entering Refresh */

  SetBkColor(hdc, oldBkColor);
  SelectObject(hdc, currentFont);     
  SetTextColor(hdc, oldTextColor);
}


static LRESULT 
MONTHCAL_GetMinReqRect(HWND hwnd, WPARAM wParam, LPARAM lParam)
{
  MONTHCAL_INFO *infoPtr = MONTHCAL_GetInfoPtr(hwnd);
  LPRECT lpRect = (LPRECT) lParam;
  TRACE("%x %lx\n", wParam, lParam);
	
  /* validate parameters */

  if((infoPtr==NULL) ||(lpRect == NULL) ) return FALSE;

  lpRect->left = infoPtr->rcClient.left;
  lpRect->right = infoPtr->rcClient.right;
  lpRect->top = infoPtr->rcClient.top;
  lpRect->bottom = infoPtr->rcClient.bottom;
  return TRUE;
}


static LRESULT 
MONTHCAL_GetColor(HWND hwnd, WPARAM wParam, LPARAM lParam)
{
  MONTHCAL_INFO *infoPtr = MONTHCAL_GetInfoPtr(hwnd);

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

  switch((int)wParam) {
    case MCSC_BACKGROUND:
      return infoPtr->bk;
    case MCSC_TEXT:
      return infoPtr->txt;
    case MCSC_TITLEBK:
      return infoPtr->titlebk;
    case MCSC_TITLETEXT:
      return infoPtr->titletxt;
    case MCSC_MONTHBK:
      return infoPtr->monthbk;
    case MCSC_TRAILINGTEXT:
      return infoPtr->trailingtxt;
  }

  return -1;
}


static LRESULT 
MONTHCAL_SetColor(HWND hwnd, WPARAM wParam, LPARAM lParam)
{
  MONTHCAL_INFO *infoPtr = MONTHCAL_GetInfoPtr(hwnd);
  int prev = -1;

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

  switch((int)wParam) {
    case MCSC_BACKGROUND:
      prev = infoPtr->bk;
      infoPtr->bk = (COLORREF)lParam;
      break;
    case MCSC_TEXT:
      prev = infoPtr->txt;
      infoPtr->txt = (COLORREF)lParam;
      break;
    case MCSC_TITLEBK:
      prev = infoPtr->titlebk;
      infoPtr->titlebk = (COLORREF)lParam;
      break;
    case MCSC_TITLETEXT:
      prev=infoPtr->titletxt;
      infoPtr->titletxt = (COLORREF)lParam;
      break;
    case MCSC_MONTHBK:
      prev = infoPtr->monthbk;
      infoPtr->monthbk = (COLORREF)lParam;
      break;
    case MCSC_TRAILINGTEXT:
      prev = infoPtr->trailingtxt;
      infoPtr->trailingtxt = (COLORREF)lParam;
      break;
  }

  InvalidateRect(hwnd, NULL, FALSE);
  return prev;
}


static LRESULT 
MONTHCAL_GetMonthDelta(HWND hwnd, WPARAM wParam, LPARAM lParam)
{
  MONTHCAL_INFO *infoPtr = MONTHCAL_GetInfoPtr(hwnd);

  TRACE("%x %lx\n", wParam, lParam);
  
  if(infoPtr->delta)
    return infoPtr->delta;
  else
    return infoPtr->visible;
}


static LRESULT 
MONTHCAL_SetMonthDelta(HWND hwnd, WPARAM wParam, LPARAM lParam)
{
  MONTHCAL_INFO *infoPtr = MONTHCAL_GetInfoPtr(hwnd);
  int prev = infoPtr->delta;

  TRACE("%x %lx\n", wParam, lParam);
	
  infoPtr->delta = (int)wParam;
  return prev;
}


static LRESULT 
MONTHCAL_GetFirstDayOfWeek(HWND hwnd, WPARAM wParam, LPARAM lParam)
{
  MONTHCAL_INFO *infoPtr = MONTHCAL_GetInfoPtr(hwnd);
	
  return infoPtr->firstDay;
}


/* sets the first day of the week that will appear in the control */
/* 0 == Monday, 6 == Sunday */
/* FIXME: this needs to be implemented properly in MONTHCAL_Refresh() */
/* FIXME: we need more error checking here */
static LRESULT 
MONTHCAL_SetFirstDayOfWeek(HWND hwnd, WPARAM wParam, LPARAM lParam)
{
  MONTHCAL_INFO *infoPtr = MONTHCAL_GetInfoPtr(hwnd);
  int prev = infoPtr->firstDay;
  char buf[40];
  int day;

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

  if((lParam >= 0) && (lParam < 7)) {
    infoPtr->firstDay = (int)lParam;
  }
  else
    {
      GetLocaleInfoA(LOCALE_USER_DEFAULT, LOCALE_IFIRSTDAYOFWEEK,
		     buf, sizeof(buf));
      TRACE("%s %d\n", buf, strlen(buf));
      if(sscanf(buf, "%d", &day) == 1)
	infoPtr->firstDay = day;
      else
	infoPtr->firstDay = 0;
    }
  return prev;
}


/* FIXME: fill this in */
static LRESULT
MONTHCAL_GetMonthRange(HWND hwnd, WPARAM wParam, LPARAM lParam) 
{
  MONTHCAL_INFO *infoPtr = MONTHCAL_GetInfoPtr(hwnd);

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

  return infoPtr->monthRange;
}


static LRESULT
MONTHCAL_GetMaxTodayWidth(HWND hwnd)
{
  MONTHCAL_INFO *infoPtr = MONTHCAL_GetInfoPtr(hwnd);

  return(infoPtr->todayrect.right - infoPtr->todayrect.left);
}


/* FIXME: are validated times taken from current date/time or simply
 * copied? 
 * FIXME:    check whether MCM_GETMONTHRANGE shows correct result after
 *            adjusting range with MCM_SETRANGE
 */

static LRESULT
MONTHCAL_SetRange(HWND hwnd, WPARAM wParam, LPARAM lParam)
{
  MONTHCAL_INFO *infoPtr = MONTHCAL_GetInfoPtr(hwnd);
  SYSTEMTIME lprgSysTimeArray[1];
  int prev;

  TRACE("%x %lx\n", wParam, lParam);
  
  if(wParam & GDTR_MAX) {
    if(MONTHCAL_ValidateTime(lprgSysTimeArray[1])){
      MONTHCAL_CopyTime(&lprgSysTimeArray[1], &infoPtr->maxDate);
      infoPtr->rangeValid|=GDTR_MAX;
    } else  {
      GetSystemTime(&infoPtr->todaysDate);
      MONTHCAL_CopyTime(&infoPtr->todaysDate, &infoPtr->maxDate);
    }
  }
  if(wParam & GDTR_MIN) {
    if(MONTHCAL_ValidateTime(lprgSysTimeArray[0])) {
      MONTHCAL_CopyTime(&lprgSysTimeArray[0], &infoPtr->maxDate);
      infoPtr->rangeValid|=GDTR_MIN;
    } else {
      GetSystemTime(&infoPtr->todaysDate);
      MONTHCAL_CopyTime(&infoPtr->todaysDate, &infoPtr->maxDate);
    }
  }

  prev = infoPtr->monthRange;
  infoPtr->monthRange = infoPtr->maxDate.wMonth - infoPtr->minDate.wMonth;

  if(infoPtr->monthRange!=prev) { 
	COMCTL32_ReAlloc(infoPtr->monthdayState, 
		infoPtr->monthRange * sizeof(MONTHDAYSTATE));
  }

  return 1;
}


/* CHECKME: At the moment, we copy ranges anyway,regardless of
 * infoPtr->rangeValid; a invalid range is simply filled with zeros in 
 * SetRange.  Is this the right behavior?
*/

static LRESULT
MONTHCAL_GetRange(HWND hwnd, WPARAM wParam, LPARAM lParam)
{
  MONTHCAL_INFO *infoPtr = MONTHCAL_GetInfoPtr(hwnd);
  SYSTEMTIME *lprgSysTimeArray = (SYSTEMTIME *)lParam;

  /* validate parameters */

  if((infoPtr==NULL) || (lprgSysTimeArray==NULL)) return FALSE;

  MONTHCAL_CopyTime(&infoPtr->maxDate, &lprgSysTimeArray[1]);
  MONTHCAL_CopyTime(&infoPtr->minDate, &lprgSysTimeArray[0]);

  return infoPtr->rangeValid;
}


static LRESULT
MONTHCAL_SetDayState(HWND hwnd, WPARAM wParam, LPARAM lParam)

{
  MONTHCAL_INFO *infoPtr = MONTHCAL_GetInfoPtr(hwnd);
  int i, iMonths = (int)wParam;
  MONTHDAYSTATE *dayStates = (LPMONTHDAYSTATE)lParam;

  TRACE("%x %lx\n", wParam, lParam);
  if(iMonths!=infoPtr->monthRange) return 0;

  for(i=0; i<iMonths; i++) 
    infoPtr->monthdayState[i] = dayStates[i];
  return 1;
}

static LRESULT 
MONTHCAL_GetCurSel(HWND hwnd, WPARAM wParam, LPARAM lParam)
{
  MONTHCAL_INFO *infoPtr = MONTHCAL_GetInfoPtr(hwnd);
  SYSTEMTIME *lpSel = (SYSTEMTIME *) lParam;

  TRACE("%x %lx\n", wParam, lParam);
  if((infoPtr==NULL) ||(lpSel==NULL)) return FALSE;
  if(GetWindowLongA(hwnd, GWL_STYLE) & MCS_MULTISELECT) return FALSE;

  MONTHCAL_CopyTime(&infoPtr->minSel, lpSel);
  return TRUE;
}

/* FIXME: if the specified date is not visible, make it visible */
/* FIXME: redraw? */
static LRESULT 
MONTHCAL_SetCurSel(HWND hwnd, WPARAM wParam, LPARAM lParam)
{
  MONTHCAL_INFO *infoPtr = MONTHCAL_GetInfoPtr(hwnd);
  SYSTEMTIME *lpSel = (SYSTEMTIME *)lParam;

  TRACE("%x %lx\n", wParam, lParam);
  if((infoPtr==NULL) ||(lpSel==NULL)) return FALSE;
  if(GetWindowLongA(hwnd, GWL_STYLE) & MCS_MULTISELECT) return FALSE;

  TRACE("%d %d\n", lpSel->wMonth, lpSel->wDay);

  MONTHCAL_CopyTime(lpSel, &infoPtr->minSel);
  MONTHCAL_CopyTime(lpSel, &infoPtr->maxSel);

  InvalidateRect(hwnd, NULL, FALSE);

  return TRUE;
}


static LRESULT 
MONTHCAL_GetMaxSelCount(HWND hwnd, WPARAM wParam, LPARAM lParam)
{
  MONTHCAL_INFO *infoPtr = MONTHCAL_GetInfoPtr(hwnd);

  TRACE("%x %lx\n", wParam, lParam);
  return infoPtr->maxSelCount;
}


static LRESULT 
MONTHCAL_SetMaxSelCount(HWND hwnd, WPARAM wParam, LPARAM lParam)
{
  MONTHCAL_INFO *infoPtr = MONTHCAL_GetInfoPtr(hwnd);

  TRACE("%x %lx\n", wParam, lParam);
  if(GetWindowLongA(hwnd, GWL_STYLE) & MCS_MULTISELECT)  {
    infoPtr->maxSelCount = wParam;
  }

  return TRUE;
}


static LRESULT 
MONTHCAL_GetSelRange(HWND hwnd, WPARAM wParam, LPARAM lParam)
{
  MONTHCAL_INFO *infoPtr = MONTHCAL_GetInfoPtr(hwnd);
  SYSTEMTIME *lprgSysTimeArray = (SYSTEMTIME *) lParam;

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

  /* validate parameters */

  if((infoPtr==NULL) ||(lprgSysTimeArray==NULL)) return FALSE;

  if(GetWindowLongA(hwnd, GWL_STYLE) & MCS_MULTISELECT)
  {
    MONTHCAL_CopyTime(&infoPtr->maxSel, &lprgSysTimeArray[1]);
    MONTHCAL_CopyTime(&infoPtr->minSel, &lprgSysTimeArray[0]);
    TRACE("[min,max]=[%d %d]\n", infoPtr->minSel.wDay, infoPtr->maxSel.wDay);
    return TRUE;
  }
 
  return FALSE;
}


static LRESULT 
MONTHCAL_SetSelRange(HWND hwnd, WPARAM wParam, LPARAM lParam)
{
  MONTHCAL_INFO *infoPtr = MONTHCAL_GetInfoPtr(hwnd);
  SYSTEMTIME *lprgSysTimeArray = (SYSTEMTIME *) lParam;

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

  /* validate parameters */

  if((infoPtr==NULL) ||(lprgSysTimeArray==NULL)) return FALSE;

  if(GetWindowLongA( hwnd, GWL_STYLE) & MCS_MULTISELECT)
  {
    MONTHCAL_CopyTime(&lprgSysTimeArray[1], &infoPtr->maxSel);
    MONTHCAL_CopyTime(&lprgSysTimeArray[0], &infoPtr->minSel);
    TRACE("[min,max]=[%d %d]\n", infoPtr->minSel.wDay, infoPtr->maxSel.wDay);
    return TRUE;
  }
 
  return FALSE;
}


static LRESULT 
MONTHCAL_GetToday(HWND hwnd, WPARAM wParam, LPARAM lParam)
{
  MONTHCAL_INFO *infoPtr = MONTHCAL_GetInfoPtr(hwnd);
  SYSTEMTIME *lpToday = (SYSTEMTIME *) lParam;

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

  /* validate parameters */

  if((infoPtr==NULL) || (lpToday==NULL)) return FALSE;
  MONTHCAL_CopyTime(&infoPtr->todaysDate, lpToday);
  return TRUE;
}


static LRESULT 
MONTHCAL_SetToday(HWND hwnd, WPARAM wParam, LPARAM lParam)
{
  MONTHCAL_INFO *infoPtr = MONTHCAL_GetInfoPtr(hwnd);
  SYSTEMTIME *lpToday = (SYSTEMTIME *) lParam;

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

  /* validate parameters */

  if((infoPtr==NULL) ||(lpToday==NULL)) return FALSE;
  MONTHCAL_CopyTime(lpToday, &infoPtr->todaysDate);
  InvalidateRect(hwnd, NULL, FALSE);
  return TRUE;
}


static LRESULT
MONTHCAL_HitTest(HWND hwnd, LPARAM lParam)
{
  MONTHCAL_INFO *infoPtr = MONTHCAL_GetInfoPtr(hwnd);
  PMCHITTESTINFO lpht = (PMCHITTESTINFO)lParam;
  UINT x,y;
  DWORD retval;
  int day,wday,wnum;
  
  
  x = lpht->pt.x;
  y = lpht->pt.y;
  retval = MCHT_NOWHERE;
  

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

  /* are we in the header? */
  
  if(PtInRect(&infoPtr->title, lpht->pt)) {
    if(PtInRect(&infoPtr->titlebtnprev, lpht->pt)) {
      retval = MCHT_TITLEBTNPREV;
      goto done;
    }
    if(PtInRect(&infoPtr->titlebtnnext, lpht->pt)) {
      retval = MCHT_TITLEBTNNEXT;
      goto done;
    }
    if(PtInRect(&infoPtr->titlemonth, lpht->pt)) {
      retval = MCHT_TITLEMONTH;
      goto done;
    }
    if(PtInRect(&infoPtr->titleyear, lpht->pt)) {
      retval = MCHT_TITLEYEAR;
      goto done;
    }
    
    retval = MCHT_TITLE;
    goto done;
  }
  
  day = MONTHCAL_CalcDayFromPos(infoPtr,x,y,&wday,&wnum);
  if(PtInRect(&infoPtr->wdays, lpht->pt)) {
    retval = MCHT_CALENDARDAY;
    lpht->st.wYear  = infoPtr->currentYear;
    lpht->st.wMonth = (day < 1)? infoPtr->currentMonth -1 : infoPtr->currentMonth;
    lpht->st.wDay   = (day < 1)? 
      MONTHCAL_MonthLength(infoPtr->currentMonth-1,infoPtr->currentYear) -day : day;
    goto done;
  }
  if(PtInRect(&infoPtr->weeknums, lpht->pt)) {  
    retval = MCHT_CALENDARWEEKNUM; 
    lpht->st.wYear  = infoPtr->currentYear;
    lpht->st.wMonth = (day < 1) ? infoPtr->currentMonth -1 : 
      (day > MONTHCAL_MonthLength(infoPtr->currentMonth,infoPtr->currentYear)) ? 
      infoPtr->currentMonth +1 :infoPtr->currentMonth;
    lpht->st.wDay   = (day < 1 ) ? 
      MONTHCAL_MonthLength(infoPtr->currentMonth-1,infoPtr->currentYear) -day : 
      (day > MONTHCAL_MonthLength(infoPtr->currentMonth,infoPtr->currentYear)) ? 
      day - MONTHCAL_MonthLength(infoPtr->currentMonth,infoPtr->currentYear) : day;
    goto done;				    
  }
  if(PtInRect(&infoPtr->days, lpht->pt)) 
    {
      lpht->st.wYear  = infoPtr->currentYear;
      if ( day < 1) 
	{
	  retval = MCHT_CALENDARDATEPREV;
	  lpht->st.wMonth = infoPtr->currentMonth - 1;
	  if (lpht->st.wMonth <1)
	    {
	      lpht->st.wMonth = 12;
	      lpht->st.wYear--;
	    }
	  lpht->st.wDay   = MONTHCAL_MonthLength(lpht->st.wMonth,lpht->st.wYear) -day;
	}
      else if (day > MONTHCAL_MonthLength(infoPtr->currentMonth,infoPtr->currentYear))
	{
	  retval = MCHT_CALENDARDATENEXT;
	  lpht->st.wMonth = infoPtr->currentMonth + 1;
	  if (lpht->st.wMonth <12)
	    {
	      lpht->st.wMonth = 1;
	      lpht->st.wYear++;
	    }
	  lpht->st.wDay   = day - MONTHCAL_MonthLength(infoPtr->currentMonth,infoPtr->currentYear) ;
	}
      else {
	retval = MCHT_CALENDARDATE;
	lpht->st.wMonth = infoPtr->currentMonth;
	lpht->st.wDay   = day;
      }
      goto done;
    }
  if(PtInRect(&infoPtr->todayrect, lpht->pt)) {
    retval = MCHT_TODAYLINK; 
    goto done;
  }
  
  
  /* Hit nothing special? What's left must be background :-) */
  
  retval = MCHT_CALENDARBK;       
 done: 
  lpht->uHit = retval;
  return retval;
}


static void MONTHCAL_GoToNextMonth(HWND hwnd, MONTHCAL_INFO *infoPtr)
{
  DWORD dwStyle = GetWindowLongA(hwnd, GWL_STYLE);

  TRACE("MONTHCAL_GoToNextMonth\n");

  infoPtr->currentMonth++;
  if(infoPtr->currentMonth > 12) {
    infoPtr->currentYear++;
    infoPtr->currentMonth = 1;
  }

  if(dwStyle & MCS_DAYSTATE) {
    NMDAYSTATE nmds;
    int i;

    nmds.nmhdr.hwndFrom = hwnd;
    nmds.nmhdr.idFrom   = GetWindowLongA(hwnd, GWL_ID);
    nmds.nmhdr.code     = MCN_GETDAYSTATE;
    nmds.cDayState	= infoPtr->monthRange;
    nmds.prgDayState	= COMCTL32_Alloc(infoPtr->monthRange * sizeof(MONTHDAYSTATE));

    SendMessageA(GetParent(hwnd), WM_NOTIFY,
    (WPARAM)nmds.nmhdr.idFrom, (LPARAM)&nmds);
    for(i=0; i<infoPtr->monthRange; i++)
      infoPtr->monthdayState[i] = nmds.prgDayState[i];
  }
}


static void MONTHCAL_GoToPrevMonth(HWND hwnd,  MONTHCAL_INFO *infoPtr)
{
  DWORD dwStyle = GetWindowLongA(hwnd, GWL_STYLE);

  TRACE("MONTHCAL_GoToPrevMonth\n");

  infoPtr->currentMonth--;
  if(infoPtr->currentMonth < 1) {
    infoPtr->currentYear--;
    infoPtr->currentMonth = 12;
  }

  if(dwStyle & MCS_DAYSTATE) {
    NMDAYSTATE nmds;
    int i;

    nmds.nmhdr.hwndFrom = hwnd;
    nmds.nmhdr.idFrom   = GetWindowLongA(hwnd, GWL_ID);
    nmds.nmhdr.code     = MCN_GETDAYSTATE;
    nmds.cDayState	= infoPtr->monthRange;
    nmds.prgDayState	= COMCTL32_Alloc 
                        (infoPtr->monthRange * sizeof(MONTHDAYSTATE));

    SendMessageA(GetParent(hwnd), WM_NOTIFY,
        (WPARAM)nmds.nmhdr.idFrom, (LPARAM)&nmds);
    for(i=0; i<infoPtr->monthRange; i++)
       infoPtr->monthdayState[i] = nmds.prgDayState[i];
  }
}

static LRESULT
MONTHCAL_RButtonDown(HWND hwnd, WPARAM wParam, LPARAM lParam)
{
  MONTHCAL_INFO *infoPtr = MONTHCAL_GetInfoPtr(hwnd);
  HMENU hMenu;
  POINT menupoint;
  char buf[32];
  
  hMenu = CreatePopupMenu();
  if (!LoadStringA(COMCTL32_hModule,IDM_GOTODAY,buf,sizeof(buf)))
    {
      WARN("Can't load resource\n");
      strcpy(buf,"Go to Today:");
    }
  AppendMenuA(hMenu, MF_STRING|MF_ENABLED,1, buf);
  menupoint.x=(INT)LOWORD(lParam);
  menupoint.y=(INT)HIWORD(lParam);
  ClientToScreen(hwnd, &menupoint);
  if( TrackPopupMenu(hMenu,TPM_RIGHTBUTTON| TPM_NONOTIFY|TPM_RETURNCMD,
		     menupoint.x,menupoint.y,0,hwnd,NULL))
    {
      infoPtr->currentMonth=infoPtr->todaysDate.wMonth;
      infoPtr->currentYear=infoPtr->todaysDate.wYear;
      InvalidateRect(hwnd, NULL, FALSE);
    }	
  return 0;
}

static LRESULT
MONTHCAL_LButtonDown(HWND hwnd, WPARAM wParam, LPARAM lParam)
{
  MONTHCAL_INFO *infoPtr = MONTHCAL_GetInfoPtr(hwnd);
  MCHITTESTINFO ht;
  DWORD hit;
  HMENU hMenu;
  RECT rcDay; /* used in determining area to invalidate */
  char buf[32];
  int i;
  POINT menupoint;
  TRACE("%x %lx\n", wParam, lParam);
	
  if (infoPtr->hWndYearUpDown)
    {
      infoPtr->currentYear=SendMessageA( infoPtr->hWndYearUpDown, UDM_SETPOS,   (WPARAM) 0,(LPARAM)0);
      if(!DestroyWindow(infoPtr->hWndYearUpDown))
	{
	  FIXME("Can't destroy Updown Control\n");
	}
      else
	infoPtr->hWndYearUpDown=0;
      if(!DestroyWindow(infoPtr->hWndYearEdit))
	{
	  FIXME("Can't destroy Updown Control\n");
	}
      else
	infoPtr->hWndYearEdit=0;
      InvalidateRect(hwnd, NULL, FALSE);
    }
  
  ht.pt.x = (INT)LOWORD(lParam);
  ht.pt.y = (INT)HIWORD(lParam);
  hit = MONTHCAL_HitTest(hwnd, (LPARAM)&ht);

  /* FIXME: these flags should be checked by */
  /*((hit & MCHT_XXX) == MCHT_XXX) b/c some of the flags are */
  /* multi-bit */
  if(hit ==MCHT_TITLEBTNNEXT) {
    MONTHCAL_GoToNextMonth(hwnd, infoPtr);
    infoPtr->status = MC_NEXTPRESSED;
    SetTimer(hwnd, MC_NEXTMONTHTIMER, MC_NEXTMONTHDELAY, 0);
    InvalidateRect(hwnd, NULL, FALSE);
    return TRUE;
  }
  if(hit == MCHT_TITLEBTNPREV){ 
    MONTHCAL_GoToPrevMonth(hwnd, infoPtr);
    infoPtr->status = MC_PREVPRESSED;
    SetTimer(hwnd, MC_PREVMONTHTIMER, MC_NEXTMONTHDELAY, 0);
    InvalidateRect(hwnd, NULL, FALSE);
    return TRUE;
  }

  if(hit == MCHT_TITLEMONTH) {
    hMenu = CreatePopupMenu();
    
    for (i=0; i<12;i++)
      {
	GetLocaleInfoA( LOCALE_USER_DEFAULT,LOCALE_SMONTHNAME1+i,
		  buf,sizeof(buf));
	AppendMenuA(hMenu, MF_STRING|MF_ENABLED,i+1, buf);
      }
    menupoint.x=infoPtr->titlemonth.right;
    menupoint.y=infoPtr->titlemonth.bottom;
    ClientToScreen(hwnd, &menupoint);
    i= TrackPopupMenu(hMenu,TPM_LEFTALIGN | TPM_NONOTIFY | TPM_RIGHTBUTTON | TPM_RETURNCMD,
		      menupoint.x,menupoint.y,0,hwnd,NULL);
    if ((i>0) && (i<13))
      {
	infoPtr->currentMonth=i;
	InvalidateRect(hwnd, NULL, FALSE);
      }
  }
  if(hit == MCHT_TITLEYEAR) {
    infoPtr->hWndYearEdit=CreateWindowExA(0,
			 "EDIT",
			   0,
			 WS_VISIBLE | WS_CHILD |UDS_SETBUDDYINT,
			 infoPtr->titleyear.left+3,infoPtr->titlebtnnext.top,
			 infoPtr->titleyear.right-infoPtr->titleyear.left,
			 infoPtr->textHeight,
			 hwnd,
			 (HMENU)NULL, 
			 (HINSTANCE)NULL, 
			 NULL);
    infoPtr->hWndYearUpDown=CreateWindowExA(0,
			 UPDOWN_CLASSA,
			   0,
			 WS_VISIBLE | WS_CHILD |UDS_SETBUDDYINT|UDS_NOTHOUSANDS|UDS_ARROWKEYS,
			 infoPtr->titleyear.right+6,infoPtr->titlebtnnext.top,
			 20,
			 infoPtr->textHeight,
			 hwnd,
			 (HMENU)NULL, 
			 (HINSTANCE)NULL, 
			 NULL);
    SendMessageA( infoPtr->hWndYearUpDown, UDM_SETRANGE, (WPARAM) 0, MAKELONG (9999, 1753));
    SendMessageA( infoPtr->hWndYearUpDown, UDM_SETBUDDY, (WPARAM) infoPtr->hWndYearEdit, (LPARAM)0 );
    SendMessageA( infoPtr->hWndYearUpDown, UDM_SETPOS,   (WPARAM) 0,(LPARAM)infoPtr->currentYear );
    return TRUE;
	 
  }
  if(hit == MCHT_TODAYLINK) {
    infoPtr->currentMonth=infoPtr->todaysDate.wMonth;
    infoPtr->currentYear=infoPtr->todaysDate.wYear;
    InvalidateRect(hwnd, NULL, FALSE);
    return TRUE;
  }
  if(hit && MCHT_CALENDARDATE) {
    SYSTEMTIME selArray[2];
    NMSELCHANGE nmsc;

    TRACE("MCHT_CALENDARDATE\n");
    nmsc.nmhdr.hwndFrom = hwnd;
    nmsc.nmhdr.idFrom   = GetWindowLongA(hwnd, GWL_ID);
    nmsc.nmhdr.code     = MCN_SELCHANGE;
    MONTHCAL_CopyTime(&nmsc.stSelStart, &infoPtr->minSel);
    MONTHCAL_CopyTime(&nmsc.stSelEnd, &infoPtr->maxSel);
	
    SendMessageA(GetParent(hwnd), WM_NOTIFY,
           (WPARAM)nmsc.nmhdr.idFrom,(LPARAM)&nmsc);

    MONTHCAL_CopyTime(&ht.st, &selArray[0]);
    MONTHCAL_CopyTime(&ht.st, &selArray[1]);
    MONTHCAL_SetSelRange(hwnd,0,(LPARAM) &selArray); 

    /* redraw both old and new days if the selected day changed */
    if(infoPtr->curSelDay != ht.st.wDay) {
      MONTHCAL_CalcPosFromDay(infoPtr, ht.st.wDay, ht.st.wMonth, &rcDay);
      InvalidateRect(hwnd, &rcDay, TRUE);

      MONTHCAL_CalcPosFromDay(infoPtr, infoPtr->curSelDay, infoPtr->currentMonth, &rcDay);
      InvalidateRect(hwnd, &rcDay, TRUE);
    }

    infoPtr->firstSelDay = ht.st.wDay;
    infoPtr->curSelDay = ht.st.wDay;
    infoPtr->status = MC_SEL_LBUTDOWN;
    return TRUE;
  }

  return 0;
}


static LRESULT
MONTHCAL_LButtonUp(HWND hwnd, WPARAM wParam, LPARAM lParam)
{
  MONTHCAL_INFO *infoPtr = MONTHCAL_GetInfoPtr(hwnd);
  NMSELCHANGE nmsc;
  NMHDR nmhdr;
  BOOL redraw = FALSE;
  MCHITTESTINFO ht;
  DWORD hit;

  TRACE("\n");

  if(infoPtr->status & MC_NEXTPRESSED) {
    KillTimer(hwnd, MC_NEXTMONTHTIMER);
    redraw = TRUE;
  }
  if(infoPtr->status & MC_PREVPRESSED) {
    KillTimer(hwnd, MC_PREVMONTHTIMER);
    redraw = TRUE;
  }

  ht.pt.x = (INT)LOWORD(lParam);
  ht.pt.y = (INT)HIWORD(lParam);
  hit = MONTHCAL_HitTest(hwnd, (LPARAM)&ht);

  infoPtr->status = MC_SEL_LBUTUP;

  if(hit ==MCHT_CALENDARDATENEXT) {
    MONTHCAL_GoToNextMonth(hwnd, infoPtr);
    InvalidateRect(hwnd, NULL, FALSE);
    return TRUE;
  }
  if(hit == MCHT_CALENDARDATEPREV){ 
    MONTHCAL_GoToPrevMonth(hwnd, infoPtr);
    InvalidateRect(hwnd, NULL, FALSE);
    return TRUE;
  }
  nmhdr.hwndFrom = hwnd;
  nmhdr.idFrom   = GetWindowLongA( hwnd, GWL_ID);
  nmhdr.code     = NM_RELEASEDCAPTURE;
  TRACE("Sent notification from %x to %x\n", hwnd, GetParent(hwnd));

  SendMessageA(GetParent(hwnd), WM_NOTIFY,
                                (WPARAM)nmhdr.idFrom, (LPARAM)&nmhdr);

  nmsc.nmhdr.hwndFrom = hwnd;
  nmsc.nmhdr.idFrom   = GetWindowLongA(hwnd, GWL_ID);
  nmsc.nmhdr.code     = MCN_SELECT;
  MONTHCAL_CopyTime(&nmsc.stSelStart, &infoPtr->minSel);
  MONTHCAL_CopyTime(&nmsc.stSelEnd, &infoPtr->maxSel);
	
  SendMessageA(GetParent(hwnd), WM_NOTIFY,
           (WPARAM)nmsc.nmhdr.idFrom, (LPARAM)&nmsc);
  
  /* redraw if necessary */
  if(redraw)
    InvalidateRect(hwnd, NULL, FALSE);
	
  return 0;
}


static LRESULT
MONTHCAL_Timer(HWND hwnd, WPARAM wParam, LPARAM lParam)
{
  MONTHCAL_INFO *infoPtr = MONTHCAL_GetInfoPtr(hwnd);
  BOOL redraw = FALSE;

  TRACE(" %d\n", wParam);
  if(!infoPtr) return 0;

  switch(wParam) {
  case MC_NEXTMONTHTIMER: 
    redraw = TRUE;
    MONTHCAL_GoToNextMonth(hwnd, infoPtr);
    break;
  case MC_PREVMONTHTIMER:
    redraw = TRUE;
    MONTHCAL_GoToPrevMonth(hwnd, infoPtr);
    break;
  default:
    ERR("got unknown timer\n");
  }

  /* redraw only if necessary */
  if(redraw)
    InvalidateRect(hwnd, NULL, FALSE);

  return 0;
}


static LRESULT
MONTHCAL_MouseMove(HWND hwnd, WPARAM wParam, LPARAM lParam)
{
  MONTHCAL_INFO *infoPtr = MONTHCAL_GetInfoPtr(hwnd);
  MCHITTESTINFO ht;
  int oldselday, selday, hit;
  RECT r;

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

  ht.pt.x = LOWORD(lParam);
  ht.pt.y = HIWORD(lParam);
	
  hit = MONTHCAL_HitTest(hwnd, (LPARAM)&ht);
  
  /* not on the calendar date numbers? bail out */
  TRACE("hit:%x\n",hit);
  if((hit & MCHT_CALENDARDATE) != MCHT_CALENDARDATE) return 0;

  selday = ht.st.wDay;
  oldselday = infoPtr->curSelDay;
  infoPtr->curSelDay = selday;
  MONTHCAL_CalcPosFromDay(infoPtr, selday, ht.st. wMonth, &r);

  if(GetWindowLongA(hwnd, GWL_STYLE) & MCS_MULTISELECT)  {
    SYSTEMTIME selArray[2];
    int i;

    MONTHCAL_GetSelRange(hwnd, 0, (LPARAM)&selArray);
    i = 0;
    if(infoPtr->firstSelDay==selArray[0].wDay) i=1;
    TRACE("oldRange:%d %d %d %d\n", infoPtr->firstSelDay, selArray[0].wDay, selArray[1].wDay, i);
    if(infoPtr->firstSelDay==selArray[1].wDay) {  
      /* 1st time we get here: selArray[0]=selArray[1])  */
      /* if we're still at the first selected date, return */
      if(infoPtr->firstSelDay==selday) goto done;
      if(selday<infoPtr->firstSelDay) i = 0;
    }
			
    if(abs(infoPtr->firstSelDay - selday) >= infoPtr->maxSelCount) {
      if(selday>infoPtr->firstSelDay)
        selday = infoPtr->firstSelDay + infoPtr->maxSelCount;
      else
        selday = infoPtr->firstSelDay - infoPtr->maxSelCount;
    }
		
    if(selArray[i].wDay!=selday) {
      TRACE("newRange:%d %d %d %d\n", infoPtr->firstSelDay, selArray[0].wDay, selArray[1].wDay, i);
			
      selArray[i].wDay = selday;

      if(selArray[0].wDay>selArray[1].wDay) {
        DWORD tempday;
        tempday = selArray[1].wDay;
        selArray[1].wDay = selArray[0].wDay;
        selArray[0].wDay = tempday;
      }

      MONTHCAL_SetSelRange(hwnd, 0, (LPARAM)&selArray);
    }
  }

done:

  /* only redraw if the currently selected day changed */
  /* FIXME: this should specify a rectangle containing only the days that changed */
  /* using InvalidateRect */
  if(oldselday != infoPtr->curSelDay)
    InvalidateRect(hwnd, NULL, FALSE);

  return 0;
}


static LRESULT
MONTHCAL_Paint(HWND hwnd, WPARAM wParam)
{
  MONTHCAL_INFO *infoPtr = MONTHCAL_GetInfoPtr(hwnd);
  HDC hdc;
  PAINTSTRUCT ps;

  /* fill ps.rcPaint with a default rect */
  memcpy(&(ps.rcPaint), &(infoPtr->rcClient), sizeof(infoPtr->rcClient));

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


static LRESULT
MONTHCAL_KillFocus(HWND hwnd, WPARAM wParam, LPARAM lParam)
{
  TRACE("\n");

  InvalidateRect(hwnd, NULL, TRUE);

  return 0;
}


static LRESULT
MONTHCAL_SetFocus(HWND hwnd, WPARAM wParam, LPARAM lParam)
{
  TRACE("\n");
  
  InvalidateRect(hwnd, NULL, FALSE);

  return 0;
}

/* sets the size information */
static void MONTHCAL_UpdateSize(HWND hwnd)
{
  HDC hdc = GetDC(hwnd);
  MONTHCAL_INFO *infoPtr = MONTHCAL_GetInfoPtr(hwnd);
  RECT *rcClient=&infoPtr->rcClient;
  RECT *rcDraw=&infoPtr->rcDraw;
  RECT *title=&infoPtr->title;
  RECT *prev=&infoPtr->titlebtnprev;
  RECT *next=&infoPtr->titlebtnnext;
  RECT *titlemonth=&infoPtr->titlemonth;
  RECT *titleyear=&infoPtr->titleyear;
  RECT *wdays=&infoPtr->wdays;
  RECT *weeknumrect=&infoPtr->weeknums;
  RECT *days=&infoPtr->days;
  RECT *todayrect=&infoPtr->todayrect;
  SIZE size;
  TEXTMETRICA tm;
  DWORD dwStyle = GetWindowLongA(hwnd, GWL_STYLE);
  HFONT currentFont;
  double xdiv;

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

  /* FIXME: need a way to determine current font, without setting it */
  /*
  if(infoPtr->hFont!=currentFont) {
    SelectObject(hdc, currentFont);
    infoPtr->hFont=currentFont;
    GetObjectA(currentFont, sizeof(LOGFONTA), &logFont);
    logFont.lfWeight=FW_BOLD;
    infoPtr->hBoldFont = CreateFontIndirectA(&logFont);
  }
  */

  /* get the height and width of each day's text */
  GetTextMetricsA(hdc, &tm);
  infoPtr->textHeight = tm.tmHeight + tm.tmExternalLeading;
  GetTextExtentPoint32A(hdc, "Sun", 3, &size);
  infoPtr->textWidth = size.cx + 2;

  /* retrieve the controls client rectangle info infoPtr->rcClient */
  GetClientRect(hwnd, rcClient);

  /* rcDraw is the rectangle the control is drawn in */
  rcDraw->left = rcClient->left;
  rcDraw->right = rcClient->right;
  rcDraw->top = rcClient->top;
  rcDraw->bottom = rcClient->bottom;

  /* recalculate the height and width increments and offsets */
  /* FIXME: We use up all available width. This will inhibit having multiple 
     calendars in a row, like win doesn 
  */
  if(dwStyle & MCS_WEEKNUMBERS)
    xdiv=8.0;
  else
    xdiv=7.0;
  infoPtr->width_increment = (infoPtr->rcDraw.right - infoPtr->rcDraw.left) / xdiv; 
  infoPtr->height_increment = (infoPtr->rcDraw.bottom - infoPtr->rcDraw.top) / 10.0; 
  infoPtr->left_offset = (infoPtr->rcDraw.right - infoPtr->rcDraw.left) - (infoPtr->width_increment * xdiv);
  infoPtr->top_offset = (infoPtr->rcDraw.bottom - infoPtr->rcDraw.top) - (infoPtr->height_increment * 10.0);

  rcDraw->bottom = rcDraw->top + 10 * infoPtr->height_increment;
  /* this is correct, the control does NOT expand vertically */
  /* like it does horizontally */
  /* make sure we don't move the controls bottom out of the client */
  /* area */
  /* title line has about 3 text heights, abrev days line, 6 weeksline and today circle line*/
  /*if((rcDraw->top + 9 * infoPtr->textHeight + 5) < rcDraw->bottom) {
    rcDraw->bottom = rcDraw->top + 9 * infoPtr->textHeight + 5;
    }*/
   
  /* calculate title area */
  title->top    = rcClient->top;
  title->bottom = title->top + 2 * infoPtr->height_increment;
  title->left   = rcClient->left;
  title->right  = rcClient->right;

  /* set the dimensions of the next and previous buttons and center */
  /* the month text vertically */
  prev->top    = next->top    = title->top + 6;
  prev->bottom = next->bottom = title->bottom - 6;
  prev->left   = title->left  + 6;
  prev->right  = prev->left + (title->bottom - title->top) ;
  next->right  = title->right - 6;
  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 =infoPtr->left_offset;
  if(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   = rcClient->left;
  todayrect->right  = rcClient->right;
  todayrect->top    = days->bottom;
  todayrect->bottom = days->bottom + infoPtr->height_increment;

  /* uncomment for excessive debugging 
  TRACE("dx=%d dy=%d rcC[%d %d %d %d] t[%d %d %d %d] wd[%d %d %d %d] w[%d %d %d %d] t[%d %d %d %d]\n",
	infoPtr->width_increment,infoPtr->height_increment,
	 rcClient->left, rcClient->right, rcClient->top, rcClient->bottom,
	    title->left,    title->right,    title->top,    title->bottom,
	    wdays->left,    wdays->right,    wdays->top,    wdays->bottom,
	     days->left,     days->right,     days->top,     days->bottom,
	todayrect->left,todayrect->right,todayrect->top,todayrect->bottom);
  */
  
  /* restore the originally selected font */
  SelectObject(hdc, currentFont);     

  ReleaseDC(hwnd, hdc);
}

static LRESULT MONTHCAL_Size(HWND hwnd, int Width, int Height)
{
  TRACE("(hwnd=%x, width=%d, height=%d)\n", hwnd, Width, Height);

  MONTHCAL_UpdateSize(hwnd);

  /* invalidate client area and erase background */
  InvalidateRect(hwnd, NULL, TRUE);

  return 0;
}

/* FIXME: check whether dateMin/dateMax need to be adjusted. */
static LRESULT
MONTHCAL_Create(HWND hwnd, WPARAM wParam, LPARAM lParam)
{
  MONTHCAL_INFO *infoPtr;
  LOGFONTA	logFont;

  /* allocate memory for info structure */
  infoPtr =(MONTHCAL_INFO*)COMCTL32_Alloc(sizeof(MONTHCAL_INFO));
  SetWindowLongA(hwnd, 0, (DWORD)infoPtr);

  if(infoPtr == NULL) {
    ERR( "could not allocate info memory!\n");
    return 0;
  }
  if((MONTHCAL_INFO*)GetWindowLongA(hwnd, 0) != infoPtr) {
    ERR( "pointer assignment error!\n");
    return 0;
  }

  infoPtr->hFont = GetStockObject(DEFAULT_GUI_FONT);
  GetObjectA(infoPtr->hFont, sizeof(LOGFONTA), &logFont);
  logFont.lfWeight = FW_BOLD;
  infoPtr->hBoldFont = CreateFontIndirectA(&logFont);

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

  GetSystemTime(&infoPtr->todaysDate);
  MONTHCAL_SetFirstDayOfWeek(hwnd,0,(LPARAM)-1);
  infoPtr->currentMonth = infoPtr->todaysDate.wMonth;
  infoPtr->currentYear = infoPtr->todaysDate.wYear;
  MONTHCAL_CopyTime(&infoPtr->todaysDate, &infoPtr->minDate);
  MONTHCAL_CopyTime(&infoPtr->todaysDate, &infoPtr->maxDate);
  infoPtr->maxSelCount  = 7;
  infoPtr->monthRange = 3;
  infoPtr->monthdayState = COMCTL32_Alloc 
                         (infoPtr->monthRange * sizeof(MONTHDAYSTATE));
  infoPtr->titlebk     = GetSysColor(COLOR_ACTIVECAPTION);
  infoPtr->titletxt    = GetSysColor(COLOR_WINDOW);
  infoPtr->monthbk     = GetSysColor(COLOR_WINDOW);
  infoPtr->trailingtxt = GetSysColor(COLOR_GRAYTEXT);
  infoPtr->bk          = GetSysColor(COLOR_WINDOW);
  infoPtr->txt	       = GetSysColor(COLOR_WINDOWTEXT);

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

  return 0;
}


static LRESULT
MONTHCAL_Destroy(HWND hwnd, WPARAM wParam, LPARAM lParam)
{
  MONTHCAL_INFO *infoPtr = MONTHCAL_GetInfoPtr(hwnd);

  /* free month calendar info data */
  COMCTL32_Free(infoPtr);
  SetWindowLongA(hwnd, 0, 0);
  return 0;
}


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

  case MCM_SETCURSEL:
    return MONTHCAL_SetCurSel(hwnd, wParam, lParam);

  case MCM_GETMAXSELCOUNT:
    return MONTHCAL_GetMaxSelCount(hwnd, wParam, lParam);

  case MCM_SETMAXSELCOUNT:
    return MONTHCAL_SetMaxSelCount(hwnd, wParam, lParam);

  case MCM_GETSELRANGE:
    return MONTHCAL_GetSelRange(hwnd, wParam, lParam);

  case MCM_SETSELRANGE:
    return MONTHCAL_SetSelRange(hwnd, wParam, lParam);

  case MCM_GETMONTHRANGE:
    return MONTHCAL_GetMonthRange(hwnd, wParam, lParam);

  case MCM_SETDAYSTATE:
    return MONTHCAL_SetDayState(hwnd, wParam, lParam);

  case MCM_GETMINREQRECT:
    return MONTHCAL_GetMinReqRect(hwnd, wParam, lParam);

  case MCM_GETCOLOR:
    return MONTHCAL_GetColor(hwnd, wParam, lParam);

  case MCM_SETCOLOR:
    return MONTHCAL_SetColor(hwnd, wParam, lParam);

  case MCM_GETTODAY:
    return MONTHCAL_GetToday(hwnd, wParam, lParam);

  case MCM_SETTODAY:
    return MONTHCAL_SetToday(hwnd, wParam, lParam);

  case MCM_HITTEST:
    return MONTHCAL_HitTest(hwnd,lParam);

  case MCM_GETFIRSTDAYOFWEEK:
    return MONTHCAL_GetFirstDayOfWeek(hwnd, wParam, lParam);

  case MCM_SETFIRSTDAYOFWEEK:
    return MONTHCAL_SetFirstDayOfWeek(hwnd, wParam, lParam);

  case MCM_GETRANGE:
    return MONTHCAL_GetRange(hwnd, wParam, lParam);

  case MCM_SETRANGE:
    return MONTHCAL_SetRange(hwnd, wParam, lParam);

  case MCM_GETMONTHDELTA:
    return MONTHCAL_GetMonthDelta(hwnd, wParam, lParam);

  case MCM_SETMONTHDELTA:
    return MONTHCAL_SetMonthDelta(hwnd, wParam, lParam);

  case MCM_GETMAXTODAYWIDTH:
    return MONTHCAL_GetMaxTodayWidth(hwnd);

  case WM_GETDLGCODE:
    return DLGC_WANTARROWS | DLGC_WANTCHARS;

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

  case WM_RBUTTONDOWN:
    return MONTHCAL_RButtonDown(hwnd, wParam, lParam);

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

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

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

  case WM_PAINT:
    return MONTHCAL_Paint(hwnd, wParam);

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

  case WM_SIZE:
    return MONTHCAL_Size(hwnd, (int)SLOWORD(lParam), (int)SHIWORD(lParam));

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

  case WM_TIMER:
    return MONTHCAL_Timer(hwnd, wParam, lParam);

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

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


void
MONTHCAL_Register(void)
{
  WNDCLASSA wndClass;

  ZeroMemory(&wndClass, sizeof(WNDCLASSA));
  wndClass.style         = CS_GLOBALCLASS;
  wndClass.lpfnWndProc   = (WNDPROC)MONTHCAL_WindowProc;
  wndClass.cbClsExtra    = 0;
  wndClass.cbWndExtra    = sizeof(MONTHCAL_INFO *);
  wndClass.hCursor       = LoadCursorA(0, IDC_ARROWA);
  wndClass.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
  wndClass.lpszClassName = MONTHCAL_CLASSA;
 
  RegisterClassA(&wndClass);
}


void
MONTHCAL_Unregister(void)
{
    UnregisterClassA(MONTHCAL_CLASSA, (HINSTANCE)NULL);
}
