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



#include "app.h"

extern BOOLEAN draw_view_edit_scrollbar;

/********************************************************
* Function:	PhonebookViewEditSetupScreen
* Purpose: 	This function is called in order to setup
the screen of View Edit 
* Scope:		application
* Input:		None
* Output:		None
* Return:		TRUE			success
FALSE			error occure
* Comment: 	The screen will be set up according to the app_status
and the KeyboardCheckKeyboardStatus()
*********************************************************/
void PhonebookViewEditSetupScreen()
{
	void        *addr;
	BYTE        object_type;
	ObjectID    count_id, end_count_id;
	BYTE        *textbox_string;
	UBYTE       cate_num;
	BYTE        cate_name[30];
	USHORT      total_num_rows;
	Field       *field_ptr;
	BOOLEAN     set = FALSE;
	BYTE	    temp_text[2000], *temp_text1;
	WORD	    count = 0;
	Table	    *table_ptr;
	WORD        char_count = 0;
	ObjectID	strTemp,fldTemp;
	
	/* Initialisation of POPUP_TRIGGER_CATE */
	//hide if not in edit mode
	FormGetObjectPointer(POPUP_TRIGGER_CATE, &object_type, (void **)&addr);
	((Control*)addr)->control_attr.control_enable = TRUE;
	((Control*)addr)->control_attr.control_visible = (app_status.status != VIEW);
	FormGetObjectPointer(STRING_VIEW_EDIT_CATE, &object_type, (void **)&addr);
	//hide if in edit mode
	if (app_status.status == VIEW)
	{
		((String*)addr)->string_attr.string_visible = TRUE;
		DataRecordInfo(pb_dbid, app_status.rec_id, NULL, &cate_num, NULL, NULL, NULL);
		DataCategoryName(pb_dbid, cate_num, cate_name);
		StringSetText(STRING_VIEW_EDIT_CATE,cate_name);
	}
	else 
		((String*)addr)->string_attr.string_visible = FALSE;
	
	/* Initialisation of STRING_VIEW_EDIT_LARGE_NAME */
	FormGetObjectPointer(STRING_VIEW_EDIT_LARGE_NAME, &object_type, (void **)&addr);
	((String*)addr)->string_attr.string_visible = (app_status.status == VIEW);
	
	/* Initialisation of STRING_VIEW_EDIT_LARGE_TITLE */
	FormGetObjectPointer(STRING_VIEW_EDIT_LARGE_TITLE, &object_type, (void **)&addr);
	((String*)addr)->string_attr.string_visible = (app_status.status == VIEW && strlen(((String*)addr)->string_text));
	
	/* Initialisation of STRING_VIEW_EDIT_LARGE_COMPANY */
	FormGetObjectPointer(STRING_VIEW_EDIT_LARGE_COMPANY, &object_type, (void **)&addr);
	((String*)addr)->string_attr.string_visible = (app_status.status == VIEW && strlen(((String*)addr)->string_text));
	
	/* Initialisation of PUSHBUTTON_CINFO */
	FormGetObjectPointer(PUSHBUTTON_CINFO, &object_type, (void **)&addr);
	((Control*)addr)->control_attr.control_visible = (app_status.status != VIEW);
	((Control*)addr)->bounds.ycoord = PB_YCOORD5;
	
	/* Initialisation of PUSHBUTTON_HINFO */
	FormGetObjectPointer(PUSHBUTTON_HINFO, &object_type, (void **)&addr);
	((Control*)addr)->control_attr.control_visible = (app_status.status != VIEW);
	((Control*)addr)->bounds.ycoord = PB_YCOORD6;
	
	FormGetObjectPointer(BUTTON_DEL_HOME_COMPANY, &object_type, (void **)&addr);
	((Control*)addr)->control_attr.control_visible = ((app_status.status == VIEW)&&(app_status.new_record == FALSE));
	
	FormGetObjectPointer(BUTTON_VIEW_HOME, &object_type, (void **)&addr);
	((Control*)addr)->control_attr.control_visible = (app_status.status == VIEW);
	
	FormGetObjectPointer(BUTTON_VIEW_COMPANY, &object_type, (void **)&addr);
	((Control*)addr)->control_attr.control_visible = (app_status.status == VIEW);
	
	/* Initialisation of TABLE_VIEW_EDIT */
	FormGetObjectPointer(TABLE_VIEW_EDIT, &object_type, (void **)&table_ptr);
	table_ptr->table_attr.table_visible = TRUE;
	table_ptr->table_attr.table_enable = (app_status.status == EDIT);
	
	MenuDeleteItem(MENU_POPUP1,5);
	
	if (app_status.status == EDIT)
	{
		MenuInsertItem(MENU_POPUP1, 5, PB_SETTINGS);
		if(app_status.company)
			FormSetControlGroupSelection(FORM_VIEW_EDIT, PUSHBUTTON_CINFO);
		
		table_ptr->bounds.ycoord = (table_font_size==MEDIUM_FONT) ? 33 : 35;
		if(table_font_size==MEDIUM_FONT)
			table_ptr->bounds.height = (KeyboardCheckKeyboardStatus()) ? 55 : 110;
		else
			table_ptr->bounds.height = (KeyboardCheckKeyboardStatus()) ? 63 : 108;
		
		table_ptr->table_num_row = 12;
		//set up table position
		if(app_status.home == TRUE)
		{
			StringSetText(STRING_ROW0, PB_F_FIRSTNAME);
			StringSetText(STRING_ROW1, PB_F_LASTNAME);
			StringSetText(STRING_ROW4, PB_F_ADDRESS);
			StringSetText(STRING_ROW5, PB_F_CITY);
			StringSetText(STRING_ROW6, PB_F_STATE);
			StringSetText(STRING_ROW7, PB_F_ZIPCODE);
			StringSetText(STRING_ROW8, PB_F_COUNTRY);
			StringSetText(STRING_ROW9, PB_F_EMAIL);
			
			table_ptr->table_item_ptr[8]->table_item_ui_id=STRING_ROW4;
			table_ptr->table_item_ptr[4]->table_item_ui_id=POPUP_TRIGGER_HT;
			table_ptr->table_item_ptr[6]->table_item_ui_id=POPUP_TRIGGER_HF;
			table_ptr->table_item_ptr[20]->table_item_ui_id=POPUP_TRIGGER_HP;
			table_ptr->table_item_ptr[22]->table_item_ui_id=POPUP_TRIGGER_HM;
			
			ControlPopupSetSelectedItem(POPUP_TRIGGER_HT,field_buffers[26][3]);
			ControlPopupSetSelectedItem(POPUP_TRIGGER_HF,field_buffers[26][4]);
			ControlPopupSetSelectedItem(POPUP_TRIGGER_HP,field_buffers[26][5]);
			ControlPopupSetSelectedItem(POPUP_TRIGGER_HM,field_buffers[26][6]);
		}
		else if(app_status.company == TRUE)
		{
			
			StringSetText(STRING_ROW0, PB_F_COMPANY);
			StringSetText(STRING_ROW1, PB_F_TITLE);
			StringSetText(STRING_ROW5, PB_F_EMAIL);
			StringSetText(STRING_ROW6, PB_F_WEBSITE);
			StringSetText(STRING_ROW7, PB_F_ADDRESS);
			StringSetText(STRING_ROW8, PB_F_CITY);
			StringSetText(STRING_ROW9, PB_F_STATE);
			StringSetText(STRING_ROW10,PB_F_ZIPCODE);
			StringSetText(STRING_ROW11,PB_F_COUNTRY);
			
			table_ptr->table_item_ptr[20]->table_item_ui_id=STRING_ROW10;
			table_ptr->table_item_ptr[22]->table_item_ui_id=STRING_ROW11;
			table_ptr->table_item_ptr[4]->table_item_ui_id=POPUP_TRIGGER_OT;
			table_ptr->table_item_ptr[6]->table_item_ui_id=POPUP_TRIGGER_DL;
			table_ptr->table_item_ptr[8]->table_item_ui_id=POPUP_TRIGGER_OF;
			
			ControlPopupSetSelectedItem(POPUP_TRIGGER_OT,field_buffers[26][0]);
			ControlPopupSetSelectedItem(POPUP_TRIGGER_DL,field_buffers[26][1]);
			ControlPopupSetSelectedItem(POPUP_TRIGGER_OF,field_buffers[26][2]);
		}
		
		for(count_id = FIELD_ROW0;count_id<=FIELD_ROW11;count_id++)
		{
			FormGetObjectPointer(count_id, &object_type, (void **)&field_ptr);
			field_ptr->field_font_id = (table_font_size == SMALL_FONT) ? SMALL_FONT : MEDIUM_FONT;
			field_ptr->field_back_line = GREY_LINE;
		}
		
		FormGetObjectPointer(FIELD_ROW0, &object_type, (void **)&addr);
		field_ptr->field_max_chars = (app_status.company == TRUE) ? 100 : 70;
		
		FormGetObjectPointer(FIELD_ROW1, &object_type, (void **)&addr);
		field_ptr->field_max_chars = (app_status.company == TRUE) ? 100 : 70;
		
		FormGetObjectPointer(FIELD_ROW2, &object_type, (void **)&addr);
		field_ptr->field_max_chars = (app_status.company == TRUE) ? 32 : 32;
		
		FormGetObjectPointer(FIELD_ROW3, &object_type, (void **)&addr);
		field_ptr->field_max_chars = (app_status.company == TRUE) ? 32 : 32;
		
		FormGetObjectPointer(FIELD_ROW4, &object_type, (void **)&addr);
		field_ptr->field_max_chars = (app_status.company == TRUE) ? 32 : 200;
		
		FormGetObjectPointer(FIELD_ROW5, &object_type, (void **)&addr);
		field_ptr->field_max_chars = (app_status.company == TRUE) ? 100 : 40;
		
		FormGetObjectPointer(FIELD_ROW6, &object_type, (void **)&addr);
		field_ptr->field_max_chars = (app_status.company == TRUE) ? 100 : 40;
		
		FormGetObjectPointer(FIELD_ROW7, &object_type, (void **)&addr);
		field_ptr->field_max_chars = (app_status.company == TRUE) ? 200 : 20;
		
		FormGetObjectPointer(FIELD_ROW8, &object_type, (void **)&addr);
		field_ptr->field_max_chars = 40;
		
		FormGetObjectPointer(FIELD_ROW9, &object_type, (void **)&addr);
		field_ptr->field_max_chars = (app_status.company == TRUE) ? 40 : 100;
		
		FormGetObjectPointer(FIELD_ROW10, &object_type, (void **)&addr);
		field_ptr->field_max_chars = (app_status.company == TRUE) ? 20 : 32;
		
		FormGetObjectPointer(FIELD_ROW11, &object_type, (void **)&addr);
		field_ptr->field_max_chars = (app_status.company == TRUE) ? 40 : 32;
	}
	
	//load fields with data
	if (app_status.status == VIEW)
	{
		//position text
		StringGetText(STRING_VIEW_EDIT_LARGE_COMPANY, &temp_text1);
		if (strlen(temp_text1) == 0)
		{
			table_ptr->bounds.ycoord = 45;
			table_ptr->bounds.height = 90;
		}
		else 
		{	
			table_ptr->bounds.ycoord = 63;
			table_ptr->bounds.height = (table_font_size==MEDIUM_FONT) ? 77 : 72;
		}
		
		total_num_rows = 0;
		table_ptr->table_num_row = 12;
		
		for (count_id = FIELD_ROW0; count_id <= FIELD_ROW11; count_id++)
			FieldSetMaxNumChars(count_id, 32768);
		fldTemp = FIELD_ROW0;
		strTemp = STRING_ROW0;
		for (count_id = FIELD_ROW2; count_id <= FIELD_ROW11; count_id++)
		{
			FormGetObjectPointer(count_id, &object_type, (void**)&field_ptr);
			
			//concat address,city,state,zip,country
			if((count_id == FIELD_ROW7 && app_status.company == TRUE)||(count_id == FIELD_ROW4 && app_status.home == TRUE)) 
			{
				strcpy(temp_text,"");
				FormGetObjectPointer(count_id, &object_type, (void**)&field_ptr);
				if(strlen(field_ptr->field_string))
				{
					strcat(temp_text,field_ptr->field_string);
					strcat(temp_text,"\r");
				}
				FormGetObjectPointer(count_id + 1, &object_type, (void**)&field_ptr);
				if(strlen(field_ptr->field_string))
				{
					strcat(temp_text,field_ptr->field_string);
					strcat(temp_text,", ");
				}
				FormGetObjectPointer(count_id + 2, &object_type, (void**)&field_ptr);
				if(strlen(field_ptr->field_string))
				{
					strcat(temp_text,field_ptr->field_string);
					strcat(temp_text," ");
				}
				FormGetObjectPointer(count_id + 3, &object_type, (void**)&field_ptr);
				if(strlen(field_ptr->field_string))
				{
					strcat(temp_text,field_ptr->field_string);
					if(strlen(temp_text))
						strcat(temp_text,"\r");
				}
				FormGetObjectPointer(count_id + 4, &object_type, (void**)&field_ptr);
				if(strlen(field_ptr->field_string))
				{
					strcat(temp_text,field_ptr->field_string);
				}
				
				if (strlen(temp_text))
				{
					StringSetText(strTemp, PB_F_ADDRESS);
					FieldSetText(fldTemp, temp_text);
					fldTemp++;
					strTemp++;
				}
				
				count_id = count_id + 4;
				continue;
			}
			
			if(strlen(field_ptr->field_string))
			{
				FieldSetText(fldTemp, field_ptr->field_string);
				switch (count_id)
				{
				case FIELD_ROW2: 
				case FIELD_ROW3: 
				case FIELD_ROW4: 
				case FIELD_ROW10: 
				case FIELD_ROW11: 
					if (app_status.company)
					{
						switch(field_buffers[26][count_id - FIELD_ROW2])
						{
						case 0:
							StringSetText(strTemp, PB_F_CTEL);
							break;
						case 1:
							StringSetText(strTemp, PB_F_DIRLINE);
							break;
						case 2:
							StringSetText(strTemp, PB_F_CFAX);
							break;
						case 3:
							StringSetText(strTemp, PB_F_CPAGER);
							break;
						case 4:
							StringSetText(strTemp, PB_F_CMOBILE);
							break;
						}
					}
					else
					{
						char_count = (count_id>FIELD_ROW8) ? FIELD_ROW8 : FIELD_ROW2;
						switch(field_buffers[26][count_id - char_count + 3])
						{
						case 0:
							StringSetText(strTemp, PB_F_HTEL);
							break;
						case 1:
							StringSetText(strTemp, PB_F_HFAX);
							break;
						case 2:
							StringSetText(strTemp, PB_F_HPAGER);
							break;
						case 3:
							StringSetText(strTemp, PB_F_HMOBILE);
							break;
						}
					}
					break;
				case FIELD_ROW5: 
				case FIELD_ROW9: 
					StringSetText(strTemp, PB_F_EMAIL);
					break;
				case FIELD_ROW6: 
					StringSetText(strTemp, PB_F_WEBSITE);
					break;
				default: 
					break;
				}		
				fldTemp++;
				strTemp++;
			}
		}
		table_ptr->table_num_row = fldTemp - FIELD_ROW0;
	}
	
	// initialization of scrollbar
	FormGetObjectPointer(SCROLLBAR_VIEW_EDIT, &object_type, (void **)&addr);
	((Scrollbar*)addr)->bounds.ycoord = table_ptr->bounds.ycoord;
	((Scrollbar*)addr)->bounds.height = table_ptr->bounds.height;
	
	//show notes bitmaps if needed
	FormGetObjectPointer(BITMAP_NOTES, &object_type, (void **)&addr);
	((Bitmap*)addr)->bitmap_attr.bitmap_visible = (strlen(field_buffers[25])>0)||(app_status.status==EDIT);
}		

/********************************************************
* Function:	PhonebookRedrawWithKeyboard
* Purpose: 	This function is called in order to redraw 
the VIEW EDIT screen when the keyboard is popup
* Scope:		application
* Input:		None
* Output:		None
* Return:		
* Comment: 	
*********************************************************/
void PhonebookRedrawWithKeyboard()
{
	TableEraseTable(TABLE_VIEW_EDIT);
	TableDrawTable(TABLE_VIEW_EDIT);
	ScrollbarDrawScrollbar(SCROLLBAR_VIEW_EDIT);
}

/********************************************************
* Function:	PhonebookClearFieldBuffers
* Purpose: 	This function is used to clear the 21 field buffers
* Scope:		application
* Input:		None
* Output:		None
* Return:		None
* Comment: 	None
*********************************************************/
void PhonebookClearFieldBuffers()
{
	USHORT count;
	
	for(count = 0; count<27;count++)
	{
		if (field_buffers[count] !=NULL)
		{
			qfree(field_buffers[count]);
			field_buffers[count] = NULL;
		}
	}
}

/********************************************************
* Function:	PhonebookInitFieldBuffers
* Purpose: 	This function is used to clear the 21 field buffers
* Scope:		application
* Input:		None
* Output:		None
* Return:		None
* Comment: 	None
*********************************************************/
void PhonebookInitFieldBuffers()
{
	USHORT count;
	
	for(count = 0; count<26;count++)
	{
		if (field_buffers[count] !=NULL)
			qfree(field_buffers[count]);
		field_buffers[count] = (BYTE*)qmalloc(sizeof(BYTE));
		strcpy(field_buffers[count],(BYTE*)(""));
	}
	field_buffers[26] = (BYTE*)qmalloc(8*sizeof(BYTE));
	field_buffers[26][0] = 0;
	field_buffers[26][1] = 1;
	field_buffers[26][2] = 2;
	field_buffers[26][3] = 0;
	field_buffers[26][4] = 1;
	field_buffers[26][5] = 2;
	field_buffers[26][6] = 3;
	field_buffers[26][7] = 5;
}

/********************************************************
* Function:	PhonebookFieldBuffersToField
* Purpose: 	This function is called to send data from field buffers to 
corresponding UI objects
* Scope:		application
* Input:		None
* Output:		None
* Return:		TRUE			success
FALSE			error occure
* Comment: 	The screen will be set up according to the app_status
and the KeyboardCheckKeyboardStatus()
*********************************************************/
void PhonebookFieldBuffersToField()
{
	USHORT		count;
    BYTE        out_string[200];
    Table		*table_ptr;
    BYTE        object_type;
	
    FormGetObjectPointer(TABLE_VIEW_EDIT, &object_type, (void**)&table_ptr);
    table_ptr->table_num_row = 12;
	
	PhonebookPrepareFirstLastName(field_buffers[0], field_buffers[1], out_string);
	StringSetText(STRING_VIEW_EDIT_LARGE_NAME, out_string);
	
	StringSetText(STRING_VIEW_EDIT_LARGE_TITLE,		field_buffers[4]);
	StringSetText(STRING_VIEW_EDIT_LARGE_COMPANY,	field_buffers[3]);
	
	if (app_status.company == TRUE)
	{
		FieldSetMaxNumChars(FIELD_ROW0, 100);	//company
		FieldSetMaxNumChars(FIELD_ROW1, 100);	//title
		FieldSetMaxNumChars(FIELD_ROW2, 32);	//office tel
		FieldSetMaxNumChars(FIELD_ROW3, 32);	//direct line
		FieldSetMaxNumChars(FIELD_ROW4, 32);	//fax
		FieldSetMaxNumChars(FIELD_ROW5, 100);	//e-mail
		FieldSetMaxNumChars(FIELD_ROW6, 100);	//web site
		FieldSetMaxNumChars(FIELD_ROW7, 200);	//address
		FieldSetMaxNumChars(FIELD_ROW8, 40);	//city
		FieldSetMaxNumChars(FIELD_ROW9, 40);	//state
		FieldSetMaxNumChars(FIELD_ROW10, 20);	//zip
		FieldSetMaxNumChars(FIELD_ROW11, 40);	//country
		for(object_type=FIELD_ROW0;object_type<=FIELD_ROW11;object_type++)
			FieldSetText(object_type,field_buffers[3 + (object_type - FIELD_ROW0)]);
	}
	else if (app_status.home == TRUE)
	{	
		FieldSetMaxNumChars(FIELD_ROW0, 70);	//first name
		FieldSetMaxNumChars(FIELD_ROW1, 70);	//last name
		
		FieldSetMaxNumChars(FIELD_ROW2, 32);	//home tel
		FieldSetMaxNumChars(FIELD_ROW3, 32);	//home fax
		FieldSetMaxNumChars(FIELD_ROW4, 200);	//home address
		FieldSetMaxNumChars(FIELD_ROW5, 40);	//city
		FieldSetMaxNumChars(FIELD_ROW6, 40);	//state
		FieldSetMaxNumChars(FIELD_ROW7, 20);	//zip
		FieldSetMaxNumChars(FIELD_ROW8, 40);	//country
		FieldSetMaxNumChars(FIELD_ROW9, 100);	//email
		FieldSetMaxNumChars(FIELD_ROW10, 32);	//pager
		FieldSetMaxNumChars(FIELD_ROW11, 32);	//mobile
		
		FieldSetText((ObjectID)FIELD_ROW0, field_buffers[0]);	//first name
		FieldSetText((ObjectID)FIELD_ROW1, field_buffers[1]);	//last name
		for(object_type=FIELD_ROW2;object_type<=FIELD_ROW11;object_type++)
			FieldSetText(object_type,field_buffers[15 + (object_type - FIELD_ROW2)]);
	}
}

/********************************************************
* Function:	PhonebookFieldtoFieldBuffer
* Purpose: 	This function is called in order to put the data
in the field objects to field buffers
* Scope:		application
* Input:		dbid			The ID of the database
record_id		The ID of the record that is required to be 
put in the field objects
* Output:		None
* Return:		TRUE			Success
FALSE			FALSE
* Comment: 	None
*********************************************************/
void PhonebookFieldToFieldBuffer()
{
	BYTE *temp;
	BYTE count = 0;
	BYTE *first_name, *last_name;
	BYTE out_string[200];
	
	if(app_status.status==EDIT)
	{
		if (app_status.company == TRUE)
		{
			for(count = FIELD_ROW0;count<=FIELD_ROW11;count++)
			{
				FieldGetTextPointer(count, &temp);
				field_buffers[3 + (count - FIELD_ROW0)] = (BYTE*)qmalloc((strlen(temp) + 1)*sizeof(BYTE));
				strcpy(field_buffers[3 + (count - FIELD_ROW0)],temp);
			}
		}
		else if (app_status.home == TRUE)
		{
			for (count = 0; count < 3; count++)
			{
				if (field_buffers[count] != NULL)
					qfree(field_buffers[count]);
			}
			FieldGetTextPointer(FIELD_ROW0, &temp);
			field_buffers[0] = (BYTE*)qmalloc((strlen(temp) + 1)*sizeof(BYTE));
			strcpy(field_buffers[0],temp);
			FieldGetTextPointer(FIELD_ROW1, &temp);
			field_buffers[1] = (BYTE*)qmalloc((strlen(temp) + 1)*sizeof(BYTE));
			strcpy(field_buffers[1],temp);
			
			
			//HENRY 001229
			//if (strlen(field_buffers[0]) == 0 || strlen(field_buffers[1]) == 0)
			//	PhonebookPrepareLastFirstNameForDisplay(field_buffers[0], field_buffers[1], out_string);
			//			else 
			PhonebookPrepareLastFirstNameForDisplay1(field_buffers[0], field_buffers[1], out_string);
			
			field_buffers[2] = (BYTE*)qmalloc((strlen(out_string) + 1)*sizeof(BYTE));
			strcpy(field_buffers[2], out_string);
			
			for(count = FIELD_ROW2;count<=FIELD_ROW11;count++)
			{
				FieldGetTextPointer(count, &temp);
				field_buffers[15 + (count - FIELD_ROW2)] = (BYTE*)qmalloc((strlen(temp) + 1)*sizeof(BYTE));
				strcpy(field_buffers[15 + (count - FIELD_ROW2)],temp);
			}
		}
	}
	else if(app_status.status==NOTES_EDIT)
	{
		if (field_buffers[25] != NULL)
			qfree(field_buffers[25]);
		FieldGetTextPointer(FIELD_NOTES, &temp);
		field_buffers[25]=(BYTE*)qmalloc((strlen(temp)+1)*sizeof(BYTE));
		strcpy(field_buffers[25], temp);				
	}
}

/********************************************************
* Function:	PhonebookRecordToFieldBuffers
* Purpose: 	This function is called in order to store all data from 
record to field buffers
* Scope:		application
* Input:		rec_id			The record 
* Output:		None
* Return:		TRUE		Success
FALSE		NotHandled
* Comment: 	None
*********************************************************/
BOOLEAN PhonebookRecordToFieldBuffers(RecordID rec_id)
{
	UWORD 		rec_num;
	BYTE 		*buffer;
	UWORD 		byte_read;
	USHORT 		count=0;
    BYTE        out_string[200];
    Err         error1, error2;
	
    error1 = DataRecIDtoNum(pb_dbid, rec_id, &rec_num);
    error2 = DataOpenRecord(pb_dbid, rec_num, &rec_id, NULL);
	
    for (count = 0; count <26; count++)
	{
		if (count == 2) //skip last,first first,last fields
			continue;
		DataGetField(pb_dbid, rec_id, count, &buffer, &byte_read);
		if (field_buffers[count] != NULL)
			qfree(field_buffers[count]);
		field_buffers[count] = (BYTE*)qmalloc((strlen(buffer) + 1)*sizeof(BYTE));
		strcpy(field_buffers[count], buffer);
		qfree(buffer);
	}
	
	if (field_buffers[2] != NULL)
		qfree(field_buffers[2]);
	
	//HENRY 001229
	//if (strlen(field_buffers[0]) == 0 || strlen(field_buffers[1]) == 0)
	//	PhonebookPrepareLastFirstNameForDisplay1(field_buffers[0], field_buffers[1], out_string);
	//else 
	PhonebookPrepareLastFirstNameForDisplay1(field_buffers[0], field_buffers[1], out_string);
	field_buffers[2] = (BYTE*)qmalloc((strlen(out_string) + 1)*sizeof(BYTE));
	strcpy(field_buffers[2], out_string);
	
	
	DataGetField(pb_dbid, rec_id, 27, &buffer, &byte_read);
	
	//index settings
	if (field_buffers[26] != NULL)
		qfree(field_buffers[26]);
	field_buffers[26] = (BYTE*)qmalloc(8*sizeof(BYTE));
	
	field_buffers[26][0] = buffer[0];
	field_buffers[26][1] = buffer[1];
	field_buffers[26][2] = buffer[2];
	field_buffers[26][3] = buffer[3];
	field_buffers[26][4] = buffer[4];
	field_buffers[26][5] = buffer[5];
	field_buffers[26][6] = buffer[6];
	qfree(buffer);
	
	if(DataGetField(pb_dbid,rec_id,28,&buffer,&byte_read)!=TRUE)
	{
		qfree(buffer);
		buffer = qmalloc(1*sizeof(BYTE));
		buffer[0] = 0;
	}
	field_buffers[26][7]=*(BYTE*)buffer;
	qfree(buffer);
	
	DataCloseRecord(pb_dbid, rec_id);
	return TRUE;
}

/********************************************************
* Function:	PhonebookSaveRecord
* Purpose: 	This function is called in order to save the edited record
back into database.
* Scope:		application
* Input:		dbid			The ID of the database
record_id		The ID of the record that is required to be 
put in the field objects
new_record		BOOLENA variable to show whether new record or 
old record 
* Output:		None
* Return:		TRUE			Success
FALSE			FALSE
* Comment: 	None
*********************************************************/
BOOLEAN PhonebookSaveRecord(DatabaseID pb_dbid, RecordID rec_id, BOOLEAN new_record)
{
	BYTE        *cate_name = NULL;
    UBYTE       cate_num,email_cate;
	SHORT       item_num;
	USHORT      count;
	UWORD       rec_num;
    BYTE        out_string[200];
	BYTE		item;
    Err         error;
    
    
	if (new_record == TRUE)
	{
		ControlPopupGetSelectedItem(POPUP_TRIGGER_CATE, &item_num);
		if ((item_num == -1) || (item_num == 0))
		{
			DataNewRecord(pb_dbid,0,31,&rec_id);
			if (save_cate != NULL)
				qfree(save_cate);
			save_cate = (BYTE*)qmalloc(30*sizeof(BYTE));
			strcpy(save_cate, PBUNFILED);
            cate_num = 0;
		}
		else
		{
			ControlPopupGetPopupItem(POPUP_TRIGGER_CATE, item_num, &cate_name);
			PhonebookCateNameToNum(pb_dbid, cate_name, &cate_num);
			DataNewRecord(pb_dbid,cate_num,31,&rec_id);
			if (save_cate != NULL)
				qfree(save_cate);
			save_cate = (BYTE*)qmalloc(30*sizeof(BYTE));
			strcpy(save_cate, cate_name);
		}
        email_cate = 0;
        DataWriteField(pb_dbid,rec_id,26, 1 , (BYTE*)&email_cate);
	}
	else
	{
        if (DataRecordInfo(pb_dbid, rec_id, NULL, NULL, NULL, NULL, NULL) != TRUE)
        {            
			DataNewRecord(pb_dbid,cate_num,31,&rec_id);
			
            app_status.rec_id = rec_id;
            email_cate = 0;
            DataWriteField(pb_dbid,rec_id,26, 1 , (BYTE*)&email_cate);
        }
        else 
        {
            DataRecIDtoNum(pb_dbid, rec_id, &rec_num);
			DataOpenRecord(pb_dbid, rec_num, &rec_id, NULL);
        }
		ControlPopupGetSelectedItem(POPUP_TRIGGER_CATE, &item_num);
		if ((item_num == -1) || (item_num == 0))
		{
			if (save_cate != NULL)
				qfree(save_cate);
			save_cate = (BYTE*)qmalloc(30*sizeof(BYTE));
            cate_num = 0;
			DataCategoryName(pb_dbid, 0, save_cate);
			DataSetRecordAttribute(pb_dbid, rec_id, ATTR_UNCHG, ATTR_UNCHG, 0);
		}
		else
		{
			ControlPopupGetPopupItem(POPUP_TRIGGER_CATE, item_num, &cate_name);
			if (save_cate != NULL)
				qfree(save_cate);
			save_cate = (BYTE*)qmalloc(30*sizeof(BYTE));
			strcpy(save_cate, cate_name);
			PhonebookCateNameToNum(pb_dbid, cate_name, &cate_num);
			DataSetRecordAttribute(pb_dbid, rec_id, ATTR_UNCHG, ATTR_UNCHG, cate_num);
		}
	}
	
	for (count = 0; count <26; count++)
		DataWriteField(pb_dbid,rec_id,count,(strlen(field_buffers[count]) + 1),field_buffers[count]);
	
	//need to save field 27 index
	DataWriteField(pb_dbid,rec_id,27,7,field_buffers[26]);
	
	//need to save field 28 selected no
	item = field_buffers[26][7];
    DataWriteField(pb_dbid,rec_id,28,1,&item);
	
	//create last name, first name
	if((strlen(field_buffers[0])==0)&&(strlen(field_buffers[1])==0))
		sprintf(out_string,"%s",field_buffers[3]);  //use company
	else if(strlen(field_buffers[0])==0)
		sprintf(out_string,"%s",field_buffers[1]);
	else if(strlen(field_buffers[1])==0)
		sprintf(out_string,"%s",field_buffers[0]);
	else
		sprintf(out_string,"%s,%s",field_buffers[1],field_buffers[0]);
	
	DataWriteField(pb_dbid,rec_id,2,(strlen(out_string) + 1),out_string);
	if(sort_mode==2)
		save_first_letter = out_string[0];
	
	//create company, last name
	if((strlen(field_buffers[3])==0)&&(strlen(field_buffers[1])==0))
		sprintf(out_string,"%s",field_buffers[0]);  //use first name
	else if(strlen(field_buffers[3])==0)
		sprintf(out_string,"%s",field_buffers[1]);
	else if(strlen(field_buffers[1])==0)
		sprintf(out_string,"%s",field_buffers[3]);
	else
		sprintf(out_string,"%s,%s",field_buffers[3],field_buffers[1]);
	
	DataWriteField(pb_dbid,rec_id,29,(strlen(out_string) + 1),out_string);
	if(sort_mode==29)
		save_first_letter = out_string[0];
	
	//create first name last name
	if((strlen(field_buffers[0])==0)&&(strlen(field_buffers[1])==0))
		sprintf(out_string,"%s",field_buffers[3]);  //use company info
	else if(strlen(field_buffers[0])==0)
		sprintf(out_string,"%s",field_buffers[1]);
	else if(strlen(field_buffers[1])==0)
		sprintf(out_string,"%s",field_buffers[0]);
	else
		sprintf(out_string,"%s %s",field_buffers[0],field_buffers[1]);
	
	DataWriteField(pb_dbid,rec_id,30,(strlen(out_string) + 1),out_string);
	if(sort_mode==30)
		save_first_letter = out_string[0];
	
    if (strlen(field_buffers[8]))
		DataSetRecordAttribute(pb_dbid, rec_id, ATTR_SET, ATTR_UNCHG, cate_num);
    else if (strlen(field_buffers[22]))
		DataSetRecordAttribute(pb_dbid, rec_id, ATTR_CLR, ATTR_UNCHG, cate_num);
    else
		DataSetRecordAttribute(pb_dbid, rec_id, ATTR_SET, ATTR_UNCHG, cate_num);
	
	DataCloseRecord(pb_dbid,rec_id);
	
	
	return TRUE;
}

/********************************************************
* Function:	PhonebookCombineFirstLastName
* Purpose: 	This function is called in order to combine two text strings
into one
* Scope:		application
* Input:		in_string1
*				in_string2
* Output:		None
* Return:		TRUE		Success
FALSE		NotHandled
* Comment: 	The string will be put to field_buffers[0], field_buffers[1] and
field_buffers[2]
*********************************************************/
void PhonebookCombineFirstLastName(BYTE *in_string1, BYTE *in_string2)
{
	BYTE *temp, *temp1;
	USHORT count;
	
	temp = (BYTE*)qmalloc(((strlen(in_string1) + strlen(in_string2)) * 2 + 2)*sizeof(BYTE));			
	temp1 = temp;
	if (strlen(in_string1) != 0)
	{
		strcpy(temp,in_string1);
		temp += strlen(in_string1);
		*temp = 32;
		temp++;
	}
	strcpy(temp,in_string2);
	for (count = 0; count < 3; count++)
	{
		if (field_buffers[count] != NULL)
			qfree(field_buffers[count]);
	}
	field_buffers[0] = (BYTE*)qmalloc((strlen(in_string1) + 1)*sizeof(BYTE));
	field_buffers[1] = (BYTE*)qmalloc((strlen(in_string2) + 1)*sizeof(BYTE));
	field_buffers[2] = (BYTE*)qmalloc((strlen(temp1) + 1)*sizeof(BYTE));
	strcpy(field_buffers[0],in_string1);
	strcpy(field_buffers[1],in_string2);
	strcpy(field_buffers[2],temp1);
}

/********************************************************
* Function:	PhonebookGetTableNumLines
* Purpose: 	This function is called in order to get
the total number of lines in table a object (if 
a column is full of field objects
* Scope:		application
* Input:		table_id			The ID value of table object to be scrolled
*				ref_col				the column number of the reference row
* Output:		total_num_lines		The total number of lines
* Return:		TRUE		Success
FALSE		NotHandled
* Comment: 	The reference row should consists only of field objects
*********************************************************/
BOOLEAN PhonebookGetTableNumLines(ObjectID table_id, USHORT ref_col, WORD *total_num_lines)
{
	Table *addr;
	BYTE object_type;
	USHORT num_rows, count;
	WORD field_num_lines;
	
	if (FormGetObjectPointer(table_id, &object_type, (void**)&addr) != TRUE)
		return FALSE;
	
	num_rows = addr->table_num_row;
	*total_num_lines = 0;
	
	for (count = ref_col; count < (addr->table_num_row * addr->table_num_column); count += addr->table_num_column)
	{
		FieldGetTotalNumOfLines((ObjectID)((addr->table_item_ptr[count])->table_item_ui_id), &field_num_lines);
		*total_num_lines += (USHORT)field_num_lines;
	}
	return TRUE;
}

/********************************************************
* Function:	PhonebookGetTableMaxNumLines
* Purpose: 	This function is called to in order to get
the max num of lines that the table can 
handle
* Scope:		application
* Input:		table_id			The ID value of table object to be scrolled
*				font_id				The font type
* Output:		max_num_lines		The maximum number of lines
* Return:		TRUE		Success
FALSE		NotHandled
* Comment: 	None
*********************************************************/
BOOLEAN PhonebookGetTableMaxNumLines(ObjectID table_id, BYTE font_id, WORD *max_num_lines)
{
	Table *addr;
	BYTE object_type;
	SHORT table_height;
	SHORT line_height;
	
	if (FormGetObjectPointer(table_id, &object_type, (void**)&addr) != TRUE)
		return FALSE;
	
	table_height = addr->bounds.height;
	line_height = SysGetFontHeight(font_id) + SPACE_LINE;
	
	*max_num_lines = table_height / line_height;
	return TRUE;
}

/********************************************************
* Function:	PhonebookGetScrollBarMaxValue
* Purpose: 	This fucntion is called in order to work out the 
max value of the scrollbar
* Scope:		application
* Input:		None
* Output:		None
* Return:		max. value
* Comment: 	None
*********************************************************/
WORD PhonebookGetScrollbarMaxValue(ObjectID table_id, USHORT ref_col)
{
	Table *table_ptr;
	SHORT count = 0;
	WORD acc_num_lines = 0;
	WORD max_num_lines;
	BYTE object_type;
	BYTE font_id;
	WORD num_lines;
	WORD total_num_lines;
	
	FormGetObjectPointer(table_id, &object_type, (void**)&table_ptr);
	FieldGetFont(table_ptr->table_item_ptr[ref_col]->table_item_ui_id, &font_id);
	PhonebookGetTableMaxNumLines(table_id, font_id, &max_num_lines);
	PhonebookGetTableNumLines(table_id, ref_col, &total_num_lines);
    if (table_ptr->table_num_row == 1)
    {
        FieldGetTotalNumOfLines((ObjectID)(table_ptr->table_item_ptr[ref_col]->table_item_ui_id), &num_lines);
        return (num_lines - max_num_lines);
    }
	
    for (count = (table_ptr->table_num_row - 1); count >= 0; count--)
	{
		FieldGetTotalNumOfLines((ObjectID)(table_ptr->table_item_ptr[count * table_ptr->table_num_column + ref_col]->table_item_ui_id), &num_lines);
		acc_num_lines += num_lines;
		
		if (acc_num_lines > max_num_lines)
		{
			acc_num_lines -= num_lines;
            if (acc_num_lines == 0)
                acc_num_lines = max_num_lines;
			return (total_num_lines - acc_num_lines);
		}
	}
	return (total_num_lines - acc_num_lines);
}

/********************************************************
* Function:	EmailDecideTopRowNum
* Purpose:		This function is called to decide the to row number
of the table with field objects
* Scope:		application
* Input:		table_id			The ID value of table object to be scrolled
field_id			The focused field object
* Output:		None
* Return:		TRUE		Success
FALSE		NotHandled
* Comment: 	The decision is made depending on the 
*********************************************************/
BOOLEAN PhonebookDecideTopRowNum(ObjectID table_id, ObjectID active_id)
{
	Table *addr;
	ObjectID first_field_id;
	BYTE object_type;
	USHORT count;
	USHORT active_row;
	BYTE font_id;
	WORD max_num_lines;
	USHORT acc_num_lines = 0;
	USHORT row_num;
	WORD field_num_lines;
	Field *field_ptr;
	SHORT line_height;
	BOOLEAN return_boolean = FALSE;
	
	if (FormGetObjectPointer(table_id, &object_type, (void**)&addr) != TRUE)
		return FALSE;
	
	first_field_id = (addr->table_item_ptr[1])->table_item_ui_id;
	
	FieldGetFont(active_id, &font_id);	
	line_height = SysGetFontHeight(font_id) + SPACE_LINE;
	
	for(count = 0; count < (addr->table_num_row); count++)
		if (active_id == (ObjectID)(first_field_id + count)) active_row = count;
		
		PhonebookGetTableMaxNumLines(table_id, font_id, &max_num_lines);
		
		row_num = addr->table_top_row_num;
		
		while (row_num < (addr->table_num_row))
		{			
			TableUpdateObjectScreenBounds(table_id, (ObjectID)(first_field_id + row_num));
			FormGetObjectPointer((ObjectID)(first_field_id + row_num), &object_type, (void**)&field_ptr);
			StrAnalyzeLine(field_ptr);
			FieldGetTotalNumOfLines((ObjectID)(first_field_id + row_num), &field_num_lines);
			acc_num_lines += (USHORT)field_num_lines;
			if ((acc_num_lines > max_num_lines) && row_num <= active_row &&
				addr->table_top_row_num != active_row)
			{
				acc_num_lines = 0;
				addr->table_top_row_num ++;
				row_num = addr->table_top_row_num;
				field_num_lines = 0;
				return_boolean = TRUE;
			}
			else if ((acc_num_lines > max_num_lines) && row_num == active_row &&
				addr->table_top_row_num == active_row)
			{
				FormGetObjectPointer((ObjectID)(first_field_id + active_row), &object_type, (void**)&field_ptr);
				if (field_ptr->bounds.height != max_num_lines * line_height)
				{	
					field_ptr->bounds.height = field_ptr->field_total_num_lines * line_height;
					addr->table_row_height[active_row] = field_ptr->bounds.height;
					return TRUE;
				}
				else return FALSE;
			}
			else if ((acc_num_lines > max_num_lines) && addr->table_top_row_num == active_row &&
				row_num > active_row)
				return FALSE;
			else if (acc_num_lines == max_num_lines && row_num >= active_row)
			{
				if (return_boolean == FALSE) return FALSE;
				else return TRUE;
			}
			else if (acc_num_lines < max_num_lines && row_num == addr->table_num_row - 1)
			{
				if (return_boolean == FALSE) return FALSE;
				else return TRUE;
			}
			else row_num++;
		}
		return TRUE;
}

/********************************************************
* Function:	PhonebookSetViewEditTable
* Purpose: 	This function is called in order to 
set up the table in the Email Edit screen 
when the data is first put to table or the ekyboard is popuped 
up and down
* Scope:		application
* Input:		form_id				The ID value of the form that the table is on
table_id			The ID value of table object to be scrolled
* Output:		None
* Return:		TRUE		Success
FALSE		NotHandled
* Comment: 	None
*********************************************************/
BOOLEAN PhonebookSetViewEditTable(ObjectID form_id, ObjectID table_id)
{
	ObjectID first_field_id;	//the field object id in the first row of the table 
	ObjectID active_id;			//The ID value of the field object in the table 
	WORD count = 0;				// another temperatory variable 
	BYTE object_type;
	Table *table_ptr;
	Field *field_ptr;
	USHORT table_num_rows;
	WORD table_max_num_lines, total_num_lines;
	BYTE font_id;
	SHORT field_height;
	SHORT line_height;			/* line_height = SysGetFontHeight(font_id) + SPACE_LINE;*/
	BOOLEAN insert_pt_on = FALSE;
	USHORT table_top_row_num, table_num_row_displayed;
	SHORT acc_height = 0;
	WORD first_visible_char, last_visible_char;
	
	/*The bounds of the table should be set outside this function according
	to the keyboard status */	  
	
	FormGetObjectPointer(table_id, &object_type, (void**)&table_ptr);
	first_field_id = (table_ptr->table_item_ptr[1])->table_item_ui_id;
	table_num_rows = table_ptr->table_num_row;
	
	FieldGetFont(first_field_id, &font_id);
	
	PhonebookGetTableMaxNumLines(table_id, font_id, &table_max_num_lines);
	PhonebookGetTableNumLines(table_id, 1, &total_num_lines);
	line_height = SysGetFontHeight(font_id) + SPACE_LINE;
	FormGetActiveObject(form_id, &active_id);
	
	for (count = FIELD_ROW0; count < (FIELD_ROW0 + table_num_rows); count++)
	{
		FormGetObjectPointer((ObjectID)(count), &object_type, (void**)&field_ptr);	
		field_ptr->bounds.height = 9;
		table_ptr->table_row_height[(count - FIELD_ROW0)];
	}
	
	
	if (active_id < first_field_id || active_id > (table_num_rows - 1 + first_field_id))
		active_id = (ObjectID)(table_ptr->table_top_row_num + first_field_id);
	else
	{
		FormGetObjectPointer(active_id, &object_type, (void**)&field_ptr);		
		insert_pt_on = field_ptr->field_attr.field_insert_pt_visible;
	}
	
	if (table_max_num_lines >= total_num_lines)
		table_ptr->table_top_row_num = 0;
	
	/*set up the bounds of the field object*/
	for (count = 0; count < table_num_rows; count++)
	{
		FormGetObjectPointer((ObjectID)(count + first_field_id), &object_type, (void**)&field_ptr);		
		field_height = field_ptr->field_total_num_lines * line_height;
		if (field_height >= table_ptr->bounds.height)
		{
			table_ptr->table_row_height[count] = table_ptr->bounds.height;
			field_ptr->bounds.height = table_ptr->bounds.height;
		}
		else
		{
			table_ptr->table_row_height[count] = field_height;
			field_ptr->bounds.height = field_height;
		}
	}
	PhonebookDecideTopRowNum(table_id, active_id);         /*decide the top row num*/
	table_top_row_num = table_ptr->table_top_row_num;
	table_num_row_displayed  = 0;
	acc_height = 0;
	
	for (count = table_top_row_num; count < table_num_rows; count++)
	{
		acc_height += table_ptr->table_row_height[count];
		if (acc_height <= table_ptr->bounds.height)
		{
			table_num_row_displayed ++;
			TableUpdateObjectScreenBounds(table_id, (ObjectID)(count + first_field_id));
			FormGetObjectPointer((ObjectID)(count + first_field_id), &object_type, (void**)&field_ptr);		
			StrAnalyzeLine(field_ptr);
			if (acc_height >= (table_max_num_lines * line_height)) break;
		}
		else 
		{
			acc_height -= table_ptr->table_row_height[count];
			FormGetObjectPointer((ObjectID)(count + first_field_id), &object_type, (void**)&field_ptr);		
			if (acc_height == (table_max_num_lines * line_height)) break;
			field_ptr->bounds.height = (table_max_num_lines - acc_height/line_height) * line_height;
			table_ptr->table_row_height[count] = field_ptr->bounds.height;
			field_ptr->field_top_line_num = 0;
			TableUpdateObjectScreenBounds(table_id, (ObjectID)(count + first_field_id));
			StrAnalyzeLine(field_ptr);
			break;
		}
	}
	
	return TRUE;
}


/********************************************************
* Function:	PhonebookKeyInChangeViewEditTable
* Purpose: 	This function is called when the content in table changed,
then both table
* Scope:		application
* Input:		table_id			The ID value of table object to be scrolled
*				scroll_id			The ID value of scrollbar object
*				field_id			The ID value of active field
*				active_field		whether there is active field or not
* Output:		None
* Return:		TRUE		The table layout is changed
FALSE		The table layout is not changed
* Comment: 	None
*********************************************************/
BOOLEAN PhonebookKeyInChangeViewEditTable(ObjectID form_id, ObjectID table_id, ObjectID scrollbar_id)
{
	ObjectID first_field_id;	/*the field object id in the first row of the table */
	ObjectID active_id;			/*The ID value of the field object in the table */
	WORD count = 0;				/* another temperatory variable */
	BYTE object_type;
	Table *table_ptr;
	Field *field_ptr, *field_ptr1;
	USHORT table_num_rows;
	WORD table_max_num_lines;
	BYTE font_id;
	SHORT line_height;			/* line_height = SysGetFontHeight(font_id) + SPACE_LINE;*/
	BOOLEAN insert_pt_on = FALSE;
	SHORT acc_height = 0;
	BOOLEAN return_boolean = FALSE;
	WORD field_total_num_lines, num_lines_displayed, acc_num_lines = 0, num_lines, table_total_num_lines, row_num;
	
	
	/*The bounds of the table should be set outside this function according
	to the keyboard status */
	
	FormGetObjectPointer(table_id, &object_type, (void**)&table_ptr);
	first_field_id = (table_ptr->table_item_ptr[1])->table_item_ui_id;
	table_num_rows = table_ptr->table_num_row;
	
	FieldGetFont(first_field_id, &font_id);
	PhonebookGetTableMaxNumLines(table_id, font_id, &table_max_num_lines);
    PhonebookGetTableNumLines(table_id, 1, &table_total_num_lines);
	line_height = SysGetFontHeight(font_id) + SPACE_LINE;
	FormGetActiveObject(form_id, &active_id);
	if (active_id < first_field_id || active_id > (table_num_rows - 1 + first_field_id))
		active_id = (ObjectID)(table_ptr->table_top_row_num + first_field_id);
	else
	{
		FormGetObjectPointer(active_id, &object_type, (void**)&field_ptr);		
		insert_pt_on = field_ptr->field_attr.field_insert_pt_visible;
	}
	
	FieldGetTotalNumOfLines(active_id, &field_total_num_lines);
	FieldGetNumOfLinesDisplayed(active_id, &num_lines_displayed);
	FormGetObjectPointer(active_id, &object_type, (void**)&field_ptr);
	if (table_total_num_lines <= table_max_num_lines && table_ptr->table_top_row_num > 0)
	{
		return_boolean = TRUE;
		table_ptr->table_top_row_num = 0;
		for (row_num = 0;row_num < table_ptr->table_num_row; row_num++)
		{
			FormGetObjectPointer((ObjectID)(first_field_id +  row_num), &object_type, (void**)&field_ptr1);
			field_ptr1->bounds.height = field_ptr1->field_total_num_lines * line_height;
			field_ptr1->field_top_line_num = 0;
			table_ptr->table_row_height[row_num] = field_ptr1->bounds.height;
			if ((ObjectID)(first_field_id + row_num) == active_id && insert_pt_on)
				FieldSetInsertPointPositionByCharPos((ObjectID)(first_field_id + row_num), field_ptr1->field_insert_pt_char_pos);							
		}
	}
	else if (field_total_num_lines >= table_max_num_lines &&
		field_ptr->bounds.height != table_max_num_lines * line_height)
	{
		field_ptr->bounds.height = table_max_num_lines * line_height;
		table_ptr->table_row_height[(USHORT)(active_id - first_field_id)] = field_ptr->bounds.height;
		if (field_total_num_lines <= field_ptr->bounds.height/line_height)
			field_ptr->field_top_line_num = 0;
		else if (field_ptr->field_top_line_num >= (field_ptr->field_total_num_lines - field_ptr->bounds.height/line_height))
			field_ptr->field_top_line_num = (field_ptr->field_total_num_lines - field_ptr->bounds.height/line_height);
		
		return_boolean = TRUE;
	}
	else if (field_total_num_lines < (field_ptr->screen_bounds.height/(SysGetFontHeight(font_id) + SPACE_LINE)))
	{
		field_ptr->bounds.height = (field_total_num_lines)*(SysGetFontHeight(font_id) + SPACE_LINE);
		TableUpdateObjectScreenBounds(table_id, active_id);
		if (field_total_num_lines <= field_ptr->bounds.height/line_height)
			field_ptr->field_top_line_num = 0;
		else if (field_ptr->field_top_line_num >= (field_ptr->field_total_num_lines - field_ptr->bounds.height/line_height))
			field_ptr->field_top_line_num = (field_ptr->field_total_num_lines - field_ptr->bounds.height/line_height);
		
		StrAnalyzeLine(field_ptr);
		StrCharPosToXY(field_ptr, field_ptr->field_insert_pt_char_pos, 
			&(field_ptr->field_insert_pt_x), &(field_ptr->field_insert_pt_y));
		table_ptr->table_row_height[(USHORT)(active_id - first_field_id)] = field_ptr->bounds.height;
		return_boolean = TRUE;
	}			
	else if (num_lines_displayed < field_total_num_lines && 
		field_total_num_lines <= table_max_num_lines)
	{
		field_ptr->bounds.height = field_total_num_lines * line_height;
		TableUpdateObjectScreenBounds(table_id, active_id);
		if (field_ptr->field_top_line_num >0) field_ptr->field_top_line_num--;
		if (field_total_num_lines <= field_ptr->bounds.height/line_height)
			field_ptr->field_top_line_num = 0;
		else if (field_ptr->field_top_line_num >= (field_ptr->field_total_num_lines - field_ptr->bounds.height/line_height))
			field_ptr->field_top_line_num = (field_ptr->field_total_num_lines - field_ptr->bounds.height/line_height);
		
		StrAnalyzeLine(field_ptr);
		StrCharPosToXY(field_ptr, field_ptr->field_insert_pt_char_pos, 
			&(field_ptr->field_insert_pt_x), &(field_ptr->field_insert_pt_y));
		table_ptr->table_row_height[(USHORT)(active_id - first_field_id)] = field_ptr->bounds.height;
		return_boolean = TRUE;
	}
	if (PhonebookDecideTopRowNum(table_id, active_id) == TRUE) 
		return_boolean = TRUE;
	if (insert_pt_on)
	{
		TableUpdateObjectScreenBounds(table_id, active_id);		
		StrAnalyzeLine(field_ptr);
		StrCharPosToXY(field_ptr, field_ptr->field_insert_pt_char_pos, 
			&(field_ptr->field_insert_pt_x), &(field_ptr->field_insert_pt_y));
	}
	acc_num_lines = 0;
	for (count = table_ptr->table_top_row_num; count < table_ptr->table_num_row; count++)
	{
		FieldGetTotalNumOfLines((ObjectID)(table_ptr->table_item_ptr[count * table_ptr->table_num_column + 1]->table_item_ui_id), &num_lines);
		acc_num_lines += num_lines;
		if (acc_num_lines == table_max_num_lines)
			break;
		else if (acc_num_lines > table_max_num_lines)
		{
			acc_num_lines -= num_lines;
			FormGetObjectPointer((ObjectID)(table_ptr->table_item_ptr[count * table_ptr->table_num_column + 1]->table_item_ui_id), &object_type, (void**)&field_ptr);
			if (field_ptr->bounds.height != (table_max_num_lines - acc_num_lines) * line_height)
			{	
				field_ptr->bounds.height = (table_max_num_lines - acc_num_lines) * line_height;
				table_ptr->table_row_height[count] = field_ptr->bounds.height;
				return_boolean = TRUE;
			}
			break;
		}
	}
	
	PhonebookViewEditTableSetScrollbar(table_id, scrollbar_id);
	return return_boolean;
}


/********************************************************
* Function:	PhonebookViewEditTableSetScrollbar
* Purpose: 	This function is to set the scrollbar beside the table
* Scope:		application
* Input:		table_id			The ID value of table object to be scrolled
*				scroll_id			The ID value of scrollbar object
* Output:		None
* Return:		TRUE		The table layout is changed
FALSE		The table layout is not changed
* Comment: 	None
*********************************************************/
BOOLEAN PhonebookViewEditTableSetScrollbar(ObjectID table_id, ObjectID scrollbar_id)
{
	ObjectID first_field_id;
	BYTE object_type;
	Table *table_ptr;
	Scrollbar *scroll_ptr;
	Field *field_ptr;
	BYTE font_id;
	WORD table_max_num_lines, table_total_num_lines;
	WORD value, max_value, min_value, pagesize, scrollbar_total_num_lines;
	WORD count, field_total_num_lines, acc_num_lines = 0, acc_num_lines1 = 0, top_line_num;
	WORD acc_num_lines2 = 0;
	SHORT line_height = 0;
	BOOLEAN set = FALSE;
	
	/*The bounds of the table should be set outside this function according
	to the keyboard status */
	
	FormGetObjectPointer(table_id, &object_type, (void**)&table_ptr);
	FormGetObjectPointer(scrollbar_id, &object_type, (void**)&scroll_ptr);
	first_field_id = (table_ptr->table_item_ptr[1])->table_item_ui_id;
	
	FieldGetFont(first_field_id, &font_id);
	PhonebookGetTableMaxNumLines(table_id, font_id, &table_max_num_lines);
	PhonebookGetTableNumLines(table_id, 1, &table_total_num_lines);
	line_height = SysGetFontHeight(font_id) + SPACE_LINE;
	
	if ((table_total_num_lines > table_max_num_lines) && (app_status.company != app_status.home))
		scroll_ptr->scrollbar_attr.scrollbar_visible = TRUE;
	else
	{
		scroll_ptr->scrollbar_attr.scrollbar_visible = FALSE;
        if (draw_scrollbar)
            ScrollbarEraseScrollbar(scrollbar_id);
		return TRUE;
	}
	
	ScrollbarGetScrollbar(scrollbar_id, &value, &max_value, &min_value, &pagesize, &scrollbar_total_num_lines);
	for (count = 0; count < table_ptr->table_top_row_num; count++)
	{
		FieldGetTotalNumOfLines((count + first_field_id), &field_total_num_lines);
		acc_num_lines += field_total_num_lines;
	}
	FieldGetTopLineNum((ObjectID)(table_ptr->table_top_row_num + first_field_id), &top_line_num);
	for (count = table_ptr->table_top_row_num; count < table_ptr->table_num_row; count++)
	{
		FormGetObjectPointer((ObjectID)(count + first_field_id), &object_type, (void**)&field_ptr);
		acc_num_lines2 += field_ptr->bounds.height/line_height; 
		if (acc_num_lines2 > table_max_num_lines)
		{
			table_ptr->table_num_row_display = count - table_ptr->table_top_row_num;
			set = TRUE;
			break;
		}
	}
	if (set == FALSE)
		table_ptr->table_num_row_display = table_ptr->table_num_row - table_ptr->table_top_row_num; 
	acc_num_lines += top_line_num;
	
	//get occasional error from this line:
	for (count = table_ptr->table_top_row_num; count < (table_ptr->table_top_row_num + table_ptr->table_num_row_display);count++)
	{
		if(FormGetObjectPointer((ObjectID)(count + first_field_id), &object_type, (void**)&field_ptr)==TRUE)
			acc_num_lines1 += (field_ptr->bounds.height/line_height);
	}
	
	ScrollbarSetScrollbar(scrollbar_id, acc_num_lines, PhonebookGetScrollbarMaxValue(table_id, 1), 0, acc_num_lines1, table_total_num_lines);
	scroll_ptr->scrollbar_draw_pagesize = table_max_num_lines;
    if (draw_view_edit_scrollbar)
        ScrollbarDrawScrollbar(scrollbar_id);
	
	return TRUE;
}

/********************************************************
* Function:	PhonebookScrollbarSetViewEditTable
* Purpose: 	This function is called in order to change the content 
of a table when a scrollbar is being moved
* Scope:		application
* Input:		None
* Output:		None
* Return:		TRUE		Success
FALSE		NotHandled
* Comment: 	None
*********************************************************/
BOOLEAN PhonebookScrollbarSetViewEditTable(ObjectID table_id, ObjectID scrollbar_id, EvtType *Event)
{
	Table       *table_ptr;
	BYTE        object_type;
	WORD        *row_num_lines;		/* The numbers of lines of different field objects in the table*/
	USHORT      table_current_row;
	USHORT      table_largest_top_row_num;
	WORD        temp;
	Field       *field_ptr, *ptr;
	ObjectID    first_field_id;
	Scrollbar   *scroll_ptr;
	BYTE        font_id;
	WORD        table_max_num_lines, table_total_num_lines;
	WORD        value, max_value, min_value, pagesize, scrollbar_total_num_lines;
	WORD        count, acc_num_lines = 0, acc_num_lines1 = 0, field_current_line_num, field_num_lines_displayed;
	WORD        num_lines;
	SHORT       line_height = 0;
    BOOLEAN     table_change = FALSE;
    BOOLEAN     field_change = FALSE;
    ObjectID    field_redraw_id = 0, last_field_id = 0;
    USHORT      cell_number;
	
    Field   *test_ptr;
	
	FormGetObjectPointer(table_id, &object_type, (void**)&table_ptr);
	FormGetObjectPointer(scrollbar_id, &object_type, (void**)&scroll_ptr);
	
	first_field_id = (table_ptr->table_item_ptr[1])->table_item_ui_id;
	FieldGetFont(first_field_id, &font_id);
	PhonebookGetTableMaxNumLines(table_id, font_id, &table_max_num_lines);
	PhonebookGetTableNumLines(table_id, 1, &table_total_num_lines);
	line_height = SysGetFontHeight(font_id) + SPACE_LINE;
    if (scroll_ptr->scrollbar_max == scroll_ptr->scrollbar_value)
    {
		if ((table_ptr->table_top_row_num <= (table_ptr->table_num_row - 1)) &&
			((table_ptr->table_top_row_num + table_ptr->table_num_row_display) >= (table_ptr->table_num_row)))
		{
			cell_number = ((table_ptr->table_top_row_num + table_ptr->table_num_row_display - 1) * table_ptr->table_num_column) + 1;
			last_field_id = ((TableItems*)(table_ptr->table_item_ptr[cell_number]))->table_item_ui_id;
			FormGetObjectPointer(last_field_id, &object_type, (void**)&ptr);
			if (ptr->field_top_line_num == (ptr->field_total_num_lines - ptr->field_num_lines_displayed))
			{
				return TRUE;
			}
		}
    }
	for (count = FIELD_ROW0; count < (FIELD_ROW0 + table_ptr->table_num_row); count++)
	{
		FormGetObjectPointer((ObjectID)(count), &object_type, (void**)&field_ptr);	
		field_ptr->bounds.height = 9;
		field_ptr->screen_bounds.height = 9;
		table_ptr->table_row_height[(count - FIELD_ROW0)] = 9;
	}
	
	row_num_lines = (WORD*)qmalloc(table_ptr->table_num_row*sizeof(WORD));
	
	/* find out the total number of lines in each field object */
	for (count = 0; count < (table_ptr->table_num_row); count++)
	{
		FieldGetTotalNumOfLines((ObjectID)(count + first_field_id), &temp);
		row_num_lines[count] = temp;
	}
	
	/* find out the table_current_row */
	for (count = 0; count < (table_ptr->table_num_row); count++)
	{
		acc_num_lines += row_num_lines[count];
		if ((WORD)(Event->para2) < acc_num_lines)
		{
			table_current_row = (USHORT)count;
			acc_num_lines -= row_num_lines[count];
			field_current_line_num = (WORD)((WORD)(Event->para2) - (WORD)(acc_num_lines));
			break;
		}
	}
	
	/* find out the table's largest top_row_number */
	for (count = table_ptr->table_num_row - 1; count >=0; count--)
	{
		acc_num_lines1 += row_num_lines[count];
		if (acc_num_lines1 > table_max_num_lines)
		{
			table_largest_top_row_num = count + 1;
			break;
		}
	}
	
	ScrollbarGetScrollbar(scrollbar_id, &value, &max_value, &min_value, &pagesize, &scrollbar_total_num_lines);
	if (table_ptr->table_top_row_num != table_current_row)
	{	
		table_ptr->table_top_row_num = table_current_row;
		table_change = TRUE;
	}
	if (table_ptr->table_top_row_num > table_largest_top_row_num)
	{
		table_ptr->table_top_row_num = table_largest_top_row_num;
		table_change = TRUE;
	}
	
	FormGetObjectPointer((first_field_id + table_ptr->table_top_row_num), &object_type, (void**)&field_ptr);
	if (field_ptr->field_total_num_lines < table_max_num_lines)
		field_num_lines_displayed = field_ptr->field_total_num_lines;
	else 
		field_num_lines_displayed = table_max_num_lines;
	
	if (field_current_line_num > (field_ptr->field_total_num_lines - field_num_lines_displayed))
	{
		if ((Event->para2 - Event->para1) > 0)
		{
			if (table_ptr->table_top_row_num != table_ptr->table_num_row - 1)
			{
				table_ptr->table_top_row_num++;
				(WORD)(Event->para2) += (field_ptr->field_total_num_lines - field_current_line_num);
				table_change = TRUE;
			}
			else
			{
				(WORD)(Event->para2) -= (field_ptr->field_num_lines_displayed - (field_ptr->field_total_num_lines - field_current_line_num));
			}
		}
		else if ((Event->para2 - Event->para1) < 0)
		{
			(WORD)(Event->para2) -= (field_ptr->field_num_lines_displayed - (field_ptr->field_total_num_lines - field_current_line_num));
		}
	}
	else
	{	
        field_ptr->field_top_line_num = field_current_line_num;
        field_change = TRUE;
        field_redraw_id = field_ptr->identification.ui_object_id;
	}
	
	acc_num_lines = 0;
	for (count = table_ptr->table_top_row_num; count < table_ptr->table_num_row; count++)
	{
		FieldGetTotalNumOfLines((ObjectID)(table_ptr->table_item_ptr[count * table_ptr->table_num_column + 1]->table_item_ui_id), &num_lines);
		acc_num_lines += num_lines;
		FormGetObjectPointer((ObjectID)(count +  first_field_id), &object_type, (void**)&field_ptr);
		if (acc_num_lines <= table_max_num_lines)
		{
			if (field_ptr->bounds.height != field_ptr->field_total_num_lines * line_height)
			{	
				field_ptr->bounds.height = field_ptr->field_total_num_lines * line_height;
				table_ptr->table_row_height[count] = field_ptr->bounds.height;
				table_change = TRUE;
			}
			if (acc_num_lines == table_max_num_lines) break;
		}
		else if (acc_num_lines > table_max_num_lines)
		{
			acc_num_lines -= num_lines;
			FormGetObjectPointer((ObjectID)(table_ptr->table_item_ptr[count * table_ptr->table_num_column + 1]->table_item_ui_id), &object_type, (void**)&field_ptr);
            if ((field_ptr->bounds.height != (table_max_num_lines - acc_num_lines) * line_height) ||
                (table_ptr->table_row_height[count] != (table_max_num_lines - acc_num_lines) * line_height))
            {
                field_ptr->bounds.height = (table_max_num_lines - acc_num_lines) * line_height;
                table_ptr->table_row_height[count] = field_ptr->bounds.height;
                table_change = TRUE;
            }
			break;
		}
	}
	
	if (table_ptr->table_top_row_num == (table_ptr->table_num_row - 1))
	{
		FormGetObjectPointer((ObjectID)(table_ptr->table_item_ptr[table_ptr->table_top_row_num * table_ptr->table_num_column + 1]->table_item_ui_id), &object_type, (void**)&field_ptr);
        if ((field_ptr->bounds.height != table_max_num_lines * line_height) ||
            (table_ptr->table_row_height[table_ptr->table_top_row_num] != table_max_num_lines * line_height))
        {
            field_ptr->bounds.height = table_max_num_lines * line_height;
            table_ptr->table_row_height[table_ptr->table_top_row_num] = field_ptr->bounds.height;
            table_change = TRUE;
        }
	}
	
	ScrollbarSetScrollbar(scrollbar_id, (WORD)(Event->para2), max_value, 0, pagesize, scrollbar_total_num_lines);
	ScrollbarDrawScrollbar(scrollbar_id);
	
	acc_num_lines = 0;
	
    TableUpdateNumRowDisplay(table_id, 1);
	
	for (count = table_ptr->table_top_row_num; count < table_ptr->table_num_row; count++)
	{
		FormGetObjectPointer((ObjectID)(count +  first_field_id), &object_type, (void**)&field_ptr);
		acc_num_lines += field_ptr->field_total_num_lines;
		if (acc_num_lines <= table_max_num_lines)
		{
			if (field_ptr->bounds.height != field_ptr->field_total_num_lines * line_height)
			{	
				field_ptr->bounds.height = field_ptr->field_total_num_lines * line_height;
				table_ptr->table_row_height[count] = field_ptr->bounds.height;
				table_change = TRUE;
			}
			if (acc_num_lines == table_max_num_lines) break;
		}
		else
		{
            if (count == table_ptr->table_top_row_num)
            {
                if ((field_ptr->bounds.height != (table_max_num_lines *line_height)) ||
                    (table_ptr->table_row_height[count] != (table_max_num_lines - acc_num_lines)*line_height))
                {
                    field_ptr->bounds.height = table_max_num_lines *line_height;
                    table_ptr->table_row_height[count] = field_ptr->bounds.height;
                    table_change = TRUE;
                }
                break;
            }                              
            acc_num_lines -= field_ptr->field_total_num_lines;
            if ((field_ptr->bounds.height != (table_max_num_lines - acc_num_lines)*line_height) ||
                (field_ptr->field_top_line_num != 0) ||
                (table_ptr->table_row_height[count] != (table_max_num_lines - acc_num_lines)*line_height))
            {
                field_ptr->bounds.height = (table_max_num_lines - acc_num_lines)*line_height;
                field_ptr->field_top_line_num = 0;
                table_ptr->table_row_height[count] = field_ptr->bounds.height;
                table_change = TRUE;
            }
		}
	}
	
    if (table_change)
	{
        if (Event->eventType == EVT_SCROLLBAR_SELECT ||
            (Event->eventType == EVT_SCROLLBAR_REPEAT))
        {
            LcdEnableInsertPt(FALSE, 0, 0, SMALL_FONT);            
            TableDrawTable(table_id);
        }            
	}
	else if (field_change)
		FieldDrawField(field_redraw_id);
	
	qfree(row_num_lines);
	return TRUE;
}

/********************************************************
* Function:	PhonebookSwitchInfoInit
* Purpose: 	This function is called in order to initialise the layout 

  * Scope:		application
  * Input:		table_id			The ID value of table object to be scrolled
  * Output:		None
  * Return:		TRUE		Success
  FALSE		NotHandled
  * Comment: 	None
  *********************************************************/
  BOOLEAN PhonebookSwitchInfoInit(ObjectID table_id)
  {
	  Field *field_ptr;
	  Table *table_ptr;
	  BYTE object_type;
	  USHORT count;
	  ObjectID count_id;
	  
	  if (FormGetObjectPointer(table_id, &object_type, (void**)&table_ptr) != TRUE) return ERR_UI_RES_NOT_FOUND;
	  table_ptr->table_top_row_num = 0;
	  for (count = 0; count <11; count++)
		  table_ptr->table_row_height[count] = 9;
	  
	  for (count_id = FIELD_ROW0; count_id <= FIELD_ROW11; count_id++)
	  {
		  if (FormGetObjectPointer(count_id, &object_type, (void**)&field_ptr) != TRUE) return ERR_UI_RES_NOT_FOUND;
		  if (table_font_size == SMALL_FONT)
			  field_ptr->bounds.height = SysGetFontHeight(SMALL_FONT) + SPACE_LINE;
		  else if (table_font_size == MEDIUM_FONT)
			  field_ptr->bounds.height = SysGetFontHeight(MEDIUM_FONT) + SPACE_LINE;
		  TableUpdateObjectScreenBounds(TABLE_VIEW_EDIT, count_id);
		  field_ptr->field_attr.field_insert_pt_visible = FALSE;
		  field_ptr->field_attr.field_active = FALSE;
	  }
	  return TRUE;
  }
  
  /********************************************************
  * Function:	PhonebookViewEditChangeFont
  * Purpose: 	This function is called in order to change the font size fo the 
  font in each field object
  * Scope:		application
  * Input:		None
  * Output:		None
  * Return:		TRUE		Success
  FALSE		NotHandled
  * Comment: 	None
  *********************************************************/
  BOOLEAN PhonebookViewEditChangeFont()
  {
	  Field *field_ptr;
	  Table *table_ptr;
	  void* addr;
	  Scrollbar *scroll_ptr;
	  BYTE object_type;
	  USHORT count;
	  SHORT line_height;
	  BYTE original_font;
	  WORD acc_num_lines = 0;
	  WORD num_lines_displayed = 0;
	  ObjectBounds ob;
	  
	  if (table_font_size == MEDIUM_FONT) 
		  table_font_size = SMALL_FONT;
	  else 
		  table_font_size = MEDIUM_FONT;
	  FormGetObjectPointer(TABLE_VIEW_EDIT, &object_type, (void**)&table_ptr);
	  FormGetObjectPointer(SCROLLBAR_VIEW_EDIT, &object_type, (void**)&scroll_ptr);
	  FieldGetFont(FIELD_ROW0, &original_font);
	  line_height = SysGetFontHeight(table_font_size) + SPACE_LINE;
	  
	  switch (table_font_size)
	  {
	  case SMALL_FONT:
		  if (original_font == SMALL_FONT) return TRUE;
		  font_size = SMALL_FONT;
		  ControlSetLabel(BUTTON_VIEW_ZOOMIN, PBLFONT);
		  ControlDrawControl(BUTTON_VIEW_ZOOMIN);
		  MenuDeleteItem(MENU_POPUP1, 4);
		  MenuInsertItem(MENU_POPUP1, 4, PBLFONT);
		  for (count = 0; count < (table_ptr->table_num_row); count++)
		  {
			  table_ptr->table_row_height[count] = SysGetFontHeight(SMALL_FONT) + SPACE_LINE;
			  FormGetObjectPointer((ObjectID)(FIELD_ROW0 + count), &object_type, (void**)&field_ptr);
			  field_ptr->bounds.height = table_ptr->table_row_height[count];
			  field_ptr->field_font_id = SMALL_FONT;
			  TableUpdateObjectScreenBounds(TABLE_VIEW_EDIT, (ObjectID)(FIELD_ROW0 + count));
			  StrAnalyzeLine(field_ptr);
		  }
		  break;
	  case MEDIUM_FONT:
		  if (original_font == MEDIUM_FONT) return TRUE;
		  font_size = MEDIUM_FONT;
		  ControlSetLabel(BUTTON_VIEW_ZOOMIN, PBSFONT);
		  ControlDrawControl(BUTTON_VIEW_ZOOMIN);
		  MenuDeleteItem(MENU_POPUP1, 4);
		  MenuInsertItem(MENU_POPUP1, 4, PBSFONT);
		  for (count = 0; count < (table_ptr->table_num_row); count++)
		  {
			  table_ptr->table_row_height[count] = SysGetFontHeight(MEDIUM_FONT) + SPACE_LINE;
			  FormGetObjectPointer((ObjectID)(FIELD_ROW0 + count), &object_type, (void**)&field_ptr);
			  field_ptr->bounds.height = table_ptr->table_row_height[count];
			  field_ptr->field_font_id = MEDIUM_FONT;
			  TableUpdateObjectScreenBounds(TABLE_VIEW_EDIT, (ObjectID)(FIELD_ROW0 + count));
			  StrAnalyzeLine(field_ptr);
		  }
		  break;
	  default: return FALSE;
	  }
	  
	  //clean up old text
	  if((app_status.home==TRUE)&&(app_status.status==EDIT))
	  {
		  ob.xcoord=47;
		  ob.ycoord=41;
		  ob.height=16;
		  ob.width=101;
		  LcdEraseRegion(&ob);
	  }
	  return TRUE;
  }
  
  /********************************************************
  * Function:	PhonebookViewEditCheckEmptyFields
  * Purpose: 	This function is called in order to check whether 
  all the fields are empty or nor
  * Scope:		application
  * Input:		None
  * Output:		None
  * Return:		TRUE			empty
  FALSE			not empty
  * Comment: 	None
  *********************************************************/
  BOOLEAN PhonebookViewEditCheckEmptyFields()
  {
	  int i;
	  int j = 0;
	  
	  if(app_status.new_record)
	  {
		  //if all records are empty than just exit
		  for(i=0;i<26;i++)
			  j += strlen(field_buffers[i]);
		  if(j==0)
			  return TRUE;
	  }
	  return ((strlen(field_buffers[0]) == 0) && (strlen(field_buffers[1]) == 0) && (strlen(field_buffers[3]) == 0));
  }
  
  /********************************************************
  * Function:	PhonebookPrepareFirstLastName
  * Purpose: 	
  * Scope:		application
  * Input:		in_string1
  *				in_string2
  * Output:		None
  * Return:		TRUE		Success
  FALSE		NotHandled
  * Comment: 	The string will be put to field_buffers[0], field_buffers[1] and
  field_buffers[2]
  *********************************************************/
  void PhonebookPrepareFirstLastName(BYTE *in_string1, BYTE *in_string2, BYTE *out_string)
  {
	  BYTE *temp;
	  USHORT count;
	  
	  temp = out_string;
	  
	  if (strlen(in_string1) != 0)
	  {
		  strcpy(temp,in_string1);
		  temp += strlen(in_string1);
		  *temp = 32;
		  temp++;
	  }
	  strcpy(temp,in_string2);	
  }
  
  /********************************************************
  * Function:	PhonebookPrepareLastFirstName
  * Purpose: 	
  * Scope:		application
  * Input:		in_string1
  *				in_string2
  * Output:		None
  * Return:		TRUE		Success
  FALSE		NotHandled
  * Comment: 	The string will be put to field_buffers[0], field_buffers[1] and
  field_buffers[2]
  *********************************************************/
  void PhonebookPrepareLastFirstName(BYTE *in_string1, BYTE *in_string2, BYTE *out_string)
  {
	  BYTE *temp;
	  USHORT count;
	  
	  temp = out_string;
	  
	  if (strlen(in_string2) != 0)
	  {
		  strcpy(temp,in_string2);
		  temp += strlen(in_string2);
		  *temp = 32;
		  temp++;
	  }
	  strcpy(temp,in_string1);	
  }
  
  /********************************************************
  * Function:	PhonebookPrepareLastFirstNameForDisplay
  * Purpose: 	
  * Scope:		application
  * Input:		in_string1
  *				in_string2
  * Output:		None
  * Return:		TRUE		Success
  FALSE		NotHandled
  * Comment: 	The string will be put to field_buffers[0], field_buffers[1] and
  field_buffers[2]
  *********************************************************/
  void PhonebookPrepareLastFirstNameForDisplay(BYTE *in_string1, BYTE *in_string2, BYTE *out_string)
  {
	  BYTE *temp;
	  USHORT count;
	  
	  BYTE* l_str1;
	  BYTE* l_str2;
	  
	  l_str1 = in_string1;
	  l_str2 = in_string2;
	  
	  temp = out_string;
	  
	  if (strlen(l_str1) == 0 && strlen(l_str2) == 0)
		  out_string[0] = 0;
	  else if (strlen(l_str1) != 0 && strlen(l_str2) == 0)
		  strcpy(out_string, l_str1);
	  else if (strlen(l_str1) == 0 && strlen(l_str2) != 0)
		  strcpy(out_string, l_str2);
	  else
	  {
		  strcpy(temp, l_str2);
		  temp += strlen(l_str2);
		  *temp = ',';
		  temp ++;
		  *temp = 32;
		  temp ++;
		  strcpy(temp, l_str1);
	  }
  }
  
  /********************************************************
  * Function:	PhonebookPrepareLastFirstNameForDisplay1
  * Purpose: 	
  * Scope:		application
  * Input:		in_string1
  *				in_string2
  * Output:		None
  * Return:		TRUE		Success
  FALSE		NotHandled
  * Comment: 	The string will be put to field_buffers[0], field_buffers[1] and
  field_buffers[2]
  *********************************************************/
  void PhonebookPrepareLastFirstNameForDisplay1(BYTE *in_string1, BYTE *in_string2, BYTE *out_string)
  {
	  BYTE *temp;
	  USHORT count;
	  BYTE* l_str1;
	  BYTE* l_str2;
	  
	  temp = out_string;
	  
	  l_str1 = in_string1;
	  l_str2 = in_string2;
	  
	  if (strlen(l_str1) == 0 && strlen(l_str2) == 0)
		  out_string[0] = 0;
	  else if (strlen(l_str1) != 0 && strlen(l_str2) == 0)
		  strcpy(out_string, l_str1);
	  else if (strlen(l_str1) == 0 && strlen(l_str2) != 0)
		  strcpy(out_string, l_str2);
	  else
	  {
		  strcpy(temp, l_str2);
		  temp += strlen(l_str2);
		  *temp = ',';
		  temp ++;
		  strcpy(temp, l_str1);
	  }
  }
  
  /********************************************************
  * Function:    PhonebookPrepareChangeInfo
  * Purpose:     This function is called to prepare the scrren before
  changing the information
  * Scope:		application
  * Input:		None
  * Output:		None
  * Return:      None
  None
  * Comment:     None
  *********************************************************/
  void PhonebookPrepareChangeInfo()
  {
	  
	  ObjectID    count_id;
	  Field       *field_ptr;
	  BYTE        object_type;
	  Control     *control_ptr;
	  
	  if(app_status.status == EDIT)
	  {
		  FormSetFormActiveObject(FORM_VIEW_EDIT, FIELD_ROW0);
		  FieldSetInsertPointOn(FIELD_ROW0);
		  FieldSetInsertPointPositionByCharPos(FIELD_ROW0, 0);
	  }
	  
	  for (count_id = FIELD_ROW0; count_id <= FIELD_ROW11; count_id++)
	  {
		  FormGetObjectPointer(count_id, &object_type, (void**)&field_ptr);
		  field_ptr->field_attr.field_highlight = FALSE;
		  field_ptr->field_top_line_num = 0;
		  field_ptr->field_highlight_length = 0;        
		  FormGetObjectPointer(BUTTON_VIEW_ZOOMIN, &object_type, (void**)&control_ptr);
		  if ((control_ptr->control_text)[0] == PB_FONT_INT)
		  {
			  field_ptr->field_font_id = MEDIUM_FONT;
			  field_ptr->bounds.height = SysGetFontHeight(MEDIUM_FONT) + SPACE_LINE;
			  field_ptr->screen_bounds.height = SysGetFontHeight(MEDIUM_FONT) + SPACE_LINE;
		  }
		  else
		  {
			  field_ptr->field_font_id = SMALL_FONT;
			  field_ptr->bounds.height = SysGetFontHeight(SMALL_FONT) + SPACE_LINE;
			  field_ptr->screen_bounds.height = SysGetFontHeight(SMALL_FONT) + SPACE_LINE;
		  }
		  StrAnalyzeLine(field_ptr);        
	  }
  }
  
  /********************************************************
  * Function:    PhonebookChangeViewInfo
  * Purpose:     This function is called to change the view
  (Home or Company) by checking whether the information
  in Home and company is empty or not
  * Scope:       application
  * Input:       None
  * Output:      None
  * Return:      None
  None
  * Comment:     None
  *********************************************************/
  void PhonebookChangeViewInfo()
  {
	  BOOLEAN home_empty = TRUE, company_empty = TRUE;
	  SHORT   count;
	  
	  for (count = 3; count < 15; count++)
	  {
		  if (strlen(field_buffers[count]) != 0)
		  {
			  company_empty = FALSE;
			  break;
		  }
	  }
	  
	  for (count = 15; count < 26; count++)
	  {
		  if (strlen(field_buffers[count]) != 0)
		  {
			  home_empty = FALSE;
			  break;
		  }
	  }
	  
	  if (company_empty == FALSE)
	  {
		  app_status.company  = TRUE;
		  app_status.home     = FALSE;
	  }
	  else if (company_empty == TRUE && home_empty == TRUE)
	  {
		  app_status.company  = TRUE;
		  app_status.home     = FALSE;
	  }
	  else if (company_empty == TRUE && home_empty == FALSE)
	  {
		  app_status.company  = FALSE;
		  app_status.home     = TRUE;
	  }
  }
