/*************************************************************************
*                                                                        *
*                                                                        *
*                       DOSHelper Version 1.60                           *
*                         by  John Youells                               *
*                        &  Wayne Westfield                              *
*                     © John Youells & LifeStream                        *
*                                                                        *
*                                                                        *
*                                                                        *
*                                                                        *
*    This program is being distributed as "shareware".  If you like  it, *
*             and use it  please send $10.00 to:                         *
*                       John Youells                                     *
*                       94 Second Ave.                                   *
*                       Kingston, PA 18704                               *
*                                                                        *
*                                                                        *
*    Feel free to distribute this program to other Amiga users and       *
*    modify it to suit your needs as long as the original credits        *
*    remain intact.  We would appreciate knowing about any errors or     *
*    improvements.....                                                   *
*                                                 Enjoy                  *
*                                              John Youells              *
*                                              QLink  "JAY"              *
*                                              PLink OFR539              *
*                                                                        *
*    This program was compiled under ManxC and Lattice C v3.02.....      *
*                                                                        *
*    We would like to thank John Draper (aka Cap'n Crunch) for his       *
*    excellent tutorial called "menus.c" which allowed us to build       *
*    menu structures that are both smaller and more readable.            *
*                                                                        *
*    BUGS:  There is one - if you make the window smaller and then       *
*    select an item the IntuiText is not clipped properly and will       *
*    overwrite the window borders.  We understand that this bug in       *
*    Workbench 1.1 ( and the manuals! ) will be corrected in 1.2.        *
*                                                                        *
*                                                                        *
************************************************************************ */

#include <exec/types.h>
#include <exec/nodes.h>
#include <exec/lists.h>
#include <exec/ports.h>
#include <exec/io.h>
#include <exec/exec.h>
#include <exec/execbase.h>
#include <exec/devices.h>
#include <exec/memory.h>
#include <libraries/dos.h>
#include <intuition/intuition.h>
#include <devices/console.h>
#include <devices/keymap.h>
#include <graphics/regions.h>
#include <graphics/copper.h>
#include <graphics/gels.h>
#include <graphics/gfxbase.h>
#include <graphics/clip.h>
#include <graphics/layers.h>
#include <graphics/gfx.h>
#include <graphics/view.h>
#include <graphics/rastport.h>
#include <hardware/blit.h>

/* Don't need all of these - just so tired of all those warnings */



/**************************************************************************
*                      I M P O R T A N T   C O N S T A N T S              *
**************************************************************************/


#define  NL 0

/*** CLOSE FLAGS FOR VARIOUS THINGS ***/


long mask = 0;

#define INTUITION 0x00000001
#define GRAPHICS  0x00000002
#define SCREEN    0x00000004
#define WINDOW    0x00000008
#define COLORMAP  0x00000010
#define MENU      0x00000020

/***************************************************************************
*                   F U N C T I O N   D E C L A R A T I O N S              *
***************************************************************************/



#define AZTEC               /* Comment this line out if using Lattice C */

#ifdef  AZTEC

extern void *OpenLibrary();
extern struct Window *OpenWindow();
extern struct IntuiMessage *GetMsg();

#endif

/**************************************************************************
      THIS IS THE STRUCTURE DEFINITION FOR THE TEXT FILE FOR DOSHelper    *
***************************************************************************/

struct file
{
char line1[80];
char line2[80];
char line3[80];
char line4[80];
char line5[80];
char line6[80];
char line7[80];
char line8[80];
char line9[80];
char line10[80];
char line11[80];
char line12[80];
char line13[80];
char line14[80];
char line15[80];
char line16[80];
char line17[80];
char line18[80];
char line19[80];
};
#include <DHFiles>

/**************************************************************************
*       I N T U I T I O N   G L O B A L   V A R I A B L E S               *
**************************************************************************/


struct IntuitionBase  *IntuitionBase;
struct GfxBase        *GfxBase;
struct IntuiMessage   *message;
struct RastPort       *MyPort;
struct Window         *w;
struct IntuiText      display[23];   /*    display array                  */
struct IntuiText      clear[23];     /*    clear the screen array         */


/**************************************************************************
*                 M E N U   D E F I N I T I O N S                         *
**************************************************************************/



#define NUM_MENUS 4          /* number of menus */

/* Copies of this sturcture will get stamped into more structures        */
/* allocated later                                                       */

struct IntuiText generic = {
  0,1,                       /* background pen, foreground pen     */
  JAM2,5,                    /* text mode, LeftEdge                */
  0,NL,                      /* Top (to be filled in later), Front */
  NL,                        /* Name (to be filled in later)       */ 
  NL                         /* pointer to the next structure      */

                           };

/* Menu numbers */

#define SYSTEM_MENU        0
#define BATCH_MENU         1
#define FILE_MENU          2
#define MISC_MENU          3

/* Menu widths */

#define SYSTEM_WIDTH  90
#define BATCH_WIDTH   90
#define FILE_WIDTH    90
#define MISC_WIDTH    90


/* initialize an array of item withs */

int item_widths[ NUM_MENUS ] ={   95,95,95,95   };

/* all menu items have the following flags set */

#define BOX_FILL  ITEMTEXT | ITEMENABLED | HIGHBOX

/************************* MISC MENU *****************/

#define NUM_MISC     4   /* number of items in menu */
#define Say          0   /* an item number for each */
#define Why          1
#define Help         2
#define About        3
struct MenuItem misc_items[ NUM_MISC ];
struct IntuiText  misc_names[ NUM_MISC ];

char *misces_names[]={
   "Say",                   /* text for the item names  */
   "Why",
   "HELP",
   "ABOUT...",
                     };

struct Menu misc_menu={
   NL,                                            /* no next menu */
   20 + SYSTEM_WIDTH + BATCH_WIDTH + FILE_WIDTH,  /* LeftEdge */
   0, MISC_WIDTH, 10 ,                         /* TopEdge, Width, Height */
   MENUENABLED,                                   /* FLAGS */
   "Misc.",                                       /* name of menu */
   misc_items                                     /* first item structure */
                      } ;

/* Repeat this for each menu */


/******************** FILE MENU ***************/

#define NUM_FILE  13
#define Copy      0
#define Delete    1
#define Dir       2
#define Ed        3
#define Edit      4
#define Filenote  5
#define Join      6
#define Protect   7
#define Relabel   8
#define Rename    9
#define Search    10
#define Sort      11
#define Type      12

struct MenuItem file_items[ NUM_FILE ];
struct IntuiText file_names[ NUM_FILE ];

char *files_names[]={

            "Copy",
            "Delete",
            "Dir",
            "Ed",
            "Edit",
            "Filenote",
            "Join",
            "Protect",
            "Relabel",
            "Rename",
            "Search",
            "Sort",
            "Type"
                    };

struct Menu file_menu={
   &misc_menu,
   20 + BATCH_WIDTH + SYSTEM_WIDTH,
   0,  FILE_WIDTH, 10,
   MENUENABLED,
   "File",
   file_items
                       };


/******************** BATCH MENU *********************/

#define NUM_BATCH 9
#define Echo      0
#define Execute   1
#define Failat    2
#define Fault     3
#define If        4
#define Lab       5
#define Quit      6
#define Skip      7
#define wait      8

struct MenuItem batch_items[ NUM_BATCH ];
struct IntuiText batch_names[ NUM_BATCH ];

char *batches_names[]={
            "Echo",
            "Execute",
            "Failat",
            "Fault",
            "If",
            "Lab",
            "Quit",
            "Skip",
            "Wait"
                      };

struct Menu batch_menu={
   &file_menu,
   20 + SYSTEM_WIDTH,
   0,  BATCH_WIDTH,   10,
   MENUENABLED,
   "Batch",
   batch_items
                       };


/*********************************** SYSTEM MENU ************/

#define NUM_SYSTEM  16
#define Assign       0
#define Break        1
#define Cd           2
#define Date         3
#define Diskcopy     4
#define Endcli       5
#define Format       6
#define Info         7
#define Install      8
#define List         9
#define Makedir     10
#define Newcli      11
#define Prompt      12
#define Run         13
#define Stack       14
#define Status      15

struct MenuItem system_items[ NUM_SYSTEM ];
struct IntuiText system_names[ NUM_SYSTEM ];

char *systems_names[]={
            "Assign",
            "Break",
            "Cd",
            "Date",
            "Diskcopy",
            "Endcli",
            "Format",
            "Info",
            "Install",
            "List",
            "Makedir",
            "Newcli",
            "Prompt",
            "Run",
            "Stack",
            "Status"
                      };


struct Menu system_menu={
   &batch_menu,
   20,
   0,  SYSTEM_WIDTH, 10,
   MENUENABLED,"System",
   system_items

                         };
                             /* Thats all for the menus - whew!       */
                             /* But its a lot longer to do the        */
                             /* way its shown in the Intuition Manual */  
                             /*   Thanks John!                        */

/***************************************************************************
*                N E W   W I N D O W   S T R U C T U R E                   *
***************************************************************************/


struct  NewWindow  nw = {
   0, 0,                     /*   Start Position                      */
   640, 200,                 /*   Width, Height,                      */
   0, 1,                     /*   DetailPen, BlockPen                 */
     CLOSEWINDOW             /*   IDCMPFlags                          */
   | REFRESHWINDOW
   | MOUSEBUTTONS
   | MENUPICK ,
     WINDOWDEPTH             /* Regular flags for gadgets attached to */
   | WINDOWSIZING            /* the window and its characteristics    */
   | WINDOWDRAG
   | WINDOWCLOSE
   | SMART_REFRESH           /* For the window title below we cast    */
   | ACTIVATE ,              /* the pointer to an unsigned char to    */
                             /* avoid compiler warnings...            */

     NULL,                   /* no user defined Gadgets               */
     NULL,                   /* no user defined CheckMark             */

     (UBYTE *)"   DOSHelper  ©  1986 LifeStream  Version 1.60   15Aug86 ",

     NULL,                   /* pointer to Screen (set if custom )    */
     NULL,                   /* pointer to SUPER_BITMAP               */
     60, 80, 640, 200,       /* MinWidth, MinHeight, MaxWidth,        */
                             /* MaxHeight for resizing                */
     WBENCHSCREEN,           /* Use the standard screen type          */
                        };

/*************************************************************************
*            P R I N T  to the  S C R E E N                              *
**************************************************************************/


print(port,file)
struct RastPort *port;
int file;
{
    PrintIText(port,&clear,10,11);
    display[1].IText=(UBYTE *)files[file].line1;
    display[2].IText=(UBYTE *)files[file].line2;
    display[3].IText=(UBYTE *)files[file].line3;
    display[4].IText=(UBYTE *)files[file].line4;
    display[5].IText=(UBYTE *)files[file].line5;
    display[6].IText=(UBYTE *)files[file].line6;
    display[7].IText=(UBYTE *)files[file].line7;
    display[8].IText=(UBYTE *)files[file].line8;
    display[9].IText=(UBYTE *)files[file].line9;
    display[10].IText=(UBYTE *)files[file].line10;
    display[11].IText=(UBYTE *)files[file].line11;
    display[12].IText=(UBYTE *)files[file].line12;
    display[13].IText=(UBYTE *)files[file].line13;
    display[14].IText=(UBYTE *)files[file].line14;
    display[15].IText=(UBYTE *)files[file].line15;
    display[16].IText=(UBYTE *)files[file].line16;
    display[17].IText=(UBYTE *)files[file].line17;
    display[18].IText=(UBYTE *)files[file].line18;
    display[19].IText=(UBYTE *)files[file].line19;
    PrintIText(port,&display,10,11);
}

/**************************************************************************
*                C L E A R   the   S C R E E N                            * 
***************************************************************************/

/*  There is a built in function to do this but so far either we or the
  compilers can't get it right.  So we will build our own....             */



Setclear()
{


int i;
int y;
for(i=0;i<21;i++)
  {
clear[i].FrontPen=1;
clear[i].BackPen=0;
clear[i].DrawMode=JAM2;
clear[i].LeftEdge=2;
clear[i].TopEdge=i*9;
clear[i].ITextFont=NULL;
clear[i].IText=(UBYTE *)"                                                                            ";
  }
for(y=0;y<21;y++)
  {
clear[y].NextText=&clear[y+1];
  }
clear[21].NextText=NULL;
}

/*************************************************************************/

SetUpDisplay()
{

int i;
int y;
for(i=0;i<21;i++)
  {
display[i].FrontPen=1;
display[i].BackPen=0;
display[i].DrawMode=JAM2;
display[i].LeftEdge=2;
display[i].TopEdge=i*9;
display[i].ITextFont=NULL;
   }
for(y=0;y<20;y++)
   {
display[y].NextText=&display[y+1];
   }
display[20].NextText=NULL;
}
/***************************************************************************
*             M A I N   P R O G R A M   M O D U L E                        *
***************************************************************************/

     



main()
{
ULONG class;
USHORT code;
int    i;


/************************************************************************
*  Read in libraries, and set each "read" mask bit                      *
************************************************************************/

 
   if(!(GfxBase = (struct GfxBase *)OpenLibrary("graphics.library",0L)))
   {
      puts("no graphics library!!!");
      close_things();
      exit(1);
   }
   mask |= GRAPHICS;
 
 if(!(IntuitionBase = (struct IntuitionBase *)
       OpenLibrary("intuition.library",0L)))
   {
      puts("no intuition here!!");
      close_things();
      exit(2);
   }
   mask |= INTUITION;
 
/***************************************************************************
                OPEN UP THE WINDOW ON TOP OF WORKBENCH SCREEN
***************************************************************************/
 
   if (!(w = (struct Window *)OpenWindow(&nw) ))
   {
      puts("could not open the window");
      close_things();
      exit(3);
   }
   mask |= WINDOW;
 
/***************************************************************************
                          CREATE THE THREE MENUS
***************************************************************************/
 

NewMenu(&system_menu,systems_names,system_items,system_names,NUM_SYSTEM,
        item_widths[0],BOX_FILL);

NewMenu(&batch_menu,batches_names,batch_items,batch_names,NUM_BATCH,
        item_widths[1],BOX_FILL);

NewMenu(&file_menu,files_names,file_items,file_names,NUM_FILE,
        item_widths[2],BOX_FILL);

NewMenu(&misc_menu,misces_names,misc_items,misc_names,NUM_MISC,
        item_widths[3],BOX_FILL);


MyPort=w->RPort;

SetMenuStrip( w,&system_menu);
Setclear();
SetUpDisplay();

for (;;)


  {

   if ((message = (struct IntuiMessage *) GetMsg(w->UserPort)) == 0L)  {
   Wait(1L<<w->UserPort->mp_SigBit);
   continue;
                                                                        }

   class=message->Class;
   code=message->Code;
   ReplyMsg(message);
   switch (class)  {

 
           case CLOSEWINDOW : close_things();
                              exit(0);
                              break;
 
           case MENUPICK    : if (MENUNUM(code) != MENUNULL)
                                domenu(MENUNUM(code), ITEMNUM(code),
                                       SUBNUM(code));
                              break;
          case MOUSEBUTTONS : break;
                    }   /* Case */
  }  /* for */
}   /* End of Main */
 
/***************************************************************************
                        DO THE MENU SELECTIONS
***************************************************************************/
domenu(menu, item, subitem)
int  menu, item, subitem;
{
   switch (menu)  {

         case SYSTEM_MENU:
               switch(item)
                    {
                     case Assign:
                           print(MyPort,0);
                           break;
                     case Break:
                           print(MyPort,1);
                           break;
                     case Cd:
                           print(MyPort,2);
                           break;
                     case Date:
                           print(MyPort,4);
                           break;
                     case Diskcopy:
                           print(MyPort,7);
                           break;
                     case Endcli:
                           print(MyPort,11);
                           break;
                     case Format:
                           print(MyPort,16);
                           break;
                     case Info:
                           print(MyPort,18);
                           break;
                     case Install:
                           print(MyPort,19);
                           break;
                     case List:
                           print(MyPort,22);
                           break;
                     case Makedir:
                           print(MyPort,23);
                           break;
                     case Newcli:
                           print(MyPort,24);
                           break;
                     case Prompt:
                           print(MyPort,25);
                           break;
                     case Run:
                           print(MyPort,30);
                           break;
                     case Stack:
                           print(MyPort,34);
                           break;
                     case Status:
                           print(MyPort,35);
                           break;
                    }
            break;
            case BATCH_MENU:
               switch(item)
                    {

                     case Echo:
                           print(MyPort,8);
                           break;
                     case Execute:
                           print(MyPort,12);
                           break;
                     case Failat:
                           print(MyPort,13);
                           break;
                     case Fault:
                           print(MyPort,14);
                           break;
                     case If:
                           print(MyPort,17);
                           break;
                     case Lab:
                           print(MyPort,21);
                           break;
                     case Quit:
                           print(MyPort,27);
                           break;
                     case Skip:
                           print(MyPort,32);
                           break;
                     case wait:
                           print(MyPort,37);
                           break;
                     }
            break;
           case FILE_MENU:
                switch(item)
                     {


                     case Copy:
                           print(MyPort,3);
                           break;
                     case Delete:
                           print(MyPort,5);
                           break;
                     case Dir:
                           print(MyPort,6);
                           break;
                     case Ed:
                           print(MyPort,9);
                           break;
                     case Edit:
                           print(MyPort,10);
                           break;
                     case Filenote:
                           print(MyPort,15);
                           break;
                     case Join:
                           print(MyPort,20);
                           break;
                     case Protect:
                           print(MyPort,26);
                           break;
                     case Relabel:
                           print(MyPort,28);
                           break;
                     case Rename:
                           print(MyPort,29);
                           break;
                     case Search:
                           print(MyPort,31);
                           break;
                     case Sort:
                           print(MyPort,33);
                           break;
                     case Type:
                           print(MyPort,36);
                           break;
                     }
              break;
              case MISC_MENU:
                switch(item)
                     {

                     case Say:
                           print(MyPort,39);
                           break;
                     case Why:
                           print(MyPort,38);
                           break;
                     case Help:
                           print(MyPort,40);
                           break;
                     case About:
                           print(MyPort,41);
                           break;

                     }
              break;


                   }
 }


/**************************************************************************
*              C R E A T E   A   N E W   M E N U                          *
**************************************************************************/


NewMenu(menu, item_names, menu_items, menu_text, num_items, Mwidth, flag)

struct Menu       *menu;
unsigned char     *item_names[];
struct MenuItem   menu_items[];
struct IntuiText  menu_text[];
int               num_items;
int               Mwidth;
int               flag;
{
   int i;
   int height=0;
   for (i=0; i< num_items; i++)
     {

   menu_text[i]= generic;
   menu_text[i].IText=item_names[i];
   menu_items[i].NextItem = &menu_items[i + 1];
   menu_items[i].TopEdge= 10 * i;
   menu_items[i].LeftEdge=0;
   menu_items[i].Height=8;
   menu_items[i].ItemFill=(APTR)&menu_text[i];
   menu_items[i].Flags=flag;
   menu_items[i].Width=Mwidth;
   menu_items[i].MutualExclude = 0x0000;
   menu_items[i].Command =0;
   menu_items[i].SubItem=NL;
   menu_items[i].NextSelect=NL;
   height += 10;
     }

   menu_items[num_items-1].NextItem=NULL;
   menu->Height=height;
}


 
/***************************************************************************
                     C L O S E      T H I N G S
***************************************************************************/
 
close_things()
{
   if (mask & MENU)      ClearMenuStrip(w, &system_menu);
   if (mask & WINDOW)    CloseWindow(w);
   if (mask & GRAPHICS)  CloseLibrary(GfxBase);
      OpenWorkBench();
   if (mask & INTUITION) CloseLibrary(IntuitionBase);
}
 
