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


static void SendDataRealSend(Char *data)
{
    Err    error;
    static char buffer[256];


    error = SerialOpen();
    if (error == errNone)
    {
        /* SerialClearRead(); */
        FrmCustomAlert(ErrorAlert, "I am sending ", data, NULL);
        error = SerialWriteLine(data);
        SerialWaitWrite();
        if (error != errNone) {
            FrmCustomAlert(ErrorAlert, "Error sending ", data, NULL);
        } else {

            /* in the command mode:   the modem repeats the command and then send the reply   */
            /* in the connected mode: the modem only transmits the reply from the remote host */
            /* some modems add extra new lines. We must get rid of them */
            do
            {
                error = SerialReadLine(buffer, 255, 250); /* we will wait only up to 250ms */
            } while( error==errNone && buffer[0]==chrNull );
            if (error != errNone) {
                FrmCustomAlert(ErrorAlert, "ERROR receiving reply", NULL, NULL);
            } else {
                FrmCustomAlert(ErrorAlert, "The echo is: ", buffer, NULL);
        
                /* some modems add extra new lines. We must get rid of them */
                do
                {
                    error = SerialReadLine(buffer, 255, 250);
                } while( error==errNone && buffer[0]==chrNull );
                if (error != errNone) {
                    FrmCustomAlert(ErrorAlert, "ERROR receiving reply", NULL, NULL);
                } else {
                    FrmCustomAlert(ErrorAlert, "The reply is: ", buffer, NULL);
                }
            }
        }

    } else {
        char locbuf[26];
        StrIToA(locbuf, error);
        FrmCustomAlert(ErrorAlert, "I am sorry but I cannot open the craddle serial port. Error =", locbuf, NULL);
    }

    SerialClose();
}

static void SendDataHandler()
{
    FormType   *form = FrmGetActiveForm();
    FieldType  *field;
    MemHandle  hd;


    field = FrmGetObjectPtr(form, FrmGetObjectIndex(form, MainDataField));
    hd = FldGetTextHandle(field);
    if (hd) {
        Char  *d;
        d = MemHandleLock((void *)hd);
        SendDataRealSend(d);
        MemHandleUnlock((void *)hd);
    } else {
        FrmCustomAlert(ErrorAlert, "Anonymous user refused or no data to send.", NULL, NULL);
    }
}


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


static void StopApplication(void)
{
    SerialClose();
}

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


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

    switch (menuID) {
        case MainEditUndo:
            FldUndo(field);
            handled = true;
            break;
        case MainEditCut:
            FldCut(field);
            handled = true;
            break;
        case MainEditCopy:
            FldCopy(field);
            handled = true;
            break;
        case MainEditPaste:
            FldPaste(field);
            handled = true;
            break;
        case MainEditSelectAll:
            FldSetSelection(field, 0, FldGetTextLength(field));
            handled = true;
            break;

        case MainEditKeyboard:
            SysKeyboardDialog(kbdDefault);
            handled = true;
            break;

        case MainEditGraffitiHelp:
            SysGraffitiReferenceDialog(referenceDefault);
            handled = true;
            break;

        case MainOptionsAbout:
            FrmAlert(AboutAlert);
            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);
            FrmSetFocus(form, FrmGetObjectIndex(form, MainDataField));
            handled = true;
        }
            break;

        case ctlSelectEvent:
            switch (event->data.ctlSelect.controlID) {
                case MainSendButton:
                    SendDataHandler();
                    handled = true;
                    break;

                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) {
            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)
{
    Err  err=errNone;


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

        default:
            break;
    }

    return err;
}