/***********************************************/
/*                                             */
/* menu.c - v. 1.0 - 5.88 - Antonio Ferrillo   */
/*                                             */
/*       funzioni di gestione menus            */
/*                                             */ 
/*    versione Aztec 3.4  -  Lattice 3.10      */
/*                                             */
/***********************************************/ 

  #include <functions.h>   /* rimuovere questa 
linea se si usano i compilatori Lattice V. 3.xx */

  #include <exec/types.h>
  #include <intuition/intuition.h> 

  struct Window *Window_Addr(); 
  
  struct Menu Titoli[5];
  struct MenuItem Items[5][8];
  struct IntuiText ItemText[5][8];
  struct MenuItem SubItems[5][8][4];
  struct IntuiText SubText[5][8][4];


/*---------------------------------------------
|   int
|   Menu_Set(wn,fp,men)
|
|    FUNZIONE  : aggancia max 5 menu-strips ad
|                una finestra aperta in precedenza
|
|    ARGOMENTI : int wn; - 
|       (valore = 1 o 2 o 3 o 4) numero della
|       finestra cui associare le menu-strips.
|
|                int fp; - 
|       (valore da 0 a 31) colore delle scritte.
|   
|                char men[5][9][5][12]; - 
|       array quadridimensionale  contenente max 
|       5 elementi-menu' (tendine), ognuno dei 
|       quali contiene max 9 elementi_item
|       (1 per il nome sulla barra + 8 per gli 
|       items), ognuno dei quali contiene max 
|       5 elementi-stringhe (1 per l'item + 4 
|       per i subitems associati), ognuno dei 
|       quali contiene max 12 elementi carattere
|       (Il primo elemento e' il carattere di 
|       comando da tastiera in alternativa al 
|       mouse : se non lo si vuol usare inserire
|       uno spazio, seguono 10 caratteri per il 
|       testo + '\0' aggiunto dal compilatore).
|       Naturalmente vanno inizializzati solo gli
|       elementi che servono ma e' necessario, 
|       per il buon funzionamento della routine 
|       Menu_Set, dimensionare l'array come 
|       indicato. 
|
|    RITORNO : TRUE se e' andato tutto bene
|              FALSE se non sono stati superati 
|              i controlli
| 
|    NOTE : La funzione permette di legare alla 
|           finestra max 5 menu-strips,
|           ognuna delle quali puo' essere 
|           composta da max 8 items, ognuno dei 
|           quali puo' avere max 4 subitems 
|           associati.   
|           Richiede precedente apertura di 
|           'Intuition Library' e di una 
|           finestra con la Window_Open().
|           La finestra puo' essere aperta sullo
|           schermo del Workbench o su di uno 
|           schermo Custom aperto con una 
|           Screen_Open().
|           Se la finestra e' stata aperta su di
|           uno schermo a bassa risoluzione 
|           (320 x 256) e' possibile inizializzare 
|           solamente max 3 menu-strip.  
|           A chiusura lavoro e' necessario 
|           richiamare la Menu_Reset()
|           per rilasciare i menus prima della 
|           chiusura della window.
|_____________________________________________*/          

  int
  Menu_Set(wn,fp,men)
  int wn;
  int fp; 
  char men [5][9][5][12];
  {
   int  nm,nt,ns;
  
   if(wn < 1 || wn > 4) return(FALSE);  
   if(fp > 31) return(FALSE); 

/*           inizializzazione strutture      */
   
   for (nt=0; nt < 5; nt++)
   {
     if (nt == 4)  Titoli[nt].NextMenu = NULL;
     else
     Titoli[nt].NextMenu = &Titoli[nt+1];
     Titoli[nt].LeftEdge = nt * 98 + 3;
     Titoli[nt].TopEdge = 0;
     Titoli[nt].Width = 98;
     Titoli[nt].Height = 10;
     Titoli[nt].Flags = MENUENABLED;
     Titoli[nt].MenuName = NULL;
     Titoli[nt].FirstItem = &Items[nt][0];
	
     for (nm=0; nm < 8; nm++)
     { 
       ItemText[nt][nm].FrontPen = fp;
       ItemText[nt][nm].BackPen = -1;
       ItemText[nt][nm].DrawMode = JAM1;
       ItemText[nt][nm].LeftEdge = 0;
       ItemText[nt][nm].TopEdge = 1;
       ItemText[nt][nm].ITextFont = NULL;
       ItemText[nt][nm].IText = NULL;
       ItemText[nt][nm].NextText = NULL;

       if (nm == 7) Items[nt][nm].NextItem = NULL;
       else 
       Items[nt][nm].NextItem = &Items[nt][nm+1];
       Items[nt][nm].LeftEdge = 0; 
       Items[nt][nm].TopEdge = nm * 10;
       Items[nt][nm].Width = 117;
       Items[nt][nm].Height = 10; 
       Items[nt][nm].Flags =  ITEMENABLED 
                           | ITEMTEXT | HIGHCOMP;
       Items[nt][nm].MutualExclude = 0; 
       Items[nt][nm].ItemFill = 
                         (APTR)&ItemText[nt][nm];
       Items[nt][nm].SelectFill = NULL;
       Items[nt][nm].Command = NULL;
       Items[nt][nm].SubItem = 
                            &SubItems[nt][nm][0];
       Items[nt][nm].NextSelect = NULL;

       for (ns=0; ns < 4; ns++)
       {
         SubText[nt][nm][ns].FrontPen = fp;
         SubText[nt][nm][ns].BackPen = -1;
         SubText[nt][nm][ns].DrawMode = JAM1;
         SubText[nt][nm][ns].LeftEdge = 0;
         SubText[nt][nm][ns].TopEdge = 1;
         SubText[nt][nm][ns].ITextFont = NULL;
         SubText[nt][nm][ns].IText = NULL;
         SubText[nt][nm][ns].NextText = NULL;
        
         if (ns == 3) 
           SubItems[nt][nm][ns].NextItem = NULL; 
         else
         SubItems[nt][nm][ns].NextItem = 
                        &SubItems[nt][nm][ns+1];
         SubItems[nt][nm][ns].LeftEdge = 120; 
         SubItems[nt][nm][ns].TopEdge = ns * 10;
         SubItems[nt][nm][ns].Width = 117;
         SubItems[nt][nm][ns].Height = 10; 
         SubItems[nt][nm][ns].Flags = 
              ITEMENABLED | ITEMTEXT | HIGHCOMP;
         SubItems[nt][nm][ns].MutualExclude = 0; 
         SubItems[nt][nm][ns].ItemFill =
                     (APTR)&SubText[nt][nm][ns];
         SubItems[nt][nm][ns].SelectFill = NULL;
         SubItems[nt][nm][ns].Command = NULL;
         SubItems[nt][nm][ns].SubItem = NULL;
         SubItems[nt][nm][ns].NextSelect = NULL;
       } /* for ns */
     } /* for nm */
   } /* for nt */

/*    filling strutture in funzione dell'array 
      passato come argomento      */

   for (nt=0; nt < 5; nt++)
   {
     if (men[nt][0][0][0] == '\0')
          {Titoli[nt-1].NextMenu=NULL; break; };
     Titoli[nt].MenuName = &men[nt][0][0][0];

     for (nm=0; nm < 8; nm++)   
     {
       if (men[nt][nm+1][0][0] == '\0')
    { Items[nt][nm-1].NextItem = NULL; break; }
       ItemText[nt][nm].IText = 
                 (UBYTE *)&men[nt][nm+1][0][1];
       if(men[nt][nm+1][0][0] != ' ')
       {
         Items[nt][nm].Command = 
                           men[nt][nm+1][0][0];
         Items[nt][nm].Flags |= COMMSEQ;
       }
       if (men[nt][nm+1][1][0] == '\0')
    { Items[nt][nm].SubItem = NULL; continue; } 
       for (ns=0; ns < 4; ns++)
       { 
         if (men[nt][nm+1][ns+1][0] == '\0')
{SubItems[nt][nm][ns-1].NextItem = NULL; break;}  
         SubText[nt][nm][ns].IText = 
               (UBYTE *)&men[nt][nm+1][ns+1][1];
         if(men[nt][nm+1][ns+1][0] != ' ')
         {   
           SubItems[nt][nm][ns].Command = 
                         men[nt][nm+1][ns+1][0];
           SubItems[nt][nm][ns].Flags |= COMMSEQ;
         }
       } /* for ns */
     } /* for nm */
   } /* for nt */

  SetMenuStrip(Window_Addr(wn),&Titoli[0]);
  return(TRUE);
  }



/*----------------------------------------------
|   void
|   Menu_OnOff(wn,onoff,menu,item,subitem)
|
|    FUNZIONE  : abilita o disabilita alla 
|                selezione una intera menu-strip,
|                o un item, o un subitem.
|
|    ARGOMENTI : int wn;   - 
|         (valore da 1 a 4) numero della finestra
|         cui e' stata associata la menu-strip.   
|
|               int onoff; - 
|         (valore = 0 o 1) 0 = disabilitazione,
|                             1 = abilitazione.
|
|                int menu; -  (valore da 1 a 5) 
|         numero ordinale della strip
|         da abilitare/disabilitare oppure a cui 
|         appartiene l'item o il subitem da             
|         abilitare/disabilitare.
|
|                int item; - (valore da 0 a 8) 
|         numero ordinale a partire da 1
|         dell'item da abilitare/disabilitare 
|         oppure a cui appartiene il subitem da 
|         abilitare/disabilitare.
|         Va posto uguale a 0 se si vuole 
|         abilitare/disabilitare l'intera strip 
|         in questo caso l'argomento subitem non
|         viene considerato e si consiglia di 
|         porlo uguale a 0. 
|    
|             int subitem; - (valore da 0 a 4) 
|         numero ordinale a partire da 1
|         del subitem da abilitare/disabilitare,
|         va posto uguale a 0 se si vuol 
|         abilitare/disabilitare l'intera 
|         menu-strip oppure l'intero item oppure
|         nel caso in cui l'item passato come 
|         secondo argomento non abbia subitems 
|         collegati.    
|_____________________________________________*/           

  void
  Menu_OnOff(wn,onoff,menu,item,subitem)
  int wn;
  int onoff;
  int menu;
  int item;
  int subitem;
  {
   USHORT elemento = 0;
  
   menu -= 1;
   item -= 1; 
   subitem -= 1;

   if(item < 0) item = NOITEM;
   if(subitem < 0) subitem = NOSUB;

   elemento = SHIFTSUB(subitem) 
          | SHIFTITEM(item) | SHIFTMENU(menu);

   if(onoff) OnMenu(Window_Addr(wn),elemento);
   else OffMenu(Window_Addr(wn),elemento);
  }


/*---------------------------------------------
|    void
|    Menu_Reset(wn)
|
|    FUNZIONE  : rilascia le menu-strips 
|          precedentemente legate alla finestra
|
|    ARGOMENTI : int wn;   - (valore da 1 a 4) 
|          numero della finestra cui sono state
|          associate le menu-strips.   
|______________________________________________*/

  void
  Menu_Reset(wn)
  int wn;
  {
   ClearMenuStrip(Window_Addr(wn));
  }


