//******************************************************************************
//* File		: date.h
//* Project		: VTech OS (Ver 2.0)
//* Company		: VTech Info-Tech Ltd.
//* By			: Kam Ching
//* Revision	: 1.0
//* Description	: Define the universal calender function prototypes
//* ----------------------------------------------------------------------------
//* History:
//* Jan.05,2000	Kam		- Initial design
//******************************************************************************

#ifndef _DATE_H_
#define _DATE_H_

// Include files ---------------------------------------------------------------
#include "datatype.h"
#include "tmrapi.h"

// Configuration defines -------------------------------------------------------
#define	YR_0000			1						// calender valid from 0000 to 3099
#define	YR_1600			2						// calender valid from 1900 to 3099
#define	CLDR			YR_1600					// compile this calender for YR_1600

// Constant	variables ----------------------------------------------------------

#if		CLDR == YR_0000 ////////////////////////////////////////////////////////

#define	DT_YEAR_MIN		0						// min valid year
#define	DT_YEAR_MAX		3099					// max valid year

#elif	CLDR == YR_1600 ////////////////////////////////////////////////////////

#define	DT_YEAR_MIN		1600					// min valid year
#define	DT_YEAR_MAX		3099					// max valid year

#else	////////////////////////////////////////////////////////////////////////

#error	"Configuration flag CLDR is not valid"

#endif	CLDR ///////////////////////////////////////////////////////////////////

/******************************************************************************\
* data structure
\******************************************************************************/
/* use RTM instead
typedef struct _DATETIME
{
	SHORT msec;				// milli-second, range from 0 to 99
	SHORT sec;				// second, range from 0 to 59
	SHORT min;				// minute, range from 0 to 59
	SHORT hour;				// hour, range from 0 to 23
	SHORT mday;				// day of month, range from 1 to 31
	SHORT mon;				// month, range from 0 to 11 (Jan to Dec)
	SHORT year;				// A.D. year, range from 1901 to 2099
	SHORT wday;				// day of week, range from 0 to 6 (Sunday to Saturday)
	SHORT yday;				// day of year, range from 0 to 365
} DATETIME;
*/

/******************************************************************************\
* macro
\******************************************************************************/
// number of day(s) to go to the start of week (include today); i.e. Sunday is 0,
// Monday is 6, Saturaday is 1; assume Sunday is start of week
#define	MOD_WK(st_wday,wday)	((((st_wday)+7) - (wday)) % 7)
// round off a week (i.e. from Thursday onward is not count as one week if start of week is Sunday)
#define	ROUND_WK(st_wday,wday)	((MOD_WK(st_wday,wday) >= 4) ? 1 : 0)
#define	ADD_WD(wday,i)			(((wday) + (i)) % 7)
#define	SUB_WD(wday,i)			(((wday) - (i) + 7) % 7)

/******************************************************************************\
* function prototypes
\******************************************************************************/
SHORT Dt_Date_WDay (SHORT Year, SHORT Month, SHORT Day);	// get wday by date
SHORT Dt_Date_YDay (SHORT Year, SHORT Month, SHORT Day);	// get yday by date
SHORT Dt_YDay_Date (SHORT Year, SHORT YDay, RTM *pDate);// get date by yday

SHORT Dt_Date_MWeek (SHORT Year, SHORT Month, SHORT Day);	// get week of month by date
SHORT Dt_MWeek_Date (SHORT Year, SHORT Month, SHORT MWeek, SHORT WDay, RTM *pDate);
SHORT Dt_Date_MRWeek (SHORT Year, SHORT Month, SHORT Day, SHORT StartWDay, RTM *pDate);
SHORT Dt_MRWeek_Date (SHORT Year, SHORT Month, SHORT MWeek, SHORT WDay, SHORT StartWDay, RTM *pDate);
SHORT Dt_Date_YWeek (SHORT Year, SHORT Month, SHORT Day, SHORT StartWDay, SHORT *pYear);
SHORT Dt_YWeek_Date (SHORT Year, SHORT YWeek, SHORT WDay, SHORT StartWDay, RTM *pDate);
SHORT Dt_Date_M7day (SHORT Year, SHORT Month, SHORT Day);	// get week of month by date
SHORT Dt_M7day_Date (SHORT Year, SHORT Month, SHORT M7day, SHORT WDay, RTM *pDate);
SHORT Dt_Date_Y7day (SHORT Year, SHORT Month, SHORT Day);	// get week of year by date (ISO861)
SHORT Dt_Y7day_Date (SHORT Year, SHORT Y7day, SHORT WDay, RTM *pDate);

SHORT Dt_CmpDate (RTM *pDateS, RTM *pDateT);		// compare source to target date
SHORT Dt_DiffDays (RTM *pDateS, RTM *pDateT);		// days of different source & target date
void Dt_AddDays (RTM *pDateS, SHORT Days, RTM *pDateD);	// add source date & days to destination date
void Dt_AddDate (RTM *pDateS, RTM *pDateT, RTM *pDateD);	// add source & target date to destination date

BOOLEAN Dt_IsLeapYear (SHORT Year);							// Is the year a leap year ?
BOOLEAN Dt_IsValidDate (SHORT Year, SHORT Month, SHORT Day);
SHORT Dt_DaysOfMon (SHORT Year, SHORT Month);

#endif	_DATE_H_
