/* :ts=8 */
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
/*                                                              */
/*      SampleMenu.c                                            */
/*                                                              */
/*      Menu builder 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>


#define PUBCLEAR MEMF_PUBLIC | MEMF_CLEAR

struct Menu *NewMenu();
struct MenuItem *AddItem();
struct MenuItem *AddSubItem();

struct Window *Mwindow; /* currently chosen window and screen for */
struct Screen *Mscreen; /* this menu build operation              */


#define ITEMSTD         ITEMTEXT | ITEMENABLED | HIGHCOMP
#define ITEMSTDBOX      ITEMTEXT | ITEMENABLED | HIGHBOX
#define CHKITEMSTDBOX   CHECKIT | ITEMSTDBOX
#define CTLITEMSTD      (w != controlwindow ? ITEMSTD : ITEMTEXT | HIGHCOMP)
#define OFFITEMSTD      ITEMTEXT | HIGHCOMP
#define CHKITEMSTD      ITEMSTD | CHECKIT
#define OFFCHKITEMSTD   OFFITEMSTD | CHECKIT

struct Menu *MMenu;
struct MenuItem *NMenu,*OMenu;
extern struct GfxBase *GfxBase;

/*****************/
/* MENU FUNCTIONS*/
/*****************/

int     Draw1();
int     Draw2();
int     Quit();


struct Menu *InitMenu(s,w)      /* returns pointer to root of list */
struct Screen *s;    /* pointer to the screen, used for TextLength calls */
struct Window *w;    /* pointer to the window for which to build menu */
{

  register struct Menu *mp,*rmp;/* current menu pointer, root menu pointer */
  register struct MenuItem *mip,*mip2;


        Mscreen = s;
        Mwindow = w;

        rmp = NULL;

        mp = NewMenu(   rmp,
                        -1,0,    /* origin */
                        -1,10,  /* width (-1 means figure it out for me), */
                                /* height */
                        MENUENABLED,
                        "Test Menu");

        rmp = mp;

        AddItem(mp,ITEMSTD,"Draw String 1",Draw1);
        AddItem(mp,ITEMSTD,"Draw String 2",Draw2);
        AddItem(mp,ITEMSTD | COMMSEQ,"Quit",Quit,'Q');

     /*====================================================================*/
     /* this section of code scans the entire menu tree,                   */
     /* it looks for submenus and passes them to be positioned optimumlly. */
     /*====================================================================*/

      MMenu = rmp;
      while ( MMenu )
      {
        NMenu = MMenu -> FirstItem;
        while ( NMenu )
        {
          if ( NMenu -> SubItem)
            PositionSubMenu(MMenu,NMenu);
          NMenu = NMenu -> NextItem;
        }
        MMenu = MMenu -> NextMenu;
      }

  return(rmp);
}

PositionSubMenu(Menu,smenu)
  struct Menu *Menu;
  struct MenuItem *smenu;
{
  register bottom_edge=0,right_edge=0,top_edge=0xFFFF,left_edge=0xFFFF;
  int most = 0,ypos,edge;
  struct MenuItem *temp,*menu;
  struct IntuiText *ITText;

  ypos = smenu -> TopEdge;

  smenu = smenu -> SubItem;
  menu = Menu -> FirstItem;

  temp = smenu;
  while ( temp )
  {
    if ( temp -> LeftEdge < left_edge )
      left_edge = temp -> LeftEdge;
    if ( temp -> TopEdge  < top_edge )
      top_edge  = temp -> TopEdge;
    if ( temp -> LeftEdge + temp -> Width > right_edge )
      right_edge = temp -> LeftEdge + temp -> Width;
    if ( temp -> TopEdge + temp -> Height > bottom_edge )
      bottom_edge = temp -> TopEdge + temp -> Height;
    temp = temp -> NextItem;
  }
  /* we now have the outside coordinates of the submenu box */
  top_edge += ypos;
  bottom_edge += ypos;

  temp = menu;
  while ( temp )
  {
    /* if this conditional is true then this menu item is adjacent to the
       submenu box */
    if ( temp -> TopEdge > top_edge - 8 &&
         temp -> TopEdge + temp -> Height < bottom_edge + 8 )
    {
      edge = temp -> LeftEdge + temp -> Width;
      ITText = temp -> ItemFill;
      if ( strlen ( ITText -> IText ) > most ) most = strlen ( ITText -> IText);
    }
    temp = temp -> NextItem;
  }
  most = left_edge - ( most * 8 ) - 4 ;
  if ( right_edge - most < edge ) most -= edge - ( right_edge - most );
  /* now we now the longest menu item that is adjacent to the submenu box */

  temp = smenu;
  while ( temp )
  {
    temp -> LeftEdge -= most;
    temp = temp -> NextItem;
  }
}

Quit()
{
  extern SHORT quitcode;

  quitcode = TRUE;
}

Draw1()
{
  extern struct Window *window;
  Move(window -> RPort,50,50);
  Text(window -> RPort,"AmigaPLUS Programming example",29);
}

Draw2()
{
  extern struct Window *window;
  Move(window -> RPort,50,90);
  Text(window -> RPort,"Intuition Plus",14);
}

