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


static void GadgetInit(FormType *form)
{
    UInt16    gadgetIndex = FrmGetObjectIndex(form, DrawingGadget);
    /* allocate memory for gadget's data, say 10 Bytes, below: */
    Char     *data = MemPtrNew(sizeof(Char[10]));
    if (data)
    {
        /* we should initialize the gadget data here */
        data[0]='\0';

        /* replace NULL with a pointer to your data */
        FrmSetGadgetData(form, gadgetIndex, data);

    }
}

static void GadgetShutDown(FormType *form)
{
    UInt16    gadgetIndex = FrmGetObjectIndex(form, DrawingGadget);
    MemHandle dataH;
    dataH = FrmGetGadgetData(form, gadgetIndex);
    if (dataH) MemHandleFree(dataH);
}

static void GadgetRedraw(FormType *form)
{
    UInt16        gadgetIndex = FrmGetObjectIndex(form, DrawingGadget);
    RectangleType bounds;
    MemHandle     dataH;
    Char         *data;
    FrmGetObjectBounds(form, gadgetIndex, &bounds);
    WinEraseRectangle(&bounds, 0);
    WinDrawRectangleFrame(rectangleFrame, &bounds);
    /* add your custom drawing code here */

    data = FrmGetGadgetData(form, gadgetIndex);
    if (data)
    {
        /* data is provided in case your custom draw needs to refer to it */

    }

}

static Boolean GadgetPenEvent(FormType *form, EventPtr eventP)
{
    /* STATIC: initialized only once, then keep values between Fn calls */
    static Int16 lastX=0, lastY=0;

    UInt16    gadgetIndex = FrmGetObjectIndex(form, DrawingGadget);
    RectangleType bounds;
    FrmGetObjectBounds(form, gadgetIndex, &bounds);
    if (RctPtInRectangle(eventP->screenX, eventP->screenY, &bounds))
    {
        switch (eventP->eType)
        {
            /* when the pen starts touching the digitizer */
            case penDownEvent:
                lastX = eventP->screenX;
                lastY = eventP->screenY;
                WinPaintPixel(lastX, lastY);
                break;

            /* note: pen movement can be detected only if it is dragged */
            case penMoveEvent:
                WinPaintLine(lastX, lastY, eventP->screenX, eventP->screenY);
                lastX = eventP->screenX;
                lastY = eventP->screenY;
                break;

            /* when the pen stops touching the digitizer */
            case penUpEvent:
                /* do nothing this time */
                break;

            default:
                break;
        }
        return(true);
    }
    else
    {
        return(false);
    }
}



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


static void StopApplication(void)
{
}


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

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

    switch (menuID) {
        case MainOptionsAbout:
            FrmAlert(AboutAlert);
            handled = true;
            break;

        default:
            break;
    }

    return handled;
}


static Boolean MainFormHandleEvent(EventPtr event)
{
    Boolean  handled = false;
    FormType *form   = FrmGetActiveForm();

    switch (event->eType) {
        case frmOpenEvent:
            GadgetInit(form);
            FrmDrawForm(form);
            GadgetRedraw(form);
            handled = true;
            break;

        case frmCloseEvent:
            GadgetShutDown(form);
            handled = true;
            break;

        case ctlSelectEvent:
            switch (event->data.ctlSelect.controlID) {
                case ClearButton:
                    GadgetRedraw(form);
                    handled = true;
                    break;

                default:
                    break;
            }
            break;

        case penDownEvent:
        case penMoveEvent:
        case penUpEvent:
            handled = GadgetPenEvent(form, event);
            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;
}