#ifndef __CALENDAR__
  #define __CALENDAR__
  
  #include "Derivative.h"
  #include "FslTypes.h"
  #include "S08_TOD_Driver.h"
  
  /* Real Time Clock Structure Definition */
  typedef struct
  {
    UINT8 Year;
    UINT8 Month;
    UINT8 Date;
    UINT8 Day;
    UINT8 Hours;
    UINT8 Minutes;
    UINT8 Seconds;
  }RTC_Type;
  
  typedef enum
  {
    _SUNDAY_,
    _MONDAY_,
    _TUESDAY_,
    _WEDNESDAY_,
    _THURSDAY_,
    _FRIDAY_,
    _SATURDAY_
  }Days_Of_The_Week_Enum;
/* 
This algorithm shows how to come up with four numbers. 
Find the sum of these four and using modulus to restrict the 
result to 0 through 6, the day of the week can be determined. 
Since this algorithm uses the "zeroth" day, we can add the day 
of the month directly (without subtracting 1). Examples of the 
evaluation of this algorithm are below. The four numbers are:

Centuries: First, we can either refer to the centuries table 
below or use the rule: Where century is the first two digits 
of the year, define  c = 2(3 - (Century mod 4))

Years: Because there are 365 days in a common year, which is 
52 weeks plus 1 day, each year will start on the day of the 
week after that starting the preceding year. Each leap year 
has of course one more day than a common year. Assuming we 
know on which day a century starts (from above), if we add 
the number of years elapsed since the start of the century, 
plus the number of leap years that have elapsed since the 
start of the century, we get the day of the week on which 
the year starts. Where year is the last two digits of the 
year, define    y = year + [year/4)

Months: We refer to the months table below to work out on which 
day of the week a month starts. Notice that January starts on day 0
, which is simply another way of saying that the year and January 
of that year start on the same day. The months table shown allows 
for leap years; other algorithms leave the correction to the end 
and then deduct 1 from the final figure if the month is a January 
or February of a leap year. 

Day of the Month: Once we know on which day of the week the 
month starts, we simply add the day of the month to find the 
final result (noting that as mentioned above, we've been 
working with the "zeroth" day of the month as the start).   */  

/*     Centuries Table
   1700-1799     4     (Still Julian Calendar in Great Britain and its colonies until 1752)    
   1800-1899     2
   1900-1999     0
   2000-2099     6
   2100-2199     4
   2200-2299     2
   2300-2399     0
   2400-2499     6
   2500-2599     4
   2600-2699     2
*/

/*       Months Table Common
   January      0        (in leap year 6)
   February     3        (in leap year 2)
   March        3
   April        6
   May          1
   June         4
   July         6
   August       2
   September    5
   October      0
   November     3
   December     5
*/
/*       Days Table
   Sunday    0
   Monday    1
   Tuesday   2
   Wednesday 3
   Thursday  4
   Friday    5
   Saturday  6
*/

  #define DAYS_OF_WEEK                   7
  #define MONTHS_PER_YEAR                12
  
  #define RESTART_CALENDAR_COUNTER()     TODC_TODR = 1
  
  #define CALENDAR_MATCH_EVENT           TOD_MATCH_EVENT
  #define CALENDAR_CLEAR_MATCH_EVENT     CLEAR_MATCH_EVENT
  
  #define CALENDAR_SECONDS_EVENT         TOD_SECONDS_EVENT
  #define CALENDAR_CLEAR_SECONDS_EVENT   CLEAR_SECONDS_EVENT
  
  #define DISABLE_CALENDAR_COUNTER()     TODC_TODEN = 0
  
  #define CALENDAR_ENABLE_QSEC_INT()     TODSC_QSECIE = 1
  #define CALENDAR_DISABLE_QSEC_INT()    TODSC_QSECIE = 0
  
  #define CALENDAR_ENABLE_SECONDS_INT()  TODSC_SECIE = 1
  #define CALENDAR_DISABLE_SECONDS_INT() TODSC_SECIE = 0
  
  #define CALENDAR_QSEC_EVENT            TOD_QSECONDS_EVENT
  #define CALENDAR_CLEAR_QSEC_EVENT      CLEAR_QSECONDS_EVENT
  
  #define CALENDAR_MATCH_WAKEUP_IN_5SECS       TOD_MATCH_5_SEC
  #define CALENDAR_MATCH_WAKEUP_IN_10SECS      TOD_MATCH_10_SEC
  #define CALENDAR_MATCH_WAKEUP_IN_15SECS      TOD_MATCH_15_SEC
  #define CALENDAR_MATCH_WAKEUP_IN_30SECS      TOD_MATCH_30_SEC
  #define CALENDAR_MATCH_WAKEUP_IN_60SECS      TOD_MATCH_60_SEC
  
  
  #define CALENDAR_WAKEUP_EVERY_QSEC     TODSC_QSECIE_MASK
  #define CALENDAR_WAKEUP_EVERY_1SEC     TODSC_SECIE_MASK
  #define CALENDAR_WAKEUP_ON_MATCH       (TODSC_MTCHIE_MASK | TODSC_MTCHEN_MASK)
  
  
  #define INIT_CALENDAR_COUNTER(WakeupOptions, WakeupTime)  \
  vfnTOD_Init(_TOD_32_768KHZ_XTAL_, WakeupOptions, WakeupTime)
  //vfnTOD_Init(_TOD_32_768KHZ_XTAL_, (TODSC_SECIE_MASK | TODSC_MTCHIE_MASK | TODSC_MTCHEN_MASK), WakeupTime)
  //vfnTOD_Init(_TOD_32_768KHZ_XTAL_, (TODSC_SECIE_MASK | TODSC_MTCHIE_MASK | TODSC_MTCHEN_MASK), TOD_MATCH_5_SEC);  
    
  
  extern const UINT8 MonthsNames[12][3];
  extern const UINT8 DaysNames[7][2];
  
  //void vfnCalendar_Init(void);
  void vfnCalendar_Init(UINT8 CalendarOptions, UINT8 CalendarWakeupPeriod);
  void vfnCalendar_UpdateDateAndTime(void);
  void vfnCalendar_SetTime (UINT8 Hours, UINT8 Minutes, UINT8 Seconds);
  void vfnCalendar_SetDate (UINT8 Year, UINT8 Month, UINT8 Date, UINT8 Day);
  
  void vfnCalendarUpdateHours(void);
  void vfnCalendarUpdateMinutes(void);
  void vfnCalendarUpdateDay(void);
  void vfnCalendarUpdateDate(void);
  void vfnCalendarUpdateMonth(void);
  void vfnCalendarUpdateYear(void);
  
  extern RTC_Type Calendar_RTC;
  
#endif