#include <stdio.h>

#include <X11/Xlib.h>
#include <X11/StringDefs.h> /* string definitions for things like XtNwidth */
#include <X11/Xresource.h>
#include <X11/Intrinsic.h>  /* include all the intrinsic headers */
                            /* includes XToolkit definitions     */
#include <X11/Xatom.h>
#include <X11/Xutil.h>
#include <X11/Composite.h>  /* facilitate creation of composite widgets */
#include <X11/Shell.h>      /* include shell widget class header files  */
#include <X11/Form.h>       /* not only includes the Form widget defs   */
                            /* but also the constraint defs             */
#include <X11/Command.h>    /* include command widget class header file */
#include <X11/Box.h>        /* include box widget class header files    */
#include <X11/Label.h>      /* include label widget class header files  */
#include <X11/AsciiText.h>  /* include for asciiStringWidgetClass widgets */
#include <X11/Scroll.h>     /* include scrollbar widget class header file */

#ifdef X11_R2
/* This should be defined in <X11/AsciiText.h>, but R2 has dumb bugs */
typedef struct {
  int firstPos;
  int length;
  char *ptr;
} XtTextBlock;
#endif

#include "memory.h"
#include "profile.h"
#include "end.h"
#include "altime.h"
#include "al.h"
#include "data.h"
#include "ruleset.h"
#include "RSreg.h"
#include "rule.h"
#include "sysdep.h"
#include "foldert.h"
#include "ruleprint.h"

#include "sm_up_arrow_iconP.h"
#include "sm_down_arrow_iconP.h"

#define AlRse_debug(a) 
#define AlRse_debug2(a)  

/* Dummy out this function for now */
#define AlRse_rule_string(the_rseditor, rule_no)   "Place Rule String Here"

/*
#ifndef BUTTON_BM
#define BUTTON_BM
#define button_width 18
#define button_height 18
static char button_bits[] = {
   0xf8, 0x1f, 0x00, 0x04, 0x20, 0x00, 0x02, 0x40, 0x00, 0xf9, 0x9f, 0x00,
   0xf9, 0x9f, 0x01, 0x01, 0x80, 0x03, 0x01, 0x80, 0x03, 0xf9, 0x9f, 0x03,
   0xf9, 0x9f, 0x03, 0x01, 0x80, 0x03, 0x01, 0x80, 0x03, 0xf9, 0x9f, 0x03,
   0xf9, 0x9f, 0x03, 0x02, 0xc0, 0x03, 0x04, 0xe0, 0x03, 0xf8, 0xff, 0x01,
   0xf0, 0xff, 0x00, 0xe0, 0x7f, 0x00};
#endif
*/

#ifndef DARKGREY_BM
#define DARKGREY_BM
#define darkgrey_width 16
#define darkgrey_height 16
static char darkgrey_bits[] = 
 { 0xaa, 0xaa, 0x55, 0x55, 0xaa, 0xaa, 0x55, 0x55,
   0xaa, 0xaa, 0x55, 0x55, 0xaa, 0xaa, 0x55, 0x55,
   0xaa, 0xaa, 0x55, 0x55, 0xaa, 0xaa, 0x55, 0x55,
   0xaa, 0xaa, 0x55, 0x55, 0xaa, 0xaa, 0x55, 0x55
 };
#endif

/* The following pixmap is to get around a basic design bug in the core */
/* widget class (a widget can set a backgroundPixmap, but can't unset   */
/* a backgroundPixmap to use the background color again).               */
/* -------------------------------------------------------------------- */
#ifndef WHITE_BM
#define WHITE_BM
#define white_width 16
#define white_height 16
static char white_bits[] = 
 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
 };
#endif

#define USE_STR "Usage: rsedit [-h[elp]]\nUsage: rsedit [-new] ruleset\n"

#define RULE_BUF_LEN  1000

   static Arg arg_list[40];

   XFontStruct *timesRoman12, *timesBold12;  /* font structures needed   */
   XFontStruct *timesRoman14, *timesBold14;  /* font structures needed   */
   XFontStruct *timesBold18;                 /* font structures needed   */
   XFontStruct *fixedFont;                   /* font structures needed   */

#define AlRse_Comment_Out(a)   /* comment out a section of code */

/*********************************************************/
/*     Set up indirect way of referencing fonts          */
/*     to make future modifications easy.                */

#define FIXEDFONT      0
#define TIMESROMAN12   1
#define TIMESROMAN14   2
#define TIMESBOLD12    3
#define TIMESBOLD14    4
#define TIMESBOLD18    5

#define AlRse_font(font) \
  ((font == TIMESROMAN12) ? timesRoman12 : \
   ((font == TIMESROMAN14) ? timesRoman14 : \
    ((font == TIMESBOLD12) ? timesBold12 : \
     ((font == TIMESBOLD14) ? timesBold14 : \
      ((font == TIMESBOLD18) ? timesBold18 : \
       fixedFont)))))

/*********************************************************/
/*             Ditto for Justifications                  */

#define LEFT   0
#define CENTER  1
#define RIGHT  2

#define AlRse_justify(justification) \
  ((justification == CENTER) ? XtJustifyCenter : \
   ((justification == LEFT) ? XtJustifyLeft : \
    ((justification == RIGHT) ? XtJustifyRight : \
     XtJustifyCenter)))

/*********************************************************/
#define N_VISIBLE_RULES  6
#define MAX_NUM_LENGTH   9

struct _AlRse_struct
 { 
   /* top-most instance variables */
   /* --------------------------- */
   Widget    shell_widget;
   Widget    errbox;              /* popup widget for error messages */
   Widget    errlabel;            /* label holding error message for errbox */
   XtIntervalId errbox_intervalid; /* holds interval id of popped up errbox */
   char      *ruleset_name;
/*   char      path[256]; */
   AlRuleSet the_ruleset;
   Darray    AlRSEdarray;         /* holds all the rules in the rule set */
   int       d_len;               /* length of Darray, AlRSEdarray */
   int       current_rule_number; /* currently selected rule (-1 if not sel) */
   int       current_rulebox_number; /* currently selected rulebox */
                                     /* (-1 if none are selected) */
   int       top_rule;            /* top rule visible in the rule area */
   int       n_rules_visible;     /* number of rules visible in rule area */
   VOIDP_FUNCPTR exit_function;   /* to call when exiting the RuleSetEditor */
                                  /* function should expect an AlRSEditor,  */
                                  /* and an integer error code as arguments */

   /* general X info */
   /* -------------- */
   Display *the_display;      /* the display for this rule set editor window */
   int the_screen;            /* the screen for this rule set editor window */

   /* Arrays for Rule Set Editor's visible rules. */
   /* ------------------------------------------- */
   Widget rulebox_form[N_VISIBLE_RULES];
   int    rule_number[N_VISIBLE_RULES];           /* rule# in integer format */
   char   rule_num_label[N_VISIBLE_RULES][MAX_NUM_LENGTH + 1]; 
                               /* rule# in char format =  rule_num_label[][] */
   Widget num_rule_widget[N_VISIBLE_RULES];   /*  widget that displays rule# */
   char   *text_str[N_VISIBLE_RULES];         /* text string format of  rule */
   Widget text_str_widget[N_VISIBLE_RULES];   /* holds text format of a rule */
   Widget button_rule_widget[N_VISIBLE_RULES];   /* button w/ selected state */
   struct rule_call_struct *parm_struct[N_VISIBLE_RULES];   /* closure parms */
                                         /* for button_rule_widget callbacks */

/*   char   *rule_label[N_VISIBLE_RULES];      now= text_str */
/*   Widget label_rule_widget[N_VISIBLE_RULES]; now= text_str_widget */

 };

typedef struct _AlRse_struct AlRSEditor;

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

struct rule_call_struct
 {
   AlRSEditor *the_rseditor;
   int        rulebox_number;
 };

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

void AlRse_set_str(text_str, init_str)
     char *text_str, *init_str;
 { int j, len;

   len = strlen(init_str);
   len = (len < RULE_BUF_LEN) ? len : RULE_BUF_LEN;
   for(j = 0; j < len; j++)
     text_str[j] = init_str[j];

   for(; j < RULE_BUF_LEN; j++)
     text_str[j] = ' ';

   text_str[RULE_BUF_LEN] = '\0';
 };

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

void AlRse_unselect(the_rseditor)
     AlRSEditor *the_rseditor;
 { 
   static Pixmap white_pixmap;

   if (white_pixmap == NULL)
     { white_pixmap =
	 XCreatePixmapFromBitmapData(the_rseditor->the_display,
                      DefaultRootWindow(the_rseditor->the_display),
                      white_bits,
                      white_width, white_height,
                      BlackPixel(the_rseditor->the_display, 
				 the_rseditor->the_screen),
                      WhitePixel(the_rseditor->the_display,
				 the_rseditor->the_screen),
                      DefaultDepth(the_rseditor->the_display, 
				   the_rseditor->the_screen));
     };

   AlRse_debug(printf(
        " In AlRse_unselect: the_rseditor->current_rule_number = %d\n", 
		      the_rseditor->current_rule_number));

   the_rseditor->current_rule_number = -1;

   /* nothing is selected yet, can't unselect, so just return */
   /* ------------------------------------------------------- */
   if (the_rseditor->current_rulebox_number == -1)
     return;

   /* reset the label on the rule's button */
   /* ------------------------------------ */
   XtSetArg(arg_list[0], XtNlabel, (caddr_t) "Select");
   XtSetArg(arg_list[1], NULL, (caddr_t) NULL);
   XtSetValues(
       the_rseditor->button_rule_widget[the_rseditor->current_rulebox_number],
       arg_list, 1);

   /* reset the background of the rulebox's form */
   /* ------------------------------------------ */
   XtSetArg(arg_list[0], XtNbackgroundPixmap, (caddr_t) white_pixmap);
   XtSetArg(arg_list[1], NULL, (caddr_t) NULL);
   XtSetValues(
	      the_rseditor->rulebox_form[the_rseditor->current_rulebox_number],
	      arg_list, 1);

   the_rseditor->current_rulebox_number = -1;
   the_rseditor->current_rule_number = -1;
 };

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

void AlRse_select(the_rseditor, rulebox_number)
     AlRSEditor *the_rseditor;
     int rulebox_number;
 { int unselect;                   /* flag if rule is being unselected */
   static Pixmap darkgrey_pixmap;

   AlRse_debug(printf(
" Entering AlRse_select:  rulebox_number= %d,\
 the_rseditor->current_rule_number = %d\n", 
		      rulebox_number, the_rseditor->current_rule_number));

   unselect = ((the_rseditor->rule_number[rulebox_number]
                  == the_rseditor->current_rule_number)
                && (the_rseditor->current_rule_number != -1))
              || ((the_rseditor->current_rule_number == -2)
		  && (the_rseditor->current_rulebox_number == rulebox_number));

   AlRse_unselect(the_rseditor);

   AlRse_debug(printf(
        " After AlRse_unselect: the_rseditor->current_rule_number = %d\n", 
		      the_rseditor->current_rule_number));

   if (darkgrey_pixmap == NULL)
     { darkgrey_pixmap =
	 XCreatePixmapFromBitmapData(the_rseditor->the_display,
                      DefaultRootWindow(the_rseditor->the_display),
                      darkgrey_bits,
                      darkgrey_width, darkgrey_height,
                      BlackPixel(the_rseditor->the_display, 
				 the_rseditor->the_screen),
                      WhitePixel(the_rseditor->the_display,
				 the_rseditor->the_screen),
                      DefaultDepth(the_rseditor->the_display, 
				   the_rseditor->the_screen));
     };

   if (!unselect)
     { 
       if ((rulebox_number >= 0)
	   && (rulebox_number < the_rseditor->n_rules_visible))
	 {
	   /* reset the background of the rulebox's form */
	   /* ------------------------------------------ */
	   the_rseditor->current_rulebox_number =  rulebox_number;
           if (the_rseditor->rule_number[rulebox_number] < 0)
	     { the_rseditor->current_rule_number = -2;
	     }
           else
             the_rseditor->current_rule_number = 
	                           the_rseditor->rule_number[rulebox_number];
	   
	   XtSetArg(arg_list[0], XtNbackgroundPixmap, darkgrey_pixmap);
	   XtSetArg(arg_list[1], NULL, (caddr_t) NULL);
	   XtSetValues(
	      the_rseditor->rulebox_form[the_rseditor->current_rulebox_number],
	      arg_list, 1);
	   
	   /* set the label on the rule's button */
	   /* ---------------------------------- */
	   XtSetArg(arg_list[0], XtNlabel, (caddr_t) "Unselect");
	   XtSetArg(arg_list[1], NULL, (caddr_t) NULL);
	   XtSetValues(
		   the_rseditor->button_rule_widget[rulebox_number],
		   arg_list, 1);
	 }
       else
	 XBell(the_rseditor->the_display, 1);  /* beep console at low volume */
     };

   AlRse_debug(printf(
        " Exiting AlRse_select: the_rseditor->current_rule_number = %d\n", 
		      the_rseditor->current_rule_number));

 };

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

struct rule_call_struct *AlRse_make_parms(the_rseditor, rulebox_number)
     AlRSEditor *the_rseditor;
     int rulebox_number;
 { struct rule_call_struct *parms;

   parms = (struct rule_call_struct *)
     Memory_allocate((long) sizeof(struct rule_call_struct));
   parms->the_rseditor = the_rseditor;
   parms->rulebox_number = rulebox_number;

   return(parms);
 };

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

void AlRse_exit_function(the_rseditor, err_code)
     AlRSEditor *the_rseditor;
     int err_code;
 {
   AlRSreg_save(the_rseditor->ruleset_name);
   Al_cleanup();
   exit(err_code);
 };

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

void AlRse_popup(the_rseditor)
   AlRSEditor *the_rseditor;
 {
   XtPopup(the_rseditor->shell_widget, XtGrabNonexclusive);

 };       /* end of AlRse_popup()  */

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

void AlRse_popdown(the_rseditor)
   AlRSEditor *the_rseditor;
 {
   XtPopdown(the_rseditor->shell_widget, XtGrabNonexclusive);

 };       /* end of AlRse_popdown()  */

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

void AlRse_loadfonts(prog_name, the_display, the_screen)
     char *prog_name;
     Display *the_display;
     int the_screen;
 {
   /* Load in necessary fonts */
   /* ----------------------- */
   fixedFont = XLoadQueryFont(the_display, "fixed"); /* default */
   if ((timesRoman12 = XLoadQueryFont(the_display,
	  "-*-times-medium-r-*-*-*-120-*-*-p-*")) == NULL)
     { if ((timesRoman12 = XLoadQueryFont(the_display, "times-roman12"))
           == NULL)  /* may be old an R2 server running */
         timesRoman12 = fixedFont; /* use default */
     };
   if ((timesBold12 = XLoadQueryFont(the_display,
	  "-*-times-bold-r-*-*-*-120-*-*-p-*")) == NULL)
     { if ((timesBold12 = XLoadQueryFont(the_display, "times-Bold12"))
           == NULL)  /* may be old an R2 server running */
         timesBold12 = fixedFont; /* use default */
     };
   if ((timesRoman14 = XLoadQueryFont(the_display,
	  "-*-times-medium-r-*-*-*-140-*-*-p-*")) == NULL)
     { if ((timesRoman14 = XLoadQueryFont(the_display, "times-roman14"))
           == NULL)  /* may be old an R2 server running */
         timesRoman14 = timesRoman12; /* use closest font */
           fprintf(stderr, "%s: Couldn't find \"times-roman14\" font.\n",
		   prog_name);
     };
   if ((timesBold14 = XLoadQueryFont(the_display,
	  "-*-times-bold-r-*-*-*-140-*-*-p-*")) == NULL)
     { if ((timesBold14 = XLoadQueryFont(the_display, "times-Bold14"))
           == NULL)  /* may be old an R2 server running */
         timesBold14 = timesBold12; /* use closest */
           fprintf(stderr, "%s: Couldn't find \"times-bold14\" font.\n",
		   prog_name);
     };
   if ((timesBold18 = XLoadQueryFont(the_display,
	  "-*-times-bold-r-*-*-*-180-*-*-p-*")) == NULL)
     { if ((timesBold18 = XLoadQueryFont(the_display, "times-Bold18"))
           == NULL)  /* may be old an R2 server running */
         timesBold18 = timesBold14; /* use closest */
           fprintf(stderr, "%s: Couldn't find \"times-bold18\" font.\n",
		   prog_name);
     };

 };        /* end of AlRse_loadfonts()  */

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

#define RE_APPEND_COMMAND "%sruleeditor -rs %s " /* append to ruleset */
#define RE_NEW_COMMAND "%sruleeditor -rs %s -f " /* new ruleset */
#define RE_COMMAND "%sruleeditor -rs %s %s %d " /* ruleset, option, rule# */
 
static
Bool re_Editor(the_rseditor, ruleset_name, rule_no, new_rule, new_rset)
     AlRSEditor *the_rseditor;
     char *ruleset_name;
     int  rule_no;
     Bool new_rule;
     int new_rset;       /* an integer bool, TRUE or FALSE */
 {
   char *command;
   Bool flag = Bool_FALSE;
   FILE *fp;
   int ret_val;
   char *path = "";

   /* Create a buffer in which to load the control string and 2 str params. */
   /* --------------------------------------------------------------------- */
   command = (char *) Memory_allocate((long) strlen(RE_COMMAND) + 31
                                      + strlen(path) 
                                      + strlen(ruleset_name));

   /* Load the shell command into a buffer. */
   /* ------------------------------------- */
   if (new_rset == TRUE)                        /* add new rule set */
     sprintf(command, RE_NEW_COMMAND, path, ruleset_name);

   else if (new_rule == Bool_TRUE)              /* add new rule  */
     { if (rule_no == 0)
         sprintf(command, RE_COMMAND, path, 
		 the_rseditor->ruleset_name,  "-ib", (rule_no + 1));
       else if ((rule_no > 0)
		&& (rule_no < Darray_len(the_rseditor->AlRSEdarray)))
         sprintf(command, RE_COMMAND, path, 
		 the_rseditor->ruleset_name, "-ib", rule_no);
       else
         sprintf(command, RE_APPEND_COMMAND, path, the_rseditor->ruleset_name);
     }
   else                                    /* existing rule */
     sprintf(command, RE_COMMAND, path, 
	     the_rseditor->ruleset_name, "-rn", rule_no);

   /* Invoke the command in a shell process */
   /* ------------------------------------- */

   /* First save ruleset, so rule editor gets newest version. */
   if (new_rset != TRUE)
     AlRSreg_save(the_rseditor->ruleset_name);

   AlRse_debug2(printf("ruleeditor command line = \"%s\"\n", command));

   fp = popen(command, "w+");
   if (fp == NULL)
     flag = Bool_FALSE;
   else
     flag = Bool_TRUE;
   fflush(fp);

   /* Wait for rule editor to finish, because we can't have more than */
   /* 1 copy of rule editor existing in this version.                 */
   ret_val=pclose(fp);
   Memory_free((VOIDP) command);

   /* Re-load in the ruleset. */
   /* ----------------------- */
   if (ret_val==0) 
     {
       AlRSreg_load(ruleset_name);
       if (new_rset == TRUE)
	 return(flag);
       if ((the_rseditor->the_ruleset = 
	    AlRSreg_find (the_rseditor->ruleset_name)) == NULL)
	 { Al_fatal_error1(
			   "Error in Rule Set. (Ruleset name trashed?)\
 Bad rule set name specified: %s\n",
                         the_rseditor->ruleset_name);
       };
   }
   else
     Al_fatal_error("Error with ruleeditor.\n");

   return(flag);
 };                       /* end of re_Editor()  */

/****************************************************************/
/****************************************************************/
/*           Error Messages Popup Box Functions                 */
/****************************************************************/

void AlRse_popdown_errbox(client_data, id)
     caddr_t client_data;
     XtIntervalId *id;
 { AlRSEditor *the_rseditor;

   /* ------------------------------------------------------------------- */
   /* Pop down the errbox of rsedit, which is displaying an error message */
   /* ------------------------------------------------------------------- */

   the_rseditor = (AlRSEditor *) client_data;
   if (the_rseditor->errbox_intervalid)
     XtPopdown(the_rseditor->errbox);

   if (the_rseditor->errbox_intervalid)
     { /* Assume timer is already removed, and update the_rseditor object */
       /* --------------------------------------------------------------- */
       the_rseditor->errbox_intervalid = 0;
     };
 };

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

void AlRse_errbox_popdown_callback(widget, closure, call_data)
     Widget widget;
     caddr_t closure;
     caddr_t call_data;
 { int new_top;
   AlRSEditor *the_rseditor;

   /* -------------------------------------------------------------- */
   /* User has clicked on the errbox, before its timer ran down      */
   /* User probably wanted to pop it down. So, popdown & stop timer. */
   /* -------------------------------------------------------------- */

   the_rseditor = (AlRSEditor *) closure;

   /* First, pop-down the errbox */
   /* -------------------------- */
   AlRse_popdown_errbox(closure, &(the_rseditor->errbox_intervalid));

   /* Now, remove the interval timer id */
   /* --------------------------------- */
   if (the_rseditor->errbox_intervalid)
     { /* XtRemoveTimeOut(the_rseditor->errbox_intervalid); */
       the_rseditor->errbox_intervalid = 0;
     };

 };     /* end of AlRse_errbox_popdown_callback()  */

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

void AlRse_create_popup_errbox(the_rseditor)
     AlRSEditor *the_rseditor;
 {
   Widget edit_shell;  /* the Override Shell that holds button editor */
   Widget edit_menu;   /* the background box for button editor menu   */
   Widget errbox_label;
   Widget parent, grandparent_widget;

   /* -------------------------------------------------------- */
   /* Create a popup error message box for this ruleset editor */
   /* -------------------------------------------------------- */

   parent = the_rseditor->rulebox_form[0];
   grandparent_widget = the_rseditor->shell_widget;

   /* Create an empty popup edit menu for a widget */
   /* -------------------------------------------- */
   edit_shell = XtCreatePopupShell("ErrorMessageBoxShell",
			  overrideShellWidgetClass,
			  grandparent_widget,
			  NULL, 0);
   edit_menu = 
	   XtCreateManagedWidget("ErrorMessageBox",
		       boxWidgetClass,
   		       edit_shell,
		       NULL, 0);

   /* Place a sensible Label ontop of the popup edit menu */
   /* ------------------------------------------------------ */
   arg_list[0].name = XtNlabel;
   arg_list[0].value = (XtArgVal)
                          "You must click on a SELECT button above, first.";
   errbox_label = XtCreateManagedWidget("ErrorMessageBoxLabel",
			       commandWidgetClass, edit_menu,
			       arg_list, 1);
   XtAddCallback(errbox_label, XtNcallback,
                AlRse_errbox_popdown_callback,
	        (caddr_t) the_rseditor);


   the_rseditor->errbox = edit_shell;
   the_rseditor->errlabel = errbox_label;
   the_rseditor->errbox_intervalid = 0;

  };         /* end of AlRse_create_popup_errbox()  */

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

void AlRse_popup_errbox(the_rseditor, the_msg)
     AlRSEditor *the_rseditor;
     Widget     the_msg;
 { XtIntervalId id;
/* XtTimerCallbackProc AlRse_popdown_errbox; */ /* function, pops-down errbox */
   int x, y, win_x, win_y;
   unsigned int mask;
   Window root, child;

   /* -------------------------------------------------------------------- */
   /* Pop up an error message box, and set a timer to automatically pop it */
   /* back down. Also, give a callback to pop it down if clicked on.       */
   /* -------------------------------------------------------------------- */

   XBell(the_rseditor->the_display, 1);    /* beep console at low volume */

   /* Set label to the error message */
   /* ------------------------------ */
   XtSetArg(arg_list[0], XtNlabel, the_msg);
   XtSetArg(arg_list[1], NULL, NULL);
   XtSetValues(the_rseditor->errlabel, arg_list, 1);

   /* Position the popup and realize it */
   /* --------------------------------- */
   XQueryPointer(the_rseditor->the_display,
		 RootWindow(the_rseditor->the_display,
			    the_rseditor->the_screen),
		 &root, &child, &x, &y, &win_x, &win_y, &mask);
   XtSetArg(arg_list[0], XtNx, x - 15);
   XtSetArg(arg_list[1], XtNy, y + 4);
   XtSetArg(arg_list[2], NULL, NULL);
   XtSetValues(the_rseditor->errbox, arg_list, 2);
   XtPopup(the_rseditor->errbox, XtGrabNone);

   /* Set the errbox to pop itself down after 10 seconds */
   /* -------------------------------------------------- */
#ifdef X11_R2
   id = XtAddTimeOut(
                10000,                    /* pop-down errbox in 10 seconds */
                /* (XtTimerCallbackProc) */
                 AlRse_popdown_errbox,    /* function to pop-down the errbox */
                (caddr_t) the_rseditor);  /* client data */
#else
   id = XtAddTimeOut(
                10000,                    /* pop-down errbox in 10 seconds */
                /* (XtTimerCallbackProc) */
                 AlRse_popdown_errbox,    /* function to pop-down the errbox */
                (caddr_t) the_rseditor);  /* client data */
#endif

   the_rseditor->errbox_intervalid = id;

 };        /* end of AlRse_popup_errbox()  */

/*********************************************************/
/*********************************************************/
/*               Callbacks                               */
/*********************************************************/

void rsedit_up_callback(widget, closure, call_data)
     Widget widget;
     caddr_t closure;
     caddr_t call_data;
 { int new_top;
   AlRSEditor *the_rseditor;

   the_rseditor = (AlRSEditor *) closure;

   new_top = (the_rseditor->top_rule) - (the_rseditor->n_rules_visible) + 1;
   if (new_top < 1)
     new_top = 1;
   if (new_top > the_rseditor->d_len)
     new_top = the_rseditor->d_len;

   AlRse_unselect(the_rseditor);

   the_rseditor->top_rule = new_top;
   AlRse_redraw(the_rseditor, the_rseditor->top_rule);

 };          /* end of rsedit_up_callback()  */

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

void rsedit_down_callback(widget, closure, call_data)
     Widget widget;
     caddr_t closure;
     caddr_t call_data;
 { int new_top;
   AlRSEditor *the_rseditor;

   the_rseditor = (AlRSEditor *) closure;

   new_top = (the_rseditor->top_rule) + (the_rseditor->n_rules_visible) - 1;
   if (new_top < 1)
     new_top = 1;
   if (new_top > the_rseditor->d_len)
     new_top = the_rseditor->d_len;

   AlRse_unselect(the_rseditor);

   the_rseditor->top_rule = new_top;
   AlRse_redraw(the_rseditor, the_rseditor->top_rule);

 };          /* end of rsedit_down_callback()  */

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

void rsedit_rule_callback(widget, closure, call_data)
     Widget widget;
     caddr_t closure;
     caddr_t call_data;
 { AlRSEditor *the_rseditor;
   struct rule_call_struct *parms;
   int rulebox_number;

   parms = (struct rule_call_struct *) closure;
   the_rseditor = parms->the_rseditor;
   rulebox_number = parms->rulebox_number;

   AlRse_select(the_rseditor, rulebox_number); /* also unslects old rule */

 };          /* end of rsedit_rule_callback()  */

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

void rsedit_quit_callback(widget, closure, call_data)
     Widget widget;
     caddr_t closure;
     caddr_t call_data;
 { AlRSEditor *the_rseditor;

   the_rseditor = (AlRSEditor *) closure;

   (the_rseditor->exit_function)(the_rseditor, 0);
     
 };          /* end of rsedit_quit_callback()  */

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

void rsedit_print_callback(widget, closure, call_data)
     Widget widget;
     caddr_t closure;
     caddr_t call_data;
 {   AlRSEditor *the_rseditor;
     char buffer[RULE_BUF_LEN];
     FILE *printer;
     int i;
     AlRule the_rule;

     the_rseditor = (AlRSEditor *) closure;

     if ((printer = popen("lpr ", "w+")) == NULL)
       { Al_warning2("Argus RuleSet Editor: Unable to open printer. %s%s",
	   "Unix Environment variable \"PRINTER\" may not be set correctly.",
           " (see \"man setenv\")");
         AlRse_popup_errbox(the_rseditor,
        "Can't find printer. You may need to \"setenv PRINTER yourprinter\"?");
	 return;
       };

     /* Start by printing a header with the rule set name */
     /* ------------------------------------------------- */
     fprintf(printer,
             "      ------------------------------------------------------\n");
     fprintf(printer,
	     "                 Argus RuleSet = \"%s\"  \n", 
	     the_rseditor->ruleset_name);
     fprintf(printer,
           "      ------------------------------------------------------\n\n");

       for (i = 0; i < the_rseditor->d_len; i++)
	 { the_rule = AlRuleSet_get_rule(the_rseditor->the_ruleset,
					  (unsigned int) i);
/*
	     Darray_get(the_rseditor->AlRSEdarray,
					  (unsigned int) i);
*/
	   Alruleprint(buffer,                                 /* buffer */
		       (RULE_BUF_LEN - 1),                     /* buflen */
		       Bool_TRUE,                              /* print_type */
		       the_rule);                              /* the rule */

	   buffer[RULE_BUF_LEN - 1] = '\0';
	   fprintf(printer, "[%d.]\n", (i + 1));
	   fprintf(printer, "%s\n", buffer);
	 };

     fclose(printer);
     AlRse_popup_errbox(the_rseditor,
        "Sucessfully printed.");

 };          /* end of rsedit_print_callback()  */

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

void rsedit_delete_callback(widget, closure, call_data)
     Widget widget;
     caddr_t closure;
     caddr_t call_data;
 { AlRSEditor *the_rseditor;

   the_rseditor = (AlRSEditor *) closure;
   
   if (the_rseditor->current_rule_number > 0)
     { AlRuleSet_remove_rule(the_rseditor->the_ruleset,
	      (unsigned) (the_rseditor->current_rule_number - 1));
       Darray_destroy(the_rseditor->AlRSEdarray);
       the_rseditor->AlRSEdarray = Darray_create();
       AlRuleSet_get_rules(the_rseditor->the_ruleset,
			   the_rseditor->AlRSEdarray);
       the_rseditor->d_len = Darray_len(the_rseditor->AlRSEdarray);
       if (the_rseditor->top_rule > the_rseditor->d_len)
	 the_rseditor->top_rule = the_rseditor->d_len;
       AlRse_unselect(the_rseditor);

       /* update screen */
       AlRse_redraw(the_rseditor, the_rseditor->top_rule); 
     }
   else
     { AlRse_popup_errbox(the_rseditor,
          "You must click on a valid rule's SELECT button above, first.");
     };

 };          /* end of rsedit_delete_callback()  */

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

void rsedit_edit_callback(widget, closure, call_data)
     Widget widget;
     caddr_t closure;
     caddr_t call_data;
 { AlRSEditor *the_rseditor;
   XLeaveWindowEvent the_event;

   the_rseditor = (AlRSEditor *) closure;
   
   if (the_rseditor->current_rule_number > 0)
     {
       /* Invoke the Rule Editor. */
       /* ----------------------- */
       if (the_rseditor->current_rule_number > 0)
	 re_Editor(the_rseditor, the_rseditor->ruleset_name,
		   the_rseditor->current_rule_number,
		   Bool_FALSE, FALSE);
       
       /* Refresh the display, using the new rule. */
       /* ---------------------------------------- */
       Darray_destroy(the_rseditor->AlRSEdarray);
       the_rseditor->AlRSEdarray = Darray_create();
       AlRuleSet_get_rules(the_rseditor->the_ruleset,
			   the_rseditor->AlRSEdarray);
       /* update screen */
       AlRse_redraw(the_rseditor,
                the_rseditor->top_rule);

       /* Unhighlight the button before exiting. */
       /* -------------------------------------- */
       the_event.mode = NotifyNormal;
       the_event.window = XtWindow(widget);
       the_event.x = 0;
       the_event.y = 0;
       XSendEvent(the_rseditor->the_display, XtWindow(widget), 
		  True,    /* do propagate */
		  LeaveWindowMask,
		  &the_event);
     }
   else
     { AlRse_popup_errbox(the_rseditor,
          "You must click on a valid rule's SELECT button above, first.");
     };

 };          /* end of rsedit_edit_callback()  */

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

void rsedit_copy_callback(widget, closure, call_data)
     Widget widget;
     caddr_t closure;
     caddr_t call_data;
 { AlRSEditor *the_rseditor;
   AlRule the_rule;

   the_rseditor = (AlRSEditor *) closure;
   
   if (the_rseditor->current_rule_number > 0)
     { the_rule = AlRule_copy(Darray_get(the_rseditor->AlRSEdarray, (unsigned)
			      (the_rseditor->current_rule_number - 1)));
       AlRuleSet_put_rule_at_index(the_rseditor->the_ruleset, the_rule, 
			  (unsigned) (the_rseditor->current_rule_number - 1));
       Darray_destroy(the_rseditor->AlRSEdarray);
       the_rseditor->AlRSEdarray = Darray_create();
       AlRuleSet_get_rules(the_rseditor->the_ruleset,
			   the_rseditor->AlRSEdarray);
       AlRse_redraw(the_rseditor,
		    the_rseditor->top_rule);  /* update screen */
     }
   else
     { AlRse_popup_errbox(the_rseditor,
          "You must click on a valid rule's SELECT button above, first.");
     };

 };          /* end of rsedit_copy_callback()  */

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

void rsedit_insert_callback(widget, closure, call_data)
     Widget widget;
     caddr_t closure;
     caddr_t call_data;
 { AlRSEditor *the_rseditor;
   XLeaveWindowEvent the_event;

   the_rseditor = (AlRSEditor *) closure;
   
   if (the_rseditor->current_rule_number > 0)
     { 
       /* Call the Rule editor interface function. */
       /* ---------------------------------------- */
       re_Editor(the_rseditor, the_rseditor->ruleset_name,
		 the_rseditor->current_rule_number,
		 Bool_TRUE, FALSE);

       /* Take new rule into account and update the rule set editor screen. */
       /* ----------------------------------------------------------------- */
       Darray_destroy(the_rseditor->AlRSEdarray);
       the_rseditor->AlRSEdarray = Darray_create();
       AlRuleSet_get_rules(the_rseditor->the_ruleset,
			   the_rseditor->AlRSEdarray);
       the_rseditor->d_len = Darray_len(the_rseditor->AlRSEdarray);
       AlRse_redraw(the_rseditor, the_rseditor->top_rule);  /* update screen */
     }
   else if (the_rseditor->current_rule_number < -1)
     { 
       /* Call the Rule editor interface function. */
       /* ---------------------------------------- */
       re_Editor(the_rseditor, the_rseditor->ruleset_name,
		 the_rseditor->current_rule_number,
		 Bool_TRUE, FALSE);

       /* Take new rule into account and update the rule set editor screen. */
       /* ----------------------------------------------------------------- */
       Darray_destroy(the_rseditor->AlRSEdarray);
       the_rseditor->AlRSEdarray = Darray_create();
       AlRuleSet_get_rules(the_rseditor->the_ruleset,
			   the_rseditor->AlRSEdarray);
       the_rseditor->d_len = Darray_len(the_rseditor->AlRSEdarray);
       AlRse_redraw(the_rseditor, the_rseditor->top_rule);  /* update screen */
     }
   else
     { AlRse_popup_errbox(the_rseditor,
          "You must click on a SELECT button above, first.");
     };

 };          /* end of rsedit_insert_callback()  */

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

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

void AlRse_refresh_widget(widget)
     Widget widget;
 {
   XExposeEvent the_event;

       /* Send an Expose event to the asciitext widget to refresh itself */
       /* -------------------------------------------------------------- */
/*
       the_event.window = XtWindow(widget);
       the_event.x = 0;
       the_event.y = 0;
       the_event.width = 517;
       the_event.height = 33;
       the_event.count = 0;
       XSendEvent(XtDisplay(widget), XtWindow(widget), 
		  True, 
		  ExposureMask,
		  &the_event);
*/

       XtUnmanageChild(widget);
       XtSetArg(arg_list[0], XtNwidth, 517);
       XtSetArg(arg_list[1], XtNheight, 33);
       XtSetArg(arg_list[2], XtNresizable, FALSE);
       XtSetArg(arg_list[3], NULL, NULL);
       XtSetValues(widget, arg_list, 3);
       XtManageChild(widget);

 };

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

void AlRse_set_rule_widget(the_rseditor, view_index, rulenum, msg)
     AlRSEditor *the_rseditor;     /* the rule set editor object */
     int view_index;               /* # of visible rulebox */
     int rulenum;                  /* # of the rule to be assoc'ed to rulebox*/
     char *msg;                    /* ascii text format of rule */
 { 
   int  i, msg_length;
   AlRule the_rule;
   static char temp_buf[RULE_BUF_LEN];
#ifdef X11_R2
   XtTextBlock text_block;
#endif

   /* --------------------------------------------- */
   /* Display a new rule in the Rule Set Editor's   */
   /* view window (number "view_index").            */
   /* --------------------------------------------- */

   /* Set the new label for the rule number. */
   /* -------------------------------------- */
   if ((rulenum > 0) && (rulenum <= the_rseditor->d_len))
     sprintf(the_rseditor->rule_num_label[view_index], "%4d%c", rulenum, '\0');
   else
     { strcpy(the_rseditor->rule_num_label[view_index], "  - ");
       the_rseditor->rule_number[view_index] = rulenum;
       temp_buf[0] = '\0';

       /* Replace the old rule's source string with the new rule's string */
       /* --------------------------------------------------------------- */
#ifdef X11_R2
       AlRse_set_str(the_rseditor->text_str[view_index], temp_buf);
       AlRse_refresh_widget(the_rseditor->text_str_widget[view_index]);
#else
       AlRse_set_str(the_rseditor->text_str[view_index], temp_buf);
       XtTextInvalidate(the_rseditor->text_str_widget[view_index],
		    (XtTextPosition) 0, (XtTextPosition) (RULE_BUF_LEN - 1));
       XtTextDisplay(the_rseditor->text_str_widget[view_index]); 
#endif

       /* Set the new label for the Rule# widget. */
       /* --------------------------------------- */
       XtSetArg(arg_list[0], XtNlabel,
                the_rseditor->rule_num_label[view_index]);
       XtSetArg(arg_list[1], XtNheight, 14);
       XtSetArg(arg_list[2], XtNresizable, False);
       XtSetArg(arg_list[3], NULL, NULL);
       XtSetValues(the_rseditor->num_rule_widget[view_index], arg_list, 3);
#ifdef X11_R2
       XtSetArg(arg_list[0], XtNheight, 14);
       XtSetArg(arg_list[1], XtNresizable, False);
       XtSetArg(arg_list[2], NULL, NULL);
       XtSetValues(the_rseditor->num_rule_widget[view_index], arg_list, 2);
#endif
       return;
     };
   the_rseditor->rule_number[view_index] = rulenum;

   /* Set the new text for the rule's string. */
   /* --------------------------------------- */
   if (msg == NULL)
     { the_rule = AlRuleSet_get_rule(the_rseditor->the_ruleset,
					  (unsigned int) rulenum - 1);

       Alruleprint(temp_buf,                                   /* buffer */
		   RULE_BUF_LEN,                               /* buflen */
		   Bool_TRUE,                                  /* print_type */
		   the_rule);                                  /* the rule */
       temp_buf[RULE_BUF_LEN] = '\0';

       AlRse_debug(printf("In AlRse_set_rule_widget: temp_buf = \"%s\"\n",
                          temp_buf));

       /* Replace the old rule's source string with the new rule's string */
       /* --------------------------------------------------------------- */
#ifdef X11_R2
       AlRse_set_str(the_rseditor->text_str[view_index], temp_buf);
       AlRse_refresh_widget(the_rseditor->text_str_widget[view_index]);
#else
       AlRse_set_str(the_rseditor->text_str[view_index], temp_buf);
       XtTextInvalidate(the_rseditor->text_str_widget[view_index],
		    (XtTextPosition) 0, (XtTextPosition) (RULE_BUF_LEN - 1));
       XtTextDisplay(the_rseditor->text_str_widget[view_index]);
#endif

     }
   else
     {
       /* Replace the old rule's source string with the new rule's string */
       /* --------------------------------------------------------------- */
#ifdef X11_R2
       AlRse_set_str(the_rseditor->text_str[view_index], temp_buf);
       AlRse_refresh_widget(the_rseditor->text_str_widget[view_index]);
#else
       AlRse_set_str(the_rseditor->text_str[view_index], msg);
       XtTextInvalidate(the_rseditor->text_str_widget[view_index],
		    (XtTextPosition) 0, (XtTextPosition) (RULE_BUF_LEN - 1));
       XtTextDisplay(the_rseditor->text_str_widget[view_index]); 
#endif
     };

   AlRse_debug(printf("the_rseditor->text_str[view_index]=\"%s\"\n",
		      the_rseditor->text_str[view_index]));

   /* Set the new label for the Rule# widget. */
   /* --------------------------------------- */
   XtSetArg(arg_list[0], XtNlabel, the_rseditor->rule_num_label[view_index]);
   XtSetArg(arg_list[1], XtNheight, 14);
   XtSetValues(the_rseditor->num_rule_widget[view_index], arg_list, 2);
#ifdef X11_R2
       XtSetArg(arg_list[0], XtNheight, 14);
       XtSetArg(arg_list[1], XtNresizable, False);
       XtSetArg(arg_list[2], NULL, NULL);
       XtSetValues(the_rseditor->num_rule_widget[view_index], arg_list, 2);
#endif

 };         /* end of AlRse_set_rule_widget()  */

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

AlRse_redraw(the_rseditor, new_top_no)                    /* update screen */
     AlRSEditor *the_rseditor;        /* the rule set editor object */
     int        new_top_no;          /* the new top rule */
 {
   int i, d_len, top_rule_no, rule_no;


   d_len = the_rseditor->d_len;
   if (new_top_no <= 0)
     top_rule_no = 1;
   else if (new_top_no > d_len)
     top_rule_no = d_len;
   else
     top_rule_no = new_top_no;

   AlRse_unselect(the_rseditor);

   rule_no = top_rule_no;
   for (i = 0; i < the_rseditor->n_rules_visible; i++)
     { if (rule_no < 1)
         AlRse_set_rule_widget(the_rseditor, i, -1, " ");
       else if (rule_no <= d_len)
         AlRse_set_rule_widget(the_rseditor, i, rule_no, NULL);
       else
         AlRse_set_rule_widget(the_rseditor, i, -1, " ");

       rule_no++;
     };
 };         /* end of AlRse_redraw()  */

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

Widget AlRse_mktext(the_rseditor, name, parent, 
		    x, y, height, width, border, text_str, len, font)
     AlRSEditor *the_rseditor;
     char *name;
     Widget parent;
     int x, y, height, width, border;
     char *text_str;
     int  len, font;
{
   Widget the_widget;
   int i;

   i = 0;

   /* Create a scrollable Ascii Text Widget, whose parent is parent */

   XtSetArg(arg_list[i], XtNx, x);                                   i++;
   XtSetArg(arg_list[i], XtNy, y);                                   i++;
   XtSetArg(arg_list[i], XtNhorizDistance, x);                       i++;
   XtSetArg(arg_list[i], XtNvertDistance, y);                        i++;
   XtSetArg(arg_list[i], XtNwidth, width);                           i++;
   XtSetArg(arg_list[i], XtNheight, height);                         i++;
   XtSetArg(arg_list[i], XtNborderWidth, border);                    i++;
   XtSetArg(arg_list[i], XtNleft, XtRubber);                         i++;
   XtSetArg(arg_list[i], XtNright, XtRubber);                        i++;
   XtSetArg(arg_list[i], XtNtop, XtRubber);                          i++;
   XtSetArg(arg_list[i], XtNbottom, XtRubber);                       i++;
   XtSetArg(arg_list[i], XtNfont, AlRse_font(font));                 i++;
   XtSetArg(arg_list[i], XtNresizable, FALSE);                       i++;

/*   XtSetArg(arg_list[i], XtNeditType, XttextEdit);                   i++; */
/*   XtSetArg(arg_list[i], XtNeditType, XttextRead);                   i++; */
   XtSetArg(arg_list[i], XtNlength, strlen(text_str));               i++;
#ifdef X11_R2
  /* XtSetArg(arg_list[i], XtNmaxLength, len);                         i++;  */
#endif
   XtSetArg(arg_list[i], XtNstring, text_str);                       i++;
   XtSetArg(arg_list[i], XtNtextOptions,
	    /* editable |  */
	    scrollVertical | wordBreak);                             i++;
   XtSetArg(arg_list[i], NULL, NULL);

   the_widget = XtCreateManagedWidget(name, asciiStringWidgetClass,
				      parent, arg_list, i);

   return(the_widget);

};          /* end of AlRse_mktext()  */

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

Widget AlRse_mkscrollbar(the_rseditor, name, parent,
		    x, y, height, width, border, vert_flag)
     AlRSEditor *the_rseditor;
     char *name;
     Widget parent;
     int x, y, height, width, border;
     int vert_flag;   /* if vert_flag == 1  vertical scrollbar, else horiz */
 { 
   Widget the_widget;
   int i;

   i = 0;

   /* Create Scrollbar Widget, whose parent is parent */

   XtSetArg(arg_list[i], XtNx, x); i++;
   XtSetArg(arg_list[i], XtNy, y); i++;
   XtSetArg(arg_list[i], XtNhorizDistance, x); i++;
   XtSetArg(arg_list[i], XtNvertDistance, y); i++;
   XtSetArg(arg_list[i], XtNheight, height); i++;
   XtSetArg(arg_list[i], XtNwidth, width); i++;
   XtSetArg(arg_list[i], XtNborderWidth, border); i++;
   if (vert_flag == 1)
     { XtSetArg(arg_list[i], XtNorientation, XtorientVertical); i++;
     }
   else
     { XtSetArg(arg_list[i], XtNorientation, XtorientHorizontal); i++;
     };

   /* Form related instance variables, about placement */
   XtSetArg(arg_list[i], XtNleft, XtRubber); i++;
   XtSetArg(arg_list[i], XtNright, XtRubber); i++;
   XtSetArg(arg_list[i], XtNtop, XtRubber); i++;
   XtSetArg(arg_list[i], XtNbottom, XtRubber); i++;
   XtSetArg(arg_list[i], XtNresizable, TRUE); i++;
   XtSetArg(arg_list[i], NULL, NULL);

   the_widget = XtCreateManagedWidget(name, scrollbarWidgetClass,
				      parent, arg_list, i);

   return(the_widget);

};          /* end of AlRse_mkscrollbar()  */

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

Widget AlRse_mkform(the_rseditor, name, parent,
		    x, y, height, width, border, inverse_flag, vert_resizable)
     AlRSEditor *the_rseditor;
     char *name;
     Widget parent;
     int x, y, height, width, border;
     int  inverse_flag;  
     int vert_resizable;     /* 1 if form resizes proportionally vertically, */
                             /* else 0 for form to be clipped on rseize vert */
 { 
   Widget the_widget;
   int i;

   i = 0;

   /* Create Form Widget, whose parent is parent */

   XtSetArg(arg_list[i], XtNx, x); i++;
   XtSetArg(arg_list[i], XtNy, y); i++;
   XtSetArg(arg_list[i], XtNhorizDistance, x); i++;
   XtSetArg(arg_list[i], XtNvertDistance, y); i++;
   XtSetArg(arg_list[i], XtNheight, height); i++;
   XtSetArg(arg_list[i], XtNwidth, width); i++;
   XtSetArg(arg_list[i], XtNborderWidth, border); i++;
   XtSetArg(arg_list[i], XtNdefaultDistance, 0); i++;
   if (inverse_flag == 1)           /* form is highlighted */
     { XtSetArg(arg_list[i], XtNforeground,
		WhitePixel(the_rseditor->the_display,
			   the_rseditor->the_screen)); i++;
       XtSetArg(arg_list[i], XtNbackground, 
		BlackPixel(the_rseditor->the_display, 
			   the_rseditor->the_screen)); i++;
     }
   else                             /* form is unhighlighted */
     { XtSetArg(arg_list[i], XtNforeground,
		BlackPixel(the_rseditor->the_display, 
			   the_rseditor->the_screen)); i++;
       XtSetArg(arg_list[i], XtNbackground,
		WhitePixel(the_rseditor->the_display, 
			   the_rseditor->the_screen)); i++; 
     };
   /* Form related instance variables, about placement */
   if (vert_resizable == 1)
     {
       XtSetArg(arg_list[i], XtNleft, XtRubber); i++;
       XtSetArg(arg_list[i], XtNright, XtRubber); i++;
       XtSetArg(arg_list[i], XtNtop, XtRubber); i++;
       XtSetArg(arg_list[i], XtNbottom, XtRubber); i++;
     }
   else   /* form shouldn't try to retain proportional size (vert) to parent */
     {
       XtSetArg(arg_list[i], XtNleft, XtRubber); i++;
       XtSetArg(arg_list[i], XtNright, XtRubber); i++;
       XtSetArg(arg_list[i], XtNtop, XtChainTop); i++;
       XtSetArg(arg_list[i], XtNbottom, XtChainTop); i++;
     };
   XtSetArg(arg_list[i], XtNresizable, TRUE); i++;
   XtSetArg(arg_list[i], NULL, NULL);

   the_widget = XtCreateManagedWidget(name, formWidgetClass,
				      parent, arg_list, i);

   return(the_widget);

 };          /* end of AlRse_mkform()  */

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

Widget AlRse_mklabel(name, parent, label, x, y, height, width, justify, font)
     char *name;
     Widget parent;
     char *label;
     int x, y, height, width, justify, font;
 { 
   Widget the_widget;
   int i;

   i = 0;

   /* Create Label Widget, whose parent is parent */

   XtSetArg(arg_list[i], XtNlabel, label); i++;
   XtSetArg(arg_list[i], XtNjustify, AlRse_justify(justify)); i++;
   XtSetArg(arg_list[i], XtNx, x); i++;
   XtSetArg(arg_list[i], XtNy, y); i++;
   XtSetArg(arg_list[i], XtNhorizDistance, x); i++;
   XtSetArg(arg_list[i], XtNvertDistance, y); i++;
   XtSetArg(arg_list[i], XtNheight, height); i++;
   XtSetArg(arg_list[i], XtNwidth, width); i++;
   XtSetArg(arg_list[i], XtNborderWidth, 0); i++;
   /* Form related instance variables, about placement */
   XtSetArg(arg_list[i], XtNleft, XtRubber); i++;
   XtSetArg(arg_list[i], XtNright, XtRubber); i++;
   XtSetArg(arg_list[i], XtNtop, XtRubber); i++;
   XtSetArg(arg_list[i], XtNbottom, XtRubber); i++;
   XtSetArg(arg_list[i], XtNresizable, TRUE); i++;
   XtSetArg(arg_list[i], XtNfont, AlRse_font(font)); i++;
   XtSetArg(arg_list[i], NULL, NULL);

   the_widget = XtCreateManagedWidget(name, labelWidgetClass,
				      parent, arg_list, i);

   return(the_widget);

 };          /* end of AlRse_mklabel()  */

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

Widget AlRse_mkbutton(name, parent, label, x, y, height, width, font, fromhor)
     char *name;
     Widget parent;
     char *label;
     int x, y, height, width, font;
     Widget fromhor;
 { 
   Widget the_widget;
   int i;

   i = 0;

   /* Create Button Widget, whose parent is parent */

   XtSetArg(arg_list[i], XtNlabel, label); i++;
   XtSetArg(arg_list[i], XtNjustify, XtJustifyCenter); i++;
   XtSetArg(arg_list[i], XtNx, x); i++;
   XtSetArg(arg_list[i], XtNy, y); i++;
   XtSetArg(arg_list[i], XtNhorizDistance, x); i++;
   XtSetArg(arg_list[i], XtNvertDistance, y); i++;
   XtSetArg(arg_list[i], XtNheight, height); i++;
   XtSetArg(arg_list[i], XtNwidth, width); i++;
   XtSetArg(arg_list[i], XtNhighlightThickness, 2); i++;
   XtSetArg(arg_list[i], XtNfromHoriz, fromhor); i++;
   /* Form related instance variables, about placement */
   XtSetArg(arg_list[i], XtNleft, XtRubber); i++;
   XtSetArg(arg_list[i], XtNright, XtRubber); i++;
   XtSetArg(arg_list[i], XtNtop, XtRubber); i++;
   XtSetArg(arg_list[i], XtNbottom, XtRubber); i++;
   XtSetArg(arg_list[i], XtNresizable, TRUE); i++;
   XtSetArg(arg_list[i], XtNfont, AlRse_font(font)); i++;
   XtSetArg(arg_list[i], NULL, NULL);

   the_widget = XtCreateManagedWidget(name, commandWidgetClass,
				      parent, arg_list, i);

   return(the_widget);

 };          /* end of AlRse_mkbutton()  */

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

void AlRse_mkrulebox(the_rseditor, rsedit_rule_form, nth_rulebox)
     AlRSEditor *the_rseditor;
     Widget rsedit_rule_form;
     int nth_rulebox;
 {
/*   Widget rsedit_rule_mouse; */
   Widget rsedit_rule_ascii_form;
   Widget rsedit_rule_asciitext;
   Widget rsedit_rule_button;
   Widget rsedit_rule_label;
   Widget rsedit_rule_number;
/*   static Pixmap button_icon; */
   int xn = 10;
   int hn = 35;

   the_rseditor->rulebox_form[nth_rulebox] = rsedit_rule_form;

   /* Create Label Widget, whose parent is rsedit_rule_form */
/*
   rsedit_rule_mouse =
     AlRse_mklabel("rsedit_rule_mouse", rsedit_rule_form,
		    "Mo",
		    112 - xn - xn, 11, 20, 28, CENTER, TIMESBOLD14);
*/
   /* place an argus-button pixmap in widget */
/*
   if (button_icon == NULL)
     { button_icon =
	 XCreatePixmapFromBitmapData(the_rseditor->the_display,
                      DefaultRootWindow(the_rseditor->the_display),
                      button_bits,
                      button_width, button_height,
                      BlackPixel(the_rseditor->the_display, 
				 the_rseditor->the_screen),
                      WhitePixel(the_rseditor->the_display,
				 the_rseditor->the_screen),
                      DefaultDepth(the_rseditor->the_display, 
				   the_rseditor->the_screen));
     };
   if (button_icon != NULL)
     { XtSetArg(arg_list[0], XtNbackgroundPixmap, button_icon);
       XtSetArg(arg_list[1], XtNwidth, button_width);
       XtSetArg(arg_list[2], XtNheight, button_height);
       XtSetArg(arg_list[3], XtNlabel, " ");
       XtSetArg(arg_list[4], XtNresizable, FALSE);
       XtSetArg(arg_list[5], NULL, NULL);
       XtSetValues(rsedit_rule_mouse, arg_list, 5);
     }
   else
     { XtSetArg(arg_list[0], XtNlabel, "UP ");
       XtSetArg(arg_list[1], NULL, NULL);
       XtSetValues(rsedit_rule_mouse, arg_list, 1);
     };
*/

   /* Create Form Widget, whose parent is rsedit_rule_form */
   rsedit_rule_ascii_form =
     AlRse_mkform(the_rseditor, "rsedit_rule_ascii_form", rsedit_rule_form,
		  150 - xn - xn - 35, 3,
		  67 - hn, 517, 1, 0,   /* x, y, h, w, border, inverse */
      0);     /* retain vertical porportion to parent flag */

   /* Create scrollable Ascii Text Widget, parent is rsedit_rule_ascii_form */
   rsedit_rule_asciitext =
      AlRse_mktext(the_rseditor, "rsedit_rule_asciitext",
		   rsedit_rule_ascii_form,
		   0, 0, 67 - hn, 517, 0,        /* x, y, h, w, border */
		   the_rseditor->text_str[nth_rulebox], RULE_BUF_LEN,
		   TIMESROMAN14);
   the_rseditor->text_str_widget[nth_rulebox] = 
      rsedit_rule_asciitext;  /* Widget that holds the text format of a rule */

   /* Create Button Widget("Select"), whose parent is rsedit_rule_form */
   rsedit_rule_button =
      AlRse_mkbutton("rsedit_rule_button", rsedit_rule_form,
		    "Select", 15 - xn, 36 - 20, 20, 62 - 9, TIMESBOLD14, NULL);
   XtAddCallback(rsedit_rule_button, XtNcallback,
                rsedit_rule_callback,
		 (caddr_t) 
		 (the_rseditor->parm_struct[nth_rulebox] =
		  AlRse_make_parms(the_rseditor, nth_rulebox)));
   the_rseditor->button_rule_widget[nth_rulebox] =
         rsedit_rule_button;   /* button Widget that displays selected state */

   /* Create Label Widget("Rule  #"), whose parent is rsedit_rule_form */
   rsedit_rule_label =
     AlRse_mklabel("rsedit_rule_label", rsedit_rule_form,
		   "Rule  #",
		   14 - xn, 1, 14, 53, RIGHT, TIMESBOLD14);

   /* Create Label Widget("1"), whose parent is rsedit_rule_form */
   rsedit_rule_number =
     AlRse_mklabel("rsedit_rule_number", rsedit_rule_form,
		   " ",
		   67 - xn, 1, 14, 15, LEFT, TIMESBOLD14);
   the_rseditor->num_rule_widget[nth_rulebox] = 
            rsedit_rule_number;          /* labelWidget that displays rule# */

 };          /* end of AlRse_mkrulebox()  */

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

AlRSEditor *create_rsedit(the_rseditor, shell_widget)
     AlRSEditor *the_rseditor;
     Widget shell_widget;
 {
   int i;
   Widget base_widget;         /* the base widget (visible background) */
   Widget rsedit_background;
   Widget rsedit_titlebar;
   Widget rsedit_title;
   Widget rsedit_subtitle;
   Widget rsedit_ruleset_name;
   Widget rsedit_scroll_area;
   Widget rsedit_up_button;
   Widget rsedit_down_button;
   Widget rsedit_scrollbar;
   Widget rsedit_rule_area;
   Widget rsedit_rule_form[N_VISIBLE_RULES];
   Widget rsedit_button_area;
   Widget rsedit_quit_button;
   Widget rsedit_print_button;
   Widget rsedit_delete_button;
   Widget rsedit_edit_button;
   Widget rsedit_copy_button;
   Widget rsedit_insert_button;
   Widget rsedit_underline;
   static Pixmap sm_up_arrow_icon;
   static Pixmap sm_down_arrow_icon;
   static Arg arg_list[12];
   int hn = 36;

   /* Create main (background) widget for the rule set editor  */
   /* -------------------------------------------------------- */
   XtSetArg(arg_list[0], XtNresizable, TRUE);
   XtSetArg(arg_list[1], XtNdefaultDistance, 0);
   XtSetArg(arg_list[2], NULL, NULL);
   base_widget = XtCreateManagedWidget("Top Level Form",
			       formWidgetClass, shell_widget,
			       arg_list, 2);

   the_rseditor->the_display = XtDisplay(base_widget);  /* display of rsedit */
   the_rseditor->the_screen = DefaultScreen(the_rseditor->the_display);

   AlRse_loadfonts("rsedit:",
		   the_rseditor->the_display, the_rseditor->the_screen);

   /* Create Form Widget, whose parent is base_widget */
   rsedit_background =
     AlRse_mkform(the_rseditor, "rsedit_background", base_widget,
		  0, 0, 352, 798, 1, 0,   /* x, y, h, w, border, inverse */
                  1);     /* retain vertical porportion to parent flag */

   /* Create Form Widget, whose parent is rsedit_background */
   rsedit_titlebar =
     AlRse_mkform(the_rseditor, "rsedit_titlebar", rsedit_background,
		  4, 4, 33, 520, 0, 0,   /* x, y, h, w, border, inverse */
		  1);     /* retain vertical porportion to parent flag */

   i = 0;

   /* Create Label Widget("ARGUS  Rule Set Editor"), parent= rsedit_titlebar */
   rsedit_title =
      AlRse_mklabel("rsedit_title", rsedit_titlebar,
		    "ARGUS  Rule Set Editor",
		    4, 4, 25, 206, CENTER, TIMESBOLD18);

   /* Create Label Widget("EDITING the rule set named") */
   rsedit_subtitle =
      AlRse_mklabel("rsedit_subtitle", rsedit_titlebar,
		    "EDITING the rule set named",
		    253, 8, 20, 191, RIGHT, TIMESROMAN14);

   /* Create Label Widget("myruleset"), whose parent is rsedit_titlebar */
   rsedit_ruleset_name =
      AlRse_mklabel("rsedit_ruleset_name", rsedit_titlebar,
		    the_rseditor->ruleset_name,
		    446, 8, 20, 70, LEFT, TIMESROMAN14);

   /* Create Form Widget, whose parent is rsedit_background */
   rsedit_scroll_area =
     AlRse_mkform(the_rseditor, "rsedit_scroll_area", rsedit_background,
		  4, 47, 261, 41, 0, 0,   /* x, y, h, w, border, inverse */
		  1);     /* retain vertical porportion to parent flag */

   /* Create Button Widget("UP "), whose parent is rsedit_scroll_area */
   rsedit_up_button = 
     AlRse_mkbutton("rsedit_up_button", rsedit_scroll_area,
		    "UP ", 5, 4,
		    sm_up_arrow_height, sm_up_arrow_width, TIMESBOLD14, NULL);
   XtAddCallback(rsedit_up_button, XtNcallback,
                rsedit_up_callback, (caddr_t) the_rseditor);
   /* place an arrow pixmap in widget */
   if (sm_up_arrow_icon == NULL)
     { sm_up_arrow_icon = 
	 XCreatePixmapFromBitmapData(the_rseditor->the_display,
                      DefaultRootWindow(the_rseditor->the_display),
                      sm_up_arrow_bits,
                      sm_up_arrow_width, sm_up_arrow_height,
                      BlackPixel(the_rseditor->the_display, 
				 the_rseditor->the_screen),
                      WhitePixel(the_rseditor->the_display,
				 the_rseditor->the_screen),

                      DefaultDepth(the_rseditor->the_display, 
				   the_rseditor->the_screen));
     };
   if (sm_up_arrow_icon != NULL)
     { XtSetArg(arg_list[0], XtNbackgroundPixmap, sm_up_arrow_icon);
       XtSetArg(arg_list[1], XtNwidth, sm_up_arrow_width);
       XtSetArg(arg_list[2], XtNheight, sm_up_arrow_height);
       XtSetArg(arg_list[3], XtNlabel, "     ");
       XtSetArg(arg_list[4], XtNresizable, FALSE);
       XtSetArg(arg_list[5], NULL, NULL);
       XtSetValues(rsedit_up_button, arg_list, 5);
#ifdef X11_R2
       XtSetArg(arg_list[0], XtNwidth, sm_up_arrow_width);
       XtSetArg(arg_list[1], XtNheight, sm_up_arrow_height);
       XtSetArg(arg_list[2], NULL, NULL);
       XtSetValues(rsedit_up_button, arg_list, 2);
#endif
     }
   else
     { XtSetArg(arg_list[0], XtNlabel, "UP ");
       XtSetArg(arg_list[1], NULL, NULL);
       XtSetValues(rsedit_up_button, arg_list, 1);
     };

   /* Create Button Widget("DN"), whose parent is rsedit_scroll_area */
   rsedit_down_button =
     AlRse_mkbutton("rsedit_down_button", rsedit_scroll_area,
		    "DN", 5, 235, 
		    sm_down_arrow_height, sm_down_arrow_width,
		    TIMESBOLD14, NULL);
   XtAddCallback(rsedit_down_button, XtNcallback,
                rsedit_down_callback, (caddr_t) the_rseditor);
      /* place an arrow pixmap in widget */
   if (sm_down_arrow_icon == NULL)
     { sm_down_arrow_icon =
	 XCreatePixmapFromBitmapData(the_rseditor->the_display,
                      DefaultRootWindow(the_rseditor->the_display),
                      sm_down_arrow_bits,
                      sm_down_arrow_width, sm_down_arrow_height,
                      BlackPixel(the_rseditor->the_display, 
				 the_rseditor->the_screen),
                      WhitePixel(the_rseditor->the_display,
				 the_rseditor->the_screen),

                      DefaultDepth(the_rseditor->the_display, 
				   the_rseditor->the_screen));
     };
   if (sm_down_arrow_icon != NULL)
     { XtSetArg(arg_list[0], XtNbackgroundPixmap, sm_down_arrow_icon);
       XtSetArg(arg_list[1], XtNwidth,  sm_down_arrow_width);
       XtSetArg(arg_list[2], XtNheight,  sm_down_arrow_height);
       XtSetArg(arg_list[3], XtNlabel, "     ");
       XtSetArg(arg_list[4], XtNresizable, FALSE);
       XtSetArg(arg_list[5], NULL, NULL);
       XtSetValues(rsedit_down_button, arg_list, 5);
#ifdef X11_R2
       XtSetArg(arg_list[0], XtNwidth,  sm_down_arrow_width);
       XtSetArg(arg_list[1], XtNheight,  sm_down_arrow_height);
       XtSetArg(arg_list[2], NULL, NULL);
       XtSetValues(rsedit_down_button, arg_list, 2);
#endif
     }
   else
     { XtSetArg(arg_list[0], XtNlabel, "DN");
       XtSetArg(arg_list[1], NULL, NULL);
       XtSetValues(rsedit_down_button, arg_list, 1);
     };


   /* Create Form Widget, whose parent is rsedit_scroll_area */
   rsedit_scrollbar =
     AlRse_mkform(the_rseditor, "rsedit_scrollbar", rsedit_scroll_area,
		  20, 27, 207, 2, 0, 1,   /* x, y, h, w, border, inverse */
		  1);     /* retain vertical porportion to parent flag */
/*
   rsedit_scrollbar =
     AlRse_mkscrollbar(the_rseditor, "rsedit_scrollbar", rsedit_scroll_area,
		  4, 28, 203, 30, 1, 1); */
      /* x, y, h, w, border, vert_flag */


   /* Create Form Widget, whose parent is rsedit_background */
   rsedit_rule_area =
     AlRse_mkform(the_rseditor, "rsedit_rule_area", rsedit_background,
	        54, 49, 256, 683, 0, 0,   /* x, y, h, w, border, inverse */
		1);     /* retain vertical porportion to parent flag */

   for (i = 0; i < N_VISIBLE_RULES; i++)
     {
       /* Create Form Widget, whose parent is rsedit_rule_area */
       rsedit_rule_form[i] =
	 AlRse_mkform(the_rseditor, "rsedit_rule_form", rsedit_rule_area,
		      4, ((78-hn)* i), (78-hn), 673,  /* x, y, h, w */
		      0, 0,     /* border, inverse */
		      0);       /* retain vertical porportion to parent flag */

       XtSetArg(arg_list[0], XtNdefaultDistance, 1);
       XtSetValues(rsedit_rule_form[i], arg_list, 1);

       /* Create all widgets that form a rule box, parent=rsedit_rule_form[] */
       AlRse_mkrulebox(the_rseditor, rsedit_rule_form[i], i);
     };

   /* Create Form Widget, whose parent is rsedit_background */
   rsedit_button_area =
     AlRse_mkform(the_rseditor, "rsedit_button_area", rsedit_background,
		  0, 314, 32, 789, 1, 0,   /* x, y, h, w, border, inverse */
		  1);     /* retain vertical porportion to parent flag */
   XtSetArg(arg_list[0], XtNdefaultDistance, 3);
   XtSetValues(rsedit_button_area, arg_list, 1);

   /* Create Button Widget("Quit"), whose parent is rsedit_button_area */
   rsedit_quit_button =
      AlRse_mkbutton("rsedit_quit_button", rsedit_button_area,
		     "Quit", 3, 3, 20, 35, TIMESBOLD14, NULL);
   XtAddCallback(rsedit_quit_button, XtNcallback,
                rsedit_quit_callback, (caddr_t) the_rseditor);

   /* Create Button Widget("Add New Rule After Selected Rule") */
   rsedit_insert_button =
      AlRse_mkbutton("rsedit_insert_button", rsedit_button_area,
		     "Add New Rule",
		     3, 3, 20, 150, TIMESBOLD14,
		     rsedit_quit_button);
   XtAddCallback(rsedit_insert_button, XtNcallback,
                rsedit_insert_callback, (caddr_t) the_rseditor);

   /* Create Button Widget("Edit Selected Rule"), parent= rsedit_button_area */
   rsedit_edit_button =
      AlRse_mkbutton("rsedit_edit_button", rsedit_button_area,
		     "Edit Rule", 3, 3, 20, 126, TIMESBOLD14,
		     rsedit_insert_button);
   XtAddCallback(rsedit_edit_button, XtNcallback,
                rsedit_edit_callback, (caddr_t) the_rseditor);

   /* Create Button Widget("Delete Selected Rule") parent rsedit_button_area */
   rsedit_delete_button =
      AlRse_mkbutton("rsedit_delete_button", rsedit_button_area,
		     "Delete Rule", 3, 3, 20, 142, TIMESBOLD14,
		     rsedit_edit_button);
   XtAddCallback(rsedit_delete_button, XtNcallback,
                rsedit_delete_callback, (caddr_t) the_rseditor);

   /* Create Button Widget("Copy Selected Rule"), parent= rsedit_button_area */
   rsedit_copy_button =
      AlRse_mkbutton("rsedit_copy_button", rsedit_button_area,
		     "Copy Rule", 3, 3, 20, 132, TIMESBOLD14,
		     rsedit_delete_button);
   XtAddCallback(rsedit_copy_button, XtNcallback,
                rsedit_copy_callback, (caddr_t) the_rseditor);

   /* Create Button Widget("Print Rule Set"), parent is rsedit_button_area */
   rsedit_print_button =
      AlRse_mkbutton("rsedit_print_button", rsedit_button_area,
		     "Print Rule Set", 3, 3, 20, 99, TIMESBOLD14,
		     rsedit_copy_button);
   XtAddCallback(rsedit_print_button, XtNcallback,
                rsedit_print_callback, (caddr_t) the_rseditor);

   /* Create Form Widget, whose parent is rsedit_background */
   rsedit_underline =
     AlRse_mkform(the_rseditor, "rsedit_underline", rsedit_background,
	       0, 40, 1, 750 - 33, 1, 1,  /* x, y, h, w, border, inverse */
	       1);     /* retain vertical porportion to parent flag */

   AlRse_create_popup_errbox(the_rseditor);  /* install the error msg popup */

   return(the_rseditor);

 };    /* end of create_rsedit() */

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

AlRSEditor *AlRse_create(shell_widget, ruleset_name, the_ruleset, exit_func)
     Widget shell_widget;
     char *ruleset_name;
     AlRuleSet the_ruleset;
     VOIDP_FUNCPTR exit_func;
 {
   AlRSEditor *the_rseditor;
   int i, j;

   the_rseditor = (AlRSEditor *) Memory_allocate((long) sizeof(AlRSEditor));
   the_rseditor->the_ruleset = the_ruleset;
   the_rseditor->AlRSEdarray = Darray_create();
   AlRuleSet_get_rules(the_rseditor->the_ruleset, the_rseditor->AlRSEdarray);
   the_rseditor->d_len = Darray_len(the_rseditor->AlRSEdarray);
   the_rseditor->ruleset_name = ruleset_name;
/*   the_rseditor->path = NULL; */
   the_rseditor->current_rule_number = -1;
   the_rseditor->current_rulebox_number = -1;
   the_rseditor->top_rule = 1;
   the_rseditor->n_rules_visible = N_VISIBLE_RULES;

   for(i = 0; i < N_VISIBLE_RULES; i++)
     { the_rseditor->text_str[i] = (char *)
	                           Memory_allocate((long) RULE_BUF_LEN);
       AlRse_set_str(the_rseditor->text_str[i], "");
     };

   the_rseditor->shell_widget = shell_widget;
   the_rseditor->exit_function = exit_func;
   create_rsedit(the_rseditor,
		 shell_widget);  /* Hang all widgets off the shell_widget */

   AlRse_redraw(the_rseditor, 1);

   return(the_rseditor);

 };        /* end of AlRse_create()  */

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

void AlRse_destroy(the_rseditor)
   AlRSEditor *the_rseditor;
 {
   XtDestroyWidget(the_rseditor->shell_widget);

   Darray_destroy(the_rseditor->AlRSEdarray);

   Memory_free((VOIDP) the_rseditor);

 };        /* end of AlRse_destroy()  */

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

main(argc, argv)
     int argc;
     char *argv[];
 {
   Widget shell;          /* the top level application shell      */
   AlRSEditor *the_rseditor;
   char *ruleset_name;
   AlRuleSet the_ruleset;
   int n_rs_flag = FALSE;
   Arg arg_list[3];

   /* Initialize a toplevel root shell widget */
   /* --------------------------------------- */
   shell = XtInitialize(argv[0],
		       "Top Level Shell",
		       NULL, 0, &argc, argv);

   /* Allow top level shell resize by child */
   /* ------------------------------------- */
   XtSetArg(arg_list[0], XtNallowShellResize, TRUE);
   XtSetArg(arg_list[1], NULL,  (XtArgVal) NULL);
   XtSetValues(shell, arg_list, 1);

   /* Handle Command Line arguments */
   /* ----------------------------- */

  if ((argc < 2) || (argc > 4))
    { fprintf(stderr, USE_STR);
      exit(1);
    }
  else if ((strcmp(argv[1], "-h") == 0)    /* user requested help */
	   || (strcmp(argv[1], "-help") == 0))
    { fprintf(stderr, USE_STR);
      fprintf(stderr, "Where:    [-h]   gives this help listing.\n");
      fprintf(stderr,
	      "Where:    [-new] specifies new ruleset is to be created.\n\n");
      fprintf(stderr, "Usage-Note:  rsedit -- ruleset\n");
      fprintf(stderr,
      "             Can be used for rulesets whose name begins with a '-'.\n\n"
	      );
      exit(1);
    }
  else if (strcmp(argv[1], "-new") == 0)  /* ruleset is to be created new */
    { ruleset_name = argv[2];
      n_rs_flag = TRUE;
    }
  else if (strcmp(argv[1], "--") == 0)  /* ruleset might have strange name */
    { if (strcmp(argv[2], "-new") == 0)  /* ruleset is to be created new */
	{ if (argc > 3)
	    ruleset_name = argv[3];
	else
	  { fprintf(stderr, USE_STR);
	    Al_fatal_error1(
		  "Missing Rule Set name. Rule set name omitted after: %s\n",
			    argv[2]);
	  };
	  n_rs_flag = TRUE;
	}
    else
      ruleset_name = argv[2];
    }
  else
    ruleset_name = argv[1];


  Al_init();
  
  /* If its a new rule set, call rule editor immediately.               */
  /* Editing an empty rule set wouldn't make sense, & would waste time. */   
  if (n_rs_flag == TRUE)
    re_Editor(NULL, ruleset_name, 0, Bool_TRUE, n_rs_flag);

  if ((the_ruleset = AlRSreg_find (ruleset_name)) == NULL)
    { fprintf(stderr, USE_STR);
      Al_fatal_error1(
		      "Error in Rule Set. Bad rule set name specified: %s\n",
		      ruleset_name);
    };
  


   the_rseditor = AlRse_create(shell, ruleset_name, the_ruleset,
			       (VOIDP_FUNCPTR) AlRse_exit_function);

   XtRealizeWidget(shell);           /* Make all widgets visible */

   XtMainLoop();                     /* Infinite event loop */

 };        /* end of main() */

