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

#include "stdafx.h"

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

//#define DEBUG

/********************************************************
* Function:	BitmapDrawBitmap
* Purpose:		to draw the line object on the display
* Scope:		Application
* Input:		bitmap_id		OBJECTID of the bitmap object
* Output:		None
* Return:		TRUE if no error
ERR_UI_RES_NOT_FOUND
* Comment:     None
*********************************************************/
Err BitmapDrawBitmap(ObjectID bitmap_id)
{
	Bitmap *addr;
	BYTE object_type;
	
	if (UISearchForAddress(bitmap_id,&object_type, (void**)&addr) == TRUE)
	{
		if (addr->bitmap_attr.bitmap_visible == FALSE) return FALSE;
		if (addr->identification.table_related != 0xFFFF)
		{
			addr->bitmap_bitmap1.xcoord = addr->screen_bounds.xcoord;
			addr->bitmap_bitmap1.ycoord = addr->screen_bounds.ycoord;
			addr->bitmap_bitmap1.height = addr->screen_bounds.height;
			addr->bitmap_bitmap1.width = addr->screen_bounds.width;
			addr->bitmap_bitmap2.xcoord = addr->screen_bounds.xcoord;
			addr->bitmap_bitmap2.ycoord = addr->screen_bounds.ycoord;
			addr->bitmap_bitmap2.height = addr->screen_bounds.height;
			addr->bitmap_bitmap2.width = addr->screen_bounds.width;
		}
		else
		{
			addr->bitmap_bitmap1.xcoord = addr->bounds.xcoord;
			addr->bitmap_bitmap1.ycoord = addr->bounds.ycoord;
			addr->bitmap_bitmap1.height = addr->bounds.height;
			addr->bitmap_bitmap1.width = addr->bounds.width;
			addr->bitmap_bitmap2.xcoord = addr->bounds.xcoord;
			addr->bitmap_bitmap2.ycoord = addr->bounds.ycoord;
			addr->bitmap_bitmap2.height = addr->bounds.height;
			addr->bitmap_bitmap2.width = addr->bounds.width;
		}
		
		if (addr->bitmap_attr.bitmap_enter && addr->bitmap_style == 0)
			LcdDrawBitmap(&(addr->bitmap_bitmap1),1);
		else if (addr->bitmap_attr.bitmap_enter && addr->bitmap_style == 1)
			LcdDrawBitmap(&(addr->bitmap_bitmap2),0);
		else LcdDrawBitmap(&(addr->bitmap_bitmap1),0);
		addr->bitmap_attr.bitmap_drawn = TRUE;
		return TRUE;
	}
	return ERR_UI_RES_NOT_FOUND;
}
/********************************************************
* Function:	BitmapEraseBitmap
* Purpose:		to erase the bitmap object
* Scope:		Application
* Input:		bitmap_id		OBJECTID of the bitmap object
* Output:		None
* Return:		TRUE if no error
ERR_UI_RES_NOT_FOUND
* Comment:     None
*********************************************************/
Err BitmapEraseBitmap(ObjectID bitmap_id)
{
	Bitmap *addr;
	BYTE object_type;
    ObjectBounds bounds;
	
	if (UISearchForAddress(bitmap_id,&object_type, (void**)&addr) == TRUE)
	{
		if (addr->identification.table_related == 0xFFFF) bounds = addr->bounds;
		else bounds = addr->screen_bounds;
		if (addr->bitmap_attr.bitmap_drawn) LcdEraseRegion(&bounds);
		addr->bitmap_attr.bitmap_drawn = FALSE;
		return TRUE;
	}
	return ERR_UI_RES_NOT_FOUND;
}
/********************************************************
* Function:	BitmapGetAttribute
* Purpose:		to check whether the bitmap is drawn on the
display or not
* Scope:		Application
* Input:		bitmap_id		DBID of the bitmap object
* Output:		bitmap_drawn	Pointer to Boolean value
*				bitmap_active	Pointer to Boolean value that shows 
*								whether it is active or not
*				bitmap_enable	Pointer to Boolean value that shows 
*								whether it is enable or not
*				bitmap_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 BitmapGetAttribute(ObjectID bitmap_id,BOOLEAN *bitmap_drawn, BOOLEAN *bitmap_enable, BOOLEAN *bitmap_active, BOOLEAN *bitmap_visible)
{
	Bitmap *addr;
	BYTE object_type;
	/* to find out the pointer for the bitmap object
	for an DBID, then return the bitmap_drawn attribute */
	if (UISearchForAddress(bitmap_id,&object_type,(void**)&addr) == TRUE)
	{
		*bitmap_drawn = addr->bitmap_attr.bitmap_drawn;
		*bitmap_enable = addr->bitmap_attr.bitmap_enable;
		*bitmap_active = addr->bitmap_attr.bitmap_active;
		*bitmap_visible = addr->bitmap_attr.bitmap_visible;
		return TRUE;
	}
	return ERR_UI_RES_NOT_FOUND;
}
/*********************************************************************
* Function	: BitmapSetAttribute
* Purpose	: Used to set the attribute of the bitmap object
* Scope		: Application
* Input		: bitmap_id - DBID of the bitmap object
*			  att_drawn - Set the state of the bitmap_drawn attribute
*			  att_enable - Set the state of the bitmap_enable attribute
*		      att_active - Set the state of the schine_active attribute
*			  attr_visible	- Set the state of the bitmap_visible attribute
* Output	: None
* Return	: Return True if no error or return ErrResNotFound if
*		  	  Invalid object ID
* Comment	: None
**********************************************************************/
Err BitmapSetAttribute(ObjectID bitmap_id, BOOLEAN att_drawn, BOOLEAN att_enable, BOOLEAN att_active, BOOLEAN att_visible)
{
	Bitmap *addr;
	BYTE object_type;
	
	if (UISearchForAddress(bitmap_id,&object_type,(void**)&addr) == TRUE)
	{
		addr->bitmap_attr.bitmap_drawn = att_drawn;
		addr->bitmap_attr.bitmap_active = att_active;
		addr->bitmap_attr.bitmap_visible = att_visible;
		addr->bitmap_attr.bitmap_enable = att_enable;
		return TRUE;
	}
	return ERR_UI_RES_NOT_FOUND;
}


/*********************************************************************
* Function	: BitmapSetBitmapBounds
* Purpose	: This function is called to set the bounds of bitmap
* Scope		: Application
* Input		: bitmap_id			DBID of the bitmap object
*			  bounds 			bounds of bitmap
* Output	: None
* Return	: Return True if no error or return ErrResNotFound if
*		  	  Invalid object ID
* Comment	: None
**********************************************************************/
Err BitmapSetBitmapBounds(ObjectID bitmap_id, ObjectBounds bitmap_bounds)
{
	Bitmap *addr;
	BYTE object_type;
	
	if (UISearchForAddress(bitmap_id,&object_type,(void**)&addr) != TRUE) 	return ERR_UI_RES_NOT_FOUND;
	addr->bounds = bitmap_bounds;
	return TRUE;
}

/*********************************************************************
* Function	: BitmapSetBitmapBounds
* Purpose	: This function is called to get the bounds of bitmap
* Scope		: Application
* Input		: bitmap_id			DBID of the bitmap object
*			  bounds 			bounds of bitmap
* Output	: None
* Return	: Return True if no error or return ErrResNotFound if
*		  	  Invalid object ID
* Comment	: None
**********************************************************************/
Err BitmapGetBitmapBounds(ObjectID bitmap_id, ObjectBounds *bitmap_bounds)
{
	Bitmap *addr;
	BYTE object_type;
	
	if (UISearchForAddress(bitmap_id,&object_type,(void**)&addr) != TRUE) 	return ERR_UI_RES_NOT_FOUND;
	*bitmap_bounds = addr->bounds;
	return TRUE;
}


/********************************************************
* Function:	BitmapDeleteBitmap
* Purpose:		to delete the bitmap object from memory
* Scope:		Application
* Input:		bitmap_id		OBJECTID of the bitmap object
* Output:		None
* Return:		TRUE if no error
ERR_UI_RES_NOT_FOUND
* Comment:     None
*********************************************************/
Err BitmapDeleteBitmap(ObjectID bitmap_id)
{
    Bitmap *bitmap_addr;
	BYTE object_type;
	Err Error;
	
	if (UISearchForAddress(bitmap_id,&object_type,(void**)&bitmap_addr) != TRUE)
        return ERR_UI_RES_NOT_FOUND;
	Error = UIDeleteLookupTableElement(bitmap_id);
	if (Error !=TRUE) return Error;
	pfree(bitmap_addr);
	return TRUE;
}

/*********************************************************************
* Function	: BitmapSetBitmapTemplate
* Purpose	: This function is called to set the bitmap templates for a bitmap object
* Scope		: Application
* Input		: bitmap_id					DBID of the bitmap object
*			  bitmap_template_0			First bitmap template
*			  bitmap_template_1			Second bitmap template
* Output	: None
* Return	: Return True if no error or return ErrResNotFound if
*		  	  Invalid object ID
* Comment	: None
**********************************************************************/
Err BitmapSetBitmapTemplate(ObjectID bitmap_id, BitmapTemplate bitmap_template_0,
							BitmapTemplate bitmap_template_1)
{
	Bitmap *addr;
	BYTE object_type;
	
	if (UISearchForAddress(bitmap_id,&object_type,(void**)&addr) != TRUE) 	return ERR_UI_RES_NOT_FOUND;
	addr->bitmap_bitmap1 = bitmap_template_0;
	addr->bitmap_bitmap2 = bitmap_template_1;
	return TRUE;
}	

/*********************************************************************
* Function	: BitmapGetBitmapTemplate
* Purpose	: This function is called to get the bitmap templates for a bitmap object
* Scope		: Application
* Input		: bitmap_id					DBID of the bitmap object
* Output	: bitmap_template_0			Pointer to First bitmap template
*			  bitmap_template_1			Pointer to Second bitmap template
* Return	: Return True if no error or return ErrResNotFound if
*		  	  Invalid object ID
* Comment	: NULL can be passed in to the variable bitmap_template_0 or 
bitmap_template_1 if u don't want to get this data
**********************************************************************/
Err BitmapGetBitmapTemplate(ObjectID bitmap_id, BitmapTemplate *bitmap_template_0,
							BitmapTemplate *bitmap_template_1)
{
	Bitmap *addr;
	BYTE object_type;
	
	if (UISearchForAddress(bitmap_id,&object_type,(void**)&addr) != TRUE) 	return ERR_UI_RES_NOT_FOUND;
	if (bitmap_template_0 != NULL)
		*bitmap_template_0 = addr->bitmap_bitmap1;
	if (bitmap_template_1 != NULL)
		*bitmap_template_1 = addr->bitmap_bitmap2;
	return TRUE;
}	



/********************************************************
* Function:	BitmapInitBitmap
* Purpose:	1) to initialise the line object
2) to read the resource file
3) to create a corresponding line structure
in RAM
* Scope:	Application
* Input:	DBID of the line object
* Output:	None
* Return:      Error code
* Comment:     None
*********************************************************/
Err BitmapInitBitmap(ObjectID bitmap_id)
{
	BYTE *buffer;
	UWORD byte_return;
	Bitmap *addr;
	Err Error;
	BYTE object_type;
	UWORD field_size;
	
    object_type = BITMAP;
	/*put the pointer to the DBID lookup table */
	Error = UIAddressToLookupTable(bitmap_id,object_type,(void**)&addr); 
	if (Error != TRUE) return Error;
	/*check whether the resource file is opened */
    Error = ResOpen(bitmap_id);
    if (Error != TRUE) return Error;
	
	addr->identification.ui_object_id = bitmap_id;
	/* get field 0 of resource file */
	ResGetField(bitmap_id,0,&buffer,&byte_return);
	addr->identification.ui_object_type = *buffer;
	pfree(buffer);
	/* get field 1 of resource file */
	ResGetField(bitmap_id,1,&buffer,&byte_return);
	addr->identification.table_related = *(ObjectID*)buffer;
	pfree(buffer);
	/* get field 2 from byte 0 for 2 bytes */
	ResReadField(bitmap_id,2,0,2,&buffer,&byte_return);
	addr->bounds.xcoord = *(SHORT*)buffer;
	pfree(buffer);
	ResReadField(bitmap_id,2,2,2,&buffer,&byte_return);
	addr->bounds.ycoord = *(SHORT*)buffer;
	pfree(buffer);
	ResReadField(bitmap_id,2,4,2,&buffer,&byte_return);
	addr->bounds.width = *(SHORT*)buffer;
	pfree(buffer);
	ResReadField(bitmap_id,2,6,2,&buffer,&byte_return);
	addr->bounds.height = *(SHORT*)buffer;
	pfree(buffer);
	/* get field 3 of resource file */
	ResGetField(bitmap_id,3,&buffer,&byte_return);
	addr->bitmap_style = *buffer;
	pfree(buffer);
	/* get field 4 of resource file */
	ResFieldSize(bitmap_id,4,&field_size);
	if (field_size > 8)
	{
		ResReadField(bitmap_id,4,0,2,&buffer,&byte_return);
		addr->bitmap_bitmap1.xcoord = *(SHORT*)buffer;
		pfree(buffer);
		ResReadField(bitmap_id,4,2,2,&buffer,&byte_return);
		addr->bitmap_bitmap1.ycoord = *(SHORT*)buffer;
		pfree(buffer);
		ResReadField(bitmap_id,4,4,2,&buffer,&byte_return);
		addr->bitmap_bitmap1.width = *(SHORT*)buffer;
		pfree(buffer);
		ResReadField(bitmap_id,4,6,2,&buffer,&byte_return);
		addr->bitmap_bitmap1.height = *(SHORT*)buffer;
		pfree(buffer);
		ResReadField(bitmap_id,4,8,1,&buffer,&byte_return);
		addr->bitmap_bitmap1.compressed = *buffer;
		pfree(buffer);
		ResReadField(bitmap_id,4,9,1,&buffer,&byte_return);
		addr->bitmap_bitmap1.quantisation = *buffer;
		pfree(buffer);	 
		ResReadField(bitmap_id,4,10,2,&buffer,&byte_return);
		addr->bitmap_bitmap1.size = *(USHORT*)buffer;
		pfree(buffer);
		ResGetPointer(bitmap_id,4,12,(void**)&buffer);
		addr->bitmap_bitmap1.bitmap_data = (UWORD*)buffer;
	}
	/* get field 5 of resource file */
	ResFieldSize(bitmap_id,5,&field_size);
	if (field_size > 8)
	{
		ResReadField(bitmap_id,5,0,2,&buffer,&byte_return);
		addr->bitmap_bitmap2.xcoord = *(SHORT*)buffer;
		pfree(buffer);
		ResReadField(bitmap_id,5,2,2,&buffer,&byte_return);
		addr->bitmap_bitmap2.ycoord = *(SHORT*)buffer;
		pfree(buffer);
		ResReadField(bitmap_id,5,4,2,&buffer,&byte_return);
		addr->bitmap_bitmap2.width = *(SHORT*)buffer;
		pfree(buffer);
		ResReadField(bitmap_id,5,6,2,&buffer,&byte_return);
		addr->bitmap_bitmap2.height = *(SHORT*)buffer;
		pfree(buffer);
		ResReadField(bitmap_id,5,8,1,&buffer,&byte_return);
		addr->bitmap_bitmap2.compressed = *buffer;
		pfree(buffer);
		ResReadField(bitmap_id,5,9,1,&buffer,&byte_return);
		addr->bitmap_bitmap2.quantisation = *buffer;
		pfree(buffer);	 
		ResReadField(bitmap_id,5,10,2,&buffer,&byte_return);
		addr->bitmap_bitmap2.size = *(USHORT*)buffer;
		pfree(buffer);
		ResGetPointer(bitmap_id,5,12,(void**)&buffer);
		addr->bitmap_bitmap2.bitmap_data = (UWORD*)buffer;
	}
	/* get field 6 from byte 0 for 2 bytes */
	ResReadField(bitmap_id,6,0,2,&buffer,&byte_return);
	addr->bitmap_attr.bitmap_enable = *(BOOLEAN*)buffer;
	pfree(buffer);
	ResReadField(bitmap_id,6,2,2,&buffer,&byte_return);
	addr->bitmap_attr.bitmap_active = *(BOOLEAN*)buffer;
	pfree(buffer);
	ResReadField(bitmap_id,6,4,2,&buffer,&byte_return);
	addr->bitmap_attr.bitmap_visible = *(BOOLEAN*)buffer;
	pfree(buffer);
	addr->bitmap_attr.bitmap_drawn = FALSE;
	addr->bitmap_attr.bitmap_enter = FALSE;
	ResClose(bitmap_id);
	return TRUE;
}
