/**  men.c *************************************************************
 *
 *              men.c - Menu functions for John Draper's GadEd
 *
 *      Routines in this module: Do_menu
 *              Temporarily : initgads(), getgad(), savegad()
 *                 these belong in the filemenu.c module.
 *
 *      David Milligan - Cleaned up menu appearance & layout.
 *       6/7/86 - Broke up menu into discrete structures for fine-tuning.
 *              - Added shortcut keys to Flags & Activation items.
 *              - Added rudimentary MutualExcluding.
 *       6/9/86 - Made menu structures into separate file in consideration
 *                of other programmers on project.
 *      6/11/86 - Re-implemented 'stamping' method of menu init.
 *              - Re-wrote the NewMenu() function to use pointer indexing.
 *                Much cleaner & more efficient.
 *      6/14/86 - Broke men.c into three files: menstructs.c, men.c, men.h
 *      7/6/86  - Put men.h BACK into men.c. It seems John didn't like it.
 *                Compiled his new changes with no problems.
 *
 *      11/17/86- RRL added some code to call the intuitext requesters
 *                and to clear the flags and checkmarks when a new type
 *                of gadget is selected.
 *
 *      11/22/86- RRL added the delete function and modified the image
 *                editor interface. Made GADGIMAGE and GADGHIMAGE flags
 *                non-selectable by the user to avoid bad flag crashes. 
 *
 *      12/2/86-  JTD Changed the width and height tweaking to take place
 *                ONLY on proportional Gadgets.
 *
 *      David Milligan, Surrealistic Software, Sacramento, CA.
 *              The WELL        - dmil
 *              CompuServe      - 70707,2521
 *              BIX             - dmilligan
 *      home phone - (916)366-1269
 ***********************************************************************/
 
/**  men.h *************************************************************
 *
 *              men.h - Menu definitions for John Draper's GadEd
 *
 *      created 6/14/86 -- David Milligan, Surrealistic Software
 *
 ***********************************************************************/
 
/*  The usual header files to be inserted later  */
#include <intuition/intuition.h>
#include <libraries/dosextens.h>
#include <graphics/gfxbase.h>
#include <graphics/gfx.h>
#include <graphics/display.h>
#include <exec/memory.h>
#include <workbench/workbench.h>
#include <workbench/startup.h>
#include <devices/narrator.h>
#include <devices/audio.h>
#include <libraries/translator.h>
#include "gad.h"
#include "men.h"
 
/*================== global variables ===============*/
 
/* gadget index pointers */
int pflag = FALSE;          /*  propinfo flag */
int curgad = 0;             /* Pointer into gadget pointer array */
int nextgad = 0;            /* Pointer into Next gadget to be entered */
extern int nextlink;        /* the index of the next gad to linked */
int nextprop = 0;           /* index into next propinfo pointer */
int nexttext = 0;           /* index to next intuitext structure pointer */
int nx_strings = 0;         /* index to next stringinfo pointer */
USHORT oldtype;             /* Last gadget type before change */
 
struct Gadget *gads[MAX_NUM_GADGETS];
struct IntuiText *Texts[MAX_INTUITEXTS];
char gadimage[MAX_PROPINFOS][NAM_SIZ];
char selectimage[MAX_PROPINFOS][NAM_SIZ];
struct PropInfo *props[MAX_PROPINFOS];
struct StringInfo *strings[MAX_STRINGINFOS];
 
 
UBYTE *gadnames[MAX_NUM_GADGETS];
char *textnames[MAX_INTUITEXTS];
char *propnames[MAX_PROPINFOS];
char *strnames[MAX_STRINGINFOS];
 
/* space for gadget names */
UBYTE names [MAX_NUM_GADGETS] [NAM_SIZ];
 
/*================== EXTERNAL FUNCTION DECLARATIONS ===================*/
 
extern SHORT AddGadget();
extern UBYTE *getrname();           /*  in reqn.c */
extern struct Image *Image_Ed();    /* Ray's stuff in image.c */
extern struct StringInfo *nam_info(); /* Returns Info for getrname */
 
/*===================== EXTERNAL GLOBAL VARIABLES =====================*/
 
extern struct Gadget testgad;
extern struct Gadget *SelectedGadget;
extern struct PropInfo Prop;
extern struct StringInfo String;
extern struct Window *w;
extern struct RastPort *rp;
extern long mask;
extern int holding;
extern int erase;
extern int siz_flag;
extern SHORT Left, Top, Width, Height;
extern SHORT N_Bitplanes;

extern struct Menu file_menu;
extern struct MenuItem info_items[]; 
extern struct MenuItem flags_items[]; 
extern struct MenuItem act_items[]; 
/*----------------------- Important arrays -------------------*/
 
/* Gadget types */
USHORT gadtype[] = {
   BOOLGADGET,
   PROPGADGET,
   STRGADGET
};
 
/* Activation flags supported */
USHORT actflags[] = {
   0,                /* Clear all flags */
   RELVERIFY,
   FOLLOWMOUSE,
   GADGIMMEDIATE,
   ENDGADGET,
   TOGGLESELECT,
   LONGINT,
   RIGHTBORDER,
   LEFTBORDER,
   TOPBORDER,
   BOTTOMBORDER,
   STRINGCENTER,
   STRINGRIGHT,
   ALTKEYMAP
};
 
/* Gadget flags supported */
 
USHORT gadflags[] = {
  0,                   /* Reset all flags */
  GADGHCOMP,
  GADGHBOX,
  GADGHIMAGE,
  GADGIMAGE,
  GRELBOTTOM,
  GRELRIGHT,
  GRELWIDTH,
  GRELHEIGHT,
  SELECTED,
  GADGDISABLED
};
 
/* Propinfo flags supported */
 
USHORT propflags[] = {
    0,                 /* reset all flags */
    AUTOKNOB,
    FREEHORIZ,
    FREEVERT,
    PROPBORDERLESS,
    KNOBHIT
};
 
/***************************************************************************
                        DO THE MENU SELECTIONS
***************************************************************************/
Do_menu(menu, item)
long menu, item;
{
    struct PropInfo *pr;
    SHORT val;
    SHORT wid, hgt;
    UBYTE *str;
    int i;
    struct Image *imag1, *imag2;
    struct StringInfo *si;      /* Info for getrname */
    struct PropInfo *pi;        /* PropInfo pointer */
    long flags, lf, tp, wd, ht;
 
    switch (menu) {
 
      case FILE_MENU:  switch(item) {
 
            case NEW_GAD:  initgads();  /* Init the gadget area */
                           break;
 
            case GET_GAD:               /* Gets the gadget info from file */
                            ClearMenuStrip(w);/* don't let user quit while */
                                               /* file is being read   */
                            getgad();   
		            SetMenuStrip(w,&file_menu);
                            break;
 
            case SAVE_GAD:               /* Saves the gadget to disk */
                            ClearMenuStrip(w);/* don't let user quit while */
                                               /* source is being dumped    */
                            savegad();   
		            SetMenuStrip(w,&file_menu);
                            break;
 
            case SAV_SOURCE:           /* Saves the source */               
                             ClearMenuStrip(w);/* don't let user quit while */
                                               /* source is being dumped    */
                             dumpgadgets();
		             SetMenuStrip(w,&file_menu);
                             break;
 
            case QUIT_PROG:  CloseThings(); /* Close down */
                             exit(NULL);
                             break;
 
      } break;
 
      case GAD_TYPE_MENU:   oldtype = testgad.GadgetType;
                            testgad.GadgetType = gadtype[item];
	                    /* ### new RRL */
                            ClearMenuStrip(w);
			    for(i=1;i<NUM_SPEC_ITEMS;i++)
			       info_items[i].Flags &= ~CHECKED;
                            pflag = 0;
			    for(i=1;i<NUM_FLAGS;i++)
			       flags_items[i].Flags &= ~CHECKED;
                            testgad.Flags = 0;
			    for(i=1;i<NUM_ACT_FLAGS;i++)
			       act_items[i].Flags &= ~CHECKED;
			    testgad.Activation = 0;
			    SetMenuStrip(w,&file_menu);
                            break;
 
      case GAD_ACT_MENU:    if (item == 0) testgad.Activation = 0;
                            else testgad.Activation |= actflags[item];
                            break;
 
      case GADFLAGS_MENU:   if (item == 0) testgad.Flags = 0;
                            else testgad.Flags |= gadflags[item];
                            break;
 
      case UTIL_MENU:  switch(item) {
 
           case NEW_GADGET:  /*  Adds gadget to list */
                           if ((testgad.GadgetType == PROPGADGET) &&
				(pflag == 0)){
                           autoreq("You need to set PROPINFO flags first!",
                                       "OK","CANCEL");
                                break;
                             }
			    /*  erase the last box	*/
			    draw_box(rp, Left-1, Top-1, Width, Height);
			    
			    /* clear image flags if they are hanging around */
			    testgad.Flags &= ~(GADGIMAGE | GADGHIMAGE);

                            linkgadgets();
			    SelectedGadget = NULL;
                            break;
 
           case DEL_GADGET:  /* Delete selected gadget  - works now -RRL*/
                         if (SelectedGadget == NULL) {
                           autoreq(
                         "You have to click on the gadget to delete first",
                                       " OK ","Right");
                           SelectedGadget = NULL;
                           break;
		          }
		          /* highlight the selected gadget */
                          SetDrMd(rp, COMPLEMENT);
                          RectFill(rp, 
                                (LONG)SelectedGadget->LeftEdge-1,
                                (LONG)SelectedGadget->TopEdge-1,
                                (LONG)SelectedGadget->LeftEdge +
                                     (LONG)SelectedGadget->Width,
                                (LONG)SelectedGadget->TopEdge +
                                (LONG)SelectedGadget->Height);
   
                           if(autoreq("REALLY delete the highlighted gadget?",
                                       "YES","NO!! CANCEL"))
                             { /* we just remove the gad and it's imagery */
                               RemoveGadget(w,SelectedGadget);
                               ClearAllTexts(SelectedGadget,
                                   (LONG)SelectedGadget->LeftEdge,
                                   (LONG)SelectedGadget->TopEdge);
                               SetAPen(rp,0L);
                               SetDrMd(rp, JAM1);
                               RectFill(rp, 
                                   (LONG)SelectedGadget->LeftEdge-1,
                                   (LONG)SelectedGadget->TopEdge-1,
                                   (LONG)SelectedGadget->LeftEdge +
                                      (LONG)SelectedGadget->Width,
                                   (LONG)SelectedGadget->TopEdge +
                                      (LONG)SelectedGadget->Height);
                                       
                              /* remove the gadget pointer from the */      
                              /* gads array and move others up. Also*/
                              /* move names associated with the gad */
                              curgad = findadr(gads,SelectedGadget,nextgad);
                              if (curgad != -1){
                                 for (i=curgad; i < nextgad; i++) {
                                     gads[i] = gads[i+1];
                                     gadnames[i] = gadnames[i+1];
                                     strcpy(gadimage[i], gadimage[i+1]);
                                     strcpy(selectimage[i], selectimage[i+1]);
                                  }
                                 nextgad--;
                                 nextlink--;
                              }
                           }
                           else /* undo the highlighting */
                            SetDrMd(rp, COMPLEMENT);
                            RectFill(rp, 
                                (LONG)SelectedGadget->LeftEdge-1,
                                (LONG)SelectedGadget->TopEdge-1,
                                (LONG)SelectedGadget->LeftEdge +
                                     (LONG)SelectedGadget->Width,
                                (LONG)SelectedGadget->TopEdge +
                                (LONG)SelectedGadget->Height);
                            SetAPen(rp,1L);
                            SetDrMd(rp, JAM1);
                            holding = FALSE;
                            erase = FALSE;

                            break;
 
           case SET_GAD_NAME:  /* Open Requester, get name */
                            si = nam_info();    /* Get name info */
                            *si->Buffer = '\0';  /* Zap old name */
                            si->BufferPos = 0;
                            str = getrname("Enter Gadget name");
                            if (str == NULL) {
                                SelectedGadget = NULL;
				break;
                            }
                            strcpy(names[curgad], str);
                            gadnames[curgad] = names[curgad];
                            break;
 
           case ADD_INTUITEXT: /* Add Intuitext to border */
                            ITextEd(SelectedGadget,w);
                            break;
 
 
           case SET_IMAG_BORD: /* Add GadgetRender */
                      if (SelectedGadget == NULL) {
                           autoreq(
                         "First click on the gadget you want to add the image to.",
                                       " OK ","Right");
                           SelectedGadget = NULL;
                           break;
		          }
	      i = curgad;
              curgad = findadr(gads,SelectedGadget,nextgad);
  	      if (curgad == -1) { 
  	         kprintf("couldn't find selected gad in gads array!!\n");
                 break;
              }
              if (nextgad) {
                  if (!get_req_name("Enter Image Name", gadimage[curgad])) {
                     SelectedGadget = NULL;
		     break;
                  }
                  flags = (long)SelectedGadget->UserData;
                  wid = SelectedGadget->Width;    /* Image width */
                  hgt = SelectedGadget->Height;   /* Image Width */
                  if (SelectedGadget->GadgetType == PROPGADGET) {
                     pi = (struct PropInfo *)SelectedGadget->SpecialInfo;
                     if ((pi->Flags & FREEHORIZ) == FREEHORIZ) {
                        wid -= 8;  wid >>= 2;
                     }
                     if ((pi->Flags & FREEVERT)  == FREEVERT) {
                        hgt -= 3;  hgt >>= 2;
                     }
                  }
                  if ((flags & GAD_BORDER_TYPE) == GAD_BORDER_TYPE) {
                     imag1 = Image_Ed(w->WScreen,
                          wid,  /* Image same as Gadget */
                          hgt,   /* Height same also */
                          N_Bitplanes,           /* WB Scrn depth */
                          NULL );                /* Create new image */
                      if (imag1 == NULL) break;
                      SelectedGadget->GadgetRender = (APTR)imag1;
                      flags &= ~GAD_BORDER_TYPE;
                      flags |= GAD_IMAGE_TYPE;
                      SelectedGadget->Flags |= GADGIMAGE;
                      ClearMenuStrip(w);
		      flags_items[4].Flags |= CHECKED;
                      SetMenuStrip(w,&file_menu);
                      SelectedGadget->UserData = (APTR)flags;
                   } 
 
                   else if ((flags & GAD_IMAGE_TYPE) == GAD_IMAGE_TYPE) {
                      imag2 = (struct Image *)SelectedGadget->GadgetRender;
                      imag1 = Image_Ed(w->WScreen,
                          wid,               /* Use same as Gadget */
                          hgt,               /* Same as Gadget */
                          N_Bitplanes,       /* WB Scrn depth */
                          imag2);     /* Use current image */
                      if (imag1 == NULL) break;
                      SelectedGadget->GadgetRender = (APTR)imag1;
                   }
                   else if ((flags & KNOB_IMAGE_TYPE) == KNOB_IMAGE_TYPE) {
                      imag1 = Image_Ed(w->WScreen,
                          wid,               /* Use same as Gadget */
                          hgt,               /* Same as Gadget */
                          N_Bitplanes,       /* WB Scrn depth */
                          NULL);     /* Use current image */
                      if (imag1 == NULL) break;
                      SelectedGadget->GadgetRender = (APTR)imag1;
                      pi = (struct PropInfo *)SelectedGadget->SpecialInfo;
                      pi->Flags &= ~AUTOKNOB;
                      flags &= ~KNOB_IMAGE_TYPE;
                      flags |= GAD_IMAGE_TYPE;
                      SelectedGadget->Flags |= GADGIMAGE;
                      ClearMenuStrip(w);
		      flags_items[4].Flags |= CHECKED;
                      SetMenuStrip(w,&file_menu);
                      SelectedGadget->UserData = (APTR)flags;
                   }
              }
              SetAPen(rp, 0L);
              SetDrMd(rp, JAM1);
              lf = (long)(SelectedGadget->LeftEdge-1);
              tp = (long)(SelectedGadget->TopEdge-1);
              wd = (long)(SelectedGadget->Width+1);
              ht = (long)(SelectedGadget->Height+1);
 
              RectFill(rp, lf, tp, lf+wd, tp+ht);
              RefreshGadgets(gads[0], w, NULL);
              break;
 
           case SET_SEL_BORD: /* Add SelectRender */
               if (SelectedGadget == NULL) {
                   autoreq(
                    "First click on the gadget you want to add the image to.",
                               " OK ","Right");
                   SelectedGadget = NULL;
                   break;
               }

  	      flags = (long)SelectedGadget->UserData;
    	      if ((flags & GAD_IMAGE_TYPE) != GAD_IMAGE_TYPE){
    	         /* can't do a select image without a gad image */
    	         autoreq("Must create Gadget image before Select image!",
                         "OK","Sure Thing");
                 SelectedGadget = NULL;
    	         break;
    	      }   

              i = curgad;
              curgad = findadr(gads,SelectedGadget,nextgad);
  	      if (curgad == -1) { 
  	         kprintf("couldn't find selected gad in gads array!!\n");
                 break;
              }

              if (nextgad) {
                  if (!get_req_name("Enter Image name", selectimage[curgad])) {
                      SelectedGadget = NULL;
                      break;
                  }
                  flags = (long)SelectedGadget->UserData;
                  wid = SelectedGadget->Width;    /* Imahe width */
                  hgt = SelectedGadget->Height;   /* Image Width */
                  if (SelectedGadget->GadgetType == PROPGADGET) {
                     pi = (struct PropInfo *)SelectedGadget->SpecialInfo;
                     if ((pi->Flags & FREEHORIZ) == FREEHORIZ) {
                        wid -= 8; wid >>= 2;
                     }
                     if ((pi->Flags & FREEVERT)  == FREEVERT) {
                        hgt -= 3; hgt >>= 2;
                     }
                  }
 
                  if (((flags & SEL_BORDER_TYPE) == SEL_BORDER_TYPE) 
                      || SelectedGadget->SelectRender == NULL) {
                     /* let user edit select image if desired */ 
                     if( autoreq("Modify gadget image for select image?",
                                       "YES","No- New Image"))
                        imag2 = (struct Image *)SelectedGadget->GadgetRender;
                     else imag2 = NULL;

                     imag1 = (struct Image *)Image_Ed(w->WScreen,
                          wid,    /* Image same as Gadget */
                          hgt,   /* Width same also */
                          N_Bitplanes,             /* WB Scrn depth */
                          imag2 );                 /* image to mod or new */
                     if (imag1 == NULL) break;
 
                      flags &= ~SEL_BORDER_TYPE;
                      SelectedGadget->SelectRender = (APTR)imag1;
                      flags |= SEL_IMAGE_TYPE;
                      SelectedGadget->Flags |= GADGHIMAGE;
                      ClearMenuStrip(w);
		      flags_items[3].Flags |= CHECKED;
                      SetMenuStrip(w,&file_menu);
                      SelectedGadget->UserData = (APTR)flags;

                   }
  
                   else if ((flags & SEL_IMAGE_TYPE) == SEL_IMAGE_TYPE) {
                      imag2 = (struct Image *)SelectedGadget->SelectRender;
                      imag1 = (struct Image *)Image_Ed(w->WScreen,
                          wid,    /* Use same as Gadget */
                          hgt,   /* Same as Gadget */
                          N_Bitplanes,   /* WB Scrn depth */
                          imag2);     /* Use current image */
                      if (imag1 == NULL) break;
                      SelectedGadget->SelectRender = (APTR)imag1;
                   }

              }
              SetAPen(rp, 0L);
              SetDrMd(rp, JAM1);
              
              lf = (long)(SelectedGadget->LeftEdge-1);
              tp = (long)(SelectedGadget->TopEdge-1);
              wd = (long)(SelectedGadget->Width+1);
              ht = (long)(SelectedGadget->Height+1);
              
              RectFill(rp, lf, tp, lf+wd, tp+ht);
              RefreshGadgets(gads[0], w, NULL);
              break;
 
           case SET_GADSIZ:  siz_flag = TRUE;
                            break;
 
           case SET_GADLOC:  siz_flag = FALSE;
                            break;
 
           case ADD_MUT_EXCLUD: /* Add Mutual exclude */
                            dispgad(gads[0]);
                            break;
 
           case ADD_USR_ID: /* Add User ID value */
                            trap();      /* Debug trap */
                            break;
 
      } break;
 
      case SPEC_MENU:
                       if (item == 0) pflag = NULL;
                       else pflag |= propflags[item];
                       break;
 
    }
}
/* Go here if we want to go into the debugger */
trap()
{
    kprintf("Entered into debugger\n");
}
 
/*=================== Menu Action functions here ===================*/
/*------- Clear out for new gadget file -------*/
initgads()
{
}
