/*******************************************************************************

					CONDAT (UK)

********************************************************************************

 This software product is the property of Condat (UK) Ltd and may not be
 disclosed to any third party without the express permission of the owner.

********************************************************************************

 $Project name:
 $Project code:
 $Module:
 $File:		    ATBWapAUI.c
 $Revision:

 $Author:		Condat(UK)
 $Date:

********************************************************************************

 Description:
 	Provides most of the functionality of the ATB, as well as an interface with the AUI.


********************************************************************************

 $History: ATBWapAUI.c
 
    Sep 06 2005  REF:  MMI-SPR-34048  x0012849, Jagan
    Description :  GIF is displayed as  ?
    Solution:  Close the decoder  once for each open
 	xreddymn Aug-03-2005 MMI-SPR-33058:
    Handling of animated GIF images with transparency
 
    xreddymn Jun-29-2005 MMI-ENH-32467:
    Handling of animated GIF images

    xrashmic 29 Jun, 2005 MMI-SPR-32462
    Patch given by Kyle for display of table border
 
    xreddymn Jun-21-2005 MMI-SPR-30291: Send one message for the entire profile,
    instead of sending one parameter at a time, to the WAP adapter
 
	Jun-08-2005 MMI-SPR-30291 xreddymn: Added patches from FG

       May 11 2005  REF:  MMI-SPR-29887  x0012849
       To Implement the deferred MMS retrieval.
       
      Apr 28 2005  REF:  MMI-SPR-30400  x0012849
      To display the contents of Drop down menu correctly when a page is browsed through  D sample.

	xreddymn Mar-22-2005 MMI-SPR-29767
	Modified behaviour of SL push message handling in MMI

       xrashmic 08 Feb, 2005 MMI-SPR-27853
       Error handling in sending MMS and also displaying the progress  value
       
    Jan-24-2005 MMI-SPR-28135 - xreddymn: WAP_OTA settings saved in WAP profiles

       xrashmic 21 Jan, 2005 MMI-SPR-28223
       When a plugin image is displayed, we ignore the scroll key events

       xrashmic 28 Jan, 2005 MMI-SPR-28166
       Adding support for saving plugin images

	xreddymn Jan-06-2005 MMI-SPR-27618:
	Added end of string character to terminate strings in ATB_wap_entry_add

	xrashmic 16 Dec, 2004 MMI-SPR-27622
	To add support for deleting and adding Profiles

	Dec-10-2003 MMI-SPR-26159 - xreddymn: Prevent duplicate entries in History List

	15/05/2003 - SPR#1983 - SH - Updated to latest from 1.6.3 version.

 $End

*******************************************************************************/
#ifndef MFW
#define MFW
#endif

#ifdef MFW
#define ENTITY_MFW
#else
#ifdef SMI
#define ENTITY_SMI
#else
#define ENTITY_ACI
#endif
#endif

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#include "typedefs.h"

/* BEGIN ADD: Sumit : Req ID: : 31-Mar-2005*/
#ifndef NEPTUNE_BOARD
/* END ADD: Sumit : Req ID: : 31-Mar-2005*/
#include "ffs/ffs.h"
/* BEGIN ADD: Sumit : Req ID: : 31-Mar-2005*/
#else
#include "ffs.h"
#endif
/* END ADD: Sumit : Req ID: : 31-Mar-2005*/

#include "MmiWapFfs.h"
#ifdef FF_GPF_TCPIP
#include "leconfig.h"
#include "capimic.h"
#include "aapimic.h"
#include "wapmic_types.h"
//kyle 29 Jun, 2005 MMI-SPR-32462
#include "tapimmi.h"
#else
#include "gledef.h"
#include "capiclnt.h"
#include "aapiclnt.h"
#include "wap_types.h"
#endif


#include "ATBWapACI.h"
#include "ATBData.h"
#include "ATBWapAUI.h"
#include "font_bitmaps.h"

#include "cus_aci.h"
#include "prim.h"
#ifndef PCM_2_FFS
#include "pcm.h"
#endif
#include "dspl.h"
#ifdef FF_GPF_TCPIP
#include "mfw_sms.h"
#endif

void long_IP_to_char_IP(ULONG IPs,char* IPd);
#define DEFAULT_PROFILE 0		/* The default starting profile */

static T_WAP_VIEW		*View_header = 0;		/* View header points to first element in the view chain */
static T_WAP_VIEW		*Current_view = 0;		/* Points to the current view */

#if defined (FF_MMI_MMS) && defined (FF_GPF_TCPIP)
// May 11 2005  REF:  MMI-SPR-29887  x0012849
// MmsRetrievalType is used while Reading or writing Data from flash regarding retrieval type.
extern FlashDataMmsRetrievalType *MmsRetrievalType; 
//xrashmic 19 Aug, 2004 Bug: 2, 3, 36 and 42
extern int MMSactive;
//xrashmic 08 Feb, 2005 MMI-SPR-27853
extern void AUI_mms_status_notify(int status);

#endif

#ifdef FF_GPF_TCPIP
 // Apr 28 2005  REF:  MMI-SPR-30400 x0012849
 //This is added to see that check box is inline with the text.
 #define OFFSET_CHECKBOX 4
//xrashmic 21 Jan, 2005 MMI-SPR-28223
extern BOOL pluginImageDisplayed;

// xreddymn Jan-25-2005 MMI-SPR-28135: WAP_OTA
#include "mfw_ss.h" // For definitions of MFW_ASCII, MFW_DCS_UCS2
int 	ATB_convert_String(			char * ipString,	UBYTE ipDataType,	int ipLength,
									char * opString, 	UBYTE opDataType,	int opLength, UBYTE addNull);
extern void AUI_profile_list_redraw(S32 index);

#endif

/* LOCAL FUNCTION PROTOTYPES */

static void ATB_wap_buffer_image_scale(T_WAP_MMI_SEND_IMAGE_IND *image);
static void ATB_wap_buffer_text_draw(T_WAP_MMI_SEND_TEXT_IND *parameter);
static void ATB_wap_buffer_table_draw(T_WAP_MMI_SEND_TABLE_IND *parameter);
static void ATB_wap_buffer_line_draw(SHORT x1, SHORT y1, SHORT x2, SHORT y2);
static BOOL ATB_wap_buffer_onscreen(SHORT x, SHORT y, SHORT *deltaX, SHORT *deltaY);
static void ATB_wap_buffer_image_display(T_WAP_MMI_SEND_IMAGE_IND *image);

#if defined(TRACE_ATBWAPAUI) || defined(TRACE_ATBWAPACI)

/* Functions to display strings, for tracing purposes.
 * SPR#1437 - SH - Fixed these so they won't overwrite array bounds */

void ATB_trace_string(char *String, USHORT length)
{
	UBYTE stringIndex;
	UBYTE trace_string[41];

	for (stringIndex=0; (stringIndex<40 && stringIndex<length); stringIndex++)
		trace_string[stringIndex] = String[stringIndex];

	trace_string[stringIndex] = 0;

	TRACE_EVENT_P2("%s (%d)", trace_string, length);

	return;
}

void ATB_trace_ushort_string(USHORT *String, USHORT length)
{
	USHORT stringIndex;
	UBYTE trace_string[41];

	for (stringIndex=0; (stringIndex<40 && stringIndex<length); stringIndex++)
		trace_string[stringIndex] = (char) String[stringIndex];

	trace_string[stringIndex] = 0;

	TRACE_EVENT_P2("%s (%d)", trace_string, length);

	return;
}

#endif


/*******************************************************************************

 $Function:    	ATB_wap_start

 $Description:	Starts the WAP application and initialises the view chain

 $Returns:		None.

 $Arguments:	parameter		- dummy empty parameter

*******************************************************************************/

#ifdef CO_UDP_IP
void ATB_wap_start(T_MMI_WAP_START_IND *parameter)
#else
void ATB_wap_start(T_MMI_WAP_START_USER_AGENT_REQ *parameter)
#endif
{
#ifdef TRACE_ATBWAPAUI
	TRACE_FUNCTION("ATB_wap_start");
#endif

	M_MMI_WAP_START_IND(parameter);

	/* Initialise the pointer to the view chain */

	View_header = NULL;
	Current_view = NULL;

	return;
}

#if defined (FF_MMI_MMS) && defined (FF_GPF_TCPIP)
//TISHMMS Project
/*******************************************************************************

 $Function:    	ATB_mms_init_wap_data

 $Description:	init WapData and WapProfilesData

 $Returns:

 $Arguments:	parameter

*******************************************************************************/
void ATB_mms_init_wap_data(void)
{

#ifdef TRACE_ATBWAPAUI
    //TRACE_FUNCTION("ATB_mms_init_wap_data");
#endif

    if (WapData == NULL)
    {
        WapData = (FlashDataWap *) AUI_wap_memory_alloc(sizeof(FlashDataWap));      // Allocate memory for flash data
    }

    if (WapProfilesData == NULL)
    {
        WapProfilesData = (FlashDataWapProfiles *) AUI_wap_memory_alloc(sizeof(FlashDataWapProfiles));        // Allocate memory for profiles data
    }

    /* read FFS file to get WapData */
    if (flash_wap_read() == 0)
    {
        ATB_wap_profile_default_create();
    }

    return;
}

void ATB_mms_init_mms_data(void)
{
    // May 11 2005  REF:  MMI-SPR-29887  x0012849
    // type will hold the current retrieval condition
    BOOL Type; 
    if (MmsProfilesData == NULL)
    {
        MmsProfilesData = (FlashDataMmsProfiles *) AUI_wap_memory_alloc(sizeof(FlashDataMmsProfiles));        // Allocate memory for profiles data
    }
    // May 11 2005  REF:  MMI-SPR-29887  x0012849
    // Allocate memory for the MmsRetrievalType    
    // The memory allocated here freed in the function ATB_mms_free_wap_data
    if ( NULL == MmsRetrievalType)   
    {
        MmsRetrievalType = (FlashDataMmsRetrievalType *) AUI_wap_memory_alloc(sizeof(FlashDataMmsRetrievalType));       
    }	

    /* read FFS file to get WapData */
    if (flash_mms_read() == 0)
    {
        ATB_mms_profile_default_create();
    }
    // May 11 2005  REF:  MMI-SPR-29887  x0012849
    //If the Information is stored on flash then do nothing, other wise create a file on Flash
    // Initially MMS retrieval type is set to Immediate Retrieval.
   if(flash_mms_retrieval_type_read(&Type)==0)
   {
      flash_mms_retrieval_type_write(0);  // passed 0 indicates immediate
   }   
    return;
}


/*******************************************************************************

 $Function:    	ATB_mms_free_wap_data

 $Description:	free WapData

 $Returns:

 $Arguments:	parameter

*******************************************************************************/
void ATB_mms_free_wap_data(void)
{

#ifdef TRACE_ATBWAPAUI
	//TRACE_FUNCTION("ATB_mms_free_wap_data");
#endif

    if (WapData)
    {
        AUI_wap_memory_free ((UBYTE *)WapData, sizeof(FlashDataWap));
        WapData = NULL;
    }

    if (WapProfilesData)
    {
        AUI_wap_memory_free ((UBYTE *)WapProfilesData, sizeof(FlashDataWapProfiles));
        WapProfilesData = NULL;
    }

    if (MmsProfilesData)
    {
        AUI_wap_memory_free ((UBYTE *)MmsProfilesData, sizeof(FlashDataMmsProfiles));
        MmsProfilesData = NULL;
    }
   // May 11 2005  REF:  MMI-SPR-29887  x0012849
   // Memory is freed here for the MmsProfilesData
    if (MmsRetrievalType)
    {
        AUI_wap_memory_free ((UBYTE *)MmsRetrievalType, sizeof(FlashDataMmsRetrievalType ));
        MmsRetrievalType = NULL;
    }	

    return;
}/* end of ATB_mms_free_wap_data */


char* ATB_mms_get_MmscAddress(void)
{
    UBYTE ucProfileId;
    char* MmscAddress;

    ucProfileId = WapData->ProfileId;

    MmscAddress = MmsProfilesData->Profile[ucProfileId].MmscAddress;

    return MmscAddress;
}

void ATB_mms_get_wap_Profile(void ** MmsWapProfile)
{
    UBYTE			ucProfileId;

    char            TraceBuffer[100];

    T_WAP_PROFILE *  pTemp;


    ucProfileId = WapData->ProfileId;

    sprintf(TraceBuffer, "ATB_mms_get_wap_grofile called!ucProfileId = ");
    //M4_DebugStringMessage( TraceBuffer,(strlen(TraceBuffer)), ucProfileId);

    *MmsWapProfile = (void*)(&(WapProfilesData->Profile[ucProfileId]));

    pTemp = &(WapProfilesData->Profile[ucProfileId]);

    return;
}

void ATB_mms_profile_save(void)
{
	flash_mms_write();

	return;
}

//TISHMMS Project
//modification end
#endif
/*******************************************************************************

 $Function:    	ATB_wap_new_view

 $Description:	Starts a new view, defining the graphical size of the screen to
 				be handled.

 $Returns:		Pointer to the data structure of the new view

 $Arguments:	parameter		- width and height of the WAP view, etc.
 				UIdata			- Optional generic pointer, for use by the AUI.  This
 								can point to window information, etc, but is not used
 								by ATB.

*******************************************************************************/
#ifdef FF_GPF_TCPIP
T_WAP_VIEW* ATB_wap_new_view(T_MMI_WAP_NEW_VIEW_IND *parameter, void* UIdata)
{
	T_WAP_VIEW	*View	= (T_WAP_VIEW *) AUI_wap_memory_alloc (sizeof(T_WAP_VIEW));	// Create the view
	T_WAP_VIEW *ViewIndex;

#ifdef TRACE_ATBWAPAUI
	TRACE_FUNCTION("ATB_wap_new_view");
#endif

	/* SPR#2086 - SH - Changes to allow for multiple views */

	View->URL	= (char *)AUI_wap_memory_alloc ((URL_MAX_LEN+1)*sizeof(char));
	/* SPR#1816 - SH - Card title is unicode */
	View->Title			= (USHORT *)AUI_wap_memory_alloc ((CARD_TITLE_MAX_LEN+1)*sizeof(USHORT)); // Title of card
	View->cardWidth		= WAP_SCREEN_WIDTH;
	View->cardHeight	= WAP_SCREEN_HEIGHT;
	/* SPR#1816 - SH - Profiles list is unicode */
	View->ProfilesList	= ATB_wap_entry_list_create(WAP_PROFILES_LIST, MAX_PROFILES, PROFILENAME_MAX_LEN, TRUE); // ...profiles names list
	View->object_id		= parameter->object_id;
	View->channel		= WAP_CHANNEL_ID;
	View->UIdata		= UIdata;
	View->ElementHeader	= NULL;					/* Element chain is as yet empty */
	View->NextView		= NULL;
	View->browser_status = ATB_WAP_NO_STATUS;	/* SPR#1547 - SH - Replaced 'status' with 'browser_status' */
	View->CustSoftKeys	= FALSE;				/* Whether we have customised soft keys */

	/* SPR#1816 - SH - Create entry lists.  Now with unicode parameter */

	View->Bookmarks		= ATB_wap_entry_list_create(WAP_BOOKMARKS_LIST, MAX_BOOKMARKS, CARD_TITLE_MAX_LEN, TRUE);
	View->BookmarksURL	= ATB_wap_entry_list_create(WAP_URL_LIST, MAX_BOOKMARKS, URL_MAX_LEN, FALSE);
	View->History		= ATB_wap_entry_list_create(WAP_HISTORY_LIST, MAX_HISTORY, CARD_TITLE_MAX_LEN+NUMBER_PADDING, TRUE);
	View->HistoryURL	= ATB_wap_entry_list_create(WAP_URL_LIST, MAX_HISTORY, URL_MAX_LEN, FALSE);
	View->cId			= -1;

	/* Check if WAP data exists */

	if (!WapData)
	{
		WapData = (FlashDataWap *) AUI_wap_memory_alloc(sizeof(FlashDataWap));		// Allocate memory for flash data
		WapProfilesData  = (FlashDataWapProfiles *) AUI_wap_memory_alloc(sizeof(FlashDataWapProfiles));		// Allocate memory for profiles data

		/* Default values are provided.  If either of the files 'mmi/wapdata'
		 * or 'mmi/wapprof' aren't found, files are created with these defaults.
		 * The '0' size indicator indicates that one of the files was not present. */

		if (flash_wap_read() == 0)
		{
			ATB_wap_profile_default_create();
		}
	}

	View->ProfileId		= WapData->ProfileId;								// Default starting profile								// Read in the current profile

	if (View_header == NULL)
		View_header = View;														// This is the first entry
	else
	{
		ViewIndex = View_header;
		while (ViewIndex->NextView != NULL)										// If not the last entry,
			ViewIndex = ViewIndex->NextView;									// find the next entry!
		ViewIndex->NextView = View;												// New entry is last entry in chain
	}

	Current_view = View;
	ATB_wap_profile_names_read(View);
	ATB_wap_profile_read(View, View->ProfileId);

	M_MMI_WAP_NEW_VIEW_IND(parameter);

	return View;
}

#else /* #ifdef FF_GPF_TCPIP */

T_WAP_VIEW* ATB_wap_new_view(T_MMI_WAP_NEW_VIEW_IND *parameter, void* UIdata)
{
	T_WAP_VIEW	*View;
	T_WAP_VIEW *ViewIndex;

#ifdef TRACE_ATBWAPAUI
	TRACE_FUNCTION("ATB_wap_new_view");
#endif

	/* Create the view */

	View = (T_WAP_VIEW *) AUI_wap_memory_alloc (sizeof(T_WAP_VIEW));

	/* Allocate memory for two FFS files */

	WapData = (FlashDataWap *) AUI_wap_memory_alloc(sizeof(FlashDataWap));
	WapProfilesData  = (FlashDataWapProfiles *) AUI_wap_memory_alloc(sizeof(FlashDataWapProfiles));

	/* Allocate some arrays and lists */

	View->URL	= (char *)AUI_wap_memory_alloc ((URL_MAX_LEN+1)*sizeof(char));
	View->Title	= (USHORT *)AUI_wap_memory_alloc ((CARD_TITLE_MAX_LEN+1)*sizeof(USHORT));

	/* Set up some default values */

	View->cardWidth		= WAP_SCREEN_WIDTH;
	View->cardHeight	= WAP_SCREEN_HEIGHT;
	View->object_id		= parameter->object_id;
	View->channel		= WAP_CHANNEL_ID;
	View->UIdata		= UIdata;
	View->ElementHeader	= NULL;					/* Element chain is as yet empty */
	View->NextView		= NULL;
	View->browser_status = ATB_WAP_NO_STATUS;	/* Browser status is idle */
	View->CustSoftKeys	= FALSE;				/* Whether we have customised soft keys */
	View->cId			= -1;

	/* Create entry lists */

	View->ProfilesList	= ATB_wap_entry_list_create(WAP_PROFILES_LIST, MAX_PROFILES, PROFILENAME_MAX_LEN, TRUE);
	View->Bookmarks		= ATB_wap_entry_list_create(WAP_BOOKMARKS_LIST, MAX_BOOKMARKS, CARD_TITLE_MAX_LEN, TRUE);
	View->BookmarksURL	= ATB_wap_entry_list_create(WAP_URL_LIST, MAX_BOOKMARKS, URL_MAX_LEN, FALSE);
	View->History		= ATB_wap_entry_list_create(WAP_HISTORY_LIST, MAX_HISTORY, CARD_TITLE_MAX_LEN+NUMBER_PADDING, TRUE);
	View->HistoryURL	= ATB_wap_entry_list_create(WAP_URL_LIST, MAX_HISTORY, URL_MAX_LEN, FALSE);

	/* Read in profile information from flash */

	ATB_wap_profile_names_read(View);
	ATB_wap_profile_read(View, View->ProfileId);
	/* Add this view to the view chain */

	if (View_header == NULL)
		View_header = View;			/* This is the first entry */
	else
	{
		ViewIndex = View_header;
		while (ViewIndex->NextView != NULL)			/* If not the last entry, */
			ViewIndex = ViewIndex->NextView;		/* find the next entry! */
		ViewIndex->NextView = View;					/* New entry is last entry in chain */
	}

	Current_view = View;

	/* Tell WAP Browser to create new view */

	M_MMI_WAP_NEW_VIEW_IND(parameter);

	return View;
}

#endif  /* !#ifdef FF_GPF_TCPIP */

#ifdef FF_GPF_TCPIP
/*******************************************************************************

 $Function:    	ATB_wap_new_view_invisible

 $Description:	Starts a new view that is not associated with a browser
 				SPR#2086 - SH - Added

 $Returns:		Pointer to the data structure of the new view

 $Arguments:	object_id	- The object_id of the new view

*******************************************************************************/

T_WAP_VIEW* ATB_wap_new_view_invisible(UBYTE object_id)
{
	T_WAP_VIEW	*View	= (T_WAP_VIEW *) AUI_wap_memory_alloc (sizeof(T_WAP_VIEW));	// Create the view
	T_WAP_VIEW *ViewIndex;

#ifdef TRACE_ATBWAPAUI
	TRACE_FUNCTION("ATB_wap_new_view_invisible");
#endif

	memset((void *)View, 0, sizeof(T_WAP_VIEW));

	/* Check if WAP data exists */

	if (!WapData)
	{
		WapData = (FlashDataWap *) AUI_wap_memory_alloc(sizeof(FlashDataWap));		// Allocate memory for flash data
		WapProfilesData  = (FlashDataWapProfiles *) AUI_wap_memory_alloc(sizeof(FlashDataWapProfiles));		// Allocate memory for profiles data

		/* Default values are provided.  If either of the files 'mmi/wapdata'
		 * or 'mmi/wapprof' aren't found, files are created with these defaults.
		 * The '0' size indicator indicates that one of the files was not present. */

		if (flash_wap_read() == 0)
		{
			ATB_wap_profile_default_create();
		}
	}

	View->ProfileId		= WapData->ProfileId;								// Default starting profile
	View->object_id		= object_id;
	View->channel		= WAP_CHANNEL_ID;
	View->browser_status = ATB_WAP_NO_STATUS;
	View->cId			= -1;
	View->Title			= (USHORT *)AUI_wap_memory_alloc ((CARD_TITLE_MAX_LEN+1)*sizeof(USHORT)); // Title of card


	if (View_header == NULL)
		View_header = View;			/* This is the first entry */
	else
	{
		ViewIndex = View_header;
		while (ViewIndex->NextView != NULL)			/* If not the last entry, */
			ViewIndex = ViewIndex->NextView;		/* find the next entry! */
		ViewIndex->NextView = View;					/* New entry is last entry in chain */
	}

	Current_view = View;

	ATB_wap_profile_read(View, View->ProfileId);								// Read in the current profile

	return View;
}

#endif


/*******************************************************************************

 $Function:    	ATB_wap_get_view

 $Description:	Returns a pointer to a view, given its object_id

 $Returns:		Pointer to the data structure of the specified view, or NULL if not found

 $Arguments:	object_id  - the id of the view

*******************************************************************************/

T_WAP_VIEW* ATB_wap_get_view(UBYTE object_id)
{
	T_WAP_VIEW *View = View_header;
	UBYTE Index;

#ifdef TRACE_ATBWAPAUI
	TRACE_FUNCTION("ATB_wap_get_view()");
#endif

	if (!View_header)
	{
		return NULL;
	}

	/* SPR#1497 - SH - If object_id is 0, any view will do */

	if (object_id==0)
		return View;

	/* Search for object_id */

	for (Index = 0; View!=NULL && View->object_id!=object_id; Index++)
	{
		View = View->NextView;
	}

	return View;
}


#ifdef FF_GPF_TCPIP
/*******************************************************************************

 $Function:    	ATB_wap_change_view

 $Description:	Change the view to the one specified
 				SPR#2086 - SH - Added

 $Returns:		None.

 $Arguments:	object_id - The identifier for the view

*******************************************************************************/

void ATB_wap_change_view(UBYTE object_id)
{
	T_WAP_VIEW *View;

	TRACE_FUNCTION("ATB_wap_change_view()");

	if (!(View = ATB_wap_get_view(object_id)))
		return;

	Current_view = View;
	AUI_wap_view_changed(View);

	return;
}

#endif
/*******************************************************************************

 $Function:    	ATB_wap_destroy

 $Description:	Destroys any open view.  If no views are open, destroys the WAP
 				application by calling ATB_wap_terminate().

 $Returns:		WAP_OK if successful, WAP_FAIL if otherwise

 $Arguments:	None.


*******************************************************************************/

#ifdef FF_GPF_TCPIP
T_WAP_RES ATB_wap_destroy()
{
	T_MMI_WAP_CLOSE_VIEW_IND		parameter1;
	static T_MMI_WAP_TERMINATE_IND	parameter2;
	T_WAP_VIEW						*ViewIndex;
	T_WAP_VIEW						*PrevView;

#ifdef TRACE_ATBWAPAUI
	TRACE_FUNCTION("ATB_wap_destroy");
#endif
	/* Destroys an open view each time it is called.
	 * if there are no open views, the WAP browser is terminated. */

	/* Destroy the view chain.
 	 * If views still exist, destroy the bottom one */

	if (Current_view!=NULL)			/*Until end of chain */
	{
		ViewIndex = View_header;
		PrevView = NULL;

		/* Find the next view, or go to the view header */

		while (ViewIndex!=Current_view && ViewIndex!=NULL)
		{
			PrevView = ViewIndex;
			ViewIndex = ViewIndex->NextView;
		}

		TRACE_EVENT_P2("Found current view as %X; previous view = %X", ViewIndex, PrevView);

		if (ViewIndex==NULL)
		{
			TRACE_EVENT("**ERROR - cannot destroy view***");
			return;
		}

		/* If we're at the view header, then there is no previous view */

		if (ViewIndex==View_header)
		{
			View_header = View_header->NextView;
			Current_view = View_header;
		}
		else
		{
			Current_view = PrevView;
			Current_view->NextView = ViewIndex->NextView;	/* Close gap in view chain */
		}

		TRACE_EVENT_P1("Current view is now %X", Current_view);

		/* Notify MMI of new view */

		AUI_wap_view_changed(Current_view);

		parameter1.object_id = ViewIndex->object_id;

		ATB_wap_entry_list_destroy(ViewIndex->ProfilesList);					// Destroy profiles names list
		ATB_wap_entry_list_destroy(ViewIndex->Bookmarks);						// Destroy bookmarks
		ATB_wap_entry_list_destroy(ViewIndex->BookmarksURL);
		ATB_wap_entry_list_destroy(ViewIndex->History);							// Destroy history list
		ATB_wap_entry_list_destroy(ViewIndex->HistoryURL);

		/* SPR#2086 - SH - Only delete memory that has been allocated */

		if (ViewIndex->URL)
		{
			AUI_wap_memory_free ((UBYTE *)ViewIndex->URL, (URL_MAX_LEN+1)*sizeof(char)); // Delete URL string
		}

		if (ViewIndex->Title)
		{
			/* SPR#1816 - SH - Title is unicode */
			AUI_wap_memory_free ((UBYTE *)ViewIndex->Title, (CARD_TITLE_MAX_LEN+1)*sizeof(USHORT));   // Delete card title
		}

		if (ViewIndex->ElementHeader)
		{
			ATB_wap_buffer_clear(ViewIndex);										// Clear the element buffer
			ViewIndex->ElementHeader = ViewIndex->NewElementHeader;					// Just in case a new card is being created
			ATB_wap_buffer_clear(ViewIndex);										// Clear this too!
		}

		TRACE_EVENT_P1("Destroying view %X", ViewIndex);

		AUI_wap_memory_free((UBYTE *)ViewIndex, sizeof(T_WAP_VIEW));			// Destroy the current entry

		/* If the view is associated with a user agent, close that too */

		if (parameter1.object_id<WAP_DOWNLOAD_VIEW)
		{
			M_MMI_WAP_CLOSE_VIEW_IND(&parameter1);
		}
		/* Otherwise, indicate this view is closed */

		else
		{
			ATB_wap_close_view_done();
		}

		return WAP_OK;
	}

	else
	{
		/* SPR#1794 - SH - WAP data now split between two FFS files */
		/* Destroy the RAM copy of the FFS data */

		if (WapData)
		{
			AUI_wap_memory_free ((UBYTE *)WapData, sizeof(FlashDataWap));
			WapData = NULL;
		}

		/* Destroy the RAM copy of the FFS profiles information */

		if (WapProfilesData)
		{
			AUI_wap_memory_free ((UBYTE *)WapProfilesData, sizeof(FlashDataWapProfiles));
			WapProfilesData = NULL;
		}

		View_header = NULL;
		Current_view = NULL;

		/* Shut down WAP Browser */

		return ATB_wap_terminate(&parameter2);
	}
}

#else /* #ifdef FF_GPF_TCPIP */

T_WAP_RES ATB_wap_destroy()
{
	T_MMI_WAP_CLOSE_VIEW_IND		parameter1;
	static T_MMI_WAP_TERMINATE_IND	parameter2;
	T_WAP_VIEW						*ViewIndex;
	T_WAP_VIEW						*NextView;

#ifdef TRACE_ATBWAPAUI
	TRACE_FUNCTION("ATB_wap_destroy");
#endif

	/* Destroy the view chain.
 	 * If views still exist, destroy the bottom one */

	if (View_header!=NULL)								/* Until end of chain */
	{
		ViewIndex = View_header;						/* Store the current entry pointer */
		View_header = ViewIndex->NextView;				/* Find the next entry */

		parameter1.object_id = ViewIndex->object_id;

		/* Destroy entry lists */

		ATB_wap_entry_list_destroy(ViewIndex->ProfilesList);
		ATB_wap_entry_list_destroy(ViewIndex->Bookmarks);
		ATB_wap_entry_list_destroy(ViewIndex->BookmarksURL);
		ATB_wap_entry_list_destroy(ViewIndex->History);
		ATB_wap_entry_list_destroy(ViewIndex->HistoryURL);

		/* Free strings */

		AUI_wap_memory_free ((UBYTE *)ViewIndex->URL, (URL_MAX_LEN+1)*sizeof(char));
		AUI_wap_memory_free ((UBYTE *)ViewIndex->Title, (CARD_TITLE_MAX_LEN+1)*sizeof(USHORT));

		/* Clear the element buffer */

		ATB_wap_buffer_clear(ViewIndex);

		/* If a new card is being created, clear this too */

		ViewIndex->ElementHeader = ViewIndex->NewElementHeader;
		ATB_wap_buffer_clear(ViewIndex);

		/* Free View memory */

		AUI_wap_memory_free((UBYTE *)ViewIndex, sizeof(T_WAP_VIEW));

		/* Tell WAP Browser to close the view */

		M_MMI_WAP_CLOSE_VIEW_IND(&parameter1);

		return WAP_OK;
	}

	else
	{
		/* Destroy the RAM copy of the FFS data */

		if (WapData)
		{
			AUI_wap_memory_free ((UBYTE *)WapData, sizeof(FlashDataWap));
			WapData = NULL;
		}

		/* Destroy the RAM copy of the FFS profiles information */

		if (WapProfilesData)
		{
			AUI_wap_memory_free ((UBYTE *)WapProfilesData, sizeof(FlashDataWapProfiles));
			WapProfilesData = NULL;
		}

		View_header = NULL;
		Current_view = NULL;

		/* Shut down WAP Browser */

		return ATB_wap_terminate(&parameter2);
	}
}

#endif /* !#ifdef FF_GPF_TCPIP */

/*******************************************************************************

 $Function:    	ATB_wap_UIdata

 $Description:	Returns the UI pointer, for use by AUI

 $Returns:		The void pointer

 $Arguments:	None.

*******************************************************************************/

void * ATB_wap_UIdata()
{
	if (View_header)
		return View_header->UIdata;
	else
		return NULL;
}


/*******************************************************************************

 $Function:    	ATB_wap_terminate

 $Description:	Closes the WAP application and frees all the memory allocated

 $Returns:		WAP_OK

 $Arguments:	parameter - see MMI_WAP_TERMINATE_IND

*******************************************************************************/

T_WAP_RES ATB_wap_terminate(T_MMI_WAP_TERMINATE_IND *parameter)
{
#ifdef TRACE_ATBWAPAUI
	TRACE_FUNCTION("ATB_wap_terminate");
#endif

	/* SPR#1850 - SH - No longer terminate call here */

	M_MMI_WAP_TERMINATE_IND(parameter);

	return WAP_OK;
}


/*******************************************************************************

 $Function:    	ATB_wap_config_int

 $Description:	SPR#1921 - SH - Added
 				Sends integer configuration information to the browser

 $Returns:		WAP_OK if successful, WAP_FAIL if otherwise

 $Arguments:	View	- The current view
 				param	- ID of the configuration
 				value	- Integer value of the configuration

*******************************************************************************/

T_WAP_RES ATB_wap_config_int(T_WAP_VIEW *View, USHORT param, U32 value)
{
	T_MMI_WAP_CONFIGURE_IND parameter;
	parameter.object_id = View->object_id;
	parameter.type = WAP_IntConfig;
	parameter.param = param;
	parameter.intvalue = value;
	parameter.strvalue = NULL;
	parameter.length = 0;

	M_MMI_WAP_CONFIGURE_IND(&parameter);

	return WAP_OK;
}


/*******************************************************************************

 $Function:    	ATB_wap_config_str

 $Description:	SPR#1921 - SH - Added
 				Sends string configuration information to the browser

 $Returns:		WAP_OK if successful, WAP_FAIL if otherwise

 $Arguments:	View	- The current view
 				param	- ID of the configuration
 				value	- Integer value of the configuration
 				string	- String value of the configuration
 				length	- Length of the string value

*******************************************************************************/

T_WAP_RES ATB_wap_config_str(T_WAP_VIEW *View, USHORT param, char *string, U32 length)
{
	T_MMI_WAP_CONFIGURE_IND parameter;
	parameter.object_id = View->object_id;
	parameter.type = WAP_StrConfig;
	parameter.param = param;
	parameter.intvalue = 0;
	parameter.strvalue = string;
	parameter.length = length;

	M_MMI_WAP_CONFIGURE_IND(&parameter);

	return WAP_OK;
}


/*******************************************************************************

 $Function:    	ATB_wap_conn_config_int

 $Description:	SPR#1921 - SH - Added
 				Sends integer configuration information to the browser

 $Returns:		WAP_OK if successful, WAP_FAIL if otherwise

 $Arguments:	View	- The current view
 				param	- ID of the configuration
 				value	- Integer value of the configuration

*******************************************************************************/

T_WAP_RES ATB_wap_conn_config_int(T_WAP_VIEW *View, USHORT param, U32 value)
{
	T_MMI_WAP_CONNECTION_CONFIGURE_IND parameter;
	parameter.object_id = View->object_id;
	parameter.type = WAP_IntConfig;
	parameter.channel_id = View->channel;
	parameter.param = param;
	parameter.intvalue = value;
	parameter.strvalue = NULL;
	parameter.length = 0;

	M_MMI_WAP_CONNECTION_CONFIGURE_IND(&parameter);

	return WAP_OK;
}


/*******************************************************************************

 $Function:    	ATB_wap_conn_config_str

 $Description:	SPR#1921 - SH - Added
 				Sends string configuration information to the browser

 $Returns:		WAP_OK if successful, WAP_FAIL if otherwise

 $Arguments:	View	- The current view
 				param	- ID of the configuration
 				value	- Integer value of the configuration
 				string	- String value of the configuration
 				length	- Length of the string value

*******************************************************************************/

T_WAP_RES ATB_wap_conn_config_str(T_WAP_VIEW *View, USHORT param, char *string, U32 length)
{
	T_MMI_WAP_CONNECTION_CONFIGURE_IND parameter;
	parameter.object_id = View->object_id;
	parameter.type = WAP_StrConfig;
	parameter.channel_id = View->channel;
	parameter.param = param;
	parameter.intvalue = 0;
	parameter.strvalue = string;
	parameter.length = length;

	M_MMI_WAP_CONNECTION_CONFIGURE_IND(&parameter);

	return WAP_OK;
}


/*******************************************************************************

 $Function:    	ATB_wap_download_url

 $Description:	Requests the WAP browser to download a particular URL

 $Returns:		WAP_OK

 $Arguments:	View - The current view
 				URL	 - The URL to download
 				reload - TRUE if page is to be fetched from network, not cache.

*******************************************************************************/

T_WAP_RES ATB_wap_download_url(T_WAP_VIEW *View, char *URL, BOOL reload)
{
	T_MMI_WAP_DOWNLOAD_URL_IND parameter;

#ifdef TRACE_ATBWAPAUI
	TRACE_FUNCTION("ATB_wap_download_url");
#endif

	parameter.object_id = View->object_id;
	parameter.Url = URL;
	parameter.url_length = (U32)(strlen(URL)+1);
	parameter.reload = reload;
	// Jun-08-2005 MMI-SPR-30291: Added patches from FG
	#ifdef FF_GPF_TCPIP
	parameter.view_height = View->cardHeight;
	parameter.view_width = View->cardWidth;
	#endif
	M_MMI_WAP_DOWNLOAD_URL_IND(&parameter);

	return WAP_OK;
}


/*******************************************************************************

 $Function:    	ATB_wap_stop_download

 $Description:	Requests the WAP browser to stop downloading a particular URL

 $Returns:		WAP_OK

 $Arguments:	View - the current view

*******************************************************************************/

T_WAP_RES ATB_wap_stop_download(T_WAP_VIEW *View)
{
	T_MMI_WAP_BROWSE_CONTROL_IND parameter;

#ifdef TRACE_ATBWAPAUI
	TRACE_FUNCTION("ATB_wap_stop_download");
#endif

	parameter.object_id = View->object_id;
	parameter.browse_command = WAP_DOWNLOAD_STOP;
	M_MMI_WAP_BROWSE_CONTROL_IND(&parameter);

	ATB_wap_status_change(View,ATB_WAP_NO_STATUS);

	return WAP_OK;
}


/*******************************************************************************

 $Function:    	ATB_wap_card_refresh

 $Description:	Requests the WAP browser to refresh the current card from the network

 $Returns:		WAP_OK if successful, WAP_FAIL if otherwise

 $Arguments:	View - the current view

*******************************************************************************/

T_WAP_RES ATB_wap_card_refresh(T_WAP_VIEW *View)
{
	T_MMI_WAP_BROWSE_CONTROL_IND parameter;

#ifdef TRACE_ATBWAPAUI
	TRACE_FUNCTION("ATB_wap_card_refresh");
#endif

	parameter.object_id = View->object_id;
	parameter.browse_command = WAP_CARD_REFRESH;
	M_MMI_WAP_BROWSE_CONTROL_IND(&parameter);

	return WAP_OK;
}


/*******************************************************************************

 $Function:    	ATB_wap_card_display

 $Description:	Requests the WAP browser to redisplay a card held in the cache

 $Returns:		WAP_OK if successful, WAP_FAIL if otherwise

 $Arguments:	View - the current view

*******************************************************************************/

T_WAP_RES ATB_wap_card_display(T_WAP_VIEW *View)
{
	T_MMI_WAP_BROWSE_CONTROL_IND parameter;

#ifdef TRACE_ATBWAPAUI
	TRACE_FUNCTION("ATB_wap_card_display");
#endif

	parameter.object_id = View->object_id;
	parameter.browse_command = WAP_CARD_DISPLAY;
	M_MMI_WAP_BROWSE_CONTROL_IND(&parameter);

	return WAP_OK;
}


/*******************************************************************************

 $Function:    	ATB_wap_card_go_back

 $Description:	Requests the WAP browser to go to the previous card

 $Returns:		WAP_OK if successful, WAP_FAIL if otherwise

 $Arguments:	View - the current view

*******************************************************************************/

T_WAP_RES ATB_wap_card_go_back(T_WAP_VIEW *View)
{
	T_MMI_WAP_BROWSE_CONTROL_IND parameter;

#ifdef TRACE_ATBWAPAUI
	TRACE_FUNCTION("ATB_wap_card_go_back");
#endif

	parameter.object_id = View->object_id;
	parameter.browse_command = WAP_CARD_GO_BACK;
	M_MMI_WAP_BROWSE_CONTROL_IND(&parameter);

	return WAP_OK;
}


/*******************************************************************************

 $Function:    	ATB_wap_card_key_event

 $Description:	Requests the WAP browser react to a key event, up/down etc.

 $Returns:		WAP_OK if successful, WAP_FAIL if otherwise

 $Arguments:	View - the current view
 				keyType - the type of key selected

*******************************************************************************/

T_WAP_RES ATB_wap_card_key_event(T_WAP_VIEW *View, WAP_CONTROL_TYPES keyType)
{
	T_MMI_WAP_BROWSE_CONTROL_IND	command;
	T_MMI_WAP_DRAW_CARD_REQ			current_card;

#ifdef TRACE_ATBWAPAUI
	TRACE_FUNCTION("ATB_wap_card_key_event");
#endif

#ifdef FF_GPF_TCPIP
	// xreddymn Jun-28-2005 MMI-SPR-32467	
	ATB_animated_GIF_clear();
#endif

	command.object_id = View->object_id;
	command.browse_command = keyType;
	M_MMI_WAP_BROWSE_CONTROL_IND(&command);

	/* For select, need to redraw card in order to update changed elements */

	if (keyType == WAP_KEY_SELECT)
	{
		current_card.object_id = View->object_id;
		M_MMI_WAP_DRAW_CARD_REQ(&current_card);
	}

	return WAP_OK;
}


/*******************************************************************************

 $Function:    	ATB_wap_key_selected

 $Description:	Send the id of the selected WAP key to the AUS browser.

 $Returns:		WAP_OK if successful, WAP_FAIL if otherwise

 $Arguments:	View - the current view
 				keyId - Key identifier

*******************************************************************************/

T_WAP_RES ATB_wap_key_selected(T_WAP_VIEW *View, USHORT keyId)
{

	T_MMI_WAP_KEY_SELECTED_IND parameter;

#ifdef TRACE_ATBWAPAUI
	TRACE_FUNCTION("ATB_wap_key_selected");
#endif

	parameter.object_id = View->object_id;
	parameter.keyId = keyId;
	M_MMI_WAP_KEY_SELECTED_IND(&parameter);

	return WAP_OK;
}


/*******************************************************************************

 $Function:    	ATB_wap_card scroll

 $Description:	Scroll to a y position on the current card

 $Returns:		WAP_OK if successful, WAP_FAIL if otherwise

 $Arguments:	View - the current view
 				scrollPos - Y position on card to which to scroll

*******************************************************************************/

T_WAP_RES ATB_wap_card_scroll(T_WAP_VIEW *View, SHORT scrollPos)
{
	T_MMI_WAP_BROWSE_CONTROL_IND	parameter;

	/* Make sure the scroll destination is on the card */

	if (scrollPos > (View->cardHeight-WAP_SCREEN_HEIGHT))
		scrollPos = View->cardHeight-WAP_SCREEN_HEIGHT;

	if (scrollPos<0)
		scrollPos = 0;

	/* Send the event */

	parameter.object_id = View->object_id;
	parameter.browse_command = WAP_KEY_SCROLL;
	parameter.browse_parameter = (USHORT)scrollPos;

	M_MMI_WAP_BROWSE_CONTROL_IND(&parameter);

	return WAP_OK;
}


/*******************************************************************************

 $Function:    	ATB_wap_input_dialog_closed

 $Description:	Provides the answer of an input dialog.

 $Returns:		WAP_OK if successful, WAP_FAIL if otherwise

 $Arguments:	parameter	- Dialog confirmation information

*******************************************************************************/

T_WAP_RES ATB_wap_input_dialog_closed(T_MMI_WAP_INPUT_DIALOG_CNF *parameter)
{
	T_MMI_WAP_DRAW_CARD_REQ current_card;

#ifdef TRACE_ATBWAPAUI
	TRACE_FUNCTION("ATB_wap_input_dialog_closed");
#endif

	M_MMI_WAP_INPUT_DIALOG_CNF(parameter);
	current_card.object_id = parameter->object_id;
	M_MMI_WAP_DRAW_CARD_REQ(&current_card);

	return WAP_OK;
}


/*******************************************************************************

 $Function:    	ATB_wap_password_dialog_closed

 $Description:	Provides the answer of a password dialog.

 $Returns:		WAP_OK if successful, WAP_FAIL if otherwise

 $Arguments:	parameter - Dialog confirmation information

*******************************************************************************/

T_WAP_RES ATB_wap_password_dialog_closed(T_MMI_WAP_PASSWORD_DIALOG_CNF *parameter)
{
#ifdef TRACE_ATBWAPAUI
	TRACE_FUNCTION("ATB_wap_password_dialog_closed");
#endif

	M_MMI_WAP_PASSWORD_DIALOG_CNF(parameter);

	return WAP_OK;
}


/*******************************************************************************

 $Function:    	ATB_wap_confirm_dialog_closed

 $Description:	Provides the answer of a confirmation dialog.

 $Returns:		WAP_OK if successful, WAP_FAIL if otherwise

 $Arguments:	parameter		- Dialog confirmation information

*******************************************************************************/

T_WAP_RES ATB_wap_confirm_dialog_closed(T_MMI_WAP_CONFIRM_DIALOG_CNF *parameter)
{
#ifdef TRACE_ATBWAPAUI
	TRACE_FUNCTION("ATB_wap_confirm_dialog_closed");
#endif

	M_MMI_WAP_CONFIRM_DIALOG_CNF(parameter);

	return WAP_OK;
}


/*******************************************************************************

 $Function:    	ATB_wap_info_dialog_closed

 $Description:	Provides the answer of an info dialog.

 $Returns:		WAP_OK if successful, WAP_FAIL if otherwise

 $Arguments:	parameter	- Dialog confirmation information

*******************************************************************************/

T_WAP_RES ATB_wap_info_dialog_closed(T_MMI_WAP_INFO_DIALOG_CNF *parameter)
{
#ifdef TRACE_ATBWAPAUI
	TRACE_FUNCTION("ATB_wap_info_dialog_closed");
#endif

	M_MMI_WAP_INFO_DIALOG_CNF(parameter);

	return WAP_OK;
}


/*******************************************************************************

 $Function:    	ATB_wap_options_menu_select

 $Description:	The AUI will notify to the WAP.ATB the id of the selected item

 $Returns:		WAP_OK if successful, WAP_FAIL if otherwise

 $Arguments:	View - the current view

*******************************************************************************/

T_WAP_RES ATB_wap_options_menu_select(T_WAP_VIEW *View)
{
#ifdef TRACE_ATBWAPAUI
	TRACE_FUNCTION("ATB_wap_options_menu_select");
#endif

	ATB_wap_card_key_event(View, WAP_KEY_SELECT);

	return WAP_OK;
}


/*******************************************************************************

 $Function:    	ATB_wap_buffer_add_element

 $Description:	Add a new element to the element chain

 $Returns:		Pointer to the element

 $Arguments:	SPR#1721 - SH - Modified parameters slightly
 				View - 	the current view
 				type - the type of element (text, fieldset, image)

*******************************************************************************/

T_WAP_ELEMENT * ATB_wap_buffer_add_element(T_WAP_VIEW *View, WAP_ELEMENT_TYPE type)
{
	T_WAP_ELEMENT	*Element;
	T_WAP_ELEMENT	*ElementIndex;
	static USHORT	elementCount = 0;

#ifdef TRACE_ATBWAPAUI
	TRACE_FUNCTION("ATB_wap_buffer_add_element");
#endif

	if (!View)
		return;

	/* Create the element */

	Element = (T_WAP_ELEMENT *)AUI_wap_memory_alloc(sizeof(T_WAP_ELEMENT));

	/* If it's the first element in the chain, it forms the element chain header */

	if (View->NewElementHeader == NULL)
	{
		View->NewElementHeader = Element;
		elementCount = 0;
	}

	/* Otherwise, find its place in the chain and add it */

	else
	{
		ElementIndex = View->NewElementHeader;
		while(ElementIndex->NextElement !=NULL)
			ElementIndex = ElementIndex->NextElement;
		ElementIndex->NextElement = Element;
	}

	Element->type		= type;
	Element->NextElement = NULL;

	elementCount++;

	return Element;
}

// xreddymn Jun-28-2005 MMI-SPR-32467
// Implementation for animated GIF image handling

#ifdef FF_GPF_TCPIP

// If value of WAP_MAX_ANIMATED_GIFS is changed, make sure
// that ATB_animated_GIF_image_CB_list is also updated and
// callbacks are added or removed as required.

#define WAP_MAX_ANIMATED_GIFS	8

// Structure that stores details about an animated GIF image
typedef struct
{
	T_WAP_MMI_SEND_IMAGE_IND	*image_ind;			// Pointer to image indication received from WAP adapter
	T_MFW_HND					timer_handle;		// Handle to timer created to animate the GIF image
	UBYTE						disposal;			// Disposal method for the current frame
	UBYTE						frame;				// Currently displayed frame number (1 to n_frames)
	UBYTE						n_frames;			// Total number of frames in the animation
	S16							x;
	S16							y;
	S16							width;
	S16							height;
	void 						*pGIFInfo;

} WAP_animated_GIF_image;

WAP_animated_GIF_image		WAP_animated_GIF_images[WAP_MAX_ANIMATED_GIFS];
S16 						n_WAP_animated_GIF_elements = 0;

#include "mfw_tim.h"
#include "mfw_win.h"

extern UBYTE wapmic_GIF_convert(void *pInfo, int frame, T_WAP_MMI_SEND_IMAGE_IND *input, T_WAP_MMI_SEND_IMAGE_IND *output, int *n_frames, UBYTE *delay, UBYTE *disposal);
extern void wapmic_GIF_close_decoder(void *data);
extern void *wapmic_GIF_open_decoder(void *data, int size);

extern T_MFW_HND AUI_wap_get_win(void);
extern void ATB_animated_GIF_image_CB (int index, T_MFW_EVENT event, MfwTim *tc);
extern U32 mfwCheckMemoryLeft(void);
extern U32 wapmicCheckMemoryLeft(void);
extern void AUI_wap_restore_background(S32 x1, S32 y1, S32 x2, S32 y2);

void WAP_FFS_log_message(char *s, int len);

/*******************************************************************************

 $Function:    	ATB_animated_GIF_image_X_CB

 $Description:	Callback functions to handle animated image timer expiries.

 $Returns:		None.

 $Arguments:	event = MFW event structure
 				tc = pointer to MFW timer element

*******************************************************************************/

void ATB_animated_GIF_image_0_CB (T_MFW_EVENT event, MfwTim *tc)
{
	ATB_animated_GIF_image_CB(0, event, tc);
}

void ATB_animated_GIF_image_1_CB (T_MFW_EVENT event, MfwTim *tc)
{
	ATB_animated_GIF_image_CB(1, event, tc);
}

void ATB_animated_GIF_image_2_CB (T_MFW_EVENT event, MfwTim *tc)
{
	ATB_animated_GIF_image_CB(2, event, tc);
}

void ATB_animated_GIF_image_3_CB (T_MFW_EVENT event, MfwTim *tc)
{
	ATB_animated_GIF_image_CB(3, event, tc);
}

void ATB_animated_GIF_image_4_CB (T_MFW_EVENT event, MfwTim *tc)
{
	ATB_animated_GIF_image_CB(4, event, tc);
}

void ATB_animated_GIF_image_5_CB (T_MFW_EVENT event, MfwTim *tc)
{
	ATB_animated_GIF_image_CB(5, event, tc);
}

void ATB_animated_GIF_image_6_CB (T_MFW_EVENT event, MfwTim *tc)
{
	ATB_animated_GIF_image_CB(6, event, tc);
}

void ATB_animated_GIF_image_7_CB (T_MFW_EVENT event, MfwTim *tc)
{
	ATB_animated_GIF_image_CB(7, event, tc);
}

// Array of callback functions
void (*ATB_animated_GIF_image_CB_list[WAP_MAX_ANIMATED_GIFS]) (T_MFW_EVENT event, MfwTim *tc) =
{
	ATB_animated_GIF_image_0_CB,
	ATB_animated_GIF_image_1_CB,
	ATB_animated_GIF_image_2_CB,
	ATB_animated_GIF_image_3_CB,
	ATB_animated_GIF_image_4_CB,
	ATB_animated_GIF_image_5_CB,
	ATB_animated_GIF_image_6_CB,
	ATB_animated_GIF_image_7_CB,
};

/*******************************************************************************

 $Function:    	ATB_animated_GIF_image_CB

 $Description:  Common callback function to handle animated image timer expiries.

 $Returns:      None.

 $Arguments:    index = When there is more than one animated GIF image being
                displayed, index is used to identify each image.
                event = MFW event structure
                tc = pointer to MFW timer element

*******************************************************************************/

void ATB_animated_GIF_image_CB (int index, T_MFW_EVENT event, MfwTim *tc)
{
	T_WAP_MMI_SEND_IMAGE_IND 	converted_image;
	UBYTE						delay;
	UBYTE						disposal;

	if(WAP_animated_GIF_images[index].frame == WAP_animated_GIF_images[index].n_frames)
	{
		WAP_animated_GIF_images[index].frame = 1;
	}
	else
	{
		WAP_animated_GIF_images[index].frame++;
	}
//	TRACE_EVENT_P1("\nATB_animated_GIF_image_CB, disposal = %d", WAP_animated_GIF_images[index].disposal);
	if((WAP_animated_GIF_images[index].disposal == 2) || (WAP_animated_GIF_images[index].disposal == 3))
	{
		AUI_wap_restore_background(WAP_animated_GIF_images[index].x,
			WAP_animated_GIF_images[index].y,
			WAP_animated_GIF_images[index].x + WAP_animated_GIF_images[index].width,
			WAP_animated_GIF_images[index].y + WAP_animated_GIF_images[index].height);
	}
	if(wapmic_GIF_convert(WAP_animated_GIF_images[index].pGIFInfo, WAP_animated_GIF_images[index].frame, WAP_animated_GIF_images[index].image_ind, &converted_image, NULL, &delay, &disposal))
	{
		WAP_animated_GIF_images[index].x = converted_image.pX + WAP_LEFT_BORDER;
		WAP_animated_GIF_images[index].y = converted_image.pY + WAP_TOP_BORDER;
		WAP_animated_GIF_images[index].width = converted_image.pWidth;
		WAP_animated_GIF_images[index].height = converted_image.pHeight;
		converted_image.bmpFormat = BMP_FORMAT_16BIT_LCD_COLOUR;
		if (ATB_wap_profile_setting(WAP_STATUS_SCALEIMAGES))						// Image is to be scaled
		{
			ATB_wap_buffer_image_scale((T_WAP_MMI_SEND_IMAGE_IND *)&converted_image);
		}
		else
		{
			ATB_wap_buffer_image_display((T_WAP_MMI_SEND_IMAGE_IND *)&converted_image);
		}
		micFree(converted_image.Image);
		WAP_animated_GIF_images[index].disposal = disposal;
		timSetTime(WAP_animated_GIF_images[index].timer_handle, delay * 10);
		timStart(WAP_animated_GIF_images[index].timer_handle);
	}
	else
	{
		timStop(WAP_animated_GIF_images[n_WAP_animated_GIF_elements].timer_handle);
		timDelete(WAP_animated_GIF_images[n_WAP_animated_GIF_elements].timer_handle);
	}
}

/*******************************************************************************

 $Function:    	ATB_animated_GIF_clear

 $Description:  Stops all animating images, image data is not released by this
                function. Image data is released when LEa_freeObject is called
                by the browser.

 $Returns:      None.

 $Arguments:    None.

*******************************************************************************/

void ATB_animated_GIF_clear(void)
{
	S16 i;
	for(i = 0; i < n_WAP_animated_GIF_elements; i++)
	{
		timStop(WAP_animated_GIF_images[i].timer_handle);
		timDelete(WAP_animated_GIF_images[i].timer_handle);
		wapmic_GIF_close_decoder(WAP_animated_GIF_images[i].pGIFInfo);
	}
	n_WAP_animated_GIF_elements = 0;
}

/*******************************************************************************

 $Function:    	ATB_animate_GIF_image

 $Description:  Called after displaying the first frame of a GIF image, this
                function will start a timer to animate the image. It also adds
                the image details to the WAP_animated_GIF_images array.

 $Returns:      None.

 $Arguments:    image_ind = Image indication containing details of the input
                            GIF image
                delay = duration after which the first frame must be removed
                disposal = disposal method to use for the first frame
                n_frames = Total number of frames (this is obtained when
                           the first frame is decoded)

*******************************************************************************/

void ATB_animate_GIF_image(void *pGIFInfo, S16 x, S16 y, S16 width, S16 height, T_WAP_MMI_SEND_IMAGE_IND *image_ind, UBYTE delay, UBYTE disposal, UBYTE n_frames)
{
	T_MFW_HND wap_win;
	S16 i;

	for(i = 0; i < n_WAP_animated_GIF_elements; i++)
	{
		if(WAP_animated_GIF_images[i].image_ind == image_ind)
		{
			return;
		}
	}
	wap_win=AUI_wap_get_win();//mfwParent(mfwHeader());
	if(!wap_win) return;
	if(n_WAP_animated_GIF_elements < (WAP_MAX_ANIMATED_GIFS-1))
	{
		WAP_animated_GIF_images[n_WAP_animated_GIF_elements].timer_handle = timCreate(wap_win, delay * 10, (MfwCb)ATB_animated_GIF_image_CB_list[n_WAP_animated_GIF_elements]);
		if(WAP_animated_GIF_images[n_WAP_animated_GIF_elements].timer_handle)
		{
			WAP_animated_GIF_images[n_WAP_animated_GIF_elements].pGIFInfo = pGIFInfo;
			WAP_animated_GIF_images[n_WAP_animated_GIF_elements].image_ind = image_ind;
			WAP_animated_GIF_images[n_WAP_animated_GIF_elements].disposal = disposal;
			WAP_animated_GIF_images[n_WAP_animated_GIF_elements].frame = 1;
			WAP_animated_GIF_images[n_WAP_animated_GIF_elements].n_frames = n_frames;
			WAP_animated_GIF_images[n_WAP_animated_GIF_elements].x=x+WAP_LEFT_BORDER;
			WAP_animated_GIF_images[n_WAP_animated_GIF_elements].y=y+WAP_TOP_BORDER;
			WAP_animated_GIF_images[n_WAP_animated_GIF_elements].width=width;
			WAP_animated_GIF_images[n_WAP_animated_GIF_elements].height=height;
			timStart(WAP_animated_GIF_images[n_WAP_animated_GIF_elements].timer_handle);
			n_WAP_animated_GIF_elements++;
		}
	}
}

#endif // FF_GPF_TCPIP

/*******************************************************************************

 $Function:    	ATB_wap_buffer_display

 $Description:	Displays the card from the buffer

 $Returns:		None.

 $Arguments:	View - the current view

*******************************************************************************/

void ATB_wap_buffer_display(T_WAP_VIEW *View)
{
	T_WAP_ELEMENT				*Element		= View->ElementHeader;
	USHORT						elementCount	= 0;		/* No. of element */
	SHORT						titleX;						/* Position of title to centre it */
	SHORT						titleWidth;					/* Width of the title in pixels */
	double						doubleTemp;					/* Temporary double value */
	SHORT						scrollBarSize;				/* Size of scroll bar in pixels */
	SHORT						scrollBarPos;				/* Y position of top of scroll bar */
	SHORT						lineX;						/* First X position of line */
	SHORT						lineY;						/* First Y position of line */
	USHORT						*temp;						/* Temporary storage for text strings */
	UBYTE						scrollIndex;				/* For drawing scrollbar */
	USHORT						titleLen;					/* Length of title */

#ifdef FF_GPF_TCPIP
	// xreddymn Jun-28-2005 MMI-SPR-32467
	T_WAP_MMI_SEND_IMAGE_IND 	*image_ind;
	T_WAP_MMI_SEND_IMAGE_IND 	converted_image;
	UBYTE						delay;
	UBYTE						disposal;
	int							n_frames;
	SHORT						dx, dy;
#endif // FF_GPF_TCPIP

#ifdef TRACE_ATBWAPAUI
	TRACE_FUNCTION("ATB_wap_buffer_display");
#endif

#ifdef FF_GPF_TCPIP
	// xreddymn Jun-28-2005 MMI-SPR-32467
	ATB_animated_GIF_clear();
#endif // FF_GPF_TCPIP

	/* Display the title of the card, centred, over the line */

	temp = (USHORT *)AUI_wap_memory_alloc((CARD_TITLE_MAX_LEN+1)*sizeof(USHORT));
	/* SPR#1816 - SH - Obtain card title in MMI unicode */

	if (ATB_wap_status_get(View, ATB_WAP_DOWNLOADING))
	{
		/* Card is downloading */
		titleLen = AUI_wap_stringID(temp, CARD_TITLE_MAX_LEN, WAP_STRING_DOWNLOADING);
	}
	else if (ATB_wap_status_get(View, ATB_WAP_CARD_READING))
	{
		/* Card is updating */
		titleLen = AUI_wap_stringID(temp, CARD_TITLE_MAX_LEN, WAP_STRING_UPDATING);
	}
	else
	{
		/* Normal card title */
		titleLen = ATB_uc_text_copy(temp, View->Title, CARD_TITLE_MAX_LEN);
	}

	titleWidth = ATB_uc_text_width(temp, titleLen);		/* Width of the title */
	titleX = (WAP_TOTAL_WIDTH - titleWidth)/2;			/* Position of title to centre it */
	dspl_TextOut(titleX,0,DSPL_TXTATTR_SIGNED_COORDS | DSPL_TXTATTR_UNICODE, (char *)temp);

	AUI_wap_memory_free((UBYTE *)temp, (CARD_TITLE_MAX_LEN+1)*sizeof(USHORT));

	/* Horizontal scroll bar and top line */

	dspl_DrawLine(titleX-2, WAP_TOP_BORDER/2, 0, WAP_TOP_BORDER/2);	  /* Line to left of title */
	dspl_DrawLine(WAP_TOTAL_WIDTH-titleX+1, WAP_TOP_BORDER/2,
		WAP_TOTAL_WIDTH-WAP_VSCROLLBAR_WIDTH, WAP_TOP_BORDER/2);		/* Line to right of title */

	if (View->cardWidth>WAP_SCREEN_WIDTH)
	{
		doubleTemp = WAP_HSCROLLBAR_WIDTH*(double)WAP_SCREEN_WIDTH/(double)View->cardWidth;
		scrollBarSize = (SHORT)(doubleTemp+0.5);			/* Round to nearest int */
		if (scrollBarSize>WAP_HSCROLLBAR_WIDTH)
			scrollBarSize = WAP_HSCROLLBAR_WIDTH;

		doubleTemp = WAP_HSCROLLBAR_WIDTH*(double)View->cardXPosition/(double)View->cardWidth;
		scrollBarPos = (SHORT)(doubleTemp+0.5);				/* Round to nearest int */

		for (scrollIndex=0; scrollIndex<scrollBarSize; scrollIndex++)
		{
			dspl_DrawLine(scrollBarPos+scrollIndex, 0,
				scrollBarPos+scrollIndex, WAP_TOP_BORDER/2);
		}

		if (WAP_HSCROLLBAR_WIDTH<(titleX-1))
			dspl_DrawLine( WAP_HSCROLLBAR_WIDTH, 0, WAP_HSCROLLBAR_WIDTH, WAP_TOP_BORDER/2);
	}
#ifdef FF_GPF_TCPIP
        //xrashmic 21 Jan, 2005 MMI-SPR-28223
       pluginImageDisplayed=FALSE;
#endif
	/* Display the elements of the card one by one */
	while (Element!=NULL)
	{
		switch(Element->type)
		{
			case WAP_TEXT:
				/* Text Element */
				ATB_wap_buffer_text_draw((T_WAP_MMI_SEND_TEXT_IND *)Element->data);
				break;

			
//kyle 29 Jun, 2005 MMI-SPR-32462
			case WAP_BORDER:
				#ifdef FF_GPF_TCPIP
				ATB_wap_buffer_border_draw((T_WAP_MMI_DRAW_BORDER_IND *)Element->data);
				#endif
				break;

			
			case WAP_TABLE:
				/* Table/Fieldset element */
				ATB_wap_buffer_table_draw((T_WAP_MMI_SEND_TABLE_IND *)Element->data);
				break;
			case WAP_IMAGE:
				/* Image element */
#ifdef FF_GPF_TCPIP
                     case WAP_PLUGIN_IMAGE://xrashmic 21 Jan, 2005 MMI-SPR-28223
                       //xrashmic 21 Jan, 2005 MMI-SPR-28223
                       //When there is a plugin image, we disable scroll. Storing this info in pluginImageDisplayed
                            if(Element->type==WAP_IMAGE)
                                pluginImageDisplayed=FALSE;
                            else
                                pluginImageDisplayed=TRUE;
#endif
			// xreddymn Jun-28-2005 MMI-SPR-32467: Handling of GIF images
#ifdef FF_GPF_TCPIP
			image_ind = Element->data;
			if(!image_ind) break;
			if((image_ind->image_length > 2) && (strncmp((char*)image_ind->Image, "GIF", 3) == 0))
			{
				void *pGIFInfo;

				converted_image = *image_ind;
				pGIFInfo = wapmic_GIF_open_decoder(image_ind->Image, image_ind->image_length); 
				if(wapmic_GIF_convert(pGIFInfo, 1, image_ind, &converted_image, &n_frames, &delay, &disposal))
				{
					// TRACE_EVENT_P2("GIF image converted (%d, %d)",converted_image.pWidth, converted_image.pHeight);
					// TRACE_EVENT_P3("GIF frames=%d, delay=%d, disposal=%d",n_frames, delay, disposal);
//					TRACE_EVENT_P1("GIF URL = %s", wapmic_image_URL(image_ind->ImageReq));
					converted_image.bmpFormat = BMP_FORMAT_16BIT_LCD_COLOUR;
					if (ATB_wap_profile_setting(WAP_STATUS_SCALEIMAGES))						// Image is to be scaled
					{
						ATB_wap_buffer_image_scale((T_WAP_MMI_SEND_IMAGE_IND *)&converted_image);
					}
					else
					{
						ATB_wap_buffer_image_display((T_WAP_MMI_SEND_IMAGE_IND *)&converted_image);
					}
					micFree(converted_image.Image);
					if(n_frames > 1)
					{
						if((converted_image.pX >= 0) && 
						((converted_image.pX + converted_image.pWidth - 1) < (WAP_LEFT_BORDER + WAP_SCREEN_WIDTH - 1)) &&
						(converted_image.pY >= 0) &&
						((converted_image.pY + converted_image.pHeight - 1) < (WAP_TOP_BORDER + WAP_SCREEN_HEIGHT - 1)))
					{
							ATB_animate_GIF_image(pGIFInfo, converted_image.pX, converted_image.pY, converted_image.pWidth, converted_image.pHeight, 
								image_ind, delay, disposal, n_frames);
						}
						else if(image_ind->pluginImage)
						{
							ATB_animate_GIF_image(pGIFInfo, converted_image.pX, converted_image.pY, converted_image.pWidth, converted_image.pHeight, 
								image_ind, delay, disposal, n_frames);
						}
					}
                                  // Sep 06 2005  REF:  MMI-SPR-34048  x0012849
                                  //The ? symbol is appeared for pictures with single frame because decoder is not closed at all  and after
                                  // few instances of deocder are opened, trying to open further will result in memory error.
				      // To avoid this close the decoder each time its opened
					else  
					{
					   wapmic_GIF_close_decoder(pGIFInfo);
					}
				}
				else
				{
					USHORT elementX1, elementY1, elementX2, elementY2;
					elementX1 = (USHORT)image_ind->pX+WAP_LEFT_BORDER;
					elementY1 = (USHORT)image_ind->pY+WAP_TOP_BORDER;
					if(image_ind->pWidth < 14)
					{
						elementX2 = (USHORT)14 + elementX1 - 1;
					}
					else
					{
						elementX2 = (USHORT)image_ind->pWidth + elementX1 - 1;
					}
					if(image_ind->pHeight < 14)
					{
						elementY2 = (USHORT)14 + elementY1 - 1;
					}
					else
					{
						elementY2 = (USHORT)image_ind->pHeight + elementY1 - 1;
					}
					dspl_DrawRect(elementX1,elementY1, elementX2, elementY2);
					dspl_TextOut(elementX1 + 6, elementY1 + 0, DSPL_TXTATTR_SIGNED_COORDS, "?");
				}
			}
			else
#endif // FF_GPF_TCPIP
			{
#ifdef FF_GPF_TCPIP
				((T_WAP_MMI_SEND_IMAGE_IND *)Element->data)->transparency_flag = 0;
#endif
			#ifdef FF_GPF_TCPIP
				if (ATB_wap_profile_setting(WAP_STATUS_SCALEIMAGES))						// Image is to be scaled
			#else
				if (View->Status & WAP_STATUS_SCALEIMAGES)
			#endif
					ATB_wap_buffer_image_scale((T_WAP_MMI_SEND_IMAGE_IND *)Element->data);
				else
					ATB_wap_buffer_image_display((T_WAP_MMI_SEND_IMAGE_IND *)Element->data);
			}
			break;
		}
		elementCount++;
		Element = Element->NextElement;		/* Find the next element */
	}

	/* Vertical scroll bar and right frame */

	scrollBarSize = WAP_SCREEN_HEIGHT*WAP_SCREEN_HEIGHT/View->cardHeight;
	if (scrollBarSize>WAP_SCREEN_HEIGHT)
		scrollBarSize = WAP_SCREEN_HEIGHT;

	scrollBarPos = WAP_SCREEN_HEIGHT*View->cardYPosition/View->cardHeight;

	dspl_DrawLine(WAP_TOTAL_WIDTH-WAP_VSCROLLBAR_WIDTH, WAP_TOP_BORDER/2,
		WAP_TOTAL_WIDTH-WAP_VSCROLLBAR_WIDTH, WAP_SCREEN_BOTTOM);			/* Line to top of bar */

	for (scrollIndex=1; scrollIndex<WAP_VSCROLLBAR_WIDTH; scrollIndex++)
	{
		dspl_DrawLine(WAP_TOTAL_WIDTH-WAP_VSCROLLBAR_WIDTH+scrollIndex, scrollBarPos+WAP_TOP_BORDER,
			WAP_TOTAL_WIDTH-WAP_VSCROLLBAR_WIDTH+scrollIndex, scrollBarPos+WAP_TOP_BORDER+scrollBarSize);
	}

	return;
}


/*******************************************************************************

 $Function:    	ATB_wap_buffer_text_draw

 $Description:	Draws text

 $Returns:		None.

 $Arguments:	parameter	- the send text event

*******************************************************************************/

static void ATB_wap_buffer_text_draw(T_WAP_MMI_SEND_TEXT_IND *parameter)
{
	USHORT	*temp;			/* SPR#1816 - SH - Unicode string storage */
	SHORT	elementX;		/* X position of element on-screen */
	SHORT	elementY;		/* Y position of element on-screen */
	USHORT	textWidth;		/* Width of text to draw */
	USHORT textLength;		/* SPR#1816 - SH - Length of text */

	textWidth = parameter->pWidth;
	if ((textWidth + parameter->pX)>WAP_SCREEN_WIDTH)		/* if text goes off the screen, */
		textWidth = WAP_SCREEN_WIDTH-parameter->pX;			/* cut it down to size */

	elementX = (USHORT)parameter->pX+WAP_LEFT_BORDER;		/* Absolute position of text */
	elementY = (USHORT)parameter->pY+WAP_TOP_BORDER;		/* on screen */

	/* Draw special text features */

	switch(parameter->type)
	{
		case WAP_TEXT_OPTION:
                       // Apr 28 2005  REF:  MMI-SPR-30400 x0012849
                       // To see that box aligns with the text.
                       #ifdef FF_GPF_TCPIP
  			    elementY+=OFFSET_CHECKBOX; 
			  #endif		   
			/* An options menu item - draw checkbox */
			dspl_DrawRect(elementX,
				elementY+WAP_CHECKBOX_TOP, \
				elementX+WAP_CHECKBOX_WIDTH-1, \
				elementY+WAP_CHECKBOX_TOP+WAP_CHECKBOX_HEIGHT-1);

			/* Draw check if item is selected */

			if (parameter->selected)
			{
				dspl_DrawRect(elementX+WAP_CHECKBOX_INDENT, \
					elementY+WAP_CHECKBOX_TOP+WAP_CHECKBOX_INDENT, \
					elementX+WAP_CHECKBOX_WIDTH-1-WAP_CHECKBOX_INDENT, \
					elementY+WAP_CHECKBOX_TOP+WAP_CHECKBOX_HEIGHT-1-WAP_CHECKBOX_INDENT);
			}

			/* Shift text to right to make space for checkbox */

			elementX += (WAP_CHECKBOX_WIDTH+WAP_CHECKBOX_RIGHT);
			textWidth -= (WAP_CHECKBOX_WIDTH+WAP_CHECKBOX_RIGHT);
                     // Apr 28 2005  REF:  MMI-SPR-30400 x0012849
                     // To see that box aligns with the text.
                     #ifdef FF_GPF_TCPIP
          		  elementY-=OFFSET_CHECKBOX;
			#endif		 
			break;

		case WAP_TEXT_OPTIONGROUP:
			/* Option group titles are currently not distinguished from normal text */
			break;
	}

	/* SPR#1816 - SH - Allocate memory for unicode string */

	temp = (USHORT *)AUI_wap_memory_alloc((parameter->text_length+1)*sizeof(USHORT));

	/* SPR#1816 - SH - Copy text and convert to MMI unicode */

	ATB_uc_text_copy(temp, parameter->Text, (USHORT)parameter->text_length);
	ATB_uc_text_convert(temp, (USHORT)parameter->text_length);		/* SPR#1816 - SH - Swap bytes of unicode */

	/* SPR#1816 - SH - Crop text to fit width */
      // Apr 28 2005  REF:  MMI-SPR-30400 x0012849
      // For the text of the Drop down menu , no need to crop the text, instead call 
      // ATB_uc_text_cut, which will return the text that will fit to the screen, otherwise scroll bar will be 
      // overwritten with the text.
       if(WAP_TEXT_OPTION == parameter->type )
	     textLength = ATB_uc_text_cut(temp, parameter->text_length, textWidth);		   	
	else		
	     textLength = ATB_uc_text_crop(temp, parameter->text_length, textWidth);	

	if (!parameter->invert)
		dspl_TextOut((USHORT)elementX,(USHORT)elementY,DSPL_TXTATTR_SIGNED_COORDS | DSPL_TXTATTR_UNICODE,(char*)temp);
	else
		dspl_TextOut((USHORT)elementX,(USHORT)elementY,DSPL_TXTATTR_INVERS | DSPL_TXTATTR_SIGNED_COORDS | DSPL_TXTATTR_UNICODE, (char*)temp);

	AUI_wap_memory_free((UBYTE *)temp, (parameter->text_length+1)*sizeof(USHORT));

	return;
}

/*******************************************************************************

 $Function:    	ATB_wap_buffer_border_draw

 $Description:	Draws border
                //kyle 29 Jun, 2005 MMI-SPR-32462

 $Returns:		None.

 $Arguments:	

*******************************************************************************/
#ifdef FF_GPF_TCPIP
static void ATB_wap_buffer_border_draw(T_WAP_MMI_DRAW_BORDER_IND *parameter)
{

	LAYOUT_BORDER bottom, left, right, top;
		
#ifdef TRACE_ATBWAPAUI
	TRACE_FUNCTION("ATB_wap_buffer_border_draw");
#endif

	bottom = parameter->borderBottom;
	left = parameter->borderLeft;
	right = parameter->borderRight;
	top = parameter->borderTop;

	if (bottom.cssPropCode != CSS_VALUE_NONE)
	{
		bottom.pX += WAP_LEFT_BORDER;
		bottom.pY += WAP_TOP_BORDER;
		dspl_DrawFilledRect(bottom.pX, bottom.pY, bottom.pX + bottom.pWidth, bottom.pY + bottom.pHeight);		
	}

	if (left.cssPropCode != CSS_VALUE_NONE)
	{
		left.pX += WAP_LEFT_BORDER;
		left.pY += WAP_TOP_BORDER;
		dspl_DrawFilledRect(left.pX, left.pY, left.pX + left.pWidth, left.pY + left.pHeight);		
	}

	if (right.cssPropCode != CSS_VALUE_NONE)
	{
		right.pX += WAP_LEFT_BORDER;
		right.pY += WAP_TOP_BORDER;
		dspl_DrawFilledRect(right.pX, right.pY, right.pX + right.pWidth, right.pY + right.pHeight);		
	}

	if (top.cssPropCode != CSS_VALUE_NONE)
	{
		top.pX += WAP_LEFT_BORDER;
		top.pY += WAP_TOP_BORDER;
		dspl_DrawFilledRect(top.pX, top.pY, top.pX + top.pWidth, top.pY + top.pHeight);		
	}

	return;
}
#endif

/*******************************************************************************

 $Function:    	ATB_wap_buffer_table_draw

 $Description:	Draws a table, or a fieldset

 $Returns:		None.

 $Arguments:	parameter	- the send table event

*******************************************************************************/

static void ATB_wap_buffer_table_draw(T_WAP_MMI_SEND_TABLE_IND *parameter)
{
	SHORT	elementX	= parameter->pX+WAP_LEFT_BORDER;			/* Left edge position of table/fieldset */
	SHORT	elementY	= parameter->pY+WAP_TOP_BORDER;				/* Top edge position of table/fieldset */
	SHORT	top			= elementY+WAP_CHAR_HEIGHT/2;				/* Top of fieldset */
	SHORT	bottom		= elementY+parameter->pHeight-1; 			/* Bottom of table/fieldset */
	SHORT	right		= elementX+parameter->pWidth-1;				/* Right side of table/fieldset */
	SHORT	lineX;													/* X position of column line */
	SHORT	lineY;													/* Y position of row line */
	USHORT	*temp;													/* Temp storage for title. */
	USHORT	titleWidth;												/* Width of the title in pixels */
	USHORT titleLength;												/* Length of title */
	USHORT	index;													/* Index for columns and rows */

#ifdef TRACE_ATBWAPAUI
	TRACE_FUNCTION("ATB_wap_buffer_table_draw");
	TRACE_EVENT_P4( "Fieldset/table pX, pY, pWidth, pHeight: %d, %d, %d, %d",
		parameter->pX, parameter->pY, parameter->pWidth, parameter->pHeight);
#endif

	/* Convert title to MMI Unicode */

	temp = (USHORT *)AUI_wap_memory_alloc((parameter->title_length+1)*sizeof(USHORT));
	titleLength = parameter->title_length;
	ATB_uc_text_copy(temp, parameter->Title, titleLength);
	ATB_uc_text_convert(temp, titleLength);		/* Convert to MMI unicode */

	/* Crop title if it overshoots screen */

	if ((parameter->pX+gle_fieldset_spaceLeft+ATB_uc_text_width(temp, titleLength)) > WAP_SCREEN_WIDTH)
	{
		titleLength = ATB_uc_text_crop(temp, titleLength, WAP_SCREEN_WIDTH-parameter->pX-gle_fieldset_spaceLeft);
	}

	/* Crop title if it overshoots edge of fieldset */

	if ((gle_fieldset_spaceLeft+ATB_uc_text_width(temp, titleLength)+gle_fieldset_spaceRight) > parameter->pWidth)
	{
		titleLength = ATB_uc_text_crop(temp, titleLength, parameter->pWidth-gle_fieldset_spaceLeft-gle_fieldset_spaceRight);
	}

	titleWidth = ATB_uc_text_width(temp, titleLength);	/* Width of the title */

	/* Display title if it's onscreen */

	if (parameter->pY >= 0 && parameter->pY < WAP_TEXT_LOWEST)
	{
		dspl_TextOut(elementX+gle_fieldset_spaceLeft, elementY, DSPL_TXTATTR_SIGNED_COORDS | DSPL_TXTATTR_UNICODE, (char *)temp);
	}
	AUI_wap_memory_free((UBYTE *)temp, (parameter->title_length+1)*sizeof(USHORT));

	/* Horizontal lines */

	lineY = elementY+gle_cell_vBefore;
	ATB_wap_buffer_line_draw(elementX, bottom, right, bottom);	/* Bottom line of table */

	if (parameter->rows_length > 0)
		ATB_wap_buffer_line_draw(elementX, lineY, right, lineY);	/* Line under title */
	else
	{
		ATB_wap_buffer_line_draw(elementX+gle_fieldset_spaceLeft-2, top, elementX, top);     /* Line to left of title */
		ATB_wap_buffer_line_draw(elementX+gle_fieldset_spaceLeft+titleWidth+2, top, right, top);   /* right */
	}

	/* Row lines */

	if (parameter->rows_length > 1)
	{
		for (index=0; index<(parameter->rows_length-1); index++)
		{
			lineY += parameter->RowHeight[index]+gle_cell_spaceToBorder;
			ATB_wap_buffer_line_draw(elementX, lineY, right, lineY);
			lineY += gle_cell_borderExtent+gle_cell_spaceToBorder;
		}
	}

	/* Vertical lines */

	lineX = elementX+gle_cell_hBefore;

	if (parameter->rows_length == 0)
		lineY = top;												/* For fieldset */
	else
		lineY = elementY+gle_cell_vBefore;							/* For table */

	ATB_wap_buffer_line_draw(elementX, lineY, elementX, bottom);	/* Left hand line */

	/* Column lines */

	if (parameter->cols_length > 1)
	{
		for (index=0; index<(parameter->cols_length-1); index++)
		{
			lineX += parameter->ColWidth[index]+gle_cell_spaceToBorder;
			ATB_wap_buffer_line_draw(lineX, lineY, lineX, bottom);
			lineX += gle_cell_borderExtent+gle_cell_spaceToBorder;
		}
	}
	ATB_wap_buffer_line_draw(right, lineY, right, bottom);			/* Right hand line */

	return;
}


/*******************************************************************************

 $Function:    	ATB_wap_buffer_line_draw

 $Description:	Draws a line, making sure it fits on-screen

 $Returns:		None.

 $Arguments:	x1,y1 - Coordinates of the start of the line
 				x2,y2 - Coordinates of the end of the line

*******************************************************************************/

static void ATB_wap_buffer_line_draw(SHORT x1, SHORT y1, SHORT x2, SHORT y2)
{
	SHORT deltaX1;
	SHORT deltaY1;
	SHORT deltaX2;
	SHORT deltaY2;
	double m;

	ATB_wap_buffer_onscreen(x1,y1, &deltaX1, &deltaY1);
	ATB_wap_buffer_onscreen(x2,y2, &deltaX2, &deltaY2);

	if (x2==x1)
	{
		if (deltaX1)
			return;
		y1+=deltaY1;
		y2+=deltaY2;
	}
	else if (y2==y1)
	{
		if (deltaY1)
			return;
		x1+=deltaX1;
		x2+=deltaX2;
	}
	else
	{
		m = (y2-y1)/(x2-x1);
		if (deltaX1 || deltaY1)
		{
			x1 += deltaX1;
			y1 += m*deltaX1;
			if (!ATB_wap_buffer_onscreen(x1,y1,&deltaX1,&deltaY1))
				return;
		}
		if (deltaX2 || deltaY2)
		{
			x2 += deltaX2;
			y2 += m*deltaX2;
			if (!ATB_wap_buffer_onscreen(x2,y2,&deltaX2,&deltaY2))
				return;
		}
	}

	dspl_DrawLine(x1,y1,x2,y2);
	return;
}


/*******************************************************************************

 $Function:    	ATB_wap_buffer_onscreen

 $Description:	Returns TRUE if the point supplied is on-screen

 $Returns:		TRUE if point is onscreen

 $Arguments:	x,y - coordinates of the point
 				deltaX, deltaY - returns offset from screen

*******************************************************************************/

static BOOL ATB_wap_buffer_onscreen(SHORT x, SHORT y, SHORT *deltaX, SHORT *deltaY)
{
	BOOL outcome = TRUE;
	*deltaX = 0;
	*deltaY = 0;

	if (x<WAP_LEFT_BORDER)
	{
		outcome = FALSE;
		*deltaX = WAP_LEFT_BORDER-x;
	}
	if (x>(WAP_SCREEN_RIGHT-1))
	{
		outcome = FALSE;
		*deltaX = (WAP_SCREEN_RIGHT-1)-x;
	}
	if (y<WAP_TOP_BORDER)
	{
		outcome = FALSE;
		*deltaY = WAP_TOP_BORDER-y;
	}
	if (y>(WAP_SCREEN_BOTTOM-1))
	{
		outcome = FALSE;
		*deltaY = (WAP_SCREEN_BOTTOM-1)-y;
	}

	return outcome;
}


/*******************************************************************************

 $Function:    	ATB_wap_buffer_image_display

 $Description:	Trims an image to fit into the specified space, then displays it

 $Returns:		None.

 $Arguments:	image - the image to display

*******************************************************************************/

#ifdef FF_GPF_TCPIP
#define RGB16(r,g,b) (( ((b & 0xf8) >> 3) | ((g & 0xfc) << 3) | ((r & 0xf8) << 8) ))
#define RGB32(r,g,b) (( (r << 16) & 0x00FF0000) | ((g << 8) & 0x0000FF00) | ( b & 0x000000FF))
#endif

static void ATB_wap_buffer_image_display(T_WAP_MMI_SEND_IMAGE_IND *image)
{
	UBYTE *Region;								/* Pointer to trimmed image */
	SHORT offsetX = 0;							/* Offsets from origin of original image... */
	SHORT offsetY = 0;							/* ...where trimmed image starts */
	SHORT scrWidth = image->pWidth;				/* Width of trimmed image on screen */
	SHORT scrHeight = image->pHeight;			/* Height of trimmed image on screen */
	SHORT elementX;								/* Its x position on the screen */
	SHORT elementY;								/* Its y position on the screen */
	USHORT byteWidth;							/* Width of original in bytes */
	USHORT scrByteWidth;						/* Width of screen image in bytes */
	USHORT	offsetByteWidth;
	USHORT heightIndex;
	USHORT widthIndex;
	USHORT memIndex = 0;
	UBYTE *Image = image->Image;				/* The image data */
	UBYTE pixShift;								/* Pixel shift, shift bytes by this amount */

#ifdef TRACE_ATBWAPAUI
	TRACE_FUNCTION("ATB_wap_buffer_image_display");
#endif

	byteWidth = image->pWidth/8;
	if (image->pWidth % 8)
		byteWidth++;

	elementX = image->pX;
	elementY = image->pY;

	/* If image starts off the left of the screen */

	if (elementX < 0)
	{
		offsetX = -elementX;					/* Set the X offset so it is trimmed appropriately */
		scrWidth -= offsetX;					/* Change its width */
		elementX = 0;							/* And place it at the left of the screen */
	}

	/* If image starts above the top of the screen */

	if (image->pY < 0)
	{
		offsetY = -elementY;					/* Set the Y offset so it is trimmed appropriately */
		scrHeight -= offsetY;					/* Change its height */
		elementY = 0;							/* And place it at the top of the screen */
	}

	/* If the image goes off the right of the screen, reduce its width */

	if ((elementX+scrWidth)>WAP_SCREEN_WIDTH)
		scrWidth = WAP_SCREEN_WIDTH-elementX;

	/* If the image goes off the bottom of the screen, trim its height */

	if ((elementY+scrHeight)>WAP_SCREEN_HEIGHT)
		scrHeight = WAP_SCREEN_HEIGHT-elementY;

	scrByteWidth = scrWidth/8;	/* Work out the width of the trimmed image in bytes */
	if (scrWidth % 8)
		scrByteWidth++;

#ifdef FF_GPF_TCPIP

  if (image->bmpFormat == BMP_FORMAT_16BIT_LCD_COLOUR) {
	long ColorVal;
	UINT32 clr;
	unsigned char* p;
    int x, y;
#if 0
    for (x = 0; x < image->pWidth; x++) {
      for (y = 0; y < image->pHeight; y++) {
        p = (unsigned char*)(image->Image + ((y * image->pWidth + x) * 2));
		ColorVal = 256*(p[0]) + (p[1]);
		clr = RGB32( (((0xf800 & ColorVal)>>11) << 3), (((0x07e0 & ColorVal)>>5) << 2), ((0x1f & ColorVal) << 3) );
        scrPoint(image->pX + WAP_LEFT_BORDER + x, image->pY + WAP_TOP_BORDER + y, clr);
      }
    }
#else
	if((scrWidth > 0) && (scrHeight > 0))
	{
		int offset = (offsetY * image->pWidth + offsetX) << 1;
		int old_offset;
		UINT16 col16;
		UBYTE *data = image->Image;
		int imageX = image->pX;
		int imageY = image->pY;
		if(imageX < 0) imageX = 0;
		if(imageY < 0) imageY = 0;
		imageX += WAP_LEFT_BORDER;
		imageY += WAP_TOP_BORDER;
		if(image->transparency_flag)
		{
			for(y = 0; y < scrHeight; y++)
			{
				old_offset = offset;
				for(x = 0; x < scrWidth; x++)
				{
					col16 = data[offset++] << 8;
					col16 |= data[offset++];
					if(col16 != 0xAAAA)
					{
						clr = RGB32( (((0xf800 & col16)>>11) << 3), (((0x07e0 & col16)>>5) << 2), ((0x1f & col16) << 3) );
			        	scrPoint(imageX + x, imageY + y, clr);
			        }
				}
				offset = old_offset + (image->pWidth << 1);
			}
		}
		else
		{
			for(y = 0; y < scrHeight; y++)
			{
				old_offset = offset;
				for(x = 0; x < scrWidth; x++)
				{
					col16 = data[offset++] << 8;
					col16 |= data[offset++];
					clr = RGB32( (((0xf800 & col16)>>11) << 3), (((0x07e0 & col16)>>5) << 2), ((0x1f & col16) << 3) );
		        	scrPoint(imageX + x, imageY + y, clr);
				}
				offset = old_offset + (image->pWidth << 1);
			}
		}
	}
#endif
    // dspl_BitBlt2(image->pX + WAP_LEFT_BORDER, image->pY + WAP_TOP_BORDER, image->pWidth, image->pHeight, (void *)image->Image, 0, image->bmpFormat);
    return;
  }
  #endif
	/* Allocate memory for the trimmed image */

	Region = (UBYTE *)AUI_wap_memory_alloc(scrByteWidth*scrHeight);

	offsetByteWidth = offsetX/8;
	pixShift = offsetX % 8;			/* Offset within the byte of the first pixel */

	Image += (offsetY*byteWidth)+offsetByteWidth;	/* Point to the first byte of the region to be isolated */

	/* Copy the trimmed region of the image into our allocated memory,
	 * inverting it as necessary */

	for (heightIndex = 0; heightIndex<scrHeight; heightIndex++)
	{
		for (widthIndex = 0; widthIndex<scrByteWidth; widthIndex++)
		{
			Region[memIndex] = Image[widthIndex] << pixShift;
			if ((offsetByteWidth+scrByteWidth)<byteWidth || widthIndex<(scrByteWidth-1))
				Region[memIndex] |= Image[widthIndex+1] >> (8-pixShift);

			if (!image->invert)
				Region[memIndex] ^= 0xFF;	/* De-invert it if not selected */

			memIndex++;
		}
		Image += byteWidth;					/* Move down one line */
	}

#ifdef TRACE_ATBWAPAUI
	TRACE_EVENT_P2( "byteWidth: %d, scrByteWidth: %d", byteWidth, scrByteWidth);
	TRACE_EVENT_P4( "pX: %d, pY: %d, pWidth: %d, pHeight: %d", image->pX, image->pY, image->pWidth, image->pHeight);
	TRACE_EVENT_P4( "offsetX: %d, offsetY: %d, scrWidth: %d, scrHeight: %d", offsetX, offsetY, scrWidth, scrHeight);
	TRACE_EVENT_P2( "elementX: %d, elementY: %d", elementX, elementY);
	TRACE_EVENT_P2( "Region size: %d, should be: %d", memIndex, scrByteWidth*scrHeight);
#endif

	/* Display the image */

	dspl_BitBlt (elementX+WAP_LEFT_BORDER, elementY+WAP_TOP_BORDER, scrWidth, scrHeight, 0, (void *)Region, 0);

	/* Free the memory */

	AUI_wap_memory_free(Region, scrByteWidth*scrHeight);

	return;
}


/*******************************************************************************

 $Function:    	ATB_wap_buffer_image_scale

 $Description:	Scales an image to fit into a specified space

 $Returns:		None.

 $Arguments:	View - pointer to the appropriate view

*******************************************************************************/

static void ATB_wap_buffer_image_scale(T_WAP_MMI_SEND_IMAGE_IND *image)
{
	T_WAP_MMI_SEND_IMAGE_IND *Scaled = NULL;
	SHORT	newWidth;
	SHORT	newHeight;
	USHORT heightIndex;
	USHORT widthIndex;
	USHORT oldIndex;
	USHORT	newIndex;
	USHORT	byteWidth;
	USHORT	scrByteWidth;
	UBYTE	*Image = image->Image;
	UBYTE	oldMask;						/* Pixel shift, shift bytes by this amount */
	UBYTE	newMask;
	UBYTE	pixel;
	USHORT	xScale;
	USHORT	xScaleOld;
	USHORT	yScale;
	USHORT	yScaleOld;

#ifdef TRACE_ATBWAPAUI
	TRACE_FUNCTION("ATB_wap_buffer_image_scale");
#endif

#ifdef FF_GPF_TCPIP
  if (image->bmpFormat == BMP_FORMAT_16BIT_LCD_COLOUR) {
    ATB_wap_buffer_image_display(image);
    return;
  }
#endif
  Scaled = (T_WAP_MMI_SEND_IMAGE_IND *)AUI_wap_memory_alloc(sizeof(T_WAP_MMI_SEND_IMAGE_IND));																// Pointer to scaled image

	/* Squash to fit horizontally */

	if (image->pWidth > WAP_SCREEN_WIDTH)
		newWidth = WAP_SCREEN_WIDTH;
	else
		newWidth = image->pWidth;

	/* Squash to fit vertically */

	if (image->pHeight > WAP_SCREEN_HEIGHT)
		newHeight = WAP_SCREEN_HEIGHT;
	else
		newHeight = image->pHeight;

	/* Work out the width of the original image in bytes */

	byteWidth = image->pWidth/8;
	if (image->pWidth % 8)
		byteWidth++;

	/* Work out the width of the scaled image in bytes */
	scrByteWidth = newWidth/8;
	if (newWidth % 8)
		scrByteWidth++;

	/* Allocate memory for the scaled image */

	Scaled->Image = (UBYTE *)AUI_wap_memory_alloc(scrByteWidth*newHeight);

	oldIndex = -1;
	newIndex = -1;
	yScaleOld = 0;

	/* Scale the image */

	for (heightIndex = 0; heightIndex<image->pHeight; heightIndex++)
	{
		yScale = (USHORT) (heightIndex+1)*newHeight/image->pHeight;

		if (yScale != yScaleOld)
		{
			oldMask = 1;		/* Mask within the byte of the first pixel */
			newMask = 1;
			xScaleOld = 0;

			for (widthIndex = 0; widthIndex<image->pWidth; widthIndex++)
			{
				xScale = (USHORT) (widthIndex+1)*newWidth/image->pWidth;

				if (oldMask == 1)
				{
					oldMask = 128;
					oldIndex++;
				}
				else
					oldMask /= 2;

				if (xScale != xScaleOld)
				{
					if (newMask == 1)
					{
						newMask = 128;
						newIndex++;
						Scaled->Image[newIndex] = 0;
					}
					else
						newMask /= 2;

					if (Image[oldIndex] & oldMask)							/* If old pixel set, */
						Scaled->Image[newIndex] |= newMask;					/* set new pixel */
				}

				xScaleOld = xScale;
			}
		}
		else
		{
			oldIndex += byteWidth;
		}
		yScaleOld = yScale;
	}

#ifdef TRACE_ATBWAPAUI
	TRACE_EVENT_P2( "byteWidth: %d, scrByteWidth: %d", byteWidth, scrByteWidth);
	TRACE_EVENT_P4( "pX: %d, pY: %d, pWidth: %d, pHeight: %d",
		image->pX, image->pY, image->pWidth, image->pHeight);
	TRACE_EVENT_P2( "newWidth: %d, newHeight: %d", newWidth, newHeight);

#endif

	/* Display the image */

	Scaled->object_id = image->object_id;
	Scaled->image_length = scrByteWidth*newHeight;
	Scaled->invert = image->invert;
	Scaled->pX = image->pX;
	Scaled->pY = image->pY;
	Scaled->pWidth = newWidth;
	Scaled->pHeight = newHeight;
	Scaled->selected = image->selected;

	ATB_wap_buffer_image_display(Scaled);

	/* Free the memory */

	AUI_wap_memory_free(Scaled->Image, scrByteWidth*newHeight);
	AUI_wap_memory_free((UBYTE *)Scaled, sizeof(T_WAP_MMI_SEND_IMAGE_IND));

	return;
}


/*******************************************************************************

 $Function:    	ATB_wap_buffer_clear

 $Description:	Clears the element buffer

 $Returns:		None.

 $Arguments:	View - pointer to the appropriate view

*******************************************************************************/

void ATB_wap_buffer_clear(T_WAP_VIEW *View)
{
	T_WAP_ELEMENT					*Element	= View->ElementHeader;
	T_WAP_ELEMENT					*NextElement;
	T_WAP_MMI_SEND_TEXT_IND			*TextElement;
	T_WAP_MMI_SEND_TABLE_IND 		*TableElement;
	T_WAP_MMI_SEND_IMAGE_IND 		*ImageElement;
	USHORT 							elementCount = 0;

#ifdef TRACE_ATBWAPAUI
	TRACE_FUNCTION("ATB_wap_buffer_clear");
#endif

#ifdef FF_GPF_TCPIP
	// xreddymn Jun-28-2005 MMI-SPR-32467
	ATB_animated_GIF_clear();
#endif // FF_GPF_TCPIP

	while (Element != NULL)
	{
		switch (Element->type)
		{
			case WAP_TEXT:
				/* Delete a text element */
				TextElement = (T_WAP_MMI_SEND_TEXT_IND *)Element->data;
				if (TextElement->text_length != 0)
					AUI_wap_memory_free((UBYTE *)TextElement->Text, TextElement->text_length*sizeof(USHORT));
				if (TextElement->formatstring_length != 0)
				{
					AUI_wap_memory_free((UBYTE *)TextElement->Formatstring,
						TextElement->formatstring_length*sizeof(USHORT));
				}
				AUI_wap_memory_free((UBYTE *)TextElement, sizeof(T_WAP_MMI_SEND_TEXT_IND));
				break;

			case WAP_TABLE:
				/* Delete a table/fieldset element */
				TableElement = (T_WAP_MMI_SEND_TABLE_IND *)Element->data;
				if (TableElement->title_length != 0)
					AUI_wap_memory_free((UBYTE *)TableElement->Title, TableElement->title_length*sizeof(USHORT));
				if (TableElement->cols_length != 0)
					AUI_wap_memory_free((UBYTE *)TableElement->ColWidth, TableElement->cols_length*sizeof(SHORT));
				if (TableElement->rows_length != 0)
					AUI_wap_memory_free((UBYTE *)TableElement->RowHeight, TableElement->rows_length*sizeof(SHORT));
				AUI_wap_memory_free((UBYTE *)TableElement, sizeof(T_WAP_MMI_SEND_TABLE_IND));
				break;

			case WAP_IMAGE:
				/* Delete an image element */
				ImageElement = (T_WAP_MMI_SEND_IMAGE_IND *)Element->data;
				if (ImageElement->image_length != 0)
					AUI_wap_memory_free((UBYTE *)ImageElement->Image, ImageElement->image_length*sizeof(UBYTE));
				AUI_wap_memory_free((UBYTE *)ImageElement, sizeof(T_WAP_MMI_SEND_IMAGE_IND));
				break;
		}

		NextElement = Element->NextElement;
		AUI_wap_memory_free((UBYTE *)Element, sizeof(T_WAP_ELEMENT));
		Element = NextElement;
		elementCount++;
	}

	/* Element chain is now empty */

	View->ElementHeader = NULL;

	return;
}


/*******************************************************************************

 $Function:    	ATB_wap_buffer_identify_element

 $Description:	Identifies which element is selected (based on the invert property) and
 				returns an appropriate type.

 $Returns:		The type of the element that is selected, or NULL if none

 $Arguments:	View	- pointer to the view

*******************************************************************************/

UBYTE ATB_wap_buffer_identify_element(T_WAP_VIEW *View)
{
	T_WAP_ELEMENT				*Element	= View->ElementHeader;
	T_WAP_MMI_SEND_TEXT_IND		*TextElement;
	T_WAP_MMI_SEND_IMAGE_IND	*ImageElement;

#ifdef TRACE_ATBWAPAUI
	TRACE_FUNCTION("ATB_wap_buffer_identify_element");
#endif

	while (Element!=NULL)
	{
		switch (Element->type)
		{
			case WAP_TEXT:
				TextElement = (T_WAP_MMI_SEND_TEXT_IND *)Element->data;
				if (TextElement->invert)
				{
					return TextElement->type;
				}
				break;

			case WAP_IMAGE:
#ifdef FF_GPF_TCPIP
			case WAP_PLUGIN_IMAGE:
				//xrashmic 21 Jan, 2005 MMI-SPR-28223
				ImageElement = (T_WAP_MMI_SEND_IMAGE_IND *)Element->data;
                            //xrashmic 28 Jan, 2005 MMI-SPR-28166
                            //When the card contains the plugin Image, we need to send this
                            //indication, so that Save can be provided in the option menu
                                if(ImageElement->pluginImage)
                            {
                                  return WAP_PLUGINIMAGE;
                            }
				else if (ImageElement->invert)
				{
					return WAP_SELECTABLE_IMAGE;
				}
#else
				if (ImageElement->invert)
				{
					return WAP_SELECTABLE_IMAGE;
				}
#endif
				break;
		}
		Element = Element->NextElement;
	}

	/* Element not identified */

	return NULL;
}


/*******************************************************************************

 $Function:    	ATB_wap_profile_read

 $Description:	Reads in the specified profile and changes the ProfileId

 $Returns:		WAP_OK

 $Arguments:	View		- Pointer to the current view
 				ProfileId	- the id of the profile to read from the flash

*******************************************************************************/
#ifdef FF_GPF_TCPIP

T_WAP_RES ATB_wap_profile_read(T_WAP_VIEW *View, UBYTE ProfileId)
{
	T_WAP_VIEW		*ViewIndex;
	T_WAP_PROFILE	*Profile = &(WapProfilesData->Profile[ProfileId]);
#ifdef TRACE_ATBWAPAUI
	TRACE_FUNCTION("ATB_wap_profile_read");
#endif

	if (View_header==NULL || Profile==NULL)
	{
		return WAP_FAIL;
	}

	WapData->ProfileId = ProfileId;

	/* SPR#2086 - SH - Change the profile for all open views */

	ViewIndex = View_header;
	while (ViewIndex!=NULL)
	{
		ViewIndex->ProfileId = ProfileId;
		ViewIndex->Profile = Profile;
		/* Go to next view */
		ViewIndex = ViewIndex->NextView;
	}

	return WAP_OK;
}

#else /* #ifdef FF_GPF_TCPIP */

T_WAP_RES ATB_wap_profile_read(T_WAP_VIEW *View, UBYTE ProfileId)
{
	T_WAP_PROFILE	*Profile		= View->Profile;
	UBYTE 			entryIndex;
	char			*Entry;
	char			*URL;

#ifdef TRACE_ATBWAPAUI
	TRACE_FUNCTION("ATB_wap_profile_read");
#endif

	View->ProfileId	= ProfileId;
	View->Profile	= &(WapProfilesData->Profile[View->ProfileId]);

#ifndef GPRS
	/* SPR#2324 - SH - Ensure that all profiles are of dialup type if GPRS is off */
	if (View->Profile->AccessType==WAP_GPRS_DATA)
	{
		View->Profile->AccessType = WAP_CS_DATA;
	}
#endif

	return WAP_OK;
}

#endif /* !#ifdef FF_GPF_TCPIP */
/*******************************************************************************

 $Function:    	ATB_wap_profile_names_read

 $Description:	Reads into RAM the names of all profiles stored in flash, also
 				the global bookmarks and history lists

 $Returns:		WAP_OK

 $Arguments:	Profile		- Pointer to the current profile

*******************************************************************************/

T_WAP_RES ATB_wap_profile_names_read(T_WAP_VIEW *View)
{
	T_WAP_PROFILE	*Profile;
	T_WAP_LIST 		*ProfilesList	= View->ProfilesList;
	USHORT			no_of_bookmarks;
	T_WAP_LIST		*Bookmarks		= View->Bookmarks;
	T_WAP_LIST		*BookmarksURL	= View->BookmarksURL;
	USHORT			no_of_history;
	T_WAP_LIST		*History		= View->History;
	T_WAP_LIST		*HistoryURL		= View->HistoryURL;
	UBYTE			entryIndex;
	char			*Entry;
	char			*URL;
	UBYTE			no_of_profiles;

#ifdef TRACE_ATBWAPAUI
	TRACE_FUNCTION("ATB_wap_profile_names_read");
#endif

	/* SPR#2086 - SH - FFS files now read when view created.
	 * Read in number of profiles. */
#ifdef CO_UDP_IP
	/* Default values are provided.  If either of the files 'mmi/wapdata'
	 * or 'mmi/wapprof' aren't found, files is created with these defaults.
	 * The '0' size indicator indicates that one of the files was not present. */

	if (flash_wap_read() == 0)
	{
		ATB_wap_profile_default_create(FALSE); /* SPR#2324 */
	}

	View->Status 		= WapData->Status;		/* Status flags for settings */
	View->ProfileId		= WapData->ProfileId;	/* Default starting profile */

	/* Read in profiles list */
#endif


	no_of_profiles = WapData->no_of_profiles;
	ProfilesList->no_of_entries = no_of_profiles;
	/* Get list of profile names */

	for (entryIndex = 0; entryIndex<MAX_PROFILES; entryIndex++)
	{
		ProfilesList->Entry[entryIndex] = (char *)WapProfilesData->Profile[entryIndex].Title;
	}

	/* Read in bookmarks */

	no_of_bookmarks = WapData->no_of_bookmarks;
	Bookmarks->no_of_entries	= no_of_bookmarks;
	BookmarksURL->no_of_entries	= no_of_bookmarks;

	/* SPR#1816 - SH - Cast to char */

	for (entryIndex = 0; entryIndex<MAX_BOOKMARKS; entryIndex++)
	{
		Bookmarks->Entry[entryIndex] = (char *)WapData->Bookmarks[entryIndex];
		BookmarksURL->Entry[entryIndex] = WapData->BookmarksURL[entryIndex];
	}

	/* Read in history entries */

	no_of_history = WapData->no_of_history;
	History->no_of_entries 	= no_of_history;
	HistoryURL->no_of_entries  = no_of_history;

	for (entryIndex = 0; entryIndex<MAX_HISTORY; entryIndex++)
	{
		History->Entry[entryIndex] = (char *)WapData->History[entryIndex];
		HistoryURL->Entry[entryIndex] = WapData->HistoryURL[entryIndex];
	}

	return WAP_OK;
}


/*******************************************************************************

 $Function:    	ATB_wap_profile_save

 $Description:	Store the current updated profile in flash

 $Returns:		WAP_OK

 $Arguments:	View		- Pointer to the current view

*******************************************************************************/

#ifdef FF_GPF_TCPIP
T_WAP_RES ATB_wap_profile_save(T_WAP_VIEW *View)
{

#ifdef TRACE_ATBWAPAUI
	TRACE_FUNCTION("ATB_wap_profile_save");
#endif

	/* SPR#2086 - SH - Write bookmarks information only if this is
	 * a browser view */

	if (View->Bookmarks)
	{
		WapData->no_of_bookmarks = View->Bookmarks->no_of_entries;
	}
	if (View->History)
	{
		WapData->no_of_history = View->History->no_of_entries;
	}

    WapData->ProfileId = View->ProfileId;
     //xrashmic 16 Dec, 2004 MMI-SPR-27622
     // Save the total number of profiles to flash.
    WapData->no_of_profiles		= View->ProfilesList->no_of_entries;
	flash_wap_write();

	return WAP_OK;
}

/*******************************************************************************

 $Function:    	ATB_wap_profile_delete

 $Description:	Deletes a profile, and shifts other profiles up to fill the gap
 				 //xrashmic 16 Dec, 2004 MMI-SPR-27622
 
 $Returns:		WAP_OK if successful, WAP_FAIL if otherwise

 $Arguments:	View		- Pointer to the current view
 				ProfileId	- ID of the profile to delete
 
*******************************************************************************/

T_WAP_RES ATB_wap_profile_delete(T_WAP_VIEW *View, UBYTE ProfileId)
{
	UBYTE profileIndex;
	
#ifdef TRACE_ATBWAPAUI
	TRACE_FUNCTION("ATB_wap_profile_save");
#endif
	
	if (ProfileId >= View->ProfilesList->no_of_entries)
	{
		return WAP_FAIL;
	}

	View->ProfilesList->no_of_entries--;
	
	for (profileIndex = ProfileId; profileIndex < View->ProfilesList->no_of_entries; profileIndex++)
	{
		memcpy((void *)&WapProfilesData->Profile[profileIndex],
				(void *)&WapProfilesData->Profile[profileIndex+1],
				sizeof(T_WAP_PROFILE));
	}
	return WAP_OK;
}

#else /* #ifdef FF_GPF_TCPIP */

T_WAP_RES ATB_wap_profile_save(T_WAP_VIEW *View)
{

#ifdef TRACE_ATBWAPAUI
	TRACE_FUNCTION("ATB_wap_profile_save");
#endif

	WapData->ProfileId			= View->ProfileId;
	WapData->Status				= View->Status;
	WapData->no_of_bookmarks	= View->Bookmarks->no_of_entries;
	WapData->no_of_history		= View->History->no_of_entries;
	WapData->no_of_profiles		= View->ProfilesList->no_of_entries; /*SPR#2324 - SH - Save no. of profiles */
	flash_wap_write();

	return WAP_OK;
}

/*******************************************************************************

 $Function:    	ATB_wap_profile_delete

 $Description:	Deletes a profile, and shifts other profiles up to fill the gap
 				SPR#2324 - SH - Added

 $Returns:		WAP_OK if successful, WAP_FAIL if otherwise

 $Arguments:	View		- Pointer to the current view
 				ProfileId	- ID of the profile to delete

*******************************************************************************/

T_WAP_RES ATB_wap_profile_delete(T_WAP_VIEW *View, UBYTE ProfileId)
{
	UBYTE profileIndex;

#ifdef TRACE_ATBWAPAUI
	TRACE_FUNCTION("ATB_wap_profile_save");
#endif

	if (ProfileId >= View->ProfilesList->no_of_entries)
	{
		return WAP_FAIL;
	}

	View->ProfilesList->no_of_entries--;

	for (profileIndex = ProfileId; profileIndex < View->ProfilesList->no_of_entries; profileIndex++)
	{
		memcpy((void *)&WapProfilesData->Profile[profileIndex],
				(void *)&WapProfilesData->Profile[profileIndex+1],
				sizeof(T_WAP_PROFILE));
	}

	return WAP_OK;
}


#endif /* !#ifdef FF_GPF_TCPIP */



/*******************************************************************************

 $Function:    	ATB_wap_profile_default_create

 $Description:	Creates a default profile in the flash if one isn't already there
 				SPR#1794 - SH - There's now a third default profile.
				SPR#1816 - SH - Convert all defaults to MMI unicode
 $Returns:

 $Arguments:

*******************************************************************************/
#ifdef FF_GPF_TCPIP
//TISHMMS Project
T_WAP_RES ATB_wap_profile_default_create()
{
	UBYTE	no_of_bookmarks		= 9;
	char	*bookmarksList[] =
	{
		"ZgFg wml",
		"ZgFg html",
		"Google",
		"Yahoo!",
		"Financial Times",
		"Cnet tech news",
		"T-Mobile UK",
		"WEB.DE",
		"El Pais"
	};

	char 	*bookURLList[]	=
	{
		"http://wap.fgmicrotec.hr",
		"http://www.fgmicrotec.hr/test/dsample.htm",
		"http://wap.google.com",
		"http://wap.yahoo.com",
		"http://wap.ft.com",
		"http://wap.cnet.com",
		"http://wap.t-mobile.co.uk",
		"http://wap.web.de",
		"http://wap.elpais.es"
	};

	UBYTE	no_of_history		= 0;
	char	*historyList[]		= { "dummy" };
	char	*histURLList[]		= { "www.dummy.org" };

	UBYTE	no_of_profiles	= 8;
	char 	*profilesDefault[] 	= { "fg.vip.gprs", "vip.gprs", "fg.ht.gprs", "ht.gprs", "D1.gprs", "D2.gprs", "E-Plus.gprs", "O2.gprs", "Empty"};
	char	*homepageURL[]		= { "http://wap.fgmicrotec.hr",	"http://wap.vip.hr",	"http://wap.fgmicrotec.hr",	"http://wap.fgmicrotec.hr",	"http://wap.yahoo.com",	"http://wap.yahoo.com",		"http://wap.yahoo.com",	"http://wap.yahoo.com",	"http://wap.yahoo.com"};
	char	*IPAddress1[]			= { "217.014.220.081",			"212.091.099.091",		"217.014.220.081",			"010.012.000.003",			"193.254.160.002",			"139.007.029.001",				"212.023.097.009",			"195.182.114.052",			"000.000.000.000"};
	char	*IPAddress2[]			= { "217.014.220.081",			"212.091.099.091",		"217.014.220.081",			"000.000.000.000",			"193.254.160.002",			"139.007.029.001",				"212.023.097.009",			"195.182.114.052",			"000.000.000.000"};
	char	*DialupNumber[]		= { "00448704290000",			"00448704290000",	"00448704290000",		"00448704290000",		"17266",					"00491722290100",			"00448456609561",		"00448456609561",		""};
	char	*APN[]				= { "gprs5.vipnet.hr",			"gprs5.vipnet.hr",		"www.htgprs.hr",			"www.htgprs.hr",			"wap.t-d1.de",			"wap.vodafone.de",				"wap.eplus.de",			"wap.viaginterkom.de",	""};
	char	*Username[]			= { "38591",					"38591",				"",							"",							"t-d1",					"",								"eplus",				"",						""};
	char	*Password[]			= { "38591",					"38591",				"",							"",							"wap",					"",								"wap",					"",						""};
	UBYTE AccessType[]			= { WAP_GPRS_DATA, WAP_GPRS_DATA,	WAP_GPRS_DATA, WAP_GPRS_DATA, WAP_GPRS_DATA, WAP_GPRS_DATA, WAP_GPRS_DATA, WAP_GPRS_DATA, WAP_CS_DATA};
	UBYTE ConnectionSpeed[]	= { WAP_ISDN9600, 			WAP_ISDN9600, 		WAP_ISDN9600, 			WAP_ISDN9600, 			WAP_ISDN9600, 			WAP_ISDN9600, 				WAP_ISDN9600, 			WAP_ISDN9600,			WAP_ISDN9600};
	USHORT	ResponseTimer[]		= {60, 60, 60, 60, 60, 60, 60, 60, 60};
	USHORT	Port1[]				= {9201, 9201, 9201, 9201, 9201, 9201, 9201, 9201, 9201};
	USHORT	Port2[]				= {9201, 9201, 9201, 9201, 9201, 9201, 9201, 9201, 9201};
//xpradipg - Aug 4: Added the default values for the WAP2.0 Menu Items
//Need to confirm these default values

	char *NameServer1[]		= { "000.000.000.000",			"000.000.000.000",		"000.000.000.000",		"000.000.000.000",		"000.000.000.000",		"139.007.029.001",			"212.023.097.009",		"195.182.114.052",		"000.000.000.000"};
	char *NameServer2[]		= { "000.000.000.000",			"000.000.000.000",		"000.000.000.000",		"000.000.000.000",		"000.000.000.000",		"139.007.029.001",			"212.023.097.009",		"195.182.114.052",		"000.000.000.000"};
	BOOL PPGAuthentication[]	= {FALSE, FALSE, FALSE,FALSE,FALSE,FALSE,FALSE,FALSE};
	BOOL WirelessProfiledHTTP[]={ TRUE,TRUE, TRUE, TRUE, TRUE,TRUE, TRUE, TRUE};

/*
// Germany MMS settings from Tristan (?)
	UBYTE	no_of_profiles	= 4;
	char 	*profilesDefault[] 	= { "T-Mobile", "Vodafone", "E-Plus","O2"};
	char	*IPAddress1[]		= { "193.254.160.003", "139.007.029.017", "212.023.097.153", "195.182.114.052"};
	char	*IPAddress2[]		= { "000.000.000.000", "139.007.029.017", "212.023.097.153", "195.182.114.052"};
	char	*DialupNumber[]		= { "17266", "00447836900808", "00448456609561","00448456609561" };
	char	*APN[]				= { "mms.t-d1.de", "event.vodafone.de", "mms.eplus.de", "wap.viaginterkom.de"};
	char	*Username[]			= { "t-mobil", "", "mms", "" };
	char	*Password[]			= { "mms", "", "eplus", "" };
	UBYTE AccessType[]			= { WAP_GPRS_DATA, WAP_GPRS_DATA, WAP_GPRS_DATA, WAP_GPRS_DATA };
	UBYTE ConnectionSpeed[]		= { WAP_ISDN9600, WAP_ISDN9600, WAP_ISDN9600, WAP_ISDN9600};
	USHORT	ResponseTimer[]		= {180,60,120, 120};
	USHORT	Port1[]				= {9201,9201,9201, 9201};
	USHORT	Port2[]				= {9201,9201,9201, 9201};
// MMS settings from Tristan (?)
	UBYTE	no_of_profiles	= 3;
	char 	*profilesDefault[] 	= { "CNMobile", "Orange", "Magic4"};
	char	*homepageURL[]		= { "http://wap.yahoo.com", "http://plus.orangehk.com", "http://plus.orangehk.com"};
	char	*IPAddress1[]		= { "010.000.000.172", "010.030.003.151", "010.030.003.151"};
	char	*IPAddress2[]		= { "010.000.000.172", "010.030.003.151", "010.030.003.151"};
	char	*DialupNumber[]		= { "17266", "00447836900808", "00448456609561" };
	char	*APN[]				= { "CMWAP", "web.orangehk.com", "web.orangehk.com"};
	char	*Username[]			= { "WAP", "", "" };
	char	*Password[]			= { "WAP", "", "" };
	UBYTE AccessType[]			= { WAP_GPRS_DATA, WAP_GPRS_DATA, WAP_GPRS_DATA };	/* SPR#1189 - SH - Added
	UBYTE ConnectionSpeed[]		= { WAP_ISDN9600, WAP_ISDN14400, WAP_ISDN14400};/* SPR#1827 - SH - Default connection speed values
	USHORT	ResponseTimer[]		= {180,60,120};
	USHORT	Port1[]				= {9201,9201,9201};
	USHORT	Port2[]				= {9201,9201,9201};
*/

	USHORT entryIndex;
	USHORT	profile;
	char number[NUMBER_PADDING+1];	 /* SPR#1816 -SH */

#ifdef TRACE_ATBWAPAUI
	TRACE_FUNCTION("ATB_wap_profile_default_create");
#endif

	WapData->ProfileId		= 0;
	WapData->Status = WAP_STATUS_SAVEHISTORY | WAP_STATUS_SCALEIMAGES;

	/* Copy bookmarks into WapData structure */

	WapData->no_of_bookmarks = no_of_bookmarks;

	for (entryIndex = 0; entryIndex<no_of_bookmarks; entryIndex++)
	{
		ATB_char_to_uc(WapData->Bookmarks[entryIndex], bookmarksList[entryIndex]);
		strcpy(WapData->BookmarksURL[entryIndex], bookURLList[entryIndex]);
	}

	/* Copy history list into WapData structure */

	WapData->no_of_history = no_of_history;

	for (entryIndex = 0; entryIndex<no_of_history; entryIndex++)
	{
		sprintf(number,"%2d. ",entryIndex+1);			/* store number	*/
		ATB_char_to_uc(WapData->History[entryIndex], number);
		ATB_char_to_uc(&WapData->History[entryIndex][NUMBER_PADDING], historyList[entryIndex]);
		strcpy(WapData->HistoryURL[entryIndex], histURLList[entryIndex]);
	}

	/* Copy profile data into WapData and WapProfilesData structures */

	WapData->no_of_profiles    = no_of_profiles;

	for (profile = 0; profile<no_of_profiles; profile++)
	{
		ATB_char_to_uc(WapProfilesData->Profile[profile].Title, profilesDefault[profile]);
		strcpy(WapProfilesData->Profile[profile].Homepage, homepageURL[profile]);

		WapProfilesData->Profile[profile].ConnectionType = WAP_CONTINUOUS;
		WapProfilesData->Profile[profile].ConnectionSpeed = ConnectionSpeed[profile];  /* SPR#1827 - SH - Assign connection speed values */
		WapProfilesData->Profile[profile].Security	= FALSE;
		WapProfilesData->Profile[profile].AccessType     = AccessType[profile]; /* SPR#1189 - SH - Now correctly assigned*/
		WapProfilesData->Profile[profile].ResponseTimer  = ResponseTimer[profile];
		WapProfilesData->Profile[profile].Port1		= Port1[profile];
		WapProfilesData->Profile[profile].Port2		= Port2[profile];
		strcpy(WapProfilesData->Profile[profile].IPAddress1, IPAddress1[profile]);
		strcpy(WapProfilesData->Profile[profile].IPAddress2, IPAddress2[profile]);
		strcpy(WapProfilesData->Profile[profile].DialupNumber, DialupNumber[profile]);
		strcpy(WapProfilesData->Profile[profile].APN, APN[profile]);
		strcpy(WapProfilesData->Profile[profile].Username, Username[profile]);
		strcpy(WapProfilesData->Profile[profile].Password, Password[profile]);
//xpradipg - Aug 4: changes for the WAP2.0: Populating the default values

		strcpy(WapProfilesData->Profile[profile].NameServer1, NameServer1[profile]);
		strcpy(WapProfilesData->Profile[profile].NameServer2, NameServer2[profile]);
		WapProfilesData->Profile[profile].PPGAuthentication=PPGAuthentication[profile];
		WapProfilesData->Profile[profile].WirelessProfiledHTTP=WirelessProfiledHTTP[profile];

	}

	/* Write data to flash */

	if (flash_wap_write()==EFFS_OK)												// Make sure flash data is written OK
		return WAP_OK;
	else
		return WAP_FAIL;
}


void ATB_wap_profile_default(UBYTE ProfileId)
{
 char  *profilesDefault[]  = { "fg.vip.gprs", "vip.gprs", "fg.ht.gprs", "ht.gprs", "D1.gprs", "D2.gprs", "E-Plus.gprs", "O2.gprs", "Empty"};
 char *homepageURL[]  = { "http://wap.fgmicrotec.hr", "http://wap.vip.hr", "http://wap.fgmicrotec.hr", "http://wap.fgmicrotec.hr", "http://wap.yahoo.com", "http://wap.yahoo.com",  "http://wap.yahoo.com", "http://wap.yahoo.com", "http://wap.yahoo.com"};
 UBYTE ConnectionSpeed[] = { WAP_ISDN9600,    WAP_ISDN9600,   WAP_ISDN9600,    WAP_ISDN9600,    WAP_ISDN9600,    WAP_ISDN9600,     WAP_ISDN9600,    WAP_ISDN9600,   WAP_ISDN9600};

 UBYTE AccessType[]   = { WAP_GPRS_DATA, WAP_GPRS_DATA, WAP_GPRS_DATA, WAP_GPRS_DATA, WAP_GPRS_DATA, WAP_GPRS_DATA, WAP_GPRS_DATA, WAP_GPRS_DATA, WAP_CS_DATA};

 USHORT ResponseTimer[]  = {60, 60, 60, 60, 60, 60, 60, 60, 60};
 USHORT Port1[]    = {9201, 9201, 9201, 9201, 9201, 9201, 9201, 9201, 9201};
 USHORT Port2[]    = {9201, 9201, 9201, 9201, 9201, 9201, 9201, 9201, 9201};
 char *IPAddress1[]   = { "217.014.220.081",   "212.091.099.091",  "217.014.220.081",   "010.012.000.003",   "193.254.160.002",   "139.007.029.001",    "212.023.097.009",   "195.182.114.052",   "000.000.000.000"};
 char *IPAddress2[]   = { "217.014.220.081",   "212.091.099.091",  "217.014.220.081",   "000.000.000.000",   "193.254.160.002",   "139.007.029.001",    "212.023.097.009",   "195.182.114.052",   "000.000.000.000"};
 char *DialupNumber[]  = { "00448704290000",   "00448704290000", "00448704290000",  "00448704290000",  "17266",     "00491722290100",   "00448456609561",  "00448456609561",  ""};
 char *APN[]    = { "gprs5.vipnet.hr",   "gprs5.vipnet.hr",  "www.htgprs.hr",   "www.htgprs.hr",   "wap.t-d1.de",   "wap.vodafone.de",    "wap.eplus.de",   "wap.viaginterkom.de", ""};
 char *Username[]   = { "38591",     "38591",    "",       "",       "t-d1",     "",        "eplus",    "",      ""};
 char *Password[]   = { "38591",     "38591",    "",       "",       "wap",     "",        "wap",     "",      ""};

  ATB_char_to_uc(WapProfilesData->Profile[ProfileId].Title, profilesDefault[ProfileId]);
  strcpy(WapProfilesData->Profile[ProfileId].Homepage, homepageURL[ProfileId]);
   WapProfilesData->Profile[ProfileId].ConnectionType = WAP_CONTINUOUS;
  WapProfilesData->Profile[ProfileId].ConnectionSpeed = ConnectionSpeed[ProfileId];  /* SPR#1827 - SH - Assign connection speed values */
  WapProfilesData->Profile[ProfileId].Security = FALSE;
  WapProfilesData->Profile[ProfileId].AccessType     = AccessType[ProfileId]; /* SPR#1189 - SH - Now correctly assigned*/
  WapProfilesData->Profile[ProfileId].ResponseTimer  = ResponseTimer[ProfileId];
  WapProfilesData->Profile[ProfileId].Port1  = Port1[ProfileId];
  WapProfilesData->Profile[ProfileId].Port2  = Port2[ProfileId];
  strcpy(WapProfilesData->Profile[ProfileId].IPAddress1, IPAddress1[ProfileId]);
  strcpy(WapProfilesData->Profile[ProfileId].IPAddress2, IPAddress2[ProfileId]);
  strcpy(WapProfilesData->Profile[ProfileId].DialupNumber, DialupNumber[ProfileId]);
  strcpy(WapProfilesData->Profile[ProfileId].APN, APN[ProfileId]);
  strcpy(WapProfilesData->Profile[ProfileId].Username, Username[ProfileId]);
  strcpy(WapProfilesData->Profile[ProfileId].Password, Password[ProfileId]);
 return;

}


#else

T_WAP_RES ATB_wap_profile_default_create(UBYTE only_reset_profiles)
{
	UBYTE	no_of_bookmarks		= 10;
	char	*bookmarksList[] =
	{
		"Yahoo!",
		"AOL",
		"O2",
		"Financial Times",
		"Cnet tech news",
		"T-Mobile UK",
		"Ents24",
		"WEB.DE",
		"Vizzavi",
		"El Pais"
	};

	char 	*bookURLList[]	=
	{
		"http://wap.yahoo.com",
		"http://wap.aol.co.uk",
		"http://wap.o2.co.uk/",
		"http://wap.ft.com",
		"http://wap.cnet.com",
		"http://wap.t-mobile.co.uk",
		"http://wap.ents24.co.uk",
		"http://wap.web.de",
		"http://wap.vizzavi.co.uk",
		"http://wap.elpais.es"
	};

	UBYTE	no_of_history		= 0;
	char	*historyList[]		= { "dummy" };
	char	*histURLList[]		= { "www.dummy.org" };

/* SPR#2324 - SH
 * - Only need 3 profiles now, as extra ones can be added by user
 * - Only create first 2 if there's no GPRS */
#ifdef GPRS
	UBYTE	no_of_profiles	= 3;
#else
	UBYTE	no_of_profiles	= 2;
#endif

	char 	*profilesDefault[] 	= { "Breathe", "Vodaf.CSD", "Vodaf.GPRS", "Empty", "Empty"};
	char	*homepageURL[]		= { "http://wap.yahoo.com", "http://wap.yahoo.com", "http://wap.yahoo.com", "http://wap.yahoo.com", "http://wap.yahoo.com"};
	char	*IPAddress1[]		= { "062.024.128.014", "212.183.137.012", "212.183.137.012", "000.000.000.000", "000.000.000.000"};
	char	*IPAddress2[]		= { "062.024.128.014", "212.001.130.132", "212.001.130.132", "000.000.000.000", "000.000.000.000"};
	char	*DialupNumber[]		= { "00448704290000", "00447836900808", "00448456609561", "", "" };
	char	*APN[]				= { "none", "none", "wap.vodafone.co.uk", "", ""};
	char	*Username[]			= { "breathe", "user@vodafone.net", "user@vodafone.net", "", "" };
	char	*Password[]			= { "breathewap", "user", "user", "", ""};
	UBYTE AccessType[]			= { WAP_CS_DATA, WAP_CS_DATA, WAP_GPRS_DATA, WAP_CS_DATA, WAP_CS_DATA };

	/* SPR#2324 - SH - Some defaults moved to ATB_wap_profile_default */
	USHORT entryIndex;
	USHORT	profile;
	char number[NUMBER_PADDING+1];

#ifdef TRACE_ATBWAPAUI
	TRACE_FUNCTION("ATB_wap_profile_default_create");
#endif

	WapData->ProfileId		= 0;

	/* SPR#2324 - SH - If this flag is set, don't reset settings and bookmarks */

	if (!only_reset_profiles)
	{
		WapData->Status	= WAP_STATUS_SAVEHISTORY | WAP_STATUS_SCALEIMAGES;

		/* Copy bookmarks into WapData structure */

		WapData->no_of_bookmarks = no_of_bookmarks;

		for (entryIndex = 0; entryIndex<no_of_bookmarks; entryIndex++)
		{
			ATB_char_to_uc(WapData->Bookmarks[entryIndex], bookmarksList[entryIndex]);
			strcpy(WapData->BookmarksURL[entryIndex], bookURLList[entryIndex]);
		}

		/* Copy history list into WapData structure */

		WapData->no_of_history = no_of_history;

		for (entryIndex = 0; entryIndex<no_of_history; entryIndex++)
		{
			sprintf(number,"%2d. ",entryIndex+1);			/* store number	*/
			ATB_char_to_uc(WapData->History[entryIndex], number);
			ATB_char_to_uc(&WapData->History[entryIndex][NUMBER_PADDING], historyList[entryIndex]);
			strcpy(WapData->HistoryURL[entryIndex], histURLList[entryIndex]);
		}
	}

	/* Copy profile data into WapData and WapProfilesData structures */

	WapData->no_of_profiles    = no_of_profiles;

	for (profile = 0; profile<MAX_PROFILES; profile++)
	{
		/* SPR#2324 - SH - Set up "blank" profile first, then configure
		 * WAP gateway settings */

		ATB_wap_profile_default(profile);
		if (profile<no_of_profiles)
		{
			ATB_char_to_uc(WapProfilesData->Profile[profile].Title, profilesDefault[profile]);
			strcpy(WapProfilesData->Profile[profile].Homepage, homepageURL[profile]);
			WapProfilesData->Profile[profile].AccessType = AccessType[profile];
			strcpy(WapProfilesData->Profile[profile].IPAddress1, IPAddress1[profile]);
			strcpy(WapProfilesData->Profile[profile].IPAddress2, IPAddress2[profile]);
			strcpy(WapProfilesData->Profile[profile].DialupNumber, DialupNumber[profile]);
			strcpy(WapProfilesData->Profile[profile].APN, APN[profile]);
			strcpy(WapProfilesData->Profile[profile].Username, Username[profile]);
			strcpy(WapProfilesData->Profile[profile].Password, Password[profile]);
		}
	}

	/* Write data to flash */

	if (flash_wap_write()==EFFS_OK)		/* Make sure flash data is written OK */
		return WAP_OK;
	else
		return WAP_FAIL;
}

/*******************************************************************************

 $Function:    	ATB_wap_profile_default

 $Description:	Sends the configuration information of the current profile to the WAP task.
 				SPR#2324 - SH - Added

 $Returns:		None.

 $Arguments:	ProfileId - Profile identifier

*******************************************************************************/

void ATB_wap_profile_default(UBYTE ProfileId)
{
	AUI_wap_stringID(WapProfilesData->Profile[ProfileId].Title, CARD_TITLE_MAX_LEN, WAP_STRING_UNTITLED);
	strcpy(WapProfilesData->Profile[ProfileId].Homepage, "");
	WapProfilesData->Profile[ProfileId].ConnectionType = WAP_TEMPORARY;
	WapProfilesData->Profile[ProfileId].ConnectionSpeed = WAP_ANALOGUE;  /* SPR#1827 - SH - Assign connection speed values */
	WapProfilesData->Profile[ProfileId].Security	= FALSE;
	WapProfilesData->Profile[ProfileId].AccessType     = WAP_GPRS_DATA; /* SPR#1189 - SH - Now correctly assigned*/
	WapProfilesData->Profile[ProfileId].ResponseTimer  = WAP_DEFAULT_RESPONSE_TIME;
	WapProfilesData->Profile[ProfileId].Port1		= WAP_DEFAULT_PORT;
	WapProfilesData->Profile[ProfileId].Port2		= WAP_DEFAULT_PORT;
	strcpy(WapProfilesData->Profile[ProfileId].IPAddress1, "000.000.000.000");
	strcpy(WapProfilesData->Profile[ProfileId].IPAddress2, "000.000.000.000");
	strcpy(WapProfilesData->Profile[ProfileId].DialupNumber, "");
	strcpy(WapProfilesData->Profile[ProfileId].APN, "");
	strcpy(WapProfilesData->Profile[ProfileId].Username, "");
	strcpy(WapProfilesData->Profile[ProfileId].Password, "");

	return;
}

#endif

#if defined (FF_MMI_MMS) && defined (FF_GPF_TCPIP)
T_WAP_RES ATB_mms_profile_default_create()
{
	UBYTE	no_of_profiles	= 8;
	USHORT	profile;
	char		*MmscAddress[] = { "http://mms.fgmicrotec.hr:8888/mms=fgmicro", "http://mms.vipnet.hr/servlets/mms", "http://mms.fgmicrotec.hr:8888/mms=fgmicro", "http://mms.htmobile.hr/servlets/mms", "http://mms.t-mobile.de/servlets/mms", "http://139.7.24.1/servlets/mms", "http://mms/eplus", "http://10.81.0.7:8002"};

	/* Copy profile data into MmsProfilesData structures */
	for (profile = 0; profile<no_of_profiles; profile++)
	{
		strcpy(MmsProfilesData->Profile[profile].MmscAddress, MmscAddress[profile]);
	}

	/* Write data to flash */
	if (flash_mms_write()==EFFS_OK)												// Make sure flash data is written OK
		return WAP_OK;
	else
		return WAP_FAIL;
}
#endif

/*******************************************************************************

 $Function:    	ATB_wap_profile_send

 $Description:	Sends the configuration information of the current profile to the WAP task.

 $Returns:		None.

 $Arguments:	View  - the current view

*******************************************************************************/

#ifdef FF_GPF_TCPIP
#if 0
void ATB_wap_profile_send(T_WAP_VIEW *View)
{
	T_WAP_PROFILE		*Profile = View->Profile;
	ULONG				IPAddressLong;

#ifdef TRACE_ATBWAPAUI
	TRACE_FUNCTION("ATB_wap_profile_send");
#endif

	/* Set bearer for data channel */
	switch(Profile->AccessType)
	{
		case WAP_GPRS_DATA:
			ATB_wap_conn_config_int(View, configACCESS_TYPE, BEARER_GSM_GPRS);
			break;
		case WAP_CS_DATA:
			ATB_wap_conn_config_int(View, configACCESS_TYPE, BEARER_GSM_CSD);
			break;
		case WAP_SMS:
			ATB_wap_conn_config_int(View, configACCESS_TYPE, BEARER_GSM_SMS);
			break;
	}

	/* Setup timeout */
	ATB_wap_conn_config_int(View, configTIMEOUT, Profile->ResponseTimer);
	/* Setup stack mode */
	/* This part is used only for browser */
	if (View->object_id == 1)
	{
		if (Profile->Port1 == 9201)
		{
			ATB_wap_conn_config_int(View, configCONNECTION_TYPE, CONNECTION_TYPE_WSP_CO);
			TRACE_EVENT("CONNECTION_TYPE_WSP_CO at the location 1 called");
		}
		else
		{
			ATB_wap_conn_config_int(View, configCONNECTION_TYPE, CONNECTION_TYPE_TCP);
			TRACE_EVENT("CONNECTION_TYPE_TCP at the location 1 called");
		}
	}

	if( (Profile->WirelessProfiledHTTP) || (Profile->Port1 == 9201) )
	{
	/* Set IP address
	 * Trying first IP address, so set flag accordingly */
	View->secondaryIP = FALSE;
	ATB_conv_str_to_IP(Profile->IPAddress1, strlen(Profile->IPAddress1), &IPAddressLong);
	ATB_wap_conn_config_str(View, configPROXY_ADDRESS, (CHAR *)&IPAddressLong, sizeof(ULONG));
	}

	// Config security
	ATB_wap_conn_config_int(View, configALWAYS_SECURE, 0);
	ATB_wap_conn_config_int(View, configNEVER_SECURE, 1);

	/* Set WAP host */
	//ATB_wap_conn_config_str(View, configADD_HOST, Profile->Homepage, strlen(Profile->Homepage));

	/* Set connection port 1 */
	ATB_wap_conn_config_int(View, configPROXY_PORT, Profile->Port1);
	ATB_wap_conn_config_int(View, WAP_setPort1, Profile->Port1);
	ATB_wap_conn_config_int(View, configPROXY_SECURE_PORT, 0);

	/* Set connection port 2 */
	ATB_wap_conn_config_int(View, WAP_setPort2, Profile->Port2);

	// Set proxy credentials
	ATB_wap_conn_config_str(View, WAP_transLongIP, (char*) &IPAddressLong, 4);
	ATB_wap_conn_config_str(View, WAP_transUsername, Profile->Username, strlen(Profile->Username));
	ATB_wap_conn_config_str(View, WAP_transPassword, Profile->Password, strlen(Profile->Password));


	/* SPR#2086 - SH - Set connection port for PUSH */
//	ATB_wap_conn_config_int(View, WAP_setPortPush, WAP_DEFAULT_PORT_PUSH); FG ?


	return;
}
#else

// xreddymn Jun-21-2005 MMI-SPR-30291: Changed method of sending WAP profile
// from MMI to WAP adapter.

extern void *micAlloc(int size);

void ATB_wap_profile_send(T_WAP_VIEW *View)
{
	T_WAP_PROFILE				*Profile = View->Profile;
	ULONG						IPAddressLong;
	T_MMI_WAP_PROFILE_DATA		*profile_data;
	T_MMI_WAP_SEND_PROFILE_IND	send_profile_ind;

#ifdef TRACE_ATBWAPAUI
	TRACE_FUNCTION("ATB_wap_profile_send");
#endif

	profile_data = micAlloc(sizeof(T_MMI_WAP_PROFILE_DATA));
	if(profile_data == NULL)
	{
		return;
	}

	/* Set bearer for data channel */
	switch(Profile->AccessType)
	{
		case WAP_GPRS_DATA:
			profile_data->configACCESS_TYPE = BEARER_GSM_GPRS;
			break;
		case WAP_CS_DATA:
			profile_data->configACCESS_TYPE = BEARER_GSM_CSD;
			break;
		case WAP_SMS:
			profile_data->configACCESS_TYPE = BEARER_GSM_SMS;
			break;
	}

	/* Setup timeout */
	profile_data->configTIMEOUT = Profile->ResponseTimer;
	ATB_wap_conn_config_int(View, configTIMEOUT, Profile->ResponseTimer);

	/* Setup stack mode */
	/* This part is used only for browser */
	profile_data->configCONNECTION_TYPE = -1;
	if (View->object_id == 1)
	{
		if (Profile->Port1 == 9201)
		{
			profile_data->configCONNECTION_TYPE = CONNECTION_TYPE_WSP_CO;
			TRACE_EVENT("CONNECTION_TYPE_WSP_CO at the location 1 called");
		}
		else
		{
			profile_data->configCONNECTION_TYPE = CONNECTION_TYPE_TCP;
			TRACE_EVENT("CONNECTION_TYPE_TCP at the location 1 called");
		}
	}

	profile_data->configPROXY_ADDRESS[0] = 0;
	if( (Profile->WirelessProfiledHTTP) || (Profile->Port1 == 9201) )
	{
		/* Set IP address
		 * Trying first IP address, so set flag accordingly */
		View->secondaryIP = FALSE;
		ATB_conv_str_to_IP(Profile->IPAddress1, strlen(Profile->IPAddress1), &IPAddressLong);
		memcpy(profile_data->configPROXY_ADDRESS, (CHAR *)&IPAddressLong, sizeof(ULONG));
	}

	// Config security
	profile_data->configALWAYS_SECURE = 0;
	profile_data->configNEVER_SECURE = 1;

	/* Set connection port 1 */
	profile_data->configPROXY_PORT = Profile->Port1;
	profile_data->WAP_setPort1 = Profile->Port1;
	profile_data->configPROXY_SECURE_PORT = 0;

	/* Set connection port 2 */
	profile_data->WAP_setPort2 = Profile->Port2;

	// Set proxy credentials
	memcpy(profile_data->WAP_transLongIP, (CHAR *)&IPAddressLong, sizeof(ULONG));
	strncpy(profile_data->WAP_transUsername, Profile->Username, 20);
	strncpy(profile_data->WAP_transPassword, Profile->Password, 20);

	send_profile_ind.data = (UBYTE*)profile_data;
	send_profile_ind.object_id = View->object_id;
	send_profile_ind.channel_id = View->channel;
	M_MMI_WAP_SEND_PROFILE_IND(&send_profile_ind);

	return;
}

#endif
#else /* #ifdef FF_GPF_TCPIP */

void ATB_wap_profile_send(T_WAP_VIEW *View)
{
	T_WAP_PROFILE		*Profile = View->Profile;
	ULONG				IPAddressLong;

#ifdef TRACE_ATBWAPAUI
	TRACE_FUNCTION("ATB_wap_profile_send");
#endif

	/* Set bearer for data channel */
	switch(Profile->AccessType)
	{
		case WAP_GPRS_DATA:
			ATB_wap_conn_config_int(View, configACCESS_TYPE, BEARER_GSM_GPRS);
			break;
		case WAP_CS_DATA:
			ATB_wap_conn_config_int(View, configACCESS_TYPE, BEARER_GSM_CSD);
			break;
		case WAP_SMS:
			ATB_wap_conn_config_int(View, configACCESS_TYPE, BEARER_GSM_SMS);
			break;
	}

	/* Setup timeout */
	ATB_wap_conn_config_int(View, configTIMEOUT, Profile->ResponseTimer);

	/* Set IP address
	 * Trying first IP address, so set flag accordingly */
	View->secondaryIP = FALSE;
	ATB_conv_str_to_IP(Profile->IPAddress1, strlen(Profile->IPAddress1), &IPAddressLong);
	ATB_wap_conn_config_str(View, configUDP_IP_GW, (CHAR *)&IPAddressLong, sizeof(ULONG));

	/* Set WAP Server Authentification name */
	ATB_wap_conn_config_str(View, configAUTH_ID_GW, Profile->Username, strlen(Profile->Username));

	/* Set WAP Server Authentification password */
	ATB_wap_conn_config_str(View, configAUTH_PASS_GW, Profile->Password, strlen(Profile->Password));

	/* Set WAP host */
	ATB_wap_conn_config_str(View, configADD_HOST, Profile->Homepage, strlen(Profile->Homepage));

	/* Set connection port 1 */
	ATB_wap_conn_config_int(View, WAP_setPort1, Profile->Port1);

	/* Set connection port 2 */
	ATB_wap_conn_config_int(View, WAP_setPort2, Profile->Port2);

	return;
}

#endif /* !#ifdef FF_GPF_TCPIP */

#ifdef FF_GPF_TCPIP
/*******************************************************************************

 $Function:    	ATB_wap_profile_setting_get

 $Description:	Returns the status of a particular setting

 $Returns:		1 if the setting is on, 0 otherwise

 $Arguments:	The setting to check

*******************************************************************************/

UBYTE ATB_wap_profile_setting(UBYTE setting)
{
#ifdef TRACE_ATBWAPAUI
	TRACE_FUNCTION("ATB_wap_profile_setting_get");
#endif

	if (WapData->Status & setting)
	{
		return 1;
	}
	else
	{
		return 0;
	}
}


/*******************************************************************************

 $Function:    	ATB_wap_profile_setting_change

 $Description:	Switches a setting on or off

 $Returns:		None

 $Arguments:	setting - The setting to change
 				value - The new value (1 = on, 0 = off)

*******************************************************************************/

void ATB_wap_profile_setting_change(UBYTE setting, UBYTE value)
{
#ifdef TRACE_ATBWAPAUI
	TRACE_FUNCTION("ATB_wap_profile_setting_get");
#endif

	if (value)
	{
		WapData->Status ^= setting;
	}
	else
	{
		WapData->Status &= ~setting;
	}
	return;
}

/*******************************************************************************

 $Function:    	ATB_wap_profile_add

 $Description:	Add a new profile with the given data

 $Returns:		none

 $Arguments:	p: Points to the structure containing the new profile data

 				xreddymn Jan-20-2005 MMI-SPR-28135: WAP_OTA

*******************************************************************************/

void ATB_wap_profile_add(T_WAP_PROFILE *p)
{
	if (WapData->no_of_profiles==MAX_PROFILES)
	{
		/* Overwrite currently selected profile. But the correct method would be:
		 * Ask user if the currently selected profile can be overwritten
		 */
		memcpy(&WapProfilesData->Profile[WapData->ProfileId],p,sizeof(T_WAP_PROFILE));
		flash_wap_write();
	}
	else
	{
		memcpy(&WapProfilesData->Profile[WapData->no_of_profiles],p,sizeof(T_WAP_PROFILE));
		WapData->ProfileId=WapData->no_of_profiles;
		WapData->no_of_profiles++;
		flash_wap_write();
	}
#if(0)
	if (View_header!=NULL)
	{
		ATB_wap_entry_list_destroy(View_header->ProfilesList);
		View_header->ProfilesList = ATB_wap_entry_list_create(WAP_PROFILES_LIST, MAX_PROFILES, PROFILENAME_MAX_LEN, TRUE);
	}
#endif
	AUI_profile_list_redraw(WapData->ProfileId);
}

#endif
/*******************************************************************************

 $Function:    	ATB_wap_secondary_IP

 $Description:	SPR#1688 - SH - Added this function
 				If first IP address fails, try using secondary one.

 $Returns:		None.

 $Arguments:	View  - the current view

*******************************************************************************/

void ATB_wap_secondary_IP(T_WAP_VIEW *View)
{
	ULONG IPAddressLong;

#ifdef TRACE_ATBWAPAUI
	TRACE_FUNCTION("ATB_wap_secondary_IP()");
#endif

	/* We're now using secondary IP */

	View->secondaryIP = TRUE;

	/* Send IP configuration to WAP browser */

	ATB_conv_str_to_IP(View->Profile->IPAddress2, strlen(View->Profile->IPAddress2), &IPAddressLong);
#ifdef FF_GPF_TCPIP
	ATB_wap_conn_config_str(View, configPROXY_ADDRESS, (CHAR *)&IPAddressLong, sizeof(ULONG));
#else
	ATB_wap_conn_config_str(View, configUDP_IP_GW, (CHAR *)&IPAddressLong, sizeof(ULONG));
#endif


	/* Reload the requested page */

	ATB_wap_download_url(View, View->URL, TRUE);

	return;
}


/*******************************************************************************

 $Function:    	ATB_wap_entry_list_create

 $Description:	Creates an entries list

 $Returns:		Pointer to entry list

 $Arguments:	type		- type of list
 				max_entries	- maximum number of entries in list
 				entry_size	- size of entries in characters
 				unicode		- TRUE if entries are unicode

*******************************************************************************/

T_WAP_LIST * ATB_wap_entry_list_create(WAP_LIST_TYPE type, UBYTE max_entries, UBYTE entry_size, BOOL unicode)
{
	T_WAP_LIST *EntryList;

#ifdef TRACE_ATBWAPAUI
	TRACE_FUNCTION("ATB_wap_entry_list_create");
#endif

	/* Allocate memory */

	EntryList  			= (T_WAP_LIST *)AUI_wap_memory_alloc(sizeof(T_WAP_LIST));
	EntryList->Entry	= (char **)AUI_wap_memory_alloc(max_entries*sizeof(char*));

	/* Assign list parameters */

	EntryList->type		= type;
	EntryList->max_entries = max_entries;
	EntryList->entry_size  = entry_size;
	EntryList->no_of_entries = 0;
	EntryList->unicode	= unicode;

	return EntryList;
}


/*******************************************************************************

 $Function:    	ATB_wap_entry_list_destroy

 $Description:	Destroys an entries list

 $Returns:		WAP_OK
 				WAP_FAIL if list does not exist

 $Arguments:	EntryList	- pointer to entry list data

*******************************************************************************/

T_WAP_RES ATB_wap_entry_list_destroy(T_WAP_LIST *EntryList)
{
#ifdef TRACE_ATBWAPAUI
	TRACE_FUNCTION("AUI_wap_entry_list_destroy");
#endif

	/* Ensure list exists */

	if (EntryList==NULL)
		return WAP_FAIL;

	/* Destroy structure */

	AUI_wap_memory_free((UBYTE *)EntryList->Entry, EntryList->max_entries*sizeof(char *));
	AUI_wap_memory_free((UBYTE *)EntryList,sizeof(T_WAP_LIST));

	return WAP_OK;
}


/*******************************************************************************

 $Function:    	ATB_wap_entry_add

 $Description:	Adds an entry to an entry list

 $Returns:		WAP_OK if added successfully
 				WAP_FAIL if the list is full

 $Arguments:	Entrylist	- Pointer to entries table
 				Entry		- Entry to add

*******************************************************************************/

T_WAP_RES ATB_wap_entry_add(T_WAP_LIST *EntryList, char *Entry)
{
	UBYTE entryIndex = EntryList->no_of_entries;	/* Where the new entry should go */

#ifdef TRACE_ATBWAPAUI
	TRACE_FUNCTION("ATB_wap_entry_add");
	ATB_trace_string(Entry, strlen(Entry));
#endif

	/* Check if the list is full */

	if (entryIndex==EntryList->max_entries)
		return WAP_FAIL;

	/* Add the entry */

	if (EntryList->unicode)
	{
		ATB_uc_text_copy((USHORT *)EntryList->Entry[entryIndex], (USHORT *)Entry, EntryList->entry_size);
		// xreddymn Jan-06-2005 MMI-SPR-27618: Added End Of String character
		*((USHORT *)((USHORT *)EntryList->Entry[entryIndex]+EntryList->entry_size))='\0';
	}
	else
	{
		strncpy(EntryList->Entry[entryIndex], Entry, EntryList->entry_size);
		// xreddymn Jan-06-2005 MMI-SPR-27618: Added End Of String character
		*((char *)((char *)EntryList->Entry[entryIndex]+EntryList->entry_size))='\0';
	}

	EntryList->no_of_entries++;		/* Increase list count */

	return WAP_OK;
}


/*******************************************************************************

 $Function:    	ATB_wap_entry_change

 $Description:	Changes an entry in an entry list, destroying the old entry and
 				creating a new one.

 $Returns:		WAP_OK

 $Arguments:	Entrylist 		- Pointer to entries table
 				Entry			- New entry text
 				entryIndex		- Number of entry to change

*******************************************************************************/

#ifdef FF_GPF_TCPIP
T_WAP_RES ATB_wap_entry_change(WAP_LIST_TYPE type, T_WAP_LIST *EntryList, char *Entry, UBYTE entryIndex)
#else
T_WAP_RES ATB_wap_entry_change(T_WAP_LIST *EntryList, char *Entry, UBYTE entryIndex)
#endif

{
	char number[NUMBER_PADDING+1];
	USHORT *EntryUC;

#ifdef TRACE_ATBWAPAUI
	TRACE_FUNCTION("ATB_wap_entry_change");
#endif

#ifdef FF_GPF_TCPIP
	if (type==WAP_HISTORY_LIST)
#else
	if (EntryList->type==WAP_HISTORY_LIST)
#endif
	{
		sprintf(number, "%2d. ", entryIndex+1);			/* Add "xx. " number at start */

		if (EntryList->unicode)
		{
			EntryUC = (USHORT *)EntryList->Entry[entryIndex];
			ATB_char_to_uc(EntryUC, number);
			ATB_uc_text_copy(&EntryUC[NUMBER_PADDING], (USHORT *)Entry, EntryList->entry_size-NUMBER_PADDING);
		}
		else
		{
			strcpy(EntryList->Entry[entryIndex], number);
			strncpy(&EntryList->Entry[entryIndex][NUMBER_PADDING], Entry, EntryList->entry_size-NUMBER_PADDING);
		}
	}
	else
	{
		/* SPR#1816 - SH - Modified for unicode */

		if (EntryList->unicode)
		{
			ATB_uc_text_copy((USHORT *)EntryList->Entry[entryIndex], (USHORT *)Entry, EntryList->entry_size);
		}
		else
		{
			strncpy(EntryList->Entry[entryIndex], Entry, EntryList->entry_size);
		}
	}

	return WAP_OK;
}


/*******************************************************************************

 $Function:    	ATB_wap_entry_insert

 $Description:	Insert an entry into an entry list, shifting all subsequent entries up one.
 				If the maximum limit of the entry list is reached, the last entry is
 				deleted.

 $Returns:		WAP_OK if inserted successfully
 				WAP_FAIL if list is full, or if request does not make sense

 $Arguments:	Entrylist 		- Pointer to entries table
 				Entry			- Entry to insert
 				entryIndex 		- Position at which to insert the new entry

*******************************************************************************/

#ifdef FF_GPF_TCPIP
T_WAP_RES ATB_wap_entry_insert(WAP_LIST_TYPE type, T_WAP_LIST *EntryList, char *Entry, UBYTE entryIndex)
#else
T_WAP_RES ATB_wap_entry_insert(T_WAP_LIST *EntryList, char *Entry, UBYTE entryIndex)
#endif
{
	USHORT entryIndex2 = EntryList->no_of_entries;
	USHORT *EntryUC;

#ifdef TRACE_ATBWAPAUI
	TRACE_FUNCTION("ATB_wap_entry_insert()");
#endif

	/* Check for errors */

	if (EntryList==NULL || entryIndex>EntryList->no_of_entries
		|| EntryList->no_of_entries>EntryList->max_entries)
	{
		return WAP_FAIL;
	}

	/* xreddymn Dec-10-2004 MMI-SPR-26159: Duplicate check for history list */
#ifdef FF_GPF_TCPIP

// If set to 0, will allow duplicate entries in the History List
	if(type==WAP_URL_LIST)
	{
		S32 	i, length;
		BOOL	already_exists=FALSE;

		if (EntryList->unicode)
		{
			length=ATB_uc_text_len((USHORT*)Entry);
			for(i=0;i<entryIndex2;i++)
			{
				if(ATB_uc_text_compare((USHORT*)EntryList->Entry[i],(USHORT*)Entry,length)==0)
				{
					already_exists=TRUE;
					break;
				}
			}
		}
		else
		{
//			length=strlen((const char*)Entry);
			for(i=0;i<entryIndex2;i++)
			{
				if(strcmp((const char*)EntryList->Entry[i],(const char*)Entry)==0)
				{
					already_exists=TRUE;
					break;
				}
			}
		}
		if(already_exists==TRUE)
		{
			return WAP_FAIL;
		}
	}
#endif

	if (EntryList->no_of_entries == EntryList->max_entries)  /* If the list is full... */
	{
		entryIndex2--;									/* Start shifting from second last entry */
	}
	else
	{
		EntryList->no_of_entries++;						/* Increase bookmark count */
	}

	while (entryIndex2>entryIndex)						/* Work back from end of table */
	{
		/* Shift the table down to make space */

		if (EntryList->unicode)
		{
			ATB_uc_text_copy((USHORT *)EntryList->Entry[entryIndex2],
				(USHORT *)EntryList->Entry[entryIndex2-1],
				EntryList->entry_size);
		}
		else
		{
			strncpy(EntryList->Entry[entryIndex2],
				EntryList->Entry[entryIndex2-1],
				EntryList->entry_size);
		}

		entryIndex2--;
	}

	/* For history list, need to include space for number at start */

#ifdef FF_GPF_TCPIP
	if (type==WAP_HISTORY_LIST)													// For history list, need to include space for number at start
#else
	if (EntryList->type==WAP_HISTORY_LIST)
#endif
	{
		if (EntryList->unicode)
		{
			EntryUC = (USHORT *)EntryList->Entry[entryIndex];
			ATB_uc_text_copy(&EntryUC[NUMBER_PADDING],
				(USHORT *)Entry,
				EntryList->entry_size-NUMBER_PADDING);
		}
		else
		{
			strncpy(&EntryList->Entry[entryIndex][NUMBER_PADDING],
				Entry,
				EntryList->entry_size-NUMBER_PADDING);
		}
		ATB_wap_renumber_history(EntryList);
	}
	else
	{
		/* SPR#1816 - SH - Modified for unicode */

		if (EntryList->unicode)
		{
			ATB_uc_text_copy((USHORT *)EntryList->Entry[entryIndex],
				(USHORT *)Entry,
				EntryList->entry_size);
		}
		else
		{
			strncpy(EntryList->Entry[entryIndex],
				Entry,
				EntryList->entry_size);
		}
	}

	return WAP_OK;
}


/*******************************************************************************

 $Function:    	ATB_wap_entry_remove

 $Description:	Removes an entry from the bookmarks or history list and moves
 				other entries up to close the gap.

 $Returns:		WAP_OK if entry successfully removed
 				WAP_FAIL if request does not make sense

 $Arguments:	Entrylist 		- Pointer to entries table
 				entryIndex 		- Number of the entry to delete

*******************************************************************************/

T_WAP_RES ATB_wap_entry_remove(T_WAP_LIST *EntryList, UBYTE entryIndex)
{
#ifdef TRACE_ATBWAPAUI
	TRACE_FUNCTION("ATB_wap_entry_remove");
#endif

	/* Make sure request is meaningful */

	if (EntryList==NULL || entryIndex>EntryList->no_of_entries)
	{
		return WAP_FAIL;
	}

	EntryList->no_of_entries--;	/* Decrease list count */

	while (entryIndex<(EntryList->no_of_entries))
	{
			/* If we haven't reached end of table, move entries up */

		if (EntryList->unicode)
		{
			ATB_uc_text_copy((USHORT *)EntryList->Entry[entryIndex],
				(USHORT *)EntryList->Entry[entryIndex+1],
				EntryList->entry_size);
		}
		else
		{
			strncpy(EntryList->Entry[entryIndex],
				EntryList->Entry[entryIndex+1],
				EntryList->entry_size);
		}
		entryIndex++;
	}

	return WAP_OK;
}


/*******************************************************************************

 $Function:    	ATB_wap_entry_remove_all

 $Description:	Removes all entries from a Entry List

 $Returns:		WAP_OK if successful
 				WAP_FAIL if entry list does not exist

 $Arguments:	EntryList 	- Pointer to bookmarks table

*******************************************************************************/

T_WAP_RES ATB_wap_entry_remove_all(T_WAP_LIST *EntryList)
{
	UBYTE entryIndex;

#ifdef TRACE_ATBWAPAUI
	TRACE_FUNCTION("ATB_wap_entry_remove_all");
#endif

	/* Make sure request is meaningful */
	if (EntryList==NULL)
	{
		return WAP_FAIL;
	}

	EntryList->no_of_entries = 0;
	return WAP_OK;
}


/*******************************************************************************

 $Function:    	ATB_wap_renumber_history

 $Description:	Renumber history list, changing prefixes to all entries

 $Returns:		WAP_OK

 $Arguments:	EntryList - pointer to history list

*******************************************************************************/

#ifdef FF_GPF_TCPIP
int ATB_wap_renumber_history(T_WAP_LIST *EntryList)
#else
T_WAP_RES ATB_wap_renumber_history(T_WAP_LIST *EntryList)
#endif
{
	UBYTE entryIndex;
	char number[NUMBER_PADDING+1];
	USHORT *EntryUC;

#ifdef TRACE_AUIWAP
	TRACE_FUNCTION("ATB_wap_renumber_history");
#endif

	for (entryIndex = 0; entryIndex<(EntryList->no_of_entries); entryIndex++)
	{
		sprintf(number, "%2d.", entryIndex+1);			/* Add "xx. " number at start */

		if (EntryList->unicode)
		{
			EntryUC = (USHORT *)EntryList->Entry[entryIndex];
			ATB_char_to_uc(EntryUC, number);
			/* Overwrite terminating 0 after prefix with space */
			EntryUC[NUMBER_PADDING-1] = (USHORT)(' '<<8);
		}
		else
		{
			/* Overwrite the number prefix */
			strcpy(EntryList->Entry[entryIndex],number);
			/* Overwrite terminating 0 after prefix with space */
			EntryList->Entry[entryIndex][NUMBER_PADDING-1] = ' ';
		}
	}

	return WAP_OK;
}


/*******************************************************************************

 $Function:    	ATB_wap_status_change

 $Description:	Called to change WAP Application status, i.e. downloading, updating, etc

 $Returns:		None.

 $Arguments:	View			- The current view
				status			- New status

*******************************************************************************/

void ATB_wap_status_change(T_WAP_VIEW *View, USHORT status)
{
#ifdef TRACE_ATBWAPAUI
	TRACE_FUNCTION("ATB_wap_status_change");
#endif

	View->browser_status = status;

	/* Inform AUI of status change */
#if defined (FF_MMI_MMS) && defined (FF_GPF_TCPIP)
	//xrashmic 19 Aug, 2004 Bug: 2, 3, 36 and 42
	//The status information is handled by MMS module separatly.
	if(MMSactive)
	{
            //xrashmic 08 Feb, 2005 MMI-SPR-27853
            //Modified the parameters for this function.
		AUI_mms_status_notify(status);
	}
	else
	{
		AUI_wap_status_notify(View, status);
	}

#endif

#ifdef CO_UDP_IP
	AUI_wap_status_notify(View, status);
#endif

	return;
}


/*******************************************************************************

 $Function:    	ATB_wap_status_get

 $Description:	Return TRUE if the browser is in the supplied status.

 $Returns:		TRUE/FALSE

 $Arguments:	View			- The current view
				status			- Is the browser in this state?

*******************************************************************************/

BOOL ATB_wap_status_get(T_WAP_VIEW *View, USHORT status)
{
#ifdef TRACE_ATBWAPAUI
	TRACE_FUNCTION("ATB_wap_status_get");
#endif

	if (View->browser_status==status)
		return (TRUE);
	else
		return (FALSE);
}


/*******************************************************************************

 $Function:    	ATB_uc_text_charsInWidth

 $Description:	Returns number of characters of the string that can fit into the given
 				width in pixels.

 $Returns:		Number of characters

 $Arguments:	str			- the string (unicode, converted)
				length		- the length of string to attempt to display
				width		- the width in pixels into which the string must fit

*******************************************************************************/

USHORT ATB_uc_text_charsInWidth(USHORT *str, USHORT length, SHORT width)
{
	USHORT strIndex;
	USHORT textwidth = 0;
	USHORT character;

#ifdef TRACE_ATBWAPAUI
	TRACE_FUNCTION("ATB_charsInWidth");
#endif

	for (strIndex = 0; strIndex<=length && textwidth<=width; strIndex++)
	{
		character = ((str[strIndex] & 0xFF)<<8) | ((str[strIndex] & 0xFF00)>>8);
		textwidth += font_getCharWidth(character);
	}

	return strIndex-1;
}


#ifdef FF_GPF_TCPIP
/*******************************************************************************

 $Function:    	ATB_uc_text_len

 $Description:	SPR#1816 - SH - Added
 				Returns length of unicode string

 $Returns:		Length of string

 $Arguments:	str		- the string

*******************************************************************************/

USHORT ATB_uc_text_len(USHORT *str)
{
	USHORT length;

#ifdef TRACE_ATBWAPAUI
	TRACE_EVENT("ATB_uc_text_len");
#endif

	length = 0;

	while (str[length]!=0)
	{
		length++;
	}

	return length;
}


#endif
/*******************************************************************************

 $Function:    	ATB_uc_text_copy

 $Description:	SPR#1816 - SH - Added
 				Copies unicode string src into dst

 $Returns:		Length of string copied

 $Arguments:	dst			- the destination string
 				src			- the source string
				destlen		- the maximum string length to copy

*******************************************************************************/

USHORT ATB_uc_text_copy(USHORT *dst, USHORT *src, USHORT destlen)
{
	USHORT length;

#ifdef TRACE_ATBWAPAUI
	TRACE_EVENT("ATB_uc_text_copy");
#endif

	length = 0;

	while (src[length]!=NULL && length<destlen)
	{
		dst[length] = src[length];
		length++;
	}

	dst[length] = NULL;	/* Add terminating NULL */

	return length;
}


/*******************************************************************************

 $Function:    	ATB_uc_text_width

 $Description:	Returns width of unicode string in pixels

 $Returns:		Width of string in pixels

 $Arguments:	str			- the string
				length		- the length of string to measure

*******************************************************************************/

USHORT ATB_uc_text_width(USHORT *str, USHORT length)
{
	USHORT width;
	USHORT index;
	USHORT character;

#ifdef TRACE_ATBWAPAUI
	TRACE_FUNCTION("ATB_uc_text_width");
#endif

	width = 0;

	for (index=0; str[index]!=0 && index<length; index++)
	{
		character = ((str[index] & 0xFF)<<8) | ((str[index] & 0xFF00)>>8);
		width += font_getCharWidth(character);
	}

	return width;
}

  // Apr 28 2005  REF:  MMI-SPR-30400 x0012849
  // Thos function is called to see that text is not displayed on the scroll bar space
/*******************************************************************************
 $Function:    	ATB_uc_text_cut

 $Description:	 To see that the displayed string wont appear on the scroll bar space.
                       This function is same as ATB_uc_text_crop but it wont put .. at the end.
 $Returns:		Length of the cropped string in unicode characters.

 $Arguments:	str			- the string (unicode, converted)
 				length		- the original length
				width		- the maximum pixel width of the new string

*******************************************************************************/

USHORT ATB_uc_text_cut(USHORT *str, USHORT length, SHORT width)
{
	USHORT maxlen = ATB_uc_text_charsInWidth(str, length, width);	/* Maximum length of string that will fit */

#ifdef TRACE_ATBWAPAUI
	TRACE_FUNCTION("ATB_uc_text_cut");
#endif

	if (length>maxlen)
	{
		length = maxlen;
		str[length] = NULL;
	}
	return length;
}

/*******************************************************************************

 $Function:    	ATB_uc_text_crop

 $Description:	Crops a unicode string if necessary to fit the supplied pixel width

 $Returns:		Length of the cropped string in unicode characters.

 $Arguments:	str			- the string (unicode, converted)
 				length		- the original length
				width		- the maximum pixel width of the new string

*******************************************************************************/

USHORT ATB_uc_text_crop(USHORT *str, USHORT length, SHORT width)
{
	USHORT maxlen = ATB_uc_text_charsInWidth(str, length, width);	/* Maximum length of string that will fit */

#ifdef TRACE_ATBWAPAUI
	TRACE_FUNCTION("ATB_crop_text");
#endif

	if (length>maxlen)
	{
		length = maxlen;
		str[length] = NULL;

		/* Add '..' to indicate text is cropped */

		if (length>0)
			str[length-1] = '.';
		if (length>1)
			str[length-2] = '.';
	}

	return length;
}


/*******************************************************************************

 $Function:    	ATB_uc_text_convert

 $Description:	Swap the upper and lower bytes of each unicode character in a string
 				(Converts standard unicode to MMI unicode)

 $Returns:		the string

 $Arguments:	str			- the source/destination string
				strlen		- the length of the string

*******************************************************************************/

USHORT* ATB_uc_text_convert (USHORT *str, USHORT strlen)
{
	USHORT length;

#ifdef TRACE_ATBWAPAUI
	TRACE_FUNCTION("ATB_uc_text_convert()");
#endif

	for (length = 0; str[length]!=0 && length < strlen; length++)
	{
		str[length] = ((str[length]&0xFF)<<8) | ((str[length]&0xFF00)>>8);
	}

	str[length] = NULL;	/* Add terminating NULL */

	return str;
}


/*******************************************************************************

 $Function:    	ATB_uc_to_char

 $Description:	Converts a MMI-converted unicode string to a char string

 $Returns:		The length in unicode characters of the destination string

 $Arguments:	dst			- the destination string
				src			- the source string
				srclen		- the length of the source string

*******************************************************************************/

USHORT ATB_uc_to_char(char *dst, USHORT *src, USHORT srclen)
{
	USHORT length;

#ifdef TRACE_ATBWAPAUI
	TRACE_FUNCTION("ATB_uc_to_char()");
#endif

	for (length = 0; length < srclen && src[length]!=0; length++)
	{
		dst[length] = (char)(src[length]>>8);
	}

	dst[length] = 0;	/* Add terminating NULL */

	return length;
}


/*******************************************************************************

 $Function:    	ATB_char_to_uc

 $Description:	Converts a char string to a MMI-converted unicode string

 $Returns:		The length in unicode characters of the destination string

 $Arguments:	dst			- the destination string
				src			- the source string

*******************************************************************************/

USHORT ATB_char_to_uc (USHORT *dst, char *src)
{
	USHORT length = 0;

#ifdef TRACE_ATBWAPAUI
	TRACE_FUNCTION("ATB_char_to_uc()");
#endif

	while (src[length]!=NULL)
	{
		dst[length] = (USHORT) (src[length]<<8);
		length++;
	}

	dst[length] = 0;	/* Add terminating NULL */

	return length;
}

/*******************************************************************************

 $Function:    	ATB_uc_text_copy

 $Description:	Compares unicode strings

 $Returns:		zero if strings match, non zero otherwise

 $Arguments:	dst			- the destination string
 				src			- the source string
				len			- Number of UCS2 characters to compare

				xreddymn Dec-10-2004 for MMI-SPR-26159
*******************************************************************************/

USHORT ATB_uc_text_compare(USHORT *dst, USHORT *src, USHORT len)
{
	S32 i=0;

	if((dst==NULL)||(src==NULL))
	{
		return(len);
	}
	while ((src[i]==dst[i]) && (len>0))
	{
		len--;
		i++;
	}

	return len;
}

/*******************************************************************************

 $Function:    	ATB_conv_str_to_IP

 $Description:	Converts a string IP address to a long type IP address

 $Returns:		None.

 $Arguments:	str			- the string
 				len			- the original length
				ip			- pointer to where the result will be placed

*******************************************************************************/

GLOBAL const void ATB_conv_str_to_IP(const char* str, USHORT len, ULONG* ip)
{
	char buf[16];
	char *p, *pLast;
	ULONG i, j, k, m;

#ifdef TRACE_ATBWAPAUI
	TRACE_FUNCTION("ATB_conv_str_to_IP");
#endif

	if (len >= 16)
	{
		*ip = 0;
		return;
	}

	memcpy (buf, str, len);
	buf[len] = '\0';

	p = buf;

	pLast = buf;
	k = 0;
	j = 0;
	m = 1;
	for (i=0; i<len; i++)
	{
		if (*p=='.')
		{
			*p = '\0';
			k |= (atoi(pLast) & 0xFF) * m;
			m*=0x100;
			j++;
			p++;
			pLast = p;
			if (j EQ 3)
				break;
		}
		else
			p++;
	}

	if (j NEQ 3 OR p EQ &buf[len])
	{
		*ip = 0;
		return;
	}

	k |= (atoi(pLast) & 0xFF) * m;

	*ip = k;

	return;
}

#ifdef FF_GPF_TCPIP
/*******************************************************************************

 $Function:    	ATB_wap_data_call_connect

 $Description:	Connect the specified view
 				SPR#2086 - SH - Added

 $Returns:		None

 $Arguments:	View - The current view

*******************************************************************************/

void ATB_wap_data_call_connect(T_WAP_VIEW *View)
{
#ifdef TRACE_ATBWAPAUI
	TRACE_FUNCTION("ATB_wap_data_call_connect()");
#endif

	if (View)
	{
		connect(View->object_id);
	}

	return;
}
#endif

/*******************************************************************************
 $Function:    	ATB_data_call_connected

 $Description:	Confirms that a data call has been connected

 $Returns:		None.

 $Arguments:	View - The current view

*******************************************************************************/
#ifdef FF_GPF_TCPIP
void ATB_data_call_connected(T_WAP_VIEW *View)
{
T_MMI_WAP_CONNECT_CNF parameter;

#ifdef TRACE_ATBWAPAUI
	TRACE_FUNCTION("ATB_data_call_connected");
#endif

	/* SPR#2086 - SH - Use Current_view rather than View_header */

	if (View != NULL)
	{
		parameter.object_id = View->object_id;
	 	parameter.channel = View->channel;
		parameter.success = TRUE;
		M_MMI_WAP_CONNECT_CNF(&parameter);
	}


	if (View->object_id==WAP_PUSH_VIEW)
	{
		ATB_wap_status_change(View, ATB_WAP_NO_STATUS);
	}


	return;
}

#else /* #ifdef FF_GPF_TCPIP */
void ATB_data_call_connected(void)
{
T_MMI_WAP_CONNECT_CNF parameter;

#ifdef TRACE_ATBWAPAUI
	TRACE_FUNCTION("ATB_data_call_connected");
#endif

	if (View_header != NULL)
	{
		parameter.object_id = View_header->object_id;
	 	parameter.channel = View_header->channel;


		parameter.success = TRUE;
		M_MMI_WAP_CONNECT_CNF(&parameter);
	}

	return;
}

#endif /* ! #ifdef FF_GPF_TCPIP */

#ifdef FF_GPF_TCPIP
/*******************************************************************************

 $Function:    	ATB_wap_data_call_disconnected

 $Description:	Confirms that a data call has been disconnected
 				SPR#2086 - SH - Added

 $Returns:		None

 $Arguments:	View - The current view

*******************************************************************************/

void ATB_wap_data_call_disconnected(T_WAP_VIEW *View)
{
	T_MMI_WAP_CONNECT_CNF parameter;

#ifdef TRACE_ATBWAPAUI
	TRACE_FUNCTION("ATB_wap_data_call_disconnected()");
#endif

    //xmzhou_trace_string("ATB_wap_data_call_disconnected called");

	if (View != NULL)
	{
		parameter.object_id = View->object_id;
	 	parameter.channel = View->channel;
		parameter.success = FALSE;
		M_MMI_WAP_CONNECT_CNF(&parameter);
	}

	return;
}

#endif /* #ifdef FF_GPF_TCPIP */
/*******************************************************************************

 $Function:    	ATB_wap_start_done

 $Description:	Confirms that WAP_START has completed

 $Returns:		None.

 $Arguments:	None.

*******************************************************************************/

void ATB_wap_start_done(void)
{
	AUI_wap_start_done();

	return;
}


/*******************************************************************************

 $Function:    	ATB_wap_new_view_done

 $Description:	Confirms that WAP_NEW_VIEW has completed
				Also ends configuration information to WAP browser.
				Only send parameters that will not be modified during this
				session.

 $Returns:		None.

 $Arguments:	None.

*******************************************************************************/

#ifdef FF_GPF_TCPIP
void ATB_wap_new_view_done(void)
{
	T_WAP_VIEW *View = Current_view;

	/* Set max no. of history entries */
	ATB_wap_config_int(View, configHISTORY_SIZE, MAX_HISTORY);

	ATB_wap_config_int(View, configCACHE_SIZE, WAP_cache_size);

	/* Display Images */
	//ATB_wap_config_int(View, configDISPLAY_IMAGES, 1);

	/* Don't update images */
	//ATB_wap_config_int(View, configUPDATE_IMAGES, 0);

	/* Set default channel */
	ATB_wap_config_int(View, configDEFAULT_CHANNEL, View->channel);

	/* Set connection port */
	ATB_wap_conn_config_int(View, configCLIENT_PORT, 3);

	/* Set online status (FALSE = not always online) */
	//ATB_wap_conn_config_int(View, configONLINE, FALSE);


	/* SPR#2086 - SH */
	ATB_wap_config_int(View, configPPG_AUTHENTICATION_REQUIRED, 0);


	AUI_wap_new_view_done();

	return;
}

#else /* #ifdef FF_GPF_TCPIP */

void ATB_wap_new_view_done(void)
{
	T_WAP_VIEW *View = Current_view;

	/* Set max no. of history entries */
	ATB_wap_config_int(View, configHISTORY_SIZE, MAX_HISTORY);

	/* Display Images */
	ATB_wap_config_int(View, configDISPLAY_IMAGES, 1);

	/* Don't update images */
	ATB_wap_config_int(View, configUPDATE_IMAGES, 0);

	/* Set default channel */
	ATB_wap_config_int(View, configDEFAULT_CHANNEL, View->channel);

	/* Setup stack mode */
	ATB_wap_conn_config_int(View, configSTACKMODE, MODE_CO_WSP);

	/* Set connection port */
	ATB_wap_conn_config_int(View, configCLIENT_LOCAL_PORT, 3);

	/* Set online status (FALSE = not always online) */
	ATB_wap_conn_config_int(View, configONLINE, FALSE);

	AUI_wap_new_view_done();

	return;
}

#endif /* ! #ifdef FF_GPF_TCPIP */
/*******************************************************************************

 $Function:    	ATB_wap_close_view_done

 $Description:	Confirms that WAP_CLOSE_VIEW has completed

 $Returns:		None.

 $Arguments:	None.

*******************************************************************************/

void ATB_wap_close_view_done(void)
{
	AUI_wap_close_view_done();

	return;
}

/*******************************************************************************

 $Function:    	ATB_wap_cache_prepare

 $Description:	Tell WAP Browser to prepare the cache for shutdown

 $Returns:		None.

 $Arguments:	None.

*******************************************************************************/

void ATB_wap_cache_prepare(void)
{
	T_MMI_WAP_CACHE_PREPARE_IND parameter;

	M_MMI_WAP_CACHE_PREPARE_IND(&parameter);

	return;
}


/*******************************************************************************

 $Function:    	ATB_wap_cache_prepare_done

 $Description:	Confirms that WAP_CACHE_PREPARE has completed

 $Returns:		None.

 $Arguments:	None.

*******************************************************************************/

void ATB_wap_cache_prepare_done(void)
{
	AUI_wap_cache_prepare_done();

	return;
}


/*******************************************************************************

 $Function:    	ATB_wap_terminate_done

 $Description:	Confirms that WAP_TERMINATE has completed

 $Returns:		None.

 $Arguments:	None.

*******************************************************************************/

void ATB_wap_terminate_done(void)
{
	AUI_wap_terminate_done();

	return;
}


/*******************************************************************************

 $Function:    	ATB_wap_disconnect

 $Description:	Informs WAP browser that a disconnection has occurred

 $Returns:		None.

 $Arguments:	View - the current View

*******************************************************************************/

void ATB_wap_disconnect(T_WAP_VIEW *View)
{
	T_MMI_WAP_DISCONNECT_IND parameter;

	TRACE_FUNCTION("ATB_wap_disconnect()");

	parameter.object_id = View->object_id;
	parameter.channel = View->channel;

	M_MMI_WAP_DISCONNECT_IND(&parameter);

	return;
}

#ifdef FF_GPF_TCPIP
/*******************************************************************************

 $Function:    	ATB_wap_content_get

 $Description:	Fetches content
 				SPR#2086 - SH - Added

 $Returns:		WAP_FAIL if invalid request
 				WAP_OK otherwise.

 $Arguments:	urlID - A distinct ID for this request.  Returned in ATB_wap_content().
 				Url - The URL of the content to download.
 				reload - If TRUE, any version of the requested content in the cache
 				will be ignored, and the content will be fetched from the network.
 				acceptHeader - Specifies if any Accept-Header fields will be sent with
 				the request.  Can be NULL.

*******************************************************************************/

T_WAP_RES ATB_wap_content_get(UBYTE urlID, char *Url, BOOL reload, char *acceptHeader)
{
	T_MMI_WAP_CONTENT_REQ parameter;

	TRACE_FUNCTION("ATB_wap_content_get()");

	if (!parameter.Url)
		return WAP_FAIL;

	parameter.Url = Url;
	parameter.url_length = strlen(Url);
	parameter.urlID = urlID;
	parameter.reload = reload;
	parameter.AcceptHeader = acceptHeader;
	if (acceptHeader!=NULL)
	{
		parameter.acceptHeader_length = strlen(acceptHeader);
	}
	else
	{
		parameter.acceptHeader_length = 0;
	}

	//xmzhou_trace_string("****M_MMI_WAP_CONTENT_REQ****");

	M_MMI_WAP_CONTENT_REQ(&parameter);

	return WAP_OK;
}


/*******************************************************************************

 $Function:    	ATB_wap_content

 $Description:	The requested content.
 				SPR#2086 - SH - Added

 $Returns:		None.

 $Arguments:	urlID - A distinct ID for this request, provided by ATB_wap_content_get().
				Data - The downloaded data.
				data_length - The length of the downloaded data in bytes.
				moreData - If TRUE, there is more data to come.
				(This is just an indicator; the request for further data is made by the
				function M_WAP_MMI_CONTENT_IND.
				ContentType - The type of the downloaded data.
				contentType_length - The length of the downloaded data type, in bytes.
				totalSize - If the data comes in more than one chunk, this will give
				the total size of the assembled chunks.  However, this information may
				not be provided by the WAP gateway.
				errorNo - Error code.  If this is nonzero, it is reported to the AUI in
				the function AUI_error_dialog().

*******************************************************************************/

void ATB_wap_content(UBYTE urlID,
	char *Data,
	ULONG data_length,
	BOOL moreData,
	char *ContentType,
	ULONG contentType_length,
	ULONG totalSize,
	SHORT errorNo)
{
	TRACE_FUNCTION("ATB_wap_content()");

	/* Check if an error has occurred */
	if (Data==NULL || errorNo>0)
	{
		AUI_error_dialog(Current_view, errorNo);
		return;
	}
	//xrashmic 19 Aug, 2004 Bug: 2, 3, 36 and 42
	//The download data should not be displayed for MMS module
	if(!MMSactive)
	{

	AUI_wap_content(
		urlID,
		Data,
		data_length,
		moreData,
		ContentType,
		contentType_length,
		totalSize);
	}
	return;
}


/*******************************************************************************

 $Function:    	ATB_wap_content_cancel

 $Description:	Cancel receipt of content.
 				SPR#2086 - SH - Added

 $Returns:		None.

 $Arguments:	urlID - The ID of the download.

*******************************************************************************/

void ATB_wap_content_cancel(UBYTE urlID)
{
	T_MMI_WAP_CONTENT_CANCEL_IND parameter;

	TRACE_FUNCTION("ATB_wap_content_cancel()");

	parameter.urlID = urlID;
	M_MMI_WAP_CONTENT_CANCEL_IND(&parameter);

	return;
}


/*******************************************************************************

 $Function:    	ATB_wap_content_post

 $Description:	Post content
 				SPR#2086 - SH - Added

 $Returns:		WAP_FAIL if invalid request
 				WAP_OK otherwise.

 $Arguments:	urlID - A distinct ID for this request.  Returned in ATB_wap_content().
 				Url - The URL of the content to download.
 				reload - If TRUE, any version of the requested content in the cache
 				  will be ignored, and the content will be fetched from the network.
 				acceptHeader - Specifies if any Accept-Header fields will be sent with
 				  the request (NULL terminated).  Can be NULL.
 				Data - The data to post.
 				data_length - The length of the data to post, in bytes.
 				moreData - TRUE if there are more chunks to be sent after this one.
 				contentType - May contain the content type of the data
 				  (NULL terminated string).
 				sendMode - one of WAP_SENDMODE_URL_ENCODED,
 				  WAP_SENDMODE_MULTIPART_FORMDATA, WAP_SENDMODE_BINARY
 				contentDisp - when sendMode is WAP_SENDMODE_MULTIPART_FORMDATA,
 				  contentDisp can be set to e.g. filename for the content.  Can be NULL.
 				totalSize - If moreData is TRUE, this may indicate the total size of
 				  the data to be sent.

*******************************************************************************/

T_WAP_RES ATB_wap_content_post(
	UBYTE urlID,
	char *Url,
	BOOL reload,
	char *acceptHeader,
	char *Data,
	ULONG data_length,
	BOOL moreData,
	char *ContentType,
	UBYTE sendMode,
	char *ContentDisp,
	ULONG totalSize)
{
	T_MMI_WAP_CONTENT_POST_REQ parameter;

	TRACE_FUNCTION("ATB_wap_content_post()");
       //xmzhou_trace_string("ATB_wap_content_post called!!!!");

	//if (!parameter.Url || !parameter.Data)
	//	return WAP_FAIL;

	parameter.Url = Url;
	parameter.url_length = strlen(Url);
	parameter.urlID = urlID;
	parameter.reload = reload;
	parameter.AcceptHeader = acceptHeader;
	if (acceptHeader!=NULL)
	{
		parameter.acceptHeader_length = strlen(acceptHeader);
	}
	else
	{
		parameter.acceptHeader_length = 0;
	}
	parameter.Data = Data;
	parameter.data_length = data_length;
	parameter.moreData = moreData;
	parameter.ContentType = ContentType;
	if (ContentType!=NULL)
	{
		parameter.contentType_length = strlen(ContentType);
	}
	else
	{
		parameter.contentType_length = 0;
	}
	parameter.sendMode = sendMode;
	parameter.ContentDisp = ContentDisp;
	if (ContentDisp!=NULL)
	{
		parameter.contentDisp_length = strlen(ContentDisp);
	}
	else
	{
		parameter.contentDisp_length = 0;
	}
	parameter.totalSize = totalSize;
	//xmzhou_trace_string("ATB_wap_content_post call M_MMI_WAP_CONTENT_POST_REQ!!!!");
	M_MMI_WAP_CONTENT_POST_REQ(&parameter);

	return WAP_OK;
}


/*******************************************************************************

 $Function:    	ATB_wap_content_post_more

 $Description:	Post more content (after the first chunk has been sent)
 				SPR#2086 - SH - Added

 $Returns:		WAP_FAIL if invalid request
 				WAP_OK otherwise.

 $Arguments:	urlID - A distinct ID for this request, sent in ATB_wap_content_post().
 				Data - The data to post.
 				data_length - The length of the data to post, in bytes.
 				moreData - TRUE if there are more chunks to be sent after this one.

*******************************************************************************/

T_WAP_RES ATB_wap_content_post_more(
	UBYTE urlID,
	char *Data,
	ULONG data_length,
	BOOL moreData)
{
	T_MMI_WAP_CONTENT_POST_MORE_REQ parameter;

	TRACE_FUNCTION("ATB_wap_content_post_more()");
    //xmzhou_trace_string("ATB_wap_content_post_more called");

	//if (!parameter.Data)
	//	return WAP_FAIL;

	parameter.urlID = urlID;
	parameter.Data = Data;
	parameter.data_length = data_length;
	parameter.moreData = moreData;

	M_MMI_WAP_CONTENT_POST_MORE_REQ(&parameter);

	return WAP_OK;

}



/*******************************************************************************

 $Function:    	ATB_wap_push_load_SI

 $Description:	Load the requested service indication.
 				SPR#2086 - SH - Added

 $Returns:		None.

 $Arguments:	View - The current view
 				id - The identifier of the SI.

*******************************************************************************/

void ATB_wap_push_load_SI(T_WAP_VIEW *View, SHORT id)
{
	T_MMI_WAP_PUSH_LOAD_SI_IND parameter;

#ifdef TRACE_ATBWAPAUI
	TRACE_FUNCTION("ATB_wap_push_load_SI()");
#endif

	parameter.object_id = View->object_id;
	parameter.id = id;

	M_MMI_WAP_PUSH_LOAD_SI_IND(&parameter);

	return;
}

/*******************************************************************************

 $Function:    	ATB_wap_push_delete_SI

 $Description:	Delete the requested service indication.
 				SPR#2086 - SH - Added

 $Returns:		None.

 $Arguments:	id - The identifier of the SI to delete.
 				selection - Parameter specifying which SI to delete (used if id is -1).
 				  Can be WAP_PUSH_DEL_ALL, WAP_PUSH_DEL_EXP,
 				  WAP_PUSH_DEL_NON_EXP, WAP_PUSH_DEL_LOADED,
 				  WAP_PUSH_DEL_NON_LOADED

*******************************************************************************/

void ATB_wap_push_delete_SI(SHORT id, UBYTE selection)
{
	T_MMI_WAP_PUSH_DELETE_SI_IND parameter;

#ifdef TRACE_ATBWAPAUI
	TRACE_FUNCTION("ATB_wap_push_delete_SI()");
#endif

	parameter.id = id;
	parameter.selection = selection;

	M_MMI_WAP_PUSH_DELETE_SI_IND(&parameter);

	return;
}

/*******************************************************************************

 $Function:    	ATB_wap_push_get_SI_info

 $Description:	Request info on the specified SI.
 				SPR#2086 - SH - Added

 $Returns:		None.

 $Arguments:	id - The identifier of the SI to delete.
 				selection - Parameter specifying for which SI to get info (used if id is -1).
 				  Can be WAP_PUSH_SHOW_ALL, WAP_PUSH_SHOW_EXP,
 				  WAP_PUSH_SHOW_NON_EXP, WAP_PUSH_SHOW_LOADED,
 				  WAP_PUSH_SHOW_NON_LOADED

*******************************************************************************/

void ATB_wap_push_get_SI_info(SHORT id, UBYTE selection)
{
	T_MMI_WAP_PUSH_GET_SI_INFO_REQ parameter;

#ifdef TRACE_ATBWAPAUI
	TRACE_FUNCTION("ATB_wap_push_get_SI_info()");
#endif

	parameter.id = id;
	parameter.selection = selection;

	M_MMI_WAP_PUSH_GET_SI_INFO_REQ(&parameter);

	return;
}


/*******************************************************************************

 $Function:    	ATB_wap_push_save_repository

 $Description:	Save the push repository to flash
 				SPR#2086 - SH - Added

 $Returns:		None.

 $Arguments:	None

*******************************************************************************/

void ATB_wap_push_save_to_flash(void)
{
	T_MMI_WAP_PUSH_SAVE_TO_FLASH_IND parameter;

#ifdef TRACE_ATBWAPAUI
	TRACE_FUNCTION("ATB_wap_push_load_SI()");
#endif

	M_MMI_WAP_PUSH_SAVE_TO_FLASH_IND(&parameter);

	return;
}


/*******************************************************************************

 $Function:    	ATB_wap_push_SI_new

 $Description:	A new SI has been received
 				SPR#2086 - SH - Added

 $Returns:		None.

 $Arguments:	id - identifier for the SI
				created - Date and time of when SI was created in UTC format
				expires - Date and time of when SI expires in UTC format
				Message - The description of the received SI, to be presented to the
				  end-user
				message_length - Length of Message in Unicode characters
				expired - TRUE if SI has expired, FALSE otherwise
				Url - The URL of the service to retrieve, or NULL if not provided
				url_length - Length of Url in characters
				priority - Priority of SI.  Can be: WAP_PUSH_LOW_PRIO,
				  WAP_PUSH_HIGH_PRIO, WAP_PUSH_CACHE_PRIO.
				InitURL - Identifies the push initiator.  NULL if not provided
				initURL_length - Length of InitURL in characters
				applicationType - Allows application to map message to right user
				  agent.  Can be WAP_APPLICATION_WML, WAP_APPLICATON_WTA.
				newChannelId - For Bluetooth support

*******************************************************************************/

void ATB_wap_push_SI_new(
	SHORT id,
	ULONG created,
	ULONG expires,
	USHORT *Message,
	ULONG message_length,
	BOOL expired,
	char *Url,
	ULONG url_length,
	UBYTE priority,
	char *InitURL,
	ULONG initURL_length,
	UBYTE applicationType,
	UBYTE newChannelId
	)
{
#ifdef TRACE_ATBWAPAUI
	TRACE_FUNCTION("ATB_wap_push_SI_new()");
#endif

	/* Save the current push repository to flash */

	ATB_wap_push_save_to_flash();

	/* Indicate to the user that a new push message has arrived
	 * (only if the appropriate setting is set to TRUE) */

	if (ATB_wap_profile_setting(WAP_STATUS_PUSHMESSAGES))
	{
		AUI_wap_push_show(
			Message,
			(USHORT)message_length,
			id,
			(char *)Url,
			(USHORT)url_length);
	}

	return;
}

/*******************************************************************************

 $Function:    	ATB_wap_push_SL_new

 $Description:	A new SL has been received

 $Returns:		void

 $Arguments:	id - identifier for the SL
				Url - The URL of the service to retrieve, or NULL if not provided
				url_length - Length of Url in characters
				priority - Priority of SL.  Can be: WAP_PUSH_LOW_PRIO,
				  WAP_PUSH_HIGH_PRIO, WAP_PUSH_CACHE_PRIO.
				InitURL - Identifies the push initiator.  NULL if not provided
				initURL_length - Length of InitURL in characters
				applicationType - Allows application to map message to right user
				  agent.  Can be WAP_APPLICATION_WML, WAP_APPLICATON_WTA.
				newChannelId - For Bluetooth support

				xreddymn Mar-16-2005 MMI-SPR-29767

*******************************************************************************/

void ATB_wap_push_SL_new(
	SHORT id,
	char *Url,
	ULONG url_length,
	UBYTE priority,
	char *InitURL,
	ULONG initURL_length,
	UBYTE applicationType,
	UBYTE newChannelId
	)
{
#ifdef TRACE_ATBWAPAUI
	TRACE_FUNCTION("ATB_wap_push_SL_new()");
#endif

	// Save the current push repository to flash

	ATB_wap_push_save_to_flash();

	// Launch WAP with the URL received in the SL message
	
	AUI_wap_push_load_SL(id, Url, url_length);

	return;
}

/*******************************************************************************

 $Function:    	ATB_wap_push_SI_info

 $Description:	Returns info about the specified SI.
 				SPR#2086 - SH - Added

 $Returns:		None.

 $Arguments:	id - identifier for the SI
				status - Status of the SI.  Can be WAP_PUSH_STATUS_NON_LOADED,
				  WAP_PUSH_STATUS_LOADED.
				created - Date and time of when SI was created in UTC format
				expires - Date and time of when SI expires in UTC format
				Message - The description of the received SI, to be presented to the
				  end-user
				message_length - Length of Message in Unicode characters
				expired - TRUE if SI has expired, FALSE otherwise
				Url - The URL of the service to retrieve, or NULL if not provided
				url_length - Length of Url in characters
				priority - Priority of SI.  Can be: WAP_PUSH_LOW_PRIO,
				  WAP_PUSH_HIGH_PRIO, WAP_PUSH_CACHE_PRIO.
				InitURL - Identifies the push initiator.  NULL if not provided
				initURL_length - Length of InitURL in characters

*******************************************************************************/

void ATB_wap_push_SI_info(
	SHORT id,
	UBYTE status,
	ULONG created,
	ULONG expires,
	USHORT *Message,
	ULONG message_length,
	BOOL expired,
	char *Url,
	ULONG url_length,
	UBYTE priority,
	char *InitURL,
	ULONG initURL_length
	)
{
#ifdef TRACE_ATBWAPAUI
	TRACE_FUNCTION("ATB_wap_push_SI_info()");
#endif

	AUI_wap_push_info(
		Message,
		message_length,
		id,
		(char *)Url,
		(USHORT)url_length,
		status,
		created,
		expired,
		priority);
}

char WAPServiceCentre[30] = {0};
T_MFW_PHB_TON addr_type;
T_MFW_PHB_TON sc_type;

/*******************************************************************************

 $Function:    	ATB_wap_push_SMS_received

 $Description:	Notifies WAP that a WAP SMS has been received
 				SPR#2086 - SH - Added

 $Returns:		None.

 $Arguments:	smsc - The service centre address (NULL terminated)
 				tosca - Service centre T.O.N.
 				number - The address of the sender
 				toa - Sender addresss T.O.N.
 				Data - data of message
 				data_length - Length of the message in bytes

*******************************************************************************/

void ATB_wap_push_SMS_received(
	char *Smsc,
	UBYTE tosca,
	char *number,
	UBYTE toa,
	char *Udh,
	ULONG udh_length,
	char *Data,
	ULONG data_length)
{
	T_MMI_WAP_PUSH_SMS_RECEIVED_IND parameter;
	USHORT totalsize;
	char *sms_data;

#ifdef TRACE_ATBWAPAUI
	TRACE_FUNCTION("ATB_wap_push_SMS_received");
	TRACE_EVENT_P2("udh_length %d, data_length: %d", udh_length, data_length);
#endif

	/* Concatenate the UDH and data */

	totalsize = udh_length+data_length+1;
	sms_data = (char *)AUI_wap_memory_alloc(totalsize);

	sms_data[0] = udh_length;
	memcpy((void *)&sms_data[1], Udh, udh_length);
	memcpy((void *)&sms_data[udh_length+1], Data, data_length);

	/* Store WAP Service Centre */

	memset((void *)WAPServiceCentre, 0, sizeof(WAPServiceCentre));

	if (Smsc)
	{
		strcpy(WAPServiceCentre, Smsc);
		TRACE_EVENT_P1("smsc: %s", WAPServiceCentre);
	}

	addr_type = toa;
	sc_type = tosca;

	parameter.Source = number;
	parameter.source_length = (ULONG)strlen(number);
	parameter.Data = sms_data;
	parameter.data_length = (ULONG)totalsize;

	M_MMI_WAP_PUSH_SMS_RECEIVED_IND(&parameter);

	AUI_wap_memory_free((void *)sms_data, totalsize);

	return;
}


/*******************************************************************************

 $Function:    	ATB_wap_push_SMS_send

 $Description:	WAP requests MMI to send an SMS
 				SPR#2086 - SH - Added

 $Returns:		None.

 $Arguments:	Smsc - The service centre address
 				smsc_length - Length of the service centre in characters
 				Destination - The address of the destination
 				destination_length - The length of the destination
 				toa - Sender addresss T.O.N.
 				Data - data of message
 				data_length - Length of the message in bytes

*******************************************************************************/

void ATB_wap_push_SMS_send(
	char *Smsc,
	ULONG smsc_length,
	char *Destination,
	ULONG destination_length,
	char *Data,
	ULONG data_length)
{
	char *Destination_ascii;
	char dummy[] = "Test";
#ifdef TRACE_AUIWAP
	TRACE_FUNCTION("ATB_wap_push_SMS_send");
#endif

	/* Ensure address is null-terminated */

	Destination_ascii = (char *)AUI_wap_memory_alloc(destination_length+1);
	memcpy((void *)Destination_ascii, (void *)Destination, destination_length);
	Destination_ascii[destination_length] = 0;

	sms_submit_wap_sms(MFW_SMS_REPLY,
	(CHAR *)Destination_ascii,
	addr_type,
	(UBYTE *)Data,
	(USHORT)data_length,
	WAPServiceCentre,
	sc_type);

	AUI_wap_memory_free((void *)Destination_ascii,destination_length+1);

	return;
}


/*******************************************************************************

 $Function:    	ATB_wap_push_SMS_sent

 $Description:	Notifies WAP that a WAP SMS has been sent
 				SPR#2086 - SH - Added

 $Returns:		None.

 $Arguments:	None

*******************************************************************************/

void ATB_wap_push_SMS_sent(void)
{
	T_MMI_WAP_PUSH_SMS_SENT_IND parameter;

#ifdef TRACE_AUIWAP
	TRACE_FUNCTION("ATB_wap_push_SMS_sent");

#endif

	parameter.dummy = 0;

	M_MMI_WAP_PUSH_SMS_SENT_IND(&parameter);

	return;
}


/*******************************************************************************

 $Function:    	ATB_wap_push_SMS_error

 $Description:	Notifies WAP that a WAP SMS has not been sent
 				SPR#2086 - SH - Added

 $Returns:		None.

 $Arguments:	error - an ID for the error

*******************************************************************************/

void ATB_wap_push_SMS_error(UBYTE error)
{
	T_MMI_WAP_PUSH_SMS_ERROR_IND parameter;

#ifdef TRACE_AUIWAP
	TRACE_FUNCTION("ATB_wap_push_SMS_error");
	TRACE_EVENT_P1("**ERROR: %d**",error);
#endif

	parameter.message = error;

	M_MMI_WAP_PUSH_SMS_ERROR_IND(&parameter);

	return;
}

#endif /* #ifdef FF_GPF_TCPIP */


/*******************************************************************************

 $Function:    	long_IP_to_char_IP

 $Description:	Converts a ULONG IP address into an IP address string suitable for an
 				editor.

 $Returns:		None.

 $Arguments:	IPs - The IP address
 				IPd - The string in which to store the result

*******************************************************************************/

void long_IP_to_char_IP(ULONG IPs,char* IPd)
{
	ULONG tempLong;
	char tempChar;
	int i;
	char temp[50];

#ifdef TRACE_ATBWAPAUI
	sprintf(temp,"IP Address %X",(int)IPs);
	TRACE_EVENT(temp);
#endif

	for (i=3;i>=0;i--)
	{
		tempLong=((IPs)>>8*i)&(0xFF);
		*IPd = (char)tempLong;
#ifdef TRACE_ATBWAPAUI
		sprintf(temp,"IP %d %X",i,(int)*IPd);
		TRACE_EVENT(temp);
#endif
		IPd++;
	}


}


/*******************************************************************************

 $Function:    	rAT_WAP_PPP_connected

 $Description:	Indication from ACI that PPP is connected

 $Returns:		None.

 $Arguments:	cId - Id of the WAP call
 				IPAddress - Dynamically assigned IP address

*******************************************************************************/
#ifdef FF_GPF_TCPIP
//TISHMMS Project
extern void M4_DebugStringMessage(char *in_string, UINT8 ucNumber,unsigned long para);

void rAT_WAP_PPP_connected(SHORT cId,ULONG IPAddress)
{
	char charIP[5];

	TRACE_FUNCTION("rAT_WAP_PPP_connected");

	/* SPR#1569 - SH - If there are no open views, disconnect and exit */

	if (!View_header)
	{
		TRACE_EVENT("** WAP has closed, disconnecting call **");
		/* SPR#1575 - SH - Call this function to end a GPRS or CSD call */
		AUI_end_call(0);	/* SPR#1850 - SH - Call ID 0, disconnect any call */
		return;
	}

	/* SPR#1189 - SH - If the browser is not in the correct state, disconnect */

	if (ATB_wap_status_get(Current_view, ATB_WAP_ONLINE_CONNECTION_CLOSED))
	{
		TRACE_EVENT("** WAP is not in correct status, disconnecting call **");
		AUI_end_call(0);
		return;
	}

	/* Send new IP address as config information */

	if (IPAddress)
	{
		charIP[4]='\0';

		long_IP_to_char_IP(IPAddress,(char*)charIP);

		/* Set IP address host */
		ATB_wap_conn_config_str(Current_view, WAP_transCharIP, charIP, 4);
	}

	/* SPR#1574 - SH - Removed parameter */

	ATB_wap_status_change(Current_view,ATB_WAP_CONNECTING);

	ATB_data_call_connected(Current_view);
	return;
}

#else /* #ifdef FF_GPF_TCPIP */

void rAT_WAP_PPP_connected(SHORT cId,ULONG IPAddress)
{
	char charIP[5];

	TRACE_FUNCTION("rAT_WAP_PPP_connected");

	/* If there are no open views, disconnect and exit */

	if (!View_header)
	{
		TRACE_EVENT("** WAP has closed, disconnecting call **");
		AUI_wap_end_call(0);	/* Call ID 0, disconnect any call */
		return;
	}

	/* If the browser is not in the correct state, disconnect */

	if (ATB_wap_status_get(Current_view, ATB_WAP_ONLINE_CONNECTION_CLOSED))
	{
		TRACE_EVENT("** WAP is not in correct status, disconnecting call **");
		AUI_wap_end_call(0);
		return;
	}

	/* Send new IP address as config information */

	if (IPAddress)
	{
		charIP[4]='\0';

		long_IP_to_char_IP(IPAddress,(char*)charIP);

		/* Set IP address host */
		ATB_wap_conn_config_str(Current_view, configUDP_IP_SRC, charIP, 4);
	}

	/* Set new MMI status */

	ATB_wap_status_change(Current_view,ATB_WAP_CONNECTING);

	/* Send connection confirmation to WAP Browser */

	ATB_data_call_connected();

	return;
}

#endif /* ! #ifdef FF_GPF_TCPIP */

/*******************************************************************************

 $Function:    	rAT_WAP_start_login

 $Description:	Login has begun for CSD

 $Returns:		None.

 $Arguments:	None.

*******************************************************************************/

void rAT_WAP_start_login(void)
{
	UBYTE temp;

	TRACE_FUNCTION("rAT_WAP_start_login");

	temp = dspl_Enable(0);

	/* SPR#1569 - SH - Only change status if current view exists */

	if (Current_view)
	{
		/* SPR#1574 - SH - Removed parameter */
		ATB_wap_status_change(Current_view, ATB_WAP_LOGGING_IN);
	}

	dspl_Enable(temp);

	return;
}


/*******************************************************************************

 $Function:    	rAT_WAP_start_gprs_login

 $Description:	Login has started over GPRS

 $Returns:		None.

 $Arguments:	None.

*******************************************************************************/

//NM take it out #ifdef MMI_WAP_ENABLED

void rAT_WAP_start_gprs_login(void)
{
	UBYTE temp;

	TRACE_FUNCTION("rAT_WAP_start_gprs_login");

	temp = dspl_Enable(0);

	/* SPR#1569 - SH - Only change status if current view exists */

	if (View_header && Current_view)
	{
		/* SPR#1982 - SH - Only change status if we are ATTACHING */
		if (ATB_wap_status_get(Current_view, ATB_WAP_ATTACHING))
		{
			ATB_wap_status_change(Current_view, ATB_WAP_CONNECTING);
		}
	}

	dspl_Enable(temp);

	return;
}

//NM #endif

/*******************************************************************************

 $Function:    	rAT_WAP_call_disconnected

 $Description:	Callback - disconnection occurred

 $Returns:		None.

 $Arguments:	cId - ID of the WAP call

*******************************************************************************/

#ifdef FF_GPF_TCPIP
void rAT_WAP_call_disconnected(SHORT cId)
{
	UBYTE temp;
	T_MMI_WAP_CONNECT_CNF parameter;

	TRACE_FUNCTION("rAT_WAP_call_disconnected");

	temp = dspl_Enable(0);

	/* SPR#1569 - SH - If there are no open views, do nothing */


	if (Current_view)
	{
		/* SPR#1574 - SH - Removed parameter */
		ATB_wap_status_change(Current_view, ATB_WAP_ONLINE_CONNECTION_CLOSED);

		parameter.object_id = Current_view->object_id;
	 	parameter.channel = Current_view->channel;
		parameter.success = FALSE;
		M_MMI_WAP_CONNECT_CNF(&parameter);
	}

	dspl_Enable(temp);

	return;
}

#else /* #ifdef FF_GPF_TCPIP */

void rAT_WAP_call_disconnected(SHORT cId)
{
	UBYTE temp;
	T_MMI_WAP_CONNECT_CNF parameter;

	TRACE_FUNCTION("rAT_WAP_call_disconnected");

	temp = dspl_Enable(0);

	/* If there are no open views, do nothing */

	if (View_header != NULL)
	{
		/* Inform MMI of connection closed */

		if (Current_view)
		{
			ATB_wap_status_change(Current_view, ATB_WAP_ONLINE_CONNECTION_CLOSED);
		}

		/* Inform WAP Broswer of connection closed */

		parameter.object_id = View_header->object_id;
	 	parameter.channel = View_header->channel;
		parameter.success = FALSE;
		M_MMI_WAP_CONNECT_CNF(&parameter);
		Current_view = View_header;
	}

	dspl_Enable(temp);

	return;
}

#endif /* ! #ifdef FF_GPF_TCPIP */
/*******************************************************************************

 $Function:    	writeerrorFFS/writeflagFFS

 $Description:	These functions are provided for debugging purposes

 $Returns:		None.

 $Arguments:

*******************************************************************************/

void writeerrorFFS(short error)
{
	UBYTE errordigits[6];
	sprintf((char *)errordigits, "%d", error);
	ffs_file_write("/mmi/errormmi",  &errordigits, sizeof(errordigits), FFS_O_TRUNC | FFS_O_CREATE);
}

void writeflagFFS(UBYTE flag)
{
	ffs_file_write("/mmi/flag",  &flag, sizeof(flag), FFS_O_TRUNC | FFS_O_CREATE);
}


