/*
 * Xailer source code:
 *
 * DatePicker.prg
 * Clase DatePicker()
 *
 * Copyright 2003, 2007 Ignacio Ortiz de Zuņiga
 * Copyright 2003, 2007 Xailer.com
 * All rights reserved
 *
 */

#include "Xailer.ch"
#include "CommCtrl.api"


//--------------------------------------------------------------------------

CLASS XDatePicker FROM TStdControl

PUBLISHED:
   PROPERTY nWidth   INIT 90
   PROPERTY nHeight  INIT 20

   PROPERTY nFormatType       INIT dfSHORTDATE VALUES dfSHORTDATE, dfSHORTDATECENTURY, dfLONGDATEFORMAT, dfCUSTOMFORMAT
   PROPERTY cCustomFormat     INIT "" WRITE METHOD SetFormat

   PROPERTY dValue   READ INLINE ::FdValue := iif( ! Empty( ::Handle ), ::GetDate(), ::FdValue );
                     WRITE METHOD SetDate

   PROPERTY dMinDate INIT CToD( "" )   WRITE INLINE ::SetRange( Value, ::dMaxDate )
   PROPERTY dMaxDate INIT CToD( "" )   WRITE INLINE ::SetRange( ::dMinDate, Value )

   PROPERTY nAlignment        INIT taLEFT VALUES taLEFT, taRIGHT
   PROPERTY lCheckBox         INIT .F.
   PROPERTY lUpDown           INIT .F.

   PROPERTY nClrText          INIT clWindowText    WRITE SetTextColor
   PROPERTY nClrPane          INIT clWindow

   PROPERTY nClrMonthPane     INIT clWindow        WRITE SetMonthBackgroundColor EDITOR PE_Color
   PROPERTY nClrTitlePane     INIT clActiveCaption WRITE SetTitleBackgroundColor EDITOR PE_Color
   PROPERTY nClrTitleText     INIT clCaptionText   WRITE SetTitleTextColor       EDITOR PE_Color
   PROPERTY nClrTrailingText  INIT clBtnShadow     WRITE SetTrailingTextColor    EDITOR PE_Color

   EVENT OnChange( oSender, dDate ) // --> Nil
   EVENT OnDropDown( oSender ) // --> Nil
   EVENT OnCloseUp( oSender ) // --> Nil

PUBLIC:
   PROPERTY oBrush
   PROPERTY cText
   PROPERTY lDragAcceptFiles  INIT .F.

PROTECTED:
   DATA cWinClassName INIT DATETIMEPICK_CLASS

   METHOD SetDate( dValue )
   METHOD SetRange( dMin, dMax )
   METHOD GetRange()
   METHOD SetFormat( cFormat )

PUBLIC:
   CONSTRUCTOR Create( oParent )

RESERVED:
   METHOD Notify( nWParam, nLParam )
   METHOD GetMonthCal()             INLINE ::SendMsg( DTM_GETMONTHCAL, 0, 0 )
   METHOD SetMonthCalFont( oFont )  INLINE ::SendMsg( DTM_SETMCFONT, oFont:Handle, 1 )
   METHOD GetMonthCalFont()         INLINE ::SendMsg( DTM_GETMCFONT, 0, 0 )
   METHOD SetTextColor( nColor )
   METHOD SetMonthBackgroundColor( nColor )  INLINE ::FnClrMonthPane := nColor, ::SendMsg( DTM_SETMCCOLOR, MCSC_MONTHBK, nColor )
   METHOD SetTitleBackgroundColor( nColor )  INLINE ::FnClrTitlePane := nColor, ::SendMsg( DTM_SETMCCOLOR, MCSC_TITLEBK, nColor )
   METHOD SetTitleTextColor( nColor )        INLINE ::FnClrTitleText := nColor, ::SendMsg( DTM_SETMCCOLOR, MCSC_TITLETEXT, nColor )
   METHOD SetTrailingTextColor( nColor )     INLINE ::FnClrTrailingText := nColor, ::SendMsg( DTM_SETMCCOLOR, MCSC_TRAILINGTEXT, nColor )
   METHOD WMDestroy()      INLINE ( ::FdValue := ::GetDate(), ::Super:WMDestroy() )
   METHOD WMEraseBkgnd()   INLINE 1
   METHOD WMPaint()        EXTERN XControl_EraseSolidAndPaint()
   METHOD GetDate()
   METHOD Change( dDate ) INLINE ::OnChange( dDate )

ENDCLASS

//--------------------------------------------------------------------------

METHOD Create( oParent ) CLASS XDatePicker

   ::nCtlStyle := nOr( WS_CHILD, WS_CLIPCHILDREN, WS_CLIPSIBLINGS )
   ::ChangeCtlStyle( DTS_SHOWNONE, ::lCheckBox )
   ::ChangeCtlStyle( DTS_UPDOWN, ::lUpDown )
   ::ChangeCtlStyle( DTS_RIGHTALIGN, ::nAlignment == taRIGHT )

   DO CASE
      CASE ::nFormatType == dfSHORTDATE
         ::ChangeCtlStyle( DTS_SHORTDATEFORMAT, .T. )
      CASE ::nFormatType == dfSHORTDATECENTURY
         ::ChangeCtlStyle( DTS_SHORTDATECENTURYFORMAT, .T. )
      CASE ::nFormatType == dfLONGDATEFORMAT
         ::ChangeCtlStyle( DTS_LONGDATEFORMAT, .T. )
   ENDCASE

   InitCommonControls( ICC_DATE_CLASSES )
   ::Super:Create( oParent )

   IF !Empty( ::FdValue )
      ::SetDate( ::FdValue )
   ENDIF

   ::SetTextColor( ::FnClrText )
   ::SetMonthBackgroundColor( ::FnClrMonthPane )
   ::SetTitleBackgroundColor( ::FnClrTitlePane )
   ::SetTitleTextColor( ::FnClrTitleText )
   ::SetTrailingTextColor( ::FnClrTrailingText )

   IF !Empty( ::cCustomFormat ) .AND. ::nFormatType == dfCUSTOMFORMAT
      ::SetFormat( ::cCustomFormat )
   ENDIF

   IF !Empty( ::dMinDate ) .OR. !Empty( ::dMaxDate )
      ::SetRange( ::dMinDate, ::dMaxDate )
   ENDIF

RETURN Self

//--------------------------------------------------------------------------

METHOD SetTextColor( nColor ) CLASS XDatePicker

   ::FnClrText := nColor

   ::SendMsg( DTM_SETMCCOLOR, MCSC_TEXT, nColor )
   ::SetColor( nColor, ::nClrPane )

RETURN NIL

//--------------------------------------------------------------------------

#pragma BEGINDUMP

#undef _WIN32_WINNT
#define _WIN32_WINNT   0x0400

#include <windows.h>
#include <commctrl.h>
#include <shlobj.h>
#include <xailer.h>

//--------------------------------------------------------------------------

HB_FUNC_STATIC( XDATEPICKER_NOTIFY )
{
   PHB_ITEM Self = hb_stackSelfItem();
   LPNMDATETIMECHANGE dtc = (LPNMDATETIMECHANGE) hb_parnl( 2 );
   UINT uiCode = dtc->nmhdr.code;

   hb_ret();
   switch( uiCode )
   {
      case DTN_DATETIMECHANGE:
         {
            PHB_ITEM pDate = hb_itemPutD( NULL, dtc->st.wYear, dtc->st.wMonth, dtc->st.wDay );

            XA_ObjSendItem( Self, "Change", pDate );
            hb_itemRelease( pDate );
         }
         break;

      case DTN_DROPDOWN:
         {
            XA_ObjSend( Self, "OnDropDown" );
         }
         break;

      case DTN_CLOSEUP:
         {
            XA_ObjSend( Self, "OnCloseUp" );
         }
         break;
   }
}

//--------------------------------------------------------------------------

HB_FUNC_STATIC( XDATEPICKER_SETDATE )
{
   PHB_ITEM Self = hb_stackSelfItem();
   HWND hwnd = GetHandleOf( Self );
   SYSTEMTIME st;
   PHB_ITEM pDate = hb_param( 1, HB_IT_DATETIME );

   if( !pDate )
      pDate = hb_param( 1, HB_IT_DATE );

   if( pDate && hwnd )
   {
      int lYear, lMonth, lDay, lHour, lMinute, lSec, lMilisec;
      long nDate, nTime;

      XA_ObjSendItem( Self, "_FdValue", pDate );
      hb_itemGetTDT( pDate, &nDate, &nTime );
      hb_dateDecode( nDate, &lYear, &lMonth, &lDay );
		hb_timeDecode( nTime, &lHour, &lMinute, &lSec, &lMilisec );

      st.wYear          = lYear;
      st.wMonth         = lMonth;
      st.wDay           = lDay;
      st.wDayOfWeek     = 0;

      st.wHour = lHour;
      st.wMinute = lMinute;
      st.wSecond = lSec;
      st.wMilliseconds = lMilisec;

      if( lYear | lMonth | lDay )
         SendMessage( hwnd, DTM_SETSYSTEMTIME, GDT_VALID, (LPARAM) &st );
      else
         SendMessage( hwnd, DTM_SETSYSTEMTIME, GDT_NONE, (LPARAM) &st );
   }
   hb_ret();
}

//--------------------------------------------------------------------------

HB_FUNC_STATIC( XDATEPICKER_GETDATE )
{
   PHB_ITEM Self = hb_stackSelfItem();
   HWND hwnd = GetHandleOf( Self );
   SYSTEMTIME st;

   SendMessage( hwnd, DTM_GETSYSTEMTIME, 0, (LPARAM) &st );

   //hb_retd( st.wYear, st.wMonth, st.wDay );
   hb_rettdt( hb_dateEncode( st.wYear, st.wMonth, st.wDay ),
              hb_timeEncode( st.wHour, st.wMinute, st.wSecond, st.wMilliseconds ) );

}

//--------------------------------------------------------------------------

HB_FUNC_STATIC( XDATEPICKER_SETFORMAT )
{
   PHB_ITEM Self = hb_stackSelfItem();
   HWND hwnd = GetHandleOf( Self );

   XA_ObjSendNL( Self, "_FnFormatType", 3 ); // dfCUSTOMFORMAT
   XA_ObjSendC( Self, "_FcCustomFormat", hb_parc( 1 ) );
   hb_retl( SendMessage( hwnd, DTM_SETFORMAT, 0, (LPARAM) hb_parc( 1 ) ) );
}

//--------------------------------------------------------------------------

HB_FUNC_STATIC( XDATEPICKER_SETRANGE )
{
   PHB_ITEM Self = hb_stackSelfItem();
   HWND hwnd = GetHandleOf( Self );
   SYSTEMTIME st[ 2 ];
   DWORD wFlags = 0;
   PHB_ITEM pDateMin = hb_param( 1, HB_IT_DATE );
   PHB_ITEM pDateMax = hb_param( 2, HB_IT_DATE );

   if( pDateMin )
   {
      int lYear, lMonth, lDay;

      XA_ObjSendItem( Self, "_FdMinDate", pDateMin );
      hb_dateDecode( hb_itemGetDL( pDateMin ), &lYear, &lMonth, &lDay );

      st[ 0 ].wYear        = lYear;
      st[ 0 ].wMonth       = lMonth;
      st[ 0 ].wDay         = lDay;
      st[ 0 ].wDayOfWeek   = 0;

      st[ 0 ].wHour        = 0;
      st[ 0 ].wMinute      = 0;
      st[ 0 ].wSecond      = 0;
      st[ 0 ].wMilliseconds = 0;

      wFlags = GDTR_MIN;
   }

   if( pDateMax )
   {
      int lYear, lMonth, lDay;

      XA_ObjSendItem( Self, "_FdMaxDate", pDateMax );
      hb_dateDecode( hb_itemGetDL( pDateMax ), &lYear, &lMonth, &lDay );

      st[ 1 ].wYear        = lYear;
      st[ 1 ].wMonth       = lMonth;
      st[ 1 ].wDay         = lDay;
      st[ 1 ].wDayOfWeek   = 0;

      st[ 1 ].wHour        = 0;
      st[ 1 ].wMinute      = 0;
      st[ 1 ].wSecond      = 0;
      st[ 1 ].wMilliseconds = 0;

      wFlags = wFlags | GDTR_MAX;
   }

   hb_retl( SendMessage( hwnd, DTM_SETRANGE, wFlags, (LPARAM) &st ) );
}

//--------------------------------------------------------------------------

HB_FUNC_STATIC( XDATEPICKER_GETRANGE )
{
   PHB_ITEM Self = hb_stackSelfItem();
   HWND hwnd = GetHandleOf( Self );
   SYSTEMTIME st[ 2 ];
   DWORD dwFlags;
   PHB_ITEM pArray = hb_itemArrayNew( 2 );
   PHB_ITEM pDate;

   dwFlags = SendMessage( hwnd, DTM_GETRANGE, 0, (LPARAM) &st );

   if( dwFlags & GDTR_MIN )
      pDate = hb_itemPutD( NULL, st[0].wYear, st[0].wMonth, st[0].wDay );
   else
      pDate = hb_itemPutD( NULL, 0, 0, 0 );

   hb_itemArrayPut( pArray, 1, pDate );
   hb_itemRelease( pDate );

   if( dwFlags & GDTR_MAX )
      pDate = hb_itemPutD( NULL, st[1].wYear, st[1].wMonth, st[1].wDay );
   else
      pDate = hb_itemPutD( NULL, 0, 0, 0 );

   hb_itemArrayPut( pArray, 2, pDate );
   hb_itemRelease( pDate );

   hb_itemReturnForward( pArray );
   hb_itemRelease( pArray );
}

#pragma ENDDUMP

//--------------------------------------------------------------------------
