/*
================================ 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        :   memolch.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"
#include "MemoDB.h"
#include "MemoLch.h"
///#define       DEBUG
//#define DEBUG_HENRY
//#define DEBUG_H

/*****************************************************************
********************** Global Variables **************************
*****************************************************************/

/********************************************************
* Function:	ToDoAppLaunch
* Purpose: 	This function is called to launch the 
*			To DO List application
* Scope:	application/internal
* Input:	None
* Output:	None
* Return:	TRUE if handled
*			FALSE if not handled
* Comment: 	None
*********************************************************/
BOOLEAN MemoAppLaunch(WORD cmd, void *cmd_ptr)
{
#ifdef	PR31700
	UWORD		num_rec, count, byte_read;
	USHORT		field_num;
	BYTE		*buffer, *prepare_string;
#endif
	AppID   	appid;
	RecordID	rec_id;
	
#ifdef	DEBUG
	printf("\n*** Memo Lanuch Start ***\n");
#endif
	
	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_ptr = NULL;
		
		cmd = LAUNCH_CMD_NORMAL_LAUNCH;
	}		
	
	switch(cmd)
	{
	case	LAUNCH_CMD_NORMAL_LAUNCH:
		UIApplicationInit();
		MemoAppRestore(FALSE);
		EventLoop();
		/* Exit Normal Launch */
#ifdef PR31700
		if (entry_low_memory == FALSE || entry_old_edit == FALSE)
			MemoAppSave();
#endif
#ifdef PC_SIM
		MemoAppSave();
		MemoAppRestore(FALSE);
		EventLoop();
#endif
		UIDeleteAllAppObjects();
		
		if (cmd_ptr != NULL)
		{
			pfree(cmd_ptr);
			cmd_ptr = NULL;
		}
		return TRUE;
		
	case	LAUNCH_CMD_FIND:
#ifdef 	PR31700
		app_id = SysGetActiveAppID();
		MemoDatabaseChecking();
		DataTotalRecord(memo_dbid, &num_rec);
		
		for (count =0; count<num_rec; count++)
		{
			DataOpenRecord(memo_dbid, count, &rec_id, NULL);
			
			for (field_num =1; field_num <2; field_num++)
			{
				DataGetField(memo_dbid, rec_id, field_num, &buffer, &byte_read);
				
				if (GlobalFindSearchText((BYTE*)cmd_ptr, buffer) >= 0)
				{
					MemoPrepareFindText(memo_dbid, rec_id, &prepare_string);
#ifdef	PR31700
					GlobalFindAddItem(app_id, memo_dbid, rec_id, field_num, prepare_string, FALSE);
#else
					GlobalFindAddItem(app_id, memo_dbid, rec_id, field_num, prepare_string);
#endif
					qfree(buffer);
					pfree(prepare_string);
					break;
				}
				qfree(buffer);
			}
			DataCloseRecord(memo_dbid, rec_id);
		}
		if (cmd_ptr != NULL)
			pfree(cmd_ptr);
		DataCloseDB(memo_dbid);					
#endif
		return TRUE;
		
	case	LAUNCH_CMD_GOTO_REC:
#ifdef	DEBUG
		printf("\n*** Memo Goto Item Start ***\n");
#endif
		MemoDatabaseChecking();
		/* Check if Launched by Sketch */
		SysGetAppID(SKETCH, &appid);
		
		if (((GotoRec*)cmd_ptr)->app_id != appid)
		{
#ifdef	DEBUG
			printf("\n*** Memo Goto Record ***\n");
#endif
			MemoGotoItem(((GotoRec*)cmd_ptr)->dbid, ((GotoRec*)cmd_ptr)->rec_id,
				((GotoRec*)cmd_ptr)->field_num, ((GotoRec*)cmd_ptr)->find_string);
		}
		else
		{
#ifdef	DEBUG
			printf("\n*** Memo Sketch Goto ***\n");
#endif
			MemoSketchGoto(((GotoRec*)cmd_ptr)->dbid, ((GotoRec*)cmd_ptr)->rec_id, ((GotoRec*)cmd_ptr)->field_num);
		}
#ifdef	DEBUG
		printf("\n*** Memo Goto Item Finish ***\n");
#endif
		/* Check Goto from Find or Other Application */
		if (cmd_ptr != NULL)
		{
			if (((GotoRec*)cmd_ptr)->find_string != NULL)
				pfree(((GotoRec*)cmd_ptr)->find_string);
			pfree(cmd_ptr);
		}
		EventLoop();
		/* Exit Goto Record */
#ifdef PR31700
		
		if (entry_low_memory == FALSE || entry_old_edit == FALSE)
			MemoAppSave();
#endif
		UIDeleteAllAppObjects();
     			return TRUE;
				
	default:
		return FALSE;
	}
	return FALSE;
}

/********************************************************
* Function:	ToDoPrepareFindText
* Purpose: 	This function is called to prepare the text 
*			for a record to be displayed in the global find 
*			application
* Scope:	application/internal
* Input:	dbid
*			rec_id
*			prepare_string
* Output:	None
* Return:	None
* Comment: 	None
*********************************************************/
void MemoPrepareFindText(DatabaseID dbid, RecordID rec_id, BYTE **prepare_string)
{
	ObjectBounds	content_bounds;
	BYTE			*content, *buffer;
	UWORD			byte_read;
	
	
	
	content_bounds.xcoord	=0;
	content_bounds.ycoord	=0;
	content_bounds.width	=67;
	content_bounds.height	=9;
	
	*prepare_string = (BYTE*)pmalloc(100*sizeof(BYTE));
	/* Get Memo Content */
	DataGetField(dbid, rec_id, 1, &buffer, &byte_read);
    content = (BYTE*)pmalloc((strlen(buffer) + 10) *sizeof(BYTE));
	strcpy(content, buffer);
	StrChopString(&content_bounds, content, SMALL_FONT, TRUE, 0);
	strcpy(*prepare_string, content);
	
    qfree(buffer);
	pfree(content);
}

/********************************************************
* Function:	ToDoGotoItem
* 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 MemoGotoItem(DatabaseID dbid, RecordID rec_id, USHORT field_num, BYTE *search_string)
{
	WORD	total_num_lines;
	WORD	highlight_char_pos =0, line_num;
	UWORD	rec_num;
	BOOLEAN	found =FALSE;
	Field	*fld_addr;
	UWORD	byte_read;
	BYTE	sorted_by, *buffer, object_type, deleted_record;
	Err	result;
	
	
#ifdef	DEBUG
	printf("\n*** Memo Goto Item ***\n");
#endif
	/*				  */
	/* Create the last deleted record */
	/*				  */
	DataGetField(memo_dbid, MEMO_EDIT_INFO, 15, &buffer, &byte_read);
	deleted_record = *(UWORD*)buffer;
	qfree(buffer);
	
	if (deleted_record == TRUE)
	{
#ifdef	DEBUG
		printf("\n*** Goto Item Create Deleted Record ***\n");
#endif
		DataNewRecord(memo_dbid, 0, MEMO_NUM_FIELD, &app_status.rec_id);
		/* Write Sketch Status */
		DataGetField(memo_dbid, MEMO_EDIT_INFO, 1, &buffer, &byte_read);
		app_status.sketch_status = (BYTE)(*buffer);
		qfree(buffer);
		
		DataWriteField(memo_dbid, app_status.rec_id, 0, 1, (BYTE*) &app_status.sketch_status);
		
		/* Write Modify Date */
		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);
		}	
		/* Write Text Content */
		DataGetField(memo_dbid, MEMO_EDIT_INFO, 7, &buffer, &byte_read);
		DataWriteField(memo_dbid, app_status.rec_id, 1, byte_read, buffer);
		qfree(buffer);							
		DataCloseRecord(memo_dbid, app_status.rec_id);
	}
	/*			*/
	/* Goto selected record */
	/*			*/
	app_status.rec_id = rec_id;
	/* Allocate global variable */
	if(memo_field_buffer != NULL)
		qfree(memo_field_buffer);
	memo_field_buffer = (BYTE**)qmalloc(1*sizeof(BYTE*));
	memo_field_buffer[0] = NULL;
	
	if(current_cate != NULL)
		qfree(current_cate);
	current_cate = (BYTE*)qmalloc(30*sizeof(BYTE));
	current_cate[0] = 0;
	
	if(temp_cate != NULL)
		qfree(temp_cate);
	temp_cate = (BYTE*)qmalloc(30*sizeof(BYTE));
	temp_cate[0] = 0;
	
	/* Allocate global variable */
	pressed_object1 = 0;
	pressed_object2 = 0;
	sorted_by = ALP_ORDER;
	pen_down = FALSE;
	/* Set up app_status variables */
	MemoRecordToVariable();
	MemoDatabaseChecking();
	
	/* Initialisation all the Forms */
	FormInitAllFormObjects(FORM_MEMO_NEW);
	FormInitAllFormObjects(FORM_MEMO_LIST);
	FormInitAllFormObjects(FORM_MEMO_VIEWING);
	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, 12, &buffer, &byte_read);
	table_font = (BYTE)(*buffer);
	qfree(buffer);
	
	memo_top_line = 0;
	memo_insert_pt_pos = 0;
	MemoViewingSetUpScreen();
	strcpy(temp_cate, current_cate);
	FormGetObjectPointer(FIELD_MEMO_VIEWING, &object_type, (void **)&fld_addr);
	
	/* Goto to select text */
	if (search_string != NULL)
	{
		DataRecIDtoNum(memo_dbid, rec_id, &rec_num);
		DataOpenRecord(memo_dbid, rec_num, &rec_id, NULL);
		DataGetField(memo_dbid, rec_id, 1, &buffer, &byte_read);
		strcpy(memo_field_buffer[0], buffer);
		qfree(buffer);
		
		highlight_char_pos = GlobalFindSearchText(search_string, memo_field_buffer[0]);
		total_num_lines = fld_addr->field_total_num_lines;
		
		for (line_num =0; line_num <total_num_lines; line_num++)
		{
			if ((highlight_char_pos >= fld_addr->field_lineinfo[line_num].start) &&
				(highlight_char_pos <= (fld_addr->field_lineinfo[line_num].start +
				fld_addr->field_lineinfo[line_num].length -1)))
			{
				found = TRUE;
				
				if (line_num > (total_num_lines - fld_addr->field_num_lines_displayed))
					line_num = (total_num_lines - fld_addr->field_num_lines_displayed);
				fld_addr->field_top_line_num = line_num;
				break;
			}
		}
		
		if (!found)
			fld_addr->field_top_line_num = 0;
		
		memo_top_line = fld_addr->field_top_line_num;
		MemoSetUpFieldScreen(FORM_MEMO_VIEWING);
		MemoFieldSetScrollbar(FIELD_MEMO_VIEWING, SCROLLBAR_MEMO_VIEWING);
		
		fld_addr->field_highlight_start_char = highlight_char_pos;
		fld_addr->field_highlight_end_char = highlight_char_pos + strlen(search_string) - 1;
		fld_addr->field_highlight_length = strlen(search_string);
		fld_addr->field_attr.field_highlight = TRUE;
		FormSetFormActiveObject(FORM_MEMO_VIEWING, fld_addr->identification.ui_object_id);
	}
	/* Disable the field object */
	show_line = FALSE;
	goto_highlight = TRUE;
	FormPopupForm(FORM_MEMO_VIEWING);
}

/********************************************************
* Function:	ToDoGotoItem
* 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 MemoSketchGoto(DatabaseID dbid, RecordID rec_id, USHORT field_num)
{
	WORD	highlight_char_pos =0;
	UWORD	rec_num;
	BOOLEAN	found =FALSE;
	Bitmap	*bmp_addr;
	Field	*fld_addr;
	UWORD	byte_read;
	BYTE	sorted_by, *buffer, object_type;
	BYTE	application_status;
	
#ifdef DEBUG_HENRY
    printf("\n  =========== In MemoSketchGoto ==============");
#endif
	
#ifdef DEBUG_H
    printf("\n  =========== In MemoSketchGoto %ld ==============", rec_id);
#endif    
	
	/* Set up app_status variables */
	app_status.rec_id = rec_id;
	/* Allocate global variable */
	if(memo_field_buffer != NULL)
		qfree(memo_field_buffer);
	memo_field_buffer = (BYTE**)qmalloc(1*sizeof(BYTE*));
	memo_field_buffer[0] = NULL;
	
	if(current_cate != NULL)
		qfree(current_cate);
	current_cate = (BYTE*)qmalloc(30*sizeof(BYTE));
	current_cate[0] = 0;
	
	if(temp_cate != NULL)
		qfree(temp_cate);
	temp_cate = (BYTE*)qmalloc(30*sizeof(BYTE));
	temp_cate[0] = 0;
	
	/* Allocate global variable */
	pressed_object1 = 0;
	pressed_object2 = 0;
	sorted_by = ALP_ORDER;
	pen_down = FALSE;
	
	//	MemoDatabaseChecking();
	
	/* Initialisation all the Forms */
	FormInitAllFormObjects(FORM_MEMO_NEW);
	FormInitAllFormObjects(FORM_MEMO_LIST);
	FormInitAllFormObjects(FORM_MEMO_VIEWING);
	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_STATUS, 0, &buffer, &byte_read);
	application_status = *buffer;
	qfree(buffer);
	
	DataGetField(memo_dbid, MEMO_EDIT_INFO, 12, &buffer, &byte_read);
	table_font = (BYTE)(*buffer);
	
#ifdef DEBUG_HENRY
    printf("\n  MemoSketchGoto A %ld", table_font);
#endif
	
	
	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);
	
	if (application_status == RESTART_MEMO_VIEWING)
	{		
#ifdef  DEBUG_HENRY
		printf("\n----> Sketch Goto Viewing");
#endif
		
		/* Set up app_status variables */
		///		memo_top_line = 0;
		///		memo_insert_pt_pos = 0;
		
		DataRecIDtoNum(memo_dbid, rec_id, &rec_num);
		DataOpenRecord(memo_dbid, rec_num, &rec_id, NULL);
		DataGetField(memo_dbid, MEMO_EDIT_INFO, 7, &buffer, &byte_read);
#ifdef DEBUG_H
        printf("\n %ld buffer in lch = %ld %ld", rec_id, strlen(buffer), byte_read);
#endif        		
		DataWriteField(memo_dbid, rec_id, 1, byte_read, buffer);
		qfree(buffer);	
		DataCloseRecord(memo_dbid, rec_id);
		
		MemoRecordToVariable();
		MemoViewingSetUpScreen();
		strcpy(temp_cate, current_cate);
		FormGetObjectPointer(FIELD_MEMO_VIEWING, &object_type, (void **)&fld_addr);
		
		/* Disable the field object */
		show_line = FALSE;
		FormPopupForm(FORM_MEMO_VIEWING);
	}
	else
	{	
#ifdef  DEBUG_HENRY
		printf("\n----> Sketch Goto New");
#endif
		
		DataGetField(memo_dbid, MEMO_EDIT_INFO, 2, &buffer, &byte_read);
		strcpy(app_status.create_time, buffer);
		qfree(buffer);	
		
		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, 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);
		/*  Restore New Sketch status */
		FormGetObjectPointer(BITMAP_MEMO_SKETCH, &object_type, (void **)&bmp_addr);
		
		DataRecIDtoNum(memo_dbid, rec_id, &rec_num);
		DataOpenRecord(memo_dbid, rec_num, &rec_id, NULL);
		DataGetField(memo_dbid, rec_id, 0, &buffer, &byte_read);
		if (*buffer == MEMO_SKETCH)
		{
			app_status.sketch_status = MEMO_SKETCH; 
			bmp_addr->bitmap_attr.bitmap_visible = TRUE;
			bmp_addr->bitmap_attr.bitmap_enable = TRUE;
		}
		else
		{
			app_status.sketch_status = MEMO_NO_SKETCH; 
			bmp_addr->bitmap_attr.bitmap_visible = FALSE;
			bmp_addr->bitmap_attr.bitmap_enable = FALSE;
		}
		qfree(buffer);
		
#ifdef DEBUG_HENRY
		printf("\n  MemoSketchGoto B %ld", table_font);
#endif
		
		
		/* Set up Category */
		MemoCateNameToPopupTrigger(memo_dbid);
		ControlPopupDeleteItem(POPUP_TRIGGER_CATEGORY, 0);
		ControlSetLabel(POPUP_TRIGGER_CATEGORY, current_cate);
		
#ifdef DEBUG_HENRY
        printf("\n  MemoSketchGoto C %ld", table_font);
#endif
		
		
		FieldSetText(FIELD_MEMO_NEW, memo_field_buffer[0]);
		
#ifdef DEBUG_HENRY
        printf("\n  MemoSketchGoto D %ld", table_font);
#endif
		
		
		/* Set up Field Size */
		FieldSetFont(FIELD_MEMO_NEW, table_font);
		
#ifdef DEBUG_HENRY
        printf("\n  MemoSketchGoto E %ld", table_font);
#endif
		
		
		FormPopupForm(FORM_MEMO_NEW);
#ifdef DEBUG_HENRY
        printf("\n  MemoSketchGoto F %ld", table_font);
#endif
		
	}
}
/*****************************************************************
* Function:	MemoLaunchApplication
* Purpose: 	This function is used to launch to other application
*		depend on the selection
* Scope:	application
* Input:	None
* Output:	None
* Return:	None
* Comment: 	None
*****************************************************************/
void MemoLaunchApplication()
{
	MemoSketch	*memo_sketch;
	AppID   appid;
	
	
	memo_sketch = (MemoSketch *)pmalloc(sizeof(MemoSketch));
	memo_sketch->app_id = SysGetActiveAppID();
	memo_sketch->rec_id = app_status.rec_id;
	
#ifdef DEBUG_H
    printf("\n 	app_status.rec_id = %ld", app_status.rec_id);
#endif    
	
	memo_sketch->sketch_status_num = 0;
	memo_sketch->sketch_field_num = 3;
	
	if(app_status.edit_mode == MEMO_LIST)
		memo_sketch->return_mode = LAUNCH_CMD_NORMAL_LAUNCH;
	else
		memo_sketch->return_mode = LAUNCH_CMD_GOTO_REC;
	
	SysGetAppID(SKETCH, &appid);
	EvtAppendEvt(EVT_APP_STOP, 0, 0, 0, NULL);
	EvtAppendEvt(EVT_APP_LAUNCH, appid, LAUNCH_CMD_NORMAL_LAUNCH, 0, (BYTE *)memo_sketch);
}

