/*
================================ COPYRIGHT ================================
The contents of this file are subject to the VTech Informations Ltd. License
of VT-OS Ver. 1.1 operating system (the "License"); you may not use this 
file except in compliance with the License.  

Software distributed under the License is distributed on an "AS IS" basis, 
WITHOUT WARRANTY OF ANY KIND, either express or implied.  See the License 
for the specific language governing rights and limitations under the License.
  
The Original Code is VT-OS Ver. 1.1 Operating System, released 
on October 1st, 1999
	
The Initial Developer of the Original Code is VTech Informations Ltd.  All 
codes are Copyright (C) VTech Informations Ltd. 1999.  All Rights Reserved.
===========================================================================
*/

/*
===========================================================================
File        :   SchDisplay.c
Author(s)   :   Michelle Tse
Company     :   VTech Informations Ltd.
Project     :   HelioX
Date	    :   December 17th, 1999
Purpose	    :   application c file
Revision    :   
Note        :   None
===========================================================================
*/

#include "stdafx.h"
#include "app.h"
#include "appfunc.h"

//#define DEBUG
// Michelle add 201299

/********************************************************
* Function:	SchedulerDisplayDayViewRepeat
* Purpose: 	This function is called to display all repeat records to day view
* Scope:	application/internal
* Input:	view_date		A byte pointer to store the view date
*			rec_id			The record ID of a repeat record
* Output:	repeat_str_ptr	The contents of the repeat record
* Return:	TRUE			The repeat record can be shown in day view
*			FALSE			The repeat record cannot be shown in day view
* Comment: 	None
*********************************************************/
BOOLEAN SchedulerDisplayDayViewRepeat(UBYTE *view_date, RecordID rec_id, BYTE** repeat_str_ptr)
{
	RepeatAttr *repeat_attr;
	UWORD byte_read;
	BYTE *buffer, *temp;
	SHORT i, year, month, day, day_in_yr;
	UBYTE start[8], end[8];
	SHORT count = 0;
	
	DataGetField(sch_repeat_dbid, rec_id, F_START_TIME, &buffer, &byte_read);
	i = 6;
	do
	{
		start[i] = buffer[i];
		i--;
	}while(i >= 0);
	qfree(buffer);
	DataGetField(sch_repeat_dbid, rec_id, F_END_TIME, &buffer, &byte_read);
	i = 6;
	do
	{
		end[i] = buffer[i];
		i--;
	}while(i >= 0);
	qfree(buffer);
	start[7] = '\0';
	end[7] = '\0';
	view_date[3] = 0;
	view_date[4] = 0;
	year = (SHORT)(view_date[0] + SYSETUP_YEAR_OFFSET);
	month = (SHORT)view_date[1];
	day = (SHORT)view_date[2];
	day_in_yr = GetDayOfYear(year, month, day);
	
	SchedulerConvertBYTEtoSHORT((view_date+5), day_in_yr);
	view_date[7] = '\0';
	
	if (IsCheckTimeBetweenStartAndEndTime(start, end, view_date) == FALSE) return FALSE;
	DataGetField(sch_repeat_dbid, rec_id, F_REPEAT_ATTR, (BYTE**)&repeat_attr, &byte_read);
	switch(repeat_attr->method)
	{
	case REPEAT_DAILY:
		qfree(repeat_attr);
		if (SchedulerCheckDayViewDailyRepeat(rec_id, view_date, start, end, repeat_str_ptr, DAY))
			return TRUE;
		else return FALSE;
	case REPEAT_WEEKLY:
		qfree(repeat_attr);
		if (SchedulerCheckDayViewWeeklyRepeat(rec_id, view_date, start, end, repeat_str_ptr, DAY))
			return TRUE;
		else return FALSE;
	case REPEAT_MONTHLY_DATE:
		qfree(repeat_attr);
		if (SchedulerCheckDayViewMonthlyDateRepeat(rec_id, view_date, start, end, repeat_str_ptr, DAY))
			return TRUE;
		else return FALSE;
	case REPEAT_MONTHLY_DAY:
		qfree(repeat_attr);
		if (SchedulerCheckDayViewMonthlyDayRepeat(rec_id, view_date, start, end, repeat_str_ptr, DAY))
			return TRUE;
		else return FALSE;
	case REPEAT_YEARLY:
		qfree(repeat_attr);
		if (SchedulerCheckDayViewYearlyRepeat(rec_id, view_date, start, end, repeat_str_ptr, DAY))
			return TRUE;
		else return FALSE;
	}
	return TRUE;
}

/********************************************************
* Function:	SchedulerDisplayMonthViewRepeat
* Purpose: 	This function is called to display all repeat records to month view
* Scope:	application/internal
* Input:	view_year		The year of view date
*			view_month		The month of view date
*			rec_id			The record ID of the repeat record
* Output:	month_repeat	A 32 array to indicate which date has repeat record
* Return:	TRUE			The repeat record can be shown in month view
*			FALSE			The repeat record cannot be shown in month view
* Comment: 	None
*********************************************************/
BOOLEAN SchedulerDisplayMonthViewRepeat(SHORT view_year, SHORT view_month, RecordID rec_id, BYTE *month_repeat)
{
	RepeatAttr *repeat_attr;
	BYTE *buffer;
	UWORD byte_read;
	UBYTE start[8];
	UBYTE end[8];
	UBYTE view_date[8];
	SHORT i, count = 0;
	BYTE method;
	
	//Initialize the month_repeat array
	for(i = 0; i <= 31; i++)
		month_repeat[i] = 0;
	
	//Get start time of repeat record
	DataGetField(sch_repeat_dbid, rec_id, F_START_TIME, &buffer, &byte_read);
	for(i = 0; i < 7; i++)
		start[i] = buffer[i];
	qfree(buffer);
	start[7] = 0;
	
	//Get end time of repeat record
	DataGetField(sch_repeat_dbid, rec_id, F_END_TIME, &buffer, &byte_read);
	for(i = 0; i < 7; i++)
		end[i] = buffer[i];
	qfree(buffer);
	//	if ((end[0] == -1) && (end[1] == -1) && (end[2] == -1)) end[0] = 100;
	end[7] = 0;
	
	//Initialize the view date array
	view_date[0] = (BYTE)(view_year - SYSETUP_YEAR_OFFSET);
	view_date[1] = (BYTE)view_month;
	view_date[2] = start[2];
	view_date[3] = start[3];
	view_date[4] = start[4];
	view_date[7] = 0;
	
	DataGetField(sch_repeat_dbid, rec_id, F_REPEAT_ATTR, (BYTE**)&repeat_attr, &byte_read);
	method = repeat_attr->method;
	qfree(repeat_attr);
	switch(method)
	{
	case REPEAT_DAILY:
		SchedulerCheckMonthViewDailyRepeat(rec_id, start, end, view_date, month_repeat);
		break;
	case REPEAT_WEEKLY:
		SchedulerCheckMonthViewWeeklyRepeat(rec_id, start, end, view_date, month_repeat);
		break;
	case REPEAT_MONTHLY_DATE:
	case REPEAT_MONTHLY_DAY:
		SchedulerCheckMonthViewMonthlyRepeat(rec_id, start, end, view_date, month_repeat, method);
		break;
	case REPEAT_YEARLY:
		SchedulerCheckMonthViewYearlyRepeat(rec_id, start, end, view_date, month_repeat);
		break;
	}
	return TRUE;
}

/********************************************************
* Function:	SchedulerDisplayWeekViewRepeat
* Purpose: 	This function is called to display all repeat records to week view
* Scope:	application/internal
* Input:	view_year	The year of view date
*			view_month	The month of view date
*			view_day	The day of view date
*			rec_id		The record ID of the repeat record
* Output:	start_hr	The start hour of the repeat record
*			end_hr		The end hour of the repeat record
* Return:	TRUE		The repeat record can be shown in week view
*			FALSE		The repeat record cannot be shown in week view
* Comment: 	None
*********************************************************/
BOOLEAN SchedulerDisplayWeekViewRepeat(SHORT view_year, SHORT view_month, SHORT view_day, RecordID rec_id, BYTE *start_hr, BYTE *end_hr)
{
	RepeatAttr *repeat_attr;
	BYTE *buffer;
	UWORD byte_read;
	UBYTE start[8];
	UBYTE end[8];
	UBYTE view_date[8];
	SHORT i, count = 0;
	SHORT mon, mday;
	BYTE method;
	
	//Get start time of repeat record
	DataGetField(sch_repeat_dbid, rec_id, F_START_TIME, &buffer, &byte_read);
	for(i = 0; i < 7; i++)
		start[i] = buffer[i];
	qfree(buffer);
	start[7] = 0;
	
	//Get end time of repeat record
	DataGetField(sch_repeat_dbid, rec_id, F_END_TIME, &buffer, &byte_read);
	for(i = 0; i < 7; i++)
		end[i] = buffer[i];
	qfree(buffer);
	//	if ((end[0] == -1) && (end[1] == -1) && (end[2] == -1)) end[0] = 100;
	end[7] = 0;
	
	//Initialize the view date array
	view_date[0] = (BYTE)(view_year - SYSETUP_YEAR_OFFSET);
	view_date[1] = (BYTE)(view_month + 1);
	view_date[2] = (BYTE)view_day;
	view_date[7] = 0;
	
	if (!IsCheckTimeBetweenStartAndEndTime(start, end, view_date)) return FALSE;
	DataGetField(sch_repeat_dbid, rec_id, F_REPEAT_ATTR, (BYTE**)&repeat_attr, &byte_read);
	method = repeat_attr->method;
	qfree(repeat_attr);
	switch(method)
	{
	case REPEAT_DAILY:
		if (SchedulerCheckDayViewDailyRepeat(rec_id, view_date, start, end, NULL, WEEK))
		{
			*start_hr = start[3];
			*end_hr = end[3];
			return TRUE;
		}
		else return FALSE;
	case REPEAT_WEEKLY:
		if (SchedulerCheckDayViewWeeklyRepeat(rec_id, view_date, start, end, NULL, WEEK))
		{
			*start_hr = start[3];
			*end_hr = end[3];
			return TRUE;
		}
		else return FALSE;
	case REPEAT_MONTHLY_DATE:
		if (SchedulerCheckDayViewMonthlyDateRepeat(rec_id, view_date, start, end, NULL, WEEK))
		{
			*start_hr = start[3];
			*end_hr = end[3];
			return TRUE;
		}
		else return FALSE;
	case REPEAT_MONTHLY_DAY:
		if (SchedulerCheckDayViewMonthlyDayRepeat(rec_id, view_date, start, end, NULL, WEEK))
		{
			*start_hr = start[3];
			*end_hr = end[3];
			return TRUE;
		}
		else return FALSE;
	case REPEAT_YEARLY:
		if (SchedulerCheckDayViewYearlyRepeat(rec_id, view_date, start, end, NULL, WEEK))
		{
			*start_hr = start[3];
			*end_hr = end[3];
			return TRUE;
		}
		else return FALSE;
	}
	return TRUE;
}

/********************************************************
* Function:	SchedulerCheckMonthViewDailyRepeat
* Purpose: 	This function is called to check whether the daily repeat record
*			can be shown in month view
* Scope:	application/internal
* Input:	rec_id			The record ID of the repeat record
*			start			The start date string of the repeat record
*			end				The end date string of the repeat record
*			view_date		The date string of view date
* Output:	month_repeat	A 32 array to indicate which date has repeat record
* Return:	None
* Comment: 	None
*********************************************************/
void SchedulerCheckMonthViewDailyRepeat(RecordID rec_id, UBYTE *start, UBYTE *end, UBYTE *view_date, BYTE *month_repeat)
{
	SHORT day_in_month, day_in_yr, i;
	SHORT year, month;
	BOOLEAN display = FALSE;
	RepeatAttr *repeat_attr;
	UWORD byte_read, repeat_no;
	BYTE *buffer, exception;
	
	year = (SHORT)(view_date[0] + SYSETUP_YEAR_OFFSET);
	month = (SHORT)view_date[1];
	day_in_month = Dt_DaysOfMon(year, month - 1);
	for(i = 1; i <= day_in_month; i++)
	{
		view_date[2] = (BYTE)i;
		day_in_yr = GetDayOfYear(year, month, i);		
		SchedulerConvertBYTEtoSHORT((view_date + 5), day_in_yr);
		if (IsCheckTimeBetweenStartAndEndTime(start, end, view_date))
		{
			if (SchedulerCheckDayViewDailyRepeat(rec_id, view_date, start, end, NULL, MONTH))
			{
				display = TRUE;
				month_repeat[i] = 1;
				break;
			}
		}
	}
	if (display == TRUE)
	{
		//Michelle add 250100
		DataGetField(sch_repeat_dbid, rec_id, F_EXCEPT_FLAG, &buffer, &byte_read);
		exception = *buffer;
		qfree(buffer);
		DataGetField(sch_repeat_dbid, rec_id, F_REPEAT_NUM, &buffer, &byte_read);
		repeat_no = *((UWORD*)buffer);
		qfree(buffer);
		//end add 250100
		DataGetField(sch_repeat_dbid, rec_id, F_REPEAT_ATTR, (BYTE**)&repeat_attr, &byte_read);
		if ((BYTE)end[1] == (BYTE)view_date[1])
			day_in_month = (SHORT)end[2];
		do
		{			
			i = i + repeat_attr->every_info;
			if (i > day_in_month) break;
			//Michelle add 250100
			if (exception == 1)
			{
				view_date[2] = i;
				if (SchedulerCheckExceptionDB(repeat_no, view_date)) continue;
			}
			//end add 250100
			month_repeat[i] = 1;
		}while(i < day_in_month);
		qfree(repeat_attr);
	}
	return;
}

/********************************************************
* Function:	SchedulerCheckMonthViewWeeklyRepeat
* Purpose: 	This function is called to check whether the weekly repeat record
*			can be shown in month view
* Scope:	application/internal
* Input:	rec_id			The record ID of the repeat record
*			start			The start date string of the repeat record
*			end				The end date string of the repeat record
*			view_date		The date string of view date
* Output:	month_repeat	A 32 array to indicate which date has repeat record
* Return:	None
* Comment: 	None
*********************************************************/
void SchedulerCheckMonthViewWeeklyRepeat(RecordID rec_id, UBYTE *start, UBYTE *end, UBYTE *view_date, BYTE *month_repeat)
{
	SHORT day_in_month, day_in_yr, i, wday, nth_week, j, count, k;
	SHORT year, month;
	BOOLEAN display = FALSE;
	RepeatAttr *repeat_attr;
	UWORD byte_read, repeat_no;
	BYTE weekday_no[7] = {0, 1, 2, 3, 4, 5, 6};
	BYTE temp[7] = {-1, -1, -1, -1, -1, -1, -1};
	BYTE remainder[7], data = 64, every_data;
	UWORD repeat_days;
	CountrySettings country;
	BYTE *buffer, exception, sun_bit = 128;
	
	SySetupGetCountrySettings(&country);
	year = (SHORT)(view_date[0] + SYSETUP_YEAR_OFFSET);
	month = (SHORT)view_date[1];
	day_in_month = Dt_DaysOfMon(year, month - 1);
	
	for(i = 1; i <= day_in_month; i++)
	{
		view_date[2] = (BYTE)i;
		day_in_yr = GetDayOfYear(year, month, i);
		SchedulerConvertBYTEtoSHORT((view_date + 5), day_in_yr);
		
		if (IsCheckTimeBetweenStartAndEndTime(start, end, view_date))
		{
			if (SchedulerCheckDayViewWeeklyRepeat(rec_id, view_date, start, end, NULL, MONTH))
			{
				display = TRUE;
				month_repeat[i] = 1;
				break;
			}
		}
	}
	
	//first repeat date = i
	if (display == TRUE)
	{
		DataGetField(sch_repeat_dbid, rec_id, F_EXCEPT_FLAG, &buffer, &byte_read);
		exception = *buffer;
		qfree(buffer);
		DataGetField(sch_repeat_dbid, rec_id, F_REPEAT_NUM, &buffer, &byte_read);
		repeat_no = *((UWORD*)buffer);
		qfree(buffer);
		DataGetField(sch_repeat_dbid, rec_id, F_REPEAT_ATTR,(BYTE**)&repeat_attr, &byte_read);
		repeat_days = 7 * repeat_attr->every_info;
		every_data = repeat_attr->every_data;
		qfree(repeat_attr);
		count = 0;
		j = 0;
		
		while(data >= 1)
		{
			if ((every_data & data) == data)
			{
				remainder[count] = weekday_no[j];
				count++;
			}
			data = data / 2;
			j++;
		}
		
		//Michelle new add 260100
		if ((every_data & sun_bit) == sun_bit)
		{
			if (country.start_of_week == SYSETUP_MON)
			{
				for(j = 0; j < count; j++)
				{
					if (remainder[j] == 0) remainder[j] = 6;
					else remainder[j]--;
				}
			}
		}
		//Restore the remainder list if start of week == sunday
		else
		{
			if (country.start_of_week == SYSETUP_SUN)
			{
				for(j = 0; j < count; j++)
				{
					if (remainder[j] == 6) remainder[j] = 0;
					else remainder[j]++;
				}
			}
		}
		//end add 260100
		//kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk
		//		RtcYMDToWday1(year, (month - 1), i, &wday, &nth_week);
		wday = Dt_Date_WDay(year, month - 1, i);
		//kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk
		if (country.start_of_week == SYSETUP_MON)
		{
			if (wday == 0) wday = 6;
			else wday--;
		}
		for(j = 0; j < count; j++)
			remainder[j] = remainder[j] - wday;
		for(j = 0; j < count; j++)
			if (remainder[j] < 0) remainder[j] = remainder[j] + repeat_days;
			
			//Find out the end date
			if ((BYTE)end[1] == (BYTE)view_date[1])
				day_in_month = (SHORT)end[2];
			
			do
			{
				for(j = 0; j < count; j++)
				{
					//			if (remainder[j] == 0) continue;
					if (i + remainder[j] > day_in_month) continue;
					//Michelle add 250100
					if (exception == 1)
					{
						view_date[2] = i + remainder[j];
						if (SchedulerCheckExceptionDB(repeat_no, view_date)) continue;
					}
					//end add 250100
					month_repeat[i + remainder[j]] = 1;
				}
				i = i + repeat_days;
				if (i > day_in_month) continue;
				else
				{
					if (exception == 1)
					{
						view_date[2] = i;
						if (SchedulerCheckExceptionDB(repeat_no, view_date)) continue;
					}
					month_repeat[i] = 1;
				}
			}while(i <= day_in_month);
	}
	return;
}

/********************************************************
* Function:	SchedulerCheckMonthViewMonthlyRepeat
* Purpose: 	This function is called to check whether the monthly repeat record
*			can be shown in month view
* Scope:	application/internal
* Input:	rec_id			The record ID of the repeat record
*			start			The start date string of the repeat record
*			end				The end date string of the repeat record
*			view_date		The date string of view date
* Output:	month_repeat	A 32 array to indicate which date has repeat record
* Return:	None
* Comment: 	None
*********************************************************/
void SchedulerCheckMonthViewMonthlyRepeat(RecordID rec_id, UBYTE *start, UBYTE *end, UBYTE *view_date, BYTE *month_repeat, BYTE method)
{
	RepeatAttr *repeat_attr;
	UWORD byte_read;
	SHORT year, month, day, wday, n_week, mday;
	RTM pDate;
	
	if (!IsCheckTimeBetweenStartAndEndTime(start, end, view_date)) return;
	else
	{
		if (method == REPEAT_MONTHLY_DATE)
		{
			if (SchedulerCheckDayViewMonthlyDateRepeat(rec_id, view_date, start, end, NULL, MONTH))
				month_repeat[view_date[2]] = 1;
		}
		else if (method == REPEAT_MONTHLY_DAY)
		{
			DataGetField(sch_repeat_dbid, rec_id, F_REPEAT_ATTR, (BYTE**)&repeat_attr, &byte_read);
			if (repeat_attr->every_data & 128)
				wday = (SHORT)repeat_attr->every_data + 128;
			else
				wday = (SHORT)repeat_attr->every_data;
			n_week = (SHORT)repeat_attr->n_week;
			qfree(repeat_attr);
			year = (SHORT)(view_date[0] + SYSETUP_YEAR_OFFSET);
			month = (SHORT)view_date[1];
			//kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk
			if (n_week == 5)
			{
				if (Dt_M7day_Date(year, month - 1, -1, wday, &pDate) == TRUE)
					mday = pDate.mday;
			}
			else
			{
				if (Dt_M7day_Date(year, month - 1, n_week, wday, &pDate) == TRUE)
					mday = pDate.mday;
			}
			/*
			RtcWday2ToYMD(year, (month - 1), wday, n_week, &mday);
			if (mday == -1)
			{
			n_week--;
			RtcWday2ToYMD(year, (month - 1), wday, n_week, &mday);
		}*/
			//kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk
			view_date[2] = (BYTE)mday;
			if (SchedulerCheckDayViewMonthlyDayRepeat(rec_id, view_date, start, end, NULL, MONTH))
				month_repeat[view_date[2]] = 1;
		}
	}
	return;
}

/********************************************************
* Function:	SchedulerCheckMonthViewYearlyRepeat
* Purpose: 	This function is called to check whether the yearly repeat record
*			can be shown in month view
* Scope:	application/internal
* Input:	rec_id			The record ID of the repeat record
*			start			The start date string of the repeat record
*			end				The end date string of the repeat record
*			view_date		The date string of view date
* Output:	month_repeat	A 32 array to indicate which date has repeat record
* Return:	None
* Comment: 	None
*********************************************************/
void SchedulerCheckMonthViewYearlyRepeat(RecordID rec_id, UBYTE *start, UBYTE *end, UBYTE *view_date, BYTE *month_repeat)
{
	if (!IsCheckTimeBetweenStartAndEndTime(start, end, view_date)) return;
	else
	{
		if (SchedulerCheckDayViewYearlyRepeat(rec_id, view_date, start, end, NULL, MONTH))
			month_repeat[view_date[2]] = 1;	
	}
	return;
}


/********************************************************
* Function:	SchedulerCheckDayViewDailyRepeat
* Purpose: 	This function is called to check whether the daily repeat record
*			can be shown in day view
* Scope:	application/internal
* Input:	rec_id			The record ID of the repeat record
*			view_date		The date string of view date
*			start			The start date string of the repeat record
*			end				The end date string of the repeat record
*			view_status		Indicate the view mode
* Output:	repeat_str_ptr	A byte pointer to store the content of the repeat record
* Return:	TRUE			The repeat record is inside view date
*			FALSE			The repeat record is not inside view date
* Comment: 	None
*********************************************************/
BOOLEAN SchedulerCheckDayViewDailyRepeat(RecordID rec_id, UBYTE *view_date, UBYTE *start, UBYTE *end, BYTE **repeat_str_ptr, BYTE view_status)
{
	BYTE *buffer, *temp;
	BYTE repeat_days;
	UWORD byte_read, repeat_no;
	SHORT i, diff_days, year, month, day, day_in_yr;
	SHORT view_day_in_year, start_day_in_year, result, exception_flag;
	SHORT count = 0;
	RepeatAttr *repeat_attr;
	USHORT num_length;
	SHORT status;
	AlarmAttr *alarm_attr;
	
	DataGetField(sch_repeat_dbid, rec_id, F_REPEAT_NUM, &buffer, &byte_read);
	repeat_no = *((UWORD*)buffer);
	qfree(buffer);
	DataGetField(sch_repeat_dbid, rec_id, F_REPEAT_ATTR, (BYTE**)&repeat_attr, &byte_read);
	repeat_days = repeat_attr->every_info;
	qfree(repeat_attr);
	// Check whether the daily repeat record repeats for every day
	if (repeat_days == 1)
	{
		DataGetField(sch_repeat_dbid, rec_id, F_EXCEPT_FLAG, &buffer, &byte_read);
		exception_flag = *buffer;
		qfree(buffer);
		// Check whether exception is present for this daily repeat record
		// If exception is present.....
		if (exception_flag == 1)
		{
			// If the view date does not fall to exception dates
			if (SchedulerCheckExceptionDB(repeat_no, view_date) == FALSE)
			{
				if (view_status == DAY)
				{
					SchedulerRestoreRepeatSettings(&status, repeat_no);
					DataGetField(sch_repeat_dbid, rec_id, F_CONTENTS, &buffer, &byte_read);
					num_length = strlen(buffer) + 1;
					*repeat_str_ptr = (BYTE *)qmalloc(num_length * sizeof(BYTE));
					strcpy(*repeat_str_ptr, buffer);
					qfree(buffer);
					DataGetField(sch_repeat_dbid, rec_id, F_ALARM_SETTINGS, (BYTE**)&alarm_attr, &byte_read);
					repeat_settings.alarm = alarm_attr->type;
					repeat_settings.alarm_time = alarm_attr->time;
					repeat_settings.alarm_num = alarm_attr->num;
					qfree(alarm_attr);
				}
				return TRUE;
			}
			// If the view date is an exception date
			else return FALSE;
		}
		// If no exception presents......
		else
		{
			if (view_status == DAY)
			{
				SchedulerRestoreRepeatSettings(&status, repeat_no);
				DataGetField(sch_repeat_dbid, rec_id, F_CONTENTS, &buffer, &byte_read);
				num_length = strlen(buffer) + 1;
				*repeat_str_ptr = (BYTE *)qmalloc(num_length * sizeof(BYTE));
				strcpy(*repeat_str_ptr, buffer);
				qfree(buffer);
				DataGetField(sch_repeat_dbid, rec_id, F_ALARM_SETTINGS, (BYTE**)&alarm_attr, &byte_read);
				repeat_settings.alarm = alarm_attr->type;
				repeat_settings.alarm_time = alarm_attr->time;
				repeat_settings.alarm_num = alarm_attr->num;
				qfree(alarm_attr);
			}
			return TRUE;
		}
	}
	// When the daily repeat record does not repeat for every day
	// To calculate the difference days between view date & start date
	// And use remainder to check whether the daily repeat record shows in the view date
	else
	{
		year = (SHORT)(view_date[0] + SYSETUP_YEAR_OFFSET);
		month = (SHORT)(view_date[1]);
		day = (SHORT)(view_date[2]);
		diff_days = DifferenceDaysBetween2Dates(year, month, day, start);
		result = diff_days % repeat_days;
		if (result != 0) return FALSE;
		else
		{
			DataGetField(sch_repeat_dbid, rec_id, F_EXCEPT_FLAG, &buffer, &byte_read);
			exception_flag = *buffer;
			qfree(buffer);
			if (exception_flag == 1)
			{
				if (SchedulerCheckExceptionDB(repeat_no, view_date) == FALSE)
				{
					if (view_status == DAY)
					{
						SchedulerRestoreRepeatSettings(&status, repeat_no);
						DataGetField(sch_repeat_dbid, rec_id, F_CONTENTS, &buffer, &byte_read);
						num_length = strlen(buffer) + 1;
						*repeat_str_ptr = (BYTE *)qmalloc(num_length * sizeof(BYTE));
						strcpy(*repeat_str_ptr, buffer);
						qfree(buffer);
						DataGetField(sch_repeat_dbid, rec_id, F_ALARM_SETTINGS, (BYTE**)&alarm_attr, &byte_read);
						repeat_settings.alarm = alarm_attr->type;
						repeat_settings.alarm_time = alarm_attr->time;
						repeat_settings.alarm_num = alarm_attr->num;
						qfree(alarm_attr);
					}
					return TRUE;
				}
				else return FALSE;
			}
			else
			{
				if (view_status == DAY)
				{
					SchedulerRestoreRepeatSettings(&status, repeat_no);
					DataGetField(sch_repeat_dbid, rec_id, F_CONTENTS, &buffer, &byte_read);
					num_length = strlen(buffer) + 1;
					*repeat_str_ptr = (BYTE *)qmalloc(num_length * sizeof(BYTE));
					strcpy(*repeat_str_ptr, buffer);
					qfree(buffer);
					DataGetField(sch_repeat_dbid, rec_id, F_ALARM_SETTINGS, (BYTE**)&alarm_attr, &byte_read);
					repeat_settings.alarm = alarm_attr->type;
					repeat_settings.alarm_time = alarm_attr->time;
					repeat_settings.alarm_num = alarm_attr->num;
					qfree(alarm_attr);
				}
				return TRUE;
			}
		}
		return TRUE;
	}
}

/********************************************************
* Function:	SchedulerCheckDayViewWeeklyRepeat
* Purpose: 	This function is called to check whether the weekly repeat record
*			can be shown in day view
* Scope:	application/internal
* Input:	rec_id			The record ID of the repeat record
*			view_date		The date string of view date
*			start			The start date string of the repeat record
*			end				The end date string of the repeat record
*			view_status		Indicate the view mode
* Output:	repeat_str_ptr	A byte pointer to store the content of the repeat record
* Return:	TRUE			The repeat record is inside view date
*			FALSE			The repeat record is not inside view date
* Comment: 	None
*********************************************************/
BOOLEAN SchedulerCheckDayViewWeeklyRepeat(RecordID rec_id, UBYTE *view_date, UBYTE *start, UBYTE *end, BYTE **repeat_str_ptr, BYTE view_status)
{
	BYTE weekday_no[7] = {0, 1, 2, 3, 4, 5, 6};
	BYTE remainder_list[7];
	CountrySettings country;
	// weekday definition: TRUE if start of week = MON; FALSE if start of week = SUN;
	BOOLEAN /*weekday = FALSE,*/ found = FALSE;
	SHORT i, year, mon, day, wday, nth_week;
	SHORT remainder, status, exception_flag, count=0;
	BYTE data = 64, every_data, sun_bit = 128;
	RepeatAttr *repeat_attr;
	UWORD repeat_no, byte_read;
	BYTE *buffer;
	UBYTE date[4];
	USHORT num_length;
	AlarmAttr *alarm_attr;
	UWORD repeat_days, diff_days;
	
	SySetupGetCountrySettings(&country);
	DataGetField(sch_repeat_dbid, rec_id, F_REPEAT_NUM, &buffer, &byte_read);
	repeat_no = *((UWORD*)buffer);
	qfree(buffer);
	DataGetField(sch_repeat_dbid, rec_id, F_REPEAT_ATTR, (BYTE**)&repeat_attr, &byte_read);
	repeat_days = repeat_attr->every_info * 7;
	every_data = repeat_attr->every_data;
	qfree(repeat_attr);
	// To find out the remainder list array that stores the weekday numbers for the repeat pattern
	i = 0;
	while(data >= 1)
	{
		if ((every_data & data) == data)
		{
			remainder_list[count] = weekday_no[i];
			count++;
		}
		data = data / 2;
		i++;
	}
	//Michelle add 260100
	//Restore the remainder list if start of week == monday
	if ((every_data & sun_bit) == sun_bit)
	{
		if (country.start_of_week == SYSETUP_MON)
		{
			for(i = 0; i < count; i++)
			{
				if (remainder_list[i] == 0) remainder_list[i] = 6;
				else remainder_list[i]--;
			}
		}
	}
	//Restore the remainder list if start of week == sunday
	else
	{
		if (country.start_of_week == SYSETUP_SUN)
		{
			for(i = 0; i < count; i++)
			{
				if (remainder_list[i] == 6) remainder_list[i] = 0;
				else remainder_list[i]++;
			}
		}
	}
	//end add 260100
	// To find out the weekday number of the start date
	year = (SHORT)(start[0] + SYSETUP_YEAR_OFFSET);
	mon = (SHORT)(start[1]);
	day = (SHORT)(start[2]);
	//kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk
	//RtcYMDToWday1(year, mon - 1, day, &wday, &nth_week);
	wday = Dt_Date_WDay(year, mon - 1, day);
	//kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk
	if (country.start_of_week == SYSETUP_MON)
	{
		if (wday == 0) wday = 6;
		else wday--;
	}
	for (i = 0; i < count; i++)
		remainder_list[i] = remainder_list[i] - (BYTE)wday;
	
	// To assure all the values inside remainder list array to be positive
	for (i = 0; i <  count; i++)
		if (remainder_list[i] < 0) remainder_list[i] = remainder_list[i] + repeat_days;
		
		// To calculate the number of days between the view date & the start date
		// And also find out the remainder of the difference days & repeat days
		year = (SHORT)(view_date[0] + SYSETUP_YEAR_OFFSET);
		mon = (SHORT)(view_date[1]);
		day = (SHORT)(view_date[2]);
		diff_days = DifferenceDaysBetween2Dates(year, mon, day, start);
		remainder = diff_days % repeat_days;
		// To check whether the previously calculated remainder equals to one of values in
		// remainder list array
		for (i = 0; i < count; i++)
		{
			if (remainder == remainder_list[i])
			{
				found = TRUE;
				break;
			}
			else found = FALSE;
		}
		// If equals......
		if (found)
		{
			DataGetField(sch_repeat_dbid, rec_id, F_EXCEPT_FLAG, &buffer, &byte_read);
			exception_flag = *buffer;
			qfree(buffer);
			// If exception is present.......
			if (exception_flag == 1)
			{
				// If the view date does not equal to one of exception date....
				if (SchedulerCheckExceptionDB(repeat_no, view_date) == FALSE)
				{
					if (view_status == DAY)
					{
						SchedulerRestoreRepeatSettings(&status, repeat_no);
						DataGetField(sch_repeat_dbid, rec_id, F_CONTENTS, &buffer, &byte_read);
						num_length = strlen(buffer) + 1;
						*repeat_str_ptr = (BYTE *)qmalloc(num_length * sizeof(BYTE));
						strcpy(*repeat_str_ptr, buffer);
						qfree(buffer);
						DataGetField(sch_repeat_dbid, rec_id, F_ALARM_SETTINGS, (BYTE**)&alarm_attr, &byte_read);
						repeat_settings.alarm = alarm_attr->type;
						repeat_settings.alarm_time = alarm_attr->time;
						repeat_settings.alarm_num = alarm_attr->num;
						qfree(alarm_attr);
					}
					return TRUE;
				}
				// If the view date equals to one of exception dates.....
				else return FALSE;
			}
			// If exception is not present..............
			else
			{
				if (view_status == DAY)
				{
					SchedulerRestoreRepeatSettings(&status, repeat_no);
					DataGetField(sch_repeat_dbid, rec_id, F_CONTENTS, &buffer, &byte_read);
					num_length = strlen(buffer) + 1;
					*repeat_str_ptr = (BYTE *)qmalloc(num_length * sizeof(BYTE));
					strcpy(*repeat_str_ptr, buffer);
					qfree(buffer);
					DataGetField(sch_repeat_dbid, rec_id, F_ALARM_SETTINGS, (BYTE**)&alarm_attr, &byte_read);
					repeat_settings.alarm = alarm_attr->type;
					repeat_settings.alarm_time = alarm_attr->time;
					repeat_settings.alarm_num = alarm_attr->num;
					qfree(alarm_attr);
				}
				return TRUE;
			}
		}
		// If not equal .................
		else return FALSE;
}

/********************************************************
* Function:	SchedulerCheckDayViewMonthlyDateRepeat
* Purpose: 	This function is called to check whether the date monthly
*			repeat record can be shown in day view
* Scope:	application/internal
* Input:	rec_id			The record ID of the repeat record
*			view_date		The date string of view date
*			start			The start date string of the repeat record
*			end				The end date string of the repeat record
*			view_status		Indicate the view mode
* Output:	repeat_str_ptr	A byte pointer to store the content of the repeat record
* Return:	TRUE			The repeat record is inside view date
*			FALSE			The repeat record is not inside view date
* Comment: 	None
*********************************************************/
BOOLEAN SchedulerCheckDayViewMonthlyDateRepeat(RecordID rec_id, UBYTE *view_date, UBYTE *start, UBYTE *end, BYTE **repeat_str_ptr, BYTE view_status)
{
	UWORD repeat_no, byte_read;
	BYTE *buffer;
	UBYTE date[4];
	BYTE repeat_months;
	RepeatAttr *repeat_attr;
	SHORT i, diff_days, year, mon, day, wday, nth_week, days_in_month;
	SHORT diff_months, diff_years, remainder, mday, exception_flag, count = 0;
	USHORT num_length;
	SHORT status;
	AlarmAttr *alarm_attr;
	
	DataGetField(sch_repeat_dbid, rec_id, F_REPEAT_NUM, &buffer, &byte_read);
	repeat_no = *((UWORD*)buffer);
	qfree(buffer);
	// Compare the view date between start date
	if (view_date[2] == start[2])
		diff_days = 0;
	else diff_days = 1;
	
	DataGetField(sch_repeat_dbid, rec_id, F_REPEAT_ATTR, (BYTE**)&repeat_attr, &byte_read);
	repeat_months = repeat_attr->every_info;
	qfree(repeat_attr);
	// If monthly date repeat record repeats for every month ......
	if (repeat_months == 1)
	{
		//If view date == start date ........
		if (!diff_days)
		{
			DataGetField(sch_repeat_dbid, rec_id, F_EXCEPT_FLAG, &buffer, &byte_read);
			exception_flag = *buffer;
			qfree(buffer);
			// If exception presents ........
			if (exception_flag == 1)
			{
				// If the view date does not equal to one of exception date....
				if (SchedulerCheckExceptionDB(repeat_no, view_date) == FALSE)
				{
					if (view_status == DAY)
					{
						SchedulerRestoreRepeatSettings(&status, repeat_no);
						DataGetField(sch_repeat_dbid, rec_id, F_CONTENTS, &buffer, &byte_read);
						num_length = strlen(buffer) + 1;
						*repeat_str_ptr = (BYTE *)qmalloc(num_length * sizeof(BYTE));
						strcpy(*repeat_str_ptr, buffer);
						qfree(buffer);
						DataGetField(sch_repeat_dbid, rec_id, F_ALARM_SETTINGS, (BYTE**)&alarm_attr, &byte_read);
						repeat_settings.alarm = alarm_attr->type;
						repeat_settings.alarm_time = alarm_attr->time;
						repeat_settings.alarm_num = alarm_attr->num;
						qfree(alarm_attr);
					}
					return TRUE;
				}
				// If the view date equals to one of exception dates.....
				else return FALSE;
			}
			// If exception is not present..............
			else
			{
				if (view_status == DAY)
				{
					SchedulerRestoreRepeatSettings(&status, repeat_no);
					DataGetField(sch_repeat_dbid, rec_id, F_CONTENTS, &buffer, &byte_read);
					num_length = strlen(buffer) + 1;
					*repeat_str_ptr = (BYTE *)qmalloc(num_length * sizeof(BYTE));
					strcpy(*repeat_str_ptr, buffer);
					qfree(buffer);
					DataGetField(sch_repeat_dbid, rec_id, F_ALARM_SETTINGS, (BYTE**)&alarm_attr, &byte_read);
					repeat_settings.alarm = alarm_attr->type;
					repeat_settings.alarm_time = alarm_attr->time;
					repeat_settings.alarm_num = alarm_attr->num;
					qfree(alarm_attr);
				}
				return TRUE;
			}
		}
		// If view date does not equal to start date .......
		else return FALSE;
	}
	// If monthly date repeat does not repeat for every month ......
	else
	{
		if (!diff_days)
		{
			diff_years = (SHORT)((SHORT)(view_date[0] + SYSETUP_YEAR_OFFSET) - (SHORT)(start[0] + SYSETUP_YEAR_OFFSET));
			if (diff_years == 0)
				diff_months = (SHORT)(view_date[1] - start[1]);
			else
			{
				if (diff_years > 0)
					diff_months = ((SHORT)(view_date[1]) + diff_years * 12) - (SHORT)(start[1]);
				else diff_months = -1;
			}
			if (diff_months != -1)
				remainder = diff_months % repeat_months;
			// If the repeat record shows in view date ........
			if (remainder == 0)
			{
				DataGetField(sch_repeat_dbid, rec_id, F_EXCEPT_FLAG, &buffer, &byte_read);
				exception_flag = *buffer;
				qfree(buffer);
				// If exception presents ........
				if (exception_flag == 1)
				{
					// If the view date does not equal to one of exception date....
					if (SchedulerCheckExceptionDB(repeat_no, view_date) == FALSE)
					{
						if (view_status == DAY)
						{
							SchedulerRestoreRepeatSettings(&status, repeat_no);
							DataGetField(sch_repeat_dbid, rec_id, F_CONTENTS, &buffer, &byte_read);
							num_length = strlen(buffer) + 1;
							*repeat_str_ptr = (BYTE *)qmalloc(num_length * sizeof(BYTE));
							strcpy(*repeat_str_ptr, buffer);
							qfree(buffer);
							DataGetField(sch_repeat_dbid, rec_id, F_ALARM_SETTINGS, (BYTE**)&alarm_attr, &byte_read);
							repeat_settings.alarm = alarm_attr->type;
							repeat_settings.alarm_time = alarm_attr->time;
							repeat_settings.alarm_num = alarm_attr->num;
							qfree(alarm_attr);
						}
						return TRUE;
					}
					// If the view date equals to one of exception dates.....
					else return FALSE;
				}
				// If exception is not present..............
				else
				{
					if (view_status == DAY)
					{
						SchedulerRestoreRepeatSettings(&status, repeat_no);
						DataGetField(sch_repeat_dbid, rec_id, F_CONTENTS, &buffer, &byte_read);
						num_length = strlen(buffer) + 1;
						*repeat_str_ptr = (BYTE *)qmalloc(num_length * sizeof(BYTE));
						strcpy(*repeat_str_ptr, buffer);
						qfree(buffer);
						DataGetField(sch_repeat_dbid, rec_id, F_ALARM_SETTINGS, (BYTE**)&alarm_attr, &byte_read);
						repeat_settings.alarm = alarm_attr->type;
						repeat_settings.alarm_time = alarm_attr->time;
						repeat_settings.alarm_num = alarm_attr->num;
						qfree(alarm_attr);
					}
					return TRUE;
				}
			}
			else return FALSE;
		}
		// if the view date does not show repeat record ......
		else return FALSE;
	}
}

/********************************************************
* Function:	SchedulerCheckDayViewMonthlyDayRepeat
* Purpose: 	This function is called to check whether the day monthly
*			repeat record can be shown in day view
* Scope:	application/internal
* Input:	rec_id			The record ID of the repeat record
*			view_date		The date string of view date
*			start			The start date string of the repeat record
*			end				The end date string of the repeat record
*			view_status		Indicate the view mode
* Output:	repeat_str_ptr	A byte pointer to store the content of the repeat record
* Return:	TRUE			The repeat record is inside view date
*			FALSE			The repeat record is not inside view date
* Comment: 	None
*********************************************************/
BOOLEAN SchedulerCheckDayViewMonthlyDayRepeat(RecordID rec_id, UBYTE *view_date, UBYTE *start, UBYTE *end, BYTE **repeat_str_ptr, BYTE view_status)
{
	UWORD repeat_no, byte_read;
	BYTE *buffer;
	UBYTE date[4];
	BYTE repeat_months;
	RepeatAttr *repeat_attr;
	SHORT i, diff_day, year, mon, day, wday, nth_week, days_in_month;
	SHORT diff_months, diff_years, remainder, mday, exception_flag, count = 0;
	USHORT num_length;
	SHORT status;
	AlarmAttr *alarm_attr;
	RTM pDate;
	
	DataGetField(sch_repeat_dbid, rec_id, F_REPEAT_NUM, &buffer, &byte_read);
	repeat_no = *((UWORD*)buffer);
	qfree(buffer);
	DataGetField(sch_repeat_dbid, rec_id, F_REPEAT_ATTR, (BYTE**)&repeat_attr, &byte_read);
	repeat_months = repeat_attr->every_info;
	year = (SHORT)(view_date[0] + SYSETUP_YEAR_OFFSET);
	mon = (SHORT)view_date[1];
	
#ifdef DEBUG_MICH
	printf("\nSchedulerCheckDayViewMonthlyDayRepeat()");
#endif
	
	if (repeat_attr->every_data & 128)
		wday = repeat_attr->every_data + 128;
	else
		wday = repeat_attr->every_data;
	
	nth_week = repeat_attr->n_week;
	qfree(repeat_attr);
	//kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk
	if (nth_week == 5)
	{
		if (Dt_M7day_Date(year, mon - 1, -1, wday, &pDate) == TRUE)
			mday = pDate.mday;
	}
	else
	{
		if (Dt_M7day_Date(year, mon - 1, nth_week, wday, &pDate) == TRUE)
			mday = pDate.mday;
	}
	/*
	RtcWday2ToYMD(year, mon-1, wday, nth_week, &mday);
	if (mday == -1)
	{
	nth_week--;
	RtcWday2ToYMD(year, mon-1, wday, nth_week, &mday);
}*/
	//kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk
	diff_day = (SHORT)(view_date[2]) - mday;
	// If monthly day repeat record repeats for every month ......
	if (repeat_months == 1)
	{
		if (diff_day == 0)
		{
			DataGetField(sch_repeat_dbid, rec_id, F_EXCEPT_FLAG, &buffer, &byte_read);
			exception_flag = *buffer;
			qfree(buffer);
			// If exception presents ........
			if (exception_flag == 1)
			{
				// If the view date does not equal to one of exception date....
				if (SchedulerCheckExceptionDB(repeat_no, view_date) == FALSE)
				{
					if (view_status == DAY)
					{
						SchedulerRestoreRepeatSettings(&status, repeat_no);
						DataGetField(sch_repeat_dbid, rec_id, F_CONTENTS, &buffer, &byte_read);
						num_length = strlen(buffer) + 1;
						*repeat_str_ptr = (BYTE *)qmalloc(num_length * sizeof(BYTE));
						strcpy(*repeat_str_ptr, buffer);
						qfree(buffer);
						DataGetField(sch_repeat_dbid, rec_id, F_ALARM_SETTINGS, (BYTE**)&alarm_attr, &byte_read);
						repeat_settings.alarm = alarm_attr->type;
						repeat_settings.alarm_time = alarm_attr->time;
						repeat_settings.alarm_num = alarm_attr->num;
						qfree(alarm_attr);
					}
					return TRUE;
				}
				// If the view date equals to one of exception dates.....
				else return FALSE;
			}
			// If exception is not present..............
			else
			{
				if (view_status == DAY)
				{
					SchedulerRestoreRepeatSettings(&status, repeat_no);
					DataGetField(sch_repeat_dbid, rec_id, F_CONTENTS, &buffer, &byte_read);
					num_length = strlen(buffer) + 1;
					*repeat_str_ptr = (BYTE *)qmalloc(num_length * sizeof(BYTE));
					strcpy(*repeat_str_ptr, buffer);
					qfree(buffer);
					DataGetField(sch_repeat_dbid, rec_id, F_ALARM_SETTINGS, (BYTE**)&alarm_attr, &byte_read);
					repeat_settings.alarm = alarm_attr->type;
					repeat_settings.alarm_time = alarm_attr->time;
					repeat_settings.alarm_num = alarm_attr->num;
					qfree(alarm_attr);
				}
				return TRUE;
			}
		}
		// If view date does not equal to start date .......
		else return FALSE;
	}
	// If monthly day repeat record does not repeat for every month ......
	else
	{
		diff_years = (SHORT)((SHORT)(view_date[0] + SYSETUP_YEAR_OFFSET) - (SHORT)(start[0] + SYSETUP_YEAR_OFFSET));
		if (diff_years == 0)
			diff_months = (SHORT)(view_date[1] - start[1]);
		else
		{
			if (diff_years > 0)
				diff_months = ((SHORT)(view_date[1]) + diff_years * 12) - (SHORT)(start[1]);
			else diff_months = -1;
		}
		if (diff_months != -1)
		{
			if (diff_months == 0)
			{
				if (diff_day == 0)
					remainder = 0;
				else remainder = -1;
			}
			else remainder = diff_months % repeat_months;
		}
		if ((remainder == 0) && (diff_day == 0))
		{
			DataGetField(sch_repeat_dbid, rec_id, F_EXCEPT_FLAG, &buffer, &byte_read);
			exception_flag = *buffer;
			qfree(buffer);
			// If exception presents ........
			if (exception_flag == 1)
			{
				// If the view date does not equal to one of exception date....
				if (SchedulerCheckExceptionDB(repeat_no, view_date) == FALSE)
				{
					if (view_status == DAY)
					{
						SchedulerRestoreRepeatSettings(&status, repeat_no);
						DataGetField(sch_repeat_dbid, rec_id, F_CONTENTS, &buffer, &byte_read);
						num_length = strlen(buffer) + 1;
						*repeat_str_ptr = (BYTE *)qmalloc(num_length * sizeof(BYTE));
						strcpy(*repeat_str_ptr, buffer);
						qfree(buffer);
						DataGetField(sch_repeat_dbid, rec_id, F_ALARM_SETTINGS, (BYTE**)&alarm_attr, &byte_read);
						repeat_settings.alarm = alarm_attr->type;
						repeat_settings.alarm_time = alarm_attr->time;
						repeat_settings.alarm_num = alarm_attr->num;
						qfree(alarm_attr);
					}
					return TRUE;
				}
				// If the view date equals to one of exception dates.....
				else return FALSE;
			}
			// If exception is not present..............
			else
			{
				if (view_status == DAY)
				{
					SchedulerRestoreRepeatSettings(&status, repeat_no);
					DataGetField(sch_repeat_dbid, rec_id, F_CONTENTS, &buffer, &byte_read);
					num_length = strlen(buffer) + 1;
					*repeat_str_ptr = (BYTE *)qmalloc(num_length * sizeof(BYTE));
					strcpy(*repeat_str_ptr, buffer);
					qfree(buffer);
					DataGetField(sch_repeat_dbid, rec_id, F_ALARM_SETTINGS, (BYTE**)&alarm_attr, &byte_read);
					repeat_settings.alarm = alarm_attr->type;
					repeat_settings.alarm_time = alarm_attr->time;
					repeat_settings.alarm_num = alarm_attr->num;
					qfree(alarm_attr);
				}
				return TRUE;
			}
		}
		// if the view date does not show repeat record ......
		else return FALSE;
	}
}

/********************************************************
* Function:	SchedulerCheckDayViewYearlyDateRepeat
* Purpose: 	This function is called to check whether the yearly
*			repeat record can be shown in day view
* Scope:	application/internal
* Input:	rec_id			The record ID of the repeat record
*			view_date		The date string of view date
*			start			The start date string of the repeat record
*			end				The end date string of the repeat record
*			view_status		Indicate the view mode
* Output:	repeat_str_ptr	A byte pointer to store the content of the repeat record
* Return:	TRUE			The repeat record is inside view date
*			FALSE			The repeat record is not inside view date
* Comment: 	None
*********************************************************/
BOOLEAN SchedulerCheckDayViewYearlyRepeat(RecordID rec_id, UBYTE *view_date, UBYTE *start, UBYTE *end, BYTE **repeat_str_ptr, BYTE view_status)
{
	RepeatAttr *repeat_attr;
	UWORD byte_read, repeat_no;
	BYTE *buffer;
	SHORT diff_day, diff_month, diff_year, status, remainder, exception_flag;
	USHORT num_length;
	BYTE every_info;
	AlarmAttr *alarm_attr;
	
	DataGetField(sch_repeat_dbid, rec_id, F_REPEAT_NUM, &buffer, &byte_read);
	repeat_no = *((UWORD*)buffer);
	qfree(buffer);
	DataGetField(sch_repeat_dbid, rec_id, F_REPEAT_ATTR, (BYTE**)&repeat_attr, &byte_read);
	every_info = repeat_attr->every_info;
	qfree(repeat_attr);
	// Repeat for every year
	if (every_info == 1)
	{
		if ((view_date[1] == start[1]) && (view_date[2] == start[2]))
		{
			DataGetField(sch_repeat_dbid, rec_id, F_EXCEPT_FLAG, &buffer, &byte_read);
			exception_flag = *buffer;
			qfree(buffer);
			// If repeat record has exception database...
			if (exception_flag == 1)
			{
				// If the view date does not equal to one of exception date....
				if (!SchedulerCheckExceptionDB(repeat_no, view_date))
				{
					if (view_status == DAY)
					{
						SchedulerRestoreRepeatSettings(&status, repeat_no);
						DataGetField(sch_repeat_dbid, rec_id, F_CONTENTS, &buffer, &byte_read);
						num_length = strlen(buffer) + 1;
						*repeat_str_ptr = (BYTE *)qmalloc(num_length * sizeof(BYTE));
						strcpy(*repeat_str_ptr, buffer);
						qfree(buffer);
						DataGetField(sch_repeat_dbid, rec_id, F_ALARM_SETTINGS, (BYTE**)&alarm_attr, &byte_read);
						repeat_settings.alarm = alarm_attr->type;
						repeat_settings.alarm_time = alarm_attr->time;
						repeat_settings.alarm_num = alarm_attr->num;
						qfree(alarm_attr);
					}
					return TRUE;
				}
				// If the view date equals to one of exception dates.....
				else return FALSE;
			}
			// If repeat record does not have exception database...
			else
			{
				if (view_status == DAY)
				{
					SchedulerRestoreRepeatSettings(&status, repeat_no);
					DataGetField(sch_repeat_dbid, rec_id, F_CONTENTS, &buffer, &byte_read);
					num_length = strlen(buffer) + 1;
					*repeat_str_ptr = (BYTE *)qmalloc(num_length * sizeof(BYTE));
					strcpy(*repeat_str_ptr, buffer);
					qfree(buffer);
					DataGetField(sch_repeat_dbid, rec_id, F_ALARM_SETTINGS, (BYTE**)&alarm_attr, &byte_read);
					repeat_settings.alarm = alarm_attr->type;
					repeat_settings.alarm_time = alarm_attr->time;
					repeat_settings.alarm_num = alarm_attr->num;
					qfree(alarm_attr);
				}
				return TRUE;
			}
		}
		else return FALSE;
	}
	// not repeat for every year
	else
	{
		diff_year = (SHORT)(view_date[0] + SYSETUP_YEAR_OFFSET) - (SHORT)(start[0] + SYSETUP_YEAR_OFFSET);
		if (diff_year == 0)
		{
			diff_month = (SHORT)view_date[1] - (SHORT)start[1];
			diff_day = (SHORT)view_date[2] - (SHORT)start[2];
			if ((diff_month == 0) && (diff_day == 0))
				remainder = 0;
			else remainder = 1;
		}
		else
		{
			remainder = diff_year % every_info;
			if (remainder == 0)
			{
				diff_month = (SHORT)view_date[1] - (SHORT)start[1];
				diff_day = (SHORT)view_date[2] - (SHORT)start[2];
				if ((diff_month == 0) && (diff_day == 0))
					remainder = 0;
				else remainder = 1;
			}
		}
		if (remainder == 0)
		{
			DataGetField(sch_repeat_dbid, rec_id, F_EXCEPT_FLAG, &buffer, &byte_read);
			exception_flag = *buffer;
			qfree(buffer);
			// If repeat record has exception database...
			if (exception_flag == 1)
			{
				// If the view date does not equal to one of exception date....
				if (!SchedulerCheckExceptionDB(repeat_no, view_date))
				{
					if (view_status == DAY)
					{
						SchedulerRestoreRepeatSettings(&status, repeat_no);
						DataGetField(sch_repeat_dbid, rec_id, F_CONTENTS, &buffer, &byte_read);
						num_length = strlen(buffer) + 1;
						*repeat_str_ptr = (BYTE *)qmalloc(num_length * sizeof(BYTE));
						strcpy(*repeat_str_ptr, buffer);
						qfree(buffer);
						DataGetField(sch_repeat_dbid, rec_id, F_ALARM_SETTINGS, (BYTE**)&alarm_attr, &byte_read);
						repeat_settings.alarm = alarm_attr->type;
						repeat_settings.alarm_time = alarm_attr->time;
						repeat_settings.alarm_num = alarm_attr->num;
						qfree(alarm_attr);
					}
					return TRUE;
				}
				// If the view date equals to one of exception dates.....
				else return FALSE;
			}
			// If repeat record does not have exception database...
			else
			{
				if (view_status == DAY)
				{
					SchedulerRestoreRepeatSettings(&status, repeat_no);
					DataGetField(sch_repeat_dbid, rec_id, F_CONTENTS, &buffer, &byte_read);
					num_length = strlen(buffer) + 1;
					*repeat_str_ptr = (BYTE *)qmalloc(num_length * sizeof(BYTE));
					strcpy(*repeat_str_ptr, buffer);
					qfree(buffer);
					DataGetField(sch_repeat_dbid, rec_id, F_ALARM_SETTINGS, (BYTE**)&alarm_attr, &byte_read);
					repeat_settings.alarm = alarm_attr->type;
					repeat_settings.alarm_time = alarm_attr->time;
					repeat_settings.alarm_num = alarm_attr->num;
					qfree(alarm_attr);
				}
				return TRUE;
			}
		}
		else return FALSE;
	}
}

/********************************************************
* Function:	SchedulerCheckExceptionDB
* Purpose: 	This function is called to check whether the
*			repeat record is an exception in view date
* Scope:	application/internal
* Input:	repeat_no	The repeat number of the repeat record
*			view_date	The date string of view date
* Output:	None
* Return:	TRUE		view date is an exception
*			FALSE		view date is not an exception
* Comment: 	None
*********************************************************/
BOOLEAN SchedulerCheckExceptionDB(UWORD repeat_no, UBYTE *view_date)
{
	BYTE repeat_num[5];
	UWORD rec_num;
	RecordID rec_id;
	BYTE *buffer;
	UWORD byte_read;
	UBYTE date[4];
	SHORT num_of_date, i , index;
	
	*(UWORD*)repeat_num = repeat_no;
	repeat_num[4] = 0;
	if (DataFindBinRecord(sch_except_dbid, F_REPEAT_NUM, 0, repeat_num, 4, &rec_id) != TRUE)
		return FALSE;
	else
	{
		DataRecIDtoNum(sch_except_dbid, rec_id, &rec_num);
		DataOpenRecord(sch_except_dbid, rec_num, &rec_id, NULL);
		DataGetField(sch_except_dbid, rec_id, F_EXCEPT_DATE, &buffer, &byte_read);
		num_of_date = byte_read / 3;
		index = 0;
		for(i = 0; i <= num_of_date; i++)
		{		
			if ((view_date[0] == buffer[index]) && (view_date[1] == buffer[index + 1])
				&& (view_date[2] == buffer[index + 2])) 
			{
				DataCloseRecord(sch_except_dbid, rec_id);
				return TRUE;
			}
			index +=3;
		}
		DataCloseRecord(sch_except_dbid, rec_id);
		return FALSE;
	}
}

/********************************************************
* Function:	SchedulerCalculatePopupDate
* Purpose: 	This function is called to find out the start date of 
*			weekly repeat record
* Scope:	application/internal
* Input:	view_date	The date string of view date
*			wday		The weekday of the view date
* Output:	None
* Return:	TRUE		if need to set popup date
*			FALSE		if don't need to set popup date
* Comment: 	None
*********************************************************/
BOOLEAN SchedulerCalculatePopupDate(UBYTE *view_date, SHORT wday)
{
	BYTE weekday_no[7] = {0, 1, 2, 3, 4, 5, 6};
	BYTE repeat_weekday_no[7] = {-1, -1, -1, -1, -1, -1, -1};
	SHORT i, j, count = 0, offset;
	BYTE data = 64, every_data, every_info, day_in_month, temp;
	BOOLEAN found = FALSE;
	SHORT year, month, day, weekday, n_week, found_no;
	CountrySettings country_settings;
	
	SySetupGetCountrySettings(&country_settings);
	if (country_settings.start_of_week == SYSETUP_MON)
	{
		weekday_no[6] = 0;
		for (i = 0; i < 6; i++)
			weekday_no[i] = i+1;
	}
	every_data = repeat_settings.every_data;
	every_info = repeat_settings.every_info;
	i = 0;
	while(data >= 1)
	{
		if ((every_data & data) == data)
		{
			repeat_weekday_no[count] = weekday_no[i];
			count++;
		}
		data = data / 2;
		i++;
	}
	//Check the view date
	for(i = 0; i < count; i++)
	{
		if (wday == repeat_weekday_no[i])
			found = TRUE;
	}
	if (found) return FALSE;
	
#ifdef DEBUG
	printf("\n============== Calculate popup date point 1 ================");
	printf("\nfound = %ld", found);
#endif
	
	found_no = -1;
	//Search the one which is slightly greater than wday
	for(i = 0; i < count; i++)
	{
		if (repeat_weekday_no[i] > wday)
		{
			found_no = i;
			break;
		}
	}
	
	month = (SHORT)view_date[1];
	year = (SHORT)(view_date[0] + SYSETUP_YEAR_OFFSET);
	day_in_month = Dt_DaysOfMon(year, month - 1);
	
	//Case 1: The one which is slightly greater than wday can be found
	if (found_no != -1)
	{
		offset = repeat_weekday_no[found_no] - wday;
		day = (SHORT)(view_date[2] + offset);
		if (day > day_in_month)
		{
			day -= day_in_month;
			month++;
		}
		if (month > 12)
		{
			month -= 12;
			year++;
		}
		//kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk
		//		RtcYMDToWday1(year, (month - 1), day, &weekday, &n_week);
		weekday = Dt_Date_WDay(year, month - 1, day);
		//kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk
		//Michelle
		//	SchedulerSetDayViewDate(year, month, day, weekday);
		//Michelle
	}
	else
	{
		offset = (SHORT)((repeat_weekday_no[0] - wday) + (7 * every_info));
		day = (SHORT)(view_date[2] + offset);
		if (day > (SHORT)day_in_month)
		{
			month++;
			day -= day_in_month;
		}
		if (month > 12)
		{
			year++;
			month -= 12;
		}
		//kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk
		//		RtcYMDToWday1(year, (month - 1), day, &weekday, &n_week);
		weekday = Dt_Date_WDay(year, month - 1, day);
		//kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk
		//Michelle
		//	SchedulerSetDayViewDate(year, month, day, weekday);
		//Michelle
	}
	//Michelle
#ifdef DEBUG
	printf("\n============== Calculate popup date point 2 ================");
	printf("\ndate = %ld, %ld, %ld", year, month, day);
	printf("\nwday = %ld", weekday);
#endif
	if (country_settings.start_of_week == SYSETUP_MON)
		weekday--;
	SchedulerSetDayViewDate(year, month, day, weekday);
	//Michelle
	return TRUE;
}

/********************************************************
* Function:	SchedulerRepeatCheckPushbutton
* Purpose: 	This function is called to check whether all the
*			push buttons used in weekly repeat are not set
* Scope:	application/internal
* Input:	object_id	The object id of the push button
* Output:	None
* Return:	None
* Comment: 	None
*********************************************************/
BOOLEAN SchedulerRepeatCheckPushbutton(ObjectID object_id)
{
	ObjectID start, end;
	SHORT count = 0;
	BYTE type;
	Control *addr;
	CountrySettings country;
	
	SySetupGetCountrySettings(&country);
	start = PUSHBUTTON_SCH_REPEAT_SUN;
	end = PUSHBUTTON_SCH_REPEAT_SAT + 1;
	
	while(start != end)
	{
		if (start != object_id)
		{
			FormGetObjectPointer(start, &type, (void**)&addr);
			if (((ControlTemplatePushButton*)(((Control*)addr)->control_template))->control_value)
				count++;
		}
		start++;
	}
	
	if (count > 0) return TRUE;
	else
	{
		FormGetObjectPointer(object_id, &type, (void**)&addr);
		((ControlTemplatePushButton*)(addr->control_template))->control_value = TRUE;
		ControlDrawControl(object_id);
		return FALSE;
	}
}

/********************************************************
* Function:	SchedulerCheckLastWday
* Purpose: 	This function is called to check whether the view
*			date is in the last week
* Scope:	application/internal
* Input:	None
* Output:	None
* Return:	TRUE		popup another form to ask before saving
*			FALSE		nothing do
* Comment: 	None
*********************************************************/
BOOLEAN SchedulerCheckLastWday()
{
	UBYTE date[4];
	SHORT year, month, day, mday, wday, n_week;
	SHORT days_in_month, temp_day;
	
	SchedulerGetDayViewDate(date);
	year = (SHORT)(date[0] + SYSETUP_YEAR_OFFSET);
	month = (SHORT)date[1];
	day = (SHORT)date[2];
	//kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk
	//	RtcYMDToWday2(year, (month - 1), day, &wday, &n_week);
	wday = Dt_Date_WDay(year, month - 1, day);
	n_week = Dt_Date_M7day(year, month - 1, day);
	//kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk
#ifdef DEBUG
	printf("\n &&&&& SAVE MONTHLY DAY REPEAT: Point 1 &&&&&&");
	printf("\n date = %ld, %ld, %ld", year, month, day);
	printf("\n the weekday = %ld", wday);
	printf("\n the week no = %ld", n_week);
#endif
	if (n_week == 4)
	{	
		temp_day = day + 7;
		days_in_month = Dt_DaysOfMon(year, month - 1);
		if (temp_day >= days_in_month)
		{
			FormInitAllFormObjects(FORM_CHOOSE_MONTHLY_DAY_REPEAT);
#ifdef DEBUG
			printf("\n &&&&& SAVE MONTHLY DAY REPEAT: Point 3 &&&&&&");
#endif
			repeat_settings.every_data = wday;
			FormPopupForm(FORM_CHOOSE_MONTHLY_DAY_REPEAT);
			return TRUE;
		}
	}
	repeat_settings.n_week = n_week;
	repeat_settings.every_data = wday;
#ifdef DEBUG
	printf("\n &&&&& SAVE MONTHLY DAY REPEAT: Point 3 &&&&&&");
	printf("\n the weekday = %ld", wday);
	printf("\n the week no = %ld", n_week);
#endif
	return FALSE;
}
