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


#include "stdafx.h"
#include "Todo.h"
#include "ToDoDB.h"
#include "ToDoFunc.h"

/*****************************************************************
********************** Global Variables **************************
*****************************************************************/
TableDisplay	to_do_list = {TABLE_TO_DO_LIST,0,0,0,NULL};
AlarmSettings	alarm_settings = {0,0,TRUE,TRUE,FALSE,0,NO_ALARM};
/*	dbid,				temp_recid,		rec_stop,
play_stop,			recorded,		play_pause_frame
*/
AppStatus		app_status = {0,0,0,0,5,0,0,0,0,0,0,TO_DO_LIST,PRIORITY};
/*	rec_id,				completed_status,		alarm_status,
priority_status,	sch_year,				sch_month,
sch_day,			alarm_year,				alarm_month,
alarm_day,			edit_mode,				new_sort_mode
*/
CheckStatus     chk_status = {0,0,0,0,0,0,0,0,0,0,0};

/********************************************************
* Function:	ToDoTableDisplayDraw
* Purpose: 	This function is called to draw the content of
*			in the todotable_display to a table object
* Scope:	application
* Input:	todotable_display	table-display structure
*			dbid				DatabaseID
* Output:	None
* Return:	TRUE    handled
*			FALSE   not-handled
* Comment: 	None
*********************************************************/
BOOLEAN ToDoTableDisplayDraw(TableDisplay *table_display)
{
	ObjectID	cell_ui_id;
	RecordID	rec_id;
	Table		*table_addr;
	Control		*ctl_addr;
	Bitmap		*bmp_addr;
	Form		*form_addr;
	String		*string_addr;
	USHORT		total_num_rows, max_rows_on_display;
	USHORT		top_row_num, num_rows_to_display;
	UWORD		rec_num, byte_read;
	BYTE		*buffer, object_type, text_buffer[10];
	BOOLEAN		completed;
	CountrySettings country;
	USHORT		count =0, cell =0, row_count =0, erase_count =0;
	RecordIDBlock	*temp = table_display->record_id_block;
	
	total_num_rows = table_display->total_num_rows;
	top_row_num = table_display->top_row_num;
	
	if (FormGetObjectPointer(FORM_TO_DO_LIST, &object_type, (void **)&form_addr)
		== ERR_UI_RES_NOT_FOUND)
		FormInitAllFormObjects(FORM_TO_DO_LIST);
	if (FormGetObjectPointer(FORM_TO_DO_VIEWING, &object_type, (void **)&form_addr)
		== ERR_UI_RES_NOT_FOUND)
		FormInitAllFormObjects(FORM_TO_DO_VIEWING);
	if (FormGetObjectPointer(FORM_TO_DO_NEW, &object_type, (void **)&form_addr)
		== ERR_UI_RES_NOT_FOUND)
		FormInitAllFormObjects(FORM_TO_DO_NEW);
	
	FormGetObjectPointer(TABLE_TO_DO_LIST, &object_type, (void **)&table_addr);
	/* Calculate maximum num of row can be display on screen */
	max_rows_on_display = table_addr->bounds.height / table_addr->table_row_height[1];
	
	if ((top_row_num + max_rows_on_display) <= total_num_rows)
		table_display->num_rows_displayed = max_rows_on_display;
	else 
		table_display->num_rows_displayed = total_num_rows - top_row_num;
	
	num_rows_to_display = table_display->num_rows_displayed;
	
	while (temp != NULL && num_rows_to_display > 0)
	{ 
		if (top_row_num >= count && top_row_num < count + TO_DO_BLOCK_SIZE)
		{
			DataRecIDtoNum(tdl_dbid, temp->record_id[top_row_num - count], &rec_num);
			DataOpenRecord(tdl_dbid, rec_num, &rec_id, NULL);
			/* Get the Completed Items */
			DataGetField(tdl_dbid, rec_id, 0, &buffer, &byte_read);
			cell_ui_id = ((TableItems*)(table_addr->table_item_ptr[cell]))->table_item_ui_id;
			if (UISearchForAddress(cell_ui_id,&object_type,(void**)&ctl_addr) != TRUE)return ERR_UI_RES_NOT_FOUND;
			if (*buffer == COMPLETED)
			{
				((ControlTemplateCheckBox *) ctl_addr->control_template)->control_value = TRUE;
				completed = TRUE;
			}
			else
			{
				((ControlTemplateCheckBox *) ctl_addr->control_template)->control_value = FALSE;
				completed = FALSE;
			}
			ctl_addr->control_attr.control_enable = TRUE;
			ctl_addr->control_attr.control_visible = TRUE;
			ctl_addr->control_attr.control_active = TRUE;
			qfree(buffer);
			cell++;
			/* Get the Alarm Status */
			DataGetField(tdl_dbid, rec_id, 1, &buffer, &byte_read);
			if (*buffer == TONE_ALARM)
			{
				((TableItems*)(table_addr->table_item_ptr[cell]))->table_item_ui_id = TO_DO_TONE_OFFSET + row_count;
				if (UISearchForAddress((TO_DO_TONE_OFFSET + row_count),&object_type,(void**)&bmp_addr) != TRUE) return ERR_UI_RES_NOT_FOUND;
				bmp_addr->bitmap_attr.bitmap_enable = FALSE;
				bmp_addr->bitmap_attr.bitmap_visible = TRUE;
				bmp_addr->bitmap_attr.bitmap_active = TRUE;
			}
			else if (*buffer == VOICE_ALARM || *buffer == VOICE_NO_ALARM)
			{
				((TableItems*)(table_addr->table_item_ptr[cell]))->table_item_ui_id = TO_DO_VOICE_OFFSET + row_count;
				if (UISearchForAddress((TO_DO_VOICE_OFFSET + row_count),&object_type,(void**)&bmp_addr) != TRUE) return ERR_UI_RES_NOT_FOUND;
				bmp_addr->bitmap_attr.bitmap_enable = TRUE;
				bmp_addr->bitmap_attr.bitmap_visible = TRUE;
				bmp_addr->bitmap_attr.bitmap_active = TRUE;
			}
			else
			{
				((TableItems*)(table_addr->table_item_ptr[cell]))->table_item_ui_id = TO_DO_TONE_OFFSET + row_count;
				if (UISearchForAddress((TO_DO_TONE_OFFSET + row_count),&object_type,(void**)&bmp_addr) != TRUE) return ERR_UI_RES_NOT_FOUND;
				bmp_addr->bitmap_attr.bitmap_enable = FALSE;
				bmp_addr->bitmap_attr.bitmap_visible = FALSE;
				bmp_addr->bitmap_attr.bitmap_active = FALSE;
				
				if (UISearchForAddress((TO_DO_VOICE_OFFSET + row_count),&object_type,(void**)&bmp_addr) != TRUE) return ERR_UI_RES_NOT_FOUND;
				bmp_addr->bitmap_attr.bitmap_enable = FALSE;
				bmp_addr->bitmap_attr.bitmap_visible = FALSE;
				bmp_addr->bitmap_attr.bitmap_active = FALSE;
			}
			qfree(buffer);
			cell++;
			/* Get the Priority */
			DataGetField(tdl_dbid, rec_id, 2, &buffer, &byte_read);
			cell_ui_id = ((TableItems*)(table_addr->table_item_ptr[cell]))->table_item_ui_id;
			if (UISearchForAddress(cell_ui_id,&object_type,(void**)&ctl_addr) != TRUE)return ERR_UI_RES_NOT_FOUND;
			ctl_addr->control_attr.control_enable = TRUE;
			ctl_addr->control_attr.control_visible = TRUE;
			ctl_addr->control_attr.control_active = TRUE;
			sprintf((char*)text_buffer,"%d",*buffer);
			ControlPopupSetSelectedItem(cell_ui_id,(*buffer - 1));
			ControlSetLabel(cell_ui_id,text_buffer);
			qfree(buffer);
			cell++;
			/* Get the Text Contents */
			DataGetField(tdl_dbid, rec_id, 3, &buffer, &byte_read);
			cell_ui_id = ((TableItems*)(table_addr->table_item_ptr[cell]))->table_item_ui_id;
			/* Get the Read Status */
			FormGetObjectPointer(cell_ui_id, &object_type, (void **)&string_addr);
			string_addr->string_attr.string_visible = TRUE;
			string_addr->bounds.height = table_addr->table_row_height[1];
			/* Set the color of the To Do List Content */
			if (completed == TRUE)
				string_addr->string_color = COLOR_GREY2;
			else 
				string_addr->string_color = COLOR_BLACK;
			/* Set up string bounds */
			
			if (max_rows_on_display == TO_DO_LIST_SFONT_NUM_OF_ROW)
			{
				string_addr->text_font = SMALL_FONT;
				string_addr->bounds.width = TO_DO_LIST_SCOLUMN;
			}
			else
			{
				string_addr->text_font = MEDIUM_FONT;
				string_addr->bounds.width = TO_DO_LIST_LCOLUMN;
			}
			
			if (byte_read > MAX_TEXT_ON_DISPLAY)
				buffer[MAX_TEXT_ON_DISPLAY] = '\0';
			
			StringSetText(cell_ui_id,buffer);
			qfree(buffer);
			cell++;
			/* Get the Schedule Date */
			DataGetField(tdl_dbid, rec_id, 4, &buffer, &byte_read);
			cell_ui_id = ((TableItems*)(table_addr->table_item_ptr[cell]))->table_item_ui_id;
			FormGetObjectPointer(cell_ui_id, &object_type, (void **)&string_addr);
			string_addr->string_attr.string_visible = TRUE;
			string_addr->bounds.height = table_addr->table_row_height[1];
			
			if (buffer[0] != '0')
			{
				SySetupGetCountrySettings(&country);
				
				if (country.date_fmt == SYSETUP_DMY)
				{
					buffer[0] = buffer[8];
					buffer[1] = buffer[9];
					buffer[2] = buffer[7];
					/* Convert the date to the display format */
					if (buffer[5] == '0')
					{
						buffer[3] = buffer[6];
						buffer[4] = 0;
					}
					else
					{
						buffer[3] = buffer[5];
						buffer[4] = buffer[6];
						buffer[5] = 0;
					}
				}
				else 
				{
					if (buffer[5] == '0')
					{
						buffer[0] = buffer[6];
						buffer[1] = buffer[7];
						buffer[2] = buffer[8];
						buffer[3] = buffer[9];
						buffer[4] = 0;
					}
					else
					{
						buffer[0] = buffer[5];
						buffer[1] = buffer[6];
						buffer[2] = buffer[7];
						buffer[3] = buffer[8];
						buffer[4] = buffer[9];
						buffer[5] = 0;
					}
				}
			}
			else 
				buffer[0] = 0;
			/* Set up string bounds */
			if (completed == TRUE)
				string_addr->string_color = COLOR_GREY2;
			else 
				string_addr->string_color = COLOR_BLACK;
			
			if (max_rows_on_display == TO_DO_LIST_SFONT_NUM_OF_ROW)
				string_addr->text_font = SMALL_FONT;
			else
				string_addr->text_font = MEDIUM_FONT;
			
			StringSetText(cell_ui_id,buffer);
			qfree(buffer);
			cell++;
			
			/* For Next Record */
			num_rows_to_display--;
			top_row_num++;
			row_count++;
			DataCloseRecord(tdl_dbid, rec_id);
		}
		else
		{
			count += TO_DO_BLOCK_SIZE;
			temp = temp->next;
		}
	}
	
	for (erase_count =row_count; erase_count < max_rows_on_display; erase_count++)
	{
		/* Disable column 0 */
		cell_ui_id = ((TableItems*)(table_addr->table_item_ptr[cell]))->table_item_ui_id;
		if (UISearchForAddress(cell_ui_id,&object_type,(void**)&ctl_addr) != TRUE)return ERR_UI_RES_NOT_FOUND;
		ctl_addr->control_attr.control_enable = FALSE;
		ctl_addr->control_attr.control_visible = FALSE;
		ctl_addr->control_attr.control_active = FALSE;
		cell++;
		/* Disable column 1 */
		((TableItems*)(table_addr->table_item_ptr[cell]))->table_item_ui_id = TO_DO_TONE_OFFSET + row_count;
		if (UISearchForAddress((TO_DO_TONE_OFFSET + row_count),&object_type,(void**)&bmp_addr) != TRUE) return ERR_UI_RES_NOT_FOUND;
		bmp_addr->bitmap_attr.bitmap_enable = FALSE;
		bmp_addr->bitmap_attr.bitmap_visible = FALSE;
		bmp_addr->bitmap_attr.bitmap_active = FALSE;
		cell++;
		/* Disable column 2 */
		cell_ui_id = ((TableItems*)(table_addr->table_item_ptr[cell]))->table_item_ui_id;
		if (UISearchForAddress(cell_ui_id,&object_type,(void**)&ctl_addr) != TRUE)return ERR_UI_RES_NOT_FOUND;
		ctl_addr->control_attr.control_enable = FALSE;
		ctl_addr->control_attr.control_visible = FALSE;
		ctl_addr->control_attr.control_active = FALSE;
		cell++;
		/* Disable column 3 */
		cell_ui_id = ((TableItems*)(table_addr->table_item_ptr[cell]))->table_item_ui_id;
		if (UISearchForAddress(cell_ui_id,&object_type,(void**)&string_addr) != TRUE)return ERR_UI_RES_NOT_FOUND;
		string_addr->string_attr.string_visible = FALSE;
		cell++;
		/* Disable column 4 */
		cell_ui_id = ((TableItems*)(table_addr->table_item_ptr[cell]))->table_item_ui_id;
		if (UISearchForAddress(cell_ui_id,&object_type,(void**)&string_addr) != TRUE)return ERR_UI_RES_NOT_FOUND;
		string_addr->string_attr.string_visible = FALSE;
		cell++;
		row_count++;
	}
	
	TableSetTopRowNum(table_display->table_id, 0);
	/* Number of rows displayed equals to Total number of rows */
	table_addr->table_num_row_display = table_display->num_rows_displayed;
	return TRUE;
}

/********************************************************
* Function:	ToDoDatabaseInit
* Purpose: 	This function is used to simulate and initialse the 
*			the datebase in the PDA.Try to preset some records in 
*			the database
* Scope:	application
* Input:	None
* Output:	None
* Return:	None
* Comment: 	This function should be called in the StartApplication() function.
*********************************************************/
void ToDoDatabaseInit()
{
#ifdef	PC_SIM
	RecordID rec_id;
	RecordID sound_id = 1002;
	
	SHORT i= 0;
	
	BYTE completed_items[15];
	BYTE alarm_status[15];
	BYTE priority[15];
	BYTE *to_do_contents[15];
	BYTE *schedule_date[15];
	BYTE *alarm_date[15];
	
	/* setting up data */
	for (i =0; i <15; i++)
	{
		completed_items[i] = INCOMPLETED;
		alarm_status[i] = VOICE_ALARM;
		priority[i] = 5;
	}
	alarm_status[1] = VOICE_NO_ALARM;
	///	priority[0] = 1;
	///	priority[1] = 5;
	///	priority[2] = 4;
	///	priority[3] = 3;
	///	priority[4] = 2;
	
	for (i =0; i <15; i++)
	{	
		to_do_contents[i] = (BYTE*)qmalloc(500*sizeof(BYTE));
		schedule_date[i]  = (BYTE*)qmalloc(16*sizeof(BYTE));
		alarm_date[i]  = (BYTE*)qmalloc(16*sizeof(BYTE));	
	}
	strcpy(to_do_contents[0],"1");
	strcpy(to_do_contents[1],"2");
	strcpy(to_do_contents[2],"3");
	strcpy(to_do_contents[3],"4");
	strcpy(to_do_contents[4],"5");
	strcpy(to_do_contents[5],"6");
	strcpy(to_do_contents[6],"7");
	strcpy(to_do_contents[7],"8");
	strcpy(to_do_contents[8],"9");
	strcpy(to_do_contents[9],"10");
	strcpy(to_do_contents[10],"11");
	strcpy(to_do_contents[11],"12");
	strcpy(to_do_contents[12],"13");
	strcpy(to_do_contents[13],"14");
	strcpy(to_do_contents[14],"15");
	
	strcpy(schedule_date[0],"1980/01/01");
	strcpy(schedule_date[1],"1981/02/01");
	strcpy(schedule_date[2],"1982/03/01");
	strcpy(schedule_date[3],"1983/04/01");
	strcpy(schedule_date[4],"1984/05/01");
	strcpy(schedule_date[5],"1980/01/01");
	strcpy(schedule_date[6],"1981/02/01");
	strcpy(schedule_date[7],"1982/03/01");
	strcpy(schedule_date[8],"1983/04/01");
	strcpy(schedule_date[9],"1984/05/01");
	strcpy(schedule_date[10],"1980/01/01");
	strcpy(schedule_date[11],"1981/02/01");
	strcpy(schedule_date[12],"1982/03/01");
	strcpy(schedule_date[13],"1983/04/01");
	strcpy(schedule_date[14],"1984/05/01");
	
	strcpy(alarm_date[0],"1999/03/19");
    strcpy(alarm_date[1],"1999/03/19");
    strcpy(alarm_date[2],"2000/01/20");
    strcpy(alarm_date[3],"1999/04/02");
    strcpy(alarm_date[4],"1999/04/03");
	strcpy(alarm_date[5],"1999/03/19");
    strcpy(alarm_date[6],"1999/03/19");
    strcpy(alarm_date[7],"2000/01/20");
    strcpy(alarm_date[8],"1999/04/02");
    strcpy(alarm_date[9],"1999/04/03");
	strcpy(alarm_date[10],"1999/03/19");
    strcpy(alarm_date[11],"1999/03/19");
    strcpy(alarm_date[12],"2000/01/20");
    strcpy(alarm_date[13],"1999/04/02");
    strcpy(alarm_date[14],"1999/04/03");
	
	/* New Database */
	DataNewDB(TODODB,1,TODOAPP,&tdl_dbid);
	/* Open Database and sort by priority */
	DataOpenDB(tdl_dbid,SORT_TEXT_MODE | 2,OPEN_RW);
	/* Open Database */
	for (i =0;i<15;i++)
	{
		DataNewRecord(tdl_dbid, 0x00, TO_DO_LIST_NUM_FIELD, &rec_id);
		DataWriteField(tdl_dbid,rec_id,0,12,(BYTE*) &completed_items[i]);
		DataWriteField(tdl_dbid,rec_id,1,1,(BYTE*) &alarm_status[i]);
		DataWriteField(tdl_dbid,rec_id,2,12,(BYTE*) &priority[i]);
		DataWriteField(tdl_dbid,rec_id,3,(strlen(to_do_contents[i]) + 1),to_do_contents[i]);
		DataWriteField(tdl_dbid,rec_id,4,(strlen(schedule_date[i]) + 1),schedule_date[i]);
		DataWriteField(tdl_dbid,rec_id,5,(strlen(alarm_date[i]) + 1),alarm_date[i]);
		DataWriteField(tdl_dbid,rec_id,6,4,(BYTE*) &sound_id);
		DataCloseRecord(tdl_dbid,rec_id);
	}
	
	for (i =0; i <15; i++)
	{
		qfree(to_do_contents[i]);
		qfree(schedule_date[i]);
		qfree(alarm_date[i]);
	}
#endif
}

/********************************************************
* Function:	TableDisplayInsertRecordID
* Purpose: 	This function is called in order to insert a record ID
*			to the Table Display
* Scope:	application
* Input:	table_display	table_display structure
*			record_id		record_id being inserted
* Output:	None
* Return:	None
* Comment: 	None
*********************************************************/
void TableDisplayInsertRecordID(TableDisplay *table_display, RecordID record_id, DatabaseID dbid)
{
	USHORT i;
	BOOLEAN create = FALSE;
	RecordIDBlock *temp;
	
	if (table_display->record_id_block == NULL)
	{
		table_display->record_id_block = (RecordIDBlock*)qmalloc(sizeof(RecordIDBlock));
		temp = table_display->record_id_block;
		create = TRUE;
	}
	else
	{
		temp = table_display->record_id_block;
		while (temp != NULL)
		{	/* if the current block is full, create another one and pointer to the new block */
			if (temp->num_records != TO_DO_BLOCK_SIZE)
				break;
			if (temp->next == NULL)
			{
				create = TRUE;
				temp ->next = (RecordIDBlock*)qmalloc(sizeof(RecordIDBlock));
				temp = temp->next;
				break;
			}
			else temp = temp->next;
		}
	}
	
	if (create == TRUE)
	{
		temp->next = NULL;
		temp->num_records = 0;
		for (i = 0; i<20; i++)
			temp->record_id[i] = 0;
	}	
	temp->num_records++;
	table_display->total_num_rows++;
	temp->record_id[temp->num_records - 1] = record_id;
	temp->dbid[temp->num_records -1] = dbid;
}

/********************************************************
* Function:	TableDisplayDelete
* Purpose: 	This function is called in order to insert a record ID
* Scope:	application
* Input:	table_display	table_display structure
*			record_id		record_id being inserted
* Output:	None
* Return:	TRUE    handled
*			FALSE   not-handled
* Comment: 	None
*********************************************************/
BOOLEAN TableDisplayDeleteAllRecordID(TableDisplay *table_display)
{
	RecordIDBlock *temp = table_display->record_id_block;
	RecordIDBlock *temp1 = NULL;
	
	if (temp != NULL)
	{
		temp1 = temp->next;
		if (temp1 == NULL)
		{
			qfree(temp);
			table_display->num_rows_displayed = 0;
			table_display->total_num_rows = 0;
			table_display->top_row_num = 0;
			table_display->record_id_block = NULL;
			return TRUE;
		}
		while (temp1 != NULL)
		{
			qfree(temp);
			temp = temp1;
			temp1 = temp->next;
		}
		if (temp1 == NULL)
			qfree(temp);
	}
	table_display->num_rows_displayed = 0;
	table_display->total_num_rows = 0;
	table_display->top_row_num = 0;
	table_display->record_id_block = NULL;
	return TRUE;
}

/********************************************************
* Function:	ToDoRecordToTable
* Purpose: 	This function is used to show the correct records to 
*			the table objects in the TO DO LIST page of the application
* Scope:	application
* Input:	dbid			The database ID
*			starting_char	The starting character
*			starting_string
* Output:	None
* Return:	TRUE		Complete
*			FALSE		Error
* Comment: 	The table object must be initialised first
*			The database must be opened first
*			The function will update the scrollbar too
**********************************************************/
void ToDoRecordToTable(DatabaseID dbid, BYTE sorted_by)
{
	ObjectID	form_id;
	RecordID	*sort_table, *priority_table, rec_id;
	BYTE		*date_buffer, *previous_date_buffer, object_type;
	UWORD		top_record, rec_num, byte_read, total_num_rec;
	UWORD		i, current_pos=0, count =0;
	BOOLEAN		same_date = FALSE;
	Table		*table_addr;
	Control		*ctl_addr;
	
	
	if (sorted_by == PRIORITY)
	{
		DataCloseDB(tdl_dbid);
		DataOpenDB(tdl_dbid, SORT_TEXT_MODE | 2, OPEN_RW);
	}
	else if (sorted_by == COMPLETED_ITEMS)
	{
		DataCloseDB(tdl_dbid);
		DataOpenDB(tdl_dbid, SORT_TEXT_MODE | 0, OPEN_RW);
	}
	else
	{
		DataCloseDB(tdl_dbid);
		DataOpenDB(tdl_dbid, SORT_TEXT_MODE | 4, OPEN_RW);
	}
	
	TableDisplayDeleteAllRecordID(&to_do_list);
	DataTotalRecord(tdl_dbid, &total_num_rec);
	
	if (total_num_rec > 1)
	{
		FormGetObjectPointer(BUTTON_TO_DO_SORT_RECORD, &object_type, (void **)&ctl_addr);
		ctl_addr->control_attr.control_visible = TRUE;
		ctl_addr->control_attr.control_enable = TRUE;
	}
	else
	{
		FormGetObjectPointer(BUTTON_TO_DO_SORT_RECORD, &object_type, (void **)&ctl_addr);
		ctl_addr->control_attr.control_visible = FALSE;
		ctl_addr->control_attr.control_enable = FALSE;
	}
	
	if (total_num_rec != 0)
	{
		for (i=0; i <total_num_rec; i++)
		{
			DataNumtoRecID(tdl_dbid, i, &rec_id);
			TableDisplayInsertRecordID(&to_do_list, rec_id, tdl_dbid);
		}
		if (app_status.rec_id != 0)
		{
			DataRecIDtoNum(tdl_dbid, app_status.rec_id, &rec_num);
			if (total_num_rec < TO_DO_LIST_NUM_OF_ROW)
				top_record = 0;
			else
			{	/* If the record place in the last page */
				if ((rec_num+1) + TO_DO_LIST_NUM_OF_ROW > total_num_rec)
					top_record = total_num_rec - TO_DO_LIST_NUM_OF_ROW;
				else
					top_record = rec_num;
			}
		}
		else
			top_record = 0;
		
		ToDoListSetTableTopRowNum(sorted_by, top_record);
		FormGetActiveFormID(&form_id);
		if (form_id != FORM_TO_DO_PREF)
			ToDoListSetScrollbar();
	}
	else
	{
		FormGetObjectPointer(TABLE_TO_DO_LIST, &object_type, (void **)&table_addr);
		table_addr->table_attr.table_visible = FALSE;
		ScrollbarSetScrollbarVisible(SCROLLBAR_TO_DO_LIST,FALSE);
		ScrollbarEraseScrollbar(SCROLLBAR_TO_DO_LIST);
	}
}

/********************************************************
* Function:	ToDoListSetTableTopRowNum
* Purpose: 	This function is called to set the top row number
*			of the table object
* Scope:	application
* Input:	BYTE				the starting_char
* Output:	None
* Return:	TRUE			display of table is on
*			FALSE			display of table is off
* Comment: 	The top row number of the table objects are set
*********************************************************/
BOOLEAN ToDoListSetTableTopRowNum(BYTE sorted_by, UWORD top_record)
{
	USHORT total_num_rows;
	BOOLEAN enable,drawn,active,visible,set_scroll;
	
	total_num_rows = to_do_list.total_num_rows;
	to_do_list.top_row_num = (USHORT)top_record;
	
	ToDoTableDisplayDraw(&to_do_list);
	TableGetAttributes(TABLE_TO_DO_LIST, &enable, &drawn, &active, &visible, &set_scroll);
	TableSetAttributes(TABLE_TO_DO_LIST, enable, drawn, active, TRUE, set_scroll);
	ToDoListSetScrollbar();
	return TRUE;
}

/********************************************************
* Function:	ToDoListDatabaseChecking
* Purpose: 	This function is called to check whether the required database 
is already exist or not. If not, it will creat it
* Scope:		application/internal
* Input:		None
* Output:		None
* Return:		None
* Comment: 	None
*********************************************************/
void ToDoListDatabaseChecking()
{
	BYTE application_status, sorted_by, create_font = SMALL_FONT;
	
	if (DataFindDB(TODODB, &tdl_dbid) != TRUE)
	{
		/* New Database */
		DataNewDB(TODODB,1,TODOAPP,&tdl_dbid);
		DataOpenDB(tdl_dbid,SORT_TEXT_MODE | 2,OPEN_RW);
		/* Create status record */
		DataNewRecordWithID(tdl_dbid, TDL_STATUS, 0, 1);
		//DataNewRecordWithID(tdl_dbid, TDL_EDIT_INFO, 0, 33);
		DataNewRecordWithID(tdl_dbid, TDL_EDIT_INFO, 0, 34);
		application_status = RESTART_TO_DO_LIST;
		DataWriteField(tdl_dbid, TDL_STATUS, 0, 1, &application_status);
		DataWriteField(tdl_dbid, TDL_EDIT_INFO, 29, 1, (BYTE*)&create_font);
	}
	else if (DataIsDBOpen(tdl_dbid, NULL, NULL) == FALSE)
	{
		DataOpenDB(tdl_dbid,SORT_TEXT_MODE | 2,OPEN_RW);
	}
	
	if (DataRecordInfo(tdl_dbid, TDL_STATUS, NULL, NULL, NULL, NULL, NULL) != TRUE)
	{
		DataNewRecordWithID(tdl_dbid, TDL_STATUS, 0, 1);
		application_status = RESTART_TO_DO_LIST;
		DataWriteField(tdl_dbid, TDL_STATUS, 0, 1, &application_status);
	}
	
	if (DataRecordInfo(tdl_dbid, TDL_EDIT_INFO, NULL, NULL, NULL, NULL, NULL) != TRUE)
	{
		//DataNewRecordWithID(tdl_dbid, TDL_EDIT_INFO, 0, 33);
		DataNewRecordWithID(tdl_dbid, TDL_EDIT_INFO, 0, 34);
		
		sorted_by = PRIORITY;
		DataWriteField(tdl_dbid, TDL_EDIT_INFO, 11, 1, (BYTE*)&sorted_by);
		DataWriteField(tdl_dbid, TDL_EDIT_INFO, 29, 1, (BYTE*)&create_font);
		
		alarm_settings.dbid = tdl_dbid;
		alarm_settings.temp_recid = 0;
		alarm_settings.play_pause_frame = 0;
		alarm_settings.play_stop = TRUE;
		alarm_settings.rec_stop = TRUE;
		alarm_settings.recorded = FALSE;
		
		DataWriteField(tdl_dbid, TDL_EDIT_INFO, 33, sizeof(AlarmSettings), (BYTE*)&alarm_settings);
	}
}

/********************************************************
* Function:	ToDoListAppRestore
* Purpose: 	This function is called to restore the data 
*			in the application when it is called to stopped
* Scope:	application/Internal 
* Input:	restart			whether the application is restart or not
* Output:	None
* Return:	TRUE			if handled
*			FALSE			if not handled
* Comment: 	None
*********************************************************/
void ToDoListAppRestore(BOOLEAN restart)
{
	BYTE		application_status, object_type;
	BYTE		sorted_by, *buffer, text_buffer[15];
	UWORD		byte_read, rec_num;
	Form		*form_addr;
	BYTE		*ptr = text_buffer;
	
	
	
	/* Global variables initialisation */
	pressed_object1 = 0;
	pressed_object2 = 0;
	pen_down = FALSE;
	edit_change = FALSE;
	ToDoListDatabaseChecking();
	
	if (restart == TRUE)
	{
		application_status = RESTART_TO_DO_LIST;
	}
	else
	{
		DataGetField(tdl_dbid, TDL_STATUS, 0, &buffer, &byte_read);
		application_status = *buffer;
		qfree(buffer);
	}
	
    if (MemoryCheckMemLow())
		entry_low_memory = TRUE;
    else
		entry_low_memory = FALSE;
	
    if (application_status == RESTART_TO_DO_NEW)
		entry_old_edit = TRUE;
	else 
		entry_old_edit = FALSE;
	
    DataGetField(tdl_dbid, TDL_EDIT_INFO, 33, &buffer, &byte_read);
    alarm_settings = *(AlarmSettings*)buffer;
    qfree(buffer);
	
	/* Allocate global variable */
	if(tdl_field_buffer != NULL)
		qfree(tdl_field_buffer);
	
	tdl_field_buffer = (BYTE**)qmalloc(1*sizeof(BYTE*));
	tdl_field_buffer[0] = 0;
	
	DataGetField(tdl_dbid, TDL_EDIT_INFO, 11, &buffer, &byte_read);
	sorted_by = (BYTE)(*buffer);
	qfree(buffer);
	
	DataGetField(tdl_dbid, TDL_EDIT_INFO, 29, &buffer, &byte_read);
	table_font = (BYTE)(*buffer);
	qfree(buffer);
	
	if (application_status == RESTART_TO_DO_VIEWING)
	{
		DataGetField(tdl_dbid, TDL_EDIT_INFO, 17, &buffer, &byte_read);
		chk_status.completed_status = (BYTE)(*buffer);
		qfree(buffer);
		
		DataGetField(tdl_dbid, TDL_EDIT_INFO, 18, &buffer, &byte_read);
		chk_status.alarm_status = (BYTE)(*buffer);
		qfree(buffer);
		
		DataGetField(tdl_dbid, TDL_EDIT_INFO, 19, &buffer, &byte_read);
		chk_status.priority_status = (BYTE)(*buffer);
		qfree(buffer);
		
		DataGetField(tdl_dbid, TDL_EDIT_INFO, 20, &buffer, &byte_read);
		chk_status.sch_year = *(SHORT*)(buffer);
		qfree(buffer);
		
		DataGetField(tdl_dbid, TDL_EDIT_INFO, 21, &buffer, &byte_read);
		chk_status.sch_month = *(SHORT*)(buffer);
		qfree(buffer);
		
		DataGetField(tdl_dbid, TDL_EDIT_INFO, 22, &buffer, &byte_read);
		chk_status.sch_day = *(SHORT*)(buffer);
		qfree(buffer);
		
		DataGetField(tdl_dbid, TDL_EDIT_INFO, 23, &buffer, &byte_read);
		chk_status.alarm_year = *(SHORT*)(buffer);
		qfree(buffer);
		
		DataGetField(tdl_dbid, TDL_EDIT_INFO, 24, &buffer, &byte_read);
		chk_status.alarm_month = *(SHORT*)(buffer);
		qfree(buffer);
		
		DataGetField(tdl_dbid, TDL_EDIT_INFO, 25, &buffer, &byte_read);
		chk_status.alarm_day = *(SHORT*)(buffer);
		qfree(buffer);
	}
	
	if (FormGetObjectPointer(FORM_TO_DO_LIST, &object_type, (void **)&form_addr)
		== ERR_UI_RES_NOT_FOUND)
		FormInitAllFormObjects(FORM_TO_DO_LIST);
	
	if (application_status == RESTART_TO_DO_LIST || application_status == RESTART_TO_DO_DATE)
	{
		ToDoSetTableFont();
		ToDoRecordToTable(tdl_dbid,sorted_by);
		FormPopupForm(FORM_TO_DO_LIST);	
	}
	else if (application_status == RESTART_TO_DO_VIEWING || application_status == RESTART_TO_DO_NEW)
	{
		/* Restore application status */
		DataGetField(tdl_dbid, TDL_EDIT_INFO, 0, &buffer, &byte_read);
		app_status.rec_id = *(RecordID*)buffer;
		qfree(buffer);
		
		DataGetField(tdl_dbid, TDL_EDIT_INFO, 1, &buffer, &byte_read);
		app_status.completed_status = (BYTE)(*buffer);
		qfree(buffer);
		
		DataGetField(tdl_dbid, TDL_EDIT_INFO, 2, &buffer, &byte_read);
		app_status.alarm_status = (BYTE)(*buffer);
		qfree(buffer);
		
		DataGetField(tdl_dbid, TDL_EDIT_INFO, 3, &buffer, &byte_read);
		app_status.priority_status = (BYTE)(*buffer);
		qfree(buffer);
		
		DataGetField(tdl_dbid, TDL_EDIT_INFO, 4, &buffer, &byte_read);
		app_status.sch_year = *(SHORT*)buffer;
		qfree(buffer);
		
		DataGetField(tdl_dbid, TDL_EDIT_INFO, 5, &buffer, &byte_read);
		app_status.sch_month = *(SHORT*)(buffer);
		qfree(buffer);
		
		DataGetField(tdl_dbid, TDL_EDIT_INFO, 6, &buffer, &byte_read);
		app_status.sch_day = *(SHORT*)(buffer);
		qfree(buffer);
		
		DataGetField(tdl_dbid, TDL_EDIT_INFO, 7, &buffer, &byte_read);
		app_status.alarm_year = *(SHORT*)(buffer);
		qfree(buffer);
		
		DataGetField(tdl_dbid, TDL_EDIT_INFO, 8, &buffer, &byte_read);
		app_status.alarm_month = *(SHORT*)(buffer);
		qfree(buffer);
		
		DataGetField(tdl_dbid, TDL_EDIT_INFO, 9, &buffer, &byte_read);
		app_status.alarm_day = *(SHORT*)(buffer);
		qfree(buffer);
		
		DataGetField(tdl_dbid, TDL_EDIT_INFO, 10, &buffer, &byte_read);
		app_status.edit_mode = (BYTE)(*buffer);
		qfree(buffer);
		
		DataGetField(tdl_dbid, TDL_EDIT_INFO, 11, &buffer, &byte_read);
		app_status.new_sort_mode = (BYTE)(*buffer);
		qfree(buffer);
		/* Restore Global Variables */
		DataGetField(tdl_dbid, TDL_EDIT_INFO, 12, &buffer, &byte_read);
		pressed_object1 = (BYTE)(*buffer);
		qfree(buffer);
		
		DataGetField(tdl_dbid, TDL_EDIT_INFO, 13, &buffer, &byte_read);
		pressed_object2 = (BYTE)(*buffer);
		qfree(buffer);
		
		DataGetField(tdl_dbid, TDL_EDIT_INFO, 14, &buffer, &byte_read);
		alarm_date = (BYTE)(*buffer);
		qfree(buffer);
		
		DataGetField(tdl_dbid, TDL_EDIT_INFO, 15, &buffer, &byte_read);
		detail_date = (BYTE)(*buffer);
		qfree(buffer);
		
		DataGetField(tdl_dbid, TDL_EDIT_INFO, 26, &buffer, &byte_read);
		chk_status.field_change = (BOOLEAN)(*buffer);
		qfree(buffer);
		
		DataGetField(tdl_dbid, TDL_EDIT_INFO, 27, &buffer, &byte_read);
		show_line = (BYTE)(*buffer);
		qfree(buffer);
		
		DataGetField(tdl_dbid, TDL_EDIT_INFO, 31, &buffer, &byte_read);
		field_top_line = *(UWORD*)buffer;
		qfree(buffer);
		
		DataGetField(tdl_dbid, TDL_EDIT_INFO, 32, &buffer, &byte_read);
		field_insert_pt_pos = *(UWORD*)buffer;
		qfree(buffer);
		/* Restore field_buffers */
		DataGetField(tdl_dbid, TDL_EDIT_INFO, 16, &buffer, &byte_read);			
		tdl_field_buffer[0] = (BYTE*)qmalloc((strlen(buffer) + 1)*sizeof(BYTE));
		strcpy(tdl_field_buffer[0], buffer);
		qfree(buffer);
		
		/* Check if the record id is no longer exist */
		if (DataRecIDtoNum(tdl_dbid, app_status.rec_id, &rec_num) != TRUE && application_status != RESTART_TO_DO_NEW)
		{
			if (FormGetObjectPointer(FORM_TO_DO_NEW, &object_type, (void **)&form_addr)
				== ERR_UI_RES_NOT_FOUND)
				FormInitAllFormObjects(FORM_TO_DO_NEW);
			
			application_status = RESTART_TO_DO_NEW;
			ToDoNewSetUpVariable();
		}
		if (application_status == RESTART_TO_DO_VIEWING)
		{
			DataGetField(tdl_dbid, TDL_EDIT_INFO, 30, &buffer, &byte_read);
			app_status.sound_rec_id = *(RecordID*)buffer;
			qfree(buffer);
			
			if (FormGetObjectPointer(FORM_TO_DO_VIEWING, &object_type, (void **)&form_addr)
				== ERR_UI_RES_NOT_FOUND)
				FormInitAllFormObjects(FORM_TO_DO_VIEWING);
			
			ToDoViewingSetUpScreen();
			/* Disable the field object */
			FormPopupForm(FORM_TO_DO_VIEWING);
		}
		else
		{
			DataGetField(tdl_dbid, TDL_EDIT_INFO, 28, &buffer, &byte_read);
			chk_status.new_entry_hit = (BYTE)(*buffer);
			qfree(buffer);
			
			if (FormGetObjectPointer(FORM_TO_DO_NEW, &object_type, (void **)&form_addr)
				== ERR_UI_RES_NOT_FOUND)
				FormInitAllFormObjects(FORM_TO_DO_NEW);
			
			if (detail_date == NO_DUE_DATE)
			{
				strcpy(text_buffer,TODO_NO_DUE_DATE);
				ControlSetLabel(POPUP_TRIGGER_DETAILS_DATE,text_buffer);
			}
			else
			{
				ToDoPackDueDate(ptr,app_status.sch_year,app_status.sch_month,app_status.sch_day);
				ControlSetLabel(POPUP_TRIGGER_DETAILS_DATE,text_buffer);
			}
			FieldSetText(FIELD_TO_DO_NEW, tdl_field_buffer[0]);
			/* Set up Field Size */
			FieldSetFont(FIELD_TO_DO_NEW, table_font);
			FormPopupForm(FORM_TO_DO_NEW);
			if (entry_low_memory)
			{
				low_memory_form_id = FORM_TO_DO_LIST;
				FormPopupForm(FORM_SYSTEM_LOW_MEM);	
			}
		}
	}
}

/********************************************************
* Function:	ToDoListAppSave()
* Purpose: 	This function is called to save the data in 
*			the application when it is called to stopped
* Scope:	application/internal
* Input:	None
* Output:	None
* Return:	TRUE if handled
*			FALSE if not handled
* Comment: 	None
*********************************************************/
void ToDoListAppSave()
{	
	BYTE        byte_value, object_type;
	BYTE		*temp_field_buffer;
	SHORT		short_value, temp_month;
	Form        *form_addr;
	Field		*fld_addr;
	
    SndStop();
	
	ToDoListDatabaseChecking();
	
	if (DataRecordInfo(tdl_dbid, TDL_STATUS, NULL, NULL, NULL, NULL, NULL) != TRUE)
		DataNewRecordWithID(tdl_dbid, TDL_STATUS, 0, 1);
	if (DataRecordInfo(tdl_dbid, TDL_EDIT_INFO, NULL, NULL, NULL, NULL, NULL) != TRUE)
		DataNewRecordWithID(tdl_dbid, TDL_EDIT_INFO, 0, 34);
	
	DataWriteField(tdl_dbid, TDL_STATUS, 0, 1, &restart_form);
	DataWriteField(tdl_dbid, TDL_EDIT_INFO, 33, sizeof(AlarmSettings), (BYTE*)&alarm_settings);
	
	if (alarm_set_by == ALARM_DUE_DATE)
	{
		app_status.alarm_year = app_status.sch_year;
		app_status.alarm_month = app_status.sch_month;
		app_status.alarm_day = app_status.sch_day;
	}
	else if (alarm_set_by == ALARM_BEFORE_DUE_DATE)
	{
		app_status.alarm_year = app_status.sch_year;
		temp_month = app_status.sch_month -1;
		app_status.alarm_day = app_status.sch_day;
		
		RtcDaysShift(&app_status.alarm_year, &temp_month, &app_status.alarm_day,-1);
		app_status.alarm_month = temp_month + 1;
	}
	else if (alarm_set_by == NO_ALARM_DATE)
	{
		app_status.alarm_status = NO_ALARM;
		app_status.alarm_year = 0;
		app_status.alarm_month = 0;
		app_status.alarm_day = 0;
	}
	
	/* app_status */
	DataWriteField(tdl_dbid, TDL_EDIT_INFO, 0, 4, (BYTE*)&app_status.rec_id);
	
	byte_value = (BYTE)(app_status.completed_status);
	DataWriteField(tdl_dbid, TDL_EDIT_INFO, 1, 1, (BYTE*)&byte_value);
	
	byte_value = (BYTE)(app_status.alarm_status);
	DataWriteField(tdl_dbid, TDL_EDIT_INFO, 2, 1, (BYTE*)&byte_value);
	
	byte_value = (BYTE)(app_status.priority_status);
	DataWriteField(tdl_dbid, TDL_EDIT_INFO, 3, 1, (BYTE*)&byte_value);
	
	short_value = app_status.sch_year;
	DataWriteField(tdl_dbid, TDL_EDIT_INFO, 4, 2, (BYTE*)&short_value);
	
	short_value = app_status.sch_month;
	DataWriteField(tdl_dbid, TDL_EDIT_INFO, 5, 2, (BYTE*)&short_value);
	
	short_value = app_status.sch_day;
	DataWriteField(tdl_dbid, TDL_EDIT_INFO, 6, 2, (BYTE*)&short_value);
	
	short_value = app_status.alarm_year;
	DataWriteField(tdl_dbid, TDL_EDIT_INFO, 7, 2, (BYTE*)&short_value);
	
	short_value = app_status.alarm_month;
	DataWriteField(tdl_dbid, TDL_EDIT_INFO, 8, 2, (BYTE*)&short_value);
	
	short_value = app_status.alarm_day;
	DataWriteField(tdl_dbid, TDL_EDIT_INFO, 9, 2, (BYTE*)&short_value);
	
	byte_value = (BYTE)(app_status.edit_mode);
	DataWriteField(tdl_dbid, TDL_EDIT_INFO, 10, 1, (BYTE*)&byte_value);
	
	byte_value = (BYTE)(app_status.new_sort_mode);
	DataWriteField(tdl_dbid, TDL_EDIT_INFO, 11, 1, (BYTE*)&byte_value);
	
	byte_value = (BYTE)(pressed_object1);
	DataWriteField(tdl_dbid, TDL_EDIT_INFO, 12, 1, (BYTE*)&byte_value);
	
	byte_value = (BYTE)(pressed_object2);
	DataWriteField(tdl_dbid, TDL_EDIT_INFO, 13, 1, (BYTE*)&byte_value);
	
	byte_value = (BYTE)(alarm_date);
	DataWriteField(tdl_dbid, TDL_EDIT_INFO, 14, 1, (BYTE*)&byte_value);
	
	byte_value = (BYTE)(detail_date);
	DataWriteField(tdl_dbid, TDL_EDIT_INFO, 15, 1, (BYTE*)&byte_value);
	
	byte_value = (BYTE)(show_line);
	DataWriteField(tdl_dbid, TDL_EDIT_INFO, 27, 1, (BYTE*)&byte_value);
	DataWriteField(tdl_dbid, TDL_EDIT_INFO, 29, 1, (BYTE*)&table_font);
	
	if (restart_form == RESTART_TO_DO_NEW)
	{
		if (FormGetObjectPointer(FORM_TO_DO_NEW, &object_type, (void **)&form_addr)
			== ERR_UI_RES_NOT_FOUND)
			FormInitAllFormObjects(FORM_TO_DO_NEW);
		
		FieldGetTextPointer(FIELD_TO_DO_NEW, &temp_field_buffer);
	}
	else
	{
		if (FormGetObjectPointer(FORM_TO_DO_VIEWING, &object_type, (void **)&form_addr)
			== ERR_UI_RES_NOT_FOUND)
			FormInitAllFormObjects(FORM_TO_DO_VIEWING);
		
		FieldGetTextPointer(FIELD_TO_DO_VIEWING, &temp_field_buffer);
	}
	
	if(tdl_field_buffer != NULL) 
	{
		if(tdl_field_buffer[0] != 0)
			qfree(tdl_field_buffer[0]);
		qfree(tdl_field_buffer);
	}
	
	tdl_field_buffer = (BYTE**)qmalloc(1*sizeof(BYTE*));
	tdl_field_buffer[0] = (BYTE*)qmalloc((strlen(temp_field_buffer) + 1)*sizeof(BYTE));
	strcpy(tdl_field_buffer[0],temp_field_buffer);
	
	if (tdl_field_buffer == NULL)
		DataWriteField(tdl_dbid, TDL_EDIT_INFO, 16, 1, (BYTE*)(""));
	else
		DataWriteField(tdl_dbid, TDL_EDIT_INFO, 16, (strlen(tdl_field_buffer[0]) + 1), tdl_field_buffer[0]);
	
	DataWriteField(tdl_dbid, TDL_EDIT_INFO, 17, 1, (BYTE*)&chk_status.completed_status);
	DataWriteField(tdl_dbid, TDL_EDIT_INFO, 18, 1, (BYTE*)&chk_status.alarm_status);
	DataWriteField(tdl_dbid, TDL_EDIT_INFO, 19, 1, (BYTE*)&chk_status.priority_status);
	DataWriteField(tdl_dbid, TDL_EDIT_INFO, 20, 2, (BYTE*)&chk_status.sch_year);
	DataWriteField(tdl_dbid, TDL_EDIT_INFO, 21, 2, (BYTE*)&chk_status.sch_month);
	DataWriteField(tdl_dbid, TDL_EDIT_INFO, 22, 2, (BYTE*)&chk_status.sch_day);
	DataWriteField(tdl_dbid, TDL_EDIT_INFO, 23, 2, (BYTE*)&chk_status.alarm_year);
	DataWriteField(tdl_dbid, TDL_EDIT_INFO, 24, 2, (BYTE*)&chk_status.alarm_month);
	DataWriteField(tdl_dbid, TDL_EDIT_INFO, 25, 2, (BYTE*)&chk_status.alarm_day);
	DataWriteField(tdl_dbid, TDL_EDIT_INFO, 26, 1, (BYTE*)&chk_status.field_change);
	DataWriteField(tdl_dbid, TDL_EDIT_INFO, 28, 1, (BYTE*)&chk_status.new_entry_hit);
	
	DataWriteField(tdl_dbid, TDL_EDIT_INFO, 30, 4, (BYTE*)&app_status.sound_rec_id);
	
	if (restart_form == RESTART_TO_DO_VIEWING)
	{
		FieldGetTopLineNum(FIELD_TO_DO_VIEWING, &field_top_line);
		FieldGetInsertPointPosition(FIELD_TO_DO_VIEWING, &field_insert_pt_pos);
	}
	else if (restart_form == RESTART_TO_DO_NEW)
	{
		FormGetObjectPointer(FIELD_TO_DO_NEW, &object_type, (void **)&fld_addr);
		fld_addr->field_attr.field_insert_pt_visible = TRUE;
		
		FieldGetTopLineNum(FIELD_TO_DO_NEW, &field_top_line);
		FieldGetInsertPointPosition(FIELD_TO_DO_NEW, &field_insert_pt_pos);
	}
	
	DataWriteField(tdl_dbid, TDL_EDIT_INFO, 31, 4, (BYTE*)&field_top_line);
	DataWriteField(tdl_dbid, TDL_EDIT_INFO, 32, 4, (BYTE*)&field_insert_pt_pos);
	DataCloseDB(tdl_dbid);
}

/********************************************************
* Function:	ToDoSetAllRecordsAlarm()
* Purpose: 	This function is called to set up the alarm 
*			manager
* Scope:	application/internal
* Input:	None
* Output:	None
* Return:	TRUE if handled
*			FALSE if not handled
* Comment: 	None
*********************************************************/
void ToDoSetAllRecordsAlarm(UWORD rec_num)
{
	RecordID		rec_id;
	AlarmEvent 		alarm_evt;
	AppID			app_id;
	BYTE			*alarm_buffer, *alarm_type, alarm_date[11];
	BYTE			*text_buffer, *alarm_first_type, *sound_rec_id;
	UWORD			byte_read, total_num_rec;
	Err				result = TRUE;
	AlarmExtraInfo  *extra_info;
	
	app_id = SysGetActiveAppID();
	DataCloseDB(tdl_dbid);
	DataOpenDB(tdl_dbid, SORT_TEXT_MODE | 5, OPEN_RW);
	DataTotalRecord(tdl_dbid, &total_num_rec);
	
	AlarmDelAppEvent(app_id);
	
	/* Search Records with same alarm date */
	while (rec_num < total_num_rec)
	{
		DataNumtoRecID(tdl_dbid, rec_num, &rec_id);
		DataOpenRecord(tdl_dbid, rec_num, &rec_id, NULL);
		DataGetField(tdl_dbid, rec_id, 5, &alarm_buffer, &byte_read);
		strcpy(alarm_date, alarm_buffer);
		alarm_date[4] = 0;
		alarm_evt.hit_time.year = (SHORT)atol((const char *)alarm_date);
		
		strcpy(alarm_date, alarm_buffer);
		alarm_date[0] = alarm_date[5];
		alarm_date[1] = alarm_date[6];
		alarm_date[2] = 0;
		alarm_evt.hit_time.mon = (SHORT)atol((const char *)alarm_date)-1;
		
		strcpy(alarm_date, alarm_buffer);
		alarm_date[0] = alarm_date[8];
		alarm_date[1] = alarm_date[9];
		alarm_date[2] = 0;
		alarm_evt.hit_time.mday = (SHORT)atol((const char *)alarm_date);
		
		DataGetField(tdl_dbid, rec_id, 1, &alarm_first_type, &byte_read);
		
		if (ToDoCompareAlarmDay(alarm_evt.hit_time.year, alarm_evt.hit_time.mon, alarm_evt.hit_time.mday) == TRUE &&
			(*alarm_first_type == VOICE_ALARM || *alarm_first_type == TONE_ALARM))
		{
			do
			{
				ToDoSoundDatabaseChecking();
				extra_info = (AlarmExtraInfo*) qmalloc(sizeof(AlarmExtraInfo));
				
				AlarmSetEventType(&alarm_evt, 0);
				AlarmSetEventClass(&alarm_evt, ALARM_ONDAY);
				
				alarm_evt.app = app_id;
				alarm_evt.dbid = tdl_dbid;
				alarm_evt.rec_id = rec_id;
				alarm_evt.reference = 0;
				DataGetField(tdl_dbid, rec_id, 3, &text_buffer, &byte_read);
				if (byte_read >= TO_DO_ALARM_MAX_TEXT)
					text_buffer[200] = 0;
				alarm_evt.alert_msg = text_buffer;
				alarm_evt.extra_info = extra_info;
				
				DataGetField(tdl_dbid, rec_id, 1, &alarm_type, &byte_read);
				if (*alarm_type == VOICE_ALARM)
				{
					extra_info->type = ALARM_VOICE;
					extra_info->dbid = alarm_settings.dbid;
					DataGetField(tdl_dbid, rec_id, 6, &sound_rec_id, &byte_read);
					extra_info->rec_id = *(RecordID *)sound_rec_id;
					extra_info->field_num = 0;
					qfree(sound_rec_id);
					AlarmAddEvent(alarm_evt);
				}
				else if (*alarm_type == TONE_ALARM)
				{
					extra_info->type = ALARM_TONE;
					extra_info->dbid = 0;
					extra_info->rec_id = 0;
					extra_info->field_num = 0;
					AlarmAddEvent(alarm_evt);
				}
				
				result = DataFindRecord(tdl_dbid, 5, ++rec_num, alarm_buffer, &rec_id);
				DataOpenRecord(tdl_dbid, rec_num, &rec_id, NULL);
				qfree(alarm_type);
				qfree(text_buffer);
				qfree(extra_info);
			}while (result != ERR_DATA_NOT_FOUND);
			break;
		}
		else
		{
			rec_num++;
		}
		qfree(alarm_buffer);
		qfree(alarm_first_type);
	}
	DataCloseDB(tdl_dbid);
}

/********************************************************
* Function:	ToDoDelAnAlarm()
* Purpose: 	This function is called to del an alarm 
* Scope:	application/internal
* Input:	None
* Output:	None
* Return:	TRUE if handled
*			FALSE if not handled
* Comment: 	None
*********************************************************/
void ToDoDelAnAlarm(RecordID rec_id)
{
	AlarmEvent 	alarm_evt;
	AppID		app_id;
	
	
	app_id = SysGetActiveAppID();
	alarm_evt.app = app_id;
	alarm_evt.reference = 0;
	
	AlarmSetEventType(&alarm_evt, 0);
	AlarmSetEventClass(&alarm_evt, ALARM_ONDAY);
	
	alarm_evt.rec_id = rec_id;
	AlarmDelEvent(alarm_evt);
}

/********************************************************
* Function:	ToDoSetNextRecordAlarm()
* Purpose: 	This function is called to set up the alarm 
*			manager
* Scope:	application/internal
* Input:	None
* Output:	None
* Return:	TRUE if handled
*			FALSE if not handled
* Comment: 	None
*********************************************************/
void ToDoSetNextRecordAlarm(RecordID alarmhit_rec_id)
{
	RecordID	rec_id;
	BYTE		*current_buffer, *next_buffer, *buffer, temp_buffer[20], new_alarm_status;
	UWORD		byte_read, rec_num, result, total_num_rec;
	
	DataCloseDB(tdl_dbid);
	DataOpenDB(tdl_dbid, SORT_TEXT_MODE | 5, OPEN_RW);
	DataTotalRecord(tdl_dbid, &total_num_rec);
	
	if (DataRecIDtoNum(tdl_dbid, alarmhit_rec_id, &rec_num) == TRUE)
	{
		result = DataOpenRecord(tdl_dbid, rec_num, &rec_id, NULL);
		result = DataGetField(tdl_dbid, rec_id, 5, &current_buffer, &byte_read);
		result = DataGetField(tdl_dbid, rec_id, 1, &buffer, &byte_read);
		if (*buffer == TONE_ALARM)
			new_alarm_status = NO_ALARM;
		else
			new_alarm_status = VOICE_NO_ALARM;
		
		DataWriteField(tdl_dbid, rec_id, 1, 1, &new_alarm_status);
		
		/* Search record alarm on different schedule */
		while (rec_num < (total_num_rec - 1))
		{
			if (DataOpenRecord(tdl_dbid, ++rec_num, &rec_id, NULL) == TRUE)
			{
				DataGetField(tdl_dbid, rec_id, 5, &next_buffer, &byte_read);
				strcpy((char *)temp_buffer, (char *)next_buffer);
				qfree(next_buffer);
				if (strcmp(current_buffer, temp_buffer) != SAME)
				{
					ToDoSetAllRecordsAlarm(rec_num);
					break;
				}
			}
		}
		qfree(current_buffer);
		qfree(buffer);
	}
	else
	{
		ToDoSetAllRecordsAlarm(0);
	}
}

/********************************************************
* Function:	ToDoCompareScheduleDay()
* Purpose: 	This function is called to set up the alarm 
*			manager
* Scope:	application/internal
* Input:	None
* Output:	None
* Return:	TRUE if handled
*			FALSE if not handled
* Comment: 	None
*********************************************************/
BOOLEAN ToDoCompareScheduleDay(DatabaseID dbid, RecordID rec_id, BOOLEAN shift)
{
	RTM			time;
	SHORT		sch_year, sch_month, sch_day, popup_item_num;
	UWORD		byte_read;
	BYTE		*buffer, text_buffer[10];
	SHORT		day_in_month;
	
	DataGetField(dbid, rec_id, 4, &buffer, &byte_read);
	text_buffer[0] = buffer[0];
	text_buffer[1] = buffer[1];
	text_buffer[2] = buffer[2];
	text_buffer[3] = buffer[3];
	text_buffer[4] = 0;
	sch_year = (SHORT)atol((const char *)text_buffer);
	/* Keep record With NO DUE DATE in anyway */
	if (sch_year == 0)
		return FALSE;
	
	text_buffer[0] = buffer[5];
	text_buffer[1] = buffer[6];
	text_buffer[2] = 0;
	sch_month = (SHORT)atol((const char *)text_buffer);
	
	text_buffer[0] = buffer[8];
	text_buffer[1] = buffer[9];
	text_buffer[2] = 0;
	sch_day = (SHORT)atol((const char *)text_buffer);
	qfree(buffer);
	
	RtcGetTime(&time);
	
	if (shift == TRUE)
	{
		ControlPopupGetSelectedItem(POPUP_TRIGGER_TO_DO_PURGE, &popup_item_num);
		
		if (popup_item_num == 0)
			RtcDaysShift(&time.year, &time.mon, &time.mday, -7);
		else if (popup_item_num == 1)
			RtcDaysShift(&time.year, &time.mon, &time.mday, -14);
		else if (popup_item_num == 2)
			RtcDaysShift(&time.year, &time.mon, &time.mday, -21);
		else if (popup_item_num == 3)
			RtcDaysShift(&time.year, &time.mon, &time.mday, -31);
	}
	
	if (sch_year < time.year)
		return TRUE;
	else if (sch_year > time.year)
		return FALSE;
	else
	{
		if (sch_month < time.mon + 1)
			return TRUE;
		else if (sch_month > time.mon +1)
			return FALSE;
		else
		{
			if (sch_day < time.mday)
				return TRUE;
			else
				return FALSE;
		}
	}
}

/********************************************************
* Function:	AnnCompareAlarmDay()
* Purpose: 	This function is called to set up the alarm 
*			manager
* Scope:	application/internal
* Input:	None
* Output:	None
* Return:	TRUE 	Add alarm
*		FALSE 	Not handled
* Comment: 	None
*********************************************************/
BOOLEAN ToDoCompareAlarmDay(USHORT input_year, USHORT input_month, USHORT input_day)
{
	RTM			time;
	
	RtcGetTime(&time);
	if (input_year < time.year)
		return FALSE;	
	else if (input_year > time.year)
		return TRUE;
	else
	{
		if (input_month < time.mon)
			return FALSE;
		else if (input_month > time.mon)
			return TRUE;
		else
		{
			if (input_day < time.mday)
				return FALSE;
			else
				return TRUE;
		}
	}
}

/********************************************************
* Function:	ToDoSoundDatabaseChecking
* Purpose: 	This function is called to set up the alarm 
*			manager
* Scope:	application/internal
* Input:	None
* Output:	None
* Return:	TRUE 	Add alarm
*			FALSE 	Not handled
* Comment: 	None
*********************************************************/
void ToDoSoundDatabaseChecking()
{
	if (DataFindDB(TODOSOUNDDB, &alarm_settings.dbid) != TRUE)
	{
		DataNewDB(TODOSOUNDDB,1,TODOAPP,&alarm_settings.dbid);
		DataOpenDB(alarm_settings.dbid,DB_NO_SORT,OPEN_RW);
	}
	else if (DataIsDBOpen(alarm_settings.dbid, NULL, NULL) == FALSE)
		DataOpenDB(alarm_settings.dbid,DB_NO_SORT,OPEN_RW);
}
