#include "stdlib.h"
#include "stdafx.h"
#ifdef PC_SIM
#include "stdio.h"
#endif
#include "string.h"
#include "app.h"
#include "appfunc.h"

#include "new_time.h"
//#define DEBUG
extern WORD Balance;


void ConvertRTMtoTimeStr(RTM *time, BYTE time_str[8])
{	
	SHORT buffer;
	time_str[0] = (BYTE)(time->year-SYSETUP_YEAR_OFFSET);
	time_str[1] = (BYTE)(time->mon+1);
	time_str[2] = (BYTE)time->mday;
	time_str[3] = (BYTE)time->hour;
	time_str[4] = (BYTE)time->min;
	buffer = GetDayOfYear(time->year, time->mon+1, time->mday);
	strcpy(&time_str[5], (char*)&buffer);
}

SHORT GetDayOfYear(SHORT year, SHORT mon, SHORT day)	//not zero-based
{
	SHORT acc_day;
	
	if ((year%4) == 0)
	{
		switch(mon-1)
		{
		case 0:
			acc_day = 0;
			break;
		case 1:
			acc_day = 31;
			break;
		case 2:
			acc_day = 60;
			break;
		case 3:
			acc_day = 91;
			break;
		case 4:
			acc_day = 121;
			break;
		case 5:
			acc_day = 152;
			break;
		case 6:
			acc_day = 182;
			break;
		case 7:
			acc_day = 213;
			break;
		case 8:
			acc_day = 244;
			break;
		case 9:
			acc_day = 274;
			break;
		case 10:
			acc_day = 305;
			break;
		case 11:
			acc_day = 335;
			break;
		case 12:
			acc_day = 366;
			break;
		}
	}
	else
	{
		switch(mon-1)
		{
		case 0:
			acc_day = 0;
			break;
		case 1:
			acc_day = 31;
			break;
		case 2:
			acc_day = 59;
			break;
		case 3:
			acc_day = 90;
			break;
		case 4:
			acc_day = 120;
			break;
		case 5:
			acc_day = 151;
			break;
		case 6:
			acc_day = 181;
			break;
		case 7:
			acc_day = 212;
			break;
		case 8:
			acc_day = 243;
			break;
		case 9:
			acc_day = 273;
			break;
		case 10:
			acc_day = 304;
			break;
		case 11:
			acc_day = 334;
			break;
		case 12:
			acc_day = 365;
			break;
		}
	}
	return (acc_day + (SHORT)day);
}

void GetYearInOffsetFormat(UBYTE str[8], UBYTE *result)
{
	*result = str[0];
}

void GetYear(UBYTE str[8], USHORT *result)
{
	*result = str[0] + SYSETUP_YEAR_OFFSET;
}

void GetMonth(UBYTE str[8], UBYTE *result)
{
	*result = str[1];
}

void GetDate(UBYTE str[8], UBYTE *result)
{
	*result = str[2];
}

void GetHour(BYTE str[8], BYTE *result)
{
	*result = str[3];
}

void GetMinute(BYTE str[8], BYTE *result)
{
	*result = str[4];
}

void GetDayInYear(UBYTE str[8], SHORT *result)
{
	*result = *((SHORT*)(str+5));
}


//TRUE : The check date is in the specified period
//FALSE : The check date is NOT in the specified period
//Note that the precision is just up to DAY
BOOLEAN IsCheckTimeBetweenStartAndEndTime(UBYTE start_time[8], UBYTE end_time[8], UBYTE check_time[8])
{
	UBYTE start_yr, start_month, start_date, start_hr, start_min;
	UBYTE end_yr, end_month, end_date, end_hr, end_min;
	UBYTE check_yr, check_month, check_date, check_hr, check_min;
	BOOLEAN NO_END_TIME = FALSE;
	
	GetYearInOffsetFormat(end_time, &end_yr);
	GetMonth(end_time, &end_month);
	GetDate(end_time, &end_date);
	if ((BYTE)end_yr == -1 && (BYTE)end_month == -1 && (BYTE)end_date == -1) NO_END_TIME = TRUE;
	
	
	GetYearInOffsetFormat(start_time, &start_yr);	
	GetYearInOffsetFormat(check_time, &check_yr);
	
	if (NO_END_TIME)
	{
		if (check_yr > start_yr) return TRUE;
	}
	else
	{
		if ((check_yr > start_yr) && (check_yr < end_yr))
			return TRUE;
	}
	
	if (NO_END_TIME)
	{
		if (check_yr < start_yr) return FALSE;
	}
	else
	{
		if ((check_yr < start_yr) || (check_yr > end_yr))
			return FALSE;
	}
	
	GetMonth(start_time, &start_month);
	GetMonth(check_time, &check_month);
	
	if (NO_END_TIME)
	{
		if (start_yr == check_yr)
		{
			if (check_month > start_month) return TRUE;
			if (check_month < start_month) return FALSE;
		}
		GetDate(start_time, &start_date);
		GetDate(check_time, &check_date);
		if (start_month == check_month)
		{
			if (check_date >= start_date) return TRUE;
			else return FALSE;
		}
	}
	else
	{
		if (start_yr==end_yr && start_yr==check_yr)
		{
			if (check_month>start_month && check_month<end_month)
				return TRUE;
			if ((check_month<start_month) || (check_month>end_month))
				return FALSE;
			GetDate(start_time, &start_date);
			GetDate(check_time, &check_date);
			if (start_month==end_month && start_month==check_month)
			{
				if (check_date>=start_date && check_date<=end_date)
					return TRUE;
				else
					return FALSE;
			}
			if (check_month == end_month)
			{
				if (check_date<=end_date)
					return TRUE;
				else
					return FALSE;
			}
			else
			{
				if (check_date>=start_date)
					return TRUE;
				else
					return FALSE;
			}
		}
		if (check_yr==end_yr)
		{
			if (check_month<end_month)
				return TRUE;
			if (check_month>end_month)
				return FALSE;
			GetDate(end_time, &end_date);
			GetDate(check_time, &check_date);
			if (check_date<=end_date)
				return TRUE;
		}
		else
		{
			if (check_month > start_month)
				return TRUE;
			if (check_month < start_month)
				return FALSE;
			GetDate(start_time, &start_date);
			GetDate(check_time, &check_date);
			if (check_date >= start_date)
				return TRUE;
		}
		return FALSE;
	}
}

BYTE GetEndDateOfViewMonth(PAYMENT_DISPLAY_TIME *view_time)
{
	switch(view_time->month)
	{
	case 1:
		return 31;
		break;
	case 2:
		if ((view_time->yr_offset+SYSETUP_YEAR_OFFSET)%4 == 0)
			return 29;
		else
			return 28;
		break;
	case 3:
		return 31;
		break;
	case 4:
		return 30;
		break;
	case 5:
		return 31;
		break;
	case 6:
		return 30;
		break;
	case 7:
		return 31;
		break;
	case 8:
		return 31;
		break;
	case 9:
		return 30;
		break;
	case 10:
		return 31;
		break;
	case 11:
		return 30;
		break;
	case 12:
		return 31;
		break;
	}
}

//TRUE : The record should be displayed in the view month
//FALSE : The record should NOT be displayed in the view month
BOOLEAN IsCheckTimeWithinMonth(PAYMENT_DISPLAY_TIME *view_month, UBYTE record_date[8])
{
	UBYTE rec_month, rec_yr;
	
	GetMonth(record_date, &rec_month);
	GetYearInOffsetFormat(record_date, &rec_yr);
	if ((view_month->yr_offset == rec_yr) && (view_month->month == rec_month))
		return TRUE;
	else
		return FALSE;
}

void GetWeekdayOfTheDate(UBYTE date_str[8], BYTE *weekday)
{
	UBYTE yr;
	USHORT date;
	SHORT day_of_year;
	
	GetYearInOffsetFormat(date_str, &yr);
	switch(yr)
	{
	case 0:
		date = 5;
		break;
	case -1:
		date = 4;
		break;
	case 1:
		date = 0;
		break;
	case 2:
		date = 1;
		break;    
	case 3:
		date = 2;
		break;
	case 4:
		date = 3;
		break;
	case 5:
		date = 5;
		break;
	case -5:
		date = 6;
		break;
	case -4:
		date = 0;
		break;
	case -3:
		date = 2;
		break;
	case -2:
		date = 3;
		break;
		
	}
	GetDayInYear(date_str, &day_of_year);
	date += day_of_year;
	
	*weekday = date%7;
}



SHORT DifferenceDaysBetween2Dates(SHORT yr1, BYTE month1, BYTE date1, UBYTE time_str[8])
{
	SHORT day_in_yr1, day_in_yr2, yr2;
	SHORT diff_days, diff_yrs, tempSHORT;
	BYTE i, tempBYTE, addition_days=0;
	UBYTE month2, date2;
	
	GetYear(time_str, (USHORT*)&yr2);
	GetMonth(time_str, &month2);
	GetDate(time_str, &date2);
	//the following "if" condition is to make sure that date2 is greater than date1
	if (yr1>yr2)
	{
		tempSHORT = yr1;
		yr1 = yr2;
		yr2 = tempSHORT;
		tempBYTE = month1;
		month1 = month2;
		month2 = tempBYTE;
		tempBYTE = date1;
		date1 = date2;
		date2 = tempBYTE;
	}
	else
	{
		if (yr1==yr2 && month1>month2)
		{
			tempBYTE = month1;
			month1 = month2;
			month2 = tempBYTE;
			tempBYTE = date1;
			date1 = date2;
			date2 = tempBYTE;
		}
		if (yr1==yr2 && month1==month2)
		{
			if (date1>date2)
			{
				tempBYTE = date1;
				date1 = date2;
				date2 = tempBYTE;
			}
		}
	}
	
	
	day_in_yr1 = GetDayOfYear(yr1, month1, date1);
	day_in_yr2 = GetDayOfYear(yr2, month2, date2);
	
	if ((yr1%4) == 0)
		diff_days = 366 - day_in_yr1;
	else
		diff_days = 365 - day_in_yr1;
	diff_days+=day_in_yr2;
	diff_yrs = yr2 - yr1;
	for (i=1 ; i<diff_yrs ; i++)
	{
		if (((yr1+i)%4)==0)
			diff_days++;
	}
	if (diff_yrs==0 && (yr1%4)==0)
		diff_days = diff_days - 366;
	else
		diff_days = diff_days + (diff_yrs-1)*365;
	return diff_days;
}
