/*******************************************************************
 *         S I M P L E   M E N U   D E M O N S T R A T I O N       *
 *                                                                 *
 *  This example is a continuation of last month's drawline        *
 *  program. It is by no means an exhaustive study of menus, but   *
 *  does provide a basis for further development.                  *
 *                                                                 *
 *                                          Tom                    *
 *******************************************************************/
#include <exec/types.h>
#include <intuition/intuition.h>

/* Define an Intuition Structure    */
struct IntuitionBase *IntuitionBase;

/* Define a Graphics Structure      */
struct GfxBase *GfxBase; 

/* Define a structure to get messages from Intuition through the IDCMP */
struct IntuiMessage *message;

/* Intuition and Graphics revision of 0 means that any version of the
   operating system (1.0, 1.1, or 1.2) are acceptable                  */
#define INTUITION_REV 0
#define GRAPHICS_REV  0

/* Define a structure to access fonts. This struct will (obviously) let us
   use a font called topaz.                                            */
struct TextAttr MyFont =
   {
    "topaz.font",  /* Font Name   */
    TOPAZ_SIXTY,   /* Font Height */
    FS_NORMAL,     /* Style       */
    FPF_ROMFONT    /* Preferences */
   };

/* Define the structure for the new screen (called NewScreen). This
   screen will be a low-resolution, non-interlace screen (320x200) with
   5 bit planes (32 colors). The font defined in the last structure will
   be attached to this screen in this structure.                       */

struct NewScreen NewScreen =
    {
    0,           /* the left edge               */
    0,           /* the top  edge               */  
    320,         /* Width of the screen         */
    200,         /* Height of the screen        */
    5,           /* Depth - # of bitplanes      */
    0,1,         /* DetailPen, BlockPen         */
    0,           /* ViewMode:                   */
                 /* no INTERLACE or HIRES       */
    CUSTOMSCREEN,/* Type - must be CUSTOMSCREEN */
    &MyFont,     /* Connect the font            */
    "Mouse Paint",/* Title of Screen            */
    NULL,        /* Gadgets                     */
    NULL         /* CustomBitMap                */
    };

 /* The struct Screen will be returned from the OpenScreen function */
  struct Screen *Screen;
 
 /**********************************************************************/
 /* The struct NewWindow will be passed to the OpenWindow function     */
  struct NewWindow NewWindow =
      {
        20,  20,  /* LeftEdge, TopEdge   */
       300, 100,  /* Width, Height       */
         0,  1, /* DetailPen, BlockPen */
       /* IDCMPFlags                     */
       /*      notice that we specify MENUPICK to let
               Intuition know that we wish to be informed
               about menu selections     */
       CLOSEWINDOW | MOUSEBUTTONS | MENUPICK,
       /* Flags                          */
       WINDOWCLOSE   | SMART_REFRESH | ACTIVATE    |
       WINDOWSIZING  | WINDOWDRAG    | WINDOWDEPTH |
       NOCAREREFRESH | SIZEBRIGHT,

       NULL,      /* First Gadget        */
       NULL,      /* Check Mark          */
       "Menu Demonstration", /* Title of Window */
       NULL,   /* Address of Screen this window is to be attached to
                  - we only know this after we open the Screen      */
       NULL,      /* BitMap              */
       100,  25,  /* MinWidth, MinHeight */
       300, 200,  /* MaxWidth, MaxHeight */
    
       CUSTOMSCREEN, /* What type of screen is this to be attached ?   */
       };
 /* The structure Window will be returned from the OpenWindow function */
  struct Window *Window;


 /************** M E N U    D E C L A R A T I O N S ********************/
  struct IntuiText IText[] =
  {
    {0,1,JAM2,CHECKWIDTH,0,NULL,"Boxes"},
    {0,1,JAM2,CHECKWIDTH,0,NULL,"Dots"},
    {0,1,JAM1,CHECKWIDTH,0,NULL,"Color"},
    {0,1,JAM1,CHECKWIDTH,0,NULL,"Increment"},
    {0,1,JAM1,CHECKWIDTH,0,NULL,"Decrement"}
  };

  struct MenuItem MenuItem[] =
  {
    { /* MenuItem[0] is "Boxes" */
     &MenuItem[1],  /* Point to the next menu item           */
                    /* Left edge, Top edge, Width, Height    */
     0, 0, (120 + CHECKWIDTH + LOWCOMMWIDTH), 9,
                    /* Flags for menu item. See article 
                       for explanation                       */
     (CHECKIT     | CHECKED  | ITEMTEXT  | COMMSEQ  |
      ITEMENABLED | HIGHCOMP),
     0x02,          /* This flag deals with mutual exclusion */ 
     (APTR) &IText[0], /* Tell Intuition where to get the    
                          information for this menu item     */
     NULL,          /* SelectFill                            */
     'B'            /* quick selection using Amiga-B         */
    },

    { /* MenuItem[1] is "Dots"*/
     NULL,          /* End of this menu strip                */
     0, 9, (120 + CHECKWIDTH + LOWCOMMWIDTH), 9,
     (CHECKIT     | ITEMTEXT  | COMMSEQ  |
      ITEMENABLED | HIGHCOMP),
     0x01,
     (APTR) &IText[1],
     NULL,
     'D'
    },
    
    { /* 2nd Menu, MenuItem[2] is "Color" */
     NULL, 
     0, 0, 120 , 9,
     (ITEMTEXT | ITEMENABLED | HIGHCOMP),
     NULL,             /* No mutual exclusion for this one   */ 
     (APTR) &IText[2], 
     NULL,            
     NULL,
     &MenuItem[3]      /* We're going to attach a submenu    */
    },

    { /* subitem MenuItem[3] is "Increment" */
     &MenuItem[4],  /* Point to 2nd SubItem */
     110, 4, 120 , 9,
     (ITEMTEXT | ITEMENABLED | HIGHCOMP),
     NULL,        
     (APTR) &IText[3]
    },

    { /* subitem MenuItem[4] is "Decrement" */
     NULL,          /* No more subitems     */
     110, 13, 120 , 9,
     (ITEMTEXT | ITEMENABLED | HIGHCOMP),
     NULL,        
     (APTR) &IText[4]
    }     
     
  };

  struct Menu Menu[] =
  {
    { 
     &Menu[1],       /* Point to other Menu                  */
     0, 0 ,72, 0,    /* Left edge, Top edge, Width, Height   */
     MENUENABLED,    /* enable the menu                      */
     "Shape ",       /* give the menu a name                 */
     &MenuItem[0]    /* point to the first menu item         */
     },

    { 
     NULL,           /* Last menu                            */
     75, 0, 130, 0, 
     MENUENABLED,   
     "Color Control",
     &MenuItem[2]   
     }
  };

  struct Menu *MyMenu = &Menu[0];

main()
{

  LONG   PenColor,NowX,NowY;
  USHORT WhichMenu,WhichItem,WhichSub;

  char WhichMode, DrawIt;

  DrawIt    = 'N';
  WhichMode = 'B'; /* D = dot drawing   B = box drawing */   
  PenColor  = 1;
 
 /* Open the Intuition library. If this function returns a NULL pointer,
    (zero), something is wrong, the program should exit immediately */

IntuitionBase=(struct IntuitionBase *) 
   OpenLibrary("intuition.library",INTUITION_REV);

if (IntuitionBase == NULL)
{
   printf("Bad IntuitionBase Open. \n"); 
   exit(FALSE);
} 
 
/* Open the Graphics library. If this function returns a NULL pointer,
   (zero), something (once again) is wrong. Your program should exit. */

GfxBase=(struct GfxBase *)
  OpenLibrary("graphics.library",GRAPHICS_REV);

if (GfxBase == NULL)
{
   printf("Bad GfxBase Open.\n"); 
   exit(FALSE);
}

if ((Screen=(struct Screen *)OpenScreen(&NewScreen))==NULL)
{
   printf("Bad OpenScreen. \n");
   exit(FALSE);
}

/* Now that the Screen is open get the address and open the window   */

NewWindow.Screen = Screen;
if ((Window=(struct Window *) OpenWindow(&NewWindow)) == NULL)
{
    /* If the open window was bad, close the screen                  */
    printf("Bad OpenWindow. Closing Screen. \n");
    CloseScreen(Screen);
    exit(FALSE);
}

/*  Once we have opened our window, tell Intuition about previously
    defined menu                                                     */
    
SetMenuStrip(Window, MyMenu);

/* The Main Processing Loop                                   
   - this is a do forever loop that will not waste processing cycles */
 for (;;)
 {
     /* Wait until the IDCMP says that the user did something.       */ 
     Wait(1<<Window->UserPort->mp_SigBit);
  
     while(message = GetMsg(Window->UserPort))  
     {
          /* Always check to see whether the user tried to end
             the program.                                            */
          if (message->Class == CLOSEWINDOW)
          {
             ReplyMsg(message);
             ClearMenuStrip(Window); /* Make the Menu go away        */
             CloseWindow(Window);
             CloseScreen(Screen);
             CloseLibrary(GfxBase);
             CloseLibrary(IntuitionBase);
             exit(TRUE);
          } /* end CLOSEWINDOW */

          /* Check if the left mouse button was pressed. If it was, draw 
             the appropriate thing (box or dot).                      */
          if (message->Class == MOUSEBUTTONS)
          {
             /* Get the current mouse position          */
             NowX = message->MouseX;
             NowY = message->MouseY;
  
             /* This line prevents drawing in the title bar */ 
             if (NowY < 12)
                 NowY = 12;

             switch(WhichMode)
             {
                case 'B':  /* draw boxes */
                     RectFill(Window->RPort,NowX,NowY,NowX+5L,NowY+5L);
                     break;
                case 'D':
                     WritePixel(Window->RPort,NowX,NowY);
                     break;
             } /* end switch */

             ReplyMsg(message); 

          } /* end MOUSEBUTTONS */

          /* check if the user tried the menu */
          if (message->Class == MENUPICK)
          {
              if ((message->Code) != MENUNULL) /* if they picked something */
              { 
        
          /* Get which menu item was picked from Intuition         */
                  WhichMenu = MENUNUM(message->Code);
                  WhichItem = ITEMNUM(message->Code);
                  WhichSub  = SUBNUM(message->Code);
                  ReplyMsg(message); 
 
                  /* Now that we've retrieved the menu item selected,      
                     figure out which action to take                      */ 
                  switch (WhichMenu)
                  {
                     case 0:
                            /* Shape Menu */
                            switch(WhichItem)
                            {
                               case 0: /* Draw Boxes */
                                      WhichMode = 'B';
                                      break;
                               case 1: /* Draw Dots  */
                                      WhichMode = 'D';
                                      break;
                            }
                            break;
                     case 1:
                            /* Color Menu */
                            switch(WhichSub)
                            { 
                               case 0: /* Increment the PenColor */
                                      PenColor = PenColor + 1;
                                      if (PenColor > 32)
                                      PenColor = 1;
                                      break;
                               case 1: /* Decrement the PenColor */
                                      PenColor = PenColor - 1;
                                      if (PenColor < 1)
                                      PenColor = 32;
                                      break;
                            } 
                            break;
                  }
                  /* Set the A Pen to the specified color    */                      
                  SetAPen(Window->RPort,PenColor);
             
               } /* end !MENUNULL */
          } /* end MENUPICK */
     } /* end while GetMsg */
 } /* end for - ever loop*/
}  /* End of main procedure */
