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



#include "stdafx.h"

#include "uidef.h"
#include "uifunc.h"

/********************************************************
* Function:	    StringConvertStyle
* Purpose:		To convert the styles of the string object
*				when black and white UI is selected
* Scope:		Internal
* Input:		string_addr		pointer to the string object
* Output:		None
* Return:		None
* Comment:      None
*********************************************************/
void StringConvertStyle(String *string_addr)
{
	if (color_mode == BLACK_AND_WHITE_MODE)
	{
		if (string_addr->string_style == 2 || string_addr->string_style == 5)
			string_addr->string_style = 1;		
	}
}


/********************************************************
* Function:	    StringDeleteString
* Purpose:		to delete a string object from the memory
* Scope:		Application
* Input:		string_id		OBJECTID of the string object
* Output:		None
* Return:		TRUE if no error
ERR_UI_RES_NOT_FOUND
* Comment:     None
*********************************************************/
Err StringDeleteString(ObjectID string_id)
{
    String *string_addr;
	BYTE object_type;
	Err Error;
	
	if (UISearchForAddress(string_id,&object_type,(void**)&string_addr) != TRUE) return ERR_UI_RES_NOT_FOUND;
    qfree(string_addr->string_text);
	Error = UIDeleteLookupTableElement(string_id);
	if (Error !=TRUE) return Error;
    qfree(string_addr);
	return TRUE;
}

/********************************************************
* Function:	    StringEraseString
* Purpose:		to erase the string object that is on the screen
* Scope:		Application
* Input:		string_id		OBJECTID of the string object
* Output:		None
* Return:		TRUE if no error
ERR_UI_RES_NOT_FOUND
* Comment:      the string_drawn attribute will be reset
*********************************************************/
Err StringEraseString(ObjectID string_id)
{
    String *addr;
	BYTE object_type;
    ObjectBounds bounds;
	
	if (UISearchForAddress(string_id,&object_type,(void**)&addr) != TRUE) return ERR_UI_RES_NOT_FOUND;
    if (addr->identification.table_related == 0xFFFF)
		bounds = addr->bounds;
    else bounds = addr->screen_bounds;
    if (addr->string_attr.string_drawn == TRUE)
        LcdEraseRegion(&bounds);
    addr->string_attr.string_drawn = FALSE;
    return TRUE;
}
/********************************************************
* Function:	    StringGetText
* Purpose:		to get the text of the string object
* Scope:		Application
* Input:		string_id		OBJECTID of the string object
* Output:		text            Pointer to a pointer to null-terminated string
* Return:		TRUE if no error
ERR_UI_RES_NOT_FOUND
* Comment:      None
*********************************************************/
Err StringGetText(ObjectID string_id, BYTE **text)
{
    String *string_addr;
	BYTE object_type;
	
	if (UISearchForAddress(string_id,&object_type,(void**)&string_addr) != TRUE) return ERR_UI_RES_NOT_FOUND;
    *text = string_addr->string_text;
    return TRUE;
}
/********************************************************
* Function:	    StringSetText
* Purpose:		to get the text of the string object
* Scope:		Application
* Input:		string_id		OBJECTID of the string object
text            Pointer to null-terminated string
* Output:		None
* Return:		TRUE if no error
ERR_UI_RES_NOT_FOUND
* Comment:      None
*********************************************************/
Err StringSetText(ObjectID string_id, BYTE *text)
{
    String *string_addr;
	BYTE object_type;
	UWORD length;
	
	if (UISearchForAddress(string_id,&object_type,(void**)&string_addr) != TRUE) return ERR_UI_RES_NOT_FOUND;
    qfree(string_addr->string_text);
	length = strlen(text); 
    string_addr->string_text = (BYTE *)qmalloc((length+1) * sizeof(BYTE));
	strcpy(string_addr->string_text,text);
    return TRUE;
}
/********************************************************
* Function:	    StringDrawString
* Purpose:		to draw the string box on the screen
* Scope:		Application
* Input:		string_id		OBJECTID of the string object
* Output:		None
* Return:		TRUE if no error
ERR_UI_RES_NOT_FOUND
* Comment:      None
*********************************************************/
Err StringDrawString(ObjectID string_id)
{
    String *string_addr;
	BYTE object_type;
    ObjectBounds bounds;
    ObjectBounds display_bounds;
	USHORT string_border=0;
    Table *table_ptr;
    BOOLEAN found = FALSE;
	
	
	if (UISearchForAddress(string_id,&object_type,(void**)&string_addr) != TRUE) return ERR_UI_RES_NOT_FOUND;
	if (string_addr->string_attr.string_visible == FALSE) return FALSE;	
	
	StringConvertStyle(string_addr);
	
    if (string_addr->identification.table_related == 0xFFFF)
		bounds = string_addr->bounds;
    else 
		bounds = string_addr->screen_bounds;
	
    if (string_addr->string_style == STRING_STYLE_0)
        LcdDrawBox(&bounds, string_addr->string_bg_color , string_addr->string_bg_color,FILL_SOLID);
    else if (string_addr->string_style == STRING_STYLE_1)
	{
		string_border = STRING_1_BORDER;
		LcdDrawBox(&bounds,string_addr->string_color, string_addr->string_bg_color,FILL_EMPTY);
	}
	else if (string_addr->string_style == STRING_STYLE_2)
	{
		string_border = STRING_2_BORDER;
		LcdDrawBox(&bounds,color_level[COLOR_BLACK_COLOR],string_addr->string_bg_color,FILL_EMPTY);
		LcdDrawLine(bounds.xcoord+1,bounds.ycoord+1,bounds.xcoord+bounds.width-2,
			bounds.ycoord+1,SINGLE_LINE,NON_DOTTED_LINE,color_level[COLOR_GREY2_COLOR], color_level[COLOR_GREY2_COLOR]);
		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_GREY2_COLOR],color_level[COLOR_GREY2_COLOR]);
		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 if (string_addr->string_style == STRING_STYLE_3)
	{
		string_border = STRING_1_BORDER;
		LcdDrawBox(&bounds,color_level[COLOR_BLACK_COLOR],string_addr->string_bg_color,FILL_EMPTY);
		LcdDrawLine(bounds.xcoord+1,bounds.ycoord+bounds.height-1,bounds.xcoord+bounds.width-1,
			bounds.ycoord+bounds.height-1,SINGLE_LINE,NON_DOTTED_LINE,color_level[COLOR_WHITE_COLOR],color_level[COLOR_WHITE_COLOR]);
		LcdDrawLine(bounds.xcoord+bounds.width-1,bounds.ycoord,bounds.xcoord+bounds.width-1,
			bounds.ycoord+bounds.height-2,SINGLE_LINE,NON_DOTTED_LINE,color_level[COLOR_WHITE_COLOR],color_level[COLOR_WHITE_COLOR]);
	}
	else if (string_addr->string_style == STRING_STYLE_4)
		LcdDrawBox(&bounds,string_addr->string_bg_color,string_addr->string_bg_color,FILL_SOLID);
	else if (string_addr->string_style == STRING_STYLE_5)
	{
		string_border = STRING_1_BORDER;
		LcdDrawBox(&bounds,color_level[COLOR_BLACK_COLOR],string_addr->string_bg_color,FILL_EMPTY);
	}
	
	/* Left alignment */
	if ( string_addr->text_alignment == 0)
	{
		display_bounds.xcoord = bounds.xcoord + string_border;
		display_bounds.ycoord = bounds.ycoord + (bounds.height-FONT_HEIGHT[string_addr->text_font])/2;
		display_bounds.width  = bounds.width - string_border*2;
		display_bounds.height = FONT_HEIGHT[string_addr->text_font];
		
		/* Subract a offset */
		if (string_addr->string_style == STRING_STYLE_3)
			display_bounds.ycoord -= 1;
	}
	/* Centre alignment */
	else if ( string_addr->text_alignment == 1)
	{		
		display_bounds.width= StrGetWidth(string_addr->string_text,string_addr->text_font);
		while(display_bounds.width + string_border*2 >= bounds.width)
			display_bounds.width--;
		display_bounds.xcoord = bounds.xcoord+(bounds.width-display_bounds.width)/2;
		display_bounds.ycoord = bounds.ycoord+(bounds.height-FONT_HEIGHT[string_addr->text_font])/2;
		display_bounds.height = FONT_HEIGHT[string_addr->text_font];
		
		/* Subract a offset */
		if (string_addr->string_style == STRING_STYLE_3)
			display_bounds.ycoord -= 1;
	}
	/* Right alignment */
	else
	{
		display_bounds.width = StrGetWidth(string_addr->string_text,string_addr->text_font);
		while(display_bounds.width + string_border*2 >= bounds.width)
			display_bounds.width--;
		
		display_bounds.xcoord = bounds.xcoord+bounds.width-display_bounds.width-string_border-1;
		display_bounds.ycoord = bounds.ycoord+(bounds.height-FONT_HEIGHT[string_addr->text_font])/2;
		display_bounds.height = FONT_HEIGHT[string_addr->text_font];
		
		/* Subract a offset */
		if (string_addr->string_style == STRING_STYLE_3)
			display_bounds.ycoord -= 1;
	}
	LcdDrawFixedString(&display_bounds,string_addr->string_text,string_addr->string_color,
					   string_addr->string_bg_color,(string_addr->text_font),DOTDOT,MARGIN_0);
	string_addr->string_attr.string_drawn = TRUE;
    return TRUE;
}
/********************************************************
* Function:	StringGetAttribute
* Purpose:		to check whether the string is drawn on the
display or not
* Scope:		Application
* Input:		string_id		DBID of the string object
* Output:		string_drawn	Pointer to Boolean value
*				string_active	Pointer to Boolean value that shows 
*							whether it is active or not
*				string_visible Pointer to Boolean value that shows 
*							 whether it is active or not
* Return:  	TRUE if no error
ERR_UI_RES_NOT_FOUND
* Comment:     None
*********************************************************/
Err StringGetAttribute(ObjectID string_id,BOOLEAN *string_drawn, BOOLEAN *string_visible)
{
	String *addr;
	BYTE object_type;
	/* to find out the pointer for the string object
	for an DBID, then return the string_drawn attribute */
	if (UISearchForAddress(string_id,&object_type,(void**)&addr) == TRUE)
	{
		*string_drawn = addr->string_attr.string_drawn;
		*string_visible = addr->string_attr.string_visible;
		return TRUE;
	}
	return ERR_UI_RES_NOT_FOUND;
}
/*********************************************************************
* Function	: StringSetAttribute
* Purpose	: Used to set the attribute of the string object
* Scope		: Application
* Input		: string_id - DBID of the string object
*			  att_drawn - Set the state of the string_drawn attribute
*		      att_active - Set the state of the schine_active attribute
*			  attr_visible	- Set the state of the string_visible attribute
* Output	: None
* Return	: Return True if no error or return ErrResNotFound if
*		  	  Invalid object ID
* Comment	: None
**********************************************************************/
Err StringSetAttribute(ObjectID string_id, BOOLEAN att_drawn, BOOLEAN att_visible)
{
	String *addr;
	BYTE object_type;
	
	if (UISearchForAddress(string_id,&object_type,(void**)&addr) == TRUE)
	{
		addr->string_attr.string_drawn = att_drawn;
		addr->string_attr.string_visible = att_visible;
		return TRUE;
	}
	return ERR_UI_RES_NOT_FOUND;
}
/********************************************************
* Function:	StringInitString
* Purpose:	1) to initialise the String object
2) to read the resource file
3) to create a corresponding String structure
in RAM
* Scope:	Application
* Input:	DBID of the String object
* Output:	None
* Return:      Error code
* Comment:     None
*********************************************************/
Err StringInitString(ObjectID string_id)
{
	BYTE *buffer;
	UWORD byte_return;
	String *addr;
	Err Error;
	BYTE object_type;
	
	object_type = STRING;
	/*put the pointer to the DBID lookup table */
	Error = UIAddressToLookupTable(string_id,object_type,(void**)&addr); 
	if (Error != TRUE) return Error;
	/*check whether the resource file is opened */
    Error = ResOpen(string_id);
    if (Error != TRUE) return Error;
	
	addr->identification.ui_object_id = string_id;
	/* get field 0 of resource file */
	ResGetField(string_id,0,&buffer,&byte_return);
	addr->identification.ui_object_type = *buffer;
    qfree(buffer);
	/* get field 1 of resource file */
	ResGetField(string_id,1,&buffer,&byte_return);
	addr->identification.table_related = *(ObjectID*)buffer;
    qfree(buffer);
	/* get field 2 from byte 0 for 2 bytes */
	ResReadField(string_id,2,0,2,&buffer,&byte_return);
	addr->bounds.xcoord = *(SHORT*)buffer;
    qfree(buffer);
	ResReadField(string_id,2,2,2,&buffer,&byte_return);
	addr->bounds.ycoord = *(SHORT*)buffer;
    qfree(buffer);
	ResReadField(string_id,2,4,2,&buffer,&byte_return);
	addr->bounds.width = *(SHORT*)buffer;
    qfree(buffer);
	ResReadField(string_id,2,6,2,&buffer,&byte_return);
	addr->bounds.height = *(SHORT*)buffer;
    qfree(buffer);
	/* get field 3 of resource file */
	ResGetField(string_id,3,&buffer,&byte_return);
	addr->string_style = *buffer;
    qfree(buffer);
	/* get field 4 of resource file */
	
	ResGetField(string_id,4,&buffer,&byte_return);
    addr->string_text = (BYTE*)qmalloc((strlen(buffer) + 1) * sizeof(BYTE));
    strcpy(addr->string_text, buffer);
    qfree(buffer);
	//    addr->string_text = buffer;
	
	/* get field 5 of resource file */
	ResGetField(string_id,5,&buffer,&byte_return);
	addr->string_color = UIColorConversion(*buffer);
    qfree(buffer);
	/* get field 6 of resource file */
	ResGetField(string_id,6,&buffer,&byte_return);
    addr->string_bg_color = UIColorConversion(*buffer);
    qfree(buffer);
	/* get field 7 of resource file */
	ResGetField(string_id,7,&buffer,&byte_return);
	addr->text_font = *buffer;
    qfree(buffer);
	/* get field 8 of resource file */
	ResGetField(string_id,8,&buffer,&byte_return);
	addr->text_alignment = *buffer;
    qfree(buffer);
	/* get field 9 from byte 0 for 2 bytes */
	ResGetField(string_id,9,&buffer,&byte_return);
	addr->string_attr.string_visible = *(BOOLEAN*)buffer;
    qfree(buffer);
	addr->string_attr.string_drawn  = FALSE;
	ResClose(string_id);
	
	StringConvertStyle(addr);
	return TRUE;
}
