/************************************************************************
 * File : vdilaunch.c
 * Description : Virtual Desctop Interface code.
 ***********************************************************************/

#include <PalmOS.h>
#include "vdlaunch.h"
#include "vdlaunch_res.h"

/***********************************************************************
 * FUNCTION:    vdivLaunch()
 * DESCRIPTION: Launches VD image viewer and tells it what image to show,
 *              where and at what zoom level.
 * NOTE:        Avoid caling this function while there is an active form.
 * PARAMETERS:  imgname - image database name
 *              x,y - coordinats of the upper left corner shown
 *              z - initial zoom level
 * RETURNED:    returns launch error code
 ***********************************************************************/
Err vdivLaunch(char *imagename, UInt16 x, UInt16 y, UInt16 z)
{
   APP_LAUNCH_BLOCK_PTR lb_ptr;
   LocalID dbID = 0;
   UInt32  vdiRetCode;
   UInt32  a5;
   Err     error;
   UInt16  cardNo;
   UInt16  i;
   DmSearchStateType srchState;

   dbID = 0;
   // Find VDI viewer (not accounting for several DBs of the same creator)
   error = DmGetNextDatabaseByTypeCreator(true, &srchState, 
                                          sysFileTApplication,
                                          'DOB_', true, &cardNo,
                                          &dbID);
   while (error == errNone && dbID) 
   {
      lb_ptr = MemPtrNew(sizeof(APP_LAUNCH_BLOCK));
      if(!lb_ptr)
      {
         error = memErrNotEnoughSpace;
         break;
      }
      MemSet(lb_ptr, sizeof(APP_LAUNCH_BLOCK), 0);
      lb_ptr->ver = APP_LAUNCH_BLOCK_VER;
      lb_ptr->posX = x;
      lb_ptr->posY = y;
      lb_ptr->zoom = z;
      for(i = 0; *imagename && i < dmDBNameLength; i++, imagename++)
      {
         lb_ptr->name[i] = *imagename;
      }
      error = MemPtrSetOwner(lb_ptr, 0);
      if(error != errNone)
      {
         MemPtrFree(lb_ptr);
         break;
      }
      a5 = SysSetA5(0);
      SysSetA5(a5);
      error = SysAppLaunch(cardNo, dbID, 
                           sysAppLaunchFlagNewStack |
                           sysAppLaunchFlagNewGlobals |
                           sysAppLaunchFlagUIApp,
                           sysAppLaunchCmdNormalLaunch, lb_ptr, &vdiRetCode);
      SysSetA5(a5);
      /* Who should free the memory if launch fails ? */
      break;
   }
   return error;
}




/***********************************************************************
 * The following code demonstrates how to call the vdivLaunch() function
 ***********************************************************************/

/***********************************************************************
 * FUNCTION:    MainForm_HandleEvent
 * DESCRIPTION: Handles the MainForm events
 * PARAMETERS:  event   pointer to an event structure
 * RETURNED:    returns handled/not handled
 ***********************************************************************/
Boolean MainForm_HandleEvent(EventPtr event)
{
    Boolean handled = false;
    FormPtr form;

    /* Standard form event handling */
    switch (event->eType)
    {
        case frmOpenEvent:
            // Repaint form on open
            form = FrmGetActiveForm();
            FrmDrawForm(form);
            break;
        case keyDownEvent:
            if( event->data.keyDown.modifiers & commandKeyMask )
            {
               break;
            }
            switch(event->data.keyDown.chr)
            {
               case 'l':
               case 'L':
                  FrmGotoForm(VdivForm);
                  break;
            }
            break;
        default:
            break;
    }

    return handled;
}

/***********************************************************************
 * FUNCTION:    StartApplication
 * DESCRIPTION: This routine will launch the application's main form
 * PARAMETERS:  none
 * RETURNED:    returns nothing
 ***********************************************************************/
int StartApplication()
{
   /* Open main form */
   FrmGotoForm(MainForm);
   return 0;
}


/***********************************************************************
 * FUNCTION:    ApplicationHandleEvent
 * DESCRIPTION: This routine is called from the event loop, and its
 *                              main responsibility is to load forms and set
 *                              form eventhandlers.
 * PARAMETERS:   EventPtr       event   Pointer to the event
 * RETURNED:     handled/not handled
 ***********************************************************************/
Boolean ApplicationHandleEvent(EventPtr event)
{
    UInt16 formID;
    FormPtr form;
    Boolean handled = false;

    // Application event loop
    switch (event->eType)
    {
        case frmLoadEvent:
            // Handle form load events
            formID = event->data.frmLoad.formID;

            switch (formID)
            {
                case MainForm:
                    // Set event handler for MainForm
                    form = FrmInitForm(formID);
                    FrmSetActiveForm(form);
                    FrmSetEventHandler(form,(FormEventHandlerPtr)
                                       MainForm_HandleEvent);
                    break;
                case VdivForm:
                    vdivLaunch("BostonDowntown.bmp", 100, 200, 2);
                    FrmGotoForm(MainForm);
                    break;
                default:
                    break;
            }
            handled = true;
            break;
        default:
            break;
    }

    return handled;
}


/***********************************************************************
 * FUNCTION:    EventLoop
 * DESCRIPTION: The event loop polls the event queue for new events and
 *              dispatches them to the different event handlers.
 * PARAMETERS:  Nothing
 * RETURNED:    Nothing
 ***********************************************************************/
void EventLoop(void)
{
    Err error;
    EventType event;
    UInt16 tps;

    // Main event loop
    do
    {
        /* calculate delay */
        tps = SysTicksPerSecond();
        tps >>= 3;

        /* Get next event */
        EvtGetEvent(&event, tps);

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


/***********************************************************************
 * FUNCTION:     StopApplication
 * DESCRIPTION:  this routine closes all open forms by calling
 *               FrmCloseAllForms()
 * PARAMETERS:   Nothing
 * RETURNED:     Nothing
 ***********************************************************************/
void StopApplication(void)
{
   /* Cloase all forms */
   FrmCloseAllForms();
   return;
}

/***********************************************************************
 * FUNCTION:    PilotMain
 * DESCRIPTION: Main entrypoint for the application
 * PARAMETERS:  cmd             Application Launchcode
 *              cmbBPB          Pointer to a structure that is
 *                              associated with the launch code.
 *              launchFlags     value providing extra
 *                              information about the launch
 * RETURNED:    Result of the launch
 ***********************************************************************/
UInt32 PilotMain(UInt16 cmd, void *cmdPBP, UInt16 launchFlags)
{
    switch (cmd)
    {
        case sysAppLaunchCmdNormalLaunch:
            // Application start code
            if(StartApplication() != errNone)
            {
                return 1;
            }

            // Maintain event loop
            EventLoop();

            // Stop application
            StopApplication();
            break;
        default:
            break;
    }

    return 0;
}

