/*
================================ 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        :   memodb.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 "Memo.h"
#include "MemoFunc.h"
///#define      DEBUG
//#define         DEBUG_HENRY

/*****************************************************************
********************** Global Variables **************************
*****************************************************************/
DatabaseID	memo_dbid;
BYTE **		memo_field_buffer;
BYTE *		current_cate;
BYTE *		temp_cate;

UBYTE char_to_upper_case(UBYTE x)
{
	if((x>='a') && (x<='z'))
		x-= 32;
	return x;
}

TableDisplay	memo_list = {TABLE_MEMO_LIST,0,0,0,NULL};
AppStatus               app_status = {0,0,ALP_ORDER,MEMO_LIST,0,0};
/*	rec_id,			sketch_status,		new_sort_mode
edit_mode		create_time
*/
/********************************************************
* 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 MemoAppRestore(BOOLEAN restart)
{
	Bitmap	*bmp_addr;
	UWORD	byte_read, rec_num;
	BYTE	application_status;
	BYTE	*buffer, object_type, deleted_record;
	RTM	time;
	Err	result;
	
	/* Allocate global variable */
	pressed_object1 = 0;
	pressed_object2 = 0;
	///	sorted_by = ALP_ORDER;
	pen_down = FALSE;
	
	
	MemoDatabaseChecking();
	
	if (restart == TRUE)
	{
		application_status = RESTART_MEMO;
	}
	else
	{
		DataGetField(memo_dbid, MEMO_STATUS, 0, &buffer, &byte_read);
		application_status = *buffer;
		qfree(buffer);
	}
	/* Allocate global variable */
	memo_field_buffer = (BYTE**)qmalloc(1*sizeof(BYTE*));
	memo_field_buffer[0] = NULL;
	
	current_cate = (BYTE*)qmalloc(30*sizeof(BYTE));
	current_cate[0] = 0;
	temp_cate = (BYTE*)qmalloc(30*sizeof(BYTE));
    temp_cate[0] = 0;
	
	/* Initialisation all the Forms */
	FormInitAllFormObjects(FORM_MEMO_LIST);
	FormInitAllFormObjects(FORM_MEMO_VIEWING);
	FormInitAllFormObjects(FORM_MEMO_NEW);
	FormInitAllFormObjects(FORM_SAVE_CHANGES);
	FormInitAllFormObjects(FORM_ITEM_ERASE);
	FormInitAllFormObjects(FORM_SORT_BY);
	FormInitAllFormObjects(FORM_SELECT_CATE);
	FormInitAllFormObjects(FORM_NEW_CATE);
	FormInitAllFormObjects(FORM_ERASE_CATE);
	FormInitAllFormObjects(FORM_REMOVE_CATE);
	FormInitAllFormObjects(FORM_EXISTS_CATE);
	FormInitAllFormObjects(FORM_FULL_CATE);
	FormInitAllFormObjects(FORM_EDIT_CATE);
	
	DataGetField(memo_dbid, MEMO_EDIT_INFO, 3, &buffer, &byte_read);
	app_status.new_sort_mode = (BYTE)(*buffer);
	qfree(buffer);
	
	DataGetField(memo_dbid, MEMO_EDIT_INFO, 12, &buffer, &byte_read);
	table_font = (BYTE)(*buffer);
	qfree(buffer);
	
#ifdef	PR31700
    if (MemoryCheckMemLow())
		entry_low_memory = TRUE;
    else
		entry_low_memory = FALSE;
	
    if (application_status == RESTART_MEMO_NEW)
		entry_old_edit = TRUE;
	else 
		entry_old_edit = FALSE;		    	
#endif
	
	if (application_status == RESTART_MEMO)
	{
#ifdef	DEBUG
		printf("\n*** Restore Memo List ***\n");
#endif
		MemoCateNameToPopupTrigger(memo_dbid);
		strcpy(current_cate, MEMOALL);
		MemoSetTableFont();
		MemoRecordToTable(memo_dbid, app_status.new_sort_mode, MEMOALL);
		///		MemoTableDisplayDraw(&memo_list);
		FormPopupForm(FORM_MEMO_LIST);
	}
	else if (application_status == RESTART_MEMO_VIEWING || 
		application_status == RESTART_MEMO_NEW)
	{
		DataGetField(memo_dbid, MEMO_EDIT_INFO, 0, &buffer, &byte_read);
		app_status.rec_id = *(RecordID*)buffer;
		qfree(buffer);
		
		DataGetField(memo_dbid, MEMO_EDIT_INFO, 1, &buffer, &byte_read);
		app_status.sketch_status = (BYTE)(*buffer);
		qfree(buffer);
		
		DataGetField(memo_dbid, MEMO_EDIT_INFO, 2, &buffer, &byte_read);
		strcpy(app_status.create_time, buffer);
		qfree(buffer);	
		
		DataGetField(memo_dbid, MEMO_EDIT_INFO, 4, &buffer, &byte_read);
		app_status.edit_mode = (BYTE)(*buffer);
		qfree(buffer);
		
		DataGetField(memo_dbid, MEMO_EDIT_INFO, 5, &buffer, &byte_read);
		pressed_object1 = (BYTE)(*buffer);
		qfree(buffer);
		
		DataGetField(memo_dbid, MEMO_EDIT_INFO, 6, &buffer, &byte_read);
		pressed_object2 = (BYTE)(*buffer);
		qfree(buffer);
		
		/* Restore field_buffers */
		DataGetField(memo_dbid, MEMO_EDIT_INFO, 7, &buffer, &byte_read);
		memo_field_buffer[0] = (BYTE*)qmalloc((strlen(buffer) + 1)*sizeof(BYTE));
		strcpy(memo_field_buffer[0], buffer);
		qfree(buffer);	
		
		DataGetField(memo_dbid, MEMO_EDIT_INFO, 8, &buffer, &byte_read);
		strcpy(current_cate, buffer);
		qfree(buffer);
		
		/* Restore the org cate on the list screen */
		DataGetField(memo_dbid, MEMO_EDIT_INFO, 9, &buffer, &byte_read);
		strcpy(temp_cate, buffer);
		qfree(buffer);
		
		DataGetField(memo_dbid, MEMO_EDIT_INFO, 10, &buffer, &byte_read);
		app_status.field_change = (BOOLEAN)(*buffer);
		qfree(buffer);
		
		DataGetField(memo_dbid, MEMO_EDIT_INFO, 13, &buffer, &byte_read);
		memo_top_line = *(UWORD*)buffer;
		qfree(buffer);
		
		DataGetField(memo_dbid, MEMO_EDIT_INFO, 14, &buffer, &byte_read);
		memo_insert_pt_pos = *(UWORD*)buffer;
		qfree(buffer);
		
		DataGetField(memo_dbid, MEMO_EDIT_INFO, 15, &buffer, &byte_read);
		deleted_record = *(UWORD*)buffer;
		qfree(buffer);
		
		if (deleted_record == TRUE)
		{
#ifdef	DEBUG
			printf("\n*** Restore Memo Record deleted_record ***\n");
#endif
			DataNewRecord(memo_dbid, 0, MEMO_NUM_FIELD, &app_status.rec_id);
			/* Write Sketch Status */
			DataWriteField(memo_dbid, app_status.rec_id, 0, 1, (BYTE*) &app_status.sketch_status);
			/* Write Text Content */
			/* Write Modify Date */
			result = DataGetField(memo_dbid, MEMO_EDIT_INFO, 16, &buffer, &byte_read);
			DataWriteField(memo_dbid, app_status.rec_id, 2, byte_read, buffer);
			qfree(buffer);	
			/* Write Bitmap */
			if (app_status.sketch_status == MEMO_SKETCH)
			{
				result = DataGetField(memo_dbid, MEMO_EDIT_INFO, 17, &buffer, &byte_read);
				result = DataWriteField(memo_dbid, app_status.rec_id, 3, byte_read, (BYTE*) buffer);
				qfree(buffer);
			}							
			DataWriteField(memo_dbid, app_status.rec_id, 1, (strlen(memo_field_buffer[0]) + 1), memo_field_buffer[0]);
			DataCloseRecord(memo_dbid, app_status.rec_id);
		}
		/* Check if the record id is no longer exist */
		if (DataRecIDtoNum(memo_dbid, app_status.rec_id, &rec_num) != TRUE)
		{
#ifdef	DEBUG
			printf("\n*** Restore Memo Record no longer exist ***\n");
#endif
			
			application_status = RESTART_MEMO_NEW;
			app_status.sketch_status = 0;
			memo_top_line = 0;
			memo_insert_pt_pos = 0;
			strcpy(memo_field_buffer[0], "");
			
			RtcGetTime(&time);
			RtcFormatDate(&time, MEMOSTR1, app_status.create_time);
			/* Create a new record */
			DataNewRecord(memo_dbid, 0, MEMO_NUM_FIELD, &app_status.rec_id);
		}
		
		if (application_status == RESTART_MEMO_VIEWING)
		{		
			DataGetField(memo_dbid, MEMO_EDIT_INFO, 11, &buffer, &byte_read);
			show_line = (BYTE)(*buffer);
			qfree(buffer);
			
			MemoViewingSetUpScreen();
			FormPopupForm(FORM_MEMO_VIEWING);
		}
		else
		{	
#ifdef	DEBUG
			printf("\n*** Restore Memo New ***\n");
#endif
			FormGetObjectPointer(BITMAP_MEMO_SKETCH, &object_type, (void **)&bmp_addr);
			if (app_status.sketch_status == MEMO_SKETCH)
			{
				bmp_addr->bitmap_attr.bitmap_enable = TRUE;
				bmp_addr->bitmap_attr.bitmap_visible = TRUE;
			}
			else
			{
				bmp_addr->bitmap_attr.bitmap_enable = FALSE;
				bmp_addr->bitmap_attr.bitmap_visible = FALSE;
			}
			/* Set up Category */
			MemoCateNameToPopupTrigger(memo_dbid);
			ControlPopupDeleteItem(POPUP_TRIGGER_CATEGORY, 0);
			ControlSetLabel(POPUP_TRIGGER_CATEGORY, current_cate);
			FieldSetText(FIELD_MEMO_NEW, memo_field_buffer[0]);
			/* Set up Field Size */
			FieldSetFont(FIELD_MEMO_NEW, table_font);
			FormPopupForm(FORM_MEMO_NEW);
#ifdef	PR31700
			if (entry_low_memory)
			{
				low_memory_form_id = FORM_MEMO_LIST;
				FormPopupForm(FORM_SYSTEM_LOW_MEM);	
			}
#endif			
		}
	}
}

/********************************************************
* 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 MemoAppSave()
{
	BYTE	*temp_field_buffer, object_type, delete_record = 0, *buffer;
	UWORD	rec_num, byte_read;
	Field	*fld_addr;
	Err	result;
	
	
	MemoDatabaseChecking();
	
	if (DataRecordInfo(memo_dbid, MEMO_STATUS, NULL, NULL, NULL, NULL, NULL) != TRUE)
	{
		DataNewRecordWithID(memo_dbid, MEMO_STATUS, 0, 1);
	}
	if (DataRecordInfo(memo_dbid, MEMO_EDIT_INFO, NULL, NULL, NULL, NULL, NULL) == TRUE)
	{
		DataDeleteRecord(memo_dbid, MEMO_EDIT_INFO, FALSE);
	}
	
	DataNewRecordWithID(memo_dbid, MEMO_EDIT_INFO, 0, 18);
#ifdef	DEBUG
	printf("\n----> App Save Status %d <----", restart_form);
#endif
	
	DataWriteField(memo_dbid, MEMO_STATUS, 0, 1, &restart_form);
	/* app_status */
	DataWriteField(memo_dbid, MEMO_EDIT_INFO, 0, 4, (BYTE*)&app_status.rec_id);
	DataWriteField(memo_dbid, MEMO_EDIT_INFO, 1, 1, (BYTE*)&app_status.sketch_status);
	DataWriteField(memo_dbid, MEMO_EDIT_INFO, 2, (strlen(app_status.create_time)+ 1), app_status.create_time);
	DataWriteField(memo_dbid, MEMO_EDIT_INFO, 3, 1, (BYTE*)&app_status.new_sort_mode);
	DataWriteField(memo_dbid, MEMO_EDIT_INFO, 4, 1, (BYTE*)&app_status.edit_mode);
	DataWriteField(memo_dbid, MEMO_EDIT_INFO, 5, 1, (BYTE*)&pressed_object1);
	DataWriteField(memo_dbid, MEMO_EDIT_INFO, 6, 1, (BYTE*)&pressed_object2);
	/* Save field buffer */
	if (restart_form == RESTART_MEMO_NEW)	
		FieldGetTextPointer(FIELD_MEMO_NEW, &temp_field_buffer);
	else
		FieldGetTextPointer(FIELD_MEMO_VIEWING, &temp_field_buffer);
	
#ifdef DEBUG_HENRY
    printf("\n strlen temp_field_buffer = %ld", strlen(temp_field_buffer));
#endif    		
	
	
    if (memo_field_buffer[0] != NULL)
		qfree(memo_field_buffer[0]);
	memo_field_buffer[0] = (BYTE*)qmalloc((strlen(temp_field_buffer) + 1)*sizeof(BYTE));
	strcpy(memo_field_buffer[0],temp_field_buffer);
	
#ifdef DEBUG_HENRY
    printf("\n strlen memo_field_buffer = %ld", strlen(memo_field_buffer[0]));
#endif    		
	
	
	
	if (memo_field_buffer == NULL)
		DataWriteField(memo_dbid, MEMO_EDIT_INFO, 7, 1, (BYTE*)(""));
	else
	{
		DataWriteField(memo_dbid, MEMO_EDIT_INFO, 7, (strlen(memo_field_buffer[0]) + 1), memo_field_buffer[0]);
	}
	DataWriteField(memo_dbid, MEMO_EDIT_INFO, 8, (strlen(current_cate)+ 1), current_cate);
	DataWriteField(memo_dbid, MEMO_EDIT_INFO, 9, (strlen(temp_cate)+ 1), temp_cate);
	DataWriteField(memo_dbid, MEMO_EDIT_INFO, 10, 1, (BYTE*)&app_status.field_change);
	DataWriteField(memo_dbid, MEMO_EDIT_INFO, 11, 1, (BYTE*)&show_line);
	DataWriteField(memo_dbid, MEMO_EDIT_INFO, 12, 1, (BYTE*)&table_font);
	DataWriteField(memo_dbid, MEMO_EDIT_INFO, 15, 1, (BYTE*)&delete_record);
	
	if (restart_form == RESTART_MEMO_VIEWING)
	{
#ifdef	DEBUG
		printf("\n----> App Save Viewing <----");
#endif
		
		FormGetObjectPointer(FIELD_MEMO_VIEWING, &object_type, (void **)&fld_addr);
		
		if (fld_addr->field_attr.field_insert_pt_visible == TRUE)
		{
			FieldGetTopLineNum(FIELD_MEMO_VIEWING, &memo_top_line);
			FieldGetInsertPointPosition(FIELD_MEMO_VIEWING, &memo_insert_pt_pos);
		}
	}
	else if (restart_form == RESTART_MEMO_NEW)
	{
#ifdef	DEBUG
		printf("\n----> App Save New <----");
#endif
		
		FormGetObjectPointer(FIELD_MEMO_NEW, &object_type, (void **)&fld_addr);
		
		if (fld_addr->field_attr.field_insert_pt_visible == TRUE)
		{
			FieldGetTopLineNum(FIELD_MEMO_NEW, &memo_top_line);
			FieldGetInsertPointPosition(FIELD_MEMO_NEW, &memo_insert_pt_pos);
		}
		/* Backup Sketch */
		if (app_status.sketch_status == MEMO_SKETCH)
		{
			DataRecIDtoNum(memo_dbid, app_status.rec_id, &rec_num);
			DataOpenRecord(memo_dbid, rec_num, &app_status.rec_id, NULL);
			result = DataGetField(memo_dbid, app_status.rec_id, 3, &buffer, &byte_read);
			result = DataWriteField(memo_dbid, MEMO_EDIT_INFO, 17, byte_read, (BYTE *) buffer);
#ifdef	DEBUG
			printf("\n*** Save Memo Record Deleted Record ***\n");
#endif
			qfree(buffer);
		}							
		/* Delete the create record */
		DataCloseRecord(memo_dbid, app_status.rec_id);
		DataDeleteRecord(memo_dbid, app_status.rec_id, FALSE);
		
		delete_record = TRUE;
		DataWriteField(memo_dbid, MEMO_EDIT_INFO, 15, 1, (BYTE*)&delete_record);
		DataWriteField(memo_dbid, MEMO_EDIT_INFO, 16, (strlen(app_status.create_time)+ 1), (BYTE*)&app_status.create_time);
	}
	
	if (memo_top_line < 0)
		memo_top_line = 0;
	if (memo_insert_pt_pos < 0)
		memo_insert_pt_pos =0;
	
	
	DataWriteField(memo_dbid, MEMO_EDIT_INFO, 13, 4, (BYTE*)&memo_top_line);
	result = DataWriteField(memo_dbid, MEMO_EDIT_INFO, 14, 4, (BYTE*)&memo_insert_pt_pos);
	DataCloseDB(memo_dbid);
}

/********************************************************
* Function:	MemoSetFontPageMonth
* Purpose: 	
* Scope:	application/internal
* Input:	None
* Output:	None
* Return:	None
* Comment: 	None
*********************************************************/
void MemoSetFontPageMonth(RecordID rec_id, Table *table_addr, ObjectID cell_ui_id, USHORT max_rows_on_display)
{
	UWORD		byte_read;
	BYTE		*buffer, object_type, buffer1[10];
	USHORT		sch_month;
	String		*string_addr;
	
	
	DataGetField(memo_dbid, rec_id, 2, &buffer, &byte_read);
	buffer[0] = buffer[5];
	buffer[1] = buffer[6];
	buffer[2] = 0;
	sch_month = (USHORT)atol((const char *)buffer);
	qfree(buffer);
	
	if (sch_month == 1)
		strcpy(buffer1,MEMOJAN);
	else if (sch_month == 2)
		strcpy(buffer1,MEMOFEB);
	else if (sch_month == 3)
		strcpy(buffer1,MEMOMAR);
	else if (sch_month == 4)
		strcpy(buffer1,MEMOAPR);
	else if (sch_month == 5)
		strcpy(buffer1,MEMOMAY);
	else if (sch_month == 6)
		strcpy(buffer1,MEMOJUN);
	else if (sch_month == 7)
		strcpy(buffer1,MEMOJUL);
	else if (sch_month == 8)
		strcpy(buffer1,MEMOAUG);
	else if (sch_month == 9)
		strcpy(buffer1,MEMOSEP);
	else if (sch_month == 10)
		strcpy(buffer1,MEMOOCT);
	else if (sch_month == 11)
		strcpy(buffer1,MEMONOV);
	else if (sch_month == 12)
		strcpy(buffer1,MEMODEC);
	
	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 (max_rows_on_display == MEMO_SFONT_NUM_OF_ROW)
	{
		string_addr->text_font = SMALL_FONT;
		string_addr->bounds.width = MEMO_SCOLUMN_1;
	}
	else
	{
		string_addr->text_font = MEDIUM_FONT;
		string_addr->bounds.width = MEMO_LCOLUMN_1;
	}
	StringSetText(cell_ui_id,buffer1);
	return;
}

/********************************************************
* Function:	MemoSetFontPageDate
* Purpose: 	
* Scope:	application/internal
* Input:	None
* Output:	None
* Return:	None
* Comment: 	None
*********************************************************/
void MemoSetFontPageDate(RecordID rec_id, Table *table_addr, ObjectID cell_ui_id, USHORT max_rows_on_display)
{
	UWORD		byte_read;
	BYTE		*buffer, object_type, buffer1[10], *ptr;
	USHORT		sch_day;
	String		*string_addr;
	
	
	DataGetField(memo_dbid, rec_id, 2, &buffer, &byte_read);
	buffer[0] = buffer[8];
	buffer[1] = buffer[9];
	buffer[2] = 0;
	sch_day = (USHORT)atol((const char *)buffer);
	qfree(buffer);
	
	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 (max_rows_on_display == MEMO_SFONT_NUM_OF_ROW)
	{
		string_addr->text_font = SMALL_FONT;
		string_addr->bounds.width = MEMO_SCOLUMN_2;
	}
	else
	{
		string_addr->text_font = MEDIUM_FONT;
		string_addr->bounds.width = MEMO_LCOLUMN_2;
	}
	ptr = buffer1;
	
	if (sch_day < 10)
	{
		*ptr = '0';
		ptr++;
		sprintf((char*)ptr, "%d", sch_day);
	}
	else
		sprintf((char*)ptr, "%d", sch_day);
	
	StringSetText(cell_ui_id,buffer1);
	return;
}

/********************************************************
* Function:	AnnTableDisplayDraw
* Purpose: 	This function is called to draw the content of
*			in the anntable_display to a table object
* Scope:	application
* Input:	anntable_display	table-display structure
*			dbid				DatabaseID
* Output:	None
* Return:	TRUE    handled
*			FALSE   not-handled
* Comment: 	None
*********************************************************/
BOOLEAN MemoTableDisplayDraw(TableDisplay *table_display)
{
	ObjectID	cell_ui_id;
	RecordID	rec_id;
	Bitmap		*bmp_addr;
	String		*string_addr;
	Table		*table_addr;
	UWORD		rec_num, byte_read;
	BYTE		*buffer, object_type;
	USHORT		total_num_rows, max_rows_on_display;
	USHORT		top_row_num, num_rows_to_display, erase_cell_num;
	USHORT		count =0, cell =0;
	RecordIDBlock	*temp = table_display->record_id_block;
	CountrySettings country;
	
	
	SySetupGetCountrySettings(&country);	
	total_num_rows = table_display->total_num_rows;
	top_row_num = table_display->top_row_num;
	
	FormGetObjectPointer(TABLE_MEMO_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;
	
	if (max_rows_on_display == MEMO_SFONT_NUM_OF_ROW)
	{
		if (country.date_fmt == SYSETUP_DMY)
		{
			TableSetColumnWidth(TABLE_MEMO_LIST, 0, MEMO_SCOLUMN_2);
			TableSetColumnWidth(TABLE_MEMO_LIST, 1, MEMO_SCOLUMN_1);
		}
		else
		{
			TableSetColumnWidth(TABLE_MEMO_LIST, 0, MEMO_SCOLUMN_1);
			TableSetColumnWidth(TABLE_MEMO_LIST, 1, MEMO_SCOLUMN_2);
		}
	}
	else
	{
		if (country.date_fmt == SYSETUP_DMY)
		{
			TableSetColumnWidth(TABLE_MEMO_LIST, 0, MEMO_LCOLUMN_2);
			TableSetColumnWidth(TABLE_MEMO_LIST, 1, MEMO_LCOLUMN_1);
		}
		else
		{
			TableSetColumnWidth(TABLE_MEMO_LIST, 0, MEMO_LCOLUMN_1);
			TableSetColumnWidth(TABLE_MEMO_LIST, 1, MEMO_LCOLUMN_2);
		}
	}
	
	while (temp != NULL && num_rows_to_display > 0)
	{
		if (top_row_num >= count && top_row_num < count + MEMO_BLOCK_SIZE)
		{
			DataRecIDtoNum(memo_dbid, temp->record_id[top_row_num - count], &rec_num);
			DataOpenRecord(memo_dbid, rec_num, &rec_id, NULL);
			
			if (country.date_fmt == SYSETUP_DMY)
			{	
				/* Set the Schedule Day */
				cell_ui_id = ((TableItems*)(table_addr->table_item_ptr[cell]))->table_item_ui_id;
				MemoSetFontPageDate(rec_id, table_addr, cell_ui_id, max_rows_on_display);
				cell++;
				/* Set the Schedule Month */
				cell_ui_id = ((TableItems*)(table_addr->table_item_ptr[cell]))->table_item_ui_id;
				MemoSetFontPageMonth(rec_id, table_addr, cell_ui_id, max_rows_on_display);
				cell++;
			}
			else
			{
				/* Set the Schedule Month */
				cell_ui_id = ((TableItems*)(table_addr->table_item_ptr[cell]))->table_item_ui_id;
				MemoSetFontPageMonth(rec_id, table_addr, cell_ui_id, max_rows_on_display);
				cell++;
				/* Set the Schedule Day */
				cell_ui_id = ((TableItems*)(table_addr->table_item_ptr[cell]))->table_item_ui_id;
				MemoSetFontPageDate(rec_id, table_addr, cell_ui_id, max_rows_on_display);
				cell++;
			}
			/* Get the Text Contents */
			DataGetField(memo_dbid, rec_id, 1, &buffer, &byte_read);
			cell_ui_id = ((TableItems*)(table_addr->table_item_ptr[cell]))->table_item_ui_id;
			/* Set up string bounds */
			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 (max_rows_on_display == MEMO_SFONT_NUM_OF_ROW)
			{
				string_addr->text_font = SMALL_FONT;
				string_addr->bounds.width = MEMO_SCOLUMN_3;
			}
			else
			{
				string_addr->text_font = MEDIUM_FONT;
				string_addr->bounds.width = MEMO_LCOLUMN_3;
			}
			if (byte_read > MAX_TEXT_ON_DISPLAY)
				buffer[MAX_TEXT_ON_DISPLAY] = '\0';
			StringSetText(cell_ui_id,buffer);
			qfree(buffer);
			cell++;
			/* Get the Sketch Status */
			DataGetField(memo_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**)&bmp_addr) != TRUE)
				return ERR_UI_RES_NOT_FOUND;
			FormGetObjectPointer(cell_ui_id, &object_type, (void **)&bmp_addr);
			if (*buffer == MEMO_SKETCH)
			{
				bmp_addr->bitmap_attr.bitmap_enable = TRUE;
				bmp_addr->bitmap_attr.bitmap_visible = TRUE;
				bmp_addr->bitmap_attr.bitmap_active = TRUE;
			}
			else
			{
				bmp_addr->bitmap_attr.bitmap_enable = FALSE;
				bmp_addr->bitmap_attr.bitmap_visible = FALSE;
				bmp_addr->bitmap_attr.bitmap_active = FALSE;
			}
			qfree(buffer);
			cell++;
			/* For Next Record */
			num_rows_to_display--;
			top_row_num++;
			DataCloseRecord(memo_dbid, rec_id);
		}
		else
		{
			count += MEMO_BLOCK_SIZE;
			temp = temp->next;
		}
	}	
	
	if (max_rows_on_display == MEMO_SFONT_NUM_OF_ROW)	
		erase_cell_num = MEMO_SFONT_NUM_OF_CELL;
	else
		erase_cell_num = MEMO_LFONT_NUM_OF_CELL;		
	
	while(cell < erase_cell_num)
	{
		/* Disable column 1 */
		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 2 */
		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 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**)&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++;
	}
	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;
	/* Set up the Category */
	ControlSetLabel(POPUP_TRIGGER_CATEGORY, current_cate);
	return TRUE;
}

/********************************************************
* 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:	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 != MEMO_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:	AnnDatabaseInit
* 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 MemoDatabaseInit()
{
#ifdef PC_SIM
	RecordID rec_id;
	SHORT i;		
	BYTE sketch_status[15], memo_cate[15];
	BYTE *memo_contents[15], *memo_date[15];
	
	
	for (i = 0; i <15; i++)
	{
		sketch_status[i] = 0;
		memo_cate[i] = 2;	// Personal
	}
	//	memo_cate[2] = 1;		// Business
	//	memo_cate[5] = 1;
	//	memo_cate[7] = 1;
	//	memo_cate[9] = 1;
	//	memo_cate[10] = 1;
	//	memo_cate[11] = 1;
	//	memo_cate[13] = 1;
	//	memo_cate[14] = 1;
	
	sketch_status[2]  = MEMO_SKETCH;
	sketch_status[5]  = MEMO_SKETCH;
	sketch_status[7]  = MEMO_SKETCH;
	sketch_status[9]  = MEMO_SKETCH;
	sketch_status[10] = MEMO_SKETCH;
	sketch_status[11] = MEMO_SKETCH;
	sketch_status[13] = MEMO_SKETCH;
	sketch_status[14] = MEMO_SKETCH;
	
	
	for (i = 0; i <15; i++)
	{	
		memo_contents[i] = (BYTE*)qmalloc(500*sizeof(BYTE));
		memo_date[i]  = (BYTE*)qmalloc(30*sizeof(BYTE));
	}
	
	strcpy(memo_contents[0],MEMOCHARA);
	strcpy(memo_contents[1],MEMOCHARB);
	strcpy(memo_contents[2],MEMOCHARC);
	strcpy(memo_contents[3],MEMOCHARD);
	strcpy(memo_contents[4],MEMOCHARE);
	strcpy(memo_contents[5],MEMOCHARF);
	strcpy(memo_contents[6],MEMOCHARG);
	strcpy(memo_contents[7],MEMOCHARH);
	strcpy(memo_contents[8],MEMOCHARI);
	strcpy(memo_contents[9],MEMOCHARJ);
	strcpy(memo_contents[10],MEMOCHARK);
	strcpy(memo_contents[11],MEMOCHARL);
	strcpy(memo_contents[12],MEMOCHARM);
	strcpy(memo_contents[13],MEMOCHARN);
	strcpy(memo_contents[14],MEMOCHARO);
	
	strcpy(memo_date[0],"1997/03/17/01/01/01");
	strcpy(memo_date[1],"1997/03/17/01/02/01");
	strcpy(memo_date[2],"1997/03/17/03/01/01");
	strcpy(memo_date[3],"1997/03/17/04/01/01");
	strcpy(memo_date[4],"1997/03/17/05/01/01");
	strcpy(memo_date[5],"1998/03/17/06/01/01");
	strcpy(memo_date[6],"1998/07/21/07/01/01");
	strcpy(memo_date[7],"1998/08/22/08/01/01");
	strcpy(memo_date[8],"1998/08/22/09/01/01");
	strcpy(memo_date[9],"1999/08/22/10/01/01");
	strcpy(memo_date[10],"1999/11/25/11/01/01");
	strcpy(memo_date[11],"1999/12/22/12/01/01");
	strcpy(memo_date[12],"2000/03/04/13/01/01");
	strcpy(memo_date[13],"2000/01/22/14/01/01");
	strcpy(memo_date[14],"2000/02/11/15/01/01");
	
	/* New Database */
	DataNewDB(MEMODB,1,MEMOAPP,&memo_dbid);
	/* Open Database and sort by schedule date */
	DataOpenDB(memo_dbid,SORT_TEXT_MODE | 2,OPEN_RW);
	
	DataCategorySetName(memo_dbid, 0, MEMOUNFILED);
	DataCategorySetName(memo_dbid, 1, MEMOBUS);
	DataCategorySetName(memo_dbid, 2, MEMOPER);
	/* Open Database */						
	for (i= 0;i<15;i++)
	{
		DataNewRecord(memo_dbid, memo_cate[i], MEMO_NUM_FIELD, &rec_id);
		DataWriteField(memo_dbid,rec_id,0,1,(BYTE*) &sketch_status[i]);
		DataWriteField(memo_dbid,rec_id,1,(strlen(memo_contents[i]) + 1),memo_contents[i]);
		DataWriteField(memo_dbid,rec_id,2,(strlen(memo_date[i]) + 1),memo_date[i]);
		DataCloseRecord(memo_dbid,rec_id);
	}	
	for (i= 0; i <15; i++)
	{
		qfree(memo_contents[i]);
		qfree(memo_date[i]);
	}
#endif
}

/******************************************************************
* Function:	AnnChangeUpdateRecord
* Purpose: 	
* Scope:	application/internal
* Input:	Event		received event
* Output:	None
* Return:	TRUE if handled
*			FALSE if not handled
* Comment: 	None
*******************************************************************/
void MemoChangeUpdateRecord()
{
	UWORD	rec_num;
	RTM		time;
	
	/* Modify Create Date */
	RtcGetTime(&time);
	RtcFormatDate(&time, MEMOSTR1, app_status.create_time);
	
	DataRecIDtoNum(memo_dbid, app_status.rec_id, &rec_num);
	DataOpenRecord(memo_dbid, rec_num, &app_status.rec_id, NULL);
	/* Write Field 0 of To Do List Record */
	DataWriteField(memo_dbid, app_status.rec_id, 0, 1, &app_status.sketch_status);
	/* Write Field 2 of To Do List Record */
	DataWriteField(memo_dbid, app_status.rec_id, 2, (strlen(app_status.create_time)+ 1), app_status.create_time);
	/* Close Record */
	DataCloseRecord(memo_dbid,app_status.rec_id);
}

/********************************************************
* Function:	MemoCateNameToNum
* Purpose: 	This function is used find out the cate num
* Scope:	application
* Input:	cate_name		The category name
* Output:	cate_num
* Return:	TRUE			found
*			FALSE			not exist
* Comment: 	The passed-in database must be opend 
*********************************************************/
BOOLEAN MemoCateNameToNum(BYTE *cate_name, UBYTE *cate_num)
{
	UBYTE	cate[256];
	UBYTE	num_cate;
	BYTE	*cate_cate;
	USHORT	i;
	
	num_cate = DataCategorySort(memo_dbid, cate);
	cate_cate = (BYTE*)qmalloc(30*sizeof(BYTE));
	for (i = 0; i < num_cate; i++)
	{
		DataCategoryName(memo_dbid, cate[i], cate_cate);
		if (MemoCompareTwoStrings(cate_name, cate_cate) == SAME)
		{
			*cate_num = cate[i];
			qfree(cate_cate);
			return TRUE;
		}
	}
	DataCategoryName(memo_dbid, 0, cate_cate);
	if (MemoCompareTwoStrings(cate_name, cate_cate) == SAME)
	{
		*cate_num = 0;
		qfree(cate_cate);
		return TRUE;
	}
	qfree(cate_cate);
	*cate_num = 255;
	return FALSE;
}

/********************************************************
* Function:	MemoCompareTwoStrings
* Purpose: 	This function is used to compare two strings
* Scope:	application
* Input:	string1			string 1
*			string2			string 2
* Output:	None
* Return:	FIRST			string 1 is smaller string 2
*			SECOND			string 2 is smaller string 1
*			SAME			string 1 = string 1
* Comment: 	
*********************************************************/
/*
BYTE MemoCompareTwoStrings(BYTE *string1, BYTE *string2)
{

  while ((*string1 != '\0') && (*string2 != '\0'))
  {
		if (*string1 < *string2)
		return FIRST;
		else if (*string1 > *string2)
		return SECOND;
		else
		{
		string1++;
		string2++;
		}
		}
		if (*string1 != '\0' && *string2 == '\0')
		return SECOND;
		else if (*string2 != '\0' && *string1 == '\0')
		return FIRST;
		else return SAME;
		}
*/
BYTE MemoCompareTwoStrings(BYTE *string1, BYTE *string2)
{
	USHORT i = 0;
	BYTE result = SAME;
	
	while((UBYTE)string1[i] && (UBYTE)string2[i])
	{
		if(char_to_upper_case((UBYTE)string1[i]) < char_to_upper_case((UBYTE)string2[i]))
		{
			result = FIRST;
			break;
		}
		else if(char_to_upper_case((UBYTE)string2[i]) < char_to_upper_case((UBYTE)string1[i]))
		{
			result = SECOND;
			break;
		}
		i++;
	}
	if(result != SAME)
		return result;
	
	/* String Not equal to Null */
	if(string1[i])
		return SECOND;
	else if(string2[i])
		return FIRST;
	else
		return SAME;
}
/********************************************************
* Function:	ToDoRecordToList
* 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
**********************************************************/
BOOLEAN	MemoRecordToTable(DatabaseID dbid, BYTE sorted_by, BYTE *cate_name)
{
	RecordID	rec_id;
	Table		*table_addr;
	Control		*ctl_addr;
	UBYTE		cate_number;
	BYTE		object_type;
	UWORD		top_record, rec_num, total_num_rec;
	UWORD		*match_rec_num, match_num_rec, i, display_count =0;
	Err		result;
	
	
	
	if (MemoCateNameToNum(cate_name, &cate_number) == FALSE && 
		MemoCompareTwoStrings(cate_name,MEMOALL) != SAME)
		return FALSE;
	
	if (sorted_by == ALP_ORDER)
	{
		DataCloseDB(memo_dbid);
		DataOpenDB(memo_dbid, SORT_TEXT_MODE | 1, OPEN_RW);
	}
	else
	{
		DataCloseDB(memo_dbid);
		DataOpenDB(memo_dbid, SORT_TEXT_MODE | 2, OPEN_RW);
	}
	
	TableDisplayDeleteAllRecordID(&memo_list);
	///	TableEraseTable(TABLE_MEMO_LIST);
	result = DataTotalRecord(memo_dbid, &total_num_rec);
	
	if (total_num_rec != 0)
	{
		if (MemoCompareTwoStrings(cate_name,MEMOALL) == SAME)
		{
			
			for (i=0; i <total_num_rec; i++)
			{
				DataNumtoRecID(memo_dbid, i, &rec_id);
				TableDisplayInsertRecordID(&memo_list, rec_id, memo_dbid);
				display_count++;
			}	
		}
		else
		{
			match_rec_num = (UWORD*)qmalloc(total_num_rec * sizeof(UWORD));
			MemoGetRecNumWithCateName(total_num_rec, cate_name, match_rec_num, &match_num_rec);
			
			for (i =0; i <match_num_rec; i++)
			{
				DataOpenRecord(memo_dbid, match_rec_num[i], &rec_id, NULL);
				TableDisplayInsertRecordID(&memo_list, rec_id, memo_dbid);
				display_count++;
			}
		}
		
		if (app_status.rec_id != 0)
		{
			DataRecIDtoNum(memo_dbid, app_status.rec_id, &rec_num);
			
			if (display_count < MEMO_NUM_OF_ROW)
				top_record = 0;
			else
			{	/* If the record place in the last page */
				if ((rec_num+1) + MEMO_NUM_OF_ROW > display_count)		
					top_record = display_count - MEMO_NUM_OF_ROW;
				else 				
					top_record = rec_num;
			}
		}
		else
			top_record = 0;
		
		MemoSetTableTopRowNum(top_record);
		
		if (MemoCompareTwoStrings(cate_name,MEMOALL) == SAME || match_num_rec > 1)
		{
			FormGetObjectPointer(BUTTON_MEMO_SORT, &object_type, (void **)&ctl_addr);
			ctl_addr->control_attr.control_visible = TRUE;
			ctl_addr->control_attr.control_enable = TRUE;
			ControlDrawControl(BUTTON_MEMO_SORT);
		}
		else
		{
			FormGetObjectPointer(BUTTON_MEMO_SORT, &object_type, (void **)&ctl_addr);
			ctl_addr->control_attr.control_visible = FALSE;
			ctl_addr->control_attr.control_enable = FALSE;
			ControlEraseControl(BUTTON_MEMO_SORT);
		}
		return	TRUE;
	}
	else
	{
		FormGetObjectPointer(TABLE_MEMO_LIST, &object_type, (void **)&table_addr);
		table_addr->table_attr.table_visible = FALSE;
		
		FormGetObjectPointer(BUTTON_MEMO_SORT, &object_type, (void **)&ctl_addr);
		ctl_addr->control_attr.control_visible = FALSE;
		ctl_addr->control_attr.control_enable = FALSE;
		
		ScrollbarSetScrollbarVisible(SCROLLBAR_MEMO_LIST,FALSE);
		ScrollbarEraseScrollbar(SCROLLBAR_MEMO_LIST);
		MemoTableDisplayDraw(&memo_list);
		return	TRUE;
	}
	return	TRUE;
}

/********************************************************
* Function:	MemoGetRecNumWithCateName
* Purpose: 	This function is called to get all record numbers 
*			of the records that are with the same category name
* Scope:	application
* Input:	cate_name		The required category
* Output:	rec_num			array of record number
*			num_rec			number of record returned
* Return:	TRUE			success
*			FALSE			error occure
* Comment: 	Database must be opened
*********************************************************/
BOOLEAN MemoGetRecNumWithCateName(UWORD total_num_rec, BYTE *cate_name, UWORD rec_num[], UWORD *num_rec)
{
	RecordID rec_id;
	UBYTE cate_num, rec_cate_num;
	UWORD i, total_cate_rec =0;
	
	if (MemoCateNameToNum(cate_name, &cate_num) == FALSE)
	{
		*num_rec = 0;
		return FALSE;
	}
	
	for (i = 0; i<total_num_rec; i++)
	{
		DataNumtoRecID(memo_dbid, i, &rec_id);
		DataRecordInfo(memo_dbid, rec_id, NULL, &rec_cate_num, NULL, NULL, NULL);
		
		if (rec_cate_num == cate_num)
		{
			rec_num[total_cate_rec] = i;
			total_cate_rec++;
		}
	}
	*num_rec = total_cate_rec;
	return TRUE;
}

/********************************************************
* Function:	MemoPopupCateActions
* Purpose: 	This function is called in order to take actions
*			when the popup trigger of categories is changed
* Scope:	application
* Input:	selected_item
* Output:	None
* Return:	TRUE			success
*			FALSE			error occure
* Comment: 	None
*********************************************************/
BOOLEAN MemoPopupCateActions(SHORT selected_item)
{
	UBYTE	cate[256], num_cate;
	BYTE	*cate_name, *item_text;
	USHORT	popup_total_num_items;
	SHORT	i;
	
	
	ControlPopupGetTotalItems(POPUP_TRIGGER_CATEGORY, &popup_total_num_items);
	/* Edit Category in List, Viewing and New Screen */
	if (popup_total_num_items == ((USHORT)selected_item + 1))
	{		
		ListInitList(LIST_CATE);
		MenuDeleteItem(MEMO_CATE_MENU, 0);
		
		if (table_font == SMALL_FONT)
			MenuInsertItem(MEMO_CATE_MENU, 0, MEMOLFONT);
		else
			MenuInsertItem(MEMO_CATE_MENU, 0, MEMOSFONT);
		
		ListSetFont(LIST_CATE, table_font);
		num_cate = DataCategorySort(memo_dbid, cate);
		ListDeleteAllItems(LIST_CATE);
		cate_name = (BYTE*)qmalloc(30*sizeof(BYTE));
		
		for (i =0; i < num_cate; i++)
		{
			DataCategoryName(memo_dbid, cate[i], cate_name);
			ListInsertItem(LIST_CATE, i, cate_name);
		}
		qfree(cate_name);
		
		ScrollbarInitScrollbar(SCROLLBAR_MEMO_VIEWING);
		MemoEditCateSetScrollbar();
		FormPopupForm(FORM_EDIT_CATE);		
		return TRUE;
	}
	else
	{
		ControlPopupGetPopupItem(POPUP_TRIGGER_CATEGORY, (USHORT)selected_item, &item_text);
		strcpy(current_cate, item_text);
		
		if (app_status.edit_mode == MEMO_LIST)
		{	
			MemoRecordToTable(memo_dbid, app_status.new_sort_mode, current_cate);
			MemoTableDisplayDraw(&memo_list);
			TableDrawTable(TABLE_MEMO_LIST);
			return TRUE;
		}
		else 
			return TRUE;
	}
	return FALSE;
}

/********************************************************
* Function:	AnnDatabaseChecking
* 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 MemoDatabaseChecking()
{
	BYTE	application_status, create_font = SMALL_FONT;
	
	
	if (DataFindDB(MEMODB, &memo_dbid) != TRUE)
	{
		app_status.new_sort_mode = ALP_ORDER;
		/* New Database */
		DataNewDB(MEMODB,1,MEMOAPP,&memo_dbid);
		DataOpenDB(memo_dbid,SORT_TEXT_MODE | 2,OPEN_RW);
		/* Create status record */
		DataNewRecordWithID(memo_dbid, MEMO_STATUS, 0, 1);
		DataNewRecordWithID(memo_dbid, MEMO_EDIT_INFO, 0, 18);
		application_status = RESTART_MEMO;
		DataWriteField(memo_dbid, MEMO_STATUS, 0, 1, &application_status);
		DataWriteField(memo_dbid, MEMO_EDIT_INFO, 3, 1, (BYTE*)&app_status.new_sort_mode);
		DataWriteField(memo_dbid, MEMO_EDIT_INFO, 12, 1, (BYTE*)&create_font);
	}
	else if (DataIsDBOpen(memo_dbid, NULL, NULL) == FALSE)
	{
		DataOpenDB(memo_dbid,SORT_TEXT_MODE | 2,OPEN_RW);
	}
	
	if (DataRecordInfo(memo_dbid, MEMO_STATUS, NULL, NULL, NULL, NULL, NULL) != TRUE)
	{
		DataNewRecordWithID(memo_dbid, MEMO_STATUS, 0, 1);
		application_status = RESTART_MEMO;
		DataWriteField(memo_dbid, MEMO_STATUS, 0, 1, &application_status);
	}
	
	if (DataRecordInfo(memo_dbid, MEMO_EDIT_INFO, NULL, NULL, NULL, NULL, NULL) != TRUE)
	{
		app_status.new_sort_mode = ALP_ORDER;
		DataNewRecordWithID(memo_dbid, MEMO_EDIT_INFO, 0, 18);
		DataWriteField(memo_dbid, MEMO_EDIT_INFO, 3, 1, (BYTE*)&app_status.new_sort_mode);
		DataWriteField(memo_dbid, MEMO_EDIT_INFO, 12, 1, (BYTE*)&create_font);
	}
}
