/* :ts=8 */
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
/*                                                              */
/*      SampleMain.c                                            */
/*                                                              */
/*      Main program for AmigaPLUS article about Intuition     */
/*      Written by Michael G. Lehman                            */
/*      of Intuitive Technologies                               */
/*                                                              */
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/


/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
/*      Complete Include file for Amiga programs                */
/*      Derived from examples supplied by Commodore Amiga       */
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/


#include <exec/types.h>
#include <exec/nodes.h>
#include <exec/lists.h>
#include <exec/memory.h>
#include <exec/ports.h>
#include <exec/tasks.h>
#include <exec/libraries.h>
#include <exec/devices.h>
#include <exec/io.h>
#include <exec/devices.h>

#include <libraries/dos.h>

#include <graphics/gfx.h> /* ALWAYS INCLUDE GFX.H before other includes */
#include <graphics/display.h>
#include <graphics/clip.h>
#include <graphics/rastport.h>
#include <graphics/gfxbase.h>
#include <graphics/text.h>
#include <graphics/regions.h>
#include <graphics/copper.h>
#include <graphics/gels.h>

#include <devices/inputevent.h>
#include <devices/gameport.h>
#include <devices/console.h>
#include <devices/keymap.h>

#include <intuition/intuition.h>


extern UBYTE * AllocMem();

#define SECONDS io_Actual
#define MICROSECONDS io_Length

/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
/*                                                              */
/*      Global variables                                        */
/*                                                              */
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/

long GfxBase = {0};             /* storage for pointers from OpenLibrary */
long DiskfontBase=0;
long IntuitionBase=0;
long LayersBase = 0;

struct Window *OpenWindow();
struct InputEvent *Intuition();
struct Screen *OpenScreen();

extern struct MsgPort *CreatePort();
extern struct IOStdReq *CreateStdIO();

struct IOStdReq *message2;              /* used for calling getmsg */


/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
/*                                                              */
/*      These variables are used to wait for and get info       */
/*      From Intuition                                          */
/*                                                              */
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/


ULONG wakeupbit;        /* timer bit or event bit wake us up? */
ULONG waitbits;         /* global wait bits, updated by make/shut window */


USHORT class;                   /* type of message */
USHORT code;                    /* modifier        */
USHORT qualifier;               /* such as shift, alt keys */
USHORT mousex;                  /* horizontal mouse position */
USHORT mousey;                  /* vertical   mouse position */

USHORT mode;            /* mode of operation */
APTR address;           /* address of the gadget which we hit */


struct Screen *screen;
struct RastPort *rp;
struct ViewPort *vp;
struct IntuiMessage *message;
struct Message *msg;
struct Process *my_process;

struct Window *window;

struct XMenuItem                /* our extended menu structure */
{
        struct MenuItem *NextItem;
        SHORT LeftEdge, TopEdge;
        SHORT Width, Height;
        USHORT Flags;
        LONG MutualExclude;
        APTR ItemFill;
        APTR SelectFill;
        BYTE Command;
        struct MenuItem *SubItem;
        USHORT NextSelect;
        int (*ItemHndlr)();     /* all above is standard and we add this */
};

struct Menu *InitMenu();


                        /****************************************/
extern HandleEvent();   /* returns TRUE if we should quit       */
                        /****************************************/


/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
/*                                                              */
/*      The M A I N program                                     */
/*                                                              */
/*      In this version we keep it simple.  Next time we will   */
/*      add the ability to pass arguments (projects) into our   */
/*      application and determine if they came from the CLI or  */
/*      Workbench, setup directories, etc.                      */
/*                                                              */
/*                                                              */
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
/*      But for now:                                            */
/*                                                              */
/*      1.      Initialize environment                          */
/*                                                              */
/*      2.      Build menu strip                                */
/*                                                              */
/*      3.      Open Window                                     */
/*                                                              */
/*      4.      Handle events until quit                        */
/*                                                              */
/*      5.      Clear menu strip                                */
/*                                                              */
/*      6.      Close Window                                    */
/*                                                              */
/*      7.      Shutdown environment                            */
/*                                                              */
/*      8.      And exit                                        */
/*                                                              */
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/


main(argc,argv)
int argc;
char **argv;
{


        GfxBase = OpenLibrary("graphics.library", 0);
        if (GfxBase == NULL)
        {
                exit();
        }
        IntuitionBase = OpenLibrary("intuition.library", 0);
        if (IntuitionBase == NULL)
        {
                exit();
        }
        DiskfontBase = OpenLibrary("diskfont.library", 0);
        if (DiskfontBase == NULL)
        {
                exit();
        }
        LayersBase = OpenLibrary("layers.library",0);
        if (LayersBase == NULL)
        {
                exit();
        }

        InitAppl();             /* call appl specific init code */

        /*---------------------------------*/
        /* The call above opens our window */
        /*---------------------------------*/

        class=0;  code =0;  /* initialize */

        wakeupbit = 0;

        /*----------------------------------------------*/
        /* InitMenu returns a pointer to our menu strip */
        /*----------------------------------------------*/

        SetMenuStrip(window, InitMenu(window->WScreen,window));

/*--------------------------------------------------------------------*/
/* get the signal bit we wait on (for Intuition to send us a message) */
/*--------------------------------------------------------------------*/

        waitbits  = (1 << window -> UserPort -> mp_SigBit);

again:

        /*==================================*/
        /* W A I T  F O R  A  M E S S A G E */
        /*==================================*/

       wakeupbit = Wait(waitbits);


       if(window && (wakeupbit & (1 << window -> UserPort -> mp_SigBit)))
          {

            while(window &&
             (message = (struct IntuiMessage *)GetMsg(window->UserPort)))
            {
                /******************************************/
                /* Extract the message from the structure */
                /* because we may need to send the reply  */
                /* back immediately                       */
                /******************************************/

              class = message->Class;
              code =  message->Code;
              qualifier = message->Qualifier;
              mousex = message->MouseX;
              mousey = message->MouseY;
              address = message->IAddress;

              if (class != MENUVERIFY)
                {
                  ReplyMsg(message);            /* send reply right away */
                  if (HandleEvent())
                    goto exit_program;
                }
              else
                {
                  if (HandleEvent())
                      goto exit_program;      /* the user selected quit */
                  ReplyMsg(message);
                }

            } /* end while */
          }

        goto again;

exit_program:


        UnMakeMenuStrip(window->MenuStrip);
        ClearMenuStrip(window);
        CloseWindow(window);

        CloseLibrary(LayersBase);
        CloseLibrary(DiskfontBase);
        CloseLibrary(IntuitionBase);
        CloseLibrary(GfxBase);
  exit(0);
}
