/*
================================ 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        :   aplaunch.c
Author(s)   :   Henry Fok
Company     :   VTech Informations Ltd.
Project     :   Helio 
Date:	    :   October 1st, 1999
Purpose:	:   application c file
Revision    :   1.1
Note        :   None
===========================================================================
*/              

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

//#define DEBUG_MICH
/********************************************************
* Function:	SchedulerAppLaunch
* Purpose: 	This function is called to launch the 
Scheduler application
* Scope:		application/internal
* Input:		None
* Output:		None
* Return:		TRUE if handled
FALSE if not handled
* Comment: 	None
*********************************************************/
BOOLEAN SchedulerAppLaunch(WORD cmd, void *cmd_ptr)
{
	
	UWORD		num_rec, count, byte_read, rec_num;
	RecordID	rec_id, rec_id_1, rec_id_2, *repeat_recid;
	BYTE		*buffer, *prepare_string, **string, *buffer1, *buffer2;
	UBYTE		date1[4], date2[4];
	WORD		num_appmt = 0, appmt_num = 0;
	UWORD           total_rec;
	BYTE		output, result;
	BOOLEAN		start_deleted, end_deleted;
	USHORT		start_row, end_row;
	ObjectID        active_form_id;
	SHORT		i = 0, j, total;
	AppointmentDB	*appmt_rec = NULL;
	BOOLEAN		found = TRUE;
	
	SchedulerDatabaseChecking();
	
	if (cmd == LAUNCH_CMD_GOTO_REC && DataRecordInfo(((GotoRec*)cmd_ptr)->dbid, ((GotoRec*)cmd_ptr)->rec_id, NULL, NULL, NULL, NULL, NULL) != TRUE)
	{
		if (((GotoRec*)cmd_ptr)->find_string != NULL)
			pfree(((GotoRec*)cmd_ptr)->find_string);
		pfree(cmd_ptr); 
		cmd = LAUNCH_CMD_NORMAL_LAUNCH;
	}
	
	switch(cmd)
	{
	case LAUNCH_CMD_TODAY_SCH:
	case LAUNCH_CMD_NORMAL_LAUNCH:
		virtual_table.vt_num_rows = 0;
		UIApplicationInit();
		
		if (cmd == LAUNCH_CMD_TODAY_SCH)
			SchedulerAppRestore(FALSE, TRUE, cmd_ptr);
		else			
			SchedulerAppRestore(FALSE, FALSE, cmd_ptr);
		EventLoop();
		
		/* =========================================================================================== */
		FormGetActiveFormID(&active_form_id);
		if (active_form_id == FORM_SCH_DAY_VIEW && virtual_table.vt_active_row != -1)
		{
			output = SchedulerDayViewNormal(&virtual_table, TABLE_SCH_DAY_VIEW, &start_row,
				&end_row, &start_deleted, &end_deleted);
			if (virtual_table.vt_active_row != -1 && new_appointment == TRUE)
			{
				new_appointment = FALSE;
				virtual_table.vt_items[virtual_table.vt_active_row]->appointment = -1;
			}
			virtual_table.vt_active_row = -1;
			SchedulerTimeSettingsDeleteAllEmptyAppmts(&virtual_table);
			SchedulerTimeSettingsAddAppmts(&virtual_table);
		}
		
		/* =========================================================================================== */		
		//  Michelle modified at 211299
		//  The application save function must be rewritten to fit the
		//	new structure
		SchedulerAppSave();
		UIDeleteAllAppObjects();
		DataCloseDB(sch_repeat_dbid);
		DataCloseDB(sch_except_dbid);
		DataCloseDB(sch_appmt_dbid);
		DataCloseDB(sch_voice_dbid);
		return TRUE;
	case LAUNCH_CMD_FIND:
		app_id = SysGetActiveAppID();
		DataTotalRecord(sch_repeat_dbid, &num_rec);
		repeat_recid = (RecordID*)qmalloc(num_rec * sizeof(RecordID));
		for(count = 0; count < num_rec; count++)
		{
			DataOpenRecord(sch_repeat_dbid, count, &rec_id, NULL);
			DataGetField(sch_repeat_dbid, rec_id, F_CONTENTS, &buffer, &byte_read);
			if (GlobalFindSearchText((BYTE*)cmd_ptr, buffer) >= 0)
			{
				repeat_recid[i] = rec_id;
				i++;
			}
			qfree(buffer);
			DataCloseRecord(sch_repeat_dbid, rec_id);
		}
		total = i;
		for(count = 0; count < total; count++)
		{
			if (repeat_recid[count] == -1) continue;
			DataRecIDtoNum(sch_repeat_dbid, repeat_recid[count], &rec_num);
			DataOpenRecord(sch_repeat_dbid, rec_num, &rec_id_1, NULL);
			DataGetField(sch_repeat_dbid, rec_id_1, F_CONTENTS, &buffer1, &byte_read);
			for(j = count; j < total; j++)
			{
				if (j == count) continue;
				DataRecIDtoNum(sch_repeat_dbid, repeat_recid[j], &rec_num);
				DataOpenRecord(sch_repeat_dbid, rec_num, &rec_id_2, NULL);
				DataGetField(sch_repeat_dbid, rec_id_2, F_CONTENTS, &buffer2, &byte_read);
				if (strcmp(buffer1, buffer2) != 0)
				{
					qfree(buffer1);
					qfree(buffer2);
					continue;
				}
				qfree(buffer1);
				qfree(buffer2);
				DataGetField(sch_repeat_dbid, rec_id_1, F_START_TIME, &buffer1, &byte_read);
				DataGetField(sch_repeat_dbid, rec_id_2, F_START_TIME, &buffer2, &byte_read);
				result = SchedulerCompareDate((UBYTE*)buffer1, (UBYTE*)buffer2);
				//if date1 == date2
				if (result == 1)
				{
					//if hour of date1 > hour of date2
					if (buffer1[3] > buffer2[3])
					{
						qfree(buffer1);
						qfree(buffer2);
						repeat_recid[count] = -1;
						continue;
					}
					//if hour of date1 < hour of date2
					else if (buffer1[3] < buffer2[3])
					{
						qfree(buffer1);
						qfree(buffer2);
						repeat_recid[j] = -1;
						continue;
					}
					// if hour of date1 == hour of date2
					else
					{
						//if minute of date1 > minute of date2
						if (buffer1[4] > buffer2[4])
						{
							qfree(buffer1);
							qfree(buffer2);
							repeat_recid[count] = -1;
							continue;
						}
						//if minute of date1 < minute of date2
						else if (buffer1[4] < buffer2[4])
						{
							qfree(buffer1);
							qfree(buffer2);
							repeat_recid[j] = -1;
							continue;
						}
						//if date1 totally = date2
						else
						{
							qfree(buffer1);
							qfree(buffer2);
							repeat_recid[j] = -1;
							continue;
						}
					}
				}
				DataCloseRecord(sch_appmt_dbid, rec_id_1);
				DataCloseRecord(sch_repeat_dbid, rec_id_2);
			}
		}
		DataTotalRecord(sch_appmt_dbid, &num_rec);
		for (count = 0; count < num_rec; count++)
		{
			DataOpenRecord(sch_appmt_dbid, count, &rec_id, NULL);
			DataGetField(sch_appmt_dbid, rec_id, 1, &buffer, &byte_read);
			SchedulerDBGetAppmtRec(buffer, byte_read, &appmt_rec, &num_appmt);
			qfree(buffer);
			DataGetField(sch_appmt_dbid, rec_id, 2, &buffer, &byte_read);
			SchedulerDBGetAppmtString(buffer, byte_read, &string, &num_appmt);
			qfree(buffer);
			for (appmt_num = 0; appmt_num < num_appmt; appmt_num++)
			{
				if (GlobalFindSearchText((BYTE*)cmd_ptr, string[appmt_num]) >= 0)
				{
					found = FALSE;
					for(i = 0; i < total; i++)
					{
						if (repeat_recid[i] == -1) continue;
						DataRecIDtoNum(sch_repeat_dbid, repeat_recid[i], &rec_num);
						DataOpenRecord(sch_repeat_dbid, rec_num, &rec_id_1, NULL);
						DataGetField(sch_repeat_dbid, rec_id_1, F_CONTENTS, &buffer, &byte_read);
						if (strcmp(string[appmt_num], buffer) != 0)
						{
							found = TRUE;
							SchedulerPrepareFindText(sch_appmt_dbid, rec_id, appmt_num, &prepare_string);
#ifdef PR31700
							GlobalFindAddItem(app_id, sch_appmt_dbid, rec_id, (USHORT)appmt_num, prepare_string, FALSE);
#endif
							qfree(buffer);
							break;
						}
						qfree(buffer);
						DataGetField(sch_appmt_dbid, rec_id, F_DATE, &buffer1, &byte_read);
						DataGetField(sch_repeat_dbid, rec_id_1, F_START_TIME, &buffer2, &byte_read);
						result = SchedulerCompareDate((UBYTE*)buffer1, (UBYTE*)buffer2);
						if (result != 1)
						{
							found = TRUE;
							SchedulerPrepareFindText(sch_appmt_dbid, rec_id, appmt_num, &prepare_string);
#ifdef PR31700
							GlobalFindAddItem(app_id, sch_appmt_dbid, rec_id, (USHORT)appmt_num, prepare_string, FALSE);
#endif
							qfree(buffer1);
							qfree(buffer2);
							pfree(prepare_string);							break;
						}
						else
						{
							found = TRUE;
							if (appmt_rec[appmt_num].hour > (SHORT)buffer2[3]) break;
							if (appmt_rec[appmt_num].hour == (SHORT)buffer2[3] && appmt_rec[appmt_num].minute >= (SHORT)buffer2[4]) break;
							SchedulerPrepareFindText(sch_appmt_dbid, rec_id, appmt_num, &prepare_string);
#ifdef PR31700
							GlobalFindAddItem(app_id, sch_appmt_dbid, rec_id, (USHORT)appmt_num, prepare_string, FALSE);
#endif
							repeat_recid[i] = -1;
							qfree(buffer1);
							qfree(buffer2);
							pfree(prepare_string);
							break;
						}
					}
					if (found == TRUE) break;
					if (found == FALSE)
					{
						SchedulerPrepareFindText(sch_appmt_dbid, rec_id, appmt_num, &prepare_string);
#ifdef PR31700
						GlobalFindAddItem(app_id, sch_appmt_dbid, rec_id, (USHORT)appmt_num, prepare_string, FALSE);
#endif			
						break;
					}
				}
			}
		}
		for(i = 0; i < total; i++)
		{
			if (repeat_recid[i] == -1) continue;
			SchedulerPrepareFindText(sch_repeat_dbid, repeat_recid[i], 0, &prepare_string);
#ifdef PR31700
			GlobalFindAddItem(app_id, sch_repeat_dbid, repeat_recid[i], 0, prepare_string, FALSE);
#endif
		}
		if (repeat_recid != NULL) qfree(repeat_recid);
		if (num_appmt != 0)
		{
			for(count = 0; count < num_appmt; count++)
				qfree(string[count]);
			qfree(string);
		}
		if (appmt_rec != NULL) qfree(appmt_rec);
		return TRUE;
	case LAUNCH_CMD_GOTO_REC:
		virtual_table.vt_num_rows = 0;
		SchedulerGotoItem(((GotoRec*)cmd_ptr)->dbid, ((GotoRec*)cmd_ptr)->rec_id,
			((GotoRec*)cmd_ptr)->field_num, ((GotoRec*)cmd_ptr)->find_string);
		
		if (((GotoRec*)cmd_ptr)->find_string != NULL)
			pfree(((GotoRec*)cmd_ptr)->find_string);
		pfree(cmd_ptr);
		
		//------------------------------------------------------------------------------------
		//--------------------- add at 18052000 ----------------------------------------------		
		DataGetField(sch_appmt_dbid, SCH_STATUS, 2, &buffer, &byte_read);
		alarm_count = *((UWORD*)buffer);
		qfree(buffer);
		
		DataGetField(sch_appmt_dbid, SCH_STATUS, 3, &buffer, &byte_read);
		current_appmt_num = *((UWORD*)buffer);
		qfree(buffer);
		
		DataGetField(sch_appmt_dbid, SCH_STATUS, 4, &buffer, &byte_read);
		current_repeat_num = *((UWORD*)buffer);
		qfree(buffer);
		//-------------------------------------------------------------------------------------
		
		EventLoop();
		
		/* =========================================================================================== */
		FormGetActiveFormID(&active_form_id);
		if (active_form_id == FORM_SCH_DAY_VIEW && virtual_table.vt_active_row != -1)
		{
			output = SchedulerDayViewNormal(&virtual_table, TABLE_SCH_DAY_VIEW, &start_row,
				&end_row, &start_deleted, &end_deleted);
			if (virtual_table.vt_active_row != -1 && new_appointment == TRUE)
			{
				new_appointment = FALSE;
				virtual_table.vt_items[virtual_table.vt_active_row]->appointment = -1;
			}
			virtual_table.vt_active_row = -1;
			SchedulerTimeSettingsDeleteAllEmptyAppmts(&virtual_table);
			SchedulerTimeSettingsAddAppmts(&virtual_table);
		}
		
		/* =========================================================================================== */		
		
		SchedulerAppSave();
		UIDeleteAllAppObjects();
		DataCloseDB(sch_appmt_dbid);
		DataCloseDB(sch_voice_dbid);
		return TRUE;
	case LAUNCH_CMD_ALARM_HIT:
		SchedulerManageAlarm((AlarmEventHit*)cmd_ptr);
		pfree(cmd_ptr);
		DataCloseDB(sch_appmt_dbid);
		DataCloseDB(sch_voice_dbid);
		return TRUE;
	default:
		return FALSE;
	}
	return FALSE;
}

/********************************************************
* Function:	SchedulerPrepareFindText
* Purpose: 	This function is called to prepare the find text to 
be displayed in Global Find
* Scope:		application/internal
* Input:		dbid
rec_id
prepare_string
* Output:		None
* Return:		None
* Comment: 	None
*********************************************************/
void SchedulerPrepareFindText(DatabaseID dbid, RecordID rec_id, WORD appmt_num, BYTE **prepare_string)
{
	/* sch_appmt_dbid */
	SHORT		string_text_width, string_time_width;
	ObjectBounds	text_bounds, time_bounds;
	BYTE		*text, date_time[20], *buffer, *temp, sbuffer[13], time[10], count, length_sbuffer;
	UWORD		byte_read, name_num_chars;
	WORD		num_appmt;
	BYTE		**string;
	AppointmentDB	*appmt_rec;
	
	text_bounds.xcoord	= 0;
	text_bounds.ycoord	= 0;
	text_bounds.width	= 60;
	text_bounds.height	= 9;
	
	time_bounds.xcoord	= 0;
	time_bounds.ycoord	= 0;
	time_bounds.width	= 74;
	time_bounds.height	= 9;
	
	*prepare_string = (BYTE*)pmalloc(200*sizeof(BYTE));
	
	if (dbid == sch_appmt_dbid)
	{
		DataGetField(dbid, rec_id, 1, &buffer, &byte_read);
		SchedulerDBGetAppmtRec(buffer, byte_read, &appmt_rec, &num_appmt);
		qfree(buffer);
		DataGetField(dbid, rec_id, 2, &buffer, &byte_read);
		SchedulerDBGetAppmtString(buffer, byte_read, &string, &num_appmt);
		qfree(buffer);
		
		text = (BYTE*)pmalloc((strlen(string[appmt_num]) + 10) * sizeof(BYTE));
		strcpy(text, string[appmt_num]);
		StrChopString(&text_bounds, text, SMALL_FONT, TRUE, 0);
		string_text_width = StrGetWidth(text, SMALL_FONT);
		
		DataGetField(dbid, rec_id, 0, &buffer, &byte_read);
		SchedulerCalculateDayViewDate((SHORT)(buffer[0] + SYSETUP_YEAR_OFFSET), (SHORT)(buffer[1]), (SHORT)(buffer[2]), sbuffer);
		qfree(buffer);
		SchedulerHourMinuteToString(appmt_rec[appmt_num].hour, appmt_rec[appmt_num].minute, time, TRUE);
		
		length_sbuffer = strlen(sbuffer);
		strcpy(date_time, sbuffer);
		date_time[length_sbuffer] = 32;
		for (count = 0; count <= (BYTE)(strlen(time)); count++)
			date_time[length_sbuffer + count + 1] = time[count];
		
		temp = (BYTE*)pmalloc((strlen(date_time) + 10) * sizeof(BYTE));
		strcpy(temp, date_time);
		StrChopString(&time_bounds, temp, SMALL_FONT, TRUE, 0);
		string_time_width = StrGetWidth(temp, SMALL_FONT);
		
		strcpy(*prepare_string, text);
		name_num_chars = strlen(text);
		(*prepare_string)[name_num_chars] = 11;
		(*prepare_string)[name_num_chars + 1] = 139 - string_time_width - string_text_width;
		sprintf((char*)(*prepare_string + name_num_chars + 2), "%s", temp);
		
		if (num_appmt != 0)
		{
			for (appmt_num = 0; appmt_num < num_appmt; appmt_num++)
				qfree(string[appmt_num]);
			qfree(string);
		}
		qfree(appmt_rec);
		pfree(temp);
		pfree(text);
	}
	if (dbid == sch_repeat_dbid)
	{
		DataGetField(dbid, rec_id, F_CONTENTS, &buffer, &byte_read);
		
		text = (BYTE*)pmalloc((strlen(buffer) + 10) * sizeof(BYTE));
		strcpy(text, buffer);
		StrChopString(&text_bounds, text, SMALL_FONT, TRUE, 0);
		string_text_width = StrGetWidth(text, SMALL_FONT);
		
		DataGetField(dbid, rec_id, F_START_TIME, &buffer, &byte_read);
		SchedulerCalculateDayViewDate((SHORT)((UBYTE)buffer[0] + SYSETUP_YEAR_OFFSET), (SHORT)((UBYTE)buffer[1]), (SHORT)((UBYTE)buffer[2]), sbuffer);
		SchedulerHourMinuteToString(buffer[3], buffer[4], time, TRUE);
		qfree(buffer);
		
		length_sbuffer = strlen(sbuffer);
		strcpy(date_time, sbuffer);
		date_time[length_sbuffer] = 32;
		for (count = 0; count <= (BYTE)(strlen(time)); count++)
			date_time[length_sbuffer + count + 1] = time[count];
		temp = (BYTE*)pmalloc((strlen(date_time) + 10) * sizeof(BYTE));
		strcpy(temp, date_time);
		StrChopString(&time_bounds, temp, SMALL_FONT, TRUE, 0);
		string_time_width = StrGetWidth(temp, SMALL_FONT);
		
		strcpy(*prepare_string, text);
		name_num_chars = strlen(text);
		(*prepare_string)[name_num_chars] = 11;
		(*prepare_string)[name_num_chars + 1] = 139 - string_time_width - string_text_width;
		sprintf((char*)(*prepare_string + name_num_chars + 2), "%s", temp);
		pfree(temp);
		pfree(text);
	}
}


/********************************************************
* Function:	SchedulerGotoItem
* Purpose: 	This function is called to init all related variables
and goto the specific form to display the required 
record
* Scope:		application/internal
* Input:		dbid
rec_id
field_num
search_string
* Output:		None
* Return:		None
* Comment: 	None
*********************************************************/
void SchedulerGotoItem(DatabaseID dbid, RecordID rec_id, USHORT field_num, BYTE *search_string)
{
	BYTE			*buffer, object_type;
	UWORD			byte_read, rec_num, repeat_num, *repeat_no;
	BYTE			**string;
	UBYTE			date[4];
	SHORT			wday, nth_week;
	WORD			highlight_char_pos, line_num, total_num_lines, num_lines, num_appmt;
	Field			*field_ptr;
	CountrySettings 	country;
	EvtType			evt;
	Scrollbar		*scroll_ptr;
	USHORT			row_to_be_drawn;
	BOOLEAN			found = FALSE;
	WORD			count;
	RepeatAttr		*repeat_attr;
	
	SchedulerDatabaseChecking();
	SySetupGetCountrySettings(&country);
	DataRecIDtoNum(dbid, rec_id, &rec_num);
	DataOpenRecord(dbid, rec_num, &rec_id, NULL);
	
	/* global variables initialisation */
	new_appointment = FALSE;
	day_view_old_event.eventType = 0;
	SchInitMainGlobal();
	
	FormInitAllFormObjects(FORM_SCH_DAY_VIEW);
	FormInitAllFormObjects(FORM_SCH_TIME_SETTINGS);
	FormInitAllFormObjects(FORM_SCH_ALARM);
	FormInitAllFormObjects(FORM_SCH_REC);
	FormInitAllFormObjects(FORM_SCH_REPLAY);
	FormInitAllFormObjects(FORM_SCH_DATE);
	FormInitAllFormObjects(FORM_SCH_WEEK);
	FormInitAllFormObjects(FORM_SCH_MONTH);
	FormInitAllFormObjects(FORM_SCH_REPEAT);
	
	// The searching record is not repeat.
	if (dbid == sch_appmt_dbid)
		DataGetField(dbid, rec_id, F_DATE, &buffer, &byte_read);
	// The searching record is repeat.
	else if (dbid == sch_repeat_dbid)
	{
		if (search_string != NULL)
			DataGetField(sch_repeat_dbid, rec_id, F_START_TIME, &buffer, &byte_read);
		else
			DataGetField(sch_repeat_dbid, rec_id, F_ALARM_DATE, &buffer, &byte_read);
	}
	date[0] = (UBYTE)buffer[0];
	date[1] = (UBYTE)buffer[1];
	date[2] = (UBYTE)buffer[2];
	date[4] = '\0';
	qfree(buffer);
	
	//kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk
	//RtcYMDToWday1((SHORT)(date[0] + 2000), (SHORT)(date[1] - 1), (SHORT)(date[2]), &wday, &nth_week);
	wday = Dt_Date_WDay((SHORT)(date[0] + SYSETUP_YEAR_OFFSET), (SHORT)(date[1] - 1), (SHORT)(date[2]));
#ifdef DEBUG_MICH
	printf("\n============== GO TO ITEM point 1 ================");
	printf("\ndate = %ld, %ld, %ld", date[0], date[1], date[2]);
	printf("\nwday = %ld", wday);
	printf("\nrec_id = %ld", rec_id);
	printf("\ncurrent repeat no = %ld", current_repeat_num);
#endif
	//kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk
	if (country.start_of_week == SYSETUP_MON)
	{
		if (wday == 0) wday = 6;
		else wday --;
	}
	SchedulerSetDayViewDate((SHORT)(date[0] + SYSETUP_YEAR_OFFSET), (SHORT)(date[1]), (SHORT)(date[2]), wday);
	if (dbid == sch_repeat_dbid)
	{
		DataGetField(sch_repeat_dbid, rec_id, F_REPEAT_ATTR, (BYTE**)&repeat_attr, &byte_read);
		if (repeat_attr->method == REPEAT_WEEKLY)
		{
			//kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk
			//	RtcYMDToWday1((SHORT)(date[0] + SYSETUP_YEAR_OFFSET), (SHORT)(date[1] - 1), (SHORT)(date[2]), &wday, &nth_week);
			wday = Dt_Date_WDay((SHORT)(date[0] + SYSETUP_YEAR_OFFSET), (SHORT)(date[1] - 1), (SHORT)(date[2]));
#ifdef DEBUG_MICH
			printf("\n============== GO TO ITEM point 2 ================");
			printf("\ndate = %ld, %ld, %ld", date[0], date[1], date[2]);
			printf("\nwday = %ld", wday);
			printf("\nrec_id = %ld", rec_id);
#endif
			//kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk
			if (repeat_attr->every_data & 128)
				repeat_settings.every_data = repeat_attr->every_data + 128;
			else
				repeat_settings.every_data = repeat_attr->every_data;
			repeat_settings.every_info = repeat_attr->every_info;
			SchedulerCalculatePopupDate(date, wday);
		}
		qfree(repeat_attr);
	}
	SchedulerDayViewLoadAppmtDataToScreen(&virtual_table, date);
	DataRecIDtoNum(dbid, rec_id, &rec_num);
	DataOpenRecord(dbid, rec_num, &rec_id, NULL);
	if (search_string != NULL)
	{
		VTSetVirtualTableLayout(&virtual_table);
		VTVirtualTableSetScrollbar(&virtual_table);
		//	DataOpenRecord(dbid, rec_num, &rec_id, NULL);
		if (dbid == sch_appmt_dbid)
		{
			DataGetField(dbid, rec_id, 2, &buffer, &byte_read);
			SchedulerDBGetAppmtString(buffer, byte_read, &string, &num_appmt);
			qfree(buffer);
			highlight_char_pos = GlobalFindSearchText(search_string, string[field_num]);
		}
		else if (dbid == sch_repeat_dbid)
		{
			DataGetField(dbid, rec_id, F_REPEAT_NUM, &buffer, &byte_read);
			repeat_num = *((UWORD*)buffer);
			//			repeat_num = *repeat_no;
			qfree(buffer);
			DataGetField(dbid, rec_id, F_CONTENTS, &buffer, &byte_read);
			highlight_char_pos = GlobalFindSearchText(search_string, buffer);
			qfree(buffer);
			for(line_num = 0; line_num < virtual_table.vt_num_rows; line_num++)
			{
				if (virtual_table.vt_items[line_num]->repeat_num == repeat_num)
				{
					field_num = line_num;
					break;
				}
			}
		}
		field_ptr = virtual_table.vt_items[field_num]->ptr;
		for (line_num = 0; line_num < field_ptr->field_total_num_lines; line_num++)
		{
			if ((highlight_char_pos >= field_ptr->field_lineinfo[line_num].start) &&
				(highlight_char_pos <= (field_ptr->field_lineinfo[line_num].start +
				field_ptr->field_lineinfo[line_num].length -1)))
			{
				found = TRUE;
				if (line_num > (field_ptr->field_total_num_lines - field_ptr->field_num_lines_displayed))
					line_num = (field_ptr->field_total_num_lines - field_ptr->field_num_lines_displayed);
				field_ptr->field_top_line_num = line_num;
				break;
			}
		}
		if (!found)
			field_ptr->field_top_line_num = 0;
		FormGetObjectPointer(SCROLLBAR_SCH_DAY_VIEW, &object_type, (void**)&scroll_ptr);
		evt.para1 = scroll_ptr->scrollbar_value;
		total_num_lines = 0;
		for (count = 0; count < field_num; count++)
		{
			VTGetFieldTotalNumLines(&virtual_table, (USHORT)count, &num_lines);
			total_num_lines += num_lines;
		}
		evt.para2 =	total_num_lines + field_ptr->field_top_line_num;
		VTScrollbarSetVirtualTable(&virtual_table, &evt, &row_to_be_drawn);
		field_ptr->field_highlight_start_char = highlight_char_pos;
		field_ptr->field_highlight_end_char = highlight_char_pos + strlen(search_string) - 1;
		field_ptr->field_highlight_length = strlen(search_string);
		field_ptr->field_attr.field_highlight = TRUE;
		virtual_table.vt_active_row = -1;
	}
	FormPopupForm(FORM_SCH_DAY_VIEW);
	DataCloseRecord(dbid, rec_id);
}


/********************************************************
* Function:	SchedulerManageAlarm
* Purpose: 	This function is called to init all related variables
and goto the specific form to display the required 
record
* Scope:		application/internal
* Input:		dbid
rec_id
field_num
search_string
* Output:		None
* Return:		None
* Comment: 	None
*********************************************************/
void SchedulerManageAlarm(AlarmEventHit *ptr)
{
	//Make sure all pointers are freed
	//Michelle 19-Jan-2001
	//Bug Fixed 19-Feb-2001
	//After alarm hit, if no record exists, delete the record
	USHORT			row_num;
	RecordID		rec_id, temp_rec_id;
	AppointmentDB		*appmt_rec;
	BYTE			*buffer, **string, *appmt_rec_buf, *string_buf, start[8];
	BYTE			alarm_found = 0, appmt_found = 0;	//Michelle 19-Feb-2001
	UBYTE			date[4], appmt_date[4], next_alarm_date[4], hit_date[4];
	UBYTE			repeat_date[4] = {255, 255, 255, 255}, result;
	WORD			num_appmt, count, num_bytes_appmt, num_bytes_string;
	UWORD			rec_num, count1, total_rec, reference, byte_read;
	AlarmEvent		evtAlarm;
	BOOLEAN			found = FALSE, index = FALSE;
	DatabaseID		dbid;
	RTM			time;
	SHORT			i, j;
	
	BYTE			alarm;		//Michelle 19-Jan-2001
	UBYTE			temp[4];	//Michelle 19-Jan-2001
	
	evtAlarm.type = 0;
	reference = ptr->reference;
	rec_id	= ptr->rec_id;
	dbid = ptr->dbid;
	RtcGetTime(&time);
	date[0] = (UBYTE)(time.year - SYSETUP_YEAR_OFFSET);
	date[1] = (UBYTE)(time.mon + 1);
	date[2] = (UBYTE)(time.mday);
	date[3] = 0;
	
	//Cancel the alarm of the appointment
	if (dbid == sch_appmt_dbid)
	{
		DataRecIDtoNum(sch_appmt_dbid, rec_id, &rec_num);
		if (DataOpenRecord(sch_appmt_dbid, rec_num, &rec_id, NULL) == TRUE)
		{
			DataGetField(sch_appmt_dbid, rec_id, 1, &buffer, &byte_read);
			SchedulerDBGetAppmtRec(buffer, byte_read, &appmt_rec, &num_appmt);
			qfree(buffer);
			
			DataGetField(sch_appmt_dbid, rec_id, 2, &buffer, &byte_read);
			SchedulerDBGetAppmtString(buffer, byte_read, &string, &num_appmt);
			qfree(buffer);
			
			for (count1 = 0; count1 < num_appmt; count1++)
			{
				if (appmt_rec[count1].alarm == VOICE_ALARM ||
					appmt_rec[count1].alarm == TONE_ALARM)
				{
					if (appmt_rec[count1].alarm_num == reference)
					{
						row_num = count1;
						found = TRUE;
						break;
					}
				}
			}
			
			if (found)
			{
				if (appmt_rec[row_num].alarm == VOICE_ALARM)
					appmt_rec[row_num].alarm = VOICE_NOT_ALARM;
				else appmt_rec[row_num].alarm = NO_ALARM;
				
				if (strlen(string[row_num]) == 0 && appmt_rec[row_num].alarm == NO_ALARM)
				{
					appmt_rec[row_num].appointment = -1;
					appmt_rec[row_num].appmt_num   = 0;
				}
				else
					appmt_rec[row_num].appmt_num |= 0x80000000;
				
				//---------------------------------------------------------------- Modifying codes
				for (count = 0; count < num_appmt; count ++)
				{
					if (appmt_rec[count].appointment >= 0)
						appmt_found = 1;
					if (appmt_rec[count].alarm != NO_ALARM &&
						appmt_rec[count].alarm != VOICE_NOT_ALARM)
					{
						alarm_found = 1;
						break;
					}
				}
				
				if (appmt_found)
				{
					DataWriteField(sch_appmt_dbid, rec_id, 3, 1, (BYTE*)&alarm_found);
					SchedulerDBAppmtToBuffer(appmt_rec, string, num_appmt,
						&appmt_rec_buf, &string_buf, &num_bytes_appmt,
						&num_bytes_string);
					DataWriteField(sch_appmt_dbid, rec_id, 1, num_bytes_appmt, appmt_rec_buf);
					DataWriteField(sch_appmt_dbid, rec_id, 2, num_bytes_string, string_buf);
					qfree(appmt_rec_buf);
					qfree(string_buf);
					
					if (num_appmt != 0)
					{
						for (count = 0; count < num_appmt; count++)
							qfree(string[count]);
						qfree(string);
					}
					qfree(appmt_rec);
				}
				else
				{
					DataCloseRecord(sch_appmt_dbid, rec_id);
					DataDeleteRecord(sch_appmt_dbid, rec_id, FALSE);
					qfree(appmt_rec);
				}
				//---------------------------------------------------------------- Modifying codes
			}
		}
	}
	//Write the alarm date to the repeat record
	else if (dbid == sch_repeat_dbid)
	{
		if (DataRecIDtoNum(dbid, rec_id, &rec_num) == TRUE)
		{
			hit_date[0] = (BYTE)(ptr->hit_time.year - SYSETUP_YEAR_OFFSET);
			hit_date[1] = (BYTE)(ptr->hit_time.mon + 1);
			hit_date[2] = (BYTE)(ptr->hit_time.mday);
			DataOpenRecord(dbid, rec_num, &temp_rec_id, NULL);
			DataWriteField(dbid, temp_rec_id, F_ALARM_DATE, 4, (BYTE*)hit_date);
			DataCloseRecord(dbid, temp_rec_id);
		}
	}
	
	//Search for next alarm from appointment records
	if (SchedulerBinarySearch(date, &rec_num) == TRUE)
	{
		DataTotalRecord(sch_appmt_dbid, &total_rec);
		for(count1 = rec_num; count1 < total_rec; count1++)
		{
			DataOpenRecord(sch_appmt_dbid, count1, &temp_rec_id, NULL);
			DataGetField(sch_appmt_dbid, temp_rec_id, F_ALARM, &buffer, &byte_read);
			//Make sure all the pointer is freed 19-Jan-2001
			//Michelle 19-Jan-2001
			alarm = *buffer;	//Michelle 19-Jan-2001
			qfree(buffer);		//Michelle 19-Jan-2001
			if (alarm == 1)		//Michelle 19-Jan-2001
			{
				DataGetField(sch_appmt_dbid, temp_rec_id, F_DATE, &buffer, &byte_read);
				appmt_date[0] = buffer[0];
				appmt_date[1] = buffer[1];
				appmt_date[2] = buffer[2];
				appmt_date[3] = 0;
				qfree(buffer);
				break;
			}
			else
			{
				for(i = 0; i < 3; i++)
					appmt_date[i] = -1;
				appmt_date[3] = 0;
			}
			DataCloseRecord(sch_appmt_dbid, temp_rec_id);
		}
	}
	else
	{
		for(i = 0; i < 3; i++)
			appmt_date[i] = -1;
		appmt_date[3] = 0;
	}
	//Search next alarm from repeat records
	DataTotalRecord(sch_repeat_dbid, &total_rec);
	for(i = 0; i < total_rec; i++)
	{
		DataOpenRecord(sch_repeat_dbid, (UWORD)i, &temp_rec_id, NULL);
		DataGetField(sch_repeat_dbid, temp_rec_id, F_ALARM_FLAG, &buffer, &byte_read);
		//Make sure all the pointer is freed 19-Jan-2001
		//Michelle 19-Jan-2001
		alarm = *buffer;	//Michelle 19-Jan-2001
		qfree(buffer);		//Michelle 19-Jan-2001
		if (alarm == 1)	//Michelle 19-Jan-2001
		{
			index = FALSE;
			DataGetField(sch_repeat_dbid, temp_rec_id, F_ALARM_DATE, &buffer, &byte_read);
			temp[0] = (UBYTE)buffer[0];	//Michelle 19-Jan-2001
			temp[1] = (UBYTE)buffer[1];	//Michelle 19-Jan-2001
			temp[2] = (UBYTE)buffer[2];	//Michelle 19-Jan-2001
			temp[3] = 0;			//Michelle 19-Jan-2001
			qfree(buffer);			//Michelle 19-Jan-2001
			if ((BYTE)temp[0] == -1 && (BYTE)temp[1] == -1 && (BYTE)temp[2]  == -1)	//Michelle 19-Jan-2001
			{
				DataGetField(sch_repeat_dbid, temp_rec_id, F_START_TIME, &buffer, &byte_read);
				temp[0] = (UBYTE)buffer[0];	//Michelle 19-Jan-2001
				temp[1] = (UBYTE)buffer[1];	//Michelle 19-Jan-2001
				temp[2] = (UBYTE)buffer[2];	//Michelle 19-Jan-2001
				temp[3] = 0;			//Michelle 19-Jan-2001
				qfree(buffer);			//Michelle 19-Jan-2001
				index = TRUE;
			}
			if (!SchedulerRepeatFindDate(temp_rec_id, temp, date, next_alarm_date, index)) //Michelle 19-Jan-2001
				continue;
			if ((BYTE)repeat_date[0] == -1 && (BYTE)repeat_date[1] == -1 && (BYTE)repeat_date[2] == -1 && (BYTE)repeat_date[3] == -1)
			{
				j = 3;
				do
				{
					repeat_date[j] = next_alarm_date[j];
					j--;
				}while(j >= 0);
			}
			result = SchedulerCompareDate(repeat_date, next_alarm_date);
			if (result == 2)
			{
				j = 3;
				do
				{
					repeat_date[j] = next_alarm_date[j];
					j--;
				}while(j >= 0);
			}
		}
	}
	
	if ((BYTE)appmt_date[0] == -1 && (BYTE)appmt_date[1] == -1 && (BYTE)appmt_date[2] == -1)
	{
		if ((BYTE)repeat_date[0] == -1 && (BYTE)repeat_date[1] == -1 && (BYTE)repeat_date[2] == -1)
			return;
		else SchedulerSetAppmtWholeDayAlarm(repeat_date);
	}
	else if ((BYTE)repeat_date[0] == -1 && (BYTE)repeat_date[1] == -1 && (BYTE)repeat_date[2] == -1)
	{
		SchedulerSetAppmtWholeDayAlarm(appmt_date);
	}
	else
	{
		result = SchedulerCompareDate(appmt_date, repeat_date);
		//if appmt date > repeat date
		if (result == 0)
		{
			SchedulerSetAppmtWholeDayAlarm(repeat_date);
		}
		else if (result >= 1)
		{
			SchedulerSetAppmtWholeDayAlarm(appmt_date);
		}
	}
	return;
}

/********************************************************
* Function:	SchedulerRepeatFindDate
* Purpose: 	This function is called to find out the
*				next alarm date of repeat record
* Scope:		application/internal
* Input:		rec_id
*				alarm_date	the date when repeat record alarmed
*				today		today's date
*				index		a flag indicate that the input alarm date == start date
* Output:		next_alarm_date	the date for next alarm
* Return:		TRUE		next alarm date can be found
*				FALSE		next alarm date cannot be found
* Comment: 	when index flag is set, special handle is needed
*********************************************************/
BOOLEAN SchedulerRepeatFindDate(RecordID rec_id, UBYTE *alarm_date, UBYTE *today, UBYTE *next_alarm_date, BOOLEAN index)
{
	//Make sure all pointers are freed
	//Michelle 19-Jan-2001
	RepeatAttr	*repeat_attr;
	UWORD		byte_read, repeat_no;
	BYTE		result, *buffer;
	BYTE		repeat_days, exception, data = 64, bit_sun = 128;
	BYTE		weekday_no[7] = {0, 1, 2, 3, 4, 5, 6};
	BYTE		remainder[7] = {-1, -1, -1, -1, -1, -1, -1};
	BYTE		temp[7] = {-1, -1, -1, -1, -1, -1, -1};
	UBYTE		start[8], end[8], check[8], temp_date[4];
	SHORT		i, j, day_in_month, count, year, mon, day, wday, nth_week, mday;
	BOOLEAN		found = FALSE;
	CountrySettings	country;
	RTM		pDate;
	
	if (index == TRUE)
	{
		result = SchedulerCompareDate(alarm_date, today);
		if (result == 1 || result == 0)
		{
			j = 3;
			do
			{
				next_alarm_date[j] = alarm_date[j];
				j--;
			}while(j >= 0);
			
			DataGetField(sch_repeat_dbid, rec_id, F_EXCEPT_FLAG, &buffer, &byte_read);
			exception = *buffer;
			qfree(buffer);
			if (exception != 1)
				return TRUE;
		}
	}
	
	//Get start date of repeat record
	DataGetField(sch_repeat_dbid, rec_id, F_START_TIME, &buffer, &byte_read);
	i = 6;
	do
	{
		start[i] = buffer[i];
		i--;
	}while(i >= 0);
	start[7] = 0;
	qfree(buffer);
	
	//Get end date of repeat record
	DataGetField(sch_repeat_dbid, rec_id, F_END_TIME, &buffer, &byte_read);
	i = 6;
	do
	{
		end[i] = buffer[i];
		i--;
	}while(i >= 0);
	end[7] = 0;
	qfree(buffer);		//Michelle 19-Jan-2001
	
	//Convert today to check[8] array
	i = 2;
	do
	{
		check[i] = alarm_date[i];
		i--;
	}while(i >= 0);
	i = 7;
	do
	{
		check[i] = 0;
		i--;
	}while(i >= 3);
	
	//if today is not within the repeat range
	if (!IsCheckTimeBetweenStartAndEndTime(start, end, check)) return FALSE;
	i = 3;
	do
	{
		next_alarm_date[i] = alarm_date[i];
		i--;
	}while(i >= 0);
	next_alarm_date[4] = 0;
	DataGetField(sch_repeat_dbid, rec_id, F_REPEAT_ATTR, (BYTE**)&repeat_attr, &byte_read);
	switch(repeat_attr->method)
	{
	case REPEAT_DAILY:
		repeat_days = repeat_attr->every_info;
		day_in_month = Dt_DaysOfMon((SHORT)(alarm_date[0] + SYSETUP_YEAR_OFFSET), (SHORT)(alarm_date[1] - 1));
		do
		{
			if (next_alarm_date[0] != alarm_date[0] || next_alarm_date[1] != alarm_date[1])
				day_in_month = Dt_DaysOfMon((SHORT)(next_alarm_date[0] + SYSETUP_YEAR_OFFSET), (SHORT)(next_alarm_date[1] - 1));
			next_alarm_date[2] = next_alarm_date[2] + repeat_days;
			if ((SHORT)next_alarm_date[2] > day_in_month)
			{
				next_alarm_date[2] = next_alarm_date[2] - (BYTE)day_in_month;
				next_alarm_date[1]++;
				if (next_alarm_date[1] > 12)
				{
					next_alarm_date[1] = next_alarm_date[1] - 12;
					next_alarm_date[0]++;
				}
			}
			result = SchedulerCompareDate(next_alarm_date, today);
		}while(result != 0);
		DataGetField(sch_repeat_dbid, rec_id, F_EXCEPT_FLAG, &buffer, &byte_read);
		exception = *buffer;
		qfree(buffer);
		
#ifdef DEBUG_MICH
		printf("\n In SchedulerRepeatFindDate");
		printf("\n exception = %ld", exception);
#endif
		if (exception == 1)
		{
			DataGetField(sch_repeat_dbid, rec_id, F_REPEAT_NUM, &buffer, &byte_read);
			repeat_no = *((UWORD*)buffer);
			qfree(buffer);
			while (SchedulerCheckExceptionDB(repeat_no, next_alarm_date))
			{
				next_alarm_date[2] = next_alarm_date[2] + repeat_days;
				if ((SHORT)next_alarm_date[2] > day_in_month)
				{
					next_alarm_date[2] = next_alarm_date[2] - (BYTE)day_in_month;
					next_alarm_date[1]++;
					if (next_alarm_date[1] > 12)
					{
						next_alarm_date[1] = next_alarm_date[1] - 12;
						next_alarm_date[0]++;
					}
				}
			}
#ifdef DEBUG_MICH
			printf("\n next alarm date = %ld, %ld, %ld", next_alarm_date[0], next_alarm_date[1], next_alarm_date[2]);
#endif
		}
		qfree(repeat_attr);
		break;
	case REPEAT_WEEKLY:
		SySetupGetCountrySettings(&country);
		repeat_days = repeat_attr->every_info * 7;
		//kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk
		//		day_in_month = RtcGetDaysInMonth((SHORT)(alarm_date[0] + SYSETUP_YEAR_OFFSET), (SHORT)(alarm_date[1] - 1));
		day_in_month = Dt_DaysOfMon((SHORT)(alarm_date[0] + SYSETUP_YEAR_OFFSET), (SHORT)(alarm_date[1] - 1));
#ifdef DEBUG_MICH
		printf("\n ******* Repeat Find Date point 1 *********");
		printf("\n today = %ld, %ld, %ld", today[0], today[1], today[2]);
		printf("\n day_in_month = %ld", day_in_month);
#endif
		//kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk
		i = 0;
		count = 0;
		while(data >= 1)
		{
			if ((repeat_attr->every_data & data) == data)
			{
				remainder[count] = weekday_no[i];
				count++;
			}
			data = data / 2;
			i++;
		}
		//Restore the remainder list if start of week == monday
		if ((repeat_attr->every_data & bit_sun) == bit_sun)
		{
			if (country.start_of_week == SYSETUP_MON)
			{
				for(i = 0; i < count; i++)
				{
					if (remainder[i] == 0) remainder[i] = 6;
					else remainder[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[i] == 6) remainder[i] = 0;
					else remainder[i]++;
				}
			}
		}
		// To find out the weekday number of the start date
		year = (SHORT)(next_alarm_date[0] + SYSETUP_YEAR_OFFSET);
		mon = (SHORT)(next_alarm_date[1]);
		day = (SHORT)(next_alarm_date[2]);
		//kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk
		//	RtcYMDToWday1(year, mon - 1, day, &wday, &nth_week);
		wday = Dt_Date_WDay(year, mon - 1, day);
		//kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk
		if (country.start_of_week == SYSETUP_MON)
		{
			if (wday == 0) wday = 6;
			else wday--;
		}
		for (i = 0; i < count; i++)
			remainder[i] = remainder[i] - (BYTE)wday;
		// To assure all the values inside remainder list array to be positive
		for (i = 0; i < count; i++)
			if (remainder[i] < 0)
				remainder[i] = remainder[i] + repeat_days;
			
			for(i = 0; i < count; i++)
				if (remainder[i] == 0)
					break;
				//Sort the contents of remainder array
				for(j = 0; j < count; j++)
				{
					temp[j] = remainder[i];
#ifdef DEBUG_MICH
					printf("\n temp[%d] = %ld", j, temp[j]);
#endif
					i++;
					if (i >= count) i = 0;
				}
				do
				{
					for(i = 0; i < 4; i++)
						temp_date[i] = next_alarm_date[i];
					
#ifdef DEBUG_MICH
					printf("\n Point 1~~~");
					printf("\n temp date = %ld %ld %ld", temp_date[0], temp_date[1], temp_date[2]);
					printf("\n next alarm date = %ld %ld %ld", next_alarm_date[0], next_alarm_date[1], next_alarm_date[2]);
#endif
					
					if (next_alarm_date[0] != alarm_date[0] || next_alarm_date[1] != alarm_date[1])
						day_in_month = Dt_DaysOfMon((SHORT)(next_alarm_date[0] + SYSETUP_YEAR_OFFSET), (SHORT)(next_alarm_date[1] - 1));
					
					for(j = 0; j < count; j++)
					{
						temp_date[2] = next_alarm_date[2] + temp[j];
						if ((SHORT)temp_date[2] > day_in_month)
						{
							temp_date[2] = temp_date[2] - (BYTE)day_in_month;
							temp_date[1]++;
							if (temp_date[1] > 12)
							{
								temp_date[1] = temp_date[1] - 12;
								temp_date[0]++;
							}
						}
#ifdef DEBUG_MICH
						printf("\n Point 2 ~~~ ");
						printf("\n temp date = %ld %ld %ld", temp_date[0], temp_date[1], temp_date[2]);
#endif
						result = SchedulerCompareDate(temp_date, today);
						if (result == 0)
						{
							DataGetField(sch_repeat_dbid, rec_id, F_EXCEPT_FLAG, &buffer, &byte_read);
							exception = *buffer;		//Michelle 19-Jan-2001
							qfree(buffer);			//Michelle 19-Jan-2001
							if (exception == 1)		//Michelle 19-Jan-2001
							{
#ifdef DEBUG_MICH
								printf("\n Point 2 A ~~~");
								printf("\n has exception");
#endif
								DataGetField(sch_repeat_dbid, rec_id, F_REPEAT_NUM, &buffer, &byte_read);
								repeat_no = *((UWORD*)buffer);
								qfree(buffer);
								if (SchedulerCheckExceptionDB(repeat_no, temp_date))
								{
#ifdef DEBUG_MICH
									printf("\n Point 2 B ~~~");
									printf("\n temp date is an exception date");
#endif
									found = FALSE;
									continue;
								}
							}
							found = TRUE;
							break;
						}
					}
					if (found)
					{
#ifdef DEBUG_MICH
						printf("\n Point 3");
						printf("\n next alarm date is found");
						printf("\n next alarm date = %ld %ld %ld", next_alarm_date[0], next_alarm_date[1], next_alarm_date[2]);
#endif
						for(i = 0; i < 4; i++)
							next_alarm_date[i] = temp_date[i];
						break;
					}
					next_alarm_date[2] = next_alarm_date[2] + repeat_days;
					if ((SHORT)next_alarm_date[2] > day_in_month)
					{
						next_alarm_date[2] = next_alarm_date[2] - (BYTE)day_in_month;
						next_alarm_date[1]++;
						if (next_alarm_date[1] > 12)
						{
							next_alarm_date[1] = next_alarm_date[1] - 12;
							next_alarm_date[0]++;
						}
					}
#ifdef DEBUG_MICH
					printf("\n Point 4");
					printf("\n next alarm date = %ld %ld %ld", next_alarm_date[0], next_alarm_date[1], next_alarm_date[2]);
#endif
				}while(!found);
#ifdef DEBUG_MICH
				printf("\n Finally ~~");
				printf("\n next alarm date = %ld %ld %ld", next_alarm_date[0], next_alarm_date[1], next_alarm_date[2]);
#endif
				qfree(repeat_attr);
				break;
	case REPEAT_MONTHLY_DATE:
		do
		{
			next_alarm_date[1] = next_alarm_date[1] + repeat_attr->every_info;
			if (next_alarm_date[1] > 12)
			{
				next_alarm_date[1] = next_alarm_date[1] - 12;
				next_alarm_date[0]++;
			}
			result = SchedulerCompareDate(next_alarm_date, today);
		}while(result != 0);
		DataGetField(sch_repeat_dbid, rec_id, F_EXCEPT_FLAG, &buffer, &byte_read);
		exception = *buffer;
		qfree(buffer);
		if (exception == 1)
		{
			DataGetField(sch_repeat_dbid, rec_id, F_REPEAT_NUM, &buffer, &byte_read);
			repeat_no = *((UWORD*)buffer);
			qfree(buffer);
			while(SchedulerCheckExceptionDB(repeat_no, next_alarm_date))
			{
				next_alarm_date[1] = next_alarm_date[1] + repeat_attr->every_info;
				if (next_alarm_date[1] > 12)
				{
					next_alarm_date[1] = next_alarm_date[1] - 12;
					next_alarm_date[0]++;
				}
			}
		}
		qfree(repeat_attr);
		break;
	case REPEAT_MONTHLY_DAY:
		do
		{
			next_alarm_date[1] = next_alarm_date[1] + repeat_attr->every_info;
			if (next_alarm_date[1] > 12)
			{
				next_alarm_date[1] = next_alarm_date[1] - 12;
				next_alarm_date[0]++;
			}
			year = (SHORT)(next_alarm_date[0] + SYSETUP_YEAR_OFFSET);
			mon = (SHORT)next_alarm_date[1];
			if (repeat_attr->every_data & 128)
				wday = repeat_attr->every_data + 128;
			else
				wday = repeat_attr->every_data;
			nth_week = repeat_attr->n_week;
			//kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk
			if (nth_week == 5)
			{
				if (Dt_M7day_Date(year, mon-1, -1, wday, &pDate) == TRUE)
					next_alarm_date[2] = pDate.mday;
					/*
					RtcWday2ToYMD(year, mon-1, wday, nth_week, &mday);
					if (mday == -1)
					{
					nth_week--;
					RtcWday2ToYMD(year, mon-1, wday, nth_week, &mday);
			}*/
			}
			else
			{
				if (Dt_M7day_Date(year, mon-1, nth_week, wday, &pDate) == TRUE)
					next_alarm_date[2] = pDate.mday;
			}
			//kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk
			result = SchedulerCompareDate(next_alarm_date, today);
		}while(result != 0);
		DataGetField(sch_repeat_dbid, rec_id, F_EXCEPT_FLAG, &buffer, &byte_read);
		exception = *buffer;
		qfree(buffer);
		if (exception == 1)
		{
			DataGetField(sch_repeat_dbid, rec_id, F_REPEAT_NUM, &buffer, &byte_read);
			repeat_no = *((UWORD*)buffer);
			qfree(buffer);
			while(SchedulerCheckExceptionDB(repeat_no, next_alarm_date))
			{
				next_alarm_date[1] = next_alarm_date[1] + repeat_attr->every_info;
				if (next_alarm_date[1] > 12)
				{
					next_alarm_date[1] = next_alarm_date[1] - 12;
					next_alarm_date[0]++;
				}
			}
		}
		qfree(repeat_attr);
		break;
	case REPEAT_YEARLY:
		do
		{
			next_alarm_date[0] = next_alarm_date[0] + repeat_attr->every_info;
			result = SchedulerCompareDate(next_alarm_date, today);
		}while(result != 0);
		DataGetField(sch_repeat_dbid, rec_id, F_EXCEPT_FLAG, &buffer, &byte_read);
		exception = *buffer;
		qfree(buffer);
		if (exception == 1)
		{
			DataGetField(sch_repeat_dbid, rec_id, F_REPEAT_NUM, &buffer, &byte_read);
			repeat_no = *((UWORD*)buffer);
			qfree(buffer);
			while(SchedulerCheckExceptionDB(repeat_no, next_alarm_date))
				next_alarm_date[0] = next_alarm_date[0] + repeat_attr->every_info;
		}
		qfree(repeat_attr);
		break;
	}
	if ((BYTE)end[1] == -1 && (BYTE)end[2] == -1)
		return TRUE;
	else
	{
		result = SchedulerCompareDate(next_alarm_date, end);
		if (result == 0) return FALSE;
		else return TRUE;
	}
}

/********************************************************
* Function:	SchedulerBinarySearch
* Purpose: 	This function is called to find out the
*		next alarm date of appmt record
* Scope:	application/internal
* Input:	today		today's date
* Output:	*rec_num	the record number of appmt record
* Return:	TRUE		handled
*		FALSE		not handled
* Comment:	None
*********************************************************/
BOOLEAN SchedulerBinarySearch(UBYTE *today, UWORD *rec_num)
{
	//Make sure all pointers are freed
	//Michelle 19-Jan-2001
	UWORD		min = 0, max, total_rec, mid_pt, byte_read;
	RecordID	rec_id;
	BYTE		*buffer, result;
	SHORT		i;
	
	DataCloseDB(sch_appmt_dbid);
	DataOpenDB(sch_appmt_dbid, F_DATE, OPEN_RW);
	DataTotalRecord(sch_appmt_dbid, &total_rec);
	if (total_rec == 0) return FALSE;
	
	max = total_rec - 1;
	if (max == 0)
	{
		DataOpenRecord(sch_appmt_dbid, max, &rec_id, NULL);
		DataGetField(sch_appmt_dbid, rec_id, F_DATE, &buffer, &byte_read);
		result = SchedulerCompareDate((UBYTE*)buffer, today);
		qfree(buffer);		//Michelle 19-Jan-2001
		
		if (result == 2) return FALSE;
		else
		{
			*rec_num = max;
			return TRUE;
		}
	}
	else
	{
		mid_pt = (min + max) / 2;
		do
		{
			DataOpenRecord(sch_appmt_dbid, mid_pt, &rec_id, NULL);
			DataGetField(sch_appmt_dbid, rec_id, F_DATE, &buffer, &byte_read);
			result = SchedulerCompareDate((UBYTE*)buffer, today);
			qfree(buffer);
			if (result == 1)
			{
				*rec_num = mid_pt;
				return TRUE;
			}
			else if (result == 2)
				min = mid_pt;
			else if (result == 0)
				max = mid_pt;
			mid_pt = (min + max) / 2;
		}while((mid_pt != min) && (mid_pt != max));
		DataOpenRecord(sch_appmt_dbid, min, &rec_id, NULL);
		DataGetField(sch_appmt_dbid, rec_id, F_DATE, &buffer, &byte_read);
		result = SchedulerCompareDate((UBYTE*)buffer, today);
		qfree(buffer);		//Michelle 19-Jan-2001
		if (result != 2)
		{
			*rec_num = min;
			return TRUE;
		}
		else
		{
			DataOpenRecord(sch_appmt_dbid, max, &rec_id, NULL);
			DataGetField(sch_appmt_dbid, rec_id, F_DATE, &buffer, &byte_read);
			result = SchedulerCompareDate((UBYTE*)buffer, today);
			qfree(buffer);
			if (result == 2) return FALSE;
			else
			{
				*rec_num = max;
				return TRUE;
			}
		}
	}
}
