/* $Header$ */

/*************** changes *******************
Date			Edit				Bug					Description
10-June-22 pk1450 Calendar enhancement
24-Jun-21	rmm11062								Transparent shape fields now use layered child on Windows platform; improved performance of layered child windows on Windows platform.
22-Jan-21	rmm_svg3								Support for themed fat client SVG icons.
14-Jan-21	rmm_ncs									Removed unnecessary ECM_GETCOMPSTORE... messages.
25-Apr-17	rmm9347			ST/RC/1261	Added zoom capability to report class editor.
14-Feb-13	rmm64bit5								Changes required for compiling with 64 bit target.
18-Feb-08	rmm_mobile							Mobile device support.
10-May-05 PK6715			ST/EC/904		Problem with last week in march/first week in april, for the first hour of the day
29-Jun-04	rmm5006									Multiple select knobs were missing from quite a few components.
22-Jun-04	rmm4999									Finished rmm4993: remote form fields now show $xxx correctly.
09-Jul-03	AE6287			ST/EC/448: 	Localised WEB calendar control
22-Jan-02 PK6258      ST/WT/389   Problems assigning dates invalid.
27-Apr-00 MHn0143									Added anumFldStyle
21-Apr-00	rmm3735			ST/FU/252		Allow day-specific tooltips for the calendar (non-Web) component.
																	Use localised day names for the calendar (non-Web) component.
16-Mar-00	rmm3685			ST/EC/467		Fixed GPF.
06-Dec-99	rmm3550									Added current date parameter to all calendar events
04-Oct-99	rmm3478									Added function to return version via version resource.
14-Apr-99 MHn0068									FormCal web conponent version 1.0.
*/

#include <extcomp.he>
#include <extfval.he>
#include <hwnd.he>
#include <gdi.he>
#include <dmconst.he>
#include "calendar.he"
#include "localise.he"	// rmm3735

#include <string.h>
#include <math.h>                       

#define COMPONENT_COUNT 	1				/* Number of controls within library */
#define LIB_RES_NAME 			1000		/* Resource id of library name */
#define CALENDAR_ID 			2000	/* Resource id of control within library */

#define CALENDAR_ICON 		1				/* Resource bitmap id */


#define DEFINED_KOMNISFIRSTDAY		12		// kSunday has a constant of 12 in the core

const 	qshort	// rmmuni_osx7: added qshort, to avoid Mac warning
				cCalendar_ShowDays 	= 1,
				cCalendar_ShortName   			= 2,
				cCalendar_HeadingMode   		= 3,
				cCalendar_DaysMode   				= 4,
				cCalendar_CurrDayMode   		= 5,
				cCalendar_FirstDay				  = 6,
				cCalendar_AllowChange				= 7,
				cCalendar_HeadingColor			= 8,
				cCalendar_NormalColor				= 9,
				cCalendar_TodaysColor				= 10,
				cCalendar_OtherColor				= 11,
				cCalendar_TodaysBold				= 12,
				cCalendar_CurrentDate				= 13,
				cCalendar_CurrentDayColor		= 14,
				cCalendar_HeadingBold				= 15,
				cCalendar_CurDayFace	 			= 16,
				cCalendar_DayFace						= 17,
				cCalendar_OtherDayFace			= 18,
				cCalendar_HeadingFace				= 19,
				cCalendar_TodayFace					= 20,	
				cCalendar_OtherDaysMode   	= 21,
				cCalendar_HeadingFont				= 22,
				cCalendar_HeadingFontSize		= 23,
				cCalendar_DayFont						= 24,
				cCalendar_DayFontSize				= 25,
				cCalendar_CurrentDayIcon		= 26, // MHn0068
				cCalendar_DayTooltips				= 27,	// rmm3735
				cCalendar_TooltipDate				= 28,	// rmm3735
        //pk1450
        cCalendar_UIStyle           = 30,
        cCalendar_NavColor          = 31,
        cCalendar_NavFont           = 32,
        cCalendar_NavFontSize       = 33,
        cCalendar_NavTextColor      = 34,
        cCalendar_ShowNav           = 35,
        cCalendar_ShowWeekNumbers   = 36,
        cCalendar_WeekNumberColor   = 37,
        cCalendar_WeekNumberTextColor = 38,
				// -----------------------
				cCalendarEvDateChange				= 1,
				cCalendarEvResetMonth				= 2,
				cCalendarEvDateDblClick			= 3,
				// -----------------------      
				cCalendarFuncSetDayIcon     = 1,
				cCalendarFuncGetDayIcon     = 2,
				cCalendarFuncClearDayIcons  = 3;
				

ECOparam CALENDARparamsSetDayIcon[2] =	// rmm_svg3
{
	7000, fftInteger, 0, 0,			// day
	7001, fftNone,		0, 0			// iconid
};

ECOparam CALENDARparamsGetDayIcon[2] =	// rmm_svg3
{
	7000, fftInteger,		0, 0,																						// day
	7001, fftCharacter, EXTD_FLAG_PARAMALTER|EXTD_FLAG_PARAMOPT, 0			// iconid
};

ECOmethodEvent CALENDARfunctions[3] = 
{
	cCalendarFuncSetDayIcon,  	6000, 0, 2,						&CALENDARparamsSetDayIcon[0], 0, 0, // rmm_svg3
	cCalendarFuncGetDayIcon,  	6001, fftInteger, 2,	&CALENDARparamsGetDayIcon[0], 0, 0,	// rmm_svg3
	cCalendarFuncClearDayIcons, 6002, 0, 0, 0, 0, 0,
};

ECOparam CALENDAReventParams[1] =	// rmm3550
{
	10000, 										fftDate, 	0,	0
};

ECOmethodEvent CALENDARevents[] = 
{
	cCalendarEvDateChange,  	5000, 0, 1, CALENDAReventParams, 0, 0,		// rmm3550
	cCalendarEvResetMonth,  	5001, 0, 1, CALENDAReventParams, 0, 0,		// rmm3550
	cCalendarEvDateDblClick,  5002, 0, 1, CALENDAReventParams, 0, 0,		// rmm3550
};

ECOproperty CALENDARproperties[] =
{ 
	cCalendar_ShowDays, 				4000, fftBoolean, 0, 0, 0, 0,																											// showdays
	cCalendar_ShortName, 				4001, fftBoolean, 0, 0, 0, 0,																											// heading
	cCalendar_HeadingMode, 			4002, fftInteger, EXTD_FLAG_INTCONSTANT, 0, pre3DStyleF,pre3DStyleL,							// heading draw mode
	cCalendar_DaysMode, 				4003, fftBoolean, EXTD_FLAG_INTCONSTANT, 0, pre3DStyleF,pre3DStyleL,							// days embossed
	cCalendar_CurrDayMode, 			4004, fftBoolean, EXTD_FLAG_INTCONSTANT, 0, pre3DStyleF,pre3DStyleL,							// cur day embossed
	cCalendar_OtherDaysMode,    4020, fftInteger, EXTD_FLAG_INTCONSTANT, 0, pre3DStyleF,pre3DStyleL,							// other day mode
	cCalendar_FirstDay, 				4005, fftInteger, EXTD_FLAG_INTCONSTANT, 0, preDateFuncDayF,preDateFuncDayL,			// first day
	cCalendar_AllowChange, 			4006, fftBoolean, 0, 0, 0, 0,																											// allow change
	cCalendar_HeadingColor, 		4007, fftInteger, EXTD_FLAG_PWINDCOL, 0, 0, 0,																		// heading color
	cCalendar_NormalColor, 			4008, fftInteger, EXTD_FLAG_PWINDCOL, 0, 0, 0,																		// normal color
	cCalendar_TodaysColor, 			4009, fftInteger, EXTD_FLAG_PWINDCOL, 0, 0, 0,																		// today color
	cCalendar_OtherColor, 			4010, fftInteger, EXTD_FLAG_PWINDCOL, 0, 0, 0,																		// other color
	cCalendar_TodaysBold, 			4011, fftBoolean, 0, 0, 0, 0,	
	cCalendar_CurrentDate, 			4012, fftDate, 		0, 0, 0, 0,	
	cCalendar_CurrentDayColor,	4013, fftInteger, EXTD_FLAG_PWINDCOL, 0, 0, 0,																		// current day color
	cCalendar_HeadingBold,      4014, fftBoolean, 0, 0, 0, 0,
	cCalendar_CurDayFace, 			4015, fftInteger, EXTD_FLAG_PWINDCOL, 0, 0, 0,																		// cur day face
	cCalendar_DayFace, 					4016, fftInteger, EXTD_FLAG_PWINDCOL, 0, 0, 0,																		// day face
	cCalendar_OtherDayFace, 		4017, fftInteger, EXTD_FLAG_PWINDCOL, 0, 0, 0,																		// other day face
	cCalendar_HeadingFace, 			4018, fftInteger, EXTD_FLAG_PWINDCOL, 0, 0, 0,																		// heading face
	cCalendar_TodayFace, 				4019, fftInteger, EXTD_FLAG_PWINDCOL, 0, 0, 0,																		// todays face
	cCalendar_HeadingFont, 			4021, fftInteger, EXTD_FLAG_FONTPROP, 0, 0, 0,																		// heading font
	cCalendar_HeadingFontSize, 	4022, fftInteger, 0, 0, 0, 0,																											// heading fontsize
	cCalendar_DayFont, 					4023, fftInteger, EXTD_FLAG_FONTPROP, 0, 0, 0,																		// day font
	cCalendar_DayFontSize, 			4024, fftInteger, 0, 0, 0, 0,																											// day fontsize
	cCalendar_CurrentDayIcon,		4025, fftCharacter,EXTD_FLAG_RUNTIMEONLY|EXTD_FLAG_PWINDICON, EXTD_EFLAG_SVG, 0, 0,// current day icon MHn0068 // rmm_svg3
	cCalendar_DayTooltips,			4026, fftBoolean, 0, 0, 0, 0,																											// rmm3735
	cCalendar_TooltipDate,			4027,	fftDate,		EXTD_FLAG_RUNTIMEONLY, 0, 0, 0,																	// rmm3735
  //pk1450
  cCalendar_UIStyle,          4030, fftInteger, EXTD_FLAG_EDITRONLY|EXTD_FLAG_EXTCONSTANT, 0, 9000, 9001,
  cCalendar_NavColor,         4031, fftInteger, EXTD_FLAG_PWINDCOL, 0, 0, 0,
  cCalendar_NavFont,          4032, fftInteger, EXTD_FLAG_FONTPROP, 0, 0, 0,
  cCalendar_NavFontSize,      4033, fftInteger, 0, 0, 0, 0,
  cCalendar_NavTextColor,     4034, fftInteger, EXTD_FLAG_PWINDCOL, 0, 0, 0,
  cCalendar_ShowNav,          4035, fftBoolean, 0, 0, 0, 0,
  cCalendar_ShowWeekNumbers,  4036, fftBoolean, 0, 0, 0, 0,
  cCalendar_WeekNumberColor,  4037, fftInteger, EXTD_FLAG_PWINDCOL, 0, 0, 0,
  cCalendar_WeekNumberTextColor,  4038, fftInteger, EXTD_FLAG_PWINDCOL, 0, 0, 0,
};
               
// ---------------------------------------------------------------------------------------------------------

tqfCalendar::tqfCalendar( HWND pFieldHWnd, qbool pReportObj )
{
	mHWnd = pFieldHWnd;
	mReportObj = pReportObj;
	if ( !mReportObj )
	{
		qlong style = WNDgetWindowLong( mHWnd, GWL_EXSTYLE );
		style |= WND_REDRAWONSIZE;
		WNDsetWindowLong( mHWnd, GWL_EXSTYLE, style ); 
	}
	mHeadingMode = WND_BORD_EMBOSSED;
	mDaysMode = WND_BORD_EMBOSSED;
	mOtherDaysMode = WND_BORD_EMBOSSED;
	mCurrentDayMode = WND_BORD_NONE;
	mShowHeading = mAllowDayChange = qtrue;
	mShortName = qtrue;
	mFirstDay = DEFINED_KOMNISFIRSTDAY;    
	mHeadingColor = GDI_COLOR_BTNTEXT;  
	mNormalColor = GDI_COLOR_BTNTEXT;
	mTodaysColor = GDI_COLOR_QBLACK;  
	mOtherMonthColor = GDI_COLOR_GRAYTEXT;
	mCurrentDayColor = GDI_COLOR_BTNTEXT;
	mCurrentDayColorFace = GDI_COLOR_3DFACE;
	mDayColorFace = GDI_COLOR_3DFACE;
	mOtherDayColorFace = GDI_COLOR_3DFACE;
	mHeadingColorFace = GDI_COLOR_3DFACE;
	mTodayFaceColor = GDI_COLOR_3DFACE;
	mTodayBold = qtrue; 
	mHeadingBold = qtrue;  
	mDayFont = mHeadingFont = 1;
	mDayFontSize = mHeadingFontSize = 6;
	mCurrentDayIcon = 0; // MHn0068
	initTodaysDate();
	mDayList = new EXTqlist( listVlen );
	mTooltipIndex = -1;			// rmm3735
	mDayTooltips = qfalse;	// rmm3735
  
  //pk1450
  mUIStyle = qfalse;
  mShowWeekNos = qfalse;
  mShowMonthNav = qtrue;
  mCalMode = 0;
  mNavColor = GDI_COLOR_JSTHEME_PRIMARY;
  mHeadingColorFace = GDI_COLOR_JSTHEME_PRIMARY_LIGHT;
  mDayColorFace = GDI_COLOR_3DFACE;
  mOtherDayColorFace = GDIgetDarkerShade(GDI_COLOR_3DFACE);
  mNavFont = 1;
  mNavHt = 0;
  mNavFontSize = 14;
  mNavTextColor = GDI_COLOR_JSTHEME_PRIMARY_TEXT;
  mNavHilite = GDI_COLOR_QDEFAULT;
  mTodayFaceColor = GDIgetDarkerShade(GDI_COLOR_3DFACE);
  mWeekNumberColor = GDIgetDarkerShade(GDI_COLOR_3DFACE);
  mWeekNumberTextColor = GDI_COLOR_BTNTEXT;
  mDayFontSize = 12; mHeadingFontSize = 12; //pk1450

}

tqfCalendar::~tqfCalendar()
{         
	*mDayList = qnil;
	delete mDayList;
}

void tqfCalendar::setDayMark(qlong pDay, EXTfldval& pIconId)	// rmm_svg3
{
	EXTfldval fval;
	qlong lc = mDayList->rowCnt();
	for ( qlong line = 1; line<=lc; line++ )
	{
    mDayList->getColValRef(line, 1, fval, qfalse );
		if ( fval.getLong()==pDay )
		{
			// found day, so update iconid
      mDayList->getColValRef(line, 2, fval, qtrue );
			fval = pIconId; // rmm_svg3
			return;			
		}
	}  
	qlong newline = mDayList->insertRow();
  mDayList->getColValRef(newline, 1, fval, qtrue );
	fval.setLong( pDay );
  mDayList->getColValRef(newline, 2, fval, qtrue );
	fval = pIconId; // rmm_svg3
}

void tqfCalendar::getDayMark(qlong pDay, EXTfldval& pIconId)	// rmm_svg3
{
	EXTfldval fval;
	qlong lc = mDayList->rowCnt(); 
	if (!lc) 
		return;
	for ( qlong line = 1; line<=lc; line++ )
	{
    mDayList->getColValRef(line, 1, fval, qfalse );
		if ( fval.getLong()==pDay )
		{
			// found day, so update iconid
      mDayList->getColValRef(line, 2, fval, qfalse );
			// Start rmm_svg3
			pIconId = fval;
			break;
			// End rmm_svg3
		}
	}                           
}

void tqfCalendar::functionSupport( LPARAM pMessage, WPARAM wParam, LPARAM lParam, EXTCompInfo* eci )
{
	switch( ECOgetId(eci) )
	{
		case cCalendarFuncSetDayIcon:
		{
			EXTParamInfo* param = ECOfindParamNum( eci, 1 ); 
			if ( !param ) break; // Method called with too few parameters
			EXTfldval fval( (qfldval)param->mData );
			qlong day = fval.getLong();

			param = ECOfindParamNum( eci, 2); 
			if (!param) break; // Method called with too few parameters
			EXTfldval fval2((qfldval)param->mData);
			setDayMark(day, fval2);	// rmm_svg3
			if ( !mReportObj )
				WNDinvalidateRect( mHWnd, NULL );
			break;
		}
		case cCalendarFuncGetDayIcon:
		{
			EXTParamInfo* param = ECOfindParamNum(eci, 1);
			if (!param) break; // Method called with too few parameters
			EXTfldval fval((qfldval)param->mData);
			qlong day = fval.getLong();
			// Start rmm_svg3: As well as returning the result as an integer, we also set parameter two
			EXTfldval result;
			getDayMark(day, result);
			if (ECOgetParamCount(eci) >= 2)
			{
				EXTParamInfo* param = ECOfindParamNum(eci, 2);
				EXTfldval fval(qfldval(param->mData));
				fval = result;
				ECOsetParameterChanged(eci, 2);
			}
			qlong intId = result.getLong();
			result.setLong(intId);
			// End rmm_svg3
			ECOaddParam(eci, &result);
			break;
		}
		case cCalendarFuncClearDayIcons:
		{
			mDayList->clear( listVlen );
			if ( !mReportObj )
				WNDinvalidateRect( mHWnd, NULL );
			break;
		}
	}
}

qlong tqfCalendar::attributeSupport( LPARAM pMessage, WPARAM wParam, LPARAM lParam, EXTCompInfo* eci )
{
	switch( pMessage )
	{ 
		case ECM_PROPERTYCANASSIGN: 
		{
      //pk1450   mUIStyle
      qlong idx = ECOgetId(eci);
      switch (idx)
      {
        case cCalendar_NavColor: case cCalendar_NavFont: case cCalendar_NavFontSize: case cCalendar_NavTextColor:
        case cCalendar_WeekNumberColor: case cCalendar_WeekNumberTextColor: case cCalendar_ShowNav: case cCalendar_ShowWeekNumbers:
        {
          return mUIStyle ? qtrue : qfalse;
        }
        case cCalendar_CurrDayMode: case cCalendar_HeadingMode: case cCalendar_DaysMode: case cCalendar_OtherDaysMode:
        {
          return mUIStyle ? qfalse : qtrue;
        }
      }
      // default :
      return idx != cCalendar_TooltipDate;	// rmm3735
		}
		case ECM_SETPROPERTY: 
		{       
			EXTParamInfo* param = ECOfindParamNum( eci, 1 );
			if ( param )
			{
				EXTfldval fval( (qfldval)param->mData );
				qbool doInval = qtrue;	// rmm3735
				switch( ECOgetId(eci) )
				{
					case cCalendar_ShowDays:					mShowHeading = fval.getLong()==1; setGridSizes(); break;
					case cCalendar_ShortName:   			mShortName = fval.getLong()==1; setGridSizes(); break;
					case cCalendar_HeadingMode:   		mHeadingMode = fval.getLong(); setGridSizes(); break;
					case cCalendar_DaysMode:   				mDaysMode = fval.getLong(); setGridSizes(); break;
					case cCalendar_CurrDayMode:   		mCurrentDayMode = fval.getLong(); setGridSizes(); break;
					case cCalendar_FirstDay:					
					{       
						mFirstDay = (qshort)fval.getLong(); 
						setDateArray();
						setGridSizes(); 
						break;
					}
					case cCalendar_AllowChange:				mAllowDayChange = fval.getLong()==1; setGridSizes(); break;
					case cCalendar_HeadingColor:			mHeadingColor = (qcol)fval.getLong(); setGridSizes(); break;
					case cCalendar_NormalColor:				mNormalColor = (qcol)fval.getLong(); setGridSizes(); break;
					case cCalendar_TodaysColor:				mTodaysColor = (qcol)fval.getLong(); setGridSizes(); break;
					case cCalendar_OtherColor:				mOtherMonthColor = (qcol)fval.getLong(); setGridSizes(); break;
					case cCalendar_TodaysBold:				mTodayBold = fval.getLong()==1; setGridSizes(); break;
					case cCalendar_CurrentDate:				
					{
						datestamptype date;
						if ( !fval.conv(fftDate,dpFdate1900) ) return 0L;	// PK6258
						fval.getDate( date, dpFdate1900 );
						setDateFromOmnis( date );
						break;
					}
					case cCalendar_CurrentDayColor:   mCurrentDayColor = (qcol)fval.getLong(); setGridSizes(); break;
					case cCalendar_HeadingBold:				mHeadingBold = (qbool)fval.getLong()==1; setGridSizes(); break;
					case cCalendar_CurDayFace:				mCurrentDayColorFace = (qcol)fval.getLong(); setGridSizes(); break;
					case cCalendar_DayFace:						mDayColorFace = (qcol)fval.getLong(); setGridSizes(); break;
					case cCalendar_OtherDayFace:			mOtherDayColorFace = (qcol)fval.getLong(); setGridSizes(); break;
					case cCalendar_HeadingFace:				mHeadingColorFace = (qcol)fval.getLong(); setGridSizes(); break;
					case cCalendar_TodayFace:					mTodayFaceColor = (qcol)fval.getLong(); setGridSizes(); break;
					case cCalendar_OtherDaysMode:			mOtherDaysMode = fval.getLong(); setGridSizes(); break;
					case cCalendar_HeadingFont:				mHeadingFont = ECOgetFontIndex(mHWnd,fval); setGridSizes(); break;
					case cCalendar_HeadingFontSize:		mHeadingFontSize = fval.getLong(); setGridSizes(); break;
					case cCalendar_DayFont:						mDayFont = ECOgetFontIndex(mHWnd,fval);  setGridSizes(); break;
					case cCalendar_DayFontSize:				mDayFontSize = fval.getLong(); setGridSizes(); break;
					// MHn0068 begins.
					case cCalendar_CurrentDayIcon: 
					{
						qshort day = mCurrentDate.tm_mday;
						setDayMark(day, fval); // rmm_svg3
						setGridSizes();  
						break;
					}
					// MHn0068 ends.
					// rmm3735:
					case cCalendar_DayTooltips:				mDayTooltips = (qbool) (fval.getLong() != 0); doInval = qfalse; break;
          //pk1450
          case cCalendar_UIStyle:           mUIStyle = (qshort) (fval.getLong()); setGridSizes(); break;
          case cCalendar_NavColor:          mNavColor = (qcol)fval.getLong(); setGridSizes(); break;
          case cCalendar_NavFont:           mNavFont = ECOgetFontIndex(mHWnd,fval); setGridSizes(); break;
          case cCalendar_NavFontSize:       mNavFontSize = fval.getLong(); setGridSizes(); break;
          case cCalendar_NavTextColor:      mNavTextColor = (qcol)fval.getLong(); setGridSizes(); break;
          case cCalendar_WeekNumberColor:      mWeekNumberColor = (qcol)fval.getLong(); setGridSizes(); break;
          case cCalendar_WeekNumberTextColor:  mWeekNumberTextColor = (qcol)fval.getLong(); setGridSizes(); break;
          case cCalendar_ShowNav:           mShowMonthNav = (qbool) (fval.getLong() != 0); setGridSizes(); break;
          case cCalendar_ShowWeekNumbers:   mShowWeekNos = (qbool) (fval.getLong() != 0); setGridSizes(); break;
				}
				if ( doInval && !mReportObj && ECOisSetup( mHWnd ) )	// rmm3735
				{
					WNDinvalidateRect( mHWnd, NULL );
					WNDupdateWindow( mHWnd );
				}
				return 1L;
			}
			break;
		}
		case ECM_GETPROPERTY: 
		{
			EXTfldval fval;
			switch( ECOgetId(eci) )
			{
				case cCalendar_ShowDays:					fval.setLong( (qlong)mShowHeading ); break;
				case cCalendar_ShortName:   			fval.setLong( (qlong)mShortName ); break;
				case cCalendar_HeadingMode:   		fval.setLong( mHeadingMode ); break;
				case cCalendar_DaysMode:   				fval.setLong( mDaysMode ); break;
				case cCalendar_CurrDayMode:   		fval.setLong( mCurrentDayMode ); break;
				case cCalendar_FirstDay:					fval.setLong( (qlong)mFirstDay ); break;
				case cCalendar_AllowChange:				fval.setLong( (qlong)mAllowDayChange ); break;
				case cCalendar_HeadingColor:			fval.setLong( (qlong)mHeadingColor ); break;
				case cCalendar_TodaysColor:				fval.setLong( (qlong)mTodaysColor ); break;
				case cCalendar_OtherColor:				fval.setLong( (qlong)mOtherMonthColor ); break;
				case cCalendar_NormalColor:				fval.setLong( (qlong)mNormalColor ); break;
				case cCalendar_TodaysBold:   			fval.setLong( (qlong)mTodayBold ); break;
				case cCalendar_CurrentDate:				
				{
					datestamptype date;
					getDateForOmnis( date );
					fval.setDate( date, dpFdate1900 );
					break;
				}
				case cCalendar_CurrentDayColor:   fval.setLong( (qlong)mCurrentDayColor ); break;
				case cCalendar_HeadingBold:				fval.setLong( (qlong)mHeadingBold ); break;
				case cCalendar_CurDayFace:				fval.setLong( (qlong)mCurrentDayColorFace ); break;
				case cCalendar_DayFace:						fval.setLong( (qlong)mDayColorFace ); break;
				case cCalendar_OtherDayFace:			fval.setLong( (qlong)mOtherDayColorFace ); break;
				case cCalendar_HeadingFace:				fval.setLong( (qlong)mHeadingColorFace ); break;
				case cCalendar_TodayFace:					fval.setLong( (qlong)mTodayFaceColor ); break;
				case cCalendar_OtherDaysMode:			fval.setLong( (qlong)mOtherDaysMode ); break;
				case cCalendar_HeadingFont:				fval.setLong( mHeadingFont ); break;
				case cCalendar_HeadingFontSize:		fval.setLong( mHeadingFontSize ); break;
				case cCalendar_DayFont:						fval.setLong( mDayFont ); break;
				case cCalendar_DayFontSize:				fval.setLong( mDayFontSize ); break;
				// MHn0068 begins.
				case cCalendar_CurrentDayIcon: 
				{
					qshort day = mCurrentDate.tm_mday;
					getDayMark(day, fval); // rmm_svg3
					break;
				}
				// MHn0068 ends.
				// rmm3735:
				case cCalendar_DayTooltips:				fval.setLong(mDayTooltips); break;
        //pk1450
        case cCalendar_UIStyle:           fval.setLong( (qlong)mUIStyle); break;
        case cCalendar_NavColor:          fval.setLong( (qlong)mNavColor ); break;
        case cCalendar_NavFont:           fval.setLong( (qlong)mNavFont ); break;
        case cCalendar_NavFontSize:       fval.setLong( (qlong)mNavFontSize ); break;
        case cCalendar_NavTextColor:      fval.setLong( (qlong)mNavTextColor ); break;
        case cCalendar_WeekNumberColor:   fval.setLong( (qlong)mWeekNumberColor ); break;
        case cCalendar_WeekNumberTextColor:  fval.setLong( (qlong)mWeekNumberTextColor); break;
        case cCalendar_ShowNav:           fval.setLong( (qlong)mShowMonthNav ); break;
        case cCalendar_ShowWeekNumbers:   fval.setLong( (qlong)mShowWeekNos ); break;

				case cCalendar_TooltipDate:
				{
					struct tm tooltipDate = mCurrentDate;
					if (mTooltipIndex >= 0)
					{
						tooltipDate.tm_mday = mDayDates[mTooltipIndex].mDay;
						if (mDayDates[mTooltipIndex].mThisMonth) /* Empty */ ;
						else if (mDayDates[mTooltipIndex].mPrevMonth)
						{
							tooltipDate.tm_mon--;
							if (tooltipDate.tm_mon < 0)
							{
								tooltipDate.tm_mon = 11;
								tooltipDate.tm_year--;
							}
						}
						else
						{
							// Next month
							tooltipDate.tm_mon++;
							if (tooltipDate.tm_mon > 11)
							{
								tooltipDate.tm_mon = 0;
								tooltipDate.tm_year++;
							}
						}
					}
					datestamptype date;
					getDateForOmnis( date, &tooltipDate );
					fval.setDate( date, dpFdate1900 );
					break;
				}
			}         
			ECOaddParam(eci,&fval);
			return 1L;
		}
	}
	return 0;
}

void tqfCalendar::getDateForOmnis( datestamptype& pDate, struct tm *pDateToConvert )	// rmm3735
{
	// convert mCurrentDate(tm) into datestamp
	fillc(&pDate, sizeof(pDate), 0);	// rmm3550
	// rmm3735: use pDateToConvert below, instead of mCurrentDate
	if (!pDateToConvert) pDateToConvert = &mCurrentDate;
	pDate.mYear = pDateToConvert->tm_year + 1900;
	pDate.mMonth = pDateToConvert->tm_mon+1;
	pDate.mDay = pDateToConvert->tm_mday;
	pDate.mDateOk = qtrue;
}

qshort week_wno = 0;
char   week_buf[100];

void tqfCalendar::setDateFromOmnis( datestamptype& pDate )
{
	// convert datestamp into mCurrentDate(tm)
	mCurrentDate.tm_year = pDate.mYear;
	if ( mCurrentDate.tm_year>1900 ) mCurrentDate.tm_year-=1900;
	mCurrentDate.tm_mon = pDate.mMonth-1;
	mCurrentDate.tm_mday = pDate.mDay;
	time_t tmp;
	tmp = mktime( &mCurrentDate );
	if ( tmp!=-1 ) mCurrentDate = *localtime( &tmp );   

	setDateArray();
	if ( !mReportObj )
		WNDinvalidateRect( mHWnd, NULL );
  }

void tqfCalendar::paintDayName( HDC pHdc, qshort pCell, qrect* pArea, EXTCompInfo* eci ) // rmm3735
{
	qrect cellrect = *pArea;
	GDIinsetRect( &cellrect, 2, 2 );

	GDIsetClipRect( pHdc, pArea );
  
	qchar name[64];
	qlong dayid = pCell+( mFirstDay - DEFINED_KOMNISFIRSTDAY );
	if ( dayid>6 ) dayid-=7;
	// Start rmm3735
	qlong slen;
	qbool ok = qfalse;
	qchar *namePtr;
	str255 locItemData;
	qshort locItemXn = mShortName ? cLOCxnAbbMonText : cLOCxnFullMondayText;
	locItemXn += (!dayid ? 6 : (dayid - 1));
	if (ECOreadLocalisationItem(eci, locItemXn, locItemData))
	{
		namePtr = &locItemData[1];
		slen = locItemData[0];
		ok = qtrue;
	}
	if (!ok)
	{
		qlong id = mShortName ? 3010 : 3000;
		slen = (qshort)RESloadString( gInstLib, id + dayid, &name[0], 64 );
		namePtr = name;
	}
	GDIsetTextColor( pHdc, mHeadingColor );
  
  //pk1450
  qdim top = cellrect.top;
  if ( mUIStyle )
  {
    top = cellrect.top + (cellrect.height()/2);
    qdim fht = GDIfontPart( pHdc, eFontHeight ) + 1; if ( fht ) top-=(fht/2);
  }
  
	GDIdrawText( pHdc, cellrect.left + cellrect.width()/2, top, namePtr, (qshort) slen, jstCenter );  //pk1450
	// End rmm3735

	GDIclearClip( pHdc );
}

void tqfCalendar::getBorderSpec( WNDborderStruct* pBorderSpec, qlong pMode )
{
 	switch ( pMode )
 	{
  	case WND_BORD_NONE: case WND_BORD_INSET: case WND_BORD_EMBOSSED: case WND_BORD_CHISEL: case WND_BORD_EMBOSSEDCHISEL:
		// Start rmm_svg3
		case WND_BORD_SINGLE_INSET: case WND_BORD_SINGLE_EMBOSSED: case WND_BORD_3DFACE: case WND_BORD_3DHILITE:
		case WND_BORD_CTRL_EDIT: case WND_BORD_CTRL_LIST: case WND_BORD_CRTL_LISTCELL: case WND_BORD_CTRL_TABPANE:
		case WND_BORD_CTRL_GROUPBOX: case WND_BORD_CTRL_DROPLIST: case WND_BORD_CTRL_COMBOBOX:
		// End rmm_svg3
			*pBorderSpec = WNDborderStruct( (qshort)pMode );
			break;
  	case WND_BORD_PLAIN:
  	{
  		*pBorderSpec = WNDborderStruct( (qshort)pMode, qpen(1) );
  		pBorderSpec->mSize1 = pBorderSpec->mSize2 = pBorderSpec->mSize3 = 1;
  		pBorderSpec->mLineStyle.mWidth = 1;
  		pBorderSpec->mLineStyle.mColor = colBlack;
  		break;
  	}
  	case WND_BORD_BEVEL: case WND_BORD_INSETBEVEL:
  		*pBorderSpec = WNDborderStruct( (qshort)pMode, 2, 2, 2 );
  		break;
  	case WND_BORD_SHADOW:
		case WND_BORD_CTRL_SHADOW_EX:	// rmm_svg3
  		*pBorderSpec = WNDborderStruct( (qshort)pMode, qpen(), 2, 2, colBlack );
  		break;
  	default:
  		*pBorderSpec = WNDborderStruct( WND_BORD_NONE );
  		break;
  }
}

//pk1450
void tqfCalendar::paintNavMonth( HDC pHdc, EXTCompInfo* eci )
{
  qrect clientRect = mClientRect;
  clientRect.bottom = clientRect.top + mNavHt;
  
  GDIsetTextColor( pHdc, mNavColor );
  GDIfillRect( pHdc,&clientRect,GDIgetStockBrush(BLACK_BRUSH));
  
  
  qfnt fnt = fntSmallFnt;
  ECOgetFont( mHWnd, &fnt, (qshort)mNavFont, (qshort)mNavFontSize );
  GDIfontCreator fc(pHdc, ECOgetFontDpi(mHWnd));
  HFONT font = fc.createFont(&fnt, styBold );
  
  HFONT oldfnt = GDIselectObject( pHdc, font );
  
  qdim top = clientRect.top + (clientRect.height()/2);
  qdim fht = GDIfontPart( pHdc, eFontHeight ) + 1; if ( fht ) top-=(fht/2);
  
  qbool monthshortname = mShortName;
  str255 locItemData; qshort monthid = mCurrentDate.tm_mon; qchar *namePtr; qshort slen = 0;
  qshort locItemXn = monthshortname ? cLOCxnAbbJanText :cLOCxnFullJanuaryText;
  locItemXn += (monthid); qbool ok = qfalse;
  if (ECOreadLocalisationItem(eci, locItemXn, locItemData))
  {
    namePtr = &locItemData[1];
    slen = locItemData[0];
    ok = qtrue;
  }
  if (!ok)
  {
    qlong id = monthshortname ? 3040 : 3020; qchar name[64];
    slen = (qshort)RESloadString( gInstLib, id + monthid, &name[0], 64 );
    namePtr = name;
  }
  
  str255 sx = str255(namePtr,slen);
  GDIsetTextColor( pHdc, mNavTextColor );
  // font !
  str255 year; qlongToString(mCurrentDate.tm_year + 1900,year); str255 yearsep = str255(QTEXT(", "));
  sx.concat(yearsep); sx.concat(year);
  GDIdrawText( pHdc, clientRect.left + clientRect.width()/2, top , &sx[1], sx.length(), jstCenter );
  if ( mAllowDayChange==qtrue )
  {
    str255 s = str255(QTEXT("<<"));
    GDIdrawText( pHdc, clientRect.left + 8, top, &s[1], s.length(), jstLeft );
    s = str255(QTEXT(">>"));
    GDIdrawText( pHdc, clientRect.left + clientRect.width() - 8, top, &s[1], s.length(), jstRight );
  }

  GDIselectObject( pHdc, oldfnt );
  GDIdeleteObject( font );
}

void tqfCalendar::paintDayTitles( HDC pHdc, EXTCompInfo* eci ) // rmm3735
{
	qrect clientRect = mClientRect;
  clientRect.top += mNavHt; //pk1450
	clientRect.bottom = clientRect.top + mTitleHeight;
	
	qfnt fnt = fntSmallFnt;
	ECOgetFont( mHWnd, &fnt, (qshort)mHeadingFont, (qshort)mHeadingFontSize );

	// Start rmm9347
	GDIfontCreator fc(pHdc, ECOgetFontDpi(mHWnd));
	HFONT font = fc.createFont(&fnt, mHeadingBold ? styBold : styPlain);
	// End rmm9347

	HFONT oldfnt = GDIselectObject( pHdc, font );
	qrect titleRect = clientRect; titleRect.right = titleRect.left + mColumnWidth - 1;
	
	WNDborderStruct borderSpec; getBorderSpec( &borderSpec, mHeadingMode );
		
	HBRUSH brush = GDIgetStockBrush( BLACK_BRUSH );

  if ( mUIStyle )
  {
    GDIsetTextColor( pHdc, mHeadingColorFace );
    GDIfillRect( pHdc,&clientRect,brush);
    //pk1450 paint WeekNo.
    if ( mShowWeekNos ) GDIoffsetRect(&titleRect,mColumnWidth,0);
  }

  for ( qshort i = 0; i<=6; i++ )
	{
		if ( i==6 ) titleRect.right = clientRect.right;
    //pk1450
    if ( mUIStyle )
    {
      GDIsetTextColor( pHdc, mHeadingColorFace );
      //GDIfillRect( pHdc,&titleRect,brush);
    }
    else
    {
      GDIsetTextColor( pHdc, mHeadingColorFace );
      GDIfillRect( pHdc,&titleRect,brush);
      WNDpaintBorder(	mHWnd, pHdc, &titleRect, &borderSpec );
    }
    qrect titleRect1 = titleRect;
    GDIinsetRect( &titleRect1, 2, 2 );
    paintDayName( pHdc, i, &titleRect, eci );  // rmm3735
		GDIoffsetRect( &titleRect, mColumnWidth, 0 );
	} 
	GDIselectObject( pHdc, oldfnt );
	GDIdeleteObject( font );
}

qbool tqfCalendar::isToday( qshort pIndex )
{
	return pIndex==mLastTodayIndex;
}

qbool tqfCalendar::isCurrentDay( qshort pIndex )
{
	return pIndex==mLastCurDayIndex;
}

qrect tqfCalendar::getIndexRect( qshort pIndex )
{
	qrect client=mClientRect,client1;
  if ( mUIStyle && mShowWeekNos ) client.left+=mColumnWidth;
	client1 = client;
  client.top += mNavHt; //pk1450
	client.top = client.top + mTitleHeight+1;
	client.bottom = client.top + mColumnHeight-1;
	client.right = client.left + mColumnWidth-1;
	qshort row = pIndex / 7;
	qshort col = pIndex - ( row * 7 ); 
	GDIoffsetRect( &client, col * mColumnWidth, row * mColumnHeight );
	if ( col==6 ) client.right = client1.right;
	if ( row==5 ) client.bottom = client1.bottom;
	return client;
}

//pk1450
void tqfCalendar::processNavClick( qpoint* pPoint )
{
  qrect navBar = mClientRect; navBar.bottom = navBar.top + mNavHt;
  
  qrect monthLeft = navBar; monthLeft.left=8; monthLeft.right = monthLeft.left + monthLeft.height();
  qbool eventAndResetDates = qfalse;
  
  if (GDIptInRect(&monthLeft, pPoint))
  {
    qbool canSendEvent = ECOisOMNISinTrueRuntime( mHWnd );
    if ( canSendEvent )
    {
      if ( mCalMode==0 ) { mCurrentDate.tm_mon = mCurrentDate.tm_mon-1; eventAndResetDates = qtrue; }
      else if ( mCalMode==1 ) { mCurrentDate.tm_year--; eventAndResetDates = qtrue; }
      else if ( mCalMode==2 ) { mStartYear-=10; }
      else if ( mCalMode==3 ) { mStartYear-=100; }
      if ( eventAndResetDates )
      {
        time_t tmp;
        tmp = mktime( &mCurrentDate );
        if ( tmp!=-1 ) mCurrentDate = *localtime( &tmp );
      }
    }
  }
  qrect monthRight = navBar; monthRight.right-=8; monthRight.left = monthRight.right - monthRight.height();
  if (GDIptInRect(&monthRight, pPoint))
  {
    qbool canSendEvent = ECOisOMNISinTrueRuntime( mHWnd );
    if ( canSendEvent )
    {
      if ( mCalMode==0 ) { mCurrentDate.tm_mon = mCurrentDate.tm_mon+1; eventAndResetDates = qtrue; }
      else if ( mCalMode==1 ) { mCurrentDate.tm_year++; eventAndResetDates = qtrue; }
      else if ( mCalMode==2 ) { mStartYear+=10; }
      else if ( mCalMode==3 ) { mStartYear+=100; }
      if ( eventAndResetDates )
      {
        time_t tmp;
        tmp = mktime( &mCurrentDate );
        if ( tmp!=-1 ) mCurrentDate = *localtime( &tmp );
      }
    }

  }
  qrect monthSelect = navBar; monthSelect.left=monthLeft.right; monthSelect.right=monthRight.left;
  if (GDIptInRect(&monthSelect, pPoint))
  {
    mCalMode++;
    if ( mCalMode==2 )
    {
      mStartYear = mCurrentDate.tm_year + 1900; mStartYear -= mStartYear % 10;
    }
    else if ( mCalMode==3 )
    {
      mStartYear = mCurrentDate.tm_year + 1900; mStartYear -= mStartYear % 100;
    }
    if ( mCalMode>3 ) mCalMode = 0;
    WNDinvalidateRect( mHWnd, NULL );
  }
  if ( eventAndResetDates )
  {
    EXTfldval currentDate; datestamptype ds; getDateForOmnis(ds); currentDate.setDate(ds);
    ECOsendEvent( mHWnd, cCalendarEvDateChange, &currentDate, 1, qfalse );
    setDateArray(); WNDinvalidateRect( mHWnd, NULL );
  }
  WNDupdateWindow( mHWnd );

}

void tqfCalendar::findCell( qpoint* pPoint, qbool pIsDoubleClick )
{
	if ( !mAllowDayChange ) return;
	qrect client = mClientRect;
  
  //pk1450
  if ( mNavHt && mUIStyle && mShowMonthNav )
  {
    qrect navBar = client; navBar.bottom = navBar.top + mNavHt;
    if (GDIptInRect(&navBar, pPoint))
    {
      processNavClick( pPoint );
      return;
    }
  }
  
  client.top += mNavHt; //pk1450
	client.top = client.top + mTitleHeight+1;
	client.bottom = client.top + (qshort)mColumnHeight; 
	client.right = client.left + (qshort)mColumnWidth;
  
  //pk1450
  if ( mUIStyle && ( mCalMode==1 || mCalMode==2 || mCalMode==3 ) && !mReportObj )
  {
    for ( qshort cellindex = 0; cellindex<12; cellindex++ )
    {
      qrect r = getIndexRectEx( cellindex );
      if (GDIptInRect(&r, pPoint))
      {
        qbool canSendEvent = ECOisOMNISinTrueRuntime( mHWnd );
        if ( mCalMode==1)
        {
          // month set
          mCurrentDate.tm_mon = cellindex;
        }
        if ( mCalMode==2)
        {
          // year set
          mCurrentDate.tm_year = (mStartYear + cellindex)-1900;
          canSendEvent = qfalse;
        }
        if ( mCalMode==3)
        {
          // year set - decades
          mStartYear = (mStartYear + (cellindex*10));
          //mCurrentDate.tm_year = (mStartYear + (cellindex*10))-1900;
          canSendEvent = qfalse;
        }
        if ( canSendEvent )
        {
          EXTfldval currentDate; datestamptype ds; getDateForOmnis(ds); currentDate.setDate(ds);
          ECOsendEvent( mHWnd, pIsDoubleClick ? cCalendarEvDateDblClick : cCalendarEvDateChange, &currentDate, 1, qfalse );
          setDateArray();
        }
        mCalMode--;
        WNDupdateWindow( mHWnd );
      }
    }
    return;
  }

  
		
	for ( qshort cellindex = 0; cellindex<42; cellindex++ )
	{
		qrect r = getIndexRect( cellindex );
		if (GDIptInRect(&r, pPoint))
		{
			changeDayAndSendEvent(cellindex, pIsDoubleClick);	// rmm_mobile
		}
	}
}

// rmm_mobile: Made this into a method
void tqfCalendar::changeDayAndSendEvent(qshort pCellIndex, qbool pIsDoubleClick)
{
	qbool canSendEvent = ECOisOMNISinTrueRuntime( mHWnd );
	qrect r = getIndexRect( pCellIndex );
	if ( mDayDates[pCellIndex].mThisMonth )
	{
		mCurrentDate.tm_mday = mDayDates[pCellIndex].mDay;
		qrect r1 = getIndexRect( mLastCurDayIndex );
		mLastCurDayIndex = pCellIndex;
		if ( !mReportObj )
		{
			WNDinvalidateRect( mHWnd, &r );
			WNDinvalidateRect( mHWnd, &r1 );
			if ( canSendEvent ) 
			{
				EXTfldval currentDate; datestamptype ds; getDateForOmnis(ds); currentDate.setDate(ds);															// rmm3550
				ECOsendEvent( mHWnd, pIsDoubleClick ? cCalendarEvDateDblClick : cCalendarEvDateChange, &currentDate, 1, qfalse );		// rmm3550 // rmm3685: push the event
			}
			WNDupdateWindow( mHWnd );
		}
	}  
	else
	{
		if ( mDayDates[pCellIndex].mPrevMonth )
		{
			mCurrentDate.tm_mday = mDayDates[pCellIndex].mDay;
			mCurrentDate.tm_mon--;
		}
		else
		{
			mCurrentDate.tm_mday = mDayDates[pCellIndex].mDay;
			mCurrentDate.tm_mon++;
		}
		time_t tmp;
		tmp = mktime( &mCurrentDate );
		if ( tmp!=-1 ) mCurrentDate = *localtime( &tmp );   
		setDateArray();
		if ( !mReportObj )
		{
			WNDinvalidateRect( mHWnd, NULL );
			if ( canSendEvent ) 
			{
				// Start rmm3550
				EXTfldval currentDate; datestamptype ds; getDateForOmnis(ds); currentDate.setDate(ds);
				ECOsendEvent( mHWnd, cCalendarEvResetMonth, &currentDate, 1, qfalse ); // rmm3685: push the event
				ECOsendEvent( mHWnd, pIsDoubleClick ? cCalendarEvDateDblClick : cCalendarEvDateChange, &currentDate, 1, qfalse ); // rmm3685: push the event
				// End rmm3550
			}
			WNDupdateWindow( mHWnd );
		}
	}
}

void tqfCalendar::paintSingleDay( HDC pHdc, qshort pCellIndex, HFONT pNormal, HFONT pBold )
{
	qrect cell = getIndexRect( pCellIndex );
	qbool istoday = isToday( pCellIndex ); 
	qbool isCurrent = isCurrentDay( pCellIndex );
	
	HFONT oldfnt = ( istoday && mTodayBold ) ? GDIselectObject( pHdc, pBold ) : GDIselectObject( pHdc, pNormal );  
	
	WNDborderStruct borderSpec; 
	qlong md = mDaysMode;
	if ( isCurrent ) 
		md = mCurrentDayMode;
	else if ( !mDayDates[ pCellIndex ].mThisMonth )  
		md = mOtherDaysMode;

	//pk1450
  if (mUIStyle )
  {
    if ( mDayDates[ pCellIndex ].mThisMonth )
      GDIsetTextColor( pHdc, mDayColorFace );
    else
      GDIsetTextColor( pHdc, mOtherDayColorFace );

    GDIfillRect( pHdc, &cell, GDIgetStockBrush( BLACK_BRUSH ) );


    qrect cell1 = cell;
    if ( isCurrent )
    {
      GDIsetTextColor( pHdc, mCurrentDayColorFace );
      qdim rnd = cell1.height()/4; if ( rnd<4 ) rnd = 4; if ( rnd>8 ) rnd = 8;
      GDIinsetRect(&cell1,2,2);
      GDIfillRoundRect(pHdc, &cell1, rnd, rnd, GDIgetStockBrush( BLACK_BRUSH ));
    }
    cell1 = cell;
    if ( istoday )
    {
      GDIsetTextColor( pHdc, mTodayFaceColor );
      qdim rnd = cell1.height()/4; if ( rnd<4 ) rnd = 4; if ( rnd>8 ) rnd = 8;
      if ( isCurrent ) GDIinsetRect(&cell1,4,4); else GDIinsetRect(&cell1,2,2);
      GDIfillRoundRect(pHdc, &cell1, rnd, rnd, GDIgetStockBrush( BLACK_BRUSH ));
    }
  }
  else
  {
    getBorderSpec( &borderSpec, md );
  
    if ( isCurrent )
      GDIsetTextColor( pHdc, mCurrentDayColorFace );
    else if ( istoday )
      GDIsetTextColor( pHdc, mTodayFaceColor );
    else if ( mDayDates[ pCellIndex ].mThisMonth )
      GDIsetTextColor( pHdc, mDayColorFace );
    else
      GDIsetTextColor( pHdc, mOtherDayColorFace );
    GDIfillRect( pHdc, &cell, GDIgetStockBrush( BLACK_BRUSH ) );
    WNDpaintBorder(	mHWnd, pHdc, &cell, &borderSpec );
  }
	qrect cell1 = cell;
  GDIinsetRect( &cell1, 2, 2 );
		
	// draw day id
	qshort day = mDayDates[ pCellIndex ].mDay;
	str255 s;
	qlongToString(day,s);
	if ( istoday ) 
		GDIsetTextColor( pHdc, mTodaysColor );
	else
	{ 
		if ( isCurrent ) GDIsetTextColor( pHdc, mCurrentDayColor );
		else GDIsetTextColor( pHdc, mDayDates[ pCellIndex ].mThisMonth ? mNormalColor : mOtherMonthColor );
	}
	  
  //pk1450
  qdim tw = 0; qdim gp = 0; qdim lp = 0;
  if ( mUIStyle )
  {
    tw = GDItextWidth(pHdc,&s[1], s.length());
    gp = ( cell1.width() - tw ) / 2;
    lp = cell1.left + gp;
  }

  if ( mDayDates[ pCellIndex ].mThisMonth )
  {
		// Start rmm_svg3
		EXTfldval iconId;
	  getDayMark(day, iconId);
		if (EXTBMPref::isIconID(iconId))
		{
      EXTBMPref bmp(iconId, mApp); // MHn0068
      ePicSize psize = EXTBMPref::getBmpSize(iconId);
      qrect drawrect, bmprect; bmp.getRect(&bmprect, psize);
      if ( mUIStyle )
      {
        gp = ( cell1.width() - (tw+bmprect.width() + 2) ) / 2;  // where 2 is the gap from right of text to left of icon
        lp = cell1.left + gp;
        drawrect = cell1; drawrect.left = drawrect.right - ( bmprect.width() + gp + 2 ) ;
      }
      else
      {
        drawrect = cell1; drawrect.left = drawrect.right - bmprect.width();
      }
			bmp.draw(pHdc, &drawrect, EXTBMPref::getBmpSize(iconId), picNormal, qfalse, colNone, qfalse, jstCenter, jstCenter);
		}
		// End rmm_svg3
  }

  //pk1450
  if ( mUIStyle)
  {
    //pk1450
    qdim top = cell1.top + (cell1.height()/2);
    qdim fht = GDIfontPart( pHdc, eFontHeight ) + 1; if ( fht ) top-=(fht/2);
    GDIdrawText( pHdc, lp, top, &s[1], s.length(), jstLeft) ; // jstCenter );
  }
  else
    GDIdrawText( pHdc, cell1.left, cell1.top, &s[1], s.length(), jstLeft );
	
	GDIselectObject( pHdc, oldfnt );  
}

void tqfCalendar::paintWeekNo( HDC pHdc )
{
  qfnt fnt = fntSmallFnt;
  ECOgetFont( mHWnd, &fnt, (qshort)mDayFont, (qshort)mDayFontSize );

  // Start rmm9347
  GDIfontCreator fc(pHdc, ECOgetFontDpi(mHWnd));
  HFONT font = fc.createFont(&fnt, styPlain);
  
  qrect client=mClientRect;
  client.top += mNavHt; //pk1450
  client.top = client.top + mTitleHeight+1;
  client.right = client.left + mColumnWidth-1;

  GDIsetTextColor( pHdc, mWeekNumberColor );
  GDIfillRect( pHdc, &client, GDIgetStockBrush( BLACK_BRUSH ) );
  GDIsetTextColor( pHdc, mWeekNumberTextColor );

  client.bottom = client.top + mColumnHeight-1;

  str255 s = str255(QTEXT("x"));
  qdim top = client.top + (client.height()/2);
  qdim fht = GDIfontPart( pHdc, eFontHeight ) + 1; if ( fht ) top-=(fht/2);

  HFONT oldFont = GDIselectObject(pHdc, font);
  for ( qshort cellindex = 0; cellindex<6; cellindex++ )
  {
    qlongToString(mWeekNo[cellindex],s);
    GDIdrawText( pHdc, client.left + client.width()/2, top , &s[1], s.length(), jstCenter );
    GDIoffsetRect(&client,0,mColumnHeight); top+=mColumnHeight;
  }
  GDIselectObject(pHdc, oldFont);
  GDIdeleteObject( font );
}

void tqfCalendar::paintDays( HDC pHdc )
{
	qfnt fnt = fntSmallFnt;
	ECOgetFont( mHWnd, &fnt, (qshort)mDayFont, (qshort)mDayFontSize );

	// Start rmm9347
	GDIfontCreator fc(pHdc, ECOgetFontDpi(mHWnd));
	HFONT font = fc.createFont(&fnt, styPlain);
	HFONT font2 = fc.createFont(&fnt, styBold);
	// End rmm9347
	for ( qshort cellindex = 0; cellindex<42; cellindex++ )
	{
		paintSingleDay( pHdc, cellindex, font, font2 );
	}
	GDIdeleteObject( font2 );					
	GDIdeleteObject( font );
}

void tqfCalendar::setGridSizes()
{
	if ( !mReportObj )
		WNDgetClientRect( mHWnd, &mClientRect );
	mColumnWidth = mClientRect.width() /  ((mUIStyle && mShowWeekNos) ? 8 : 7 );
  
	qshort ht = mClientRect.height();     

  //pk1450
  mNavHt = 0;
  qshort div_by = 6;  // dayrows
  qshort aver_ht = mClientRect.height();
  if ( mShowMonthNav && mUIStyle ) div_by++;
  if ( mShowHeading  ) div_by++;
  aver_ht = aver_ht / div_by;
  if ( mShowMonthNav && mUIStyle )
  {
    mNavHt = aver_ht;
    ht-= mNavHt; //pk1450
  }
  
	if ( mShowHeading )
	{
		qfnt fnt;
		ECOgetFont(mHWnd, &fnt, (qshort)mHeadingFont, (qshort)mHeadingFontSize);
		// Start rmm9347
		qdim dpi = ECOgetFontDpi(mHWnd);
		if (dpi)
		{
			HDC hdc = 0; HRESERVED res = 0;
			GDIcreateScreenDC(&hdc, &res);

			GDIfontCreator fc(hdc, dpi);
			HFONT hfont = fc.createFont(&fnt, styPlain);
			HFONT oldFont = GDIselectObject(hdc, hfont);
			mTitleHeight = 4 + GDIfontPart(hdc, eFontLineHeight);
			GDIselectObject(hdc, oldFont);
			GDIdeleteObject(hfont);

			GDIdeleteScreenDC(hdc, res);
		}
		else
			// End rmm9347
 			mTitleHeight = 4 + GDIfontPart( &fnt, styPlain, eFontLineHeight ); // rmm3735: since rectangle is inset by 4 before drawing text
 	}
 	else mTitleHeight = 0;

	if ( mShowHeading ) ht -= mTitleHeight;
	mColumnHeight = ht / 6;
  
  if ( mUIStyle )
  {
    if ( mCalMode==0 )
    {
      mNavHt = mShowMonthNav ? aver_ht : 0;
      mColumnHeight = aver_ht;
      mTitleHeight = mShowHeading ? aver_ht : 0;
    }
    else
    {
      //mNavHt=aver_ht;
      mColumnHeight = (mClientRect.height()-mNavHt) / 3;
      mColumnWidth = mClientRect.width() / 4;
      mTitleHeight=0;
    }
  }
}

void tqfCalendar::initTodaysDate()
{
  time_t now;
	time( &now );
  mCurrentDate = *localtime( &now );
  mTodaysDate = mCurrentDate;
  setDateArray();
}

#define SEARCH_PREV_MONTH 1
#define SEARCH_THIS_MONTH 2 
#define SEARCH_NEXT_MONTH 3

qshort tqfCalendar::getMonthLen( qshort pMonth )
{
	qshort len = 0; pMonth++;
	switch( pMonth )
	{
		case 1: case 3: case 5: case 7: case 8: case 10: case 12:
			len = 31; break;
		case 4: case 6: case 9: case 11:  
			len = 30; break;
		case 2:
			len = 28;
	}
	return len;
}

void tqfCalendar::setDateArray()
{
  struct tm searchmonth;
  struct tm monthstart;
  struct tm nextmonth;
  struct tm previousmonth;
    
	// get month start   
	monthstart = mCurrentDate;
	monthstart.tm_mday = 1;
	monthstart.tm_hour = 12; // PK6715
	monthstart.tm_min = 0; // PK6715
	time_t tmp = mktime( &monthstart );
	if ( tmp==-1 ) return;
	monthstart = *localtime( &tmp ); 
	// get previous month start   
	previousmonth = mCurrentDate;
	previousmonth.tm_mday = 1;
	previousmonth.tm_hour = 12; // PK6715
	previousmonth.tm_min = 0; // PK6715
	previousmonth.tm_mon--;
	if ( previousmonth.tm_mon<0 ) 
	{
		previousmonth.tm_mon = 11;
		previousmonth.tm_year--;
	}
	tmp = mktime( &previousmonth );
	if ( tmp==-1 ) return;
	previousmonth = *localtime( &tmp );   
	// get next month
	nextmonth = mCurrentDate;
	nextmonth.tm_mday = 1;
	nextmonth.tm_hour = 12; // PK6715
	nextmonth.tm_min = 0; // PK6715
	nextmonth.tm_mon++;
	if ( nextmonth.tm_mon>11 )
	{
		nextmonth.tm_mon = 0;
		nextmonth.tm_year++;
	}
	tmp = mktime( &nextmonth ); 
	if ( tmp==-1 ) return;
	nextmonth = *localtime( &tmp ); 
	// now setup days to disply from previous month
	qshort monthStart = monthstart.tm_wday;
	qshort calDayStart = mFirstDay - DEFINED_KOMNISFIRSTDAY;
	qshort daydiff = 0;
	if ( calDayStart==monthStart )
	{
		// both month and day start fall on same day, so go back a week
		daydiff = -7;		
	}
	else if ( calDayStart>monthStart )
	{
		daydiff = (calDayStart-monthStart) - 7;
	}
	else
	{
		daydiff = (calDayStart-monthStart);
	}
	daydiff++;
	  
	qshort prevmonthlen = getMonthLen( previousmonth.tm_mon );
	qshort monthlen = getMonthLen( monthstart.tm_mon );
	if ( monthstart.tm_mon==1 )
		monthlen = nextmonth.tm_yday - monthstart.tm_yday;	
	if ( previousmonth.tm_mon==1 )
		prevmonthlen = monthstart.tm_yday - previousmonth.tm_yday;	
 	
	// setup caendar day array
	
	qshort startdate = prevmonthlen + daydiff; 
	qshort monthon = SEARCH_PREV_MONTH;
	
	searchmonth = previousmonth;
	searchmonth.tm_mday = startdate;
	
	mLastCurDayIndex = mLastTodayIndex = 99;
  
  qshort wkno = 0;  //pk1450

	for ( qshort day = 0; day<42; day++ )
	{              
		qshort searchyear = searchmonth.tm_year+1900;
		
		mDayDates[day].mDay = startdate;
		mDayDates[day].mThisMonth = monthon==SEARCH_THIS_MONTH;
		mDayDates[day].mPrevMonth = monthon==SEARCH_PREV_MONTH;
		mDayDates[day].mToday = (qbool)( searchmonth.tm_mon==mTodaysDate.tm_mon && searchmonth.tm_mday==mTodaysDate.tm_mday && mTodaysDate.tm_year+1900==searchyear );
		mDayDates[day].mIsCurrent = (qbool)(monthon==SEARCH_THIS_MONTH && mCurrentDate.tm_year+1900==searchyear && mCurrentDate.tm_mday==startdate );
	
		if ( mDayDates[day].mIsCurrent ) 
			mLastCurDayIndex = day;

		if ( mDayDates[day].mToday ) 
			mLastTodayIndex = day;
    
    //pk1450
    if ( day==6 || day==13 || day==20 || day==27 || day==34 || day==41 )
    {
      qshort weekNo(struct tm* pCurrentDate);
      mWeekNo[wkno++] = weekNo(&searchmonth);
    }
	
		startdate++;
		searchmonth.tm_mday++;
		switch( monthon )
		{
			case SEARCH_PREV_MONTH:
			{
				if ( startdate>prevmonthlen )
				{
					monthon = SEARCH_THIS_MONTH;
					searchmonth.tm_mon++; 
					if ( searchmonth.tm_mon>11 )
					{
						searchmonth.tm_mon = 0;
						searchmonth.tm_year++;
					}
					searchmonth.tm_mday = 1;
					startdate = 1;
				} 
				break;
			}
			case SEARCH_THIS_MONTH:
			{
				if ( startdate>monthlen )
				{
					monthon = SEARCH_NEXT_MONTH;
					startdate = 1;
				} 
				break;
			}
		}
	} 
}



//pk1450
void tqfCalendar::paintMonthSelect( HDC pHdc,EXTCompInfo* eci )
{
  qrect clientRect = mClientRect; clientRect.bottom = clientRect.top + mNavHt;
  
  GDIsetTextColor( pHdc, mNavColor ); GDIfillRect( pHdc,&clientRect,GDIgetStockBrush(BLACK_BRUSH));
  
  qfnt fnt = fntSmallFnt;
  ECOgetFont( mHWnd, &fnt, (qshort)mNavFont, (qshort)mNavFontSize );
  GDIfontCreator fc(pHdc, ECOgetFontDpi(mHWnd));
  HFONT font = fc.createFont(&fnt, styBold );
  
  HFONT oldfnt = GDIselectObject( pHdc, font );
  
  qdim top = clientRect.top + (clientRect.height()/2);
  qdim fht = GDIfontPart( pHdc, eFontHeight ) + 1; if ( fht ) top-=(fht/2);
  
  str255 s; qlongToString(mCurrentDate.tm_year + 1900,s);

  GDIsetTextColor( pHdc, mNavTextColor );
  // font !
  GDIdrawText( pHdc, clientRect.left + clientRect.width()/2, top , &s[1], s.length(), jstCenter );
  if ( mAllowDayChange==qtrue )
  {
    s = str255(QTEXT("<<"));
    GDIdrawText( pHdc, clientRect.left + 8, top, &s[1], s.length(), jstLeft );
    s = str255(QTEXT(">>"));
    GDIdrawText( pHdc, clientRect.left + clientRect.width() - 8, top, &s[1], s.length(), jstRight );
  }
  GDIselectObject( pHdc, oldfnt );
  GDIdeleteObject( font );
}

//pk1450
void tqfCalendar::paintYearSelect( HDC pHdc, qshort pYearMode,EXTCompInfo* eci )
{
  qrect clientRect = mClientRect; clientRect.bottom = clientRect.top + mNavHt;
  
  GDIsetTextColor( pHdc, mNavColor ); GDIfillRect( pHdc,&clientRect,GDIgetStockBrush(BLACK_BRUSH));
  
  qfnt fnt = fntSmallFnt;
  ECOgetFont( mHWnd, &fnt, (qshort)mNavFont, (qshort)mNavFontSize );
  GDIfontCreator fc(pHdc, ECOgetFontDpi(mHWnd));
  HFONT font = fc.createFont(&fnt, styBold );
  
  HFONT oldfnt = GDIselectObject( pHdc, font );
  
  qdim top = clientRect.top + (clientRect.height()/2);
  qdim fht = GDIfontPart( pHdc, eFontHeight ) + 1; if ( fht ) top-=(fht/2);
  
  str255 s; qlongToString(mStartYear,s);

  str255 s2 = str255(QTEXT(" - ")); s.concat(s2);
  if ( pYearMode==0 ) qlongToString(mStartYear+12,s2); else qlongToString(mStartYear+120,s2);
  s.concat(s2);
  
  GDIsetTextColor( pHdc, mNavTextColor );
  // font !
  GDIdrawText( pHdc, clientRect.left + clientRect.width()/2, top , &s[1], s.length(), jstCenter );
  if ( mAllowDayChange==qtrue )
  {
    s = str255(QTEXT("<<"));
    GDIdrawText( pHdc, clientRect.left + 8, top, &s[1], s.length(), jstLeft );
    s = str255(QTEXT(">>"));
    GDIdrawText( pHdc, clientRect.left + clientRect.width() - 8, top, &s[1], s.length(), jstRight );
  }
  GDIselectObject( pHdc, oldfnt );
  GDIdeleteObject( font );

}

//pk1450
qrect tqfCalendar::getIndexRectEx( qshort pIndex )
{
  qrect client=mClientRect,client1;
  client1 = client;
  client.top += mNavHt + 1; //pk1450
  client.bottom = client.top + mColumnHeight-1;
  client.right = client.left + mColumnWidth-1;
  qshort row = pIndex / 4;
  qshort col = pIndex - ( row * 4 );
  GDIoffsetRect( &client, col * mColumnWidth, row * mColumnHeight );
  if ( col==3 ) client.right = client1.right;
  if ( row==3 ) client.bottom = client1.bottom;
  return client;
}

//pk1450
void tqfCalendar::paintMonths( HDC pHdc, EXTCompInfo* eci )
{
  qfnt fnt = fntSmallFnt;
  ECOgetFont( mHWnd, &fnt, (qshort)mDayFont, (qshort)mDayFontSize );

  GDIfontCreator fc(pHdc, ECOgetFontDpi(mHWnd));
  HFONT font = fc.createFont(&fnt, styPlain); HFONT font2 = fc.createFont(&fnt, styBold);
  
  HFONT oldfnt = GDIselectObject( pHdc, font );
  
  auto paintSingleMonth = [pHdc,eci, this](qshort index)
  {
    qrect cell1 = getIndexRectEx( index );
    
    qbool monthshortname = mShortName;
    str255 locItemData; qchar *namePtr; qshort slen = 0;
    qshort locItemXn = monthshortname ? cLOCxnAbbJanText :cLOCxnFullJanuaryText; locItemXn += (index); qbool ok = qfalse;
    if (ECOreadLocalisationItem(eci, locItemXn, locItemData))
    {
      namePtr = &locItemData[1]; slen = locItemData[0]; ok = qtrue;
    }
    if (!ok)
    {
      qlong id = monthshortname ? 3040 : 3020; qchar name[64];
      slen = (qshort)RESloadString( gInstLib, id + index, &name[0], 64 ); namePtr = name;
    }
    
    qdim top = cell1.top + (cell1.height()/2);
    qdim fht = GDIfontPart( pHdc, eFontHeight ) + 1; if ( fht ) top-=(fht/2);
    GDIinsetRect(&cell1,2,2);
    GDIsetTextColor( pHdc, mDayColorFace );
    GDIfillRoundRect(pHdc, &cell1, 4, 4, GDIgetStockBrush( BLACK_BRUSH ));
    GDIsetTextColor( pHdc, mNormalColor );
    GDIdrawText( pHdc, cell1.left + cell1.width()/2, top, namePtr, (qshort) slen, jstCenter );

  };

  for ( qshort cellindex = 0; cellindex<12; cellindex++ )
  {
    paintSingleMonth( cellindex );
  }
  
  GDIselectObject( pHdc, oldfnt );
  
  GDIdeleteObject( font2 );
  GDIdeleteObject( font );
}

//pk1450
void tqfCalendar::paintYears( HDC pHdc, qshort pYearMode, EXTCompInfo* eci )
{
  qfnt fnt = fntSmallFnt;
  ECOgetFont( mHWnd, &fnt, (qshort)mDayFont, (qshort)mDayFontSize );

  GDIfontCreator fc(pHdc, ECOgetFontDpi(mHWnd));
  HFONT font = fc.createFont(&fnt, styPlain); HFONT font2 = fc.createFont(&fnt, styBold);
  
  HFONT oldfnt = GDIselectObject( pHdc, font );
  
  auto paintSingleYear = [pHdc,pYearMode, eci, this](qshort index)
  {
    qrect cell1 = getIndexRectEx(index);
    str255 s;
    if ( pYearMode==0 ) qlongToString(mStartYear+index,s); else qlongToString(mStartYear+(index*10),s);
    qdim top = cell1.top + (cell1.height()/2);
    qdim fht = GDIfontPart( pHdc, eFontHeight ) + 1; if ( fht ) top-=(fht/2);
    GDIinsetRect(&cell1,2,2);
    GDIsetTextColor( pHdc, mDayColorFace );
    GDIfillRoundRect(pHdc, &cell1, 4, 4, GDIgetStockBrush( BLACK_BRUSH ));
    GDIsetTextColor( pHdc, mNormalColor );
    GDIdrawText( pHdc, cell1.left + cell1.width()/2, top, &s[1], (qshort) s.length(), jstCenter );

  };

  for ( qshort cellindex = 0; cellindex<12; cellindex++ )
  {
    paintSingleYear( cellindex );
  }
  
  GDIselectObject( pHdc, oldfnt );
  
  GDIdeleteObject( font2 );
  GDIdeleteObject( font );
}

void tqfCalendar::paintCalendar( HDC pHdc, EXTCompInfo* eci ) // rmm3635
{
	setGridSizes();
  if ( mUIStyle && (mCalMode==1 || mCalMode==2 || mCalMode==3) )
  {
    if ( mCalMode==1 ) { paintMonthSelect( pHdc,eci ); paintMonths( pHdc, eci ); }
    else if ( mCalMode==2 ) { paintYearSelect( pHdc, 0, eci ); paintYears( pHdc, 0, eci ); }
    else if ( mCalMode==3 ) { paintYearSelect( pHdc, 1, eci ); paintYears( pHdc, 1, eci ); }
  }
  else
  {
    if ( mShowMonthNav && mUIStyle ) paintNavMonth(pHdc, eci); //pk1450
    if ( mShowHeading ) paintDayTitles( pHdc, eci ); // rmm3735
    paintDays( pHdc );
    if ( mUIStyle && mShowWeekNos ) paintWeekNo( pHdc );
  }
}

qbool tqfCalendar::paint(EXTCompInfo* eci) // rmm3735
{
	// rmm11062: Draw offscreen
	qrect clientRect;
	WNDgetClientRect(mHWnd, &clientRect);

	WNDpaintStruct paintStruct;
	WNDbeginPaint( mHWnd, &paintStruct );

	HDC hdc = paintStruct.hdc;
	qrect	rcPaint = paintStruct.rcPaint;
	void* offscreenPaintInfo = GDIoffscreenPaintBegin(NULL, hdc, clientRect, rcPaint);
	if (offscreenPaintInfo)
	{
		WNDdefWindowProc(mHWnd, WM_ERASEBKGND, (WPARAM)hdc, 0, eci);

		paintCalendar(hdc, eci);	// rmm3735
		// Start rmm4999
		if (ECOisShowNumber(mHWnd))
			ECOdrawNumberEx(mHWnd, hdc, qtrue);
		// End rmm4999
		ECOdrawMultiKnobs(mHWnd, hdc); // rmm5006
		GDIoffscreenPaintEnd(offscreenPaintInfo);
	}
	WNDendPaint( mHWnd, &paintStruct );	
	return qtrue;
}

// rmm3735
void tqfCalendar::setTooltipIndex(qpoint &pPt)
{
	mTooltipIndex = -1;
	for (qshort cellindex = 0; cellindex < 42; cellindex++)
	{
		qrect r = getIndexRect(cellindex);
		if (GDIptInRect(&r, &pPt))
		{
			mTooltipIndex = cellindex;
			return;
		}
	}
}

extern "C" LRESULT OMNISWNDPROC GenericWndProc( HWND hwnd, UINT Msg, WPARAM wParam, LPARAM lParam, EXTCompInfo* eci )
{
   ECOsetupCallbacks(hwnd,eci);
	 switch (Msg)
	 {
       //pk1450
     case ECM_GETCONSTNAME:
     {
       return ECOreturnConstants(gInstLib, eci, 9000, 9001);
     }
			case WM_LBUTTONDBLCLK:
			case WM_LBUTTONDOWN:
			{
				qpoint pt;
				if ( !ECOisDesign( hwnd ) )
				{           
					ECOhideTooltip( hwnd );
					WNDmakePoint( lParam, &pt );
					tqfCalendar* object = (tqfCalendar*)ECOfindObject( eci, hwnd );
					if ( object ) 
					{
						object->findCell(&pt,Msg==WM_LBUTTONDBLCLK);
						return qtrue;
					}
				}
				break; 	
			}
			case ECM_PRINTMAPPING: return 1L; // Yes, we want printer mapping
			case ECM_PRINT:
			{
				tqfCalendar* object = (tqfCalendar*)ECOfindObject( eci, hwnd );
				if ( object )
				{
					WNDpaintStruct* paintStruct = (WNDpaintStruct*)lParam;
					object->setPrintRect( &paintStruct->rcPaint );
					object->paintCalendar( paintStruct->hdc, eci ); // rmm3735
				}
				break;
			}
			case WM_PAINT:							
			{
				tqfCalendar* object = (tqfCalendar*)ECOfindObject( eci, hwnd );
				if ( object && object->paint(eci) ) // rmm3735
					return qtrue;
				break;
			}
			case WM_ERASEBKGND: return 1L;
			case ECM_OBJCONSTRUCT:				/* Construct an object */
			{
				tqfCalendar* object = new tqfCalendar( hwnd, (qbool)wParam );
				ECOinsertObject( eci, hwnd, (void*)object );
				object->mApp = ECOgetApp( eci->mInstLocp );	 // MHn0068
				return qtrue;
			}
			case ECM_OBJDESTRUCT:					/* Destruct the object */
			{
				tqfCalendar* object = (tqfCalendar*)ECOremoveObject( eci, hwnd );
				if ( object ) delete object;              
				return qtrue;
			}
			case ECM_PROPERTYCANASSIGN:  	
			case ECM_SETPROPERTY: 				
			case ECM_GETPROPERTY:					
			{
				tqfCalendar* object = (tqfCalendar*)ECOfindObject( eci, hwnd );
				if ( object )
					return object->attributeSupport( Msg, wParam, lParam, eci );
				return 0L;
			}
      case ECM_GETCOMPLIBINFO:
      {
      	return ECOreturnCompInfo( gInstLib, eci, LIB_RES_NAME, COMPONENT_COUNT );
      }
			case ECM_GETCOMPICON:
			{ 	
				if ( eci->mCompId==CALENDAR_ID ) return ECOreturnIcon( gInstLib, eci, CALENDAR_ICON );
				return qfalse;
			}   
			case ECM_CUSTOMTABNAME:
			{
				ECOsetCustomTabName( gInstLib, eci, 8000 );
				return 1L;
			}
			case ECM_METHODCALL:
			{
				tqfCalendar* object = (tqfCalendar*)ECOfindObject( eci, hwnd );
				if ( object )
					object->functionSupport( Msg, wParam, lParam, eci );
				return 1L;
			}
			case WM_TOOLTIP:	// rmm3735
			{
				if (!ECOisDesign(hwnd) && TIP_GETTIP == wParam)
				{
					tqfCalendar *object = (tqfCalendar *)ECOfindObject(eci, hwnd);
					if (object && object->dayTooltips() && object->calMode()==0)
					{
						TIPinfo *info = (TIPinfo *) lParam;
						object->setTooltipIndex(info->mShowPoint);
						LRESULT retVal = 1L;	// rmm64bit5
						if (object->tooltipIndex() >= 0)
						{
							retVal = WNDdefWindowProc(hwnd, Msg, wParam, lParam, eci);
							if (info->mHasTip)
							{
								// Set the active show area for the tooltip to be the day's rectangle
								info->mActiveShowArea = object->getIndexRect(object->tooltipIndex());
							}
						}
						return retVal;
					}
				}
				break;
			}
			case ECM_GETCOMPID:
			{
				if ( wParam==1 )
					return ECOreturnCompID( gInstLib, eci, CALENDAR_ID, cObjType_Basic|cRepObjType_Basic );
				return 0L;
			}
			case ECM_GETEVENTNAME:
			{
				return ECOreturnEvents( gInstLib, eci, &CALENDARevents[0], sizeof(CALENDARevents)/sizeof(CALENDARevents[0]) ); // rmm3550
			}
			case ECM_GETMETHODNAME:
			{
				return ECOreturnMethods( gInstLib, eci, &CALENDARfunctions[0], 3 );
			}
			case ECM_GETPROPNAME:
			{
				return ECOreturnProperties( gInstLib, eci, &CALENDARproperties[0], sizeof(CALENDARproperties)/sizeof(CALENDARproperties[0]) ); // MHn0068 // rmm3735
			}              
			case ECM_GETVERSION:	// rmm3478
			{
				return ECOreturnVersion(gInstLib);
			}                                                                 
			case ECM_ISUNICODE:	// rmmuni
			{
				return qtrue;
			}
	 }
	 return WNDdefWindowProc(hwnd,Msg,wParam,lParam,eci);
}
// End of file



//pk1450 ---- ISO Week Support - from datefunc.

#define  CENTI_second  100.0        // number of centi-seconds in a second ...
#define  CENTI_minute  6000.0      //  ..  ditto minute
#define  CENTI_hour    360000.0    //  ..  ditto hour
#define  CENTI_day      8640000.0    //  ..  ditto day
#define  NUM_CSeconds  100.0        // number of centi-seconds in one second
#define  NUM_Seconds    60.0        // number of seconds in one minute
#define  NUM_Minutes    60.0        // number of minutes in one hour
#define  NUM_Hours      24.0        // number of hours in one day
// NB_date end

#define kYear           1
#define kMonth          2
#define kWeek           3
#define kDayofYear      4
#define kQuarter        5
#define kMonthofQuarter 6
#define kWeekofQuarter  7
#define kDayofQuarter   8
#define kWeekofMonth    9
#define kDay            10
#define kDayofWeek      11
#define kSunday         12
#define kMonday         13
#define kTuesday        14
#define kWednesday      15
#define kThursday       16
#define kFriday         17
#define kSaturday       18
#define kHour           19
#define kMinute         20
#define kSecond         21
#define kCentiSecond    22
#if defined(ismac)
  #ifndef isCOCOA  // CR0153
      #include <fp.h>
  #endif
  #define _BLYTH_MACOS
#else
  #include <math.h>
  #define _BLYTH_WIN32OS
#endif
struct val_datetime
{
  short  year;
  short  month;
  short day;
  short  hour;
  short  minute;
  short  second;
  short  hundred;
};

#define ushort unsigned short

#define NumCentiInDay (100.0 * 60.0 * 60.0 * 24.0)


double IntDate2Centi(val_datetime *aDate, qbool timeOnly)  // rmm4028
{
  double centidate = 0;    // return value containing the centiseconds ... // rmm4028
  if (!timeOnly)            // rmm4028
  {
    short chkLeapYears;    // checker for total leap-year days
    short cnt;            // Gen.Pur. count and index ...
    short  months[] =
      {  31,      // January
        28,      // Feburary
        31,      // March
        30,      // April
        31,      // May
        30,      // June
        31,      // July
        31,      // August
        30,      // September
        31,      // October
        30,      // November
        31      // December
      };

    // Check for a leap-year and adjust Febrary to 29 days ...
    if ( !( aDate->year % 4 ) && ( ( aDate->year % 100 ) || !( aDate->year % 400  ) ) )
    {
      months[ 2-1 ]++;
    }

    // calculate the total days from the years allowing for Leap-years
    centidate = (double)( aDate->year ) * 365.0;
    chkLeapYears = ( aDate->year - 1 ); // do not include the current year.
    if (chkLeapYears >= 0)
    {
      chkLeapYears -= chkLeapYears % 4;
      if ( chkLeapYears >= 0 )
      {
        while ( chkLeapYears >= 0.0 )
        {
          if ( ( chkLeapYears % 100 ) || !( chkLeapYears % 400 )  )
          {
            centidate++;
          }
          chkLeapYears-=4;
        }
      }
    }

    // add the total days from the month and day sections of the date-struct ...
    for( cnt = 1; cnt < aDate->month; cnt++ )
    {
      centidate += (double)months[ cnt - 1 ];
    }
    centidate += (double)( aDate->day - 1);

    // convert the total days into centi-seconds
    centidate *= CENTI_day;
  }
  // add the remaining hours,monutes,seconds and centi-seconds ...
  centidate += ( (double)aDate->hour * CENTI_hour );
  centidate += ( (double)aDate->minute * CENTI_minute );
  centidate += ( (double)aDate->second * CENTI_second );
  centidate += ( (double)aDate->hundred );

  return( centidate );
}

ushort IntGetDOW(double centiDate)
{
  double days;
   ushort day;

   days = (double)floor((double)(centiDate / NumCentiInDay));
   day  = kSunday + (ushort)(fmod((double)days,7.0));
   day--;

   return day;
}

void IntCenti2Date(val_datetime *aDate,double centidate, qbool timeOnly) // rmm4028
{
  double Days;          // Total num of days left for calculation ...
  double Remaining;    // Gen.Pur. store for calculation of val_datetime members ...
  short lYr;          // SDB
  double lYdays;        // SDB
  short   lNext = 1;    // SDB
  short cnt;            // Gen.Pur. count or index ...
  short  months[] =
    {  31,      // January
      28,      // Feburary
      31,      // March
      30,      // April
      31,      // May
      30,      // June
      31,      // July
      31,      // August
      30,      // September
      31,      // October
      30,      // November
      31      // December
    };

  // Setup centi-seconds,seconds,minutes and hours of date-time struct ...
  aDate->hundred = (ushort)floor( fmod( centidate, NUM_CSeconds ) );
  Remaining = floor( centidate / NUM_CSeconds );
  aDate->second = (ushort)floor( fmod( Remaining, NUM_Seconds ) );
  Remaining = floor( Remaining / NUM_Seconds );
  aDate->minute = (ushort)floor( fmod( Remaining, NUM_Minutes ) );
  Remaining = floor( Remaining / NUM_Minutes );
  aDate->hour = (ushort)floor( fmod( Remaining, NUM_Hours ) );
  Remaining = floor( Remaining / NUM_Hours );

  // Start rmm4028
  if (timeOnly)
  {
    aDate->year = aDate->month = aDate->day = 0;
    return;
  }
  // End rmm4028

  // Remainig now equals the total days since 1-Jan 0000 ...
  Days = Remaining;

  // from year 0, work through to remove the correct number of days...
  lYr = 0;
  do
  {
    if ( !(lYr % 4) && ((lYr % 100) || !(lYr % 400)))
    {
      //then it's a leap year...
      lYdays = 366;
    }
    else
    {
      lYdays = 365;
    }

    if (Days >= lYdays)
    {
      lYr++;
      Days -= lYdays;
    }
    else
    {
      lNext = 0;
    }

  }while(lNext);

  aDate->year = lYr; // subtract one off year as it's post-incremented.

  // Check for a leap-year and adjust Febrary to 29 days ...
  if ( !( aDate->year % 4 ) && ( ( aDate->year % 100 ) || !( aDate->year % 400  ) ) )
  {
    months[ 2-1 ]++;
  }

  // Now generate the month and day from the remaining ...
  cnt = 0;
  aDate->month = 1;                // Reset Month to Jan.
  while(( Days >= (double)months[ cnt ] ) && ( cnt < 11 ))
  {
    Days -= months[ cnt++ ];
    aDate->month++;
  }
  aDate->day = (ushort)Days + 1; // add one as day 0 makes no sense.
}

double IntDateDiff(ushort datePart,val_datetime *fromDate,val_datetime *toDate)
{
  double        number = 0,centiFDate,centiTDate; // rmm3068: warning
   val_datetime   tempDate;
   centiFDate = IntDate2Centi(fromDate, false);
   centiTDate = IntDate2Centi(toDate, false);
   tempDate = *fromDate;

   switch (datePart)
   {
      case kDay:
         number = centiTDate - centiFDate;
         if (datePart == kCentiSecond) break;
         number /= 100.0;
         if (datePart == kSecond) break;
         number /= 60.0;
         if (datePart == kMinute) break;
         number /= 60.0;
         if (datePart == kHour) break;
         number /= 24.0;
         if (datePart == kDay) break;
         if (datePart == kWeek){
            number = (double)floor((double)(number/7.0));  /* Figure out weeks (whole numbers only) */
            break;
         }
      default:
     {
     }
   }
   return number;
}

double IntGetStartOfWeek1(short pYear)
{
  
  val_datetime theDate, startOfWeek1;
  double centiJan1;
  ushort dayOfWeek;

  theDate.hour = theDate.minute = theDate.second = theDate.hundred = 0;
  theDate.year = pYear;
  theDate.month = theDate.day = 1;

  startOfWeek1 = theDate;

  centiJan1 = IntDate2Centi(&theDate, false);
  dayOfWeek = IntGetDOW(centiJan1);
  if (dayOfWeek == 11) // Found this test elsewhere in the file!
  {
    dayOfWeek += 7;
  }
  switch (dayOfWeek)
  {
    case kMonday:        break;  // Week 1 starts on 1st Jan
    case kTuesday:      startOfWeek1.year--; startOfWeek1.day = 31; startOfWeek1.month = 12; break;
    case kWednesday:    startOfWeek1.year--; startOfWeek1.day = 30; startOfWeek1.month = 12; break;
    case kThursday:      startOfWeek1.year--; startOfWeek1.day = 29; startOfWeek1.month = 12; break;
    case kFriday:        startOfWeek1.day = 4; break;
    case kSaturday:      startOfWeek1.day = 3; break;
    case kSunday:        startOfWeek1.day = 2; break;
  }
  return IntDate2Centi(&startOfWeek1, false);
}

qshort weekNo(struct tm* pCurrentDate)
{
  val_datetime    dateParm, toDate, fromDate;
  double          numericDate, numericStartOfWeek1, numericStartOfNextYear;
  ushort          dayDifference;
  ushort          retWeekNumber = 0;
  
  dateParm.day = pCurrentDate->tm_mday;
  dateParm.month = pCurrentDate->tm_mon+1;
  dateParm.year = pCurrentDate->tm_year + 1900;

  // Determine the date on which week 1 of the year in question starts.
  numericStartOfWeek1 = IntGetStartOfWeek1(dateParm.year);
  // Determine if the date we have been passed is in this year or last year
  dateParm.hour = dateParm.minute = dateParm.second = dateParm.hundred = 0;
  numericDate = IntDate2Centi(&dateParm, false);
  if (numericDate < numericStartOfWeek1)
  {
    // This is the last week of last year.
    // Need to work out when week 1 started last year.
    numericStartOfWeek1 = IntGetStartOfWeek1((short) (dateParm.year - 1));
  }
  else
  {
    // Determine if the date we have been passed is actually in next year
    numericStartOfNextYear = IntGetStartOfWeek1((short) (dateParm.year + 1));
    if (numericDate >= numericStartOfNextYear)
    {
      numericStartOfWeek1 = numericStartOfNextYear;
    }
  }
  // numericStartOfWeek1 now contains the start date for the correct year.
  // Find out the difference in days between the passed date and the start of week 1.
  IntCenti2Date(&toDate, numericDate, false);
  IntCenti2Date(&fromDate, numericStartOfWeek1, false);
  dayDifference = (ushort) IntDateDiff(kDay, &fromDate, &toDate);
  retWeekNumber = (dayDifference / 7) + 1;
  return retWeekNumber;
}


