#include <PalmOS.h>
#include "helloRsc.h"
#include "alarm.h"


static Err StartApplication(void)
{
    FrmGotoForm(MainForm);
    return errNone;
}


static void StopApplication(void)
{
}


static Boolean MainMenuHandleEvent(UInt16 menuID)
{
    Err        error    = errNone;
    Boolean    handled  = false;
    FormType   *form;
    FieldType  *field;

    form = FrmGetActiveForm();
    field = FrmGetObjectPtr(form, FrmGetFocus(form));

    switch (menuID) {
        /* menu items are handled here */

        case MainActAbout:
            FrmAlert(AboutAlert);
            handled = true;
            break;

        case MainActSetClr:
            error = ResetAlert();
            if (error!=errNone)
                FrmCustomAlert(InfoAlert, "Error:\nCannot reset the alert.", NULL, NULL);
            handled = true;
            break;

        case MainActSetOne:
        case MainActSetMul:
            error = SetAlert(30, !(menuID==MainActSetMul) );
            if (error==almErrMemory)
                FrmCustomAlert(InfoAlert, "Error:\nInsufficient memory.", NULL, NULL);
            else if (error==almErrFull)
                FrmCustomAlert(InfoAlert, "Error:\nAlarm table is full.", NULL, NULL);
            else if (error!=errNone)
                FrmCustomAlert(InfoAlert, "Error:\nCannot set the alert.", NULL, NULL);
            handled = true;
            break;

        case MainActSetExtra:
            FrmCustomAlert(InfoAlert, "Sorry:\nNot implemented yet.", NULL, NULL);
            handled = true;
            break;

        default:
            break;
    }

    return handled;
}


static Boolean MainFormHandleEvent(EventPtr event)
{
    Boolean  handled = false;

    switch (event->eType) {
        case frmOpenEvent:
        {
            FormType  *form = FrmGetActiveForm();
            FrmDrawForm(form);
            /* set focus to the default form element here */
            handled = true;
        }
            break;

        case ctlSelectEvent:
            switch (event->data.ctlSelect.controlID) {
                /* buttons are handled here */

                default:
                    break;
            }
            break;

        case menuEvent:
            handled = MainMenuHandleEvent(event->data.menu.itemID);
            break;

        default:
            break;
    }

    return handled;
}


static Boolean ApplicationHandleEvent(EventPtr event)
{
    FormType  *form;
    UInt16    formID;
    Boolean   handled = false;


    if (event->eType == frmLoadEvent) {
        formID = event->data.frmLoad.formID;
        form = FrmInitForm(formID);
        FrmSetActiveForm(form);

        switch (formID) {
            /* switching among available screens is handled here */
            case MainForm:
                FrmSetEventHandler(form, MainFormHandleEvent);
                break;

            default:
                break;
        }
        handled = true;
    }

    return handled;
}


static void EventLoop(void)
{
    EventType  event;
    UInt16     error;


    do {
        EvtGetEvent(&event, evtWaitForever);
        if (! SysHandleEvent(&event))
            if (! MenuHandleEvent(0, &event, &error))
                if (! ApplicationHandleEvent(&event))
                    FrmDispatchEvent(&event);
    } while (event.eType != appStopEvent);
}


UInt32 PilotMain(UInt16 launchCode, MemPtr cmdPBP, UInt16 launchFlags)
{
    SysAlarmTriggeredParamType *AlPar;
    Err  err=errNone;


    switch (launchCode) {
        case sysAppLaunchCmdNormalLaunch:
            if ((err = StartApplication()) == 0) {
                EventLoop();
                StopApplication();
            }
            break;

        case sysAppLaunchCmdSystemReset:
            /* No GUI allowed here */
            /* after reset the alarm setting is lost and must be set once again */
            break;

        case sysAppLaunchCmdSyncNotify:
            /* this is run after uploading the program to PDA */
            break;

        case sysAppLaunchCmdTimeChange:
            /* respond to the system time change, application should have registered
               with the OS before in order to receive this event */
            break;

        case sysAppLaunchCmdAlarmTriggered:
            /* schedule next alarm or/and perform a quick action such as sounding alarm */
            AlPar= (SysAlarmTriggeredParamType *) cmdPBP;

            SndPlaySystemSound(sndAlarm);
            if (AlPar->ref==0) err = SetAlert(30, 0);
            break;

        case sysAppLaunchCmdDisplayAlarm:
            /* display alarm dialog or perform a time consuming task associated witht he alarm */
            AlPar= (SysAlarmTriggeredParamType *) cmdPBP;

            if (AlPar->ref==0)
                FrmCustomAlert(InfoAlert, "Reccuring Alarm Procedure\nwas Activated!", NULL, NULL);
            else
                FrmCustomAlert(InfoAlert, "One Time Alarm Procedure\nwas Activated!", NULL, NULL);

            /* OR You can start the program as if it was a regular start
            if ((err = StartApplication()) == 0) {
                EventLoop();
                StopApplication();
            }
               OR you can provide another event loop and do something else interactively */

            break;

        default:
            break;
    }

    return err;
}