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



#include "stdafx.h"
#include "system.h"
#include "sysetup.h"
#include "dev_pwr.h"
#include "penmgr.h"
#include "sndmgr.h"

//#define DEBUG
//#define DEUBG_BIG
//#define DEBUG_SKH
//#define DEBUG_PEN
//#define DEBUG_HIGH


#define     EVT_SYNC_START          6000
#define     FORM_SCH_REC            119
#define     FORM_SCH_REPLAY         128
#define     FORM_REPLAY_VOICE       95
#define     FORM_RECORD_VOICE       78
#define     FORM_PLAY_VOICE         32


//#define COPY_SCREEN_ENABLE            


extern int CpuChkSpeed();
BYTE hotsync_button_disabled = 0;

void HELIOSYSTEMBLACKHOLE()
{
}

extern BOOLEAN 				(*SystemFormDispatchEvent)(EvtType *Event);

BYTE            			mapped_hardware_button_enable;
extern BOOLEAN  			battery_popup;
extern AppID    			prev_appid;
extern WORD     			PenMgrMode;
extern KeyMappingSettings   GKeyMapping;

/********************************************************
* Function:	SystemHandleEvent
* Purpose: 	This function is used handle all the events that is
not for the application layer
* Scope:		application/internal
* Input:		Event		received event
* Output:		None
* Return:		TRUE if handled
FALSE if not handled
* Comment: 	None
*********************************************************/
BOOLEAN SystemHandleEvent(EvtType *Event)
{
	
    ObjectID form_active_id;
	
    if (Event->eventType == EVT_FORM_LOAD)
        LcdEnableInsertPt(FALSE, 0, 0, SMALL_FONT);
	
    if (Event->eventType != RTC_EVENT && Event->eventType != POWER_EVENT)
    {
		CheckEL();
		CheckPdaPwr();
    }
	
	
    if (BatteryWarningPopup(Event)) return TRUE;
	
	if (SysTranslateCustomiseButtons(Event)) return TRUE;
	
	if (SysApplicationHandleEvent(Event)) return TRUE;
	
    if (FormGetActiveFormID(&form_active_id) == TRUE)
    {  	
        if (form_active_id == FORM_GFIND_INPUT ||
			form_active_id == FORM_GFIND_RESULT ||
			form_active_id == FORM_BATTERY ||
			form_active_id == FORM_SIO)
        {	
			if (MenuHandleEvent(Event))
				return TRUE;
			if (SystemFormDispatchEvent(Event))
				return TRUE;
        }
    }
	
    if (PenMgrMode == PEN_CALIBRATION)
        return FALSE;
	
	if (InlayHandleEvent(Event)) return TRUE;
	
	if (KeyboardHandleEvent(Event)) return TRUE;
	
	if (FormHandleEvent(Event)) return TRUE;
	
    if (!menu_status)
        if (JotHandleEvent(Event)) return TRUE;
		
		if (form_loaded_once == 0)
			if (Event->eventType != EVT_FORM_LOAD) return TRUE;
			if (gf_popup || battery_popup)
				return TRUE;
			
			return FALSE;
}

/********************************************************
* Function:    SysApplicationHandleEvent
* Purpose: 	This function is used to load the specific data of
form and set event handler of the form
* Scope:       application/internal
* Input:       Event           received event
* Output:      None
* Return:      TRUE if handled
FALSE if not handled
* Comment: 	None
*********************************************************/
BOOLEAN SysApplicationHandleEvent(EvtType *Event)
{
	Form *form_ptr;
	ObjectID form_id;
	BYTE object_type;
	Err Error;
	
    if (Event->eventType == EVT_FORM_LOAD)
	{   
		form_id = (ObjectID)Event->eventID;
		if (form_id != FORM_GFIND_INPUT &&
			form_id != FORM_GFIND_RESULT &&
			form_id != FORM_BATTERY &&
			form_id != FORM_SIO)
			return FALSE;
        
		Error = UISearchForAddress(form_id,&object_type,(void**)&form_ptr);
		if (Event->para1 == 1 || Error != TRUE)
			FormInitForm(form_id);
		if (!UISearchForAddress(form_id,&object_type,(void**)&form_ptr)) return FALSE;
		
		switch (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(form_id);
		
		return TRUE;
	}
	return FALSE;
}

/********************************************************
* Function:    SysTranslateCustomiseButtons
* Purpose:     This function is called to trranslate the            
the customised buttons or inlay regions
to pre-defined functions.
* Scope:       application/internal
* Input:       Event           received event
* Output:      None
* Return:      TRUE if handled
FALSE if not handled
* Comment: 	None
*********************************************************/
BOOLEAN SysTranslateCustomiseButtons(EvtType *Event)
{
    AppID               pcsync_app, voice_app, tetris_app, pass_app, alarm_app, sch_app, todo_app, active_app;
    WORD                *cmd_ptr;
    KeyMappingSettings  key_mapping;
    WORD                temp;
    ObjectID            active_form_id = 0xFFFF;
    Err                 found = FALSE;
    BYTE                *version_number;
    
	
	if (Event->eventType == EVT_IO_KEY_CTRL)
	{   
        if (Event->eventID != EVT_IO_KEY_PRESS && Event->eventID != EVT_IO_KEY_REPEAT)
            return FALSE;
		
#ifndef COPY_SCREEN_ENABLE            
        if (!SystemCheckMappedHardwareKeyStatus() && Event->para2 != EVT_POWER_OFF)
            return FALSE;
		
        if (battery_popup && Event->para2 != EVT_POWER_OFF)
            return FALSE;
#endif            
		
        key_mapping  = GKeyMapping;
		
		switch (Event->para2)
		{
		case EVT_POWER_OFF:                
			SysGetAppID("Password", &pass_app);
			if (SysGetActiveAppID() != pass_app)
                prev_appid = SysGetActiveAppID();
			if (battery_popup)
				BatteryWarningRestore();
			EvtAppendEvt(EVT_APP_STOP, 0, 0, 0, NULL);
			EvtAppendEvt(EVT_POWER_DOWN, 0, 0, 0, NULL);
			return TRUE;
		case IO_SOUND_PLAY:
		case (IO_SOUND_RECORD):
			if(SysGetAppID("Voice Memo", &voice_app) == TRUE)
			{
				SysGetAppID("Scheduler", &sch_app);
				SysGetAppID("Alarm Manager", &alarm_app);
				SysGetAppID("To Do List", &todo_app);
				
				active_app = SysGetActiveAppID();
				found = FormGetActiveFormID(&active_form_id);
				
				if (voice_app == active_app)
					return FALSE;                            
				else if (active_app == sch_app && found == TRUE && (active_form_id == FORM_SCH_REC || active_form_id == FORM_SCH_REPLAY))
					return FALSE;
				else if (active_app == todo_app && found == TRUE && (active_form_id == FORM_REPLAY_VOICE || active_form_id == FORM_RECORD_VOICE))
					return FALSE;
				else if (active_app == alarm_app && found == TRUE && active_form_id == FORM_PLAY_VOICE)
					return FALSE;
				else
				{
					cmd_ptr = (WORD*)pmalloc(sizeof(WORD));
					*cmd_ptr = Event->para2;
					EvtAppendEvt(EVT_APP_STOP, 0, 0, 0, NULL);
					EvtAppendEvt(EVT_APP_LAUNCH, voice_app, LAUNCH_CMD_VOXMEMO_LAUNCH, 0, (void*)cmd_ptr);
					return TRUE;
				}
			}
			return FALSE;
		case EVT_HOTSYN_KEY_PRESS:            
#ifndef COPY_SCREEN_ENABLE            
			if(hotsync_button_disabled==0)
			{
				if(SysGetAppID("PC Sync", &pcsync_app) == TRUE)
				{
					if(SysGetActiveAppID() != pcsync_app)
					{
						EvtAppendEvt(EVT_APP_STOP, 0, 0, 0, NULL);
						EvtAppendEvt(EVT_APP_LAUNCH, pcsync_app, LAUNCH_CMD_SYNC_START, 0, NULL);
					}
					else EvtAppendEvt(EVT_SYNC_START, 0, 0, 0, NULL);
					return TRUE;
				}
			}
			return FALSE;
#else
			UartInit(UART_A, UART_BAUD57600, UART_DATABIT8 | UART_PARITY_NONE | UART_STOPBIT1);
			SysEnableDebug();
			PrintScr();
			return TRUE;
#endif
			
		case IO_PHONE_BOOK:
			if (!SystemButtonTranslation(key_mapping.key1))
				return FALSE;
			return TRUE;
		case IO_TO_DO_LIST:
			if (!SystemButtonTranslation(key_mapping.key3))
				return FALSE;
			return TRUE;
		case IO_SCHEDULER:
			if (!SystemButtonTranslation(key_mapping.key5))
				return FALSE;
			return TRUE;
		default: return FALSE;			
		}
	}
    else if (Event->eventType == EVT_INLAY_SELECT && inlay_status == 1 &&
		battery_popup == FALSE)
    {
		
        key_mapping  = GKeyMapping;
        
		switch (Event->para1)
		{
		case INLAY_LEFT:
			if (!SystemButtonTranslation(key_mapping.key2))
    	           return FALSE;
			else
			{
				SndPlaySndEffect(SNDRES5_BEEP);
				return TRUE;
			}
			break;
		case INLAY_RIGHT:
			if (!SystemButtonTranslation(key_mapping.key4))
				return FALSE;
			else
			{
				SndPlaySndEffect(SNDRES5_BEEP);
				return TRUE;
			}
			break;
		default: return FALSE;			
		}
	}
	return FALSE;
}

/********************************************************
* Function:    SystemButtonTranslation
* Purpose:     This function is called to translate buttons and 
inlay regions to defined regions
* Scope:       application/internal
* Input:       key
* Output:      None
* Return:      TRUE if handled
FALSE if not handled
* Comment: 	None
*********************************************************/
BOOLEAN SystemButtonTranslation(BYTE key)
{
    AppID   app_id = 0xFFFF;
	
	
	switch (key)
	{
	case SYSETUP_ANNIVERSARIES:
		if (!SysGetAppID("Anniversaries", &app_id))
			return FALSE;
		break;                
	case SYSETUP_CALCULATOR:
		if (!SysGetAppID("Calculator", &app_id))
			return FALSE;
		break;	             	
	case SYSETUP_EMAIL:
		if (!SysGetAppID("Email", &app_id))
			return FALSE;
		break;	             	
	case SYSETUP_MEMO:
		if (!SysGetAppID("Memo", &app_id))
			return FALSE;
		break;	             	
	case SYSETUP_PHONEBOOK:
		if (!SysGetAppID("Phonebook", &app_id))
			return FALSE;
		break;	             	
	case SYSETUP_TO_DO_LIST:
		if (!SysGetAppID("To Do List", &app_id))
			return FALSE;
		break;	             	
	case SYSETUP_SCHEDULER:
		if (!SysGetAppID("Scheduler", &app_id))
			return FALSE;
		
		if(SysGetActiveAppID() == app_id)
		{
			if (gf_popup)
			{
				GlobalFindRestoreRunningApp();
				return TRUE;
			}					
			return FALSE;
		}	
		
		if (app_id != 0xFFFF)
		{
			EvtAppendEvt(EVT_APP_STOP, 0, 0, 0, NULL);
			EvtAppendEvt(EVT_APP_LAUNCH, app_id, LAUNCH_CMD_TODAY_SCH, 0, NULL);
			return TRUE;
		}
		return FALSE;				
	case SYSETUP_SKETCH:
		if (!SysGetAppID("Sketch", &app_id))
			return FALSE;
		break;	             	
	case SYSETUP_SYSTEM_SETUP:
		if (!SysGetAppID("System Setup", &app_id))
			return FALSE;
		break;	             	
	case SYSETUP_PC_SYNC:
		if (!SysGetAppID("PC Sync", &app_id))
			return FALSE;
		break;	             	
	case SYSETUP_VOICE_MEMO:
		if (!SysGetAppID("Voice Memo", &app_id))
			return FALSE;
		break;	             	
	case SYSETUP_EXPENSE:
		if (!SysGetAppID("Expense", &app_id))
			return FALSE;
		break;	             	
	case SYSETUP_JOT:
		if (!SysGetAppID("Jot", &app_id))
			return FALSE;
		break;	             	
	case SYSETUP_GLOBAL_FIND:
		break;
	default: return FALSE;
	}
	
    if(SysGetActiveAppID() == app_id)
	{
		if (gf_popup)
		{
			GlobalFindRestoreRunningApp();
			return TRUE;
		}					
		return FALSE;
	}	
	
	
    if (key == SYSETUP_GLOBAL_FIND)
    {
        if (!menu_status && !popup_status && !gf_popup)
        {
			GlobalFindPopupGlobalFind();
			return TRUE;
        }
        return FALSE;
    }
	
	
    if(SysGetActiveAppID() == app_id)
        return FALSE;
	
    if (app_id != 0xFFFF)
    {
        EvtAppendEvt(EVT_APP_STOP, 0, 0, 0, NULL);
        EvtAppendEvt(EVT_APP_LAUNCH, app_id, 0, 0, NULL);
        return TRUE;
    }
    return FALSE;
}

/********************************************************
* Function:    SystemSetMappedHardwareKeyStatus
* Purpose:     This function is called to enable the
the usage of the 3 mapped hardware buttons
* Scope:		application/internal
* Input:       status
* Output:		None
* Return:      None
* Comment: 	None
*********************************************************/
void SystemSetMappedHardwareKeyStatus(BOOLEAN status)
{
    mapped_hardware_button_enable = (BYTE)status;
}

/********************************************************
* Function:    SystemCheckMappedHardwareKeyStatus
* Purpose:     This function is called to enable the
the usage of the 3 mapped hardware buttons
* Scope:		application/internal
* Input:       status
* Output:		None
* Return:      TRUE    enabled
FALSE   disabled
* Comment: 	None
*********************************************************/
BOOLEAN SystemCheckMappedHardwareKeyStatus()
{
    return (BOOLEAN)mapped_hardware_button_enable;
}

/********************************************************
* Function:    SystemApplicationInit
* Purpose:     This function is called to initialise some system
variables before each running of a application               
* Scope:		application/internal
* Input:       status
* Output:		None
* Return:      None
* Comment: 	None
*********************************************************/
void SystemApplicationInit()
{
    KeyboardSetKeyboardStatus(FALSE);
    SystemSetMappedHardwareKeyStatus(TRUE);
    AlarmMgrEnable(TRUE);
    LcdEnableInsertPt(FALSE, 0, 0, SMALL_FONT);
    BatteryWarningSetEnableStatus(TRUE);
    LcdSetColorMode(BLACK_AND_WHITE_MODE);
	
	SysFontRestoreFont();
	KeyboardRestoreKeyboard();
	SysSetCustomInsertFunction(NULL);
	SysSetCustomBackspaceFunction(NULL);
}

/********************************************************
* Function:    SystemButtonTranslationWithoutPowerOff
* Purpose:     This function is called to translate buttons and 
inlay regions to defined regions
* Scope:       application/internal
* Input:       key
* Output:      None
* Return:      TRUE if handled
FALSE if not handled
* Comment: 	None
*********************************************************/
BOOLEAN SystemButtonTranslationWithoutPowerOff(BYTE key)
{
    AppID   app_id = 0xFFFF;
	
	
	switch (key)
	{
	case SYSETUP_ANNIVERSARIES:
		if (!SysGetAppID("Anniversaries", &app_id))
			return FALSE;
		break;                
	case SYSETUP_CALCULATOR:
		if (!SysGetAppID("Calculator", &app_id))
			return FALSE;
		break;	             	
	case SYSETUP_EMAIL:
		if (!SysGetAppID("Email", &app_id))
			return FALSE;
		break;	             	
	case SYSETUP_MEMO:
		if (!SysGetAppID("Memo", &app_id))
			return FALSE;
		break;	             	
	case SYSETUP_PHONEBOOK:
		if (!SysGetAppID("Phonebook", &app_id))
			return FALSE;
		break;	             	
	case SYSETUP_TO_DO_LIST:
		if (!SysGetAppID("To Do List", &app_id))
			return FALSE;
		break;	             	
	case SYSETUP_SCHEDULER:
		if (!SysGetAppID("Scheduler", &app_id))
			return FALSE;
		break;	             	
	case SYSETUP_SKETCH:
		if (!SysGetAppID("Sketch", &app_id))
			return FALSE;
		break;	             	
	case SYSETUP_SYSTEM_SETUP:
		if (!SysGetAppID("System Setup", &app_id))
			return FALSE;
		break;	             	
	case SYSETUP_PC_SYNC:
		if (!SysGetAppID("PC Sync", &app_id))
			return FALSE;
		break;	             	
	case SYSETUP_VOICE_MEMO:
		if (!SysGetAppID("Voice Memo", &app_id))
			return FALSE;
		break;	             	
	case SYSETUP_EXPENSE:
		if (!SysGetAppID("Expense", &app_id))
			return FALSE;
		break;	             	
	case SYSETUP_JOT:
		if (!SysGetAppID("Jot", &app_id))
			return FALSE;
		break;	             	
	case SYSETUP_GLOBAL_FIND:
		return FALSE;
	default: return FALSE;
	}
	
    if (app_id != 0xFFFF)
    {
        EvtAppendEvt(EVT_APP_STOP, 0, 0, 0, NULL);
        EvtAppendEvt(EVT_APP_LAUNCH, app_id, 0, 0, NULL);
        return TRUE;
    }
    return FALSE;
}


/********************************************************
* Function:    SysTranslateCustomiseButtonsWithoutPowerOff
* Purpose:     This function is called to trranslate the            
the customised buttons or inlay regions
to pre-defined functions.
* Scope:       application/internal
* Input:       Event           received event
* Output:      None
* Return:      TRUE if handled
FALSE if not handled
* Comment: 	None
*********************************************************/
BOOLEAN SysTranslateCustomiseButtonsWithoutPowerOff(EvtType *Event)
{
    AppID               pcsync_app, voice_app, tetris_app, pass_app;
    WORD                *cmd_ptr;
    KeyMappingSettings  key_mapping;
    WORD                temp;
	
	if (Event->eventType == EVT_IO_KEY_CTRL)
	{   
        if (Event->eventID != EVT_IO_KEY_PRESS && Event->eventID != EVT_IO_KEY_REPEAT)
            return FALSE;
		
        key_mapping  = GKeyMapping;
		
		switch (Event->para2)
		{
		case IO_SOUND_PLAY:
		case (IO_SOUND_RECORD):
			if(SysGetAppID("Voice Memo", &voice_app) == TRUE)
			{
				cmd_ptr = (WORD*)pmalloc(sizeof(WORD));
				*cmd_ptr = Event->para2;
				EvtAppendEvt(EVT_APP_STOP, 0, 0, 0, NULL);
				EvtAppendEvt(EVT_APP_LAUNCH, voice_app, LAUNCH_CMD_VOXMEMO_LAUNCH, 0, (void*)cmd_ptr);
				return TRUE;
			}
			return FALSE;
		case EVT_HOTSYN_KEY_PRESS:            
			if(SysGetAppID("PC Sync", &pcsync_app) == TRUE)
			{
				
				EvtAppendEvt(EVT_APP_STOP, 0, 0, 0, NULL);
				EvtAppendEvt(EVT_APP_LAUNCH, pcsync_app, LAUNCH_CMD_SYNC_START, 0, NULL);
				return TRUE;
			}
			return FALSE;
		case IO_PHONE_BOOK:
			if (!SystemButtonTranslationWithoutPowerOff(key_mapping.key1))
				return FALSE;
			return TRUE;
		case IO_TO_DO_LIST:
			if (!SystemButtonTranslationWithoutPowerOff(key_mapping.key3))
				return FALSE;
			return TRUE;
		case IO_SCHEDULER:
			if (!SystemButtonTranslationWithoutPowerOff(key_mapping.key5))
				return FALSE;
			return TRUE;
		default: return FALSE;			
		}
	}
    return FALSE;
}


/********************************************************
* Function:    SysDisableHotSyncButton()
* Purpose:     Disable the hot sync button                             
* Scope:       application/internal
* Input:       None
* Output:      None
* Return:      None
* Comment: 	None
*********************************************************/
void SysDisableHotSyncButton()
{
	hotsync_button_disabled = 1;
}

/********************************************************
* Function:    SysEnableHotSyncButton
* Purpose:     Enable the hot sync button
* Scope:       application/internal
* Input:       None
* Output:      None
* Return:      None
* Comment: 	None
*********************************************************/
void SysEnableHotSyncButton()
{
	hotsync_button_disabled = 0;
}

/********************************************************
* Function:    SysGetHotSyncButtonStatus
* Purpose:     Get the hot sync button status
* Scope:       application/internal
* Input:       None
* Output:      None
* Return:      0 if hot sync button is enabled
1 if hot sync button is disabled
* Comment: 	None
*********************************************************/
BYTE SysGetHotSyncButtonStatus()
{
	return hotsync_button_disabled;
}

