/*
================================ COPYRIGHT ================================
The contents of this file are subject to the VTech Informations Ltd. License
of VT-OS Ver. 1.1 operating system (the "License"); you may not use this 
file except in compliance with the License.  

Software distributed under the License is distributed on an "AS IS" basis, 
WITHOUT WARRANTY OF ANY KIND, either express or implied.  See the License 
for the specific language governing rights and limitations under the License.
  
The Original Code is VT-OS Ver. 1.1 Operating System, released 
on October 1st, 1999
	
The Initial Developer of the Original Code is VTech Informations Ltd.  All 
codes are Copyright (C) VTech Informations Ltd. 1999.  All Rights Reserved.
===========================================================================
*/

/*
===========================================================================
File        :   siopopup.c 
Author(s)   :   Henry Fok
Company     :   VTech Informations Ltd.
Project     :   Helio 
Date:	    :   October 1st, 1999
Purpose:	:   SIO popup form
Revision    :   1.1
Note        :   None
===========================================================================
*/              


#include "stdafx.h"
#include "system.h"
#include "intc.h"


extern BOOLEAN  battery_enable;
AppID           SysGetRealActiveAppID();
extern BOOLEAN  (*SystemFormDispatchEvent)(EvtType *Event);

/********************* Global Find Variable ***********************
******************************************************************/
BOOLEAN					sio_popup_popup = FALSE;

BOOLEAN                 sio_popup_keyboard_status = FALSE;
BOOLEAN                 sio_popup_menu_status = FALSE;
BOOLEAN                 sio_popup_popup_status = FALSE;

EvtType                 sio_popup_old_event;
EvtType                 sio_popup_inlay_event;

AppID                   sio_popup_current_app_id   = 0;
ObjectID                sio_popup_current_form_id  = 0;
BitmapTemplate          sio_popup_current_display_image;

BOOLEAN                 sio_popup_keyboard_visible = FALSE;

BOOLEAN					sio_popup_inlay_status = FALSE;
BOOLEAN					sio_popup_alarm_status = FALSE;
BOOLEAN					sio_popup_hardware_status = FALSE;
BOOLEAN					sio_popup_battery_status = FALSE;

//UWORD                   lcd_buffer[LCD_SIZE];

/*****************************************************************
* Function:	SIOPopupInit()
* Purpose: 	This function is called to initialise the global variables
of Global Find
* Scope:		application/internal
* Input:		None
* Output:		None
* Return:		None
* Comment: 	None
******************************************************************/
void SIOPopupInit(void)
{
	sio_popup_popup = FALSE;
	
	sio_popup_current_form_id = 0;
	sio_popup_current_display_image.xcoord = 0;
	sio_popup_current_display_image.ycoord = 0;
	sio_popup_current_display_image.width = 160;
	sio_popup_current_display_image.height = 160;
    sio_popup_current_display_image.size = LCD_SIZE * 4;
    sio_popup_current_display_image.quantisation = Q_FOUR_BIT;
    sio_popup_current_display_image.bitmap_data = NULL;
}


/*****************************************************************
* Function:	SIOPopupHandleEvent
* Purpose: 	This function is called to handle the event
sent to SIO Popup Form
* Scope:		application/internal
* Input:		None
* Output:		None
* Return:		None
* Comment: 	None
******************************************************************/
BOOLEAN SIOPopupHandleEvent(EvtType *Event)
{
	switch (Event->eventType)
	{
	case EVT_APP_STOP:
		if (sio_popup_popup)
		{
			if (sio_popup_current_display_image.bitmap_data != NULL)
			{
				Event->para1    = FROM_SYSTEM_DIALOG;
				Event->evtPBP   = &sio_popup_current_display_image;
			}
			else
			{                    
				Event->para1    = 0;
				Event->evtPBP   = NULL;
			}                                        
		}                    
		SIOPopupRestoreRunningApp1();        
		return FALSE;                        
	case EVT_FORM_OPEN:
		FormDrawForm(FORM_SIO);           
		sio_popup_popup = TRUE;
		return TRUE;
	default: return FALSE;
	}
	return FALSE;
}


/*****************************************************************
* Function:	SIOPopupRestoreRunningApp()
* Purpose: 	This function is called to restore the running 
application
* Scope:		application/internal
* Input:		None
* Output:		None
* Return:		None
* Comment: 	with drawing
******************************************************************/
void SIOPopupRestoreRunningApp()
{
    EvtType Event;
    UWORD   i;
	
    if (sio_popup_popup == FALSE)
		return;
	
    if (sio_popup_current_display_image.bitmap_data)
    {
        LcdDrawBitmap(&sio_popup_current_display_image, FALSE);
        qfree(sio_popup_current_display_image.bitmap_data);
    }
	
    if (sio_popup_current_form_id >= 2000)
	{
		switch (sio_popup_current_form_id)
		{
		case FORM_GFIND_INPUT:
            FormSetEventHandler(FORM_GFIND_INPUT, (void**)&SystemFormDispatchEvent, (void*)GlobalFindInput);
            break;            
		case FORM_GFIND_RESULT:
            FormSetEventHandler(FORM_GFIND_RESULT, (void**)&SystemFormDispatchEvent, (void*)GlobalFindResult);
            break;
        case FORM_BATTERY:
            FormSetEventHandler(FORM_BATTERY, (void**)&SystemFormDispatchEvent, (void*)BatteryWarningHandleEvent);
            break;
		case FORM_SIO:
            FormSetEventHandler(FORM_SIO, (void**)&SystemFormDispatchEvent, (void*)SIOPopupHandleEvent);
            break;		
		}            		
	}		
    
    FormSetActiveForm(sio_popup_current_form_id); 
    
    SIOPopupRestorePreviousFormStatus();
    
    if (sio_popup_keyboard_status)
    {
		EvtAppendEvt(EVT_FORM_LOAD, sio_popup_current_form_id, 0, 0, NULL);
		keyboard_status = TRUE;
		keyboard.keyboard_attr.keyboard_drawn = TRUE;
		KeyboardDrawKeyboardBitmap(keyboard.keyboard_current_bitmap_index);
		EvtAppendEvt(EVT_KEYBOARD_STATUS, 0, 1, 0, NULL);
    }
    else keyboard_status = FALSE;
    
	sio_popup_keyboard_status = FALSE;
    
    SIOPopupReset();
    
    LcdEnableInsertPt(FALSE, 0, 0, SMALL_FONT);
    EvtAppendEvt(EVT_FORM_ACTIVE, sio_popup_current_form_id, 0, 0, NULL);		
    
    InlaySetEnableStatus(sio_popup_inlay_status);
    AlmSetStatus(sio_popup_alarm_status);
    SystemSetMappedHardwareKeyStatus(sio_popup_hardware_status);
	battery_enable = sio_popup_battery_status;    
}

/*****************************************************************
* Function:	SIOPopupRestoreRunningApp1()
* Purpose: 	This function is called to restore the running 
application
* Scope:		application/internal
* Input:		None
* Output:		None
* Return:		None
* Comment: 	without drawing
******************************************************************/
void SIOPopupRestoreRunningApp1()
{
    EvtType Event; 
	
    if (sio_popup_popup == FALSE)
		return;
	
	if (sio_popup_current_form_id >= 2000)
	{
		switch (sio_popup_current_form_id)
		{
		case FORM_GFIND_INPUT:
            FormSetEventHandler(FORM_GFIND_INPUT, (void**)&SystemFormDispatchEvent, (void*)GlobalFindInput);
            break;            
		case FORM_GFIND_RESULT:
            FormSetEventHandler(FORM_GFIND_RESULT, (void**)&SystemFormDispatchEvent, (void*)GlobalFindResult);
            break;
        case FORM_BATTERY:
            FormSetEventHandler(FORM_BATTERY, (void**)&SystemFormDispatchEvent, (void*)BatteryWarningHandleEvent);
            break;
		case FORM_SIO:
            FormSetEventHandler(FORM_SIO, (void**)&SystemFormDispatchEvent, (void*)SIOPopupHandleEvent);
            break;            
		}            		
	}		
    FormSetActiveForm(sio_popup_current_form_id); 
    
    
    keyboard_status = FALSE;
	sio_popup_keyboard_status = FALSE;
	
    sio_popup_popup = FALSE;
	
    LcdEnableInsertPt(FALSE, 0, 0, SMALL_FONT);
    EvtAppendEvt(EVT_FORM_ACTIVE, sio_popup_current_form_id, 0, 0, NULL);    
	
    InlaySetEnableStatus(sio_popup_inlay_status);
    AlmSetStatus(sio_popup_alarm_status);
    SystemSetMappedHardwareKeyStatus(sio_popup_hardware_status);
	battery_enable = sio_popup_battery_status;
}

/*****************************************************************
* Function:    SIOPopupReset()
* Purpose:     This function is called to init the battery warning
* Scope:		application/internal
* Input:		None
* Output:		None
* Return:		None
* Comment: 	None
******************************************************************/
void SIOPopupReset(void)
{
    sio_popup_popup = FALSE;
    sio_popup_current_display_image.bitmap_data = NULL;    
}

/*****************************************************************
* Function:    SIOPopupPopup()
* Purpose:     This function is called to init the battery warning
* Scope:		application/internal
* Input:		None
* Output:		None
* Return:		None
* Comment: 	None
******************************************************************/
void SIOPopupPopup(void)
{
    EvtType     event;
    BYTE        object_type;
    void        *addr;
    USHORT      count;
    List        *ptr;
    Scrollbar   *scroll_ptr;
	UWORD		i;
    ObjectBounds bounds;
	
    sio_popup_inlay_status = inlay_status;
	
    if (CPU->REG_INT_ENABLE_6 & PRI_ALARMINT)
        sio_popup_alarm_status = TRUE;
    else             
        sio_popup_alarm_status = FALSE;
				
    sio_popup_hardware_status = mapped_hardware_button_enable;
    sio_popup_battery_status = battery_enable;
				
    InlaySetEnableStatus(FALSE);
    AlarmMgrEnable(FALSE);
    SystemSetMappedHardwareKeyStatus(FALSE);
    BatteryWarningSetEnableStatus(FALSE);        
	
	if (old_event.eventType != NULL_EVENT)
	{
		event.eventType = PEN_EVENT;
		event.eventID   = PEN_UP;
		event.para1     = -10;
		event.para2     = -10;
		event.evtPBP    = NULL;
		if (old_event.eventType == EVT_KEYBOARD_ENTER || old_event.eventType == EVT_KEYBOARD_EXIT)
		{
			old_event.eventType = NULL_EVENT;
			if (keyboard.keyboard_attr.keyboard_enter)
            {    
				KeyboardDrawInvertKey(keyboard.keyboard_highlight_key);
				keyboard.keyboard_attr.keyboard_enter = FALSE;
            }            	    
			else
			{
				FormGetObjectPointer((ObjectID)old_event.eventID, &object_type, (void**)&addr);                     
				switch(object_type)
				{
				case CONTROL:                  
					if (((Control*)addr)->control_attr.control_enter)
					{
						((Control*)addr)->control_attr.control_enter = FALSE;
						ControlDrawControl(old_event.eventID);
					}                   
					break;
				case FIELD:
					LcdEnableInsertPt(FALSE, 0, 0, ((Field*)addr)->field_font_id);
					break;
				case LIST:					
					ListHighlightOneItem(((List*)addr), ((List*)addr)->list_highlighted_item, FALSE);
					((List*)addr)->list_highlighted_item = -1;
					ListHighlightOneItem(((List*)addr), ((List*)addr)->list_selected_item, TRUE);
					
					count = ((List*)addr)->list_num_related_list;
					while (count)
					{
						count --;
						if (FormGetObjectPointer(((List*)addr)->list_related_list_id[count], &object_type, (void**)&ptr) != TRUE)
							break;
						ListHighlightOneItem(ptr, ptr->list_highlighted_item, FALSE);
						ptr->list_highlighted_item = -1;
						ListHighlightOneItem(ptr, ptr->list_selected_item, TRUE);
					}
					break;
				case SCROLLBAR:
					scroll_ptr = (Scrollbar *)addr;
					if (scroll_ptr->scrollbar_attr.scrollbar_enter ||
						scroll_ptr->scrollbar_attr.scrollbar_enter1 ||
						scroll_ptr->scrollbar_attr.scrollbar_enter2)
					{
						scroll_ptr->scrollbar_attr.scrollbar_enter 	= FALSE;
						scroll_ptr->scrollbar_attr.scrollbar_enter1 = FALSE;
						scroll_ptr->scrollbar_attr.scrollbar_enter2 = FALSE;										
						ScrollbarDrawScrollbar(old_event.eventID);					                					                
					}
					break;
				case TABLE:
					if (((Table*)addr)->table_attr.table_enter)
					{
						((Table*)addr)->table_attr.table_enter = FALSE;
						((Table*)addr)->table_current_row = (USHORT) (old_event.para1);
						((Table*)addr)->table_current_col = (USHORT) (old_event.para2);
						TableDrawTable(old_event.eventID);
					}
					break;
				case SCHLINE:                     
					break;
				case BITMAP:
					if (((Bitmap*)addr)->bitmap_attr.bitmap_enter)
					{
						((Bitmap*)addr)->bitmap_attr.bitmap_enter = FALSE;
						BitmapDrawBitmap(old_event.eventID);
					}
					break;
				case TEXTBOX:
					LcdEnableInsertPt(FALSE, 0, 0, ((Textbox*)addr)->textbox_font_id);
					break;
				case MENU:
					MenuCloseMenu();
					break;                                        
				}
			}
		}	        
	}
	sio_popup_keyboard_status 		= keyboard_status;       
	sio_popup_menu_status 			= menu_status;
	sio_popup_popup_status 			= popup_status;
	
	sio_popup_old_event			 	= old_event;
	sio_popup_inlay_event			= inlay_event;
	
	old_event.eventType				= NULL_EVENT;
	inlay_event.eventType			= NULL_EVENT;	
	
	sio_popup_current_app_id   = SysGetRealActiveAppID();		
	FormGetActiveFormID(&sio_popup_current_form_id);
	
	sio_popup_keyboard_visible = keyboard.keyboard_attr.keyboard_visible;
	
    LcdGetBitmap(&sio_popup_current_display_image);
    /*
    i=LCD_SIZE-1;
	do {
	lcd_buffer[i] = WordRead((i%20)*8, i/20);
	} while (i--);
    
	  sio_popup_current_display_image.bitmap_data = lcd_buffer;
    */
    FormPopupForm(FORM_SIO);
}


/********************************************************
* Function:    SIOPopupRestorePreviousFormStatus
* Purpose:     This function is called to restore previous active form status
* Scope:		application/internal
* Input:       None
* Output:		None
* Return:      None
* Comment: 	None
*********************************************************/
void SIOPopupRestorePreviousFormStatus()
{
    ObjectID    menu_id, active_object_id;
    BYTE        object_type, temp_undo_action;
    Menu        *menu_ptr;
    Control     *control_ptr;
    USHORT      num_of_objects, count;
    Form        *form_ptr;
    Field       *field_ptr;
    Textbox     *textbox_ptr;
    void        *addr;
	
    menu_status = FALSE;
    popup_status = FALSE;
    old_event = sio_popup_old_event;
    inlay_event = sio_popup_inlay_event;
	
    if (sio_popup_menu_status == TRUE)
    {
        sio_popup_menu_status = FALSE;
        FormGetMenuID(sio_popup_current_form_id, &menu_id);
        if (FormGetObjectPointer(menu_id, &object_type, (void**)&menu_ptr) == TRUE)
        {
			if (menu_ptr->menu_attr.menu_drawn == TRUE)
				MenuRestoreBehindBits(menu_id);
			menu_ptr->menu_attr.menu_drawn = FALSE;
			old_event.eventType = NULL_EVENT;
			temp_undo_action = undo_action;
			FormObjectRestoreFocus();
			undo_action = temp_undo_action;
		}        	
    }     
	
    if (sio_popup_popup_status == TRUE)
    {
        sio_popup_popup_status = FALSE;
        if (FormGetObjectPointer(old_event.eventID, &object_type, (void**)&addr) == TRUE)
        {
			if (object_type == CONTROL)
			{       
				if (((Control*)addr)->control_style == POPUP_TRIGGER)
				{
					if (((ControlTemplatePopupTrigger*)(((Control*)addr)->control_template))->control_value == TRUE)
					{                        
						((ControlTemplatePopupTrigger*)(((Control*)addr)->control_template))->control_value = FALSE;
						popup_status = FALSE;
						((Control*)addr)->control_attr.control_enter = FALSE;
						ControlRestoreBitBehind(old_event.eventID);
						FormObjectRestoreFocus();
						old_event.eventType = NULL_EVENT;
					}                		
				}                	
            }
        }
    }
	
	
    if (FormGetObjectPointer(sio_popup_current_form_id, &object_type, (void**)&form_ptr) == TRUE)
    {
		num_of_objects = form_ptr->form_num_objects;
		
		FormGetActiveObject(sio_popup_current_form_id, &active_object_id);
		for (count = 0; count < num_of_objects; count++)
		{
			if (form_ptr->form_objects_list[count].object_id == active_object_id)
			{
				if (FormGetObjectPointer(active_object_id, &object_type, (void**)&addr) != TRUE)
					continue;
				if (form_ptr->form_objects_list[count].object_type == FIELD)
				{
					if (((Field*)addr)->field_attr.field_insert_pt_visible == TRUE &&
						((Field*)addr)->field_attr.field_drawn == TRUE)                    
						FieldDrawField(form_ptr->form_objects_list[count].object_id);
					break;
				}
				else if (form_ptr->form_objects_list[count].object_type == TEXTBOX)
				{
					if (((Textbox*)addr)->textbox_attr.textbox_insert_pt_visible == TRUE &&
						((Textbox*)addr)->textbox_attr.textbox_drawn == TRUE)                    
						TextboxDrawTextbox(form_ptr->form_objects_list[count].object_id);
					break;
				}
			}
		}
	}    	
    old_event.eventType     = NULL_EVENT;
    inlay_event.eventType   = NULL_EVENT;
}

