/*
================================ 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        :   control.c
Author(s)   :   Henry Fok, David Lo
Company     :   VTech Informations Ltd.
Project     :   Helio 
Date:	    :   October 1st, 1999
Purpose:	:   control object functions
Revision    :   1.1
Note        :   None
===========================================================================
*/              
#include "stdafx.h"
#include "uifunc.h"
#include "uidef.h"

BOOLEAN     beep_beep = FALSE;

//#define DEBUG
//#define DEBUG_UP
/*********************************************************************
* Function	: ControlDrawTapButton
* Purpose	: 
* Scope		: Application/Internal
* Input		: bounds		Pointer to the bounds structure
* Output	: None
* Return	: None
* Comment	: None
**********************************************************************/
void ControlDrawTapButton(Control *addr,ObjectBounds *bounds,SHORT draw_radius,BYTE bg_color)
{
	SHORT draw_xcoord, draw_ycoord, draw_end_xcoord, draw_end_ycoord;
	ObjectBounds box;
	
	/* Draw the upper horizontal line */
	draw_xcoord = bounds->xcoord+draw_radius;
	draw_ycoord = bounds->ycoord;
	draw_end_xcoord = bounds->xcoord+bounds->width-draw_radius-1;
	draw_end_ycoord = bounds->ycoord;
	LcdDrawLine(draw_xcoord,draw_ycoord,draw_end_xcoord,draw_end_ycoord,SINGLE_LINE,NON_DOTTED_LINE,color_level[COLOR_BLACK_COLOR],color_level[COLOR_BLACK_COLOR]);
	
    /* Draw the lower horizontal line */
	draw_xcoord = bounds->xcoord;
	draw_ycoord = bounds->ycoord+bounds->height;
	draw_end_xcoord = bounds->xcoord+bounds->width-1;
	draw_end_ycoord = bounds->ycoord+bounds->height;
	LcdDrawLine(draw_xcoord,draw_ycoord,draw_end_xcoord,draw_end_ycoord,SINGLE_LINE,NON_DOTTED_LINE,bg_color,bg_color);
	
	/* Draw the left vertical line */
	draw_xcoord = bounds->xcoord;
	draw_ycoord = bounds->ycoord+draw_radius;
	draw_end_xcoord = bounds->xcoord;
	draw_end_ycoord = bounds->ycoord+bounds->height-1;
	LcdDrawLine(draw_xcoord,draw_ycoord,draw_end_xcoord,draw_end_ycoord,SINGLE_LINE,NON_DOTTED_LINE,color_level[COLOR_BLACK_COLOR],color_level[COLOR_BLACK_COLOR]);
	
	/* Draw the right vertical line */
	draw_xcoord = bounds->xcoord+bounds->width-1;
	draw_ycoord = bounds->ycoord+draw_radius;
	draw_end_xcoord = bounds->xcoord+bounds->width-1;
	draw_end_ycoord = bounds->ycoord+bounds->height-1;
    LcdDrawLine(draw_xcoord, draw_ycoord, draw_end_xcoord, draw_end_ycoord, SINGLE_LINE,NON_DOTTED_LINE, color_level[COLOR_BLACK_COLOR], color_level[COLOR_BLACK_COLOR]);
	
	/* Draw the vertical box */
	box = *bounds;
	box.xcoord = bounds->xcoord+draw_radius;
	box.ycoord = bounds->ycoord+1;
	box.width  = bounds->width-draw_radius*2;
	box.height = bounds->height-2;
	if (bg_color == color_level[COLOR_WHITE_COLOR])
		LcdDrawBox(&box,color_level[COLOR_WHITE_COLOR],color_level[COLOR_WHITE_COLOR],FILL_SOLID);
	else
		LcdDrawBox(&box,color_level[COLOR_GREY1_COLOR],color_level[COLOR_GREY1_COLOR],FILL_SOLID);
	
	/* Draw the horizontal box */
	box = *bounds;
	box.xcoord = bounds->xcoord+1;
	box.ycoord = bounds->ycoord+draw_radius;
	box.width  = bounds->width-2;
    box.height = bounds->height-2;
	if (bg_color == color_level[COLOR_WHITE_COLOR])
	{
		LcdDrawBox(&box,color_level[COLOR_WHITE_COLOR],color_level[COLOR_WHITE_COLOR],FILL_SOLID);
		box = *bounds;
		ControlDrawString(addr,&box,color_level[COLOR_BLACK_COLOR],addr->control_text,color_level[COLOR_WHITE_COLOR]);
	}
	else
	{
		LcdDrawBox(&box,color_level[COLOR_GREY1_COLOR],color_level[COLOR_GREY1_COLOR],FILL_SOLID);
		box = *bounds;
		ControlDrawString(addr,&box,color_level[COLOR_BLACK_COLOR],addr->control_text,color_level[COLOR_GREY1_COLOR]);
	}
	
	/* Draw an Arc in the first quarter */
	draw_xcoord = bounds->xcoord+bounds->width-draw_radius-1;
	draw_ycoord = bounds->ycoord+draw_radius;
	if (bg_color == color_level[COLOR_WHITE_COLOR])
		LcdDrawArc(draw_xcoord,draw_ycoord,draw_radius,NON_DOTTED_LINE,color_level[COLOR_BLACK_COLOR],color_level[COLOR_WHITE_COLOR],FILL_EMPTY,QUARTER_1);
	else
		LcdDrawArc(draw_xcoord,draw_ycoord,draw_radius,NON_DOTTED_LINE,color_level[COLOR_BLACK_COLOR],color_level[COLOR_GREY1_COLOR],FILL_EMPTY,QUARTER_1);
	
	/* Draw an Arc in the second quarter */
	draw_xcoord = bounds->xcoord+draw_radius;
	draw_ycoord = bounds->ycoord+draw_radius;
	if (bg_color == color_level[COLOR_WHITE_COLOR])
		LcdDrawArc(draw_xcoord,draw_ycoord,draw_radius,NON_DOTTED_LINE,color_level[COLOR_BLACK_COLOR],color_level[COLOR_WHITE_COLOR],FILL_EMPTY,QUARTER_2);
	else
		LcdDrawArc(draw_xcoord,draw_ycoord,draw_radius,NON_DOTTED_LINE,color_level[COLOR_BLACK_COLOR],color_level[COLOR_GREY1_COLOR],FILL_EMPTY,QUARTER_2);
}

/*********************************************************************
* Function	: ControlDrawEmptyButton
* Purpose	: To draw 4 lines of the button according to the boundary
The button will not be filled
* Scope		: Application/Internal
* Input		: bounds		Pointer to the bounds structure
draw_radius	the radius of rounded corners
* Output	: None
* Return	: None
* Comment	: None
**********************************************************************/
void ControlDrawEmptyButton(ObjectBounds *bounds,SHORT draw_radius,BYTE bg_color)
{
	SHORT draw_xcoord, draw_ycoord, draw_end_xcoord, draw_end_ycoord;
	ObjectBounds box;
	
	/* Draw the upper horizontal line */
	draw_xcoord = bounds->xcoord+draw_radius;
	draw_ycoord = bounds->ycoord;
	draw_end_xcoord = bounds->xcoord+bounds->width-draw_radius-1;
	draw_end_ycoord = bounds->ycoord;
	LcdDrawLine(draw_xcoord,draw_ycoord,draw_end_xcoord,draw_end_ycoord,SINGLE_LINE,NON_DOTTED_LINE,color_level[COLOR_BLACK_COLOR],color_level[COLOR_BLACK_COLOR]);
	if (bg_color == color_level[COLOR_WHITE_COLOR])
		LcdDrawLine(draw_xcoord,draw_ycoord+1,draw_end_xcoord,draw_end_ycoord+1,SINGLE_LINE,NON_DOTTED_LINE,color_level[COLOR_WHITE_COLOR],color_level[COLOR_WHITE_COLOR]);
	else
		LcdDrawLine(draw_xcoord,draw_ycoord+1,draw_end_xcoord,draw_end_ycoord+1,SINGLE_LINE,NON_DOTTED_LINE,color_level[COLOR_BLACK_COLOR],color_level[COLOR_BLACK_COLOR]);
	
	/* Draw the lower horizontal line */
	draw_xcoord = bounds->xcoord+draw_radius;
	draw_ycoord = bounds->ycoord+bounds->height-1;
	draw_end_xcoord = bounds->xcoord+bounds->width-draw_radius-1;
	draw_end_ycoord = bounds->ycoord+bounds->height-1;
	LcdDrawLine(draw_xcoord,draw_ycoord,draw_end_xcoord,draw_end_ycoord,SINGLE_LINE,NON_DOTTED_LINE,color_level[COLOR_BLACK_COLOR],color_level[COLOR_BLACK_COLOR]);
	
	if (bg_color == color_level[COLOR_WHITE_COLOR])
	{
		if (color_mode == GREYSCALE_MODE)
			LcdDrawLine(draw_xcoord,draw_ycoord-1,draw_end_xcoord,draw_end_ycoord-1,SINGLE_LINE,NON_DOTTED_LINE,color_level[COLOR_GREY2_COLOR],color_level[COLOR_GREY2_COLOR]);
		else			
			LcdDrawLine(draw_xcoord,draw_ycoord-1,draw_end_xcoord,draw_end_ycoord-1,SINGLE_LINE,NON_DOTTED_LINE,color_level[COLOR_WHITE_COLOR],color_level[COLOR_WHITE_COLOR]);		
	}			
	else
	{
		if (color_mode == GREYSCALE_MODE)		
			LcdDrawLine(draw_xcoord,draw_ycoord-1,draw_end_xcoord,draw_end_ycoord-1,SINGLE_LINE,NON_DOTTED_LINE,color_level[COLOR_GREY1_COLOR],color_level[COLOR_GREY1_COLOR]);		
		else
			LcdDrawLine(draw_xcoord,draw_ycoord-1,draw_end_xcoord,draw_end_ycoord-1,SINGLE_LINE,NON_DOTTED_LINE,color_level[COLOR_BLACK_COLOR],color_level[COLOR_BLACK_COLOR]);				 			
	}			
	
	
	/* Draw the left vertical line */
	draw_xcoord = bounds->xcoord;
	draw_ycoord = bounds->ycoord+draw_radius;
	draw_end_xcoord = bounds->xcoord;
	draw_end_ycoord = bounds->ycoord+bounds->height-draw_radius-1;
	LcdDrawLine(draw_xcoord,draw_ycoord,draw_end_xcoord,draw_end_ycoord,SINGLE_LINE,NON_DOTTED_LINE,color_level[COLOR_BLACK_COLOR],color_level[COLOR_BLACK_COLOR]);
	if (bg_color == color_level[COLOR_WHITE_COLOR])
		LcdDrawLine(draw_xcoord+1,draw_ycoord,draw_end_xcoord+1,draw_end_ycoord,SINGLE_LINE,NON_DOTTED_LINE,color_level[COLOR_WHITE_COLOR],color_level[COLOR_WHITE_COLOR]);
	else
		LcdDrawLine(draw_xcoord+1,draw_ycoord,draw_end_xcoord+1,draw_end_ycoord,SINGLE_LINE,NON_DOTTED_LINE,color_level[COLOR_BLACK_COLOR],color_level[COLOR_BLACK_COLOR]);	
	
	
	/* Draw the right vertical line */
	draw_xcoord = bounds->xcoord+bounds->width-1;
	draw_ycoord = bounds->ycoord+draw_radius;
	draw_end_xcoord = bounds->xcoord+bounds->width-1;
	draw_end_ycoord = bounds->ycoord+bounds->height-draw_radius-1;
	LcdDrawLine(draw_xcoord,draw_ycoord,draw_end_xcoord,draw_end_ycoord,SINGLE_LINE,NON_DOTTED_LINE,color_level[COLOR_BLACK_COLOR],color_level[COLOR_BLACK_COLOR]);
	if (bg_color == color_level[COLOR_WHITE_COLOR])
	{
		if (color_mode == GREYSCALE_MODE)	
			LcdDrawLine(draw_xcoord-1,draw_ycoord,draw_end_xcoord-1,draw_end_ycoord,SINGLE_LINE,NON_DOTTED_LINE,color_level[COLOR_GREY2_COLOR],color_level[COLOR_GREY2_COLOR]);
		else
			LcdDrawLine(draw_xcoord-1,draw_ycoord,draw_end_xcoord-1,draw_end_ycoord,SINGLE_LINE,NON_DOTTED_LINE,color_level[COLOR_WHITE_COLOR],color_level[COLOR_WHITE_COLOR]); 			
	}			
	else	
	{
		if (color_mode == GREYSCALE_MODE)
			LcdDrawLine(draw_xcoord-1,draw_ycoord,draw_end_xcoord-1,draw_end_ycoord,SINGLE_LINE,NON_DOTTED_LINE,color_level[COLOR_GREY1_COLOR],color_level[COLOR_GREY1_COLOR]);
		else 			
			LcdDrawLine(draw_xcoord-1,draw_ycoord,draw_end_xcoord-1,draw_end_ycoord,SINGLE_LINE,NON_DOTTED_LINE,color_level[COLOR_BLACK_COLOR],color_level[COLOR_BLACK_COLOR]);		
	}			
	
	box = *bounds;
	box.xcoord = bounds->xcoord+2;
	box.ycoord = bounds->ycoord+2;
	box.width  = bounds->width-4;
	box.height = bounds->height-4;
	if (bg_color == color_level[COLOR_WHITE_COLOR])
		LcdDrawBox(&box,color_level[COLOR_GREY1_COLOR],color_level[COLOR_GREY1_COLOR],DRAW_FILL);
	else
		LcdDrawBox(&box,color_level[COLOR_GREY2_COLOR],color_level[COLOR_GREY2_COLOR],DRAW_FILL);
}
/*********************************************************************
* Function	: ControlDrawArc
* Purpose	: To drawn 4 arc for the round corner of the control object
* Scope		: Application/Internal
* Input		: bounds		Pointer to the bounds structure
draw_fill     whether to fill the arc region
draw_radius	the radius of the arc
* Output	: None
* Return	: None
* Comment	: None
**********************************************************************/
void ControlDrawArc(ObjectBounds *bounds,BOOLEAN draw_fill,SHORT draw_radius,BYTE bg_color)
{
	SHORT draw_xcoord, draw_ycoord;
	/* Draw an Arc in the first quarter */
	draw_xcoord = bounds->xcoord+bounds->width-draw_radius-1;
	draw_ycoord = bounds->ycoord+draw_radius;
	if (bg_color == color_level[COLOR_WHITE_COLOR])
		LcdDrawArc(draw_xcoord,draw_ycoord,draw_radius,NON_DOTTED_LINE,color_level[COLOR_BLACK_COLOR],color_level[COLOR_GREY2_COLOR],(BYTE) draw_fill,QUARTER_1);
	else
		LcdDrawArc(draw_xcoord,draw_ycoord,draw_radius,NON_DOTTED_LINE,color_level[COLOR_BLACK_COLOR],color_level[COLOR_GREY1_COLOR],(BYTE) draw_fill,QUARTER_1);
	/* Draw an Arc in the second quarter */
	draw_xcoord = bounds->xcoord+draw_radius;
	draw_ycoord = bounds->ycoord+draw_radius;
	if (bg_color == color_level[COLOR_WHITE_COLOR])
		LcdDrawArc(draw_xcoord,draw_ycoord,draw_radius,NON_DOTTED_LINE,color_level[COLOR_BLACK_COLOR],color_level[COLOR_WHITE_COLOR], (BYTE) draw_fill,QUARTER_2);
	else
		LcdDrawArc(draw_xcoord,draw_ycoord,draw_radius,NON_DOTTED_LINE,color_level[COLOR_BLACK_COLOR],color_level[COLOR_BLACK_COLOR], (BYTE) draw_fill,QUARTER_2);		
	/* Draw an Arc in the third quarter */
	draw_xcoord = bounds->xcoord+draw_radius;
	draw_ycoord = bounds->ycoord+bounds->height-draw_radius-1;
	if (bg_color == color_level[COLOR_WHITE_COLOR])
		LcdDrawArc(draw_xcoord,draw_ycoord,draw_radius,NON_DOTTED_LINE,color_level[COLOR_BLACK_COLOR],color_level[COLOR_WHITE_COLOR], (BYTE) draw_fill,QUARTER_3);
	else
		LcdDrawArc(draw_xcoord,draw_ycoord,draw_radius,NON_DOTTED_LINE,color_level[COLOR_BLACK_COLOR],color_level[COLOR_BLACK_COLOR], (BYTE) draw_fill,QUARTER_3);
	/* Draw an Arc in the fourth quarter */
	draw_xcoord = bounds->xcoord+bounds->width-draw_radius-1;
	draw_ycoord = bounds->ycoord+bounds->height-draw_radius-1;
	if (bg_color == color_level[COLOR_WHITE_COLOR])
		LcdDrawArc(draw_xcoord,draw_ycoord,draw_radius,NON_DOTTED_LINE,color_level[COLOR_BLACK_COLOR],color_level[COLOR_GREY2_COLOR], (BYTE) draw_fill,QUARTER_4);
	else
		LcdDrawArc(draw_xcoord,draw_ycoord,draw_radius,NON_DOTTED_LINE,color_level[COLOR_BLACK_COLOR],color_level[COLOR_GREY1_COLOR], (BYTE) draw_fill,QUARTER_4);
}
/*********************************************************************
* Function	: ControlDrawString
* Purpose	: To draw a string in the control object
* Scope		: Application\Internal
* Input		: addr                Pointer to a control object
bounds              Pointer to bounds structure
draw_color          Boolean value to show what color will bel used
draw_text           pointer to a null_terminated string
border_width        width of border
* Output	: None
* Return	: None
* Comment	: None
**********************************************************************/
void ControlDrawString(Control *addr,ObjectBounds *bounds,BYTE draw_color,BYTE *draw_text,BYTE bg_color)
{
	ObjectBounds temp;
	SHORT	text_width;
	SHORT	button_border, change;
	
	
	if ((addr->control_style == PUSH_BUTTON && (addr->control_subtype == PUSHBUTTON_STYLE_1 || addr->control_subtype == PUSHBUTTON_STYLE_2)) ||
		addr->control_style == BUTTON && addr->control_subtype == BUTTON_STYLE_1 ||
		addr->control_style == POPUP_TRIGGER && (addr->control_subtype == POPUP_TRIGGER_STYLE_1 || addr->control_subtype == POPUP_TRIGGER_STYLE_2))
		button_border = BUTTON_BORDER;		/* Two pixel space between the Text and Button's border */
	else if (addr->control_style == PUSH_BUTTON && addr->control_subtype == PUSHBUTTON_STYLE_3)
		button_border = TAP_BUTTON_BORDER;	/* One pixel space between the Text and Button's border */
	else
		button_border = BUTTON_NO_BORDER;	/* No pixel space between the Text and Button's border */
	
	/* Left alignment */
	if (addr->text_alignment == 0)
	{	
		text_width = StrGetWidth(draw_text,SMALL_FONT)-2;
		temp.xcoord = bounds->xcoord;
		temp.ycoord = bounds->ycoord + (bounds->height-FONT_HEIGHT[0])/2;
		temp.width  = bounds->width - button_border*2;
		temp.height = FONT_HEIGHT[0];
		
		if (addr->control_style == POPUP_TRIGGER && addr->control_subtype == POPUP_TRIGGER_STYLE_1)
			temp.width  -= (POPUP_INDICATOR_WIDTH-button_border);
		/* Check the corresponding UI object type and subtract the offset from to y-coordinate */
		if (button_border == BUTTON_BORDER)			
			temp.ycoord -= (1+button_border);
	}
	/* Centre alignment */
	else if (addr->text_alignment == 1)
	{		
		text_width= StrGetWidth(draw_text,SMALL_FONT)-2;
		
		if (addr->control_style == POPUP_TRIGGER && addr->control_subtype == POPUP_TRIGGER_STYLE_1)
		{								
			while(text_width + POPUP_INDICATOR_WIDTH + 2 >= (bounds->width - button_border*2))
				text_width--;
			temp.xcoord = bounds->xcoord + (bounds->width-text_width-POPUP_INDICATOR_WIDTH)/2 - button_border; 
		}
		else 
		{
			if (addr->control_style == PUSH_BUTTON && addr->control_subtype == PUSHBUTTON_STYLE_2 && text_width >= bounds->width)
				change = 0;
			else
				change = button_border;
			
			while(text_width >= (bounds->width/* - button_border*2*/))
				text_width--;
			temp.xcoord = bounds->xcoord + (bounds->width-text_width)/2 - change;
		}
		temp.ycoord = bounds->ycoord+(bounds->height-FONT_HEIGHT[0])/2;
		temp.width =  bounds->width - button_border*2;
		temp.height = FONT_HEIGHT[0];
		/* Check the corresponding UI object type and subtract the offset from y-coordinate */
		if (button_border == BUTTON_BORDER)			
			temp.ycoord -= (1+button_border);
	}
	/* Right alignment */
	else
	{
		text_width = StrGetWidth(draw_text,SMALL_FONT)-2;
		
		if (addr->control_style == POPUP_TRIGGER && (addr->control_subtype == POPUP_TRIGGER_STYLE_1 || addr->control_subtype == POPUP_TRIGGER_STYLE_3))
		{								
			while(text_width+POPUP_INDICATOR_WIDTH+2 >= (bounds->width - button_border*2))
				text_width--;
			temp.xcoord = bounds->xcoord+(bounds->width-1)-text_width-POPUP_INDICATOR_WIDTH;
		}
		else 
		{
			while(text_width >= (bounds->width - button_border*2))
				text_width--;
			temp.xcoord = bounds->xcoord+(bounds->width-1)-text_width;
		}
		temp.ycoord = bounds->ycoord+(bounds->height-FONT_HEIGHT[0])/2;
		temp.width =  bounds->width - button_border*2;
		temp.height = FONT_HEIGHT[0];
		/* Check the corresponding UI object type and subtract the offset from to y-coordinate */
		if (button_border == BUTTON_BORDER)
			temp.ycoord -= (1+button_border);
	}
	if (text_width >= 0)
		LcdDrawFixedString(&temp,draw_text,draw_color,bg_color,SMALL_FONT,DOTDOT,button_border);
}
/*********************************************************************
* Function	: ControlDrawControl
* Purpose	: To draw the Control object on the display
* Scope		: Application
* Input		: DBID of the Control object
* Output	: None
* Return	: TRUE if no error
ErrUiResNotFound
* Comment	: None
**********************************************************************/
Err ControlDrawControl (ObjectID control_id)
{
	Control *addr;
	SHORT	draw_radius,draw_width;
	USHORT	popup_current_num_item,popup_top_item_num,popup_highlighted_item,popup_indicator_width;
	WORD count = 0;
	BYTE	draw_color,bg_color,get_value,enter_value,*draw_text,object_type;
	ObjectBounds	bounds,text,highlight,popup_bounds,previous_bounds,temp;
	BitmapTemplate	popup_bitmap,bitmap_struct;
	
	
	if (UISearchForAddress(control_id,&object_type,(void**)&addr) != TRUE) return ERR_UI_RES_NOT_FOUND;
	if (addr->control_attr.control_visible == FALSE) return FALSE;
	if (addr->identification.table_related == 0xFFFF) bounds = addr->bounds;
	else bounds = addr->screen_bounds;
	
	switch (addr->control_style)
	{
	case BUTTON:	
		enter_value = (BYTE)(addr->control_attr.control_enter);
		get_value = (BYTE)(((ControlTemplateButton *) addr->control_template)->control_value);
		draw_radius = ((ControlTemplateButton *) addr->control_template)->button_radius;
		/* Check for the enter state */
		if (enter_value == CLICK_ON)
			draw_color = ((ControlTemplateButton *) addr->control_template)->button_color_on;
		else
			draw_color = ((ControlTemplateButton *) addr->control_template)->button_color_off;
		/* Framed Button */
		if (addr->control_subtype == BUTTON_STYLE_1)
		{
			if (draw_color == CLICK_ON)
			{
				ControlDrawArc(&bounds,DRAW_FILL,draw_radius,draw_color);
				ControlDrawEmptyButton(&bounds,draw_radius,draw_color);
			}
			else
			{
				ControlDrawEmptyButton(&bounds,draw_radius,draw_color);
				ControlDrawArc(&bounds,DRAW_NOT_FILL,draw_radius,draw_color);
			}
		}
		draw_color = ColorInvert(draw_color);
		
		if (draw_color == color_level[COLOR_BLACK_COLOR])
			ControlDrawString(addr,&bounds,draw_color,addr->control_text,color_level[COLOR_GREY1_COLOR]);
		else 
		{
			if (addr->control_subtype == BUTTON_STYLE_1 && color_mode == GREYSCALE_MODE)
			{
				bounds.xcoord += 1;
				bounds.ycoord += 1;
			}
			ControlDrawString(addr,&bounds,draw_color,addr->control_text,color_level[COLOR_GREY2_COLOR]);
		}
		break;
		/* Push Button */
	case PUSH_BUTTON: 
		get_value = (BYTE)(((ControlTemplatePushButton *) addr->control_template)->control_value);
		enter_value = (BYTE)(addr->control_attr.control_enter);
		draw_radius = ((ControlTemplatePushButton *) addr->control_template)->push_button_radius;
		/* Check for the enter state */
		if (enter_value == CLICK_ON)
			draw_color = ((ControlTemplatePushButton *) addr->control_template)->push_button_color_on;
		else
		{
			if (get_value == CLICK_ON)
				draw_color = ((ControlTemplatePushButton *) addr->control_template)->push_button_color_on;
			else
				draw_color = ((ControlTemplatePushButton *) addr->control_template)->push_button_color_off;
		}
		/* Check if not TAP Push button */
		if (addr->control_subtype != PUSHBUTTON_STYLE_3 )
		{
			text = temp = bounds;
			/* Check if is right-corned box */			
			if (addr->control_subtype == PUSHBUTTON_STYLE_1)
			{	
				LcdDrawBox(&bounds,color_level[COLOR_BLACK_COLOR],color_level[COLOR_WHITE_COLOR],DRAW_NOT_FILL);
				if (draw_color == CLICK_OFF)
				{
					temp.xcoord += 2;
					temp.ycoord += 2;
					temp.width  -= 4;
					temp.height -= 4;
					LcdDrawBox(&temp,color_level[COLOR_GREY1_COLOR],color_level[COLOR_GREY1_COLOR],DRAW_FILL);
					
					draw_color = ColorInvert(draw_color);
					
					if (draw_color == color_level[COLOR_BLACK_COLOR])
						bg_color = color_level[COLOR_GREY1_COLOR];
					else
					{
						bg_color = color_level[COLOR_GREY2_COLOR];
						
						if (addr->control_subtype != PUSHBUTTON_STYLE_0)
						{
							text.xcoord += 1;
							text.ycoord += 1;
						}
					}
					ControlDrawString(addr,&text,draw_color,addr->control_text,bg_color);
					
					LcdDrawLine(bounds.xcoord+1,bounds.ycoord+1,
						bounds.xcoord+bounds.width-2,bounds.ycoord+1,
						SINGLE_LINE,NON_DOTTED_LINE,color_level[COLOR_WHITE_COLOR],color_level[COLOR_WHITE_COLOR]);
					if (color_mode == GREYSCALE_MODE)
						LcdDrawLine(bounds.xcoord+1,bounds.ycoord+bounds.height-2,
						bounds.xcoord+bounds.width-2,bounds.ycoord+bounds.height-2,
						SINGLE_LINE,NON_DOTTED_LINE,color_level[COLOR_GREY2_COLOR],color_level[COLOR_GREY2_COLOR]);
					else											
						LcdDrawLine(bounds.xcoord+1,bounds.ycoord+bounds.height-2,
						bounds.xcoord+bounds.width-2,bounds.ycoord+bounds.height-2,
						SINGLE_LINE,NON_DOTTED_LINE,color_level[COLOR_WHITE_COLOR],color_level[COLOR_WHITE_COLOR]);							
					LcdDrawLine(bounds.xcoord+1,bounds.ycoord+2,
						bounds.xcoord+1,bounds.ycoord+bounds.height-3,
						SINGLE_LINE,NON_DOTTED_LINE,color_level[COLOR_WHITE_COLOR],color_level[COLOR_WHITE_COLOR]);
					if (color_mode == GREYSCALE_MODE)
						LcdDrawLine(bounds.xcoord+bounds.width-2,bounds.ycoord+2,
						bounds.xcoord+bounds.width-2,bounds.ycoord+bounds.height-3,
						SINGLE_LINE,NON_DOTTED_LINE,color_level[COLOR_GREY2_COLOR],color_level[COLOR_GREY2_COLOR]);
					else			
						LcdDrawLine(bounds.xcoord+bounds.width-2,bounds.ycoord+2,
						bounds.xcoord+bounds.width-2,bounds.ycoord+bounds.height-3,
						SINGLE_LINE,NON_DOTTED_LINE,color_level[COLOR_WHITE_COLOR],color_level[COLOR_WHITE_COLOR]);															
				}
				else
				{
					temp.xcoord += 2;
					temp.ycoord += 2;
					temp.width  -= 4;
					temp.height -= 4;
					LcdDrawBox(&temp,color_level[COLOR_GREY2_COLOR],color_level[COLOR_GREY2_COLOR],DRAW_FILL);
					
					draw_color = ColorInvert(draw_color);
					
					if (draw_color == color_level[COLOR_BLACK_COLOR])
						bg_color = color_level[COLOR_GREY1_COLOR];
					else
					{
						bg_color = color_level[COLOR_GREY2_COLOR];
						
						if (addr->control_subtype != PUSHBUTTON_STYLE_0)
						{
							if (color_mode == GREYSCALE_MODE)
							{
								text.xcoord += 1;
								text.ycoord += 1;
							}
						}
					}
					ControlDrawString(addr,&text,draw_color,addr->control_text,bg_color);
					
					LcdDrawLine(bounds.xcoord+1,bounds.ycoord+1,
						bounds.xcoord+bounds.width-2,bounds.ycoord+1,
						SINGLE_LINE,NON_DOTTED_LINE,color_level[COLOR_BLACK_COLOR],color_level[COLOR_BLACK_COLOR]);
					if (color_mode == GREYSCALE_MODE)
						LcdDrawLine(bounds.xcoord+1,bounds.ycoord+bounds.height-2,
						bounds.xcoord+bounds.width-2,bounds.ycoord+bounds.height-2,
						SINGLE_LINE,NON_DOTTED_LINE,color_level[COLOR_GREY1_COLOR],color_level[COLOR_GREY1_COLOR]);
					else
						LcdDrawLine(bounds.xcoord+1,bounds.ycoord+bounds.height-2,
						bounds.xcoord+bounds.width-2,bounds.ycoord+bounds.height-2,
						SINGLE_LINE,NON_DOTTED_LINE,color_level[COLOR_BLACK_COLOR],color_level[COLOR_BLACK_COLOR]);
					LcdDrawLine(bounds.xcoord+1,bounds.ycoord+2,
						bounds.xcoord+1,bounds.ycoord+bounds.height-3,
						SINGLE_LINE,NON_DOTTED_LINE,color_level[COLOR_BLACK_COLOR],color_level[COLOR_BLACK_COLOR]);
					if (color_mode == GREYSCALE_MODE)
						LcdDrawLine(bounds.xcoord+bounds.width-2,bounds.ycoord+2,
						bounds.xcoord+bounds.width-2,bounds.ycoord+bounds.height-3,
						SINGLE_LINE,NON_DOTTED_LINE,color_level[COLOR_GREY1_COLOR],color_level[COLOR_GREY1_COLOR]);
					else
						LcdDrawLine(bounds.xcoord+bounds.width-2,bounds.ycoord+2,
						bounds.xcoord+bounds.width-2,bounds.ycoord+bounds.height-3,
						SINGLE_LINE,NON_DOTTED_LINE,color_level[COLOR_BLACK_COLOR],color_level[COLOR_BLACK_COLOR]);
				}
			}
			/* Check if is round-corned box */
			else if (addr->control_subtype == PUSHBUTTON_STYLE_2)
			{
				if (draw_color == CLICK_ON) /* Draw fill box */
				{
					ControlDrawArc(&bounds,DRAW_FILL,draw_radius,draw_color);
					ControlDrawEmptyButton(&bounds,draw_radius,draw_color);						
				}
				else /* Draw empty box */
				{
					ControlDrawEmptyButton(&bounds,draw_radius,draw_color);
					ControlDrawArc(&bounds,DRAW_NOT_FILL,draw_radius,draw_color);
				}
			}
			
			if (addr->control_subtype == PUSHBUTTON_STYLE_0 || addr->control_subtype == PUSHBUTTON_STYLE_2)
			{
				draw_color = ColorInvert(draw_color);
				
				if (draw_color == color_level[COLOR_BLACK_COLOR])
					
					bg_color = color_level[COLOR_GREY1_COLOR];
				else
				{
					bg_color = color_level[COLOR_GREY2_COLOR];
					
					/*if (addr->control_subtype != PUSHBUTTON_STYLE_0)
					{
					text.xcoord += 1;
					text.ycoord += 1;
					}
					*/
				}
				ControlDrawString(addr,&text,draw_color,addr->control_text,bg_color);
			}
				}
				/* Draw Tap Push button */
				else if ( addr->control_subtype == PUSHBUTTON_STYLE_3)
					ControlDrawTapButton(addr,&bounds,draw_radius,draw_color);
				
				break;
				
				/* Repeat Button */
		case REPEAT_BUTTON: 
			bitmap_struct = ((ControlTemplateRepeatButton *) addr->control_template)->repeat_bitmap;
			if (addr->identification.table_related != 0xFFFF)
			{
				bitmap_struct.xcoord = addr->screen_bounds.xcoord;
				bitmap_struct.ycoord = addr->screen_bounds.ycoord;
			}
			if (addr->control_attr.control_enter == CLICK_ON)
				LcdDrawBitmap(&bitmap_struct,INVERT);
			else
				LcdDrawBitmap(&bitmap_struct,NOT_INVERT);
			break;
			
			/* Check Box */
		case CHECKBOX:	
			get_value = (BYTE)(((ControlTemplateCheckBox *) addr->control_template)->control_value);
			enter_value = (BYTE)(addr->control_attr.control_enter);
			if (enter_value == CLICK_ON)
			{
				bitmap_struct = ((ControlTemplateCheckBox *) addr->control_template)->checkbox_bitmap1;
				/* If related to table */
				if (addr->identification.table_related != 0xFFFF)
				{
					bitmap_struct.xcoord = addr->screen_bounds.xcoord;
					bitmap_struct.ycoord = addr->screen_bounds.ycoord;
				}
				LcdDrawBitmap(&bitmap_struct,NOT_INVERT);
			}
			else
			{
				if (get_value == CLICK_ON)
				{
					bitmap_struct = ((ControlTemplateCheckBox *) addr->control_template)->checkbox_bitmap1;
					/* If related to table */
					if (addr->identification.table_related != 0xFFFF)
					{
						bitmap_struct.xcoord = addr->screen_bounds.xcoord;
						bitmap_struct.ycoord = addr->screen_bounds.ycoord;
					}
					LcdDrawBitmap(&bitmap_struct,NOT_INVERT);
				}
				else
				{
					bitmap_struct = ((ControlTemplateCheckBox *) addr->control_template)->checkbox_bitmap2;
					/* If related to table */
					if (addr->identification.table_related != 0xFFFF)
					{
						bitmap_struct.xcoord = addr->screen_bounds.xcoord;
						bitmap_struct.ycoord = addr->screen_bounds.ycoord;
					}
					LcdDrawBitmap(&bitmap_struct,NOT_INVERT);
				}
			}
			break;
			/* Popup Trigger */
		case POPUP_TRIGGER: 
			get_value = (BYTE)(((ControlTemplatePopupTrigger *) addr->control_template)->control_value);
			enter_value = (BYTE)(addr->control_attr.control_enter);
			/* Check for the enter state */
			if (enter_value == CLICK_ON)
				draw_color = color_level[COLOR_BLACK_COLOR]; /* Color ON */
			else
				draw_color = color_level[COLOR_WHITE_COLOR]; /* Color OFF */
			
			draw_radius = BUTTON_FIXED_CORNER;
			
			get_value = (BYTE)(((ControlTemplatePopupTrigger *) addr->control_template)->control_value);
			/* Case ON */
			if (get_value == CLICK_ON)
			{
				if (addr->control_subtype == POPUP_TRIGGER_STYLE_1)
					popup_indicator_width = POPUP_INDICATOR_WIDTH;
				else 
					popup_indicator_width = 0;
				
				previous_bounds = ((ControlTemplatePopupTrigger *) addr->control_template)->popuped;
				ControlSavePopupBounds(addr->identification.ui_object_id);
				popup_bounds = ((ControlTemplatePopupTrigger *) addr->control_template)->popuped;
				if (previous_bounds.ycoord != popup_bounds.ycoord)
				{
					((ControlTemplatePopupTrigger *) addr->control_template)->popuped = previous_bounds;
					ControlRestoreBitBehind(addr->identification.ui_object_id);
					((ControlTemplatePopupTrigger *) addr->control_template)->popuped = popup_bounds;
					ControlSaveBehindBits(addr->identification.ui_object_id);
				}
				popup_current_num_item = ((ControlTemplatePopupTrigger *) addr->control_template)->popup_current_num_item_display;
				popup_top_item_num = ((ControlTemplatePopupTrigger *) addr->control_template)->popup_top_item_num;
				popup_highlighted_item = ((ControlTemplatePopupTrigger *) addr->control_template)->popup_highlighted_item;
				/* Set up the temp bounds  */
				text.xcoord = popup_bounds.xcoord+POPUP_LEFT_BORDER;
				text.ycoord = popup_bounds.ycoord+POPUP_LEFT_BORDER;
				
				ControlDrawEmptyButton(&popup_bounds,BUTTON_FIXED_CORNER,color_level[COLOR_WHITE_COLOR]);
				ControlDrawArc(&popup_bounds,DRAW_NOT_FILL,BUTTON_FIXED_CORNER,color_level[COLOR_WHITE_COLOR]);
				
				count = 0;
				while (count < popup_current_num_item)
				{
					/* Set up the string position */
					if (count ==0)
						text.ycoord = text.ycoord;
					else
						text.ycoord = text.ycoord+FONT_HEIGHT[0]+2;
					
					draw_width = strlen(((ControlTemplatePopupTrigger *) addr->control_template)->popup_items_list[popup_top_item_num]);
					draw_text = (BYTE*)qmalloc((draw_width + 1)*sizeof(BYTE));
					strcpy(draw_text,((ControlTemplatePopupTrigger *) addr->control_template)->popup_items_list[popup_top_item_num++]);
					text.width  = popup_bounds.width - POPUP_LEFT_BORDER*2 - (popup_indicator_width+1);
					text.height = FONT_HEIGHT[0];
					
					if (popup_highlighted_item == popup_top_item_num-1)
					{
						highlight.xcoord = popup_bounds.xcoord+POPUP_HIGHLIGHT_BORDER;
						highlight.ycoord = text.ycoord;
						highlight.width  = popup_bounds.width - POPUP_HIGHLIGHT_BORDER*2 - (popup_indicator_width+1);
						highlight.height = FONT_HEIGHT[0]+1;
						
						LcdDrawBox(&highlight,color_level[COLOR_GREY2_COLOR],color_level[COLOR_GREY2_COLOR],DRAW_FILL);
						
						LcdDrawFixedString(&text,draw_text,color_level[COLOR_WHITE_COLOR],color_level[COLOR_GREY2_COLOR],SMALL_FONT,DOTDOT,MARGIN_0);
						
						LcdDrawLine(highlight.xcoord+1,highlight.ycoord-1,highlight.xcoord+highlight.width-1,
							highlight.ycoord-1,SINGLE_LINE,NON_DOTTED_LINE,color_level[COLOR_BLACK_COLOR],color_level[COLOR_BLACK_COLOR]);								
						LcdDrawLine(highlight.xcoord+1,highlight.ycoord+highlight.height,highlight.xcoord+highlight.width-1,
							highlight.ycoord+highlight.height,SINGLE_LINE,NON_DOTTED_LINE,color_level[COLOR_WHITE_COLOR],color_level[COLOR_WHITE_COLOR]);
						LcdDrawLine(highlight.xcoord,highlight.ycoord-1,highlight.xcoord,highlight.ycoord+highlight.height-1,
							SINGLE_LINE,NON_DOTTED_LINE,color_level[COLOR_BLACK_COLOR],color_level[COLOR_BLACK_COLOR]);
						LcdDrawLine(highlight.xcoord+highlight.width-1,highlight.ycoord-1,highlight.xcoord+highlight.width-1,
							highlight.ycoord+highlight.height-1,SINGLE_LINE,NON_DOTTED_LINE,color_level[COLOR_WHITE_COLOR],color_level[COLOR_WHITE_COLOR]);                                                          
					}
					else
						LcdDrawFixedString(&text,draw_text,color_level[COLOR_BLACK_COLOR],color_level[COLOR_GREY1_COLOR],SMALL_FONT,DOTDOT,MARGIN_0);
					
					qfree(draw_text);
					count ++;
				}
				ControlSetPopupTriggerUpDownArrow(addr,&popup_bounds);
			}
			else
			{
				if( addr->control_subtype == POPUP_TRIGGER_STYLE_0)
				{
					if (enter_value == CLICK_ON)
					{
						LcdDrawBox(&bounds,color_level[COLOR_BLACK_COLOR],color_level[COLOR_BLACK_COLOR],FILL_SOLID);
						ControlDrawString(addr,&bounds,color_level[COLOR_WHITE_COLOR],addr->control_text,color_level[COLOR_BLACK_COLOR]);
					}
					else
					{
						LcdEraseRegion(&bounds);							
						ControlDrawString(addr,&bounds,color_level[COLOR_BLACK_COLOR],addr->control_text,color_level[COLOR_WHITE_COLOR]);
					}
				}
				else if (addr->control_subtype == POPUP_TRIGGER_STYLE_1 || addr->control_subtype == POPUP_TRIGGER_STYLE_2)
				{
					popup_bitmap.xcoord = bounds.xcoord+(bounds.width-1)-draw_radius-POPUP_INDICATOR_WIDTH;
					popup_bitmap.ycoord = bounds.ycoord+(SHORT)(bounds.height-FONT_HEIGHT[0])/2 + 2;
					popup_bitmap.width  = POPUP_INDICATOR_WIDTH;
					popup_bitmap.height = POPUP_INDICATOR_HEIGHT;
					popup_bitmap.compressed = FALSE;
					popup_bitmap.quantisation = Q_FOUR_BIT;
					popup_bitmap.size = FALSE;
					popup_bitmap.bitmap_data = popup_lower_triangle;
					
					text = bounds;						
					text.width = text.width - POPUP_LEFT_BORDER*2;
					
					if (enter_value == CLICK_ON)
					{
						ControlDrawEmptyButton(&bounds,BUTTON_FIXED_CORNER,color_level[COLOR_BLACK_COLOR]);
						ControlDrawArc(&bounds,DRAW_FILL,BUTTON_FIXED_CORNER,color_level[COLOR_BLACK_COLOR]);
						
						text.xcoord += 1;
						text.ycoord += 1;
						ControlDrawString(addr,&text,color_level[COLOR_WHITE_COLOR],addr->control_text,color_level[COLOR_GREY2_COLOR]);
						LcdDrawBitmap(&popup_bitmap,INVERT);
					}
					else
					{
						ControlDrawEmptyButton(&bounds,BUTTON_FIXED_CORNER,color_level[COLOR_WHITE_COLOR]);
						ControlDrawArc(&bounds,DRAW_NOT_FILL,BUTTON_FIXED_CORNER,color_level[COLOR_WHITE_COLOR]);
						ControlDrawString(addr,&text,color_level[COLOR_BLACK_COLOR],addr->control_text,color_level[COLOR_GREY1_COLOR]);
						LcdDrawBitmap(&popup_bitmap,NOT_INVERT);
					}
				}
				else if (addr->control_subtype == POPUP_TRIGGER_STYLE_3)
				{
					popup_bitmap.xcoord = bounds.xcoord+(bounds.width-1)-draw_radius-POPUP_INDICATOR_WIDTH;
					popup_bitmap.ycoord = bounds.ycoord+(SHORT)(bounds.height-FONT_HEIGHT[0])/2 + 2;
					popup_bitmap.width  = POPUP_INDICATOR_WIDTH;
					popup_bitmap.height = POPUP_INDICATOR_HEIGHT;
					popup_bitmap.compressed = FALSE;
					popup_bitmap.quantisation = Q_FOUR_BIT;
					popup_bitmap.size = FALSE;
					popup_bitmap.bitmap_data = popup_lower_triangle;
					
					text = bounds;						
					text.width = text.width - POPUP_LEFT_BORDER*2;
					
					if (enter_value == CLICK_ON)
					{
						LcdDrawBox(&bounds,color_level[COLOR_BLACK_COLOR],color_level[COLOR_BLACK_COLOR],FILL_SOLID);
						//             text.xcoord += 1;
						//           text.ycoord += 1;
						ControlDrawString(addr,&text,color_level[COLOR_WHITE_COLOR],addr->control_text,color_level[COLOR_BLACK_COLOR]);
						LcdDrawBitmap(&popup_bitmap,INVERT);
					}
					else
					{
						LcdEraseRegion(&bounds);							
						ControlDrawString(addr,&text,color_level[COLOR_BLACK_COLOR],addr->control_text,color_level[COLOR_WHITE_COLOR]);
						LcdDrawBitmap(&popup_bitmap,NOT_INVERT);
					}
				}
			}
			break;
	}
	addr->control_attr.control_drawn = TRUE;
	return TRUE;
}
/********************************************************
* Function:	ControlGetAttr
* Purpose:		to get all the attributes of a control object
* Scope:		Application
* Input:		control_id		DBID of control object
* Output:		enable_attr		Pointer to Boolean varaible to
show whether the cotnrol object is
enabled or not
drawn_attr		Pointer to Boolean variable to show
whether the cotnrol object is drawn
or not
savebehind_attr Pointer to Boolean variable to show
whether there is a save covered image
behind the control object
active_attr		Pointer to Boolean variable to show
whether the control object is active or not
currently
visible_attr	Pointer to Boolean variable to show whether 
the object should be drawn on the screen or not
* Return:		TRUE if no error
ERR_UI_RES_NOT_FOUND
* Comment:     None
*********************************************************/
Err ControlGetAttributes(ObjectID control_id, BOOLEAN *enable_attr,
						 BOOLEAN *drawn_attr,BOOLEAN *savebehind_attr,
						 BOOLEAN *active_attr, BOOLEAN *visible_attr)
{
	Control *control_addr;
	BYTE object_type;
	
	/* to find out the address of the specific control structure */
	/* if it can't find out the corresponding control object, then
	ErrResNotFound is returned */
	if (UISearchForAddress(control_id,&object_type,(void**)&control_addr) != TRUE) return ERR_UI_RES_NOT_FOUND;
	*enable_attr = (control_addr->control_attr).control_enable;
	*drawn_attr = (control_addr->control_attr).control_drawn;
	*savebehind_attr = (control_addr->control_attr).control_save_behind;
	*active_attr = (control_addr->control_attr).control_active;
	*visible_attr = (control_addr->control_attr).control_visible;
	return TRUE;
}
/********************************************************
* Function:	ControlGetLabel
* Purpose:		to get the char string pointer of the control object
* Scope:		Application
* Input:		control_id		DBID of control object
* Output:		control_label	Pointer to char string that represents
the label of the control object
* Return:		TRUE if no error
ERR_UI_RES_NOT_FOUND
* Comment:     None
*********************************************************/
Err ControlGetLabel(ObjectID control_id, BYTE **control_label)
{
	Control *control_addr;
	BYTE object_type;
	if (UISearchForAddress(control_id,&object_type,(void**)&control_addr) != TRUE) return ERR_UI_RES_NOT_FOUND;
	*control_label = control_addr->control_text;
	return TRUE;
}
/********************************************************
* Function:	ControlRestoreBitBehind
* Purpose:		to re-drawn the covered and saved image that is
behind the specific object
* Scope:		Application
* Input:		control_id	DBID of control object
* Output:		None
* Return:		TRUE if no error
ERR_UI_RES_NOT_FOUND
ErrUINoBitmapForRestore
* Comment:     None
*********************************************************/
Err ControlRestoreBitBehind(ObjectID control_id)
{
	Control 						*control_addr;
	BYTE 							object_type;
	ControlTemplatePopupTrigger		*popup_template;
	
	if (UISearchForAddress(control_id,&object_type,(void**)&control_addr) != TRUE) return ERR_UI_RES_NOT_FOUND;
	/* to check whether save_behind is TRUE */
	if (control_addr->control_attr.control_save_behind != TRUE) return ERR_UI_NO_BITMAP_FOR_RESTORE;
	/* cos only popup trigger has chance to save behind,
	so it is required to check whether the DBID of the object is belongs to
	a control with stlye = 3 */
	if (control_addr->control_style == 4)
	{
		popup_template = (ControlTemplatePopupTrigger *)(control_addr->control_template); 	
		
		/* call LcdDrawBitmap function to draw the covered image */
		LcdDrawBitmap(&(popup_template->save_behind),0);
		qfree((popup_template->save_behind).bitmap_data);
		(popup_template->save_behind).bitmap_data = NULL;
		control_addr->control_attr.control_save_behind = FALSE;	
		return TRUE;
	}
	return ERR_UI_NO_BITMAP_FOR_RESTORE;
}
/********************************************************
* Function:	ControlSetLabel
* Purpose:		to set the control object label of the specified
control object
* Scope:		Application
* Input:		control_id		DBID of control object
control_label	the label of control object
* Output:		None
* Return:		Error code
* Comment:     None
*********************************************************/
Err ControlSetLabel(ObjectID control_id,BYTE *control_label)
{
	Control *control_addr;
	BYTE object_type;
	USHORT length;
	
	if (UISearchForAddress(control_id,&object_type,(void**)&control_addr) != TRUE) return ERR_UI_RES_NOT_FOUND;
	qfree(control_addr->control_text);
	length = strlen(control_label); /*check the length of the passed-in label */
	control_addr->control_text = (BYTE *)qmalloc((length+1) * sizeof(BYTE));
	strcpy(control_addr->control_text,control_label);
	return TRUE;
}
/********************************************************
* Function:	ControlDeleteControl
* Purpose:		to delete the specific control object
* Scope:		Application
* Input:		control_id	DBID of control object
* Output:		None
* Return:		TRUE if no error
ERR_UI_RES_NOT_FOUND
* Comment:     None
*********************************************************/
Err ControlDeleteControl(ObjectID control_id)
{
	Control *control_addr;
	BYTE object_type;
	Err Error;
	WORD i = 0;
	
	
	if (UISearchForAddress(control_id,&object_type,(void**)&control_addr) != TRUE) return ERR_UI_RES_NOT_FOUND;
	if (control_addr->control_style == POPUP_TRIGGER)
	{
		if (((ControlTemplatePopupTrigger*)(control_addr->control_template))->save_behind.bitmap_data != NULL)
			qfree(((ControlTemplatePopupTrigger*)(control_addr->control_template))->save_behind.bitmap_data);
		i = ((ControlTemplatePopupTrigger*)(control_addr->control_template))->popup_num_objects;
		while (i)
		{
			i--;
			qfree(((ControlTemplatePopupTrigger*)(control_addr->control_template))->popup_items_list[i]);
		}
		qfree(((ControlTemplatePopupTrigger*)(control_addr->control_template))->popup_items_list);
	}
	qfree(control_addr->control_text);
	qfree(control_addr->control_template);
	Error = UIDeleteLookupTableElement(control_id); /* delete the corresponding element in the lookup table */
	if (Error !=TRUE) return Error;
	qfree(control_addr);
	return TRUE;
}
/********************************************************
* Function:	ControlPopupSetTotalItems
* Purpose:		to set the total number of items in the popup list
* Scope:		Application
* Input:		control_id		DBID of control object
total_num_items	the total number of items in the
popup list
* Output:		None
* Return:		TRUE if no error
ERR_UI_RES_NOT_FOUND
ErrUIObjectNotMatch
* Comment:     None
*********************************************************/
Err ControlPopupSetTotalItems (ObjectID control_id,USHORT total_num_items)
{
	Control *control_addr;
	BYTE object_type;
	
	if (UISearchForAddress(control_id,&object_type,(void**)&control_addr) != TRUE) return ERR_UI_RES_NOT_FOUND;
	if (control_addr->control_style == 4)
	{
		((ControlTemplatePopupTrigger*)(control_addr->control_template))->popup_num_objects = total_num_items;
		return TRUE;
	}
	return ERR_UI_OBJECT_NOT_MATCH;
}
/********************************************************
* Function:	ControlPopupSetSelectedItem
* Purpose:		to set the the selected item in the popup trigger object
* Scope:		Application
* Input:		list_id		    DBID of popup trigger object
item_num	    the item number of the selected item
* Output:      None
* Return:		True if no error
ERR_UI_RES_NOT_FOUND
* Comment:     None
*********************************************************/
Err ControlPopupSetSelectedItem(ObjectID control_id,SHORT item_num)
{
	Control *addr;
	BYTE object_type;
	BYTE *item_text;
	
	if (UISearchForAddress(control_id,&object_type,(void**)&addr) != TRUE) return ERR_UI_RES_NOT_FOUND;
    if (item_num <= (((ControlTemplatePopupTrigger*)(addr->control_template))->popup_num_objects - 1))
    {
		((ControlTemplatePopupTrigger*)(addr->control_template))->popup_selected_item = item_num;
		ControlPopupGetPopupItem(control_id, item_num, &item_text);
		qfree(addr->control_text);
		addr->control_text = (BYTE*)qmalloc((strlen(item_text) + 1)*sizeof(BYTE));
		strcpy(addr->control_text,item_text);
		return TRUE;
    }
    return ERR_UI_ITEM_NUMBER_EXCEED;
}

/********************************************************
* Function:	ControlPopupGetSelectedItem
* Purpose:		to set the the selected item in the popup trigger object
* Scope:		Application
* Input:		list_id		    DBID of popup trigger object
* Output:      item_num	    pointer to the item number of the selected item
* Return:		True if no error
ERR_UI_RES_NOT_FOUND
* Comment:     None
*********************************************************/
Err ControlPopupGetSelectedItem(ObjectID control_id,SHORT *item_num)
{
	Control *addr;
	BYTE object_type;
	
	if (UISearchForAddress(control_id,&object_type,(void**)&addr) != TRUE) return ERR_UI_RES_NOT_FOUND;
    *item_num = ((ControlTemplatePopupTrigger*)(addr->control_template))->popup_selected_item;
	return TRUE;
}


/********************************************************
* Function:	ControlPopupGetTotalItems
* Purpose:		to get the the total number of items in the popup list
* Scope:		Application
* Input:		control_id		DBID of control object
* Output:		total_num_items	the total number of items in the
popup list
* Return:		True if no error
ERR_UI_RES_NOT_FOUND
ErrUIObjectNotMatch
* Comment:     None
*********************************************************/
Err ControlPopupGetTotalItems (ObjectID control_id,USHORT *total_num_items)
{
	Control *control_addr;
	BYTE object_type;
	
	if (UISearchForAddress(control_id,&object_type,(void**)&control_addr) != TRUE) return ERR_UI_RES_NOT_FOUND;
	if (control_addr->control_style == 4)
	{
		*total_num_items = ((ControlTemplatePopupTrigger*)(control_addr->control_template))->popup_num_objects;
		return TRUE;
	}
	return ERR_UI_OBJECT_NOT_MATCH;
}
/********************************************************
* Function:	ControlPopupGetCurrentNumOfDisplayedItems
* Purpose:		to get the number of items that are currently displayed
* Scope:		Application
* Input:		control_id		    DBID of control object
* Output:	    num_items_display	the number fo items that are displaying
* Return:		True if no error
ERR_UI_RES_NOT_FOUND
ErrUIObjectNotMatch
* Comment:     None
*********************************************************/
Err ControlPopupGetCurrentNumOfDisplayedItems (ObjectID control_id,USHORT *items_displayed)
{
	Control *control_addr;
	BYTE object_type;
	
	if (UISearchForAddress(control_id,&object_type,(void**)&control_addr) != TRUE) return ERR_UI_RES_NOT_FOUND;
	if (control_addr->control_style == 4)
	{
		*items_displayed = ((ControlTemplatePopupTrigger*)(control_addr->control_template))->popup_current_num_item_display;
		return TRUE;
	}
	return ERR_UI_OBJECT_NOT_MATCH;
}

/********************************************************
* Function:	ControlPopupDeleteItem
* Purpose:		to delete an item in the popup list and all the items
will be re-arranged
* Scope:		Application
* Input:		control_id	DBID of control object
item_number	the item number that u want to add
item to
* Output:		None
* Return:		TRUE if no error
ERR_UI_RES_NOT_FOUND
ErrObjectNotMatch
* Comment:     None
*********************************************************/
Err ControlPopupDeleteItem(ObjectID control_id,USHORT item_number)
{
	Control *control_addr;
	BYTE object_type;
	USHORT total_number;
	WORD i;
	BYTE **new_popup;
	
	if (UISearchForAddress(control_id,&object_type,(void**)&control_addr) != TRUE) return ERR_UI_RES_NOT_FOUND;
	if (control_addr->control_style == 4)
	{
		if (item_number < ((ControlTemplatePopupTrigger*)(control_addr->control_template))->popup_selected_item)
			((ControlTemplatePopupTrigger*)(control_addr->control_template))->popup_selected_item--;
		if (item_number < ((ControlTemplatePopupTrigger*)(control_addr->control_template))->popup_highlighted_item)
			((ControlTemplatePopupTrigger*)(control_addr->control_template))->popup_highlighted_item++;
		if (item_number == ((ControlTemplatePopupTrigger*)(control_addr->control_template))->popup_selected_item)
		{
			((ControlTemplatePopupTrigger*)(control_addr->control_template))->popup_selected_item = -1;
			((ControlTemplatePopupTrigger*)(control_addr->control_template))->popup_highlighted_item = -1;
		}
		if ((item_number) >= ((ControlTemplatePopupTrigger*)(control_addr->control_template))->popup_num_objects) return ERR_UI_ITEM_NUMBER_EXCEED;
		total_number = ((ControlTemplatePopupTrigger*)(control_addr->control_template))->popup_num_objects;
		qfree(((ControlTemplatePopupTrigger*)(control_addr->control_template))->popup_items_list[item_number]);
		/* the corresponding item in the popup list is deleted and all the other items are re-arrnaged */
		new_popup = (BYTE**)qmalloc((total_number - 1)*sizeof(BYTE*));
		
		i = item_number;
		while (i)
		{
			i--;
			new_popup[i] = ((ControlTemplatePopupTrigger*)(control_addr->control_template))->popup_items_list[i];
			qfree(((ControlTemplatePopupTrigger*)(control_addr->control_template))->popup_items_list[i]);
		}
		i = item_number;
		while (i <(total_number - 1))
		{
			new_popup[i] = ((ControlTemplatePopupTrigger*)(control_addr->control_template))->popup_items_list[i+1];
			i++;
		}
		
		qfree(((ControlTemplatePopupTrigger*)(control_addr->control_template))->popup_items_list);
		((ControlTemplatePopupTrigger*)(control_addr->control_template))->popup_items_list = new_popup;
		((ControlTemplatePopupTrigger*)(control_addr->control_template))->popup_num_objects = total_number - 1;
		return TRUE;
	}
	return ERR_UI_OBJECT_NOT_MATCH;
}

/********************************************************
* Function:	ControlPopupDeleteAllItems
* Purpose:		to delete all items in a popup trigger
* Scope:		Application
* Input:		control_id	    DBID of control object
* Output:		None
* Return:		TRUE if no error
ERR_UI_RES_NOT_FOUND
ERR_UI_OBJECT_NOT_MATCH
* Comment:     None
*********************************************************/
Err ControlPopupDeleteAllItems(ObjectID control_id)
{
	Control *addr;
	BYTE object_type;
	WORD i;
	
	if (UISearchForAddress(control_id,&object_type,(void**)&addr) != TRUE) return ERR_UI_RES_NOT_FOUND;
	if (addr->control_style != 4) return ERR_UI_OBJECT_NOT_MATCH;
	
	i = ((ControlTemplatePopupTrigger*)(addr->control_template))->popup_num_objects;
	while (i)
	{
		i--;
		qfree(((ControlTemplatePopupTrigger*)(addr->control_template))->popup_items_list[i]);
	}
	qfree(((ControlTemplatePopupTrigger*)(addr->control_template))->popup_items_list);
	((ControlTemplatePopupTrigger*)(addr->control_template))->popup_num_objects = 0;
	((ControlTemplatePopupTrigger*)(addr->control_template))->popup_items_list = NULL;
	return TRUE;
}
/********************************************************
* Function:	ControlPopupInsertItem
* Purpose:		to insert a new item in the popup list and the whole
list will be re-arranged again
* Scope:		Application
* Input:		control_id	DBID of control object
item_number	the item number that u want to add
item to
item_text	Pointer to the char array of item text
* Output:		None
* Return:		TRUE if no error
ErrUIObjectNotMatch
ERR_UI_RES_NOT_FOUND
* Comment:     None
*********************************************************/
Err ControlPopupInsertItem(ObjectID control_id,USHORT item_number,BYTE *item_text)
{
	Control *control_addr;
	BYTE object_type;
	USHORT total_number;
	WORD i;
	
	BYTE **new_popup;
	
	if (UISearchForAddress(control_id,&object_type,(void**)&control_addr) != TRUE) return ERR_UI_RES_NOT_FOUND;
	if (control_addr->control_style == 4)
	{
		if (item_number <= ((ControlTemplatePopupTrigger*)(control_addr->control_template))->popup_selected_item)
			((ControlTemplatePopupTrigger*)(control_addr->control_template))->popup_selected_item++;
		if (item_number <= ((ControlTemplatePopupTrigger*)(control_addr->control_template))->popup_highlighted_item)
			((ControlTemplatePopupTrigger*)(control_addr->control_template))->popup_highlighted_item++;
		if ((item_number) > ((ControlTemplatePopupTrigger*)(control_addr->control_template))->popup_num_objects)
			item_number = ((ControlTemplatePopupTrigger*)(control_addr->control_template))->popup_num_objects;
		total_number = ((ControlTemplatePopupTrigger*)(control_addr->control_template))->popup_num_objects;
		new_popup = (BYTE **)qmalloc((total_number+1)*sizeof(BYTE *));
		i = 0;
		while (i <total_number)
		{
			if (i < item_number)
			{
				new_popup[i] = ((ControlTemplatePopupTrigger*)(control_addr->control_template))->popup_items_list[i];
			}
			else if( i == item_number)
			{
				new_popup[i] = (BYTE *)qmalloc((strlen(item_text)+1)*sizeof(BYTE));
				strcpy (new_popup[i],item_text);
				new_popup[i+1] = ((ControlTemplatePopupTrigger*)(control_addr->control_template))->popup_items_list[i];
			}
			else
			{
				new_popup[i+1] = ((ControlTemplatePopupTrigger*)(control_addr->control_template))->popup_items_list[i];
			}
			i++;
		}
		if (item_number == total_number)
		{
			new_popup[item_number] = (BYTE *)qmalloc((strlen(item_text)+1)*sizeof(BYTE));
			strcpy (new_popup[item_number],item_text);
		}
		((ControlTemplatePopupTrigger*)(control_addr->control_template))->popup_num_objects = (total_number + 1);
		qfree(((ControlTemplatePopupTrigger*)(control_addr->control_template))->popup_items_list);
		((ControlTemplatePopupTrigger*)(control_addr->control_template))->popup_items_list = new_popup;
		return TRUE;
	}
	return ERR_UI_OBJECT_NOT_MATCH;
}
/********************************************************
* Function:	ControlPopupGetPopupItem
* Purpose:		to get the text of a specific popup item
* Scope:		Application
* Input:		control_id	DBID of control object
item_number	the item number that u want to add
item to
* Output:		item_text	Pointer to the char array of item text
* Return:		TRUE if no error
ERR_UI_RES_NOT_FOUND
ErrUIObjectNotMatch
* Comment:     None
*********************************************************/
Err ControlPopupGetPopupItem(ObjectID control_id,USHORT item_number,BYTE **item_text)
{
	Control *control_addr;
	BYTE object_type;
	
	if (UISearchForAddress(control_id,&object_type,(void**)&control_addr) != TRUE) return ERR_UI_RES_NOT_FOUND;
	if (control_addr->control_style == 4)
	{
		if ((item_number) >= ((ControlTemplatePopupTrigger*)(control_addr->control_template))->popup_num_objects) return ERR_UI_ITEM_NUMBER_EXCEED;
		*item_text = ((ControlTemplatePopupTrigger*)(control_addr->control_template))->popup_items_list[item_number];
		return TRUE;
	}
	return ERR_UI_OBJECT_NOT_MATCH;
}

/********************************************************
* Function:	ControlGetPushedPushButton
* Purpose:		to get the ID value of the pushbutton that is pushed down
* Scope:		Application
* Input:		form_id		The ID value of the FORM that contains the psuh button
group_id	The group id of the push button
* Output:		control_id  The ID value of the push button
* Return:		TRUE if no error
ERR_UI_RES_NOT_FOUND
ERR_UI_NO_OBJECT_FOUND
* Comment:     None
*********************************************************/
Err ControlGetPushedPushButton(ObjectID form_id, USHORT group_id, ObjectID *control_id)
{
	Control *addr;
	Form *form_ptr;
	BYTE object_type;
	WORD count;
	
	if (UISearchForAddress(form_id, &object_type,(void**)&form_ptr) != TRUE) return ERR_UI_RES_NOT_FOUND;
	count = form_ptr->form_num_objects;
	while (count)
	{
		count --;
		if (form_ptr->form_objects_list[count].object_type == CONTROL)
		{
			if (UISearchForAddress(form_ptr->form_objects_list[count].object_id, &object_type, (void**)&addr) != TRUE)
				return ERR_UI_RES_NOT_FOUND;
			if (addr->control_style == PUSH_BUTTON &&
				((ControlTemplatePushButton*)(addr->control_template))->push_button_group_id == group_id &&
				((ControlTemplatePushButton*)(addr->control_template))->control_value == TRUE)
			{
				*control_id = form_ptr->form_objects_list[count].object_id;
				return TRUE;
			}
		}				
	}
	return ERR_UI_NO_OBJECT_FOUND;
}

/********************************************************
* Function:	ControlGetCheckedCheckbox
* Purpose:		to get the ID value of the checkbox that is checked
* Scope:		Application
* Input:		form_id		The ID value of the FORM that contains the check box
group_id	The group id of the check box
* Output:		control_id  The ID value of the check box
* Return:		TRUE if no error
ERR_UI_RES_NOT_FOUND
ERR_UI_NO_OBJECT_FOUND
* Comment:     None
*********************************************************/
Err ControlGetCheckedCheckbox(ObjectID form_id, USHORT group_id, ObjectID *control_id)
{
	Control *addr;
	Form *form_ptr;
	BYTE object_type;
	WORD count;
	
	if (UISearchForAddress(form_id, &object_type,(void**)&form_ptr) != TRUE) return ERR_UI_RES_NOT_FOUND;
	count = form_ptr->form_num_objects;
	while (count)
	{
		count--;
		if (form_ptr->form_objects_list[count].object_type == CONTROL)
		{
			if (UISearchForAddress(form_ptr->form_objects_list[count].object_id, &object_type, (void**)&addr) != TRUE)
				return ERR_UI_RES_NOT_FOUND;
			if (addr->control_style == CHECKBOX &&
				((ControlTemplateCheckBox*)(addr->control_template))->checkbox_group_id == group_id &&
				((ControlTemplateCheckBox*)(addr->control_template))->control_value == TRUE)
			{
				*control_id = form_ptr->form_objects_list[count].object_id;
				return TRUE;
			}
		}				
	}
	return ERR_UI_NO_OBJECT_FOUND;
}

/********************************************************
* Function:	ControlPopupFindItemNum
* Purpose:		This function is used to call find out the item number
of the item in a popup trigger by providing the text of the item
* Scope:		Application
* Input:		control_id	DBID of control object
text		Pointer to the char array of text
* Output:		item_num	the item number of the item
* Return:		TRUE	Success
ERR_UI_RES_NOT_FOUND
FALSE   not found
ERR_UI_OBJECT_NOT_MATCH
* Comment:     None
*********************************************************/
Err ControlPopupFindItemNum(ObjectID control_id, BYTE *text,USHORT *item_num)
{
	Control *addr;
	BYTE object_type;
	WORD i = 0;
	USHORT total_num_items;
	BYTE *item_text;
	
	
	if (UISearchForAddress(control_id,&object_type,(void**)&addr) != TRUE) return ERR_UI_RES_NOT_FOUND;
	if (addr->control_style != 4) return ERR_UI_OBJECT_NOT_MATCH;
	ControlPopupGetTotalItems (control_id, &total_num_items);
	i = total_num_items;
	while (i)
	{		
		i--;
		ControlPopupGetPopupItem(control_id, (USHORT)i, &item_text);
		if (strcmp(text, item_text) == 0)
		{	
			*item_num = (USHORT)i;
			return TRUE;
		}
	}
	return FALSE;
}
/********************************************************
* Function:	ControlUpdatePopupTrigger
* Purpose:		to update the popup trigger control object
* Scope:		Application
* Input:		control_id	DBID of control object
new_top_num	the new top item number of the list
* Output:		None
* Return:		TRUE if no error
ERR_UI_RES_NOT_FOUND
ErrUIObjectNotMatch
* Comment:     this function will draw the control again too
*********************************************************/
Err ControlUpdatePopupTrigger(ObjectID control_id,USHORT new_top_num)
{
	Control *ctl_ptr;
	BYTE object_type;
	
	if (UISearchForAddress(control_id,&object_type,(void**)&ctl_ptr) != TRUE) return ERR_UI_RES_NOT_FOUND;
	if (ctl_ptr->control_style != 4) return ERR_UI_OBJECT_NOT_MATCH;
	((ControlTemplatePopupTrigger*)(ctl_ptr->control_template))->popup_top_item_num = new_top_num;
	return TRUE;
}
/********************************************************
* Function:	ControlPopupGetTopItemNumber
* Purpose:		to get the top item number of the list in
popup trigger object
* Scope:		Application
* Input:		control_id	DBID of control object
* Output:		top_num	    Pointer to the value
* Return:		TRUE if no error
ERR_UI_RES_NOT_FOUND
ErrUIObjectNotMatch
* Comment:     this function will draw the control again too
*********************************************************/
Err ControlPopupGetTopItemNumber(ObjectID control_id,USHORT *top_num)
{
	Control *ctl_ptr;
	BYTE object_type;
	
	if (UISearchForAddress(control_id,&object_type,(void**)&ctl_ptr) != TRUE) return ERR_UI_RES_NOT_FOUND;
	if (ctl_ptr->control_style != 4) return ERR_UI_OBJECT_NOT_MATCH;
	*top_num = ((ControlTemplatePopupTrigger*)(ctl_ptr->control_template))->popup_top_item_num;
	return TRUE;
}
/*********************************************************************
* Function: 	ControlHitControl
* Purpose: 		This function is used to simulate tapping a control
*		      	object
* Scope: 		Application
* Input: 		control_id 		DBID of the control object
* Output: 		None
* Return: 		TRUE if no error
*				ERR_UI_RES_NOT_FOUND
*				ErrUIObjectNotMatch
* Comment: 		Call this function if application needs to simulate
*		  		a control object is being tapped.
**********************************************************************/
Err ControlHitControl(ObjectID control_id)
{
	Control *ctl_ptr;
	BYTE object_type;
	
	if (UISearchForAddress(control_id,&object_type,(void**)&ctl_ptr) != TRUE) return ERR_UI_RES_NOT_FOUND;
	/* Append a form load event to the event quene */
	EvtAppendEvt(EVT_CONTROL_SELECT, control_id, 1, ctl_ptr->control_style, (void*)ctl_ptr);
	return TRUE;
}
/*********************************************************************
* Function: 	ControlSaveBehindBits
* Purpose: 		This function is used to set the control_save_behind
*		      	attribute and to store the image that is being covered
*			  	by the specified control object.
* Scope: 		Application
* Input: 		control_id 	DBID of the control object
* Output: 		None
* Return: 		TRUE if no error
*               ERR_UI_RES_NOT_FOUND
* Comment: 		This function should be called before the specified
*		  		control object is drawn
**********************************************************************/
Err ControlSaveBehindBits(ObjectID control_id)
{
	Control *addr;
	BYTE object_type;
	BitmapTemplate save_behind;
	
	/* Get the bounds to save */
    if (UISearchForAddress(control_id,&object_type,(void**)&addr) != TRUE) return ERR_UI_RES_NOT_FOUND;
    ControlSavePopupBounds(addr->identification.ui_object_id);
	save_behind.xcoord = ((ControlTemplatePopupTrigger*)(addr->control_template))->popuped.xcoord;
    save_behind.ycoord = ((ControlTemplatePopupTrigger*)(addr->control_template))->popuped.ycoord;
	save_behind.width  = ((ControlTemplatePopupTrigger*)(addr->control_template))->popuped.width;
	save_behind.height = ((ControlTemplatePopupTrigger*)(addr->control_template))->popuped.height;
    ((ControlTemplatePopupTrigger*)(addr->control_template))->save_behind = save_behind;
    LcdGetBitmap(&(((ControlTemplatePopupTrigger*)(addr->control_template))->save_behind));
	addr->control_attr.control_save_behind = TRUE;
    return TRUE;
}
/*********************************************************************
* Function: 	ControlEraseControl
* Purpose: 		To erase the drawn control object on the display
* Scope: 		Application
* Input: 		contol_id	DBID of the control object
* Output: 		None
* Return: 		Return True if no error or return ErrResNotFound if
*		  	  	Invalid object ID
* Comment: 		None
**********************************************************************/
Err ControlEraseControl(ObjectID control_id)
{
	Control *addr;
	BYTE object_type;
    ObjectBounds bounds;
	
	if (UISearchForAddress(control_id,&object_type,(void**)&addr) == TRUE)
	{
		if (addr->identification.table_related == 0xFFFF) bounds = addr->bounds;
		else bounds = addr->screen_bounds;
		if (addr->control_attr.control_drawn == TRUE) LcdEraseRegion(&bounds);
		addr->control_attr.control_drawn = FALSE;
		return TRUE;
	}
	return ERR_UI_RES_NOT_FOUND;
}
/*********************************************************************
* Function	: ControlSetAttribute
* Purpose	: Used to set the attribute of the control object
* Scope		: Application
* Input		: control_id - DBID of the control object
*			  att_drawn - Set the state of the control_drawn attribute
*			  att_enable - Set the state of the control_enable attribute
*		      att_active - Set the state of the schine_active attribute
*		      att_save_behind - Set the state of the control_save_behind
*								  attribute
*			  att_visible - Set the state of the control_visible attribute 	
* Output	: None
* Return	: Return True if no error or return ErrResNotFound if
*		  	  Invalid object ID
* Comment	: None
**********************************************************************/
Err ControlSetAttributes(ObjectID control_id,BOOLEAN att_enable,BOOLEAN att_drawn,
						 BOOLEAN att_save_behind,BOOLEAN att_active, BOOLEAN att_visible)
{
	Control *addr;
	BYTE object_type;
	
	if (UISearchForAddress(control_id,&object_type,(void**)&addr) == TRUE)
	{
		addr->control_attr.control_drawn = att_drawn;
		addr->control_attr.control_enable = att_enable;
		addr->control_attr.control_active = att_active;
		addr->control_attr.control_save_behind = att_save_behind;
		addr->control_attr.control_visible = att_visible;
		return TRUE;
	}
	return ERR_UI_RES_NOT_FOUND;
}
/*********************************************************************
* Function	: ControlSavePopupBounds
* Purpose	: To save the bounds of the specified popup trigger
* Scope		: Internal
* Input		: object_id     DBID of the UI object
* Output	: None
* Return	: Return True if no error
*			  ERR_UI_RES_NOT_FOUND - Invalid object ID
* Comment   : None
**********************************************************************/
Err ControlSavePopupBounds(ObjectID control_id)
{
	Control *addr;
	BYTE object_type;
	ObjectBounds popuped;
	USHORT total_objects,current_num_item,max_num_item,top_item_num,popup_indicator_width;
	SHORT draw_radius,new_width,width_sum=0, longest = 0;
	WORD count;
	
	
	if (UISearchForAddress(control_id,&object_type,(void**)&addr) != TRUE) return ERR_UI_RES_NOT_FOUND;
	if (addr->identification.table_related == 0xFFFF) popuped = addr->bounds;
	else popuped = addr->screen_bounds;
	
	((ControlTemplatePopupTrigger *) addr->control_template)->popup_arrow_up = FALSE;
	//((ControlTemplatePopupTrigger *) addr->control_template)->popup_arrow_down = FALSE;
    if (((ControlTemplatePopupTrigger *)(addr->control_template))->popup_top_item_num != 0)
        ((ControlTemplatePopupTrigger *) addr->control_template)->popup_arrow_up = TRUE;	
	
	/* Assign the value for POPUPPED Trigger */
	if (addr->control_subtype == POPUP_TRIGGER_STYLE_1)
		popup_indicator_width = POPUP_INDICATOR_WIDTH;
	else 
		popup_indicator_width = 0;
	
	total_objects = ((ControlTemplatePopupTrigger *) addr->control_template)->popup_num_objects;
	top_item_num = ((ControlTemplatePopupTrigger *) addr->control_template)->popup_top_item_num;
	draw_radius = BUTTON_FIXED_CORNER;
	
	((ControlTemplatePopupTrigger *) addr->control_template)->popup_items_list;
	
	count = total_objects;
	while (count)
	{
		count--;
		new_width = StrGetWidth(((ControlTemplatePopupTrigger *) addr->control_template)->popup_items_list[count],SMALL_FONT)-2;
		if (new_width > longest) longest = new_width;
		width_sum += new_width;
	}
	
	if (longest < 140) new_width = longest + POPUP_INDICATOR_WIDTH;
	else new_width = 140 + POPUP_INDICATOR_WIDTH;
	
	/* Assign new width of the button */
	if (new_width + BUTTON_BORDER*2 + popup_indicator_width > addr->bounds.width)
		popuped.width = new_width + BUTTON_BORDER*2 + popup_indicator_width;
	else
		popuped.width = addr->bounds.width;
	
	if (popuped.xcoord + popuped.width > LCD_WIDTH)
		popuped.xcoord = LCD_WIDTH - popuped.width;
	/* If the orginial location cannot show the whole box */
    max_num_item = ((ControlTemplatePopupTrigger *) addr->control_template)->popup_max_num_item_display;	
	if (popuped.ycoord+((FONT_HEIGHT[0]+2)*(total_objects-top_item_num)+POPUP_TOP_BORDER*2) > (LCD_HEIGHT - FORM_TOP_HEIGHT))
	{	
		/* If the alined location cannot show the whole box */
		if ((FONT_HEIGHT[0]+2)*total_objects+POPUP_TOP_BORDER*2 > (LCD_HEIGHT - FORM_TOP_HEIGHT))
		{	
			/* Alway display from the bottom */
			max_num_item = ((LCD_HEIGHT - FORM_TOP_HEIGHT)- BUTTON_BORDER*2) / (FONT_HEIGHT[0]+2);
			
			if (top_item_num == 0)
				current_num_item = max_num_item;
			else if (total_objects - (top_item_num+1) >= max_num_item)
				current_num_item = max_num_item;
			else
				current_num_item = total_objects - top_item_num;
		}
		else
			max_num_item = current_num_item = total_objects - top_item_num;
		/* Update the y-coordinate & the height of the popup trigger*/
		popuped.ycoord = LCD_HEIGHT - ((FONT_HEIGHT[0]+2)*current_num_item+POPUP_TOP_BORDER*2+4); /* Add 4 pixel offset */
	}
	else
	{
		max_num_item = current_num_item = total_objects - top_item_num;
		
		if (((ControlTemplatePopupTrigger *) addr->control_template)->popup_arrow_up == TRUE || 
			((ControlTemplatePopupTrigger *) addr->control_template)->popup_arrow_down == TRUE )
			popuped.ycoord = LCD_HEIGHT - ((FONT_HEIGHT[0]+2)*current_num_item+POPUP_TOP_BORDER*2+4);
		
	}
	popuped.height = ((FONT_HEIGHT[0]+2)*current_num_item)+POPUP_TOP_BORDER*2+2; /* Add 2 bottom offset */
	
	/* Backup the popuped coordinate */
	((ControlTemplatePopupTrigger *) addr->control_template)->popuped = popuped;
	((ControlTemplatePopupTrigger *) addr->control_template)->popup_current_num_item_display = current_num_item;
	((ControlTemplatePopupTrigger *) addr->control_template)->popup_max_num_item_display = max_num_item;
	return TRUE;
}
/*********************************************************************
* Function	: ControlSearchSelectedItem
* Purpose	: To search the selected item number from the pop-up list
* Scope		: Internal
* Input		: control_addr     Pointer to a popup trigger control object
* 			  x & y coordinate of the pen
* Output	: None
* Return	: The item number on the popup trigger list
If no HIT, then -1 is returned
* Comment   :
**********************************************************************/
SHORT ControlSearchSelectedItem(Control *control_ptr,SHORT input_xcoord,SHORT input_ycoord)
{
	USHORT check_num;
	WORD count;
	SHORT loop_height,popup_radius;
	ObjectBounds restore_popup;
	
	/* Restore the popuped value */
	restore_popup = ((ControlTemplatePopupTrigger *) control_ptr->control_template)->popuped;
	popup_radius = ((ControlTemplatePopupTrigger *) control_ptr->control_template)->popup_radius;
	
	loop_height = FONT_HEIGHT[0]+2;
	check_num = (restore_popup.height-popup_radius)/(FONT_HEIGHT[0]+2);
	restore_popup.ycoord = restore_popup.ycoord+popup_radius;
	count = 0;
	
	while (count < check_num)
	{
		if (input_xcoord >= restore_popup.xcoord &&
			input_xcoord <= restore_popup.xcoord+restore_popup.width-1 &&
			input_ycoord >= restore_popup.ycoord &&
			input_ycoord <= restore_popup.ycoord+loop_height-1)
		{
			count += ((ControlTemplatePopupTrigger *) control_ptr->control_template)->popup_top_item_num;
			return (SHORT)count;
		}
		restore_popup.ycoord = restore_popup.ycoord+loop_height;
		count ++;
	}
	return -1;
}
/*********************************************************************
* Function	: ControlSetPopupTriggerUpDownArrow
* Purpose	: To save the bounds of the specified popup trigger
* Scope		: Internal
* Input		: object_id - DBID of the UI object
* Output	: None
* Return	: Return True if no error
*			  ERR_UI_RES_NOT_FOUND - Invalid object ID
**********************************************************************/
void ControlSetPopupTriggerUpDownArrow(Control *addr,ObjectBounds *popup_bounds)
{
	
	BitmapTemplate popup_up_bitmap,popup_down_bitmap;
	
	((ControlTemplatePopupTrigger *) addr->control_template)->popup_arrow_up = FALSE;
	((ControlTemplatePopupTrigger *) addr->control_template)->popup_arrow_down = FALSE;
	if( addr->control_subtype == 1)
	{
		/* Assign the upper arrow */
		if ( ((ControlTemplatePopupTrigger *) addr->control_template)->popup_top_item_num != 0)
		{
			popup_up_bitmap.xcoord = popup_bounds->xcoord + (popup_bounds->width-1)
				- BUTTON_BORDER - POPUP_SCROLL_ARROW_SIZE;
			popup_up_bitmap.ycoord = popup_bounds->ycoord + BUTTON_BORDER;
			popup_up_bitmap.width  = POPUP_SCROLL_ARROW_SIZE;
			popup_up_bitmap.height = POPUP_SCROLL_ARROW_SIZE;
			popup_up_bitmap.compressed = FALSE;
            popup_up_bitmap.quantisation = Q_FOUR_BIT;
			popup_up_bitmap.size = 0;
			popup_up_bitmap.bitmap_data = list_34_arrow_up;
			((ControlTemplatePopupTrigger *) addr->control_template)->popup_arrow_up = TRUE;
			
			if (addr->control_attr.control_enter1 == TRUE)
				LcdDrawBitmap(&popup_up_bitmap,INVERT);
			else
				LcdDrawBitmap(&popup_up_bitmap,NOT_INVERT);
		}
		/* Assign the lower arrow */
		if ( (((ControlTemplatePopupTrigger *) (addr->control_template))->popup_top_item_num
			+ ((ControlTemplatePopupTrigger *) (addr->control_template))->popup_current_num_item_display)
			< ((ControlTemplatePopupTrigger *) (addr->control_template))->popup_num_objects)
		{
			popup_down_bitmap.xcoord = popup_bounds->xcoord + (popup_bounds->width-1)
				- BUTTON_BORDER - POPUP_SCROLL_ARROW_SIZE;
			popup_down_bitmap.ycoord = popup_bounds->ycoord + (popup_bounds->height-1)
				/*- BORDER*/ - POPUP_SCROLL_ARROW_SIZE -2;
				popup_down_bitmap.width  = POPUP_SCROLL_ARROW_SIZE;
			popup_down_bitmap.height = POPUP_SCROLL_ARROW_SIZE;
			popup_down_bitmap.compressed = FALSE;
            popup_down_bitmap.quantisation = Q_FOUR_BIT;
			popup_down_bitmap.size = 0;
			popup_down_bitmap.bitmap_data = list_34_arrow_down;
			((ControlTemplatePopupTrigger *) addr->control_template)->popup_arrow_down = TRUE;
			
			if (addr->control_attr.control_enter2 == TRUE)
				LcdDrawBitmap(&popup_down_bitmap,INVERT);
			else
				LcdDrawBitmap(&popup_down_bitmap,NOT_INVERT);
		}
	}
	((ControlTemplatePopupTrigger *) addr->control_template)->popup_arrow_up_bounds.xcoord = popup_up_bitmap.xcoord;
	((ControlTemplatePopupTrigger *) addr->control_template)->popup_arrow_up_bounds.ycoord = popup_up_bitmap.ycoord;
	((ControlTemplatePopupTrigger *) addr->control_template)->popup_arrow_down_bounds.xcoord = popup_down_bitmap.xcoord;
	((ControlTemplatePopupTrigger *) addr->control_template)->popup_arrow_down_bounds.ycoord = popup_down_bitmap.ycoord;
	((ControlTemplatePopupTrigger *) addr->control_template)->popup_arrow_up_bounds.width  =
		((ControlTemplatePopupTrigger *) addr->control_template)->popup_arrow_up_bounds.height =
		((ControlTemplatePopupTrigger *) addr->control_template)->popup_arrow_down_bounds.width  =
		((ControlTemplatePopupTrigger *) addr->control_template)->popup_arrow_down_bounds.height = POPUP_SCROLL_ARROW_SIZE;
}
/*********************************************************************
* Function	: ControlPopupClickedRegion
* Purpose	: To get the clicked region of the popup trigger
* Scope		: Internal
* Input		: addr			Pointer to the address of the specified popup
*			  x_input
*			  y_input
* Output	: None
* Return	: return the region of the popup trigger
* Comment	: None
**********************************************************************/
USHORT ControlPopupClickedRegion(Control *addr,SHORT x_input,SHORT y_input)
{
	ControlTemplatePopupTrigger *temp = (ControlTemplatePopupTrigger *)(addr->control_template);
	
	if (x_input >= temp->popup_arrow_up_bounds.xcoord &&
		x_input <  temp->popup_arrow_up_bounds.xcoord+temp->popup_arrow_up_bounds.width &&
		y_input >= temp->popup_arrow_up_bounds.ycoord &&
		y_input <  temp->popup_arrow_up_bounds.ycoord+temp->popup_arrow_up_bounds.height &&
		temp->popup_arrow_up == TRUE)
		return 1;
	
	if (x_input >= temp->popup_arrow_down_bounds.xcoord &&
		x_input <  temp->popup_arrow_down_bounds.xcoord+temp->popup_arrow_down_bounds.width &&
		y_input >= temp->popup_arrow_down_bounds.ycoord &&
		y_input <  temp->popup_arrow_down_bounds.ycoord+temp->popup_arrow_down_bounds.height &&
		temp->popup_arrow_down == TRUE)
		return 2;
	/* default value */
	return 0;
}
/*********************************************************************
* Function	: ControlSetPopupScroll
* Purpose	: To set the top item num of popup trigger
* Scope		: Internal
* Input		: addr			Pointer to the address of the specified popup
*			  up_down
* Output	: None
* Return	: None
* Comment	: Calculate the new top item number of the popup trigger
**********************************************************************/
void ControlSetPopupScroll(Control *addr,BYTE up_down)
{
	SHORT top_item;
    SHORT old_top_item;
	ControlTemplatePopupTrigger *temp = (ControlTemplatePopupTrigger *)(addr->control_template);
	
    beep_beep = FALSE;
	
	if (up_down == MOVE_UP)
	{
		top_item = (SHORT)(temp->popup_top_item_num) - (SHORT)(temp->popup_current_num_item_display);
		if (top_item < 0)
            top_item = 0;
        if (top_item == (SHORT)(temp->popup_top_item_num))
            beep_beep = FALSE;
        else beep_beep = TRUE;
		temp->popup_top_item_num = top_item;
	}
	
	if (up_down == MOVE_DOWN)
	{
        old_top_item = temp->popup_top_item_num;
		top_item = temp->popup_top_item_num + temp->popup_current_num_item_display;
		if (top_item > ((SHORT)(temp->popup_num_objects) - (SHORT)(temp->popup_current_num_item_display)))
		{
            temp->popup_top_item_num = temp->popup_num_objects - temp->popup_current_num_item_display;
            if (old_top_item == (SHORT)(temp->popup_top_item_num))
                beep_beep = FALSE;
            else beep_beep = TRUE;            
		}
        else
        {
            temp->popup_top_item_num = top_item;
            if (old_top_item == (SHORT)(temp->popup_top_item_num))
                beep_beep = FALSE;
            else beep_beep = TRUE;            
			
        }
	}
}
/********************************************************
* Function:	ControlInitControl
* Purpose:		1) to initialise the control object
2) to read the resource file
3) to create a corresponding line structure
in RAM
* Scope:		Application
* Input:		control_id	DBID of the line object
* Output:		None
* Return:      TRUE if no error
ERR_UI_RES_NOT_FOUND
* Comment:     None
*********************************************************/
Err ControlInitControl(ObjectID control_id)
{
	BYTE *buffer,*temp_buffer;
	UWORD byte_return;
	void *temp;
	Control *addr;
	Err Error;
	BYTE object_type;
	USHORT num_popup_items;
	BYTE ** temp_popup_list;
	WORD i;
	
	object_type = CONTROL;
	Error = UIAddressToLookupTable(control_id,object_type,&temp); /*put the pointer to the DBID											  lookup table */
	if (Error != TRUE) return Error;
	addr = (Control *)temp;
	if (!ResOpen(control_id)) /*check whether the resource file									 is opened */
	{
		Error = ResOpen(control_id);
		if (Error != TRUE) return Error;
	}
	
	addr->identification.ui_object_id = control_id;
	/* Field 0 */
	addr->identification.ui_object_type = CONTROL;
	/* Field 1 */
	ResGetField(control_id,1,&buffer,&byte_return);
	addr->identification.table_related = *(ObjectID*)buffer;
	qfree(buffer);
	/* Field 2 */
	ResReadField(control_id,2,0,2,&buffer,&byte_return);
	addr->bounds.xcoord = *(SHORT*)buffer;
	qfree(buffer);
	ResReadField(control_id,2,2,2,&buffer,&byte_return);
	addr->bounds.ycoord = *(SHORT*)buffer;
	qfree(buffer);
	ResReadField(control_id,2,4,2,&buffer,&byte_return);
	addr->bounds.width = *(SHORT*)buffer;
	qfree(buffer);
	ResReadField(control_id,2,6,2,&buffer,&byte_return);
	addr->bounds.height = *(SHORT*)buffer;
	qfree(buffer);
	/* Field 3 */
	ResGetField(control_id,3,&buffer,&byte_return);
	addr->control_style = *buffer;
	qfree(buffer);
	/* Field 4 */
	ResGetField(control_id,4,&buffer,&byte_return);
	addr->control_subtype = *buffer;
	qfree(buffer);
	/* Field 5 */
	ResGetField(control_id,5,&buffer,&byte_return);
	addr->control_text = (BYTE*)qmalloc((strlen(buffer)+1)*sizeof(BYTE));
	strcpy(addr->control_text,buffer);
	qfree(buffer);
	/* Field 6 */
	ResGetField(control_id,6,&buffer,&byte_return);
	addr->text_alignment = *buffer;
	qfree(buffer);
	/* Field 7 */
	ResReadField(control_id,7,0,2,&buffer,&byte_return);
	addr->control_attr.control_enable = *(BOOLEAN*)buffer;
	qfree(buffer);
	ResReadField(control_id,7,2,2,&buffer,&byte_return);
	addr->control_attr.control_active = *(BOOLEAN*)buffer;
	qfree(buffer);
	ResReadField(control_id,7,4,2,&buffer,&byte_return);
	addr->control_attr.control_visible = *(BOOLEAN*)buffer;
	qfree(buffer);
	addr->control_attr.control_drawn = FALSE;
	addr->control_attr.control_save_behind = FALSE;
	addr->control_attr.control_enter = FALSE;
	addr->control_attr.control_enter1 = FALSE;
	addr->control_attr.control_enter2 = FALSE;
	
	switch (addr->control_style)
	{
	case BUTTON:
		addr->control_template = (ControlTemplateButton*)qmalloc(sizeof(ControlTemplateButton)); 
		ResReadField(control_id,8,0,2,&buffer,&byte_return);
		((ControlTemplateButton*)(addr->control_template))->button_radius = *(SHORT*)buffer;
		qfree(buffer);
		ResReadField(control_id,8,2,1,&buffer,&byte_return);
		((ControlTemplateButton*)(addr->control_template))->button_color_on = UIColorConversion(*buffer);
		qfree(buffer);
		ResReadField(control_id,8,3,1,&buffer,&byte_return);
		((ControlTemplateButton*)(addr->control_template))->button_color_off = UIColorConversion(*buffer);
		qfree(buffer);
		((ControlTemplateButton*)(addr->control_template))->control_value = FALSE;
		break; 
	case PUSH_BUTTON:
		addr->control_template = (ControlTemplatePushButton*)qmalloc(sizeof(ControlTemplatePushButton)); 
		ResReadField(control_id,8,0,1,&buffer,&byte_return);
		((ControlTemplatePushButton*)(addr->control_template))->push_button_color_on = UIColorConversion(*buffer);
		qfree(buffer);
		ResReadField(control_id,8,1,1,&buffer,&byte_return);
		((ControlTemplatePushButton*)(addr->control_template))->push_button_color_off = UIColorConversion(*buffer);
		qfree(buffer);
		ResReadField(control_id,8,2,2,&buffer,&byte_return);
		((ControlTemplatePushButton*)(addr->control_template))->push_button_group_id = *(USHORT*)buffer;
		qfree(buffer);
		ResReadField(control_id,8,4,2,&buffer,&byte_return);
		((ControlTemplatePushButton*)(addr->control_template))->control_value = *(BOOLEAN*)buffer;
		qfree(buffer);
		ResReadField(control_id,8,6,2,&buffer,&byte_return);
		((ControlTemplatePushButton*)(addr->control_template))->push_button_radius = *(SHORT*)buffer;
		qfree(buffer);
		break;
	case REPEAT_BUTTON:
		addr->control_template = (ControlTemplateRepeatButton*)qmalloc(sizeof(ControlTemplateRepeatButton));   
		((ControlTemplateRepeatButton*)(addr->control_template))->repeat_count = 0;
		ResReadField(control_id,8,0,2,&buffer,&byte_return);
		((ControlTemplateRepeatButton*)(addr->control_template))->repeat_bitmap.xcoord = *(SHORT*)buffer;
		qfree(buffer);
		ResReadField(control_id,8,2,2,&buffer,&byte_return);
		((ControlTemplateRepeatButton*)(addr->control_template))->repeat_bitmap.ycoord = *(SHORT*)buffer;
		qfree(buffer);
		ResReadField(control_id,8,4,2,&buffer,&byte_return);
		((ControlTemplateRepeatButton*)(addr->control_template))->repeat_bitmap.width = *(SHORT*)buffer;
		qfree(buffer);
		ResReadField(control_id,8,6,2,&buffer,&byte_return);
		((ControlTemplateRepeatButton*)(addr->control_template))->repeat_bitmap.height = *(SHORT*)buffer;
		qfree(buffer);
		ResReadField(control_id,8,8,1,&buffer,&byte_return);
		((ControlTemplateRepeatButton*)(addr->control_template))->repeat_bitmap.compressed = *buffer;
		qfree(buffer);
		ResReadField(control_id,8,9,1,&buffer,&byte_return);
		((ControlTemplateRepeatButton*)(addr->control_template))->repeat_bitmap.quantisation = *buffer;
		qfree(buffer);	 
		ResReadField(control_id,8,10,2,&buffer,&byte_return);
		((ControlTemplateRepeatButton*)(addr->control_template))->repeat_bitmap.size = *(USHORT*)buffer;
		qfree(buffer);
		ResGetPointer(control_id,8,12,(void**)&buffer);
		((ControlTemplateRepeatButton*)(addr->control_template))->repeat_bitmap.bitmap_data = (UWORD*)buffer;
		break;
	case CHECKBOX:
		addr->control_template = (ControlTemplateCheckBox*)qmalloc(sizeof(ControlTemplateCheckBox)); 
		/* Field 8 */
		ResReadField(control_id,8,0,2,&buffer,&byte_return);
		((ControlTemplateCheckBox*)(addr->control_template))->checkbox_group_id = *(USHORT*)buffer;
		qfree(buffer);
		ResReadField(control_id,8,2,2,&buffer,&byte_return);
		((ControlTemplateCheckBox*)(addr->control_template))->control_value = *(BOOLEAN*)buffer;
		qfree(buffer);
		ResReadField(control_id,8,4,2,&buffer,&byte_return);
		((ControlTemplateCheckBox*)(addr->control_template))->checkbox_bitmap1.xcoord = *(SHORT*)buffer;
		qfree(buffer);
		ResReadField(control_id,8,6,2,&buffer,&byte_return);
		((ControlTemplateCheckBox*)(addr->control_template))->checkbox_bitmap1.ycoord = *(SHORT*)buffer;
		qfree(buffer);
		ResReadField(control_id,8,8,2,&buffer,&byte_return);
		((ControlTemplateCheckBox*)(addr->control_template))->checkbox_bitmap1.width = *(SHORT*)buffer;
		qfree(buffer);
		ResReadField(control_id,8,10,2,&buffer,&byte_return);
		((ControlTemplateCheckBox*)(addr->control_template))->checkbox_bitmap1.height = *(SHORT*)buffer;
		qfree(buffer);
		ResReadField(control_id,8,12,1,&buffer,&byte_return);
		((ControlTemplateCheckBox*)(addr->control_template))->checkbox_bitmap1.compressed = *buffer;
		qfree(buffer);
		ResReadField(control_id,8,13,1,&buffer,&byte_return);
		((ControlTemplateCheckBox*)(addr->control_template))->checkbox_bitmap1.quantisation = *buffer;
		qfree(buffer);
		ResReadField(control_id,8,14,2,&buffer,&byte_return);
		((ControlTemplateCheckBox*)(addr->control_template))->checkbox_bitmap1.size = *(USHORT*)buffer;
		qfree(buffer);
		ResGetPointer(control_id,8,16,(void**)&buffer);
		((ControlTemplateCheckBox*)(addr->control_template))->checkbox_bitmap1.bitmap_data = (UWORD*)buffer;
		/* Field 9 */
		ResReadField(control_id,9,0,2,&buffer,&byte_return);
		((ControlTemplateCheckBox*)(addr->control_template))->checkbox_bitmap2.xcoord = *(SHORT*)buffer;
		qfree(buffer);
		ResReadField(control_id,9,2,2,&buffer,&byte_return);
		((ControlTemplateCheckBox*)(addr->control_template))->checkbox_bitmap2.ycoord = *(SHORT*)buffer;
		qfree(buffer);
		ResReadField(control_id,9,4,2,&buffer,&byte_return);
		((ControlTemplateCheckBox*)(addr->control_template))->checkbox_bitmap2.width = *(SHORT*)buffer;
		qfree(buffer);
		ResReadField(control_id,9,6,2,&buffer,&byte_return);
		((ControlTemplateCheckBox*)(addr->control_template))->checkbox_bitmap2.height = *(SHORT*)buffer;
		qfree(buffer);
		ResReadField(control_id,9,8,1,&buffer,&byte_return);
		((ControlTemplateCheckBox*)(addr->control_template))->checkbox_bitmap2.compressed = *buffer;
		qfree(buffer);
		ResReadField(control_id,9,9,1,&buffer,&byte_return);
		((ControlTemplateCheckBox*)(addr->control_template))->checkbox_bitmap2.quantisation = *buffer;
		qfree(buffer);
		ResReadField(control_id,9,10,2,&buffer,&byte_return);
		((ControlTemplateCheckBox*)(addr->control_template))->checkbox_bitmap2.size = *(USHORT*)buffer;
		qfree(buffer);
		ResGetPointer(control_id,9,12,(void**)&buffer);
		((ControlTemplateCheckBox*)(addr->control_template))->checkbox_bitmap2.bitmap_data = (UWORD*)buffer;
		break;
	case POPUP_TRIGGER: 
		addr->control_template = (ControlTemplatePopupTrigger*)qmalloc(sizeof(ControlTemplatePopupTrigger));   
		(ControlTemplatePopupTrigger*)(addr->control_template);
		/* Field 8 */
		ResReadField(control_id,8,0,2,&buffer,&byte_return);
		((ControlTemplatePopupTrigger*)(addr->control_template))->popup_radius = *(SHORT*)buffer;
		qfree(buffer);
		ResReadField(control_id,8,2,2,&buffer,&byte_return);
		num_popup_items = *(USHORT*)buffer;
		((ControlTemplatePopupTrigger*)(addr->control_template))->popup_num_objects = *(USHORT*)buffer;
		qfree(buffer);
		ResReadField(control_id,8,4,2,&buffer,&byte_return);
		((ControlTemplatePopupTrigger*)(addr->control_template))->popup_selected_item = *(SHORT*)buffer;
		qfree(buffer);
		ResReadField(control_id,8,6,2,&buffer,&byte_return);
		((ControlTemplatePopupTrigger*)(addr->control_template))->popup_top_item_num = *(USHORT*)buffer;
		qfree(buffer);
		((ControlTemplatePopupTrigger*)(addr->control_template))->popup_highlighted_item = -1;
		((ControlTemplatePopupTrigger*)(addr->control_template))->popup_max_num_item_display = 0;
		((ControlTemplatePopupTrigger*)(addr->control_template))->popup_current_num_item_display = 0;
		((ControlTemplatePopupTrigger*)(addr->control_template))->control_value = FALSE;
		((ControlTemplatePopupTrigger*)(addr->control_template))->popup_arrow_up = FALSE;
		((ControlTemplatePopupTrigger*)(addr->control_template))->popup_arrow_down = FALSE;
		ResReadField(control_id,8,8,READ_TO_END,&buffer,&byte_return);
		temp_buffer = buffer;
		if (num_popup_items > 0)
			temp_popup_list = (BYTE**)qmalloc(sizeof(BYTE*)*num_popup_items);
		else temp_popup_list = NULL;
		i = 0;
		while (i<num_popup_items)
		{
			temp_popup_list[i] = (BYTE*)qmalloc(sizeof(BYTE)*(strlen(buffer)+1));
			strcpy(temp_popup_list[i],buffer);
			buffer = buffer + strlen(buffer) + 1;
			i++;
		}
		qfree(temp_buffer);
		((ControlTemplatePopupTrigger*)(addr->control_template))->popup_items_list = temp_popup_list;
		((ControlTemplatePopupTrigger*)(addr->control_template))->save_behind.bitmap_data = NULL;
		break;
	default:
		return TRUE;
	}
	ResClose(control_id);
	return TRUE;
}

/*********************************************************************
* Function  	: ControlHighlightOneItem
* Purpose	: HightLight / DeHightLight a item on the list object
* Scope		: Application
* Input		: addr
* Output	: None
* Return	: TRUE if no error
*			  ErrUiResNotFound
* Comment	: None
**********************************************************************/
Err ControlHighlightOneItem (Control *addr, SHORT item_num, BOOLEAN item_onoff)
{
	USHORT			popup_indicator_width, count =0;
	SHORT			draw_width;
	BYTE			*draw_text;
	ObjectBounds	text,highlight,popup_bounds;
	
	
	if (addr->control_attr.control_visible == FALSE) return FALSE;
    if (item_num < ((ControlTemplatePopupTrigger *) addr->control_template)->popup_top_item_num ||
		item_num >= ( ((ControlTemplatePopupTrigger *) addr->control_template)->popup_top_item_num + 
		((ControlTemplatePopupTrigger *) addr->control_template)->popup_current_num_item_display ))
		return	FALSE;
	
	if (addr->control_subtype == POPUP_TRIGGER_STYLE_1)
		popup_indicator_width = POPUP_INDICATOR_WIDTH;
	else 
		popup_indicator_width = 0;
	
	popup_bounds = ((ControlTemplatePopupTrigger *) addr->control_template)->popuped;
	
	text.xcoord = popup_bounds.xcoord+POPUP_LEFT_BORDER;
	text.ycoord = popup_bounds.ycoord+POPUP_LEFT_BORDER;
	
    while (count++ < (item_num - ((ControlTemplatePopupTrigger *) addr->control_template)->popup_top_item_num))
		text.ycoord = text.ycoord+FONT_HEIGHT[0]+2;
	
	draw_width = strlen(((ControlTemplatePopupTrigger *) addr->control_template)->popup_items_list[item_num]);
	draw_text = (BYTE*)qmalloc((draw_width + 1)*sizeof(BYTE));
	strcpy(draw_text,((ControlTemplatePopupTrigger *) addr->control_template)->popup_items_list[item_num]);
	
	text.width  = popup_bounds.width - POPUP_LEFT_BORDER*2 - (popup_indicator_width+1);
	text.height = FONT_HEIGHT[0];
	
	if (item_onoff == TRUE)
	{
        /* Highlight */
		highlight.xcoord = popup_bounds.xcoord + POPUP_HIGHLIGHT_BORDER;
		highlight.ycoord = text.ycoord;
		highlight.width  = popup_bounds.width - POPUP_HIGHLIGHT_BORDER*2 - (popup_indicator_width+1);
		highlight.height = FONT_HEIGHT[0]+1;
		
		LcdDrawBox(&highlight,color_level[COLOR_GREY2_COLOR],color_level[COLOR_GREY2_COLOR],DRAW_FILL);
		LcdDrawFixedString(&text,draw_text,color_level[COLOR_WHITE_COLOR],color_level[COLOR_GREY2_COLOR],SMALL_FONT,DOTDOT,MARGIN_0);
		LcdDrawLine(highlight.xcoord+1,highlight.ycoord-1,highlight.xcoord+highlight.width-1,highlight.ycoord-1,SINGLE_LINE,NON_DOTTED_LINE,color_level[COLOR_BLACK_COLOR],color_level[COLOR_BLACK_COLOR]);
		LcdDrawLine(highlight.xcoord+1,highlight.ycoord+highlight.height,highlight.xcoord+highlight.width-1,highlight.ycoord+highlight.height,SINGLE_LINE,NON_DOTTED_LINE,color_level[COLOR_WHITE_COLOR],color_level[COLOR_WHITE_COLOR]);
        LcdDrawLine(highlight.xcoord,highlight.ycoord-1,highlight.xcoord,highlight.ycoord+highlight.height -1,SINGLE_LINE,NON_DOTTED_LINE,color_level[COLOR_BLACK_COLOR],color_level[COLOR_BLACK_COLOR]);
        LcdDrawLine(highlight.xcoord+highlight.width-1,highlight.ycoord-1,highlight.xcoord+highlight.width-1,highlight.ycoord+highlight.height-1,SINGLE_LINE,NON_DOTTED_LINE,color_level[COLOR_WHITE_COLOR],color_level[COLOR_WHITE_COLOR]);
	}
	else
	{
        /* Off Highlight */
		highlight.xcoord = popup_bounds.xcoord + POPUP_HIGHLIGHT_BORDER -1;
		highlight.ycoord = text.ycoord -1;
		highlight.width  = popup_bounds.width - POPUP_HIGHLIGHT_BORDER*2 - (popup_indicator_width);
        highlight.height = FONT_HEIGHT[0]+3;
		LcdDrawBox(&highlight,color_level[COLOR_GREY1_COLOR],color_level[COLOR_GREY1_COLOR],DRAW_FILL);
		LcdDrawFixedString(&text,draw_text,color_level[COLOR_BLACK_COLOR],color_level[COLOR_GREY1_COLOR],SMALL_FONT,DOTDOT,MARGIN_0);
	}
	qfree(draw_text);
	return TRUE;
}

/*********************************************************************
* Function	: ControlSetPopupTriggerUpDownArrow
* Purpose	: To save the bounds of the specified popup trigger
* Scope		: Internal
* Input		: object_id - DBID of the UI object
* Output	: None
* Return	: Return True if no error
*			  ERR_UI_RES_NOT_FOUND - Invalid object ID
**********************************************************************/
void ControlSetPopupTriggerUpDownArrowOnly(Control *addr)
{
	BitmapTemplate popup_up_bitmap,popup_down_bitmap;
    ObjectBounds popup_bounds;
	
	((ControlTemplatePopupTrigger *) addr->control_template)->popup_arrow_up = FALSE;
	((ControlTemplatePopupTrigger *) addr->control_template)->popup_arrow_down = FALSE;
	popup_bounds = ((ControlTemplatePopupTrigger *) addr->control_template)->popuped;
	
	if( addr->control_subtype == 1)
	{
		/* Assign the upper arrow */
		if ( ((ControlTemplatePopupTrigger *) addr->control_template)->popup_top_item_num != 0)
		{
            popup_up_bitmap.xcoord = popup_bounds.xcoord + (popup_bounds.width-1)
				- BUTTON_BORDER - POPUP_SCROLL_ARROW_SIZE;
            popup_up_bitmap.ycoord = popup_bounds.ycoord + BUTTON_BORDER;
			popup_up_bitmap.width  = POPUP_SCROLL_ARROW_SIZE;
			popup_up_bitmap.height = POPUP_SCROLL_ARROW_SIZE;
			popup_up_bitmap.compressed = FALSE;
            popup_up_bitmap.quantisation = Q_FOUR_BIT;
			popup_up_bitmap.size = 0;
			popup_up_bitmap.bitmap_data = list_34_arrow_up;
			((ControlTemplatePopupTrigger *) addr->control_template)->popup_arrow_up = TRUE;
			
			if (addr->control_attr.control_enter1 == TRUE)
				LcdDrawBitmap(&popup_up_bitmap,INVERT);
			else
				LcdDrawBitmap(&popup_up_bitmap,NOT_INVERT);
		}
		/* Assign the lower arrow */
		if ( (((ControlTemplatePopupTrigger *) (addr->control_template))->popup_top_item_num
			+ ((ControlTemplatePopupTrigger *) (addr->control_template))->popup_current_num_item_display)
			< ((ControlTemplatePopupTrigger *) (addr->control_template))->popup_num_objects)
		{
            popup_down_bitmap.xcoord = popup_bounds.xcoord + (popup_bounds.width-1)
				- BUTTON_BORDER - POPUP_SCROLL_ARROW_SIZE;
            popup_down_bitmap.ycoord = popup_bounds.ycoord + (popup_bounds.height-1)
				/*- BORDER*/ - POPUP_SCROLL_ARROW_SIZE -2;
				popup_down_bitmap.width  = POPUP_SCROLL_ARROW_SIZE;
			popup_down_bitmap.height = POPUP_SCROLL_ARROW_SIZE;
			popup_down_bitmap.compressed = FALSE;
            popup_down_bitmap.quantisation = Q_FOUR_BIT;
			popup_down_bitmap.size = 0;
			popup_down_bitmap.bitmap_data = list_34_arrow_down;
			((ControlTemplatePopupTrigger *) addr->control_template)->popup_arrow_down = TRUE;
			
			if (addr->control_attr.control_enter2 == TRUE)
				LcdDrawBitmap(&popup_down_bitmap,INVERT);
			else
				LcdDrawBitmap(&popup_down_bitmap,NOT_INVERT);
		}
	}
	((ControlTemplatePopupTrigger *) addr->control_template)->popup_arrow_up_bounds.xcoord = popup_up_bitmap.xcoord;
	((ControlTemplatePopupTrigger *) addr->control_template)->popup_arrow_up_bounds.ycoord = popup_up_bitmap.ycoord;
	((ControlTemplatePopupTrigger *) addr->control_template)->popup_arrow_down_bounds.xcoord = popup_down_bitmap.xcoord;
	((ControlTemplatePopupTrigger *) addr->control_template)->popup_arrow_down_bounds.ycoord = popup_down_bitmap.ycoord;
	((ControlTemplatePopupTrigger *) addr->control_template)->popup_arrow_up_bounds.width  =
		((ControlTemplatePopupTrigger *) addr->control_template)->popup_arrow_up_bounds.height =
		((ControlTemplatePopupTrigger *) addr->control_template)->popup_arrow_down_bounds.width  =
		((ControlTemplatePopupTrigger *) addr->control_template)->popup_arrow_down_bounds.height = POPUP_SCROLL_ARROW_SIZE;
}

/********************************************************
* Function:    ControlPopupClosePopupTrigger
* Purpose:     This function is called to close the popup trigger
* Scope:		Application
* Input:       None
* Output:		None
* Return:      None
* Comment:     None
*********************************************************/
Err ControlPopupTriggerClosePopupTrigger()
{
    BYTE    object_type;
    void    *addr;
	
    if (!popup_status)
        return FALSE;
	
    FormGetObjectPointer(old_event.eventID, &object_type, (void**)&addr);
	
    if (object_type == CONTROL)
    {       
        if (((Control*)addr)->control_style == POPUP_TRIGGER &&
            ((ControlTemplatePopupTrigger*)(((Control*)addr)->control_template))->control_value == TRUE)
        {                        
			((ControlTemplatePopupTrigger*)(((Control*)addr)->control_template))->control_value = FALSE;
			popup_status = FALSE;
			((Control*)addr)->control_attr.control_enter = FALSE;
			ControlRestoreBitBehind(old_event.eventID);
			FormObjectRestoreFocus();
			old_event.eventType = NULL_EVENT;
        }
    }
}

/********************************************************
* Function:    ControlPopupKeyboardHandleControlPopup
* Purpose:     This fucntion is called to provide support to change control popup by keyboard keys
* Scope:		Application
* Input:       None
* Output:		None
* Return:      None
* Comment:     None
*********************************************************/
Err ControlPopupKeyboardHandleControlPopup(EvtType *Event)
{
	ObjectID						active_control_id;
	BYTE							object_type;
	Control							*control_ptr;
    void                            *addr;
	ControlTemplatePopupTrigger		*control_template;	
	BOOLEAN							draw = FALSE;
	
	if (!popup_status)
		return FALSE;
	
	if (old_event.eventType != EVT_CONTROL_SELECT || old_event.para2 != POPUP_TRIGGER)
		return FALSE;
	
#ifdef DEBUG
	printf("\n KeyboardSetPopup 0");
#endif
	
    if (FormGetObjectPointer(old_event.eventID, &object_type, (void**)&addr) != TRUE)
		return FALSE;
	
#ifdef DEBUG
	printf("\n KeyboardSetPopup 1");
#endif
	
    if (object_type == CONTROL)
        control_ptr = (Control*)addr;
    else return FALSE;        
	
	if (control_ptr->control_style != POPUP_TRIGGER)
		return FALSE;		
	
	active_control_id	= control_ptr->identification.ui_object_id;
	control_template 	= (ControlTemplatePopupTrigger*)(control_ptr->control_template);
	
#ifdef DEBUG
	printf("\n KeyboardSetPopup 2 - active_control_id = %ld", active_control_id);
#endif
	
	
    switch (Event->eventType)
	{
	case EVT_KEY:
		if (Event->eventID == SOFT_KEY)
		{
			Event->para2 = Event->para2 & 0x000000FF;
			switch (Event->para2)
			{
			case KEY_HOME:
				control_template->popup_top_item_num = 0;
				control_template->popup_highlighted_item = 0;
				ControlDrawControl(active_control_id);
				return TRUE;
			case KEY_END:
#ifdef DEBUG_UP
				printf("\n ================= END ==================");
				printf("\n top = %ld", control_template->popup_top_item_num);
				printf("\n max = %ld", control_template->popup_max_num_item_display);
#endif
				
				control_template->popup_top_item_num = (control_template->popup_num_objects - control_template->popup_current_num_item_display);						
				control_template->popup_highlighted_item = control_template->popup_num_objects - 1;							
				ControlDrawControl(active_control_id);
#ifdef DEBUG_UP
				printf("\n ================= PAGE_END ==================");
				printf("\n top = %ld", control_template->popup_top_item_num);
				printf("\n max = %ld", control_template->popup_max_num_item_display);
#endif
				
				return TRUE;
			case KEY_PAGE_UP:			 		
#ifdef DEBUG_UP
				printf("\n ================= PAGE_UP ==================");
				printf("\n top = %ld", control_template->popup_top_item_num);
				printf("\n max = %ld", control_template->popup_max_num_item_display);
#endif
				
				
				if (control_template->popup_top_item_num != 0)
				{
					if ((control_template->popup_top_item_num >= control_template->popup_max_num_item_display - 1))
					{
#ifdef DEBUG_UP
						printf("\n First");
#endif
						control_template->popup_top_item_num  -=  (control_template->popup_max_num_item_display - 1);			 					
#ifdef DEBUG_UP
						printf("\n top = %ld", control_template->popup_top_item_num);
#endif
					}   
					else control_template->popup_top_item_num = 0;
#ifdef DEBUG_UP
					printf("\n TOP = %ld", control_template->popup_top_item_num);
#endif
					
					control_template->popup_highlighted_item = control_template->popup_top_item_num;
					ControlDrawControl(active_control_id);								 							
				}
				return TRUE;
			case KEY_PAGE_DOWN:
				if (control_template->popup_top_item_num != (control_template->popup_num_objects - control_template->popup_current_num_item_display))
				{
					if ((control_template->popup_top_item_num + control_template->popup_current_num_item_display) >
						(control_template->popup_num_objects - control_template->popup_current_num_item_display))
						control_template->popup_top_item_num = (control_template->popup_num_objects - control_template->popup_current_num_item_display);
					else
						control_template->popup_top_item_num +=	control_template->popup_current_num_item_display;
					
					control_template->popup_highlighted_item = control_template->popup_top_item_num;
					ControlDrawControl(active_control_id);
				}			 			
				return TRUE;
			case KEY_UP:
				if (control_template->popup_highlighted_item == -1 ||
					control_template->popup_highlighted_item >= control_template->popup_num_objects)
				{	
					control_template->popup_highlighted_item = control_template->popup_top_item_num + control_template->popup_current_num_item_display - 1;
					ControlHighlightOneItem (control_ptr, control_template->popup_highlighted_item, TRUE);																 						 											
				}
				else
				{
					if (control_template->popup_highlighted_item == 0)
						return TRUE;
					else if (control_template->popup_highlighted_item == control_template->popup_top_item_num)
					{
						control_template->popup_top_item_num --;
						control_template->popup_highlighted_item --;
						ControlDrawControl(active_control_id);
					}
					else
					{
						ControlHighlightOneItem (control_ptr, control_template->popup_highlighted_item, FALSE);
						control_template->popup_highlighted_item --;								
						if ((control_template->popup_highlighted_item < control_template->popup_top_item_num) ||
							(control_template->popup_highlighted_item >=  (control_template->popup_top_item_num + control_template->popup_current_num_item_display)))						            
						{
							if ((control_template->popup_highlighted_item + control_template->popup_current_num_item_display) >
								(control_template->popup_num_objects - control_template->popup_current_num_item_display))
								control_template->popup_top_item_num = (control_template->popup_num_objects - control_template->popup_current_num_item_display);
							else
								control_template->popup_top_item_num = control_template->popup_highlighted_item;
							ControlDrawControl(active_control_id);
						}
						else 								
							ControlHighlightOneItem (control_ptr, control_template->popup_highlighted_item, TRUE);							
					}				
				}													
				return TRUE;
			case KEY_DOWN:
				if (control_template->popup_highlighted_item == -1 ||
					control_template->popup_highlighted_item >= control_template->popup_num_objects)
				{	
					control_template->popup_highlighted_item = control_template->popup_top_item_num;
					ControlHighlightOneItem (control_ptr, control_template->popup_highlighted_item, TRUE);																 						 											
				}
				else
				{
					if (control_template->popup_highlighted_item == control_template->popup_num_objects - 1)
						return TRUE;
					else if (control_template->popup_highlighted_item == (control_template->popup_top_item_num + control_template->popup_current_num_item_display - 1))
					{
						control_template->popup_top_item_num ++;
						control_template->popup_highlighted_item ++;
						ControlDrawControl(active_control_id);
					}
					else
					{
						ControlHighlightOneItem (control_ptr, control_template->popup_highlighted_item, FALSE);
						control_template->popup_highlighted_item ++;								
						if ((control_template->popup_highlighted_item < control_template->popup_top_item_num) ||
							(control_template->popup_highlighted_item >=  (control_template->popup_top_item_num + control_template->popup_current_num_item_display)))						            
						{
							if ((control_template->popup_highlighted_item + control_template->popup_current_num_item_display) >
								(control_template->popup_num_objects - control_template->popup_current_num_item_display))
								control_template->popup_top_item_num = (control_template->popup_num_objects - control_template->popup_current_num_item_display);
							else
								control_template->popup_top_item_num = control_template->popup_highlighted_item;
							ControlDrawControl(active_control_id);
						}
						else 
							ControlHighlightOneItem (control_ptr, control_template->popup_highlighted_item, TRUE);							
					}				
				}													
				return TRUE;
			case KEY_LEFT:
				return TRUE;
			case KEY_RIGHT:
				return TRUE;
			default:
				if (Event->para1 == '\r')
				{
					if (control_template->popup_highlighted_item == -1)
					{	
                     			control_template->control_value = FALSE;
								popup_status = FALSE;
								control_ptr->control_attr.control_enter = FALSE;
								ControlRestoreBitBehind(active_control_id);
								FormObjectRestoreFocus();
								old_event.eventType = NULL_EVENT;															
					}
					else
					{
						popup_status = FALSE;
						control_template->popup_selected_item = control_template->popup_highlighted_item;
						qfree(control_ptr->control_text);
						control_ptr->control_text = (BYTE*)qmalloc((strlen(control_template->popup_items_list[control_template->popup_selected_item]) + 1) * sizeof (BYTE));
						strcpy(control_ptr->control_text, control_template->popup_items_list[control_template->popup_selected_item]);
						control_template->control_value = FALSE;			  			
						control_ptr->control_attr.control_enter = FALSE;
						ControlRestoreBitBehind(active_control_id);
						ControlDrawControl(active_control_id);
						EvtAppendEvt(EVT_CONTROL_POPUP_SELECT, active_control_id, (WORD)(control_template->popup_selected_item), 0, (void*)control_ptr);
						old_event.eventType = NULL_EVENT;
						FormObjectRestoreFocus();		
					}     			
					return TRUE;							
				}
				else
					return FALSE;
				}						
			}
			return FALSE;
		default: return FALSE;
	}					
	return FALSE;	
}

/********************************************************
* Function:    ControlPopupPopupTrigger
* Purpose:     This function is called to popup a popup trigger
* Scope:		Application
* Input:       control_id
* Output:		None
* Return:      TRUE        if popuped successfully
FALSE       can't popup
* Comment:     None
*********************************************************/
Err ControlPopupPopupTrigger(ObjectID control_id)
{
    BYTE                            object_type;
    Control                         *control_ptr;
    ControlTemplatePopupTrigger     *control_template;
    void                            *addr;
    ObjectID                        active_form_id, active_object_id;
	Scrollbar						*scroll_ptr;
	EvtType							event;							
	USHORT							count;
	Form							*form_ptr;
	BOOLEAN							found;
	List							*ptr;
    
	
    if (popup_status)
		return FALSE;
	
    if (UISearchForAddress(control_id, &object_type, (void**)&addr) != TRUE)
        return ERR_UI_RES_NOT_FOUND;
	
    if (object_type != CONTROL)
        return FALSE;
	
    control_ptr = (Control*)addr;
    
    if (control_ptr->control_style != POPUP_TRIGGER || control_ptr->control_attr.control_visible == FALSE ||
		control_ptr->control_attr.control_enable == FALSE)
        return FALSE;                
	
    if (FormGetActiveFormID(&active_form_id) != TRUE)
        return FALSE;
	
	FormGetObjectPointer(active_form_id, &object_type, (void**)&form_ptr);
	found = FALSE;
	for (count = 0; count < form_ptr->form_num_objects; count++)
	{
		if (form_ptr->form_objects_list[count].object_id == control_id)
		{
			found = TRUE;
			break;
		}
	}
	
	if (!found)
		return FALSE;
	
    
    if (FormGetActiveObject(active_form_id, &active_object_id) != TRUE)
        return FALSE;
	
    control_template = (ControlTemplatePopupTrigger*)(control_ptr->control_template);        
	
    LcdEnableInsertPt(FALSE, 0, 0, SMALL_FONT);
	
    if (old_event.eventType != NULL_EVENT)
    {
        if (old_event.eventType == EVT_KEYBOARD_ENTER || old_event.eventType == EVT_KEYBOARD_EXIT)
        {
            if (keyboard.keyboard_attr.keyboard_enter)
       	    {
				KeyboardDrawInvertKey(keyboard.keyboard_highlight_key);    
                keyboard.keyboard_attr.keyboard_enter = FALSE;
            }                       		    
		}            		
        else
        {
            FormGetObjectPointer((ObjectID)old_event.eventID, &object_type, (void**)&addr);                     
            switch(object_type)
            {
			case CONTROL:                  
				if (((Control*)addr)->control_attr.control_enter)
				{
					((Control*)addr)->control_attr.control_enter = FALSE;
					ControlDrawControl(old_event.eventID);
				}                   
				break;
			case FIELD:
				LcdEnableInsertPt(FALSE, 0, 0, ((Field*)addr)->field_font_id);
				break;
			case LIST:					
				ListHighlightOneItem(((List*)addr), ((List*)addr)->list_highlighted_item, FALSE);
				((List*)addr)->list_highlighted_item = -1;
				ListHighlightOneItem(((List*)addr), ((List*)addr)->list_selected_item, TRUE);
				
				count = ((List*)addr)->list_num_related_list;
				while (count)
				{
					count --;
					if (FormGetObjectPointer(((List*)addr)->list_related_list_id[count], &object_type, (void**)&ptr) != TRUE)
						break;
					ListHighlightOneItem(ptr, ptr->list_highlighted_item, FALSE);
					ptr->list_highlighted_item = -1;
					ListHighlightOneItem(ptr, ptr->list_selected_item, TRUE);
				}
				break;
			case SCROLLBAR:
				scroll_ptr = (Scrollbar *)addr;
				if (scroll_ptr->scrollbar_attr.scrollbar_enter ||
					scroll_ptr->scrollbar_attr.scrollbar_enter1 ||
					scroll_ptr->scrollbar_attr.scrollbar_enter2)
				{
					scroll_ptr->scrollbar_attr.scrollbar_enter 	= FALSE;
					scroll_ptr->scrollbar_attr.scrollbar_enter1 = FALSE;
					scroll_ptr->scrollbar_attr.scrollbar_enter2 = FALSE;										
					ScrollbarDrawScrollbar(old_event.eventID);					                					                
				}
				break;
			case TABLE:
				if (((Table*)addr)->table_attr.table_enter)
				{
					((Table*)addr)->table_attr.table_enter = FALSE;
					((Table*)addr)->table_current_row = (USHORT) (old_event.para1);
					((Table*)addr)->table_current_col = (USHORT) (old_event.para2);
					TableDrawTable(old_event.eventID);
				}
				break;
			case SCHLINE:                     
				break;
			case BITMAP:
				if (((Bitmap*)addr)->bitmap_attr.bitmap_enter)
				{
					((Bitmap*)addr)->bitmap_attr.bitmap_enter = FALSE;
					BitmapDrawBitmap(old_event.eventID);
				}
				break;
			case TEXTBOX:
				LcdEnableInsertPt(FALSE, 0, 0, ((Textbox*)addr)->textbox_font_id);
				break;
			case MENU:
				MenuCloseMenu();
				break;                                        
            }
        }
    }             
	
    old_event.eventType = NULL_EVENT;
	old_event.eventID	= control_id;
    EvtAppendEvt(EVT_CONTROL_SELECT, control_id, 0, (WORD) control_ptr->control_style, (void*)control_ptr);
    return TRUE;
	
}        
