/*
 * Date and time picker control
 *
 * Copyright 1998, 1999 Eric Kohl
 * Copyright 1999 Alex Priem <alexp@sci.kun.nl>
 *
 *
 * TODO:
 *   - All messages.
 *   - All notifications.
 *
 */

#include "winbase.h"
#include "commctrl.h"
#include "datetime.h"
#include "monthcal.h"
#include "debugtools.h"

DEFAULT_DEBUG_CHANNEL(datetime)



#define DATETIME_GetInfoPtr(hwnd) ((DATETIME_INFO *)GetWindowLongA (hwnd, 0))
static BOOL

DATETIME_SendSimpleNotify (HWND hwnd, UINT code);

extern char *days[];  /* from ole/parsedt.c */


static LRESULT
DATETIME_GetSystemTime (HWND hwnd, WPARAM wParam, LPARAM lParam )
{
  DATETIME_INFO *infoPtr = DATETIME_GetInfoPtr (hwnd);
  DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
  SYSTEMTIME *lprgSysTimeArray=(SYSTEMTIME *) lParam;

  if (!lParam) return GDT_NONE;

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

  MONTHCAL_CopyTime (&infoPtr->date, lprgSysTimeArray);

  return GDT_VALID;
}


static LRESULT
DATETIME_SetSystemTime (HWND hwnd, WPARAM wParam, LPARAM lParam )
{
  DATETIME_INFO *infoPtr = DATETIME_GetInfoPtr (hwnd);
  SYSTEMTIME *lprgSysTimeArray=(SYSTEMTIME *) lParam;

  if (!lParam) return 0;

  if (lParam==GDT_VALID) 
  	MONTHCAL_CopyTime (lprgSysTimeArray, &infoPtr->date);
  if (lParam==GDT_NONE) {
	infoPtr->dateValid=FALSE;
    SendMessageA (infoPtr->hwndCheckbut, BM_SETCHECK, 0, 0);
	}
  return 1;
}


static LRESULT
DATETIME_GetMonthCalColor (HWND hwnd, WPARAM wParam)
{
  DATETIME_INFO *infoPtr = DATETIME_GetInfoPtr (hwnd);

  return SendMessageA (infoPtr->hMonthCal, MCM_GETCOLOR, wParam, 0);
}

static LRESULT
DATETIME_SetMonthCalColor (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
  DATETIME_INFO *infoPtr = DATETIME_GetInfoPtr (hwnd);

  return SendMessageA (infoPtr->hMonthCal, MCM_SETCOLOR, wParam, lParam);
}


/* FIXME: need to get way to force font into monthcal structure */

static LRESULT
DATETIME_GetMonthCal (HWND hwnd)
{
  DATETIME_INFO *infoPtr = DATETIME_GetInfoPtr (hwnd);

  return infoPtr->hMonthCal;
}



/* FIXME: need to get way to force font into monthcal structure */

static LRESULT
DATETIME_GetMonthCalFont (HWND hwnd)
{

  return 0;
}

static LRESULT
DATETIME_SetMonthCalFont (HWND hwnd, WPARAM wParam, LPARAM lParam)
{

  return 0;
}


static void DATETIME_Refresh (HWND hwnd, HDC hdc)

{
  DATETIME_INFO *infoPtr = DATETIME_GetInfoPtr (hwnd);
  RECT *daytxt   = &infoPtr->daytxt;
  RECT *daynumtxt= &infoPtr->daynumtxt;
  RECT *rmonthtxt= &infoPtr->rmonthtxt;
  RECT *yeartxt  = &infoPtr->yeartxt;
  RECT *calbutton= &infoPtr->calbutton;
  RECT *checkbox = &infoPtr->checkbox;
  RECT *rect     = &infoPtr->rect;
  DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
  SYSTEMTIME date = infoPtr->date;
  SIZE size;
  BOOL prssed=FALSE;
  COLORREF oldBk;
  

	
  if (infoPtr->dateValid) {
    char txt[80];
	HFONT oldFont;
  	oldFont = SelectObject (hdc, infoPtr->hFont);

	GetClientRect (hwnd, rect);

	sprintf (txt,"%s,",days[date.wDayOfWeek]);
	GetTextExtentPoint32A (hdc, txt, strlen (txt), &size);
	rect->bottom=size.cy+2;

	checkbox->left  = 0;
	checkbox->right = 0;
	checkbox->top   = rect->top;
	checkbox->bottom= rect->bottom;
    if (dwStyle & DTS_SHOWNONE) {    /* FIXME: draw checkbox */
		checkbox->right=18;
		}


	if (infoPtr->select==(DTHT_DAY|DTHT_GOTFOCUS))
		oldBk=SetBkColor (hdc, COLOR_GRAYTEXT);
       daytxt->left  = checkbox->right;
       daytxt->right = checkbox->right+size.cx;
       daytxt->top   = rect->top;
       daytxt->bottom= rect->bottom;
       DrawTextA ( hdc, txt, strlen(txt), daytxt,
                         DT_LEFT | DT_VCENTER | DT_SINGLELINE );
	if (infoPtr->select==(DTHT_DAY|DTHT_GOTFOCUS)) 
		SetBkColor (hdc, oldBk);

	if (infoPtr->select==(DTHT_MONTH|DTHT_GOTFOCUS)) 
		oldBk=SetBkColor (hdc, COLOR_GRAYTEXT);
	strcpy (txt, monthtxt[date.wMonth]);
	GetTextExtentPoint32A (hdc, "September", 9, &size);
       rmonthtxt->left  = daytxt->right;
       rmonthtxt->right = daytxt->right+size.cx;
	rmonthtxt->top   = rect->top;
	rmonthtxt->bottom= rect->bottom;
	DrawTextA ( hdc, txt, strlen(txt), rmonthtxt,
                         DT_CENTER | DT_VCENTER | DT_SINGLELINE );
	if (infoPtr->select==(DTHT_MONTH|DTHT_GOTFOCUS)) 
		SetBkColor (hdc, oldBk);

	if (infoPtr->select==(DTHT_DAYNUM|DTHT_GOTFOCUS)) 
		oldBk=SetBkColor (hdc, COLOR_GRAYTEXT);
	sprintf (txt,"%d,",date.wDay);
	GetTextExtentPoint32A (hdc, "31,", 3, &size);
       daynumtxt->left  = rmonthtxt->right;
       daynumtxt->right = rmonthtxt->right+size.cx;
	daynumtxt->top   = rect->top;
	daynumtxt->bottom= rect->bottom;
	DrawTextA ( hdc, txt, strlen(txt), daynumtxt,
                         DT_RIGHT | DT_VCENTER | DT_SINGLELINE );
	if (infoPtr->select==(DTHT_DAYNUM|DTHT_GOTFOCUS)) 
		SetBkColor (hdc, oldBk);

	if (infoPtr->select==(DTHT_YEAR|DTHT_GOTFOCUS)) 
		oldBk=SetBkColor (hdc, COLOR_GRAYTEXT);
	sprintf (txt,"%d",date.wYear);
	GetTextExtentPoint32A (hdc, "2000", 5, &size);
       yeartxt->left  = daynumtxt->right;
       yeartxt->right = daynumtxt->right+size.cx;
	yeartxt->top   = rect->top;
	yeartxt->bottom= rect->bottom;
	DrawTextA ( hdc, txt, strlen(txt), yeartxt,
                         DT_RIGHT | DT_VCENTER | DT_SINGLELINE );
	if (infoPtr->select==(DTHT_YEAR|DTHT_GOTFOCUS)) 
		SetBkColor (hdc, oldBk);
	
  	SelectObject (hdc, oldFont);
	}

	if (!(dwStyle & DTS_UPDOWN)) {

		calbutton->right = rect->right;
		calbutton->left  = rect->right-15;
		calbutton->top   = rect->top;
		calbutton->bottom= rect->bottom;

    	DrawFrameControl(hdc, calbutton, DFC_SCROLL,
        	DFCS_SCROLLDOWN | (prssed ? DFCS_PUSHED : 0) |
        	(dwStyle & WS_DISABLED ? DFCS_INACTIVE : 0) );
	}

}

static LRESULT
DATETIME_HitTest (HWND hwnd, DATETIME_INFO *infoPtr, POINT pt)
{
  TRACE ("%ld, %ld\n",pt.x,pt.y);

  if (PtInRect (&infoPtr->calbutton, pt)) return DTHT_MCPOPUP;
  if (PtInRect (&infoPtr->yeartxt, pt))   return DTHT_YEAR;
  if (PtInRect (&infoPtr->daynumtxt, pt)) return DTHT_DAYNUM;
  if (PtInRect (&infoPtr->rmonthtxt, pt)) return DTHT_MONTH;
  if (PtInRect (&infoPtr->daytxt, pt))    return DTHT_DAY;
  if (PtInRect (&infoPtr->checkbox, pt))  return DTHT_CHECKBOX;

  return 0;
}

static LRESULT
DATETIME_LButtonDown (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
    DATETIME_INFO *infoPtr = DATETIME_GetInfoPtr (hwnd);	
	POINT pt;
	int old;

    TRACE ("\n");

	old=infoPtr->select;
    pt.x=(INT)LOWORD(lParam);
    pt.y=(INT)HIWORD(lParam);
    infoPtr->select=DATETIME_HitTest (hwnd, infoPtr, pt);
                           
	if (infoPtr->select!=old) {
		HDC hdc;

		SetFocus (hwnd);
		hdc=GetDC (hwnd);
		DATETIME_Refresh (hwnd,hdc);
        ReleaseDC (hwnd, hdc);
    }
	if (infoPtr->select==DTHT_MCPOPUP) {
			POINT pt;

			pt.x=8;
			pt.y=infoPtr->rect.bottom+5;
			ClientToScreen (hwnd, &pt);
			infoPtr->hMonthCal=CreateWindowExA (0,"SysMonthCal32", 0, 
				WS_POPUP | WS_BORDER,
				pt.x,pt.y,145,150,
				GetParent (hwnd), 
				0,0,0);

			TRACE ("dt:%x mc:%x mc parent:%x, desktop:%x, mcpp:%x\n",
                      hwnd,infoPtr->hMonthCal, 
                      GetParent (infoPtr->hMonthCal),
                      GetDesktopWindow (),
                      GetParent (GetParent (infoPtr->hMonthCal)));

			SetFocus (hwnd);
			DATETIME_SendSimpleNotify (hwnd, DTN_DROPDOWN);
	}
    return 0;
}


static LRESULT
DATETIME_Paint (HWND hwnd, WPARAM wParam)
{
    HDC hdc;
    PAINTSTRUCT ps;

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

static LRESULT
DATETIME_ParentNotify (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
    DATETIME_INFO *infoPtr = DATETIME_GetInfoPtr (hwnd);	
	LPNMHDR lpnmh=(LPNMHDR) lParam;

	TRACE ("%x,%lx\n",wParam, lParam);
	TRACE ("Got notification %x from %x\n", lpnmh->code, lpnmh->hwndFrom);
	TRACE ("info: %x %x %x\n",hwnd,infoPtr->hMonthCal,infoPtr->hUpdown);
	return 0;
}

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

{
    DATETIME_INFO *infoPtr = DATETIME_GetInfoPtr (hwnd);	
	LPNMHDR lpnmh=(LPNMHDR) lParam;

	TRACE ("%x,%lx\n",wParam, lParam);
	TRACE ("Got notification %x from %x\n", lpnmh->code, lpnmh->hwndFrom);
	TRACE ("info: %x %x %x\n",hwnd,infoPtr->hMonthCal,infoPtr->hUpdown);
	return 0;
}

static LRESULT
DATETIME_KillFocus (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
    DATETIME_INFO *infoPtr = DATETIME_GetInfoPtr (hwnd);	
    HDC hdc;

    TRACE ("\n");

	if (infoPtr->select) {
			DATETIME_SendSimpleNotify (hwnd, NM_KILLFOCUS);
			infoPtr->select&= ~DTHT_GOTFOCUS;
	}
    hdc = GetDC (hwnd);
    DATETIME_Refresh (hwnd, hdc);
    ReleaseDC (hwnd, hdc);
    InvalidateRect (hwnd, NULL, TRUE);

    return 0;
}


static LRESULT
DATETIME_SetFocus (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
    HDC hdc;
    DATETIME_INFO *infoPtr = DATETIME_GetInfoPtr (hwnd);	

    TRACE ("\n");

	if (infoPtr->select) {
			DATETIME_SendSimpleNotify (hwnd, NM_SETFOCUS);	
			infoPtr->select|=DTHT_GOTFOCUS;
	}
    hdc = GetDC (hwnd);
    DATETIME_Refresh (hwnd, hdc);
    ReleaseDC (hwnd, hdc);

    return 0;
}


static BOOL
DATETIME_SendSimpleNotify (HWND hwnd, UINT code)
{
    NMHDR nmhdr;

    TRACE("%x\n",code);
    nmhdr.hwndFrom = hwnd;
    nmhdr.idFrom   = GetWindowLongA( hwnd, GWL_ID);
    nmhdr.code     = code;

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






static LRESULT
DATETIME_Create (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
  DATETIME_INFO *infoPtr;
  DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);

    /* allocate memory for info structure */
    infoPtr = (DATETIME_INFO *)COMCTL32_Alloc (sizeof(DATETIME_INFO));
    if (infoPtr == NULL) {
	ERR("could not allocate info memory!\n");
	return 0;
    }

    SetWindowLongA (hwnd, 0, (DWORD)infoPtr);

	if (dwStyle & DTS_SHOWNONE) {
		infoPtr->hwndCheckbut=CreateWindowExA (0,"button", 0, 
				WS_CHILD | WS_VISIBLE | BS_AUTOCHECKBOX, 
				2,2,13,13,
				hwnd, 
                0, GetWindowLongA  (hwnd, GWL_HINSTANCE), 0);
		SendMessageA (infoPtr->hwndCheckbut, BM_SETCHECK, 1, 0);
	}

	if (dwStyle & DTS_UPDOWN) {

			infoPtr->hUpdown=CreateUpDownControl (
				WS_CHILD | WS_BORDER | WS_VISIBLE,
				120,1,20,20,
				hwnd,1,0,0,
				UD_MAXVAL, UD_MINVAL, 0);
	}

    /* initialize info structure */
	infoPtr->hMonthCal=0;
	GetSystemTime (&infoPtr->date);
	infoPtr->dateValid = TRUE;
	infoPtr->hFont = GetStockObject(DEFAULT_GUI_FONT);
    return 0;
}


static LRESULT
DATETIME_Destroy (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
    DATETIME_INFO *infoPtr = DATETIME_GetInfoPtr (hwnd);
	
    COMCTL32_Free (infoPtr);
    return 0;
}





static LRESULT WINAPI
DATETIME_WindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{

    switch (uMsg)
    {

    case DTM_GETSYSTEMTIME:
		DATETIME_GetSystemTime (hwnd, wParam, lParam);

    case DTM_SETSYSTEMTIME:
		DATETIME_SetSystemTime (hwnd, wParam, lParam);

    case DTM_GETRANGE:
        FIXME("Unimplemented msg DTM_GETRANGE\n");
        return 0;

    case DTM_SETRANGE:
        FIXME("Unimplemented msg DTM_SETRANGE\n");
        return 1;

    case DTM_SETFORMATA:
        FIXME("Unimplemented msg DTM_SETFORMAT32A\n");
        return 1;

    case DTM_SETFORMATW:
        FIXME("Unimplemented msg DTM_SETFORMAT32W\n");
        return 1;

    case DTM_SETMCCOLOR:
        return DATETIME_SetMonthCalColor (hwnd, wParam, lParam);

    case DTM_GETMCCOLOR:
        return DATETIME_GetMonthCalColor (hwnd, wParam);

    case DTM_GETMONTHCAL:
        return DATETIME_GetMonthCal (hwnd);

    case DTM_SETMCFONT:
        return DATETIME_SetMonthCalFont (hwnd, wParam, lParam);

    case DTM_GETMCFONT:
        return DATETIME_GetMonthCalFont (hwnd);

	case WM_PARENTNOTIFY:
		return DATETIME_ParentNotify (hwnd, wParam, lParam);

	case WM_NOTIFY:
		return DATETIME_Notify (hwnd, wParam, lParam);

    case WM_PAINT:
        return DATETIME_Paint (hwnd, wParam);

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

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

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

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

	case WM_DESTROY:
	    return DATETIME_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
DATETIME_Register (void)
{
    WNDCLASSA wndClass;

    if (GlobalFindAtomA (DATETIMEPICK_CLASSA)) return;

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


VOID
DATETIME_Unregister (void)
{
    if (GlobalFindAtomA (DATETIMEPICK_CLASSA))
	UnregisterClassA (DATETIMEPICK_CLASSA, (HINSTANCE)NULL);
}

