/*****************************************************************************\

       QuickMenu               Geschrieben von Sauer Franz

  Arbeitszeiten:   10-06-88   2   Std.
                   11-06-88   3   Std.
                   21-06-88   4.5 Std.
                   22-06-88   4   Std.
                   23-06-88   5   Std.
                   24-06-88   4   Std.
                   25-06-88   8   Std.
                   26-06-88   8   Std.


\*****************************************************************************/

#include <exec/types.h>
#include <exec/memory.h>
#include <exec/tasks.h>
#include <devices/timer.h>
#include <libraries/dos.h>
#include <intuition/intuitionbase.h>
#include <libraries/dosextens.h>
#include <stdio.h>
#include <menu.h>


/*****************************************************************************\

                    W I C H T I G E    K O N S T A N T E N

\*****************************************************************************/



#define INTUITION 0x00000001  /* Scließflags fÜr verschiedene Resourcen */
#define GRAPHICS  0x00000002
#define SCREEN    0x00000004
#define WINDOW    0x00000008
#define COLORMAP  0x00000010
#define MENU      0x00000020
#define DISK      0x00000040

#define INTUITION_REV   1
#define WIN_BREITE      420      /* Breite des Uhren Fenster            */
#define WAIT_TIME       2500

#define MAXMENUS    6            /* Maximale Anzahl der Hauptmenupunkte */
#define MAXITEMS    10           /* Maximale Anzahl der Menupunkte      */
#define MAXSUBS     5            /* Maximale Anzahl der Untermenupunkte */
#define MAXFILES    300          /* Maximale Anzahl alle Menupunkte     */
#define MENUTEXTL   20           /* Maximale Laenge des Menutextes      */
#define COMMANDL    60           /* Maximale Laenge eines Befehls       */
#define MENUABSTAND 10           /* Freiraum in Pixel zwischen den Menus */

void   *OpenLibrary();
ULONG  AvailMem();

struct Window          *OpenWindow();
struct IntuiMessage    *GetMsg();
struct Window          *BuildSysRequest();
struct Gadget          *GetReqGad();
struct FileHandle      *fh, *fp, *Open(), *Output();
struct IntuitionBase   *IntuitionBase;
struct GfxBase         *GfxBase;
struct IntuiMessage    *message;
struct RastPort        *rp;
struct Window          *w;
struct timerequest     Time_Req;
struct MsgPort         *Timer_Port = NULL, *CreatePort();
struct DateStamp       jetzt;
struct Task            *FindTask();

struct Menu       menu[MAXMENUS+1];
struct MenuItem   mitem[MAXFILES];
struct IntuiText  mtext[MAXFILES];

char Datum_Buffer[40];

struct IntuiText  Datum_Text = { 1, 0,JAM2,0,0,(struct TextAttr *) NULL,
                                Datum_Buffer,(struct IntuiText *) NULL  };


/*****************************************************************************\

                        W I N D O W     S T R U K T U R

\*****************************************************************************/

struct NewWindow nw = {
  (590-WIN_BREITE), 0,   /*  Start position                               */
  WIN_BREITE, 10,        /*  Breite, Höhe,                                */
  -1, -1,                /*  detail, block pens                           */
  CLOSEWINDOW            /*  IDCMP Flags                                  */
| REFRESHWINDOW
| MOUSEBUTTONS
| MENUPICK,
                         /*  Flags                                        */
  WINDOWDEPTH
| WINDOWDRAG
| WINDOWCLOSE
| SMART_REFRESH
| NOCAREREFRESH,

  NULL,                  /* Keine Gadgets                                 */
  NULL,                  /* Keine Haken                                   */
  "",
  NULL,                  /* Screenzeiger wird später gesetzt              */
  NULL,                  /* Keine SuperBitmap Zeiger                      */
  0, 0, 0, 0,
  WBENCHSCREEN,          /* Benutzt den Workbench Screen                  */
  };


int  itemanzahl[MAXMENUS+1];
int  subanzahl[MAXMENUS+1][MAXITEMS+1];
int  z1[MAXITEMS+1];
int  subpos[MAXITEMS+1];
int  maxitemlen[MAXMENUS+1];
int  aktmenu,menuanz;

short stunden,minuten;
int   chip_frei,fast_frei;
long  mask = 0;
ULONG DosBase;

char excommand[MAXMENUS+1][MAXITEMS+1][MAXSUBS+1][COMMANDL+1];
char menutext[MAXMENUS+1][MAXITEMS+1][MAXSUBS+1][MENUTEXTL+1];
char *filebuffer;
int  *menunr;

/*****************************************************************************\

                         M A I N     P R O G R A M M

\*****************************************************************************/


main()

{

ULONG  class;
USHORT code;
int    r,i;
BOOL   cont = 1;
USHORT menunum;
USHORT itemnum;
USHORT subnum;
USHORT erlaubt=1;

if(!(GfxBase = (struct GfxBase *)OpenLibrary("graphics.library",0)))
  {
  printf("Finde leider die 'Graphics Library' nicht !!!\n");
  Schliessen();
  exit(30);
  }

mask |= GRAPHICS;

if(!(IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library",0)))
  {
  printf("Finde leider keine 'Intuition' vor !!\n");
  Schliessen();
  exit(30);
  }

mask |= INTUITION;

if (!(w = (struct Window *)OpenWindow(&nw) ))
   {
   printf("Kann mein 'Window' nicht öffnen\n");
   Schliessen();
   exit(10);
   }

mask |= WINDOW;

if (!(Timer_Port = CreatePort("Timer Port",0)))
   {
   printf("Kann das 'TIMER PORT' nicht öffnen\n");
   Schliessen();
   exit(30);
   }

if (OpenDevice(TIMERNAME,UNIT_VBLANK,(char *)&Time_Req,0)!=NULL)
   {
   printf("Kann das 'TIMER DEVICE' nicht öffnen\n");
   Schliessen();
   exit(30);
   }

if (!(DosBase=OpenLibrary("dos.library",0)))
   {
   printf("Kann das 'DOS' nicht öffnen !!\n");
   Schliessen();
   exit(30);
   }

if (!(fp=Open("s:QuickMenu.Config",MODE_OLDFILE)))
   {
   printf ("Konnte 's:QuickMenu.Config' nicht öffnen !\n");
   Schliessen();
   exit(10);
   }

mask |= DISK;

rp = w->RPort;
Time_Req.tr_node.io_Message.mn_ReplyPort = Timer_Port;
Time_Req.tr_node.io_Command              = TR_ADDREQUEST;
Time_Req.tr_node.io_Flags                = 0;
Time_Req.tr_node.io_Error                = 0;

SetTaskPri(FindTask((char *)0),0);
Variablenloeschen();
Liesconfig ();
Menuinit ();

/*****************************************************************************\

                        E R E I G N I S A B F R A G E

\*****************************************************************************/


for ( ; ; )
    {
    if ((message=(struct IntuiMessage *)GetMsg(w->UserPort))==0L ) /* && (message=GetMsg(Timer_Port))==0L ) */
       {
       if (erlaubt==1)
          Uhrsetzen ();
       Wait(1 << w->UserPort->mp_SigBit | 1 << Timer_Port->mp_SigBit);
       erlaubt=1;
       continue;
       }
    if ( message->Class )
       {
       class = message->Class;
       code =  message->Code;
       ReplyMsg(message);
       erlaubt =0;
       switch (class)
              {
              case CLOSEWINDOW : Schliessen ();
                                 exit(0);
                                 break;

              case MENUPICK    : if (MENUNUM(code) != MENUNULL)
                                    domenu(MENUNUM(code),ITEMNUM(code),SUBNUM(code));
                                    break;

             case MOUSEBUTTONS : Delay(20);
                                 break;

              }      /* Case */
       Delay(40);
       }
    }                /* for           */
}                    /* Ende von Main */





/*****************************************************************************\

                        P R O G R A M M R O U T I N E N

\*****************************************************************************/

Uhrsetzen ()

{

DateStamp(&jetzt);
chip_frei = AvailMem(MEMF_CHIP);
fast_frei = AvailMem(MEMF_FAST);
stunden   = jetzt.ds_Minute/60;
minuten   = jetzt.ds_Minute%60;
sprintf(Datum_Buffer, " Chip:%6d  Fast:%7d  Time:%2d:%02d:%02d ",chip_frei, fast_frei,stunden,minuten,jetzt.ds_Tick/TICKS_PER_SECOND);
PrintIText(rp,&Datum_Text,28,1);
Time_Req.tr_time.tv_secs  = 1;
Time_Req.tr_time.tv_micro = WAIT_TIME;
SendIO ((char *)&Time_Req.tr_node);

}







domenu (menu,item,subitem)

int menu,item,subitem;

{

if ( menu > menuanz )
   return;

menu=menuanz-menu;
if ( item > itemanzahl[menu] ) item=0; else item++;
if ( subitem > subanzahl[menu][item] ) subitem=0; else subitem++;

Execute (excommand[menu][item][subitem],0,0);

}






Schliessen ()

{
   AbortIO((char *) &Time_Req . tr_node);
   if (Time_Req . tr_node . io_Message . mn_ReplyPort) CloseDevice(&Time_Req);
   if (Timer_Port)       DeletePort(Timer_Port);
   if ( fp!=0 )          Close(fp);
   if (mask & MENU)      ClearMenuStrip(w);
   if (mask & WINDOW)    CloseWindow(w);
   if (mask & GRAPHICS)  CloseLibrary(GfxBase);
   if (mask & INTUITION) CloseLibrary(IntuitionBase);
}


Liesconfig ()

{

int  r,r1;
int  m[3];
char befehl[200];
int  filelaenge;

r=r1=0;

Seek(fp,0L,OFFSET_END);

if (!(filelaenge=Seek (fp,0L,OFFSET_BEGINNING)))
   {
   printf ("'QuickMenu.Config' nicht in Ordnung !!!\n");
   Schliessen ();
   exit (20);
   }

filebuffer = AllocMem (filelaenge+1,MEMF_FAST|MEMF_CLEAR);

if ( filebuffer==0 )
   {
   printf ("Nicht genug Speicherplatz !!!\n");
   Schliessen ();
   exit (20);
   }


Read (fp,filebuffer,filelaenge);

do    {
      aktmenu++;         /*  Gesamtanzahl der aktuellen Menus */
      r=0;
      do    {
            befehl[r++]=filebuffer[r1++];
            }
      while ( befehl[r-1]!='\n' );

      befehl[r-1]='\0';
      if ( r==1 )
         aktmenu--;
      if ( aktmenu>MAXFILES-2 )
         {
         printf ("Achtung !!! Zu viele MenÜs. ( Maximal %ld )\n",MAXFILES-2);
         Schliessen ();
         exit (20);
         }
      Machbefehl(befehl);
      }
while ( r1<= filelaenge-1 );

FreeMem (filebuffer,filelaenge+1);

Close (fp);
fp=0;

}




Machbefehl (befehl)


char *befehl;

{

int  m[3],u,u1,r2;
char mt[2],text[250],command[250];
u1=0;

for ( u=0 ; u<3 ; u++ )
    {
    mt[0]=befehl[u1++];
    mt[1]=befehl[u1++];
    mt[2]='\0';
    m[u]= atoi(&mt);
    u1++;
    }
u1++;r2=0;

do    {
      text[r2++]=befehl[u1++];
      }
while ( befehl[u1-1]!='"' );
      text[r2-1]='\0';

u1+=2;r2=0;

do    {
      command[r2++]=befehl[u1++];
      }
while ( befehl[u1-1]!='"' );
      command[r2-1]='\0';

text[MENUTEXTL-1]='\0';
command[COMMANDL-1]='\0';

Menulesen (m[0],m[1],m[2],text,command);

}



Menulesen (m,mi,ms,text,command)

int  m,mi,ms;

char *text;
char *command;


{

int r;

if ( m>MAXMENUS )
   {
   printf ("Achtung !!!  Zu viel MenÜleisten. ( Max %ld )\n",MAXMENUS);
   Schliessen();
   exit (20);
   }

if ( mi>MAXITEMS )
   {
   printf ("Achtung !!!  Zu viel MenÜpunkte. ( Max %ld )\n",MAXITEMS);
   Schliessen();
   exit (20);
   }

if ( ms>MAXSUBS )
   {
   printf ("Achtung !!!  Zu viel UntermenÜpunkte. ( Max %ld )\n",MAXSUBS);
   Schliessen();
   exit (20);
   }

r=0;
while ( text[r++]!='\0' )
      menutext[m][mi][ms][r-1]=text[r-1];

if (menuanz<m) menuanz=m;
if (itemanzahl[m]<mi) itemanzahl[m]=mi;
if (subanzahl[m][mi]<ms) subanzahl[m][mi]=ms;

strcpy (excommand[m][mi][ms],"Run ");
r=0;
while ( command[r++]!='\0' )
      excommand[m][mi][ms][r+3]=command[r-1];

}




Variablenloeschen()

{

int r0,r1;

menuanz=0;

for ( r0=0 ; r0<= MAXMENUS ; r0++ )
    {
    itemanzahl[r0]=0;
    for ( r1=0 ; r1<= MAXITEMS ; r1++ )
        {
        subanzahl[r0][r1]=0;
        z1[r1]=0;
        }
    }

}



Menuinit ()

{

int    m,mi,ms;
int    z,z2;
int    mtoffset=0;

z=0;

for ( m=1 ; m<= menuanz ; m++ )
    mtoffset=mtoffset+(strlen(menutext[m][0][0])*8)+MENUABSTAND;

if ( mtoffset>639 )
   {
   printf ("Die HauptmenÜpunkte wÜrden eine Screenbreite von %ld Punkten erfordern.\n",mtoffset);
   Schliessen();
   exit(30);
   }


mtoffset=0;

for ( m=1 ; m<= menuanz ; m++ )
    {
    cr_MenuTitle  (&mitem[z],menutext[m][0][0],&menu[m]);
    z++;
    if (itemanzahl[m]>0)
       {
       for ( mi=1 ; mi<= itemanzahl[m] ; mi++ )
           {
           if ( mi < 5 )
              subpos[mi]=0;
           else
              subpos[mi]=1;
           if ( mi < itemanzahl[m] )
              {
              cr_MenuText   (&mitem[z],menutext[m][mi][0],0,&mitem[z-1],&mtext[z-1]);
              z1[mi]=z-1;
              z++;
              }
           else
              {
              cr_MenuText   (NULL,menutext[m][mi][0],0,&mitem[z-1],&mtext[z-1]);
              z1[mi]=z-1;
              z++;
              }
           if ( z>MAXFILES-2 )
              {
              printf ("Achtung !!! Zu viele MenÜs. ( Maximal %ld )\n",MAXFILES-2);
              Schliessen ();
              exit (20);
              }
           }
       }

    if ( m==1 )
       cr_Menu (w,NULL,&menu[m],mtoffset,0,1,0);
       else
       cr_Menu (w,&menu[m-1],&menu[m],mtoffset,-20,1,0);

    mtoffset=mtoffset+(strlen(menutext[m][0][0])*8)+MENUABSTAND;

    if (itemanzahl[m]>1)
       {
       for ( mi=1 ; mi<= itemanzahl[m] ; mi++ )
           {
           if (subanzahl[m][mi]>1)
              {
              if (subanzahl[m][mi]>1)
                 {
                 z2=z; /* z2=z-1  */
                 for ( ms=0 ; ms<=subanzahl[m][mi] ; ms++ )
                     {

                     if ( ms < subanzahl[m][mi] )
                        {
                        cr_MenuText(&mitem[z],menutext[m][mi][ms],0,&mitem[z-1],&mtext[z-1]);
                        z++;
                        }
                     else
                        {
                        cr_MenuText   (NULL,menutext[m][mi][ms],0,&mitem[z-1],&mtext[z-1]);
                        cr_SubMenu    (&mitem[z1[mi]],&mitem[z2],50,subpos[mi],0,0);
                        z++;
                        }
                     if ( z>MAXFILES-2 )
                        {
                        printf ("Achtung !!! Zu viele MenÜs. ( Maximal %ld )\n",MAXFILES-2);
                        Schliessen ();
                        exit (20);
                        }
                     }
                 }
              }
           }
       }
    }

mask |= MENU;

}


