/*
 ******************************************************************************
 *              
 *     リアルタイム・クロック処理のヘッダー
 *
 *     $Id: lb_rtc.h,v 1.3 2004/03/02 01:30:26 tong Exp $
 *
 ******************************************************************************
 */
#ifndef __LIB_RTC_H_
#define __LIB_RTC_H_

#include "rtc.h"

//#if defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS)
#ifdef _LANGUAGE_C_PLUS_PLUS
extern "C" {
#endif

extern int  lbRTC_Initial(void);
extern int  lbRTC_IsAbnormal(void);
extern void lbRTC_Sampling(void);
extern void lbRTC_WriteArea(u8 *Buffer);
extern void lbRTC_ReadArea(u8 *Buffer);
    
/* メッセージキューを得るためのマクロ */    
#define lbRTC_LOC_SERIAL_MSGQ()    padmgr_LockSerialMesgQ()
#define lbRTC_UNLOC_SERIAL_MSGQ(p) padmgr_UnlockSerialMesgQ(p)

#define lbRTC_MAX_YEAR   2099
#define lbRTC_MAX_MONTH  12
#define lbRTC_MAX_DAY    31 
#define lbRTC_MAX_HOUR   23
#define lbRTC_MAX_MINUTE 59
#define lbRTC_MAX_SECOND 59

#define lbRTC_MIN_YEAR   1901
#define lbRTC_MIN_MONTH  1 
#define lbRTC_MIN_DAY    1 
#define lbRTC_MIN_HOUR   0 
#define lbRTC_MIN_MINUTE 0 
#define lbRTC_MIN_SECOND 0 

/*
 * OSRTCTimeのデータ構造
 * 
 *   typedef struct{
 *  	u8	sec;	(second 0-59)
 * 	u8	min;	(minute 0-59)
 * 	u8	hour;	(hour   0-23)
 * 	u8	day;	(day    1-31)
 * 	u8	week;	(week   0-6(sun,mon,..,sat))
 *  	u8	month;	(month  1-12)
 * 	u16	year;	(year 1901-2099)
 * } OSRTCTime;
 */    
typedef OSRTCTime        lbRTC_time_c;
typedef u8               lbRTC_ss_t;
typedef u8               lbRTC_mm_t;
typedef u8               lbRTC_hh_t;
typedef u8               lbRTC_DD_t;
typedef u8               lbRTC_WW_t;
typedef u8               lbRTC_MM_t;
typedef u16              lbRTC_YY_t;

/*
 *	年・月・日のみの日付データ
 */
typedef struct	year_month_day_data {
    lbRTC_YY_t	year;
    lbRTC_MM_t  month;
    lbRTC_DD_t  day;
} lbRTC_ymd_c;

/* 曜日 */
enum rtc_week {
    lbRTC_SUN,
    lbRTC_MON,
    lbRTC_TUE,
    lbRTC_WED,
    lbRTC_THU,
    lbRTC_FRI,
    lbRTC_SAT,
    lbRTC_WEEK
};
extern int lbRTC_IsOverWeekRTC(const lbRTC_time_c *StartTime, lbRTC_WW_t AlarmWeek);
#define lbRTC_IS_OVER_SUNDAY(st)   lbRTC_IsOverWeekRTC((st),lbRTC_SUN)
#define lbRTC_IS_OVER_MONDAY(st)   lbRTC_IsOverWeekRTC((st),lbRTC_MON)
#define lbRTC_IS_OVER_TUESDAY(st)  lbRTC_IsOverWeekRTC((st),lbRTC_TUE)
#define lbRTC_IS_OVER_WENSDAY(st)  lbRTC_IsOverWeekRTC((st),lbRTC_WED)
#define lbRTC_IS_OVER_THURSDAY(st) lbRTC_IsOverWeekRTC((st),lbRTC_THU)
#define lbRTC_IS_OVER_FRIDAY(st)   lbRTC_IsOverWeekRTC((st),lbRTC_FRI)
#define lbRTC_IS_OVER_SATURDAY(st) lbRTC_IsOverWeekRTC((st),lbRTC_SAT)

/* 月 */
enum rtc_month {
    lbRTC_JANUARY = 1,             /* １月 */
    lbRTC_FEBRUARY,                /* ２月 */
    lbRTC_MARCH,                   /* ３月 */
    lbRTC_APRIL,                   /* ４月 */
    lbRTC_MAY,                     /* ５月 */
    lbRTC_JUNE,                    /* ６月 */
    lbRTC_JULY,                    /* ７月 */
    lbRTC_AUGUST,                  /* ８月 */
    lbRTC_SEPTEMBER,               /* ９月 */
    lbRTC_OCTOBER,                 /* １０月 */
    lbRTC_NOVEMBER,                /* １１月 */
    lbRTC_DECEMBER,                /* １２月 */
    lbRTC_MONTH_NUM = lbRTC_DECEMBER
};
/* 年 */
enum rtc_yesr {
    lbRTC_NORMAL_YEAR,             /* 通常年 */
    lbRTC_LEAP_YEAR,               /* 閏年 */
    lbRTC_MODE
};
/* 時間と秒 */
enum rtc_hour_and_minute_seccond {
    lbRTC_HOURS = 24,              /* 一日の時間数 */
    lbRTC_MINUTES = 60,            /* １時間の分数 */
    lbRTC_SECCONDS = 60            /* １分の秒数 */
};
extern void lbRTC_SetTime(lbRTC_time_c *Time);
extern void lbRTC_GetTime(lbRTC_time_c *Time);
extern lbRTC_DD_t lbRTC_GetDaysByMonth(lbRTC_YY_t Year, lbRTC_MM_t Month);

extern int lbRTC_GetIntervalDays(const lbRTC_time_c *i_TimeA,
				 const lbRTC_time_c *i_TimeB);

#if 0 /* 2000/7/26 otsuki */
#if DEBUG
/*
 *	ＲＴＣを使う設定の時はＲＴＣから
 *	ＲＴＣを使わない設定の時はZCommonGet(time.rtcTime)から
 */
extern void	lbRTC_SetTime(lbRTC_time_c *);
extern void	lbRTC_GetTime(lbRTC_time_c *);
#else	/* DEBUG */
#define	lbRTC_SetTime	lbRTC_Settime
#define	lbRTC_GetTime	lbRTC_Gettime
#endif	/* DEBUG */
#endif

/* 閏年の判定("lbRTC_IS_LEAP_YEAR() == TRUE" なら閏年) */
#define	lbRTC_IS_LEAP_YEAR(x)	((((x) % 4) == 0) ? TRUE : FALSE)

/* 日付,時間を得る */
#define lbRTC_YEAR_(t)             ((t).year)
#define lbRTC_MONTH_(t)            ((t).month)
#define lbRTC_DAY_(t)              ((t).day)
#define lbRTC_WEEK_(t)             ((t).week)
#define lbRTC_HOUR_(t)             ((t).hour)
#define lbRTC_MIN_(t)              ((t).min)
#define lbRTC_SEC_(t)              ((t).sec)

#define lbRTC_YEARp_(t)            ((t)->year)
#define lbRTC_MONTHp_(t)           ((t)->month)
#define lbRTC_DAYp_(t)             ((t)->day)
#define lbRTC_WEEKp_(t)            ((t)->week)
#define lbRTC_HOURp_(t)            ((t)->hour)
#define lbRTC_MINp_(t)             ((t)->min)
#define lbRTC_SECp_(t)             ((t)->sec)

/* 時間の比較結果 */
enum {
    lbRTC_LESS_TIME = -1,
    lbRTC_OVER_TIME = 1
};
extern int lbRTC_IsOverTime(const lbRTC_time_c *dTime, const lbRTC_time_c *sTime);

/* 時間の判定モード */
enum {
    /* 無効 */
    lbRTC_NULL,                       

    /* '秒'で判定 */
    lbRTC_JUST_ss = 0x01,
    /* '分'で判定 */
    lbRTC_JUST_mm = lbRTC_JUST_ss << 1,
    /* '時'で判定 */
    lbRTC_JUST_hh = lbRTC_JUST_mm << 1,
    /* '曜日'で判定 */
    lbRTC_JUST_WW = lbRTC_JUST_hh << 1,
    /* '日'で判定 */
    lbRTC_JUST_DD = lbRTC_JUST_WW << 1,
    /* '月'で判定 */
    lbRTC_JUST_MM = lbRTC_JUST_DD << 1,
    /* '年'で判定 */
    lbRTC_JUST_YY = lbRTC_JUST_MM << 1,

    /* 全てで判定('年','月','日','曜','時','分','秒') */
    lbRTC_JUST = lbRTC_JUST_ss
                 | lbRTC_JUST_mm
                 | lbRTC_JUST_hh
                 | lbRTC_JUST_WW
                 | lbRTC_JUST_DD
                 | lbRTC_JUST_MM
                 | lbRTC_JUST_YY
};
extern int lbRTC_IsEqualDate(lbRTC_YY_t i_dYear, 
			     lbRTC_MM_t i_dMonth,
			     lbRTC_DD_t i_dDay,
			     lbRTC_YY_t i_sYear, 
			     lbRTC_MM_t i_sMonth,
			     lbRTC_DD_t i_sDay);
extern int lbRTC_IsEqualTime(const lbRTC_time_c *dTime,
			     const lbRTC_time_c *sTime,
			     int          Mode);
extern int lbRTC_IsJustAtRTC(const lbRTC_time_c *Time, int Mode);
extern int lbRTC_IsOverRTC(const lbRTC_time_c *Time);

/* 最大差分時間 */
enum {
    lbRTC_MAX_INTERVAL_TIME_e = -1
};
extern unsigned int lbRTC_IntervalTime(const lbRTC_time_c *a_time,
				       const lbRTC_time_c *b_time);

/* 日付の加減算 */
enum {
    lbRTC_MAX_ADD_DATE_e = 28,
    lbRTC_MAX_SUB_DATE_e = 28
};
extern void lbRTC_Add_YY(lbRTC_time_c *dTime, int Year);
extern void lbRTC_Add_MM(lbRTC_time_c *dTime, int Month);
//extern void lbRTC_Add_DD(lbRTC_time_c *dTime, int Days);
extern int  lbRTC_Add_DD(lbRTC_time_c *dTime, int Days);
extern void lbRTC_Add_hh(lbRTC_time_c *dTime, int Hour);
extern void lbRTC_Add_mm(lbRTC_time_c *dTime, int Minute);
extern void lbRTC_Add_ss(lbRTC_time_c *dTime, int Seccond);
extern void lbRTC_Add_Date(lbRTC_time_c *dTime, const lbRTC_time_c *sTime);

extern void lbRTC_Sub_YY(lbRTC_time_c *dTime, int Year);
extern void lbRTC_Sub_MM(lbRTC_time_c *dTime, int Month);
extern void lbRTC_Sub_DD(lbRTC_time_c *dTime, int Days);
extern void lbRTC_Sub_hh(lbRTC_time_c *dTime, int Hour);
extern void lbRTC_Sub_mm(lbRTC_time_c *dTime, int Minute);
extern void lbRTC_Sub_ss(lbRTC_time_c *dTime, int Seccond);
extern void lbRTC_Sub_Date(lbRTC_time_c *dTime, const lbRTC_time_c *sTime);

extern lbRTC_WW_t lbRTC_Week(lbRTC_YY_t i_Year,
			     lbRTC_MM_t i_Month,
			     lbRTC_DD_t i_Day);

extern void lbRTC_TimeCopy(lbRTC_time_c *dTime, const lbRTC_time_c *sTime);

extern int lbRTC_IsValidTime(const lbRTC_time_c *Time);

#ifdef _LANGUAGE_C_PLUS_PLUS
} /* extern "C" */
#endif
//#endif /* defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS) */
#endif /* __LIB_RTC_H_ */
