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


#include "stdafx.h"
#include "sysdef.h"


/********************************************************
* Function:	SySetupSetScreen
* Purpose: 	This function is called in order to set the layout of the 
screen
* Scope:		application
* Input:		form_id				The ID value of the form that the table is on
* Output:		None
* Return:		TRUE		Success
FALSE		NotHandled
* Comment: 	None
*********************************************************/
BOOLEAN SySetupSetScreen(ObjectID form_id)
{
	BYTE		object_type;
	Field		*field_ptr;
	Table		*table_ptr;
	Scrollbar	*scroll_ptr;
	
	/*Setup Table*/
	switch(form_id)
	{
	case FORM_SYSETUP_OWNINFO:
		FormGetObjectPointer(TABLE_SYSETUP_OWNINFO, &object_type, (void**)&table_ptr);
		FormGetObjectPointer(SCROLLBAR_SYSETUP_OWNINFO, &object_type, (void**)&scroll_ptr);
		if (KeyboardCheckKeyboardStatus())
		{
			//scroll_ptr->bounds.height = 69;
			//table_ptr->bounds.height = 69;
			scroll_ptr->bounds.height = 73;
			table_ptr->bounds.height = 73;
		}
		else
		{
			scroll_ptr->bounds.height = 127;
			table_ptr->bounds.height = 127;
		}
		return TRUE;
		
	case FORM_SYSETUP_PASSWORD_HINTS:
		FormGetObjectPointer(FIELD_SYSETUP_PASSWORD_HINTS, &object_type, (void**)&field_ptr);
		FormGetObjectPointer(SCROLLBAR_SYSETUP_PASSWORD_HINTS, &object_type, (void**)&scroll_ptr);
		if (KeyboardCheckKeyboardStatus())
		{
			scroll_ptr->bounds.height = 69;
			field_ptr->bounds.height = 69;
		}
		else
		{
			scroll_ptr->bounds.height = 127;
			field_ptr->bounds.height = 127;
		}
		return TRUE;
		
	case FORM_SYSETUP_EMAIL:
		FormGetObjectPointer(TABLE_SYSETUP_EMAIL, &object_type, (void**)&table_ptr);
		FormGetObjectPointer(SCROLLBAR_SYSETUP_EMAIL, &object_type, (void**)&scroll_ptr);
		if (KeyboardCheckKeyboardStatus())
		{
			scroll_ptr->bounds.height = 65;
			table_ptr->bounds.height = 65;
		}
		else
		{
			scroll_ptr->bounds.height = 108;
			table_ptr->bounds.height = 108;
		}
		return TRUE;
		
	default:	return FALSE;
	}
	
	
	return FALSE;	
}


/********************************************************
* Function:	SySetupGetTableNumLines
* 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 SySetupGetTableNumLines(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:	SySetupGetTableMaxNumLines
* 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 SySetupGetTableMaxNumLines(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:	SySetupGetScrollBarMaxValue
* Purpose: 	This fucntion is called in order to work out the 
max value of the scrollbar
* Scope:		application
* Input:		table_id			The ID value of table object to be scrolled
ref_col				The reference column of the table
* Output:		None
* Return:		max. value
* Comment: 	None
*********************************************************/
WORD SySetupGetScrollbarMaxValue(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);
	
	SySetupGetTableMaxNumLines(table_id, font_id, &max_num_lines);
	SySetupGetTableNumLines(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;
			return (total_num_lines - acc_num_lines);
		}
	}
	return (total_num_lines - acc_num_lines);
}

/********************************************************
* Function:	SySetupDecideTopRowNum
* 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
active_id			The focused field object
* Output:		None
* Return:		TRUE		Success
FALSE		NotHandled
* Comment: 	The decision is made depending on the 
*********************************************************/
BOOLEAN SySetupDecideTopRowNum(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;
		
		SySetupGetTableMaxNumLines(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:	SySetupSetTable
* Purpose: 	This function is called in order to 
set up the table in the SySetup  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 SySetupSetTable(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;
	BYTE font_id;
	SHORT field_height;
	SHORT line_height;			/* line_height = FONT_HEIGHT[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, total_num_lines;
	
	/*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);
	SySetupGetTableMaxNumLines(table_id, font_id, &table_max_num_lines);
	SySetupGetTableNumLines(table_id, 1, &total_num_lines);
	if (table_max_num_lines >= total_num_lines)
		table_ptr->table_top_row_num = 0;
	
	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;
	}
	
	/*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;
		}
	}
	SySetupDecideTopRowNum(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, (table_ptr->table_item_ptr[count * 2 + 1])->table_item_ui_id);
			FormGetObjectPointer((table_ptr->table_item_ptr[count * 2 + 1])->table_item_ui_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;
		}
	}
	if (insert_pt_on == TRUE)
	{
		FormGetObjectPointer(active_id, &object_type, (void**)&field_ptr);
		StrAnalyzeLine(field_ptr);
		FieldGetFirstVisibleChar(active_id, &first_visible_char);
		FieldGetLastVisibleChar(active_id, &last_visible_char);
		for (count = 0; count < field_ptr->field_total_num_lines; count++)
		{
			if (field_ptr->field_insert_pt_char_pos >= field_ptr->field_lineinfo[count].start &&
				field_ptr->field_insert_pt_char_pos < field_ptr->field_lineinfo[count].start + field_ptr->field_lineinfo[count].length)
				break;
		}
		if (field_ptr->field_insert_pt_char_pos < first_visible_char)
			field_ptr->field_top_line_num = count;
		else if (field_ptr->field_insert_pt_char_pos > last_visible_char)
			field_ptr->field_top_line_num = count - field_ptr->field_num_lines_displayed;
		
		if (field_ptr->field_num_lines_displayed < (field_ptr->bounds.height/(line_height)))
		{
			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));
	}
	
	return TRUE;
}


/********************************************************
* Function:	SySetupKeyInChangeTable
* Purpose: 	This function is called when the content in table changed,
then both table
* Scope:		application
* Input:		form_id				The ID value of form object to be scrolled
*				table_id			The ID value of table object to be scrolled
*				scrollbar_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 SySetupKeyInChangeTable(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);
	SySetupGetTableNumLines(table_id, 1, &table_total_num_lines);
	SySetupGetTableMaxNumLines(table_id, font_id, &table_max_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_ptr->bounds.height;
		table_ptr->table_row_height[(USHORT)(active_id - first_field_id)] = table_ptr->bounds.height;
		if (field_total_num_lines <= field_ptr->bounds.height/line_height)
			field_ptr->field_top_line_num = 0;
		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;
		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)*(SysGetFontHeight(font_id) + SPACE_LINE);
		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;
		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 (SySetupDecideTopRowNum(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;
		}
	}
	
	SySetupTableSetScrollbar(table_id, scrollbar_id);
	if (return_boolean == TRUE)
		return TRUE;
	else return FALSE;
}


/********************************************************
* Function:	SySetupTableSetScrollbar
* 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
*				scrollbar_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 SySetupTableSetScrollbar(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);
	SySetupGetTableMaxNumLines(table_id, font_id, &table_max_num_lines);
	SySetupGetTableNumLines(table_id, 1, &table_total_num_lines);
	line_height = SysGetFontHeight(font_id) + SPACE_LINE;
	
	if ((table_total_num_lines > table_max_num_lines))
		scroll_ptr->scrollbar_attr.scrollbar_visible = TRUE;
	else
	{
		scroll_ptr->scrollbar_attr.scrollbar_visible = FALSE;
		//		if (scroll_ptr->scrollbar_attr.scrollbar_drawn == TRUE)
		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;
	for (count = table_ptr->table_top_row_num; count < (table_ptr->table_top_row_num + table_ptr->table_num_row_display);count++)
	{
		FormGetObjectPointer((ObjectID)(count + first_field_id), &object_type, (void**)&field_ptr);		
		acc_num_lines1 += (field_ptr->bounds.height/line_height);
	}
	
	ScrollbarSetScrollbar(scrollbar_id, acc_num_lines, SySetupGetScrollbarMaxValue(table_id, 1), 0, acc_num_lines1, table_total_num_lines);
	scroll_ptr->scrollbar_draw_pagesize = table_max_num_lines;
	ScrollbarDrawScrollbar(scrollbar_id);
	return TRUE;
}

/********************************************************
* Function:	SySetupScrollbarSetTable
* Purpose: 	This function is called in order to change the content 
of a table when a scrollbar is being moved
* Scope:		application
* Input:		table_id			The ID value of table object to be scrolled
first_field_id		The first field ID in the table
scrollbar_id		The ID value of scrollbar object to be scrolled
Event				Input parameters of the scrollbar
* Output:		None
* Return:		TRUE		Success
FALSE		NotHandled
* Comment: 	None
*********************************************************/
BOOLEAN SySetupScrollbarSetTable(ObjectID table_id, ObjectID field_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;
	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;
	
	/*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);
	SySetupGetTableMaxNumLines(table_id, font_id, &table_max_num_lines);
	SySetupGetTableNumLines(table_id, 1, &table_total_num_lines);
	line_height = SysGetFontHeight(font_id) + SPACE_LINE;
	
    for (count = field_id; count < (field_id + 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_id)] = 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_display; count++)
	{
		if (table_ptr->table_num_row_display == 1)
			continue;
		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
		{
            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;
                StrAnalyzeLine(field_ptr);
                table_change = TRUE;
            }
		}
	}
    if (table_change)
	{
        if (Event->eventType == EVT_SCROLLBAR_SELECT ||
            (Event->eventType == EVT_SCROLLBAR_REPEAT))
		{
            TableDrawTable(table_id);
            LcdEnableInsertPt(FALSE, 0, 0, SMALL_FONT);
		}
	}
	else if (field_change)
		FieldDrawField(field_redraw_id);
	
	qfree(row_num_lines);
	return TRUE;
}


/********************************************************
* Function:	SySetupFieldSetScrollbar
* Purpose: 	This function is called in order to set the values for a scrollbar		
* Scope:		application
* Input:		field_id			The ID value of field object to be scrolled
scrollbar_id		The ID value of scrollbar object to be scrolled
* Output:		None
* Return:		TRUE				scrollbar is erased
*				FALSE				scrollbar is drawn
* Comment: 	If a scrollbar is not required, then the scrollbar will be erased 
If a scrollbar is required, the scrollbar will be displayed accordingly 
*********************************************************/
BOOLEAN SySetupFieldSetScrollbar(ObjectID field_id, ObjectID scrollbar_id)
{
	Field		*field_ptr;
	Scrollbar	*scroll_ptr;
	BYTE		font_id;
	BYTE		object_type;
	
	WORD	max_num_lines;
	WORD	max_value, min_value, pagesize;
	
	FormGetObjectPointer(field_id, &object_type, (void**)&field_ptr);
	
	FieldGetFont(field_id, &font_id);
	max_num_lines = field_ptr->bounds.height/(SysGetFontHeight(font_id) + SPACE_LINE);
	
	pagesize = max_num_lines  - 1;
	min_value = 0;
	
	max_value = field_ptr->field_total_num_lines - pagesize - 1;	
	
	
	//	if (field_ptr->field_total_num_lines >= max_num_lines)
	if (field_ptr->field_total_num_lines > max_num_lines)
		ScrollbarSetScrollbarVisible(scrollbar_id, TRUE);
	else
	{
		ScrollbarSetScrollbarVisible(scrollbar_id, FALSE);
		ScrollbarEraseScrollbar(scrollbar_id);
		return FALSE;
	}
	
	FormGetObjectPointer(scrollbar_id, &object_type, (void**)&scroll_ptr);		
	scroll_ptr->scrollbar_draw_pagesize = max_num_lines;
	
	if (field_ptr->field_top_line_num > (field_ptr->field_total_num_lines - max_num_lines))
		ScrollbarSetScrollbar(scrollbar_id, max_value, max_value, min_value,
		pagesize, field_ptr->field_total_num_lines);
	else
		ScrollbarSetScrollbar(scrollbar_id, field_ptr->field_top_line_num, max_value, min_value,
		pagesize, field_ptr->field_total_num_lines);
	ScrollbarDrawScrollbar(scrollbar_id);
	return TRUE;
}


/********************************************************
* Function:	SySetupScrollbarSetField
* Purpose: 	This function is called to set the field
*				when the scrollbar is moved.
* Scope:		application
* Input:		field_id			The ID value of field object to be scrolled
scrollbar_id		The ID value of scrollbar object to be scrolled
Event				Input parameters of the scrollbar
* Output:		None
* Return:		None
* Comment: 	None
*********************************************************/
void SySetupScrollbarSetField(ObjectID field_id, ObjectID scrollbar_id, EvtType *Event)
{
	WORD max,min,value,pagesize;
	WORD scroll_total_lines;
	WORD insert_pt_pos;
	
	ScrollbarGetScrollbar(scrollbar_id, &value, &max, &min, &pagesize, &scroll_total_lines);
	
	ScrollbarSetScrollbar(scrollbar_id, Event->para2, max, min, pagesize, scroll_total_lines);
	FieldSetTopLineNum(field_id, (USHORT)(Event->para2));	
	
	//====================================================================
	//add at 17/07/2000
	FieldGetInsertPointPosition(field_id, &insert_pt_pos);
	FieldSetInsertPointPositionByCharPos(field_id, insert_pt_pos);
	//====================================================================
	FieldDrawField(field_id);
	ScrollbarDrawScrollbar(scrollbar_id);		
	
	return;
}


/********************************************************
* Function:	SySetupSetField
* Purpose: 	This function is called in order to 
set up the table in the SySetup  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
field_id			The ID value of field object to be scrolled
* Output:		None
* Return:		TRUE		Success
FALSE		NotHandled
* Comment: 	None
*********************************************************/
BOOLEAN SySetupSetField(ObjectID form_id, ObjectID field_id)
{
	Field	*field_ptr;
	BOOLEAN insert_pt_on = FALSE;
	BYTE	font_id;
	BYTE	object_type;
	SHORT	acc_height = 0;
	SHORT	line_height;			/* line_height = FONT_HEIGHT[font_id] + SPACE_LINE;*/
	WORD	count = 0;				/* another temperatory variable */
	WORD	first_visible_char, last_visible_char;
	
	/*The bounds of the table should be set outside this function according
	to the keyboard status */
	
	FormGetObjectPointer(field_id, &object_type, (void**)&field_ptr);		
	insert_pt_on = field_ptr->field_attr.field_insert_pt_visible;
	
	FieldGetFont(field_id, &font_id);
	line_height = SysGetFontHeight(font_id) + SPACE_LINE;
	
	if (insert_pt_on == TRUE)
	{
		StrAnalyzeLine(field_ptr);
		FieldGetFirstVisibleChar(field_id, &first_visible_char);
		FieldGetLastVisibleChar(field_id, &last_visible_char);
		for (count = 0; count < field_ptr->field_total_num_lines; count++)
		{
			if (field_ptr->field_insert_pt_char_pos >= field_ptr->field_lineinfo[count].start &&
				field_ptr->field_insert_pt_char_pos < field_ptr->field_lineinfo[count].start + field_ptr->field_lineinfo[count].length)
				break;
		}
		if (field_ptr->field_insert_pt_char_pos < first_visible_char)
			field_ptr->field_top_line_num = count;
		else if (field_ptr->field_insert_pt_char_pos > last_visible_char)
			field_ptr->field_top_line_num = count - field_ptr->field_num_lines_displayed;
		
		if (field_ptr->field_num_lines_displayed < (field_ptr->bounds.height/(line_height)))
		{
			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)));
			if (field_ptr->field_top_line_num < 0)
				field_ptr->field_top_line_num = 0;
		}
		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));
	}
	return TRUE;
}

/*****************************************************************
* Function:	SySetupDisplaySystemInfo
* Purpose: 	This function is used to display the system information
*				from the database
* Scope:		application
* Input:		None
* Output:		None
* Return:		None
* Comment: 	None
*****************************************************************/
void SySetupDisplaySystemInfo(WORD pwr_level)
{
	BYTE	free_mem_string[30];
	UWORD	total_mem, sys_used_mem, free_mem;
	
	total_mem = MemoryTotalSysMem(&sys_used_mem);
	/*	free_mem = 100*(total_mem - sys_used_mem)/total_mem;
	
	  printf("\n ++++==++ free_mem=%ld, total_mem=%ld", free_mem, total_mem);
	*/
	free_mem = 100 * (BLOCK_SIZE * MemoryTotalFree())/(total_mem-sys_used_mem-131072);
	
	if (free_mem > 99)
		free_mem = 99;
	ScrollbarSetScrollbar(SCROLLBAR_SYSETUP_SYSINFO, (WORD)(free_mem), 100, 0, 1, 101);
	sprintf((char*)free_mem_string, "%ld%%", free_mem);
	ScrollbarSetScrollbarText(SCROLLBAR_SYSETUP_SYSINFO, free_mem_string);
	ScrollbarDrawScrollbar(SCROLLBAR_SYSETUP_SYSINFO);
	
	if (pwr_level > 9)
	{
		ScrollbarSetScrollbar(SCROLLBAR_SYSETUP_SYSINFO_BATTERY, 999999, 1000000, 0, 1, 1000001);
	}
	else
		ScrollbarSetScrollbar(SCROLLBAR_SYSETUP_SYSINFO_BATTERY, pwr_level*10, 100, 0, 1, 101);
	//sprintf((char*)free_mem_string, "%ld%%", pwr_level*10);
	sprintf((char*)free_mem_string, "");
	ScrollbarSetScrollbarText(SCROLLBAR_SYSETUP_SYSINFO_BATTERY, free_mem_string);
	ScrollbarDrawScrollbar(SCROLLBAR_SYSETUP_SYSINFO_BATTERY);
	
	return;
}



/********************************************************
* Function:	SySetupDelAppListSetScrollbar
* Purpose: 	This function is called in order to set the values for a scrollbar		
* Scope:		application
* Input:		None
* Output:		None
* Return:		TRUE				scrollbar is erased
*				FALSE				scrollbar is drawn
* Comment: 	If a scrollbar is not required, then the scrollbar will be erased 
If a scrollbar is required, the scrollbar will be displayed accordingly 
*********************************************************/
BOOLEAN SySetupDelAppListSetScrollbar(void)
{
	USHORT	total_num_item;
	USHORT	max_num_item_display;
	USHORT	top_item_num;
	USHORT	current_num_item_display;
	
	WORD	max_value, min_value, pagesize, total_num_lines;
	
	ListRecalculateMaxNumItemsDisplay(LIST_SYSETUP_SYSINFO_DELAPP_APPNAME);
	ListGetMaxNumItemsDisplay(LIST_SYSETUP_SYSINFO_DELAPP_APPNAME, &max_num_item_display);
	ListGetTotalItems(LIST_SYSETUP_SYSINFO_DELAPP_APPNAME, &total_num_item);
	ListGetTopItemNum(LIST_SYSETUP_SYSINFO_DELAPP_APPNAME, &top_item_num);
	ListGetNumItemsDisplay (LIST_SYSETUP_SYSINFO_DELAPP_APPNAME, &current_num_item_display);
	
	total_num_lines = total_num_item;
	pagesize = max_num_item_display-1;
	min_value = 0;
	max_value = total_num_lines - pagesize - 1;	
	
	if (total_num_item > max_num_item_display)
		ScrollbarSetScrollbarVisible(SCROLLBAR_SYSETUP_SYSINFO_DELAPP, TRUE);
	else
	{
		ScrollbarSetScrollbarVisible(SCROLLBAR_SYSETUP_SYSINFO_DELAPP, FALSE);
		ScrollbarEraseScrollbar(SCROLLBAR_SYSETUP_SYSINFO_DELAPP);
		return FALSE;
	}
	
	if (top_item_num > (total_num_item - max_num_item_display))
		ScrollbarSetScrollbar(SCROLLBAR_SYSETUP_SYSINFO_DELAPP, max_value, max_value, min_value, pagesize, total_num_lines);
	else
		ScrollbarSetScrollbar(SCROLLBAR_SYSETUP_SYSINFO_DELAPP, top_item_num, max_value, min_value, pagesize, total_num_lines);
	
	ScrollbarSetScrollbarDrawPagesize(SCROLLBAR_SYSETUP_SYSINFO_DELAPP, pagesize+1);
	return TRUE;
	
}

/********************************************************
* Function:	SySetupScrollbarSetDelAppList
* Purpose: 	This function is called to set list of the delete
application page when the scrollbar is moved.
* Scope:		application
* Input:		item_num
* Output:		None
* Return:		None
* Comment: 	None
*********************************************************/
void SySetupScrollbarSetDelAppList(USHORT item_num)
{
	WORD max, min, value, pagesize, scroll_total_lines;
	
	ScrollbarGetScrollbar(SCROLLBAR_SYSETUP_SYSINFO_DELAPP, &value, &max, &min, &pagesize, &scroll_total_lines);
	
	ScrollbarSetScrollbar(SCROLLBAR_SYSETUP_SYSINFO_DELAPP, (WORD)item_num, max, min, pagesize, scroll_total_lines);
	
	ListSetTopItemNum(LIST_SYSETUP_SYSINFO_DELAPP_APPNAME, item_num);
	ListSetTopItemNum(LIST_SYSETUP_SYSINFO_DELAPP_APPSIZE, item_num);
	
	return;
}
