#define ANSICOL

#include <stdio.h> 
#include <stdlib.h>
#include <string.h>
#include <dos.h>
#include <fcntl.h> 
#include <exec/types.h>
#include <libraries/dosextens.h>

#include <dlg/dlg.h>
#include <dlg/resman.h>
#include <dlg/user.h>
#include <dlg/portconfig.h>
#include <dlg/menu.h>
#include <dlg/log.h>
#include <dlg/input.h>

#include <link/config.h>
#include <link/io.h>
#include <link/util.h>

#include <proto/dos.h>
#include <proto/exec.h>
#include <proto/dlg.h>

#define INSTACK RStruct.Command_Stack[0]
#define STK     RStruct.Command_Stack
#define HOT     UserDat.Hot_Keys

#include <pragmas/dlg.h>

#include <private/Version.h>
#define  ObjRev "1"
const UBYTE version[]="\0$VER: Sysop Menu Editor " BUILDVER "." ObjRev " ©" COPYRIGHT " by Digerati Dreams "__AMIGADATE__;

void  main(void);
void  ConfigureMenus(void);
BOOL  FormatMenu(void);
BOOL  ListMenuEntries(BOOL);
short LetterPos(char);
BOOL  ReadMenuEntries(BOOL);
void  DelMenuEntry(void);
void  OrderMenuEntries(void);
void  AddMenuEntry(void);
void  EditMenuEntry(void);
void  UpdateMenu(void);
BOOL  WriteMenu(void);
void  EditSets(void);
BOOL  AddSet(void);
BOOL  DelSet(void);
BOOL  EditSet(void);
void  ListLangs(void);
void  ListMenus(BOOL);
void  AddLinefeeds(char *);
void  DelLinefeeds(char *);
void  AddDirectory(char *);
void  ListModules(void);
BOOL  ListFuncs(char *);
void  EditEntryFile(UBYTE , char *);
BOOL  DeleteMenu(void);
BOOL  aborted(char *);
void _CXBRK(void);


struct USER_DATA   UserDat;
struct Ram_File    RStruct;
char               Ext[4];

struct Library    *DLGBase  = NULL;
struct LangStruct *ls;
char             **SA;

#define MAXENTRY    80
struct  MenuHeader  mh       = {
"Undefined", 0, "", 0, "", "", ""}
;
short   numentries           =   0;
struct  MenuEntry   menulist[MAXENTRY];
struct  MenuStuff   ms;

int     mfd                  =  EOF;
char    menuname[15]         = "NONE";
UBYTE   menuopen             =  FALSE;

char   *temparray            =  NULL;
int     elementnum           =   0;

short   Overlay              =  FALSE;


/// Menu
struct ShortMenu Menu[11]   = {
   {
'S',"Select Menu",1}
   ,
   {
'L',"List Menu",1}
   ,
   {
'A',"Add Item",1}
   ,
   {
'D',"Delete Item",1}
   ,
   {
'E',"Edit Item",1}
   ,
   {
'O',"Change Order",1}
   ,
   {
'F',"Format Menu",1}
   ,
   {
'R',"Remove Menu",1}
   ,
   {
'U',"Undo changes",1}
   ,
   {
'C',"Custom Sets",1}
   ,
   {
'M',"Exit",1}
}
;
//-

/// SetMenu
struct ShortMenu SetMenu[6] = {
   {
'L',"List Sets",1}
   ,
   {
'A',"Add Set",1}
   ,
   {
'D',"Del Set",1}
   ,
   {
'E',"Edit Set",1}
   ,
   {
'M',"Prev Menu",1}
   ,
   {
'?',"List Commands",1}
}
;
//-

/// Main
void main()
{
   if (!(DLGBase = OpenLibrary(DLGNAME,DLGVERSION)))  exit(5);

   if (GetDevName(Ext)==-1)
   {
      printf("Unable to get port\n\n");
      _CXBRK();
   }

   if (!(ls = GetLang(Ext)))
   {
      printf("Unable to load language");
      _CXBRK();
   }

   SA=ls->strings;
   
   if (!ReadUser(&RStruct,&UserDat,Ext))
   {
      printf("Unable to load user data");
      _CXBRK();
   }

   WriteLog(SYSOP_CONFIG, RStruct.Name, Ext, SA[1882]);
   ConfigureMenus();
   _CXBRK();
}
//-

/// ConfigureMenus
void ConfigureMenus()
{
   long zflag;
   char string    [3];
   char tempstring[128];

   while(TRUE)
   {
      switch(UserDat.Help_Level)
      {
         case 0: printf(SA[1884], menuname);
         Draw_Line(UserDat.Screen_Width);
         menu(Menu,11,0);
         printf(SA[1885]);
         Draw_Line(UserDat.Screen_Width);
         printf("\n");
         break;

         case 1: menu(Menu,9,1);
         TwoLines();
         break;

         case 2: break;
      }

      Chk_Abort();
      zflag = DLGInput(NULL,string,NULL,1,1,1, SA[1886]);
      Clr(UserDat.Ansi_Flag);
      if (!zflag)  continue;

      switch(string[0])
      {
         case 'S': ListMenus(TRUE);

         DLGInput(temparray,tempstring,((char *)(-1)),14,(USHORT)elementnum,6, SA[1887]);

         TwoLines();

         if (!tempstring[0])
         {
            printf(SA[1888]);
            break;
         }
         
         menuopen = FALSE;
         strcpy(menuname, tempstring);

         if (!ReadMenuEntries(TRUE))
         {
            strcpy(menuname, "NONE");
            strcpy(mh.name,  "Undefined");
         }
         else
         {
            menuopen = TRUE;
            printf(SA[1889]);
         }
         break;

         case 'L': if (!menuopen)
         printf(SA[1890]);
         else
         ListMenuEntries(TRUE);
         break;

         case 'A': if (!menuopen)
         printf(SA[1890]);
         else
         {
            sprintf(tempstring, "DLGConfig:Menu/%s.menun", menuname);
            Copy(tempstring, "t:menu.undo2");
            AddMenuEntry();
         }
         break;

         case 'D': if (!menuopen)
         printf(SA[1890]);
         else
         DelMenuEntry();
         break;

         case 'E': if (!menuopen)
         printf(SA[1890]);
         else
         {
            sprintf(tempstring, "DLGConfig:Menu/%s.menun", menuname);
            Copy(tempstring, "t:menu.undo2");
            EditMenuEntry();
         }
         break;

         case 'O': if (!menuopen)
         printf(SA[1890]);
         else
         OrderMenuEntries();
         break;

         case 'F':  if (!menuopen)
         printf(SA[1890]);
         else
         FormatMenu();
         break;

         case 'M': return;
         break;

         case 'R': DeleteMenu();
         break;

         case 'U': {
            char options = 0;

            if (Exists("t:menu.undo2"))
            {
               printf(SA[1891]);
               options++;
            }

            if (Exists("t:menu.undo1"))
            {
               printf(SA[1892]);
               options++;
            }

            /* No undo files exist, exit */
            if (!options)
            {
               printf(SA[1893]);
               break;
            }

            /* at least one option in available */
            printf(SA[1894]);
            if (!DLGInput(NULL,string,NULL,1,1,1, SA[1895]))
            {
               printf(SA[1896]);
               break;
            }
            TwoLines();    

            if (string[0]!='L' && string[0]!='A')
            {
               printf(SA[1897]);
               break;
            }

            sprintf(tempstring, "DLGConfig:Menu/%s.menun", menuname);
            UnderScore(tempstring);

            if (string[0]=='L')
            Copy("t:menu.undo2", tempstring);
            else
            Copy("t:menu.undo1", tempstring);

            PurgeMenu(Ext, menuname);
            menuopen = FALSE;

            if (!ReadMenuEntries(FALSE))
            {
               strcpy(menuname, "NONE");
               strcpy(mh.name,  "Undefined");
               printf(SA[1898]);
            }
            else
            {
               menuopen = TRUE;
               printf(SA[1899]);
            }
         }
         break;

         case '?': if (UserDat.Help_Level==0) break;
         printf(SA[1884], menuname);
         Draw_Line(UserDat.Screen_Width);
         menu(Menu,11,0);
         printf(SA[1885]);
         Draw_Line(UserDat.Screen_Width);
         printf("\n");
         break;

         case 'C': EditSets();
         break;
      }
   }
}
//-

/// FormatMenu
BOOL FormatMenu(void)
{
   char numentry[3];
   char modulename[17];
   int  a;

   if (mh.numentry == 10)
   strcpy(numentry, "\\N");
   else
   {
      numentry[0] = mh.numentry;
      numentry[1] = 0;
   }

   DelLinefeeds(mh.prompt);

   while(TRUE)
   {
      printf(SA[1900]);
      printf(SA[1901], mh.name);
      printf(SA[1902], mh.columns);
      printf(SA[1903], mh.prompt);
      printf(SA[1904], numentry);
      printf(SA[1905], mh.module);

      a = iinput(1,5,0, SA[1985]);
      Clr(UserDat.Ansi_Flag);

      switch(a)
      {
         case 0: if (!Stricmp(numentry, "\\N"))
         mh.numentry = 10;
         else
         mh.numentry = numentry[0];

         AddLinefeeds(mh.prompt);
         UpdateMenu();
         return(TRUE);
         break;

         case 1: printf(SA[1906],mh.name);
         DLGInput(NULL,mh.name,mh.name,60,60,0, SA[1907]);
         TwoLines();
         break;

         case 2: printf(SA[1908]);
         mh.columns = iinput(1,8,mh.columns, SA[1907]);
         TwoLines();
         break;

         case 3: DLGInput(NULL,mh.prompt,mh.prompt,255,255,0, SA[1909]);
         TwoLines();
         break;

         case 4: DLGInput(NULL,numentry,numentry,2,255,1, SA[1910]);
         TwoLines();
         break;

         case 5: ListModules();
         strcpy(modulename, mh.module);      
         DLGInput(temparray,mh.module,(char *)-1,16,elementnum,6, SA[1911]);
         if (mh.module[0]=='\0')  strcpy(mh.module,modulename);
         TwoLines();
         break;
      }
   }

   return(TRUE);
}
//-

/// ListMenuEntries
BOOL ListMenuEntries(BOOL prompt)
{
   struct MenuNode *mun;
   char             command[512];

   if (!numentries)
   {
      printf(SA[1912]);
      return(FALSE);
   }

   ms.name = menuname;

   if (LockMenu(Ext, &ms, 0, "SysMenu", "Displaying", 0, PENDLOCK)!=RMNOERR)
   {
      printf(SA[1913]);
      return(FALSE);
   }

   mun = ms.mun;
   DisplayMenu(&ms,NULL,0,&UserDat,3,&RStruct,Ext,NULL);

   if (*mun->prompt && prompt)
   {
      TranslateBuffer(mun->prompt, command, 512, &UserDat, &RStruct, Ext);
      printf(command);
      printf("\n\n");
   }

   FreeMenu(Ext, menuname, "SysMenu");
   return(TRUE);
}
//-

/// LetterPos
short LetterPos(char command)
{
   short             entry;
   struct MenuEntry *mptr;
   UBYTE             used;

   used = FALSE;

   if (numentries > 0)
   {
      mptr = menulist;

      for(entry=0; entry<numentries; mptr++, entry++)
      if (mptr->command == command)
      {
         used = TRUE;
         break;
      }
   }

   if (used)
   return(entry);
   else
   return(-1);
}
//-

/// ReadMenuEntries
BOOL ReadMenuEntries(BOOL undo)
{
   ULONG size;
   long  zflag;
   long  newmenu = FALSE;

   char  filename[80];
   char  numentry[2];

   *numentry = 0;

   if (!Stricmp(menuname, "NEW"))
   {
      zflag = finput(1, SA[1914]);
      printf("\n\n");
      
      if (zflag)
      {
         char template[16];
         char templatefilename[80];

         /* We are using a template, list current menus and query for one */
         ListMenus(FALSE);
         DLGInput(temparray,template,(char *)-1,14,elementnum,6, SA[1915]);
         TwoLines();

         /* If we got one, ask the rest of the stuff */
         if (template[0])
         {
            DLGInput(NULL,menuname,NULL,13,13,1, SA[1916]);
            TwoLines();
            if (!*menuname)  return(FALSE);

            sprintf(filename, "DLGConfig:Menu/%s.menun", menuname);
            UnderScore(filename);

            sprintf(templatefilename, "DLGConfig:Menu/%s.menun", template);
            UnderScore(templatefilename);

            Copy(templatefilename, filename);

            sprintf(templatefilename, "DLGConfig:Menu/%s", menuname);
            UnderScore(templatefilename);
            AddDirectory(templatefilename);
         }
      }
   }

   if (!Stricmp(menuname, "NEW"))
   {
      /* We are starting a new menu so delete the current undo files */
      newmenu = TRUE;
      size    =   0;

      DeleteFile("t:menu.undo1");
      DeleteFile("t:menu.undo2");

      DLGInput(NULL,menuname,NULL,13,13,1, SA[1916]);
      TwoLines();
      if (!*menuname)  return(FALSE);

      sprintf(filename, "DLGConfig:Menu/%s.menun", menuname);
      UnderScore(filename);

      DLGInput(NULL,mh.name,NULL,60,60,0, SA[1917]);
      TwoLines();

      printf(SA[1918]);
      mh.columns = iinput(1,8,2, SA[1907]);
      TwoLines();

      DLGInput(NULL,mh.prompt,mh.prompt,255,255,0, SA[1909]);
      TwoLines();
      AddLinefeeds(mh.prompt);

      DLGInput(NULL,numentry,numentry,1,255,1, SA[1910]);
      TwoLines();

      ListModules();
      DLGInput(temparray,mh.module,(char *)-1,16,elementnum,6, SA[1911]);
      if (!mh.module[0])  strcpy(mh.module,"MENU");
      TwoLines();

      sprintf(filename,"DLGConfig:Menu/%s",menuname);
      AddDirectory(filename);
      strcat(filename,".menun");

      mh.numentry = numentry[0];
      WriteMenu();
   }
   else
   {
      sprintf(filename, "DLGConfig:Menu/%s.menun", menuname);
      UnderScore(filename);

      if (FileSize(filename, &size))
      {
         printf(SA[1919]);
         return(FALSE);
      }
      size -= sizeof(struct MenuHeader);

      if (undo)
      {
         Copy(filename, "t:menu.undo1");
         DeleteFile("t:menu.undo2");
      }
   }

   if ((mfd = open(filename,O_RDWR+O_CREAT))==EOF)
   {
      printf(SA[1920]);
      return(FALSE);
   }

   if (!newmenu)  read(mfd, &mh, sizeof(struct MenuHeader));
   numentries = (short)(size/sizeof(struct MenuEntry));
   if (numentries)  read(mfd, &menulist[0], size);

   close(mfd);
   mfd = EOF;

   return(TRUE);
}
//-

/// DelMenuEntry
void DelMenuEntry()
{
   char  tempstring[3];
   char  command;
   short entry;

   ListMenuEntries(FALSE);
   if (!DLGInput(NULL, tempstring, NULL, 2, 2, 1, SA[1921]))
   {
      TwoLines();
      return;
   }
   
   TwoLines();
   if (!Stricmp(tempstring, "\\N"))
   command = 10;
   else
   command = tempstring[0];

   if ((entry = LetterPos(command)) == -1)
   printf(SA[1922], tempstring);
   else
   {
      movmem(&menulist[entry+1],&menulist[entry],(numentries-entry-1)*sizeof(struct MenuEntry));

      numentries--;
      printf(SA[1923], tempstring);
      UpdateMenu();
   }
}
//-

/// OrderMenuEntries
void OrderMenuEntries(void)
{
   char             tempstring[256];
   char             command[3];

   short            entry;
   short            counter;
   short            pos;
   struct MenuEntry tempentry;

   for(counter = 0, pos = 0; counter < numentries; counter++, pos++)
   {
      if (menulist[counter].command=='\n')
      strcpy(tempstring+pos++, "\\N");
      else
      tempstring[pos] = menulist[counter].command;
   }
   tempstring[pos] = 0;

   if (!DLGInput(NULL,tempstring,tempstring,numentries+1,numentries+1,1, SA[1924]))
   {
      TwoLines();
      return;
   }
   TwoLines();

   counter = 0;
   AddLinefeeds(tempstring);
   while(tempstring[counter])
   {
      if ((entry=LetterPos(tempstring[counter]))==-1)
      {
         if (tempstring[counter] != 10)
         {
            command[0] = tempstring[counter];
            command[1] = 0;
         }
         else
         {
            command[0] = '\\';
            command[1] = 'N';
            command[2] =  0;
         }
         printf(SA[1922], command);

         movmem(tempstring+counter+1, tempstring+counter, strlen(tempstring+counter));
         continue;
      }
      else
      if (entry != counter)
      {
         movmem(&menulist[counter], &tempentry, sizeof(struct MenuEntry));
         movmem(&menulist[entry], &menulist[counter], sizeof(struct MenuEntry));
         movmem(&tempentry, &menulist[entry], sizeof(struct MenuEntry));
      }

      counter++;
   }

   UpdateMenu();
   printf(SA[1925]);
}
//-

/// AddMenuEntry
void AddMenuEntry()
{
   long             zflag;
   char             tempstring[10];
   char             helpfile  [80];
   char             filename  [80];
   struct MenuEntry MenuEntry;
   short            count;

   for(;;)
   {
      if (!DLGInput(NULL,tempstring,NULL,2,2,1, SA[1926]))
      {
         printf(SA[1927]);
         return;
      }

      OneLine();
      if (!Stricmp(tempstring, "\\N"))  tempstring[0] = 10;

      if (LetterPos(tempstring[0])!=-1)
         printf(SA[1928], tempstring);
      else
         break;
   }

   MenuEntry.command    = *tempstring;
   MenuEntry.flags      =  0;
   MenuEntry.visibility =  0;

   printf(SA[1929],(80/mh.columns)-6,SA[1930]);

   if (!DLGInput(NULL,MenuEntry.description,NULL,34,34,0, SA[1931]))
   {
      printf(SA[1927]);
      return;
   }

   OneLine();
   printf(SA[1932]);
   printf(SA[1933]);
   printf(SA[1934]);
   printf(SA[1935]);
   printf(SA[1936]);
   printf(SA[1937]);
   printf(SA[1938]);
   printf(SA[1939]);
   MenuEntry.type = iinput(1,7,1, SA[1907]);
   OneLine();

   switch(MenuEntry.type)
   {
      case MENU_EXE:      printf(SA[1940]);
      break;

      case MENU_BATCH:    printf(SA[1941]);
      break;

      case MENU_DLGBATCH: printf(SA[1942]);
      break;

      case MENU_SUB:      printf(SA[1943]);
      break;

      case MENU_STACK:    printf(SA[1944]);
      break;

      case MENU_AREXX:    printf(SA[1945]);
      break;

      case MENU_BUILTIN:  sprintf(filename, "DLGConfig:Menu/funcs/%s.funcs", mh.module);
      ListFuncs(filename);
      printf(SA[1946]);
      break;
   }

   if (MenuEntry.type==MENU_BATCH)
   strcpy(MenuEntry.program,"DLGConfig:Batch/");
   else
   strcpy(MenuEntry.program,"");

   if (MenuEntry.type==MENU_BUILTIN)
   {
      DLGInput(temparray,MenuEntry.program,(char *)-1,21,elementnum,6, SA[1947]);
   }
   else
   DLGInput(NULL,MenuEntry.program,MenuEntry.program,69,69,7, SA[1947]);
   OneLine();

   if (MenuEntry.program[0]=='\0')
   {
      printf(SA[1948]);
      return;
   }

   printf("\n");

   EditEntryFile(MenuEntry.type,MenuEntry.program);

   if (MenuEntry.command==10)
   *MenuEntry.helpfile='\0';
   else
   sprintf(MenuEntry.helpfile,"%s/%c",menuname,MenuEntry.command);

   DLGInput(NULL,MenuEntry.helpfile,MenuEntry.helpfile,16,16,0, SA[1949]);
   OneLine();

   if (MenuEntry.type != MENU_SUB)
   {
      if (MenuEntry.type!=MENU_BUILTIN && MenuEntry.type!=MENU_STACK)
      {
         if (MenuEntry.type!=MENU_AREXX)
         {
            printf("%a5Would you like this command to Chain");
            if (finput(1, SA[1930])) MenuEntry.flags|=MENU_CHAIN;
            OneLine();
         }
         printf(SA[1950]);
         if (finput(0, SA[1930])) MenuEntry.flags|=MENU_CLI;
         OneLine();
      }

      printf(SA[1951]);
      if (finput(0, SA[1930])) MenuEntry.flags|=MENU_ASK;
      OneLine();

      printf(SA[1952]);
      if (finput(1, SA[1930])) MenuEntry.flags|=MENU_BCPEND;
      OneLine();

      printf(SA[1953]);
      if (finput(0, SA[1930])) MenuEntry.visibility|=MENU_HIDDEN;
      OneLine();

      if (!(MenuEntry.flags&MENU_CHAIN) && MenuEntry.type!=MENU_BUILTIN  &&  MenuEntry.type!=MENU_AREXX)
      {
         printf(SA[1954]);
         if (finput(0, SA[1930]))  MenuEntry.flags|=MENU_RETURN;
         OneLine();
      }
   }

   MenuEntry.llev = iinput(1,255,1, SA[1955]);
   OneLine();

   MenuEntry.ulev = iinput(MenuEntry.llev,255,255, SA[1956]);
   OneLine();

   MenuEntry.logvalue=iinput(128,255,0, SA[1957]);
   OneLine();

   DLGInput(NULL,MenuEntry.action,NULL,80,80,0, SA[1958]);
   OneLine();

   MenuEntry.rate   = 0;
   MenuEntry.cost   = 0;
   MenuEntry.maxtime= 0;

   DLGInput(NULL,tempstring,NULL,3,3,0, SA[1959]);
   if (*tempstring=='\0')
   {
      printf(SA[1960]);
      MenuEntry.priority=-127;
   }
   else
   {
      MenuEntry.priority = atoi(tempstring);
      if (MenuEntry.priority>128 || MenuEntry.priority<-126)  MenuEntry.priority=-127;
   }

   OneLine();

   for(count = 0; count < 20; count++)
   MenuEntry.unused[count] = 0;

   zflag = finput(0, SA[1961]);
   TwoLines();
   
   if (zflag)
   {
      sprintf(helpfile,"DLGConfig:Menu/%s.help",MenuEntry.helpfile);
      EditFile(helpfile,&UserDat,&RStruct,Ext);
   }

   if (numentries < MAXENTRY)
   {
      movmem(&MenuEntry, &menulist[numentries], sizeof(struct MenuEntry));
      numentries++;
      UpdateMenu();
   }
}
//-

/// EditMenuEntry
void EditMenuEntry()
{
   char              command;
   char              tempstring[71];
   char              helpfile[80];
   char              filename[80];
   struct MenuEntry *MenuEntry;
   char              number;
   short             entry;

   if (!numentries)  return;
   if (!INSTACK) ListMenuEntries(FALSE);

   do
   {
      printf(SA[1962]);

      if(!DLGInput(NULL,tempstring,NULL,2,2,1, SA[1947]))
      {
         printf(SA[1948]);
         return;
      }

      TwoLines();
      if (!Stricmp(tempstring, "\\N"))
         command = 10;
      else
         command = tempstring[0];

      if ((entry=LetterPos(command))==-1)
         printf(SA[1922], tempstring);
      else
         break;
   }
   while(TRUE);

   MenuEntry = &menulist[entry];

   while(TRUE)
   {
      if (!INSTACK)
      {
         Clr(UserDat.Ansi_Flag);

         if (MenuEntry->command!=10)
         printf(SA[1963],MenuEntry->command);
         else
         printf(SA[1964]);

         printf(SA[1965]);

         switch(MenuEntry->type)
         {
            case MENU_EXE:      printf(SA[1966]); break;
            case MENU_BATCH:    printf(SA[1967]); break;
            case MENU_SUB:      printf(SA[1968]); break;
            case MENU_DLGBATCH: printf(SA[1969]); break;
            case MENU_STACK:    printf(SA[1970]); break;
            case MENU_AREXX:    printf(SA[1971]); break;
            case MENU_BUILTIN:  printf(SA[1972]); break;
         }

         printf(SA[1973],MenuEntry->program);

         if (MenuEntry->type==MENU_BATCH     ||
         MenuEntry->type==MENU_DLGBATCH  ||
         MenuEntry->type==MENU_DLGBATCH  ||
         MenuEntry->type==MENU_AREXX)
         {
            printf(SA[1974]);
         }

         printf(SA[1975],MenuEntry->description);
         printf(SA[1976]);

         switch(MenuEntry->type)
         {
            case MENU_EXE:      printf(SA[1977]); break;
            case MENU_BATCH:    printf(SA[1978]); break;
            case MENU_SUB:      printf(SA[1979]); break;
            case MENU_DLGBATCH: printf(SA[1980]); break;
            case MENU_STACK:    printf(SA[1981]); break;
            case MENU_AREXX:    printf(SA[1982]); break;
            case MENU_BUILTIN:  printf(SA[1983]); break;
         }

         printf(SA[1984],  MenuEntry->helpfile);
         printf(SA[1985],  MenuEntry->llev);
         printf(SA[1986],  MenuEntry->ulev);
         printf(SA[1987], (MenuEntry->visibility&MENU_HIDDEN)?SA[1988]:SA[1989]);

         if (MenuEntry->type==MENU_EXE       ||
         MenuEntry->type==MENU_DLGBATCH  ||
         MenuEntry->type==MENU_BATCH)
         {
            printf(SA[1990], (MenuEntry->flags&MENU_CHAIN)?SA[1991]:SA[1992]);
         }

         printf(SA[1993], (MenuEntry->flags&MENU_ASK)?SA[1988]:SA[1989]);
         printf(SA[1994], (MenuEntry->flags&MENU_BCPEND)?SA[1988]:SA[1989]);

         if ((MenuEntry->type != MENU_SUB)&&(MenuEntry->type!=MENU_BUILTIN))
         {
            printf(SA[1995], (MenuEntry->flags&MENU_CLI)?SA[1988]:SA[1989]);

            if (!(MenuEntry->flags&MENU_CHAIN) && MenuEntry->type!=MENU_AREXX)
            printf(SA[1996], (MenuEntry->flags&MENU_RETURN)?SA[1988]:SA[1989]);
         }

         printf(SA[1997]);

         if (MenuEntry->logvalue)
         printf(SA[1998],MenuEntry->logvalue);
         else
         printf(SA[1999]);

         printf(SA[2000],MenuEntry->action);

         /*  Cost accounting
         printf("%a2[%a717%a2] Cost per minute:          %a7%d\n",MenuEntry->rate);
         printf("%a2[%a718%a2] Base cost:                %a7%d\n",MenuEntry->cost);
         printf("%a2[%a719%a2] Maximum time:             %a7");
       
         if (MenuEntry->maxtime)
            printf("%d\n",MenuEntry->maxtime);
         else
            printf("None\n");*/

         if (MenuEntry->priority==-127)
         printf(SA[2001]);
         else
         printf(SA[2002],MenuEntry->priority);

         printf(SA[2003]);
      }

      number = iinput(1,21,0, SA[1895]);
      TwoLines();

      switch(number)
      {
         ///      Letter
         case 1:
         for(;;)
         {
            if (!DLGInput(NULL,tempstring,NULL,2,255,1, SA[1926]))
            {
               printf(SA[1927]);
               return;
            }

            TwoLines();

            if (!Stricmp(tempstring, "\\N"))  tempstring[0] = 10;

            if (LetterPos(tempstring[0])!=-1)
            {
               printf(SA[1928],tempstring[0]);
            }
            else
            {
               MenuEntry->command=*tempstring;
               break;
            }
         }

         break;
         //-

         ///      Sub-menu/executable/batch/whatever
         case 2:
         if (MenuEntry->type==MENU_BUILTIN)
         {
            sprintf(filename, "DLGConfig:Menu/funcs/%s.funcs", mh.module);

            if (!ListFuncs(filename)) break;
            printf(SA[2004]);

            DLGInput(temparray,tempstring,(char *)-1,21,elementnum,6,"");
         }
         else
         {
            printf(SA[2004]);
            DLGInput(NULL,tempstring,MenuEntry->program,70,70,7,"");
         }

         if (*tempstring) strcpy(MenuEntry->program,tempstring);
         TwoLines();

         break;
         //-

         ///      Edit file (batch,etc)
         case 3:
         EditEntryFile(MenuEntry->type,MenuEntry->program);
         break;
         //-

         ///      Description
         case 4:
         printf(SA[1929], (80/mh.columns)-6,SA[1930]);
         DLGInput(NULL,MenuEntry->description,MenuEntry->description,34,34,0, SA[1931]);
         TwoLines();
         break;
         //-

         ///      Type
         case 5:
         printf(SA[1932]);
         printf(SA[1933]);
         printf(SA[1934]);
         printf(SA[1935]);
         printf(SA[1936]);
         printf(SA[1937]);
         printf(SA[1938]);
         printf(SA[1939]);

         MenuEntry->type = iinput(1,7,MenuEntry->type, SA[1907]);
         TwoLines();

         if (MenuEntry->type==MENU_BUILTIN)  MenuEntry->flags &= ~MENU_CLI;
         if (MenuEntry->type==MENU_DLGBATCH) MenuEntry->flags &= ~MENU_CHAIN;
         break;
         //-

         ///      Help File
         case 6:
         DLGInput(NULL,MenuEntry->helpfile,MenuEntry->helpfile,16,16,0, SA[1949]);
         TwoLines();
         break;
         //-

         ///      Lower Level
         case 7:
         MenuEntry->llev = iinput(1,MenuEntry->ulev,MenuEntry->llev, SA[2005]);
         TwoLines();
         break;
         //-

         ///      Upper Level
         case 8:
         MenuEntry->ulev = iinput(MenuEntry->llev,255,MenuEntry->ulev, SA[2006]);
         TwoLines();
         break;
         //-

         ///      Hidden/not hidden
         case 9:
         MenuEntry->visibility=(MenuEntry->visibility&MENU_HIDDEN)?MenuEntry->flags&~MENU_HIDDEN:MenuEntry->visibility|MENU_HIDDEN;
         break;
         //-

         ///      Load Type
         case 10:
         MenuEntry->flags=(MenuEntry->flags&MENU_CHAIN)?MenuEntry->flags&~MENU_CHAIN:MenuEntry->flags|MENU_CHAIN;
         break;
         //-

         ///      Ask User if Sure
         case 11:
         MenuEntry->flags=(MenuEntry->flags&MENU_ASK)?MenuEntry->flags&~MENU_ASK:MenuEntry->flags|MENU_ASK;
         break;
         //-

         ///      Pend Messages
         case 12:
         MenuEntry->flags=(MenuEntry->flags&MENU_BCPEND)?MenuEntry->flags&~MENU_BCPEND:MenuEntry->flags|MENU_BCPEND;
         break;
         //-

         ///      CLI Mode
         case 13:
         MenuEntry->flags=(MenuEntry->flags&MENU_CLI)?MenuEntry->flags&~MENU_CLI:MenuEntry->flags|MENU_CLI;
         break;
         //-

         ///      Pause on completion
         case 14:
         MenuEntry->flags=(MenuEntry->flags&MENU_RETURN)?MenuEntry->flags&~MENU_RETURN:MenuEntry->flags|MENU_RETURN;
         break;
         //-

         ///      Log Value
         case 15:
         {
            BOOL match = FALSE;
            BPTR fh;
            struct Log *clog;
            UBYTE tempval = 0;
            ULONG lsize = 0;

            tempval=iinput(128,255,0, SA[1957]);

            if(FileSize("DLGConfig:Port/Customlog.bbs",&lsize) == -1)
            {
               //                  AFPrintf(&UserDat,Output(),"No custom log entries defined!\n");
               AFPrintf(&UserDat,Output(),SA[2042]);
               break;
            }

            if(lsize < sizeof(struct Log))
            {
               //                  AFPrintf(&UserDat,Output(),"No custom log entries defined!\n");
               AFPrintf(&UserDat,Output(),SA[2042]);
               break;
            }

            clog = calloc(1,sizeof(struct Log));

            fh = Open("DLGConfig:Port/Customlog.bbs",MODE_OLDFILE);

            if(!fh || !clog)
            {
               //                  AFPrintf(&UserDat,Output(),"Internal allocation error!\n");
               AFPrintf(&UserDat,Output(),SA[2043]);
               if(fh) Close(fh);
               if(clog) free(clog);
               break;
            }

            while(Read(fh,clog,sizeof(struct Log)))
            {
               if(clog->number == tempval)
               {
                  match = TRUE;
                  break;
               }
            }

            if(tempval == 0) match = TRUE;

            if(match)
            {
               MenuEntry->logvalue = tempval;
            }
            else
            {
               //                  AFPrintf(&UserDat,Output(),"\n\n%a3Log entry [%a1%d%a3] has not been defined.%ao\n\n",tempval);
               AFPrintf(&UserDat,Output(),SA[2044],tempval);
               Pause();
            }

            if(fh) Close(fh);
            if(clog) free(clog);

            TwoLines();
         }
         break;
         //-

         case 16: DLGInput(NULL,MenuEntry->action,MenuEntry->action,80,80,0, SA[1958]);
         TwoLines();
         break;

         /*      case 17: MenuEntry->rate=iinput("Cost/min to use entry => ",0,30000,MenuEntry->rate);
                       TwoLines();
                       break;
       
              case 18: MenuEntry->cost=iinput("Base cost to use entry => ",1,30000,MenuEntry->cost);
                       TwoLines();
                       break;
       
              case 19: MenuEntry->maxtime=iinput("Maximum time allowed [0=no limit] => ",1,30000,MenuEntry->maxtime);
                       TwoLines();
                       break;
      */

         case 17: DLGInput(NULL,tempstring,NULL,3,3,0, SA[1959]);
         if (*tempstring==0)
         {
            printf(SA[1960]);
            MenuEntry->priority=-127;
         }
         else
         {
            MenuEntry->priority = atoi(tempstring);
            if (MenuEntry->priority>128 || MenuEntry->priority<-126)
            MenuEntry->priority=-127;
         }
         TwoLines();
         break;

         case 18: sprintf(helpfile,"DLGConfig:Menu/%s.help",MenuEntry->helpfile);
         EditFile(helpfile,&UserDat,&RStruct,Ext);
         break;

         case 0:  UpdateMenu();
         return;
         break;
      }
   }
}
//-

/// UpdateMenu
void UpdateMenu()
{
   WriteMenu();
   PurgeMenu(Ext, menuname);
}
//-

/// WriteMenu
BOOL WriteMenu()
{
   char filename[128];

   sprintf(filename, "DLGConfig:Menu/%s.menun", menuname);
   UnderScore(filename);
   DeleteFile(filename);

   if ((mfd = open(filename, O_RDWR+O_CREAT))==EOF)
   {
      printf(SA[2007]);
      return(FALSE);
   }

   write(mfd, &mh, sizeof(struct MenuHeader));
   if (numentries)
   write(mfd, &menulist[0], numentries*sizeof(struct MenuEntry));
   close(mfd);
   mfd = EOF;

   return(TRUE);
}
//-

/// EditSets
void EditSets()
{
   char inp[2];

   while(TRUE)
   {
      switch(UserDat.Help_Level)
      {
         case 0: printf(SA[2008]);
         Draw_Line(UserDat.Screen_Width);
         menu(SetMenu,6,0);
         printf(SA[1885]);
         Draw_Line(UserDat.Screen_Width);
         printf("\n");
         break;

         case 1: menu(SetMenu,6,1);
         TwoLines();
         break;

         case 2: break;
      }

      inp[0] = 0;
      DLGInput(NULL,inp,NULL,1,127,1, SA[2009]);
      Clr(UserDat.Ansi_Flag);

      switch(inp[0])
      {
         case 'D': DelSet();
         break;

         case 'E': EditSet();
         break;

         case 'L': ListMenuSets(255);
         break;

         case 'A': AddSet();
         break;

         case 'M': return;
         break;

         case '?': if (UserDat.Help_Level==0) break;
         printf(SA[2008]);
         Draw_Line(UserDat.Screen_Width);
         menu(SetMenu,6,0);
         printf(SA[1885]);
         Draw_Line(UserDat.Screen_Width);
         printf("\n");
         break;
      }
   }
}
//-

/// AddSet
BOOL AddSet()
{
   long           zflag;
   struct MenuSet set;

   set.number=iinput(1,127,0, SA[2010]);
   TwoLines();

   if (!set.number)  return(aborted(""));

   zflag=DLGInput(NULL,set.name,NULL,59,59,0, SA[2011]);
   TwoLines();

   ListLangs();
   DLGInput(NULL,set.language,NULL,21,21,0, SA[2012]);
   TwoLines();

   set.level=iinput(1,255,0, SA[2013]);
   TwoLines();

   if (!zflag)  return(aborted(""));

   if (!finput(1, SA[2014]))
   {
      TwoLines();
      return(aborted(""));
   }

   printf(SA[2015]);

   if (AddStruct("DLGConfig:Misc/MenuSets.bbs",(char *)&set,sizeof(set),1)==-1)
   printf(SA[2016]);
   else
   printf(SA[2017]);

   return(TRUE);
}
//-

/// DelSet
BOOL DelSet()
{
   struct MenuSet set;

   set.number = iinput(1,127,0, SA[2018]);
   TwoLines();

   if (!set.number)  return(aborted(""));

   if (finput(1, SA[2019]))
   {
      printf(SA[2020]);

      if (DeleteStruct("DLGConfig:Misc/MenuSets.bbs",(char *)&set,sizeof(set),1))
      printf(SA[2021]);
      else
      printf(SA[2022]);
   }

   TwoLines();
   return(TRUE);
}
//-

/// EditSet
BOOL EditSet()
{
   struct MenuSet set;

   ListMenuSets(255);
   set.number = iinput(1,127,0, SA[2023]);
   TwoLines();

   if (!set.number)  return(aborted(""));

   if (GetStruct("DLGConfig:Misc/MenuSets.bbs",(char *)&set,sizeof(set),1)==-1)
   return(aborted(SA[2024]));

   while(TRUE)
   {
      printf(SA[2025],set.number);
      printf(SA[2026],set.name);
      printf(SA[2027],set.language);
      printf(SA[2028],set.level);

      switch(iinput(1,3,0, SA[1895]))
      {
         case 1:
         DLGInput(NULL,set.name,set.name,59,59,0, SA[2029]);
         TwoLines();
         break;

         case 2: TwoLines();
         ListLangs();
         DLGInput(NULL,set.language,NULL,21,21,0, SA[2012]);
         TwoLines();
         break;

         case 3:
         set.level=iinput(1,255,0, SA[2030]);
         TwoLines();
         break;

         case 0: TwoLines();
         AddStruct("DLGConfig:Misc/MenuSets.bbs",(char *)&set,sizeof(set),1);
         return(TRUE);
         break;
      }
   }

   return(TRUE);
}
//-

/// ListLangs
void ListLangs()
{
   struct SearchCookie *sc;
   char                *filename;

   printf(SA[2031]);

   sc = SearchStart("DLGConfig:Languages","*.lang");
   while(filename = SearchNext(sc))
   {
      filename[strlen(filename) - 5] = 0;
      printf("%s\n", filename);
   }
   SearchEnd(sc);

   printf(SA[2032]);
}
//-

/// ListMenus
void ListMenus(BOOL new)
{
   char  *filename;
   UBYTE  flippybindle =  0;
   struct SearchCookie *sc;

   if (temparray)  free(temparray);
   temparray  = NULL;
   elementnum = 0;

   if (!INSTACK)  Draw_Line(76);

   if (new)
   if (!INSTACK)
   {
      printf(SA[2033]);
      printf(SA[2034], "NEW");
      printf(SA[1885]);
      elementnum = BuildArray(&temparray, "NEW", 14, elementnum, 30);
      flippybindle++;
   }

   sc = SearchStart("DlgConfig:Menu", "*.menun");
   while(filename = SearchNext(sc))
   {
      filename[strlen(filename) - 6] = 0;
      if (!INSTACK)  printf(SA[2034], filename);

      flippybindle++;
      if (flippybindle == 5)
      {
         printf("\n");
         flippybindle = 0;
      }

      elementnum = BuildArray(&temparray, filename, 14, elementnum, 30);
   }
   SearchEnd(sc);
   if (flippybindle)  printf("\n");

   if (!INSTACK)
   {
      Draw_Line(76); 
      printf("\n");
   }

   BuildArray(&temparray, NULL, 14, elementnum, 30);
}
//-

/// AddLinefeeds
void AddLinefeeds(char *str)
{
   while(*str)
   {
      if (!Strnicmp(str, "\\N", 2))
      {
         *str = 10;
         movmem(str+2, str+1, strlen(str+1));
      }

      str++;
   }
}
//-

/// DelLineFeeds
void DelLinefeeds(char *str)
{
   while(*str)
   {
      if (*str == 10)
      {
         movmem(str+1, str+2, strlen(str));
         *str++ = 92;
         *str   = 'n';
      }

      str++;
   }
}
//-

/// AddDirectory
void AddDirectory(char *name)
{
   BPTR lock;

   if (lock=CreateDir(name))  UnLock(lock);
}
//-

/// ListModules
void ListModules()
{
   char                *filename;
   UBYTE                flippybindle = 0;
   struct SearchCookie *sc;

   if (temparray)  free(temparray);
   temparray  = NULL;
   elementnum =  0;

   if (!INSTACK)  Draw_Line(68);

   sc = SearchStart("DLGConfig:Menu/funcs", "*.funcs");
   while(filename = SearchNext(sc))
   {
      if (!Strnicmp(filename, "global.", 7)) continue;

      filename[strlen(filename)-6] = 0;
      if (!INSTACK)  printf(SA[2035], filename);

      flippybindle++;
      if (flippybindle == 4)
      {
         printf("\n");
         flippybindle = 0;
      }

      elementnum = BuildArray(&temparray,filename,16,elementnum, 30);
   }
   SearchEnd(sc);

   BuildArray(&temparray,NULL,16,elementnum,30);
   if (flippybindle)  printf("\n");

   if (!INSTACK)
   {
      Draw_Line(68); 
      printf("\n");
   }
}
//-

/// ListFuncs
BOOL ListFuncs(char *filename)
{
   FILE *fp;
   UBYTE flippybindle = 0;
   char  tempname[80];

   if (temparray)  free(temparray);
   temparray  = NULL;
   elementnum =  0;

   if (!INSTACK)  Draw_Line(66);

   if (!(fp=fopen("DLGConfig:Menu/Funcs/global.funcs","r"))) return(FALSE);
   while(fgets(tempname, 21, fp))
   {
      tempname[strlen(tempname)-1] = 0;
      if (!INSTACK)  printf(SA[2036], tempname);

      flippybindle++;
      if (flippybindle==3)
      {
         printf("\n");
         flippybindle = 0;
      }

      elementnum = BuildArray(&temparray,tempname,21,elementnum,30);
   }
   fclose(fp);

   if (fp = fopen(filename,"r"))
   {
      fgets(tempname,21,fp);

      while(fgets(tempname,21,fp))
      {
         tempname[strlen(tempname)-1] = 0;
         if (!INSTACK)  printf(SA[2036], tempname);

         flippybindle++;
         if (flippybindle==3)
         {
            printf("\n");
            flippybindle=0;
         }

         elementnum = BuildArray(&temparray,tempname,21,elementnum,30);
      }

      fclose(fp);
   }

   BuildArray(&temparray,NULL,21,elementnum,30);
   if (flippybindle)  printf("\n");

   if (!INSTACK)
   {
      Draw_Line(66); 
      printf("\n");
   }

   return(TRUE);
}
//-

/// EditEntryFile
void EditEntryFile(UBYTE type, char *filename)
{
   char editname[256];

   if (type==MENU_BATCH || type==MENU_DLGBATCH || type==MENU_DLGBATCH  || type==MENU_AREXX)
   {
      strcpy(editname, filename);
      EditFile(editname, &UserDat, &RStruct, Ext);
   }
}
//-

/// DeleteMenu
BOOL DeleteMenu()
{
   long zflag;
   char filename[80];

   /* Get menuname from user using completion mode */
   ListMenus(FALSE);
   DLGInput(temparray,menuname,(char *)-1,14,elementnum,6, SA[2037]);
   TwoLines();
   if (!menuname[0])
   {
      printf(SA[1888]);
      return(FALSE);
   }

   /* Ask user if he is sure */
   zflag = finput(0,SA[2019]);
   printf("\n\n");
   if (!zflag) return(FALSE);

   /* Calculate actual filename and delete menu file */
   sprintf(filename, "DLGConfig:Menu/%s.menun", menuname);
   UnderScore(filename);

   if (!DeleteFile(filename))
   printf(SA[2038], filename);
   else
   printf(SA[2039]);

   /* See if he wants to delete the help file directory as well */
   zflag = finput(0, SA[2040]);
   printf("\n\n");

   /* If yes, calculate helpfile directory name and call the low level DelDir routine to delete it */
   if (zflag)
   {
      sprintf(filename, "DLGConfig:Menu/%s", menuname);
      UnderScore(filename);
      DelDir(filename, &UserDat);
   }

   PurgeMenu(Ext, menuname);
   strcpy(menuname, "NONE");
   strcpy(mh.name,  "Undefined");
   menuopen = FALSE;

   return(TRUE);
}
//-

/// aborted
BOOL aborted(char *string)
{
   printf(SA[2041], string);
   return(FALSE);
}
//-

/// _CXBRK
void _CXBRK(void)
{
   WriteRam(&RStruct,Ext);

   if (mfd != EOF)  close(mfd);
   if (temparray)   free(temparray);

   DeleteFile("t:menu.undo1");
   DeleteFile("t:menu.undo2");

   if (!Overlay)  ChainProgram("DLG:Menu", Ext);
   CloseLibrary(DLGBase);

   exit(0);
}
//-

