/*
================================ 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        :   alarmgr.c
Author(s)   :   Kenny Ng
Company     :   VTech Informations Ltd.
Project     :   Helio 
Date:	    :   October 1st, 1999
Purpose:	:   alarm manager
Revision    :   1.1
Note        :   None
===========================================================================
*/              

//#define DEBUG

#include "stdafx.h"
#include "platform.h"
#include "datatype.h"
//#include "kernel.h"
#include "tmrapi.h"
#include "alarmgr.h"
#include "str.h"
#include "uievent.h"
#include "alaunch.h"
#include "system.h"
#include "sysetup.h"
#include "sylang.h"

AlarmEventLink 			*alarmgr_list;
AlarmQueryLink 			*alarmgr_querylist;
AlarmHitLink 			*alarmgr_hitlist;
UBYTE 					alarm_enable, almcall_app;
UWORD 					prev_hitcount;
BYTE 					is_start;
AlarmExtraInfo 			alm_alert;

extern AppID 			prev_appid;
extern USHORT 			ClickPara;
extern volatile WORD    SndAction;


/* AlarmMgrInit                                         */
/* Purpose      Init alarm manager                      */
/* Scope	OS					*/
/* Input        None					*/
/* Output       None					*/
/* Return	None					*/
/* Comment						*/
void AlarmMgrInit()
{
	alarmgr_list = NULL;
	alarmgr_querylist = NULL;
	alarmgr_hitlist = NULL;
	AlmSetStatus(FALSE);	/* disable alarm */
	alarm_enable = 0;
	almcall_app = 0;
	alm_alert.type = TYPE_TONE;
	//18-Aug-2000
	prev_hitcount = 0;
}

/* AlarmTotalEvent                                      */
/* Purpose      Get total number of scheduled even      */
/* Scope        All                                     */
/* Input        None					*/
/* Output       None					*/
/* Return       Number of alarm event (hit and un-hit)  */
/* Comment						*/
USHORT AlarmTotalEvent(void)
{
	AlarmEventLink *ptr;
	USHORT total = 0;
	
	ptr = alarmgr_list;
	
	while(ptr) {
		total++;
		ptr = ptr->next;
	}
	
	return total;
}


BOOLEAN AlarmDelQuery(AppID app, UBYTE type){
	return TRUE;
}


/* AlarmFindEvent                                       */
/* Purpose      Find an event from the alarm queue      */
/*              if found, evt_ptr = found event         */
/*              else      evt_ptr = last event and      */
/*              the function return FALSE               */
/* Scope        Internal                                */
/* Input        alm_evt : the evt to find               */
/* Output       evt_ptr, the node of the found event    */
/* Return       TRUE                                    */
/*              FALSE                                   */
/* Comment                                              */
BOOLEAN AlarmFindEvent(AlarmEvent *alm_evt, AlarmEventLink **evt_ptr)
{
	AlarmEventLink *last_node;
	
	last_node = *evt_ptr = alarmgr_list;
	
	while(*evt_ptr){
		if(((*evt_ptr)->event->app == alm_evt->app)
			&& (AlarmGetEventType(((*evt_ptr)->event)) == AlarmGetEventType(alm_evt))
			&& ((*evt_ptr)->event->rec_id == alm_evt->rec_id)
			&& ((*evt_ptr)->event->reference == alm_evt->reference))
		{
			return TRUE;   /* found */
		}
		
		last_node = *evt_ptr;
		*evt_ptr = (*evt_ptr)->next;
	}
	
	*evt_ptr = last_node;
	
	return FALSE;
}



/* AlarmGetLastAlarmTime                                */
/* Purpose      Get last alarm of an App                */
/* Scope        Internal                                */
/* Input        appid                                   */
/* Output       last_time                               */
/* Return       TRUE                                    */
/*              FALSE                                   */
/* Comment                                              */
BOOLEAN AlarmGetLastAlarmTime(AppID appid, RTM* last_time)
{
	AlarmEventLink *last_node;
	RTM max_rtm;
	BYTE found = 0;
	
	max_rtm.year = 1900;
    max_rtm.wday = 0;
	max_rtm.mon = 0;
    max_rtm.mday = 1;
	max_rtm.hour = 0;
	max_rtm.min = 0;
	max_rtm.sec = 0;
	max_rtm.msec = 0;
	
	last_node = alarmgr_list;
	
	while(last_node)
	{
		if (last_node->event->app == appid){
			if(RtcCompareTime(&(last_node->event->hit_time),&max_rtm))
				max_rtm = last_node->event->hit_time;
			
			found = 1;
		}
		last_node = last_node->next;
	}
	
    if( found && last_time) {
		*last_time = max_rtm;
	} else if(last_time) {
		RtcGetTime(last_time);
	}
	
	return (BOOLEAN) found;
}



/* AlarmAddEvent                                        */
/* Purpose      Add an new event                        */
/* Scope        All                                     */
/* Input        None					*/
/* Output       None					*/
/* Return       TRUE                                    */
/*              FALSE                                   */
/* Comment      If the event already exist, the old one */
/*              will be replaced by the new event       */
BOOLEAN AlarmAddEvent(AlarmEvent alm_evt)
{
	AlarmEventLink* evt_ptr;
	RTM alarm_time, cur_time;
#ifdef DEBUG
	BYTE buf[30];
#endif
	
	RtcGetTime(&cur_time);
#ifdef DEBUG
	RtcFormatDate(&cur_time, NULL, buf);
	printf("\nAdd Alarm,  current time: %s", buf);
	RtcFormatDate(&alm_evt.hit_time, NULL, buf);
	printf("\nAlarm time %s ", buf);
#endif
	
	
	if (AlarmGetEventClass(&alm_evt) == ALARM_ONDAY) {
		alm_evt.hit_time.hour = 0;
		alm_evt.hit_time.msec = 0;
		alm_evt.hit_time.min = 0;
		alm_evt.hit_time.sec = 0;
	}
    else
    {
		
#ifdef PR31700 
		if(RtcCompareTime(&cur_time, &alm_evt.hit_time))  /* alm_evt.hit_time < current time */
        {
#ifdef DEBUG
			printf("\nAlarmAddEvent: Invalid date time ! ");
#endif
			return FALSE;   /* do not accept alm time < current time */
		}
#endif
	}
	
	if(!AlarmFindEvent(&alm_evt, &evt_ptr))
	{  /* alarm not exist, evt_ptr is the last node */
		if (evt_ptr == NULL)  /* queue is empty */
		{
			alarmgr_list = (AlarmEventLink*) pmalloc(sizeof(AlarmEventLink));
			alarmgr_list->event = (AlarmEvent*) pmalloc(sizeof(AlarmEvent));
			evt_ptr = alarmgr_list;
			evt_ptr->next = NULL;
		}
		else //if(evt_ptr == alarmgr_list)
		{
			evt_ptr->next = (AlarmEventLink*) pmalloc(sizeof(AlarmEventLink));
			evt_ptr = evt_ptr->next;
			evt_ptr->event = (AlarmEvent*) pmalloc(sizeof(AlarmEvent));
			evt_ptr->next = NULL;
		}
	}
	else
	{
		if(evt_ptr->event->alert_msg)
			pfree(evt_ptr->event->alert_msg);
		if(evt_ptr->event->extra_info)
			pfree(evt_ptr->event->extra_info);
	}
	
	if(!evt_ptr) {
#ifdef DEBUG
		printf("\nCannot allcate space for new alarm event ");
#endif
		
		return FALSE;
	}
	
	*(evt_ptr->event) = alm_evt;
	
	if(alm_evt.alert_msg)   /* msg not NULL */
	{
		evt_ptr->event->alert_msg = (BYTE*) pmalloc(strlen(alm_evt.alert_msg)+1);
		if(!evt_ptr->event->alert_msg)
		{
#ifdef DEBUG
			printf("\nCannot allocate space for new alarm message, set pointer to NULL ");
#endif
		}
		else
		{
			strcpy(evt_ptr->event->alert_msg, alm_evt.alert_msg);
		}
	}
	else
	{
		evt_ptr->event->alert_msg = NULL;
	}
	
	if(alm_evt.extra_info)   /* extra info not NULL */
	{
		evt_ptr->event->extra_info = (AlarmExtraInfo*) pmalloc(sizeof(AlarmExtraInfo));
		if(!evt_ptr->event->extra_info)
		{
#ifdef DEBUG
			printf("\nCannot allocate space for new alarm extra info, set pointer to NULL ");
#endif
		}
		else
		{
			*(evt_ptr->event->extra_info) = *(alm_evt.extra_info);
		}
	}
	else
	{
		evt_ptr->event->extra_info = NULL;
	}
	
	/* no specify time */
	if (AlarmGetEventClass(&alm_evt) == ALARM_ONDAY)
	{
		alm_evt.hit_time.hour = 0;
		alm_evt.hit_time.msec = 0;
		alm_evt.hit_time.min = 0;
		alm_evt.hit_time.sec = 0;
		return TRUE;
	}
	
	if(alarm_enable)
	{
		AlmGetTime(&alarm_time);  /* compare the new event with next alarm event */
		if (RtcCompareTime(&alarm_time, &alm_evt.hit_time))  /* cur > hit */
		{
			AlmSetTime(&alm_evt.hit_time);   /* update new alarm time */
			AlmSetStatus(TRUE);
		}
	}
	else
	{
		AlmSetTime(&alm_evt.hit_time);
		AlmSetStatus(TRUE);
		alarm_enable = TRUE;
	}
	
	return TRUE;
}


/* AlarmDelEvent                                        */
/* Purpose      delete an event                         */
/* Scope        All                                     */
/* Input        alm_evt                                 */
/* Output       None									*/
/* Return       TRUE                                    */
/*              FALSE                                   */
/* Comment                                              */
BOOLEAN AlarmDelEvent(AlarmEvent alm_evt)
{
	return AlarmDelEventEx(alm_evt, TRUE);
}

/* AlarmDelEventEx                                      */
/* Purpose      delete an  event                        */
/* Scope        Internal                                */
/* Input        alm_evt                                 */
/*              remove_node                             */
/* Output       None					*/
/* Return       TRUE                                    */
/*              FALSE                                   */
/* Comment                                              */
BOOLEAN AlarmDelEventEx(AlarmEvent alm_evt, BOOLEAN remove_node)
{
	AlarmEventLink *ptr, *prev_node;
	
	prev_node = ptr = alarmgr_list;
	
#ifdef DEBUG
    printf("\n appid = %d", alm_evt.app);
    printf("\nEvttype = %d",  AlarmGetEventType((&alm_evt)));
    printf("\nref = %d ", alm_evt.reference);
#endif
	
	while(ptr)
	{
#ifdef DEBUG
		printf("\n appid = %d ", ptr->event->app);
		printf("\nEvtType = %d", AlarmGetEventType(ptr->event));
		printf("\nreference = %d ", ptr->event->reference);
#endif
		
		if ((ptr->event->app == alm_evt.app) 
			&& (AlarmGetEventType(ptr->event) == AlarmGetEventType((&alm_evt))) 
			&& (ptr->event->rec_id == alm_evt.rec_id) 
			&& (ptr->event->dbid == alm_evt.dbid) 
			&& (ptr->event->reference == alm_evt.reference))
		{
			break;
		}
		
		prev_node = ptr;
		ptr = ptr->next;
	}
	
	if(!ptr)
    {
#ifdef DEBUG
		printf("\nDel evt not found");
#endif
		return FALSE;   /* not found */
    }
	
	if((prev_node == alarmgr_list) && (ptr == alarmgr_list))
		alarmgr_list = ptr->next;      /* first event met */
	else
		prev_node->next = ptr->next;
	
	if(alarmgr_list)		/* set new alm time to ensure the current one is not the scheduled one */
	{
#ifdef DEBUG
		printf("\n-------------------------------\nCannot disable alarm ");
#endif
		AlmSetTime(&(alarmgr_list->event->hit_time));
		AlarmSetAlarm();
	}
	else
	{
#ifdef DEBUG
		printf("\n--------------------\nAlarm Disabled");
#endif
		AlmSetStatus(FALSE);	/* no more alarm, so disable it */
		alarm_enable = FALSE;
	}
	
	/* free the node */
	if(remove_node)
	{
		if(ptr->event->alert_msg)
			pfree(ptr->event->alert_msg);
		if(ptr->event->extra_info)
			pfree(ptr->event->extra_info);
		pfree(ptr->event);
		pfree(ptr);
	}
	
	return TRUE;
}

/* AlarmAddHit                                       */
/* Purpose      Insert an hit event                     */
/* Scope        Internal                                */
/* Input        alm_evt                                 */
/* Output       None					*/
/* Return       TRUE                                    */
/*              FALSE                                   */
/* Comment                                              */
BOOLEAN AlarmAddHit(AlarmEvent *alm_evt)
{
	AlarmHitLink *head;
	AlarmEventLink* evt_ptr;
	
	if(!AlarmFindEvent(alm_evt, &evt_ptr))
		return FALSE;
	
	head = (AlarmHitLink*) pmalloc(sizeof(AlarmHitLink));
	
	if(!head)
	{
#ifdef DEBUG
		printf("\nCannot allocate memory to add new alarm hit event ");
#endif
		return FALSE;
	}
	
	head->next = alarmgr_hitlist;
	head->event = evt_ptr->event;
	head->status = ALARM_NEW;
	alarmgr_hitlist = head;
	
	AlarmDelEventEx(*alm_evt, FALSE);
	AlarmAddQuery(alm_evt->app, AlarmGetEventType(alm_evt), alm_evt->rec_id, alm_evt->reference, alm_evt->dbid, alm_evt->hit_time);
	return TRUE;
}

/* AlarmDelHit                                          */
/* Purpose      delete an  event                        */
/* Scope        AlarmMgr UI application only            */
/* Input        alm_evt                                 */
/*              remove_node                             */
/* Output       None					*/
/* Return       TRUE                                    */
/*              FALSE                                   */
/* Comment                                              */
BOOLEAN AlarmDelHit(AlarmEvent alm_evt)
{
	AlarmHitLink *ptr, *prev_node;
	
	prev_node = ptr = alarmgr_hitlist;
	
	while(ptr)
	{
		if ((ptr->event->app == alm_evt.app) 
			&& (AlarmGetEventType((ptr->event)) == AlarmGetEventType((&alm_evt)))
			&& (ptr->event->rec_id == alm_evt.rec_id) 
			&& (ptr->event->reference == alm_evt.reference))
		{
			break;
		}
		prev_node = ptr;
		ptr = ptr->next;
	}
	
	if(!ptr)
		return FALSE;   /* not found */
	
	if((prev_node == alarmgr_hitlist) && (ptr == alarmgr_hitlist))
		alarmgr_hitlist = ptr->next;      /* first event met */
	else
		prev_node->next = ptr->next;
	
	/* free the node */
	if(ptr->event->alert_msg)
		pfree(ptr->event->alert_msg);
	if(ptr->event->extra_info)
		pfree(ptr->event->extra_info);
	
	pfree(ptr->event);
	pfree(ptr);
	
	return TRUE;
}

/* AlarmDelAllHit
/* Purpose		Delete all hit alarm
/* Scope		All
/* Input		None
/* Output		None
/* Return		None
/* Comment												*/
void AlarmDelAllHit()
{
	while(alarmgr_hitlist)
		AlarmDelHit(*(alarmgr_hitlist->event));
}

/* AlarmDelAll
/* Purpose		Delete all alarm of a specific application
/* Scope		All
/* Input		None
/* Output		None
/* Return		None
/* Comment												*/
void AlarmDelAppEvent(AppID appid)
{
	AlarmEventLink *ptr, *prev_node;
	
	prev_node = ptr = alarmgr_list;
	
	while(ptr)
	{
		if(ptr->event->app == appid)
		{
			//                        if((ptr == alarmgr_list) &&
			//                          (!alarmgr_list->next))
			//                             alarmgr_list = NULL;
			AlarmDelEvent(*(ptr->event));
			ptr = alarmgr_list;
		}
		else
		{
			ptr = ptr->next;
		}
	}
}


/* AlarmAddQuery                                        */
/* Purpose      add a query app                         */
/* Scope        Internal                                */
/* Input        app                                     */
/*              type                                    */
/* Output       None					*/
/* Return       TRUE                                    */
/*              FALSE                                   */
/* Comment                                              */
//BOOLEAN AlarmAddQuery(AppID app, UBYTE type, RecordID rec_id, USHORT reference, DatabaseID dbid, RTM hit_time)
BOOLEAN AlarmAddQuery(AppID app, UBYTE type, RecordID rec_id, UWORD reference, DatabaseID dbid, RTM hit_time)
{
	AlarmQueryLink *ptr;
    AlarmEventHit *evt_hit;
	
	ptr = (AlarmQueryLink*) pmalloc(sizeof(AlarmQueryLink));
	
	if(!ptr)
	{
#ifdef DEBUG
		printf("\nAlarmMgr: Cannot allocate memory for new query app ");
#endif
		return FALSE;
	}
	
	evt_hit = (AlarmEventHit*) pmalloc(sizeof(AlarmEventHit));
	
	if(!evt_hit)
	{
#ifdef DEBUG
		printf("\nAlarmMgr: Cannot allocate memory for new query app ");
#endif
		
		return FALSE;
	}
	
	ptr->app = app;
    ptr->evt_hit_ptr = evt_hit;
    evt_hit->type = type;
    evt_hit->rec_id = rec_id;
    evt_hit->reference = reference;
    evt_hit->dbid = dbid;
    evt_hit->hit_time = hit_time;
	ptr->next = alarmgr_querylist;
	alarmgr_querylist = ptr;
	
	return TRUE;
}

/* AlarmSetAlarm                                        */
/* Purpose      Set next alarm time                     */
/* Scope        Internal                                */
/* Input        None                                    */
/* Output       None					*/
/* Return       None					*/
/* Comment                                              */
void AlarmSetAlarm()
{
	/* go through all event, find the most recent one, set it to alarm */
	AlarmEventLink *ptr;
	RTM min_time;
	
	if(!alarmgr_list)	/* not scheduled event */
		return;
	
	min_time = alarmgr_list->event->hit_time;
	
	ptr = alarmgr_list->next;
	
	while(ptr)
	{
		if(RtcCompareTime(&min_time, &(ptr->event->hit_time)))  /* min > comp */
			min_time = ptr->event->hit_time;
		
		ptr = ptr->next;
	}
	
	AlmSetTime(&min_time);
#ifdef DEBUG
    printf("\n AlmMgr set next alarm time: %d %d %d ",min_time.hour, min_time.min, min_time.sec);
#endif
	AlmSetStatus(TRUE);
	alarm_enable = TRUE;
}




/* AlarmMgrEnable
/* Purpose		Enable/Disable Alarm Manager
/* Input		enable	- TRUE:  enable AM
/*						  FALSE: disable AM
/* Output		None
/* Return		None
/* Comment										*/
void AlarmMgrEnable(BOOLEAN enable)
{
	if(enable)
	{
		AlmSetStatus(TRUE);
		alarm_enable = TRUE;
		AlarmOnHit();
	}
	else
	{
		AlmSetStatus(FALSE);
		alarm_enable = FALSE;
	}
}

/* AlarmQueryApp
/* Purpose		Query hit applications for next alarm
/* Input		None
/* Output		None
/* Return		None
/* Comment										*/
void AlarmQueryApp()
{
	AppID active_appid;
	AlarmQueryLink *tmp_lnk, *pre_lnk;
	void (*mainfct)(WORD, void*);
	
	
	if(alarmgr_querylist)
	{
		active_appid = SysGetActiveAppID();
		tmp_lnk = alarmgr_querylist;
		
		while(tmp_lnk)
		{
			if(tmp_lnk->app == active_appid)       /* call current app */
			{
				mainfct = (void*)0x10000020;
				(*mainfct)(LAUNCH_CMD_ALARM_HIT, (void*)tmp_lnk->evt_hit_ptr);
			}
			else
			{
				SysRunMode1App(tmp_lnk->app, LAUNCH_CMD_ALARM_HIT, tmp_lnk->evt_hit_ptr);
			}
			
			pre_lnk = tmp_lnk;
			tmp_lnk = tmp_lnk->next;
			pfree(pre_lnk);
		}
		
		alarmgr_querylist = NULL;
	}
}

/* AlarmSetAlertType                                    */
/* Purpose      Set alert type                          */
/* Scope        Internal                                */
/* Input        type, dbid, rec_id, field_num           */
/* Output       None					*/
/* Return       None					*/
/* Comment                                              */
void AlarmSetAlertType(UBYTE type, DatabaseID dbid, RecordID rec_id, USHORT field_num)
{
	alm_alert.type = type;
	alm_alert.dbid = dbid;
	alm_alert.rec_id = rec_id;
	alm_alert.field_num = field_num;
#ifdef DEBUG
    printf("\n\nSet Alert type to %d ", alm_alert.type);
#endif
}


/* AlarmGetAlertType                                    */
/* Purpose      Get alert type                          */
/* Scope        Internal                                */
/* Input        type, dbid, rec_id, field_num           */
/* Output       None					*/
/* Return       None					*/
/* Comment                                              */
UBYTE AlarmGetAlertType(UBYTE *type, DatabaseID *dbid, RecordID *rec_id, USHORT *field_num)
{
#ifdef DEBUG
    printf("\n\nAlert type = %d ", alm_alert.type);
#endif
	*type = alm_alert.type;
	*dbid = alm_alert.dbid;
	*rec_id = alm_alert.rec_id;
	*field_num = alm_alert.field_num;
	
	return alm_alert.type;
}

/* AlarmOnHit                                           */
/* Purpose      Call when alarm hit                     */
/* Scope        Internal                                */
/* Input        None                                    */
/* Output       None					*/
/* Return       None					*/
/* Comment                                              */
void AlarmOnHit()
{
	RTM cur_time;
	AlarmEventLink *list;
	AppID alarmgr_appid, app_id;
	AlarmQueryLink *tmp_lnk, *pre_lnk;
	LLONG time_diff;
	BYTE new_event = 0;
	BYTE new_voice = 0;
	
	list = alarmgr_list;
	RtcGetTime(&cur_time);
	
	AlmSetStatus(FALSE);
	alarm_enable = FALSE;
	
	/* go through the list to found the hit event */
	while(list)
	{
		if (RtcCompareTime(&cur_time, &(list->event->hit_time)))
		{
			/* cur >= event hit, make it hit */
			time_diff.h = 0;
			time_diff.l = ALARM_HIT_DELAY - 1;
		}
		else
			time_diff = RtcDiffTime(&cur_time, &(list->event->hit_time));
		
		if( (time_diff.h == 0) && (time_diff.l < ALARM_HIT_DELAY) )  /* match */
		{
			AlarmAddHit(list->event);
			new_event = 1;
			if(!new_voice)
			{
				if(list->event->extra_info)
				{
					if(list->event->extra_info->type == TYPE_VOICE)
					{
						new_voice = 1;
						AlarmSetAlertType(TYPE_VOICE, list->event->extra_info->dbid, list->event->extra_info->rec_id, list->event->extra_info->field_num);
					}
				}
			}
		}
		list = list->next;
	}
	
	AlarmSetAlarm();  /* alm will enable again by AlarmSetAlarm() */
	
	if(alarmgr_hitlist)
	{
		if(new_event && (!new_voice))
		{
            if (ClickPara < ALARMMGR_MIN_SOUND_VOLUME)
                SndSetSndSettings(13, -1, 28, 2);			
			
			SndPlaySndEffect(SNDRES_KOOKOO);
			SndPlaySndEffect(SNDRES_KOOKOO);
			SndPlaySndEffect(SNDRES_KOOKOO);
			AlarmSetAlertType(TYPE_TONE, 0, 0, 0);
		}
		
		if(!SysGetRealActiveAppID())
			return;
		
		if (AlarmCallApp())
		{
			if (prev_hitcount < AlarmHitCount())
			{
				SysGetAppID(MAINMENU, &app_id);
				EvtAppendEvt(EVT_APP_STOP, 0, 0, 0, NULL);
				EvtAppendEvt(EVT_APP_LAUNCH, app_id, 0, 0, NULL);
				return;
			}
			else return;
		}
		
		SysGetAppID(ALARMGR, &alarmgr_appid);
		if((SysGetActiveAppID() == alarmgr_appid) && !(new_event))
			return;
		prev_appid = SysGetActiveAppID();
		if(prev_appid == 0)
			prev_appid = 1;
		AlarmSetCallApp();
		EvtAppendEvt(EVT_APP_STOP, 0, 0, 0, NULL);
		EvtAppendEvt(EVT_APP_LAUNCH, alarmgr_appid, 0, 0, NULL);
	}
}

/* AlarmPwrUpCheck
/* Purpose		Check for ONDAY event when system power on
/* Scope		OS
/* Input		None
/* Output		None
/* Return		None
/* Comment												*/
void AlarmPwrUpCheck()
{
	RTM cur_time;
	AlarmEventLink *list;
	LLONG time_diff;
#ifdef DEBUG
	BYTE buf[25];
#endif
	
	list = alarmgr_list;
	RtcGetTime(&cur_time);
#ifdef DEBUG
	RtcFormatDate(&cur_time, NULL, buf);
	printf("\nAlarm Hit, current time: %s", buf);
#endif
	
	AlmSetStatus(FALSE);
	alarm_enable = FALSE;
	
	/* go through the list to found the hit event */
	while(list)
	{
		if( AlarmGetEventClass(list->event) == ALARM_ONDAY)
		{
			if (RtcCompareTime(&cur_time, &(list->event->hit_time)))
			{  /* cur >= event hit, make it hit */
				time_diff.h = 0;
				time_diff.l = ALARM_HIT_DELAY - 1;
			}
			else
			{ 
				time_diff = RtcDiffTime(&cur_time, &(list->event->hit_time));
			}
			
			if( (time_diff.h == 0) && (time_diff.l < ALARM_HIT_DELAY) )  /* match */
			{
#ifdef DEBUG
				printf("\nHit Event: %s", list->event->alert_msg);
#endif
				AlarmAddHit(list->event);
			}
		}
		
		list = list->next;
	}
	
	AlarmOnHit();
}


/* AlarmHitCount                                        */
/* Purpose      get total hit                           */
/* Scope        All                                     */
/* Input        None                                    */
/* Output       None                                    */
/* Return       Total Hit                               */
/* Comment                                              */

UWORD AlarmHitCount()
{
	UWORD total_hit = 0;
    
    AlarmHitLink *ptr;
    ptr = alarmgr_hitlist;
    while(ptr)
    {
		total_hit++;
		ptr = ptr->next;
    }
	
    return total_hit;
}

/* AlarmGetVariable                                     */
/* Purpose      get system variable                     */
/* Scope        AlarmMgr UI application only            */
/* Input        None                                    */
/* Output       alarm_list, alarm_hit, alarm_query	*/
/*              alarm_en                                */
/* Return       None					*/
/* Comment                                              */
void AlarmGetVariable(AlarmEventLink **alarm_list, AlarmHitLink **alarm_hit,
					  AlarmQueryLink **alarm_query, UBYTE *alarm_en)
{
	if(alarm_list)
		*alarm_list = alarmgr_list;
	if(alarm_hit)
		*alarm_hit = alarmgr_hitlist;
	if(alarm_query)
		*alarm_query = alarmgr_querylist;
	if(alarm_en)
		*alarm_en = alarm_enable;
}

BOOLEAN AlarmCallApp()
{
	return (BOOLEAN) almcall_app;
}

void AlarmSetCallApp()
{
    almcall_app = 1;
#ifdef DEBUG
    printf("\nSet APP");
#endif
}

void AlarmResetCallApp()
{
    almcall_app = 0;
#ifdef DEBUG
    printf("\nReSet APP");
#endif
}

//18-Aug-2000
void AlarmSaveAlarmHitCount()
{
	prev_hitcount = AlarmHitCount();
}

void AlarmRestoreSoundSettings()
{
	SoundSettings sound;
	
	//wait for any sound recording/playing to stop
	while (SndAction);
	
	if (!SySetupGetSoundSettings(&sound))
		return;
	
	if (sound.click_max -  sound.click_min < 1)
	{
		sound.click_max = 14;
		sound.click_min = 0;
	}
	
	if ((sound.vol_curr == 0) && (sound.click_curr == 0))
	{
		if (!SndSetSndSettings((SHORT)SND_MAX_GAIN,	0, 0, 3))
			return;
	}
	else if(sound.vol_curr == 0)
	{
		if (!SndSetSndSettings((SHORT)SND_MAX_GAIN,	0, (SHORT)((4*sound.click_curr)/(sound.click_max-sound.click_min)+23), 3))
			return;
	}
	else if(sound.click_curr == 0)
	{
		if (!SndSetSndSettings((SHORT)SND_MAX_GAIN,	(SHORT)((8*sound.vol_curr)/(sound.click_max-sound.click_min)+23), 0, 3))
			return;
	}
	else
	{
		if (!SndSetSndSettings((SHORT)SND_MAX_GAIN,	(SHORT)((8*sound.vol_curr)/(sound.click_max-sound.click_min)+23),
			(SHORT)((4*sound.click_curr)/(sound.click_max-sound.click_min)+23), 3))
		{
			return;
		}
	}	
}