#include "rulebrowser.h"
#include "rulebrowserP.h"
#include "hand_icon.h"
#include "menu_icon.h"
#include "deleted_icon.h"
#include "editor_icon.h"
#include "new_icon.h"
#include "empty_icon.h"
#include "xstuff.h"
#include "help.h"
#include "alpop.h"
#include "Mu.h"

#ifdef DEBUG
#define AlRsb_debug(a) a
#else
#define AlRsb_debug(a) 
#endif 

#ifdef DEBUG2
#define AlRsb_debug2(a) a
#else
#define AlRsb_debug2(a) 
#endif 

#define AlRsb_popup_errbox(the_rsbrowser, widget, msg_string) \
          AlPop_Query(ALPOP_ERROR,                /* what kind of pop */  \
                      msg_string,                 /* the message      */  \
                      NULL,                       /* help message     */  \
                      widget,              /* widget to use as parent */  \
                      ALPOP_HANG_BELOW,           /* where to popup   */  \
		      the_rsbrowser->the_display,                         \
		      ALPOP_CANCEL)

#define AlRsb_make_pixmap(the_rsbrowser, parent, bits, width, height) \
           XCreatePixmapFromBitmapData(the_rsbrowser->the_display,  \
                      DefaultRootWindow(the_rsbrowser->the_display), \
                      bits, width, height,  \
		      (Pixel) Alxt_get_widget_feature(parent, XmNforeground), \
                      (Pixel) Alxt_get_widget_feature(parent, XmNbackground), \
                      DefaultDepth(the_rsbrowser->the_display, \
				   the_rsbrowser->the_screen))

#define AlRsb_make_greypixmap(the_rsbrowser, parent, bits, width, height) \
           XCreatePixmapFromBitmapData(the_rsbrowser->the_display,  \
                      DefaultRootWindow(the_rsbrowser->the_display), \
                      bits, width, height,  \
                      (Pixel) Alxt_get_widget_feature(parent,XmNforeground), \
		      (Pixel) Alxt_get_widget_feature(parent,XmNbackground), \
                      DefaultDepth(the_rsbrowser->the_display, \
				   the_rsbrowser->the_screen))

#define UPDOWN_CURSOR  42

/* Msg to ask if user quits w/o saving */
#define ALRSB_NONSAVED_QUIT_MSG   "\
 The rule set has been modified since it was last saved. \n\
 Exit the rulebrowser anyway? "

/* Help msg for above quit w/o save msg */
#define ALRSB_H_NONSAVED_QUIT_MSG "\
 CANCEL = If you click on CANCEL, then you will be returned to the \n\
            rulebrowser and you can then click on \n\
            SAVE (if you wish to save your changes). \n\
 OK     = If you click on OK, then you will exit the rulebrowser \n\
            immediately and the changes you have made since you \n\
            last clicked SAVE will NOT be saved. "


/* Help explanations of the general buttons */
/* ---------------------------------------- */
#define ALRSB_GEN_HELP "\
 APPEND RULE - To create a new rule and locate it as the last rule,\n\
      click on the APPEND RULE button located at the bottom right of\n\
      the Rulebrowser. (To edit that rule, click on its MENU icon button.)\n\
 EXPUNGE - Clicking on this button will visibly remove all the rules marked\n\
      for deletion. Use the MENU icon button, located to the right of every\n\
      rule, to mark a rule for deletion. Expunged rules are not permanently\n\
      removed until a Rulebrowser SAVE is performed.\n\
 PRINT - Clicking on this button will print the ruleset to the printer\n\
      specified by the environment variable PRINTER. (See man page `setenv').\n\
 QUIT - Clicking on this button , located at the bottom left of the\n\
      Rulebrowser, will exit the rulebrowser. All changes, AFTER the\n\
      last SAVE was done, will not be saved. Typically, you will want to\n\
      clicked on SAVE and then on QUIT.\n\
 SAVE - Clicking on this button, located at the bottom left corner of the\n\
      Rulebrowser, will save all changes made to the ruleset in this session."

/* Help explanations of the different icons */
/* ---------------------------------------- */
#define ALRSB_HAND_HELP  "\
 MOVE RULE - This button icon appears to the far left of all rules \n\
      currently being edited by the ruleeditor.\n\
      The user may move the rule to a new position in the ruleset\n\
      by clicking on the hand and dragging the rule\n\
      to the desired new location."

#define ALRSB_DELETED_HELP  "\
 DELETED RULE - This icon appears to the left of all rules currently marked\n\
      for deletion. (If the rule is also marked as being edited by\n\
      the ruleeditor, then this icon may be replaced by the editing icon.)\n\
      The rules which are marked for deletion can be visibly removed by\n\
      by clicking on the EXPUNGE button at the bottom of the Rulebrowser."

#define ALRSB_NEW_HELP  "\
 NEW RULE - This icon appears to the left of all new rules which have just\n\
      recently been added to the ruleset, but have not yet been edited\n\
      by the ruleeditor."

#define ALRSB_EDITOR_HELP  "\
 EDITING RULE - This icon appears to the left of all rules currently being\n\
      edited by the ruleeditor.\n\
      (If the rule is also marked for deletion, this icon may be\n\
      replaced by the marked-for-deletion icon.)"

#define ALRSB_MENU_HELP  "\
 MENU OPTIONS - This button icon appears just to the left of every rule.\n\
      Clicking down on it with the LEFT mouse button (button 1) will\n\
      pop-up a menu of options, which allow the user to:\n\
           Edit that rule\n\
           Copy that rule\n\
           Mark that rule for deletion\n\
           Insert a new rule at the position of that rule in the ruleset\n\
      To select an option, drag the mouse to the desired option and\n\
      release it. To not select any option, move mouse off menu and release."


#define ALRSB_NUM_OF_PIXMAP_NAMES 8

#define AlRsb_get_grey_pixmap(n) \
           AlRsb_grey_pixmap[(((n >= 0) ? n : -n) % ALRSB_NUM_OF_PIXMAP_NAMES)]
   Pixmap AlRsb_grey_pixmap[ALRSB_NUM_OF_PIXMAP_NAMES];

#define AlRsb_grey_width  4
#define AlRsb_grey_height 4
static char AlRsb_grey_bits[ALRSB_NUM_OF_PIXMAP_NAMES][4] = {
  {0x01, 0x00, 0x00, 0x08},    /* 13% grey   */
  {0xf0, 0xf5, 0xf0, 0xf5},    /* 25% grey   */
  {0x0f, 0x01, 0x01, 0x01},    /* 43% grey   */
  {0x05, 0x0a, 0x05, 0x0a},    /* 50% grey   */
  {0xf0, 0xfe, 0xfe, 0xfe},    /* 56% grey   */
  {0xfa, 0xff, 0xfa, 0xff},    /* 75% grey   */
  {0xfe, 0xff, 0xff, 0xf7},    /* 88% grey   */
  {0xff, 0xff, 0xff, 0xff}};   /* 100% black */

#define AlRsb_get_pixmap_name(n) \
           AlRsb_pixmap_name[(((n > 0) ? n : -n) % ALRSB_NUM_OF_PIXMAP_NAMES)]

   char *AlRsb_pixmap_name[ALRSB_NUM_OF_PIXMAP_NAMES] =
         {"25_foreground",
          "50_foreground",
	  "75_foreground",
	  "horizontal",
	  "vertical",
          "slant_right",
          "slant_left",
	  NULL};

   char *notes[5] =
         {"The first non-switch argument is assumed to be the ruleset name.",
          "If a ruleset name begins with a dash ('-'), then it may be",
	  "specified by using the \"-RS\" switch. For example a ruleset",
	  "named \"-temp-\" could be browsed with \"rulebrowser -RS-temp- \".",
	  NULL};
   char *examples[4] = {"rulebrowser archiverules",
                        "rulebrowser -RSarchiverules",
			"rulebrowser -force newruleset",
			NULL};

#define AlRsb_add_number_of_open_ruleeditors(the_rsbrowser, n) \
            the_rsbrowser->number_of_open_ruleeditors = \
               (the_rsbrowser->number_of_open_ruleeditors + n) % 99999;
               /* the above "% 99999" is just to prevent integer overflows */
               /* this running sum of editors opened is only used for      */
               /* calling "AlRsb_get_grey_pixmap", anyway. (To set gid).   */

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

struct _AlRsb_callback *AlRsb_create_callback_struct(the_rsbrowser, 
						     rule_link, menu)
     AlRSBrowser *the_rsbrowser;
     AlRuleLink *rule_link;
     Widget menu;
 {
   struct _AlRsb_callback *callback_struct;

   callback_struct = (struct _AlRsb_callback *)
                          Memory_allocate(sizeof(struct _AlRsb_callback));
   callback_struct->rule_link = rule_link;
   callback_struct->the_rsbrowser = the_rsbrowser;
   callback_struct->menu = menu;
   callback_struct->button = NULL;

   return(callback_struct);

 };         /* end of AlRsb_create_callback_struct()  */


int AlRsb_get_number_of_open_ruleeditors(the_rsbrowser)
     AlRSBrowser *the_rsbrowser;

 { return(the_rsbrowser->number_of_open_ruleeditors);
 };        /* end of AlRsb_get_number_of_open_ruleeditors()  */


Widget AlRsb_attach_pixmap_help(the_rsbrowser, help_shell, top_widget,
				the_pixmap, explanation_str, border_flag)
     AlRSBrowser *the_rsbrowser;
     Widget help_shell;
     Widget top_widget;
     Pixmap the_pixmap;
     char *explanation_str;
     int border_flag;
 { ArgPack gen_argp;
   Widget help_popup;
   Widget icon_widget, icon_explanation;

  /* Create a single help form */
  /* ------------------------- */
  gen_argp = ArgPack_create();
  ArgPack_add_arg(gen_argp, XmNleftAttachment, (XtArgVal) XmATTACH_FORM);
  ArgPack_add_arg(gen_argp, XmNleftOffset, (XtArgVal) 0);
  ArgPack_add_arg(gen_argp, XmNrightAttachment, (XtArgVal) XmATTACH_FORM);
  ArgPack_add_arg(gen_argp, XmNrightOffset, (XtArgVal) 0);
  if (top_widget == NULL)
    ArgPack_add_arg(gen_argp, XmNtopAttachment, (XtArgVal) XmATTACH_FORM);
  else
    { ArgPack_add_arg(gen_argp, XmNtopAttachment, (XtArgVal) XmATTACH_WIDGET);
      ArgPack_add_arg(gen_argp, XmNtopWidget, (XtArgVal) top_widget);
    };
  ArgPack_add_arg(gen_argp, XmNtopOffset, (XtArgVal) 150);
  ArgPack_add_arg(gen_argp, XmNbottomAttachment, (XtArgVal) XmATTACH_NONE);
  ArgPack_add_arg(gen_argp, XmNborderWidth, (XtArgVal) 0);
  ArgPack_add_arg(gen_argp, XmNresizable, (XtArgVal) True);
  ArgPack_add_arg(gen_argp, XmNresizePolicy, (XtArgVal) XmRESIZE_ANY);
  help_popup = XmCreateForm(help_shell, "help-form", 
			   ArgPack_the_args(gen_argp),
			   ArgPack_num_args(gen_argp));
  ArgPack_delete(gen_argp);
  
  /* Show the icon to be explanated */
  /* ------------------------------ */
  gen_argp = ArgPack_create();
  ArgPack_add_arg(gen_argp, XmNunitType, (XtArgVal) Xm100TH_MILLIMETERS);
  if (border_flag == TRUE)
    { ArgPack_add_arg(gen_argp, XmNborderWidth, (XtArgVal) 50);
      ArgPack_add_arg(gen_argp, XmNshadowThickness, (XtArgVal) 100);
    }
   else
    { ArgPack_add_arg(gen_argp, XmNborderWidth, (XtArgVal) 0);
      ArgPack_add_arg(gen_argp, XmNshadowThickness, (XtArgVal) 0);
    };
  ArgPack_add_arg(gen_argp, XmNlabelType, (XtArgVal) XmPIXMAP);
  ArgPack_add_arg(gen_argp, XmNwidth, (XtArgVal) editor_icon_width);
  ArgPack_add_arg(gen_argp, XmNheight, (XtArgVal) editor_icon_height);
  ArgPack_add_arg(gen_argp, XmNlabelPixmap, (XtArgVal) the_pixmap);
  ArgPack_add_arg(gen_argp, XmNleftAttachment, (XtArgVal) XmATTACH_FORM);
  ArgPack_add_arg(gen_argp, XmNleftOffset, (XtArgVal) 150);
  ArgPack_add_arg(gen_argp, XmNrightAttachment, (XtArgVal) XmATTACH_NONE);
  ArgPack_add_arg(gen_argp, XmNtopAttachment, (XtArgVal) XmATTACH_FORM);
  ArgPack_add_arg(gen_argp, XmNtopOffset, (XtArgVal) 10);
  ArgPack_add_arg(gen_argp, XmNbottomAttachment, (XtArgVal) XmATTACH_NONE);
  ArgPack_add_arg(gen_argp, XmNborderWidth, (XtArgVal) 0);
  ArgPack_add_arg(gen_argp, XmNresizable, (XtArgVal) True);
  ArgPack_add_arg(gen_argp, XmNresizePolicy, (XtArgVal) XmRESIZE_ANY);
  icon_widget = XmCreateLabel(help_popup, "icon",
			     ArgPack_the_args(gen_argp),
			     ArgPack_num_args(gen_argp));
  ArgPack_delete(gen_argp);  

  /* Show the icon's explanation */
  /* --------------------------- */
  gen_argp = ArgPack_create();
  ArgPack_add_arg(gen_argp, XmNunitType, (XtArgVal) Xm100TH_MILLIMETERS);
  ArgPack_add_arg(gen_argp, XmNlabelType, (XtArgVal) XmSTRING);
  ArgPack_add_arg(gen_argp, XmNwidth, (XtArgVal) editor_icon_width);
  ArgPack_add_arg(gen_argp, XmNheight, (XtArgVal) editor_icon_height);
  ArgPack_add_arg(gen_argp, XmNborderWidth, (XtArgVal) 0);
  ArgPack_add_arg(gen_argp, XmNleftAttachment, (XtArgVal) XmATTACH_WIDGET);
  ArgPack_add_arg(gen_argp, XmNleftWidget, (XtArgVal) icon_widget);
  ArgPack_add_arg(gen_argp, XmNleftOffset, (XtArgVal) 150);
  ArgPack_add_arg(gen_argp, XmNrightAttachment, (XtArgVal) XmATTACH_NONE);
  ArgPack_add_arg(gen_argp, XmNtopAttachment, (XtArgVal) XmATTACH_NONE);
  ArgPack_add_arg(gen_argp, XmNtopOffset, (XtArgVal) 150);
  ArgPack_add_arg(gen_argp, XmNbottomAttachment, (XtArgVal) XmATTACH_NONE);
  ArgPack_add_arg(gen_argp, XmNalignment, (XtArgVal) XmALIGNMENT_BEGINNING);
  ArgPack_add_arg(gen_argp, XmNfontList, (XtArgVal) (the_rsbrowser->fonts));
  ArgPack_add_arg(gen_argp, XmNlabelString, 
	     (XtArgVal) XmStringLtoRCreate(explanation_str, ALFONTS_BUTTONS));
  ArgPack_add_arg(gen_argp, XmNrecomputeSize, (XtArgVal) True);
  ArgPack_add_arg(gen_argp, XmNresizable, (XtArgVal) True);
  ArgPack_add_arg(gen_argp, XmNresizePolicy, (XtArgVal) XmRESIZE_ANY);
  icon_explanation = XmCreateLabel(help_popup, "icon-explanation",
			     ArgPack_the_args(gen_argp),
			     ArgPack_num_args(gen_argp));
  ArgPack_delete(gen_argp); 
 
  XtManageChild(icon_widget);
  XtManageChild(icon_explanation);
  XtManageChild(help_popup);

  return(help_popup);

 };        /* end of AlRsb_attach_pixmap_help()  */


NORET AlRsb_help_attach(the_rsbrowser, help_button)
     AlRSBrowser *the_rsbrowser;
     Widget help_button;
 { Widget help_popup, title, gen_explanation, returnB;
   Widget hand_widget, deleted_widget, new_widget, editor_widget, menu_widget;
   ArgPack gen_argp;
   ArgPack argp;
   struct _AlRsb_callback *callback_struct;
   void AlRsb_popup_help(), AlRsb_popdown_help();

   /* Create main widgets for popup menu */
   /* ---------------------------------- */
   argp     = ArgPack_create();
   ArgPack_add_arg(argp, XmNborderWidth, (XtArgVal) 50);
   ArgPack_add_arg(argp, XmNshadowThickness, (XtArgVal) 100);
   ArgPack_add_arg(argp, XmNshellUnitType, (XtArgVal) Xm100TH_MILLIMETERS);
   ArgPack_add_arg(argp, XmNunitType, (XtArgVal) Xm100TH_MILLIMETERS);
   ArgPack_add_arg(argp, XmNwidth, (XtArgVal) 19000);   /* 17000 */
   ArgPack_add_arg(argp, XmNrecomputeSize, (XtArgVal) True);
   ArgPack_add_arg(argp, XmNresizable, (XtArgVal) True);
   ArgPack_add_arg(argp, XmNresizePolicy, (XtArgVal) XmRESIZE_ANY);
   help_popup = XmCreateFormDialog(help_button, "popup-menu", 
				  ArgPack_the_args(argp),
				  ArgPack_num_args(argp));
   ArgPack_delete(argp);
   
   callback_struct = AlRsb_create_callback_struct(the_rsbrowser,
						  NULL, help_popup);

  /* Title */
  /* ----- */
  gen_argp = ArgPack_create();
  ArgPack_add_arg(gen_argp, XmNunitType, (XtArgVal) Xm100TH_MILLIMETERS);
  ArgPack_add_arg(gen_argp, XmNlabelType, (XtArgVal) XmSTRING);
  ArgPack_add_arg(gen_argp, XmNborderWidth, (XtArgVal) 0);
  ArgPack_add_arg(gen_argp, XmNwidth, (XtArgVal) 17000);
  ArgPack_add_arg(gen_argp, XmNleftAttachment, (XtArgVal) XmATTACH_FORM);
  ArgPack_add_arg(gen_argp, XmNleftOffset, (XtArgVal) 150);
  ArgPack_add_arg(gen_argp, XmNrightAttachment, (XtArgVal) XmATTACH_FORM);
  ArgPack_add_arg(gen_argp, XmNtopAttachment, (XtArgVal) XmATTACH_FORM);
  ArgPack_add_arg(gen_argp, XmNtopOffset, (XtArgVal) 150);
  ArgPack_add_arg(gen_argp, XmNbottomAttachment, (XtArgVal) XmATTACH_NONE);
  ArgPack_add_arg(gen_argp, XmNalignment, (XtArgVal) XmALIGNMENT_BEGINNING);
  ArgPack_add_arg(gen_argp, XmNfontList, (XtArgVal) (the_rsbrowser->fonts));
  ArgPack_add_arg(gen_argp, XmNlabelString, 
		  (XtArgVal)XmStringCreate("Help for the Rule Set Browser",
					   ALFONTS_MINOR_HEADING));
  ArgPack_add_arg(gen_argp, XmNrecomputeSize, (XtArgVal) True);
  ArgPack_add_arg(gen_argp, XmNresizable, (XtArgVal) True);
  ArgPack_add_arg(gen_argp, XmNresizePolicy, (XtArgVal) XmRESIZE_ANY);
  title = XmCreateLabel(help_popup, "help-title",
			     ArgPack_the_args(gen_argp),
			     ArgPack_num_args(gen_argp));
  ArgPack_delete(gen_argp); 
 

  /* Show the general button explanations */
  /* ------------------------------------ */
  gen_argp = ArgPack_create();
  ArgPack_add_arg(gen_argp, XmNunitType, (XtArgVal) Xm100TH_MILLIMETERS);
  ArgPack_add_arg(gen_argp, XmNlabelType, (XtArgVal) XmSTRING);
  ArgPack_add_arg(gen_argp, XmNwidth, (XtArgVal) editor_icon_width);
  ArgPack_add_arg(gen_argp, XmNheight, (XtArgVal) editor_icon_height);
  ArgPack_add_arg(gen_argp, XmNborderWidth, (XtArgVal) 0);
  ArgPack_add_arg(gen_argp, XmNleftAttachment, (XtArgVal) XmATTACH_FORM);
  ArgPack_add_arg(gen_argp, XmNleftOffset, (XtArgVal) 150);
  ArgPack_add_arg(gen_argp, XmNrightAttachment, (XtArgVal) XmATTACH_FORM);
  ArgPack_add_arg(gen_argp, XmNrightOffset, (XtArgVal) 150);
  ArgPack_add_arg(gen_argp, XmNtopAttachment, (XtArgVal) XmATTACH_WIDGET);
  ArgPack_add_arg(gen_argp, XmNtopWidget, (XtArgVal) title);
  ArgPack_add_arg(gen_argp, XmNtopOffset, (XtArgVal) 150);
  ArgPack_add_arg(gen_argp, XmNbottomAttachment, (XtArgVal) XmATTACH_NONE);
  ArgPack_add_arg(gen_argp, XmNalignment, (XtArgVal) XmALIGNMENT_BEGINNING);
  ArgPack_add_arg(gen_argp, XmNfontList, (XtArgVal) (the_rsbrowser->fonts));
  ArgPack_add_arg(gen_argp, XmNlabelString, 
	     (XtArgVal) XmStringLtoRCreate(ALRSB_GEN_HELP, ALFONTS_BUTTONS));
  ArgPack_add_arg(gen_argp, XmNrecomputeSize, (XtArgVal) True);
  ArgPack_add_arg(gen_argp, XmNresizable, (XtArgVal) True);
  ArgPack_add_arg(gen_argp, XmNresizePolicy, (XtArgVal) XmRESIZE_ANY);
  gen_explanation = XmCreateLabel(help_popup, "general-explanation",
			     ArgPack_the_args(gen_argp),
			     ArgPack_num_args(gen_argp));
  ArgPack_delete(gen_argp); 

   /* Create all Pixmap/Icon explanations */
   /* ----------------------------------- */
   hand_widget = AlRsb_attach_pixmap_help(the_rsbrowser, help_popup,
				   gen_explanation,
				   the_rsbrowser->hand_icon,
				   ALRSB_HAND_HELP, TRUE);
   menu_widget = AlRsb_attach_pixmap_help(the_rsbrowser, help_popup,
				   hand_widget, the_rsbrowser->menu_icon,
				   ALRSB_MENU_HELP, TRUE);
   deleted_widget = AlRsb_attach_pixmap_help(the_rsbrowser, help_popup,
				   menu_widget,  
				   the_rsbrowser->deleted_icon,
				   ALRSB_DELETED_HELP, FALSE);
   new_widget = AlRsb_attach_pixmap_help(the_rsbrowser, help_popup,
				   deleted_widget, the_rsbrowser->new_icon,
				   ALRSB_NEW_HELP, FALSE);
   editor_widget = AlRsb_attach_pixmap_help(the_rsbrowser, help_popup,
				   new_widget, the_rsbrowser->editor_icon,
				   ALRSB_EDITOR_HELP, FALSE);

   /* Create Exit Button for popup help */
   /* --------------------------------- */
   gen_argp = ArgPack_create();
   ArgPack_add_arg(gen_argp, XmNunitType, (XtArgVal) Xm100TH_MILLIMETERS);
   ArgPack_add_arg(gen_argp, XmNwidth, (XtArgVal) 16700);
   ArgPack_add_arg(gen_argp, XmNshadowThickness, (XtArgVal) 150);
   ArgPack_add_arg(gen_argp, XmNlabelString,
		 (XtArgVal) XmStringCreate("OK", ALFONTS_BUTTONS));
   ArgPack_add_arg(gen_argp, XmNleftAttachment, (XtArgVal) XmATTACH_FORM);
   ArgPack_add_arg(gen_argp, XmNleftOffset, (XtArgVal) 150);
   ArgPack_add_arg(gen_argp, XmNrightAttachment, (XtArgVal) XmATTACH_FORM);
   ArgPack_add_arg(gen_argp, XmNrightOffset, (XtArgVal) 150);
   ArgPack_add_arg(gen_argp, XmNtopAttachment, (XtArgVal) XmATTACH_WIDGET);
   ArgPack_add_arg(gen_argp, XmNtopWidget, (XtArgVal) editor_widget);
   ArgPack_add_arg(gen_argp, XmNtopOffset, (XtArgVal) 200);
   ArgPack_add_arg(gen_argp, XmNbottomAttachment, (XtArgVal) XmATTACH_NONE);
   ArgPack_add_arg(gen_argp, XmNbottomOffset, (XtArgVal) 150);
   ArgPack_add_arg(gen_argp, XmNrecomputeSize, (XtArgVal) True);
   ArgPack_add_arg(gen_argp, XmNresizable, (XtArgVal) True);
   ArgPack_add_arg(gen_argp, XmNresizePolicy, (XtArgVal) XmRESIZE_ANY);
   returnB = XmCreatePushButton(help_popup, "OK-button",
			      ArgPack_the_args(gen_argp),
			      ArgPack_num_args(gen_argp));
   ArgPack_delete(gen_argp);
   XtAddCallback(returnB, XmNactivateCallback, 
		 AlRsb_popdown_help, (caddr_t) callback_struct);

   XtAddCallback(help_button, XmNactivateCallback, 
		 AlRsb_popup_help, (caddr_t) callback_struct);

   /* Manage all the children */
   /* ----------------------- */
   XtManageChild(title);
   XtManageChild(gen_explanation);
   XtManageChild(returnB);

 };     /* end of AlRsb_help_attach()  */


NORET AlRsb_menu_attach(the_rsbrowser, rule_link, menu_button, name)
     AlRSBrowser *the_rsbrowser;
     AlRuleLink *rule_link;
     Widget menu_button;
     char *name;
 { Widget menu_popup, editB, deleteB, copyB, insertB;
   ArgPack gen_argp;
   ArgPack argp;
   struct _AlRsb_callback *callback_struct;
   void AlRsb_insert_callback(), AlRsb_edit_callback();
   void AlRsb_copy_callback(), AlRsb_delete_callback(), AlRsb_popup_menu();

   gen_argp = ArgPack_create();
   gen_argp = ArgPack_duplicate_args(gen_button_res);

   /* Create main widgets for popup menu */
   /* ---------------------------------- */
   argp     = ArgPack_create();
   ArgPack_add_arg(argp, XmNorientation, (XtArgVal) XmVERTICAL);
   ArgPack_add_arg(argp, XmNshellUnitType, (XtArgVal) Xm100TH_MILLIMETERS);
   ArgPack_add_arg(argp, XmNwhichButton, (XtArgVal) 1); 
   menu_popup = XmCreatePopupMenu(menu_button, "popup-menu", 
				  ArgPack_the_args(argp),
				  ArgPack_num_args(argp));
   ArgPack_delete(argp);
   
   callback_struct = AlRsb_create_callback_struct(the_rsbrowser,
						  rule_link, menu_popup);

   /* Create Edit Button for popup menu */
   /* --------------------------------- */
   argp     = ArgPack_create();
   argp = ArgPack_copy_and_append(argp, gen_argp);

   ArgPack_add_arg(argp, XmNlabelString,
		 (XtArgVal) XmStringCreate("Edit this Rule", ALFONTS_BUTTONS));
   editB = XmCreatePushButton(menu_popup, "edit-button",
			      ArgPack_the_args(argp),
			      ArgPack_num_args(argp));
   ArgPack_delete(argp);
   XtAddCallback(editB, XmNactivateCallback, 
		 AlRsb_edit_callback, (caddr_t) callback_struct);

   /* Create Copy Button for popup menu */
   /* --------------------------------- */
   argp     = ArgPack_create();
   argp = ArgPack_copy_and_append(argp, gen_argp);

   ArgPack_add_arg(argp, XmNlabelString,
		 (XtArgVal) XmStringCreate("Copy this Rule", ALFONTS_BUTTONS));
   copyB = XmCreatePushButton(menu_popup, "copy-button",
			      ArgPack_the_args(argp),
			      ArgPack_num_args(argp));
   ArgPack_delete(argp);
   XtAddCallback(copyB, XmNactivateCallback, 
		 AlRsb_copy_callback, (caddr_t) callback_struct);

   /* Create Delete Button for popup menu */
   /* ----------------------------------- */
   argp     = ArgPack_create();
   argp = ArgPack_copy_and_append(argp, gen_argp);

   ArgPack_add_arg(argp, XmNlabelString,
		 (XtArgVal) XmStringCreate("Mark to Delete", ALFONTS_BUTTONS));
   deleteB = XmCreatePushButton(menu_popup, "delete-button",
			      ArgPack_the_args(argp),
			      ArgPack_num_args(argp));
   ArgPack_delete(argp);
   XtAddCallback(deleteB, XmNactivateCallback, 
		 AlRsb_delete_callback, (caddr_t) callback_struct);

   /* Create Edit Button for popup menu */
   /* --------------------------------- */
   argp     = ArgPack_create();
   argp = ArgPack_copy_and_append(argp, gen_argp);

   ArgPack_add_arg(argp, XmNlabelString,
		(XtArgVal) XmStringCreate("Insert New Rule", ALFONTS_BUTTONS));
   insertB = XmCreatePushButton(menu_popup, "insert-button",
			      ArgPack_the_args(argp),
			      ArgPack_num_args(argp));
   ArgPack_delete(argp);
   XtAddCallback(insertB, XmNactivateCallback, 
		 AlRsb_insert_callback, (caddr_t) callback_struct);

   /* Manage all children */
   /* ------------------- */
   XtManageChild(editB);
   XtManageChild(copyB);
   XtManageChild(deleteB);
   XtManageChild(insertB);

   ArgPack_delete(gen_argp);

  /* To get around a bug in Motif which causes "whichbutton 1" not to work, */
  /* invoke an Action instead of a Callback when pressing the menu button.  */
  /* ---------------------------------------------------------------------- */
  gen_argp = ArgPack_create();
  ArgPack_add_arg(gen_argp, XmNuserData, (XtArgVal) callback_struct);
  XtSetValues(menu_button, 
	       ArgPack_the_args(gen_argp), ArgPack_num_args(gen_argp));
  ArgPack_delete(gen_argp);
  XtOverrideTranslations(menu_button,
    XtParseTranslationTable("<Btn1Down>: AlRsb_menu_action()"));

 };     /* end of AlRsb_menu_attach()  */


NORET AlRsb_mkrulebox(the_rsbrowser, rule_link, text)
     AlRSBrowser *the_rsbrowser;
     AlRuleLink *rule_link;
     char        *text;
 {
  Widget main_rulebox_form, rule_scroller, rule_scroll_form;
  Widget hand_button, editor_flag, menu_button;
  struct _AlRsb_callback *callback_struct;
  ArgPack gen_argp;
  char str[8];

  if (rule_link == NULL)
    { fprintf(stderr, " In AlRsb_mkrulebox: (rule_link == NULL)\n");
      return;
    };

  main_rulebox_form = the_rsbrowser->rulebox_form;

  /* Create a single rule_box's form */
  /* ------------------------------- */
  gen_argp = ArgPack_create();
  gen_argp = ArgPack_duplicate_args(rule_working_area_res);

  ArgPack_add_arg(gen_argp, XmNtopOffset, (XtArgVal) rule_link->y_position);
  ArgPack_add_arg(gen_argp, XmNy, (XtArgVal) rule_link->y_position);

  rule_link->rule_box = XmCreateForm(main_rulebox_form, "rule-box", 
			   ArgPack_the_args(gen_argp),
			   ArgPack_num_args(gen_argp));
  ArgPack_delete(gen_argp);
  
  /* Create the Pixmaps for rule browser, if not already loaded */
  /* ---------------------------------------------------------- */
  if (the_rsbrowser->hand_icon == NULL)
    the_rsbrowser->hand_icon = AlRsb_make_pixmap(the_rsbrowser,
						 rule_link->rule_box,
						 hand_icon_bits,
						 hand_icon_width, 
						 hand_icon_height);
  if (the_rsbrowser->deleted_icon == NULL)
    the_rsbrowser->deleted_icon = AlRsb_make_pixmap(the_rsbrowser,
						 rule_link->rule_box,
						 deleted_icon_bits,
						 deleted_icon_width, 
						 deleted_icon_height);
  if (the_rsbrowser->menu_icon == NULL)
    the_rsbrowser->menu_icon = AlRsb_make_pixmap(the_rsbrowser,
						 rule_link->rule_box,
						 menu_icon_bits,
						 menu_icon_width, 
						 menu_icon_height);
  if (the_rsbrowser->editor_icon == NULL)
    the_rsbrowser->editor_icon = AlRsb_make_pixmap(the_rsbrowser,
						 rule_link->rule_box,
						 editor_icon_bits,
						 editor_icon_width, 
						 editor_icon_height);
  if (the_rsbrowser->new_icon == NULL)
    the_rsbrowser->new_icon = AlRsb_make_pixmap(the_rsbrowser,
						 rule_link->rule_box,
						 new_icon_bits,
						 new_icon_width, 
						 new_icon_height);
  if (the_rsbrowser->empty_icon == NULL)
    the_rsbrowser->empty_icon = AlRsb_make_pixmap(the_rsbrowser,
						 rule_link->rule_box,
						 empty_icon_bits,
						 empty_icon_width, 
						 empty_icon_height);

  /* Create the rule number label for the rule_box */
  /* --------------------------------------------- */
  sprintf(str, "%d", (1 + rule_link->rule_number));
  gen_argp = ArgPack_create();
  ArgPack_add_arg(gen_argp, XmNlabelType, (XtArgVal) XmSTRING);
  ArgPack_add_arg(gen_argp, XmNwidth, (XtArgVal) hand_icon_width);
  ArgPack_add_arg(gen_argp, XmNheight, (XtArgVal) hand_icon_height);
  ArgPack_add_arg(gen_argp, XmNborderWidth, (XtArgVal) 0);
  ArgPack_add_arg(gen_argp, XmNleftAttachment, (XtArgVal) XmATTACH_FORM);
  ArgPack_add_arg(gen_argp, XmNleftOffset, (XtArgVal) 150);
  ArgPack_add_arg(gen_argp, XmNrightAttachment, (XtArgVal) XmATTACH_NONE);
  ArgPack_add_arg(gen_argp, XmNtopAttachment, (XtArgVal) XmATTACH_FORM);
  ArgPack_add_arg(gen_argp, XmNtopOffset, (XtArgVal) 10);
  ArgPack_add_arg(gen_argp, XmNbottomAttachment, (XtArgVal) XmATTACH_NONE);
  ArgPack_add_arg(gen_argp, XmNalignment, (XtArgVal) XmALIGNMENT_BEGINNING);
  ArgPack_add_arg(gen_argp, XmNfontList, (XtArgVal) (the_rsbrowser->fonts));

  ArgPack_add_arg(gen_argp, XmNlabelString, 
		  (XtArgVal)XmStringCreate(str, ALFONTS_BUTTONS));

  ArgPack_add_arg(gen_argp, XmNrecomputeSize, (XtArgVal) True); 
  ArgPack_add_arg(gen_argp, XmNresizable, (XtArgVal) True);
  ArgPack_add_arg(gen_argp, XmNresizePolicy, (XtArgVal) XmRESIZE_ANY);
  rule_link->num_label = XmCreateLabel(rule_link->rule_box, "num-label",
			     ArgPack_the_args(gen_argp),
			     ArgPack_num_args(gen_argp));
  ArgPack_delete(gen_argp);

  /* Create the hand (Move) button for the rule_box */
  /* ---------------------------------------------- */
  gen_argp = ArgPack_create();
  ArgPack_add_arg(gen_argp, XmNlabelType, (XtArgVal) XmPIXMAP);
  ArgPack_add_arg(gen_argp, XmNwidth, (XtArgVal) hand_icon_width);
  ArgPack_add_arg(gen_argp, XmNheight, (XtArgVal) hand_icon_height);
  ArgPack_add_arg(gen_argp, XmNlabelPixmap,
		  (XtArgVal) the_rsbrowser->hand_icon);
  ArgPack_add_arg(gen_argp, XmNarmPixmap,
		  (XtArgVal) the_rsbrowser->hand_icon);
  ArgPack_add_arg(gen_argp, XmNborderWidth, (XtArgVal) 0);
  ArgPack_add_arg(gen_argp, XmNleftAttachment, (XtArgVal) XmATTACH_FORM);
  ArgPack_add_arg(gen_argp, XmNleftOffset, (XtArgVal) 150);
  ArgPack_add_arg(gen_argp, XmNtopAttachment, (XtArgVal) XmATTACH_WIDGET);
  ArgPack_add_arg(gen_argp, XmNtopWidget, (XtArgVal) rule_link->num_label);
  ArgPack_add_arg(gen_argp, XmNtopOffset, (XtArgVal) 0);
  ArgPack_add_arg(gen_argp, XmNrightAttachment, (XtArgVal) XmATTACH_NONE);
  ArgPack_add_arg(gen_argp, XmNbottomAttachment, (XtArgVal) XmATTACH_FORM);
  ArgPack_add_arg(gen_argp, XmNresizable, (XtArgVal) True);
  ArgPack_add_arg(gen_argp, XmNresizePolicy, (XtArgVal) XmRESIZE_ANY);
  hand_button = XmCreatePushButton(rule_link->rule_box, "hand-button", 
			     ArgPack_the_args(gen_argp),
			     ArgPack_num_args(gen_argp));
  rule_link->hand_button = hand_button;
  ArgPack_delete(gen_argp);
  callback_struct = AlRsb_create_callback_struct(the_rsbrowser, 
						 rule_link, hand_button);
  /* To get around a bug in Motif which causes "whichbutton 1" not to work, */
  /* invoke an Action instead of a Callback when pressing the hand button.  */
  /* ---------------------------------------------------------------------- */
  gen_argp = ArgPack_create();
  ArgPack_add_arg(gen_argp, XmNuserData, (XtArgVal) callback_struct);
  XtSetValues(hand_button, 
	       ArgPack_the_args(gen_argp), ArgPack_num_args(gen_argp));
  ArgPack_delete(gen_argp);
  XtOverrideTranslations(hand_button,
    XtParseTranslationTable("<Btn1Down>: AlRsb_hand_grab()"));
  
  /* Create the rule's editor_icon flag for the rule_box */
  /* --------------------------------------------------- */
  gen_argp = ArgPack_create();
  ArgPack_add_arg(gen_argp, XmNlabelType, (XtArgVal) XmPIXMAP);
  ArgPack_add_arg(gen_argp, XmNwidth, (XtArgVal) editor_icon_width);
  ArgPack_add_arg(gen_argp, XmNheight, (XtArgVal) editor_icon_height);
  ArgPack_add_arg(gen_argp, XmNlabelPixmap,
		  (XtArgVal) the_rsbrowser->empty_icon);
  ArgPack_add_arg(gen_argp, XmNborderWidth, (XtArgVal) 0);
  ArgPack_add_arg(gen_argp, XmNleftAttachment, (XtArgVal) XmATTACH_WIDGET);
  ArgPack_add_arg(gen_argp, XmNleftWidget, (XtArgVal) hand_button);
  ArgPack_add_arg(gen_argp, XmNleftOffset, (XtArgVal) 150);
  ArgPack_add_arg(gen_argp, XmNrightAttachment, (XtArgVal) XmATTACH_NONE);
  ArgPack_add_arg(gen_argp, XmNtopAttachment, (XtArgVal) XmATTACH_NONE);
  ArgPack_add_arg(gen_argp, XmNbottomAttachment, (XtArgVal) XmATTACH_FORM);
  ArgPack_add_arg(gen_argp, XmNalignment, (XtArgVal) XmALIGNMENT_CENTER); 
  ArgPack_add_arg(gen_argp, XmNfontList, (XtArgVal) (the_rsbrowser->fonts));

  ArgPack_add_arg(gen_argp, XmNlabelString, 
		  (XtArgVal)XmStringCreate(str,
					   ALFONTS_MINOR_HEADING));
  ArgPack_add_arg(gen_argp, XmNresizable, (XtArgVal) True);
  ArgPack_add_arg(gen_argp, XmNresizePolicy, (XtArgVal) XmRESIZE_ANY);
  editor_flag = XmCreateLabel(rule_link->rule_box, "editor-icon",
			     ArgPack_the_args(gen_argp),
			     ArgPack_num_args(gen_argp));
  rule_link->state_label = editor_flag;
  ArgPack_delete(gen_argp);  

  /* Create the rule's menu_icon flag for the rule_box */
  /* ------------------------------------------------- */
  sprintf(str, " \0");
  gen_argp = ArgPack_create();
  ArgPack_add_arg(gen_argp, XmNborderWidth, (XtArgVal) 0);
  ArgPack_add_arg(gen_argp, XmNleftAttachment, (XtArgVal) XmATTACH_WIDGET);
  ArgPack_add_arg(gen_argp, XmNleftWidget, (XtArgVal) editor_flag);
  ArgPack_add_arg(gen_argp, XmNleftOffset, (XtArgVal) 150);
  ArgPack_add_arg(gen_argp, XmNrightAttachment, (XtArgVal) XmATTACH_NONE);
  ArgPack_add_arg(gen_argp, XmNtopAttachment, (XtArgVal) XmATTACH_NONE);
  ArgPack_add_arg(gen_argp, XmNbottomAttachment, (XtArgVal) XmATTACH_FORM);
  ArgPack_add_arg(gen_argp, XmNisAligned, (XtArgVal) False);
  ArgPack_add_arg(gen_argp, XmNalignment, (XtArgVal) XmALIGNMENT_BEGINNING); 
  ArgPack_add_arg(gen_argp, XmNfontList, (XtArgVal) (the_rsbrowser->fonts));
  ArgPack_add_arg(gen_argp, XmNlabelString, 
		  (XtArgVal)XmStringCreate(str,
					   ALFONTS_MINOR_HEADING));
  ArgPack_add_arg(gen_argp, XmNlabelType, (XtArgVal) XmPIXMAP);
  ArgPack_add_arg(gen_argp, XmNwidth, (XtArgVal) menu_icon_width);
  ArgPack_add_arg(gen_argp, XmNheight, (XtArgVal) menu_icon_height);
  ArgPack_add_arg(gen_argp, XmNarmPixmap,
		  (XtArgVal) the_rsbrowser->menu_icon);
  ArgPack_add_arg(gen_argp, XmNlabelPixmap,
		  (XtArgVal) the_rsbrowser->menu_icon);
  ArgPack_add_arg(gen_argp, XmNresizable, (XtArgVal) FALSE);
  ArgPack_add_arg(gen_argp, XmNresizePolicy, (XtArgVal) XmRESIZE_NONE);
  menu_button = XmCreatePushButton(rule_link->rule_box, "menu-icon",
			     ArgPack_the_args(gen_argp),
			     ArgPack_num_args(gen_argp));
  ArgPack_delete(gen_argp);

  /* Add a Pop-Up Menu to the menu button */
  /* ------------------------------------ */
  AlRsb_menu_attach(the_rsbrowser, rule_link, menu_button, "popup-menu");

  /* Create the scrolled region for text widget */
  /* ------------------------------------------ */
   gen_argp = ArgPack_create();
   ArgPack_add_arg(gen_argp, XmNborderWidth, (XtArgVal) 0);
   ArgPack_add_arg(gen_argp, XmNshadowThickness, (XtArgVal) 100); /* 100 */
   ArgPack_add_arg(gen_argp, XmNscrollingPolicy, (XtArgVal) XmAUTOMATIC);
   ArgPack_add_arg(gen_argp, XmNscrollBarPlacement, (XtArgVal) XmTOP_LEFT);
   ArgPack_add_arg(gen_argp, XmNupdateSliderSize, (XtArgVal) TRUE);
   ArgPack_add_arg(gen_argp, XmNspacing, (XtArgVal) 0);
   ArgPack_add_arg(gen_argp, XmNtopAttachment, (XtArgVal) XmATTACH_FORM);
   ArgPack_add_arg(gen_argp, XmNbottomAttachment, (XtArgVal) XmATTACH_FORM);
   ArgPack_add_arg(gen_argp, XmNrightAttachment, (XtArgVal) XmATTACH_FORM);

  ArgPack_add_arg(gen_argp, XmNleftAttachment, (XtArgVal) XmATTACH_WIDGET);
  ArgPack_add_arg(gen_argp, XmNleftWidget, (XtArgVal) menu_button);
  ArgPack_add_arg(gen_argp, XmNleftOffset, (XtArgVal) 150);
   ArgPack_add_arg(gen_argp, XmNrightOffset, (XtArgVal) 40);
   ArgPack_add_arg(gen_argp, XmNheight, (XtArgVal) ALRAREA_HEIGHT);
   ArgPack_add_arg(gen_argp, XmNunitType, (XtArgVal) Xm100TH_MILLIMETERS);
   ArgPack_add_arg(gen_argp, XmNresizable, (XtArgVal) TRUE);
   ArgPack_add_arg(gen_argp, XmNresizePolicy, (XtArgVal) XmRESIZE_ANY);
   rule_scroller = XmCreateScrolledWindow(rule_link->rule_box, "rule-scroll",
		      ArgPack_the_args(gen_argp), ArgPack_num_args(gen_argp));
   ArgPack_delete(gen_argp);

  /* Create the text label widget for the rule_box */
  /* --------------------------------------------- */
  AlRsb_debug2(fprintf(stderr, " Creating RuleText \n"));
  gen_argp = ArgPack_create();
  ArgPack_add_arg(gen_argp, XmNlabelString,
	       (XtArgVal) XmStringLtoRCreate(rule_link->text, ALFONTS_TEXT));
  ArgPack_add_arg(gen_argp, XmNfontList, (XtArgVal) (the_rsbrowser->fonts));
  ArgPack_add_arg(gen_argp, XmNshadowThickness, (XtArgVal) 0); /* 100 */
  ArgPack_add_arg(gen_argp, XmNleftAttachment, (XtArgVal) XmATTACH_NONE);
  ArgPack_add_arg(gen_argp, XmNleftOffset, (XtArgVal) 10);
  ArgPack_add_arg(gen_argp, XmNtopAttachment, (XtArgVal) XmATTACH_NONE);
  ArgPack_add_arg(gen_argp, XmNbottomAttachment, (XtArgVal) XmATTACH_NONE);
  ArgPack_add_arg(gen_argp, XmNrightAttachment, (XtArgVal) XmATTACH_FORM);
  ArgPack_add_arg(gen_argp, XmNtopOffset, (XtArgVal) 10);
  ArgPack_add_arg(gen_argp, XmNbottomOffset, (XtArgVal) 10);
  ArgPack_add_arg(gen_argp, XmNrightOffset, (XtArgVal) 10);
  ArgPack_add_arg(gen_argp, XmNresizable, (XtArgVal) True);
  ArgPack_add_arg(gen_argp, XmNresizePolicy, (XtArgVal) XmRESIZE_ANY);
  ArgPack_add_arg(gen_argp, XmNalignment, (XtArgVal) XmALIGNMENT_BEGINNING);

  rule_link->text_widget = XmCreateLabel(rule_scroller, "rule-text",
			     ArgPack_the_args(gen_argp),
			     ArgPack_num_args(gen_argp));
  ArgPack_delete(gen_argp);
  
  /* Attach a text area within the scrolled window */
  /* --------------------------------------------- */
   gen_argp = ArgPack_create();
   ArgPack_add_arg(gen_argp, XmNworkWindow, (XtArgVal) rule_link->text_widget);
   XtSetValues(rule_scroller, 
	       ArgPack_the_args(gen_argp), ArgPack_num_args(gen_argp));
  ArgPack_delete(gen_argp);

  /* Create the rule's editor_pixmap gid for the rule_box */
  /* ---------------------------------------------------- */
  gen_argp = ArgPack_create();
  ArgPack_add_arg(gen_argp, XmNwidth,
                    (XtArgVal) ((int) (empty_icon_width / 2)));
  ArgPack_add_arg(gen_argp, XmNheight,
                    (XtArgVal) ((int) (empty_icon_height / 4)));
  ArgPack_add_arg(gen_argp, XmNbackgroundPixmap,
		  (XtArgVal) the_rsbrowser->empty_icon);
  ArgPack_add_arg(gen_argp, XmNborderWidth, (XtArgVal) 0);
  ArgPack_add_arg(gen_argp, XmNleftAttachment, (XtArgVal) XmATTACH_WIDGET);
  ArgPack_add_arg(gen_argp, XmNleftWidget, (XtArgVal) rule_link->num_label);
  ArgPack_add_arg(gen_argp, XmNleftOffset, (XtArgVal) 150);
  ArgPack_add_arg(gen_argp, XmNrightAttachment, (XtArgVal) XmATTACH_WIDGET);
  ArgPack_add_arg(gen_argp, XmNrightWidget, (XtArgVal) rule_scroller);
  ArgPack_add_arg(gen_argp, XmNrightOffset, (XtArgVal) 150);
  ArgPack_add_arg(gen_argp, XmNtopAttachment, (XtArgVal) XmATTACH_FORM);
  ArgPack_add_arg(gen_argp, XmNtopOffset, (XtArgVal) 150);
  ArgPack_add_arg(gen_argp, XmNbottomAttachment, (XtArgVal) XmATTACH_WIDGET);
  ArgPack_add_arg(gen_argp, XmNbottomWidget, (XtArgVal) menu_button);
  ArgPack_add_arg(gen_argp, XmNbottomOffset, (XtArgVal) 150);
  ArgPack_add_arg(gen_argp, XmNresizable, (XtArgVal) False);
  ArgPack_add_arg(gen_argp, XmNresizePolicy, (XtArgVal) XmRESIZE_NONE);
  rule_link->editor_gid = XmCreateForm(rule_link->rule_box,"editor-identifier",
			     ArgPack_the_args(gen_argp),
			     ArgPack_num_args(gen_argp));
  ArgPack_delete(gen_argp);  

  /* Manage all the widgets */
  /* ---------------------- */
  XtManageChild(rule_link->num_label);
  XtManageChild(rule_link->editor_gid);
  XtManageChild(hand_button);
  XtManageChild(editor_flag);
  XtManageChild(menu_button);
  XtManageChild(rule_link->text_widget);
  XtManageChild(rule_scroller);
  XtManageChild(rule_link->rule_box);


 };         /* end of AlRsb_mkrulebox()  */



/*********************************************************************/
/***************** Error message and help functions ******************/
/*********************************************************************/


NORET AlRsb_errmsg2(msg1, msg2)
     char *msg1, *msg2;
 {
   /* ----------------------------------------------------------- */
   /* THIS IS TEMPORARY :: I'll make a more elaborate one, later. */
   /* ----------------------------------------------------------- */

   fprintf(stderr,"%s%s\n", msg1, msg2);  

 };         /* end of AlRsb_errmsg2()  */




/*********************************************************************/
/***************** Callbacks and exit functions **********************/
/*********************************************************************/


void AlRsb_exit_function(the_rsbrowser, exit_code)
     AlRSBrowser *the_rsbrowser;
     int exit_code;
 {
   AlRsb_debug2(fprintf(stderr, 
		   "Entering AlRsb_exit_function(): calling Al_cleanup()\n"));
   Al_cleanup();
   exit(exit_code);
 };         /* end of AlRsb_exit_function()  */


void AlRsb_quit_callback(widget, closure, call_data)
     Widget widget;
     caddr_t closure;
     caddr_t call_data;
 { AlRSBrowser *the_rsbrowser;

   the_rsbrowser = (AlRSBrowser *) closure;

   AlRsb_debug2(fprintf(stderr, 
		   "Entering AlRsb_quit_callback()\n"));

   /* If the ruleset hasn't been altered, then exit immediately */
   /* --------------------------------------------------------- */
   if (the_rsbrowser->has_been_altered == FALSE)
     { (the_rsbrowser->exit_function)(the_rsbrowser, 0);
       return;
     };

   /* If the ruleset has been altered, ask user if they really want to quit */
   /* --------------------------------------------------------------------- */
   if (1 == ((int) AlPop_Query(ALPOP_QUESTION,           /* what kind of pop */
                             ALRSB_NONSAVED_QUIT_MSG,    /* the message      */
                             ALRSB_H_NONSAVED_QUIT_MSG,  /* help message     */
                             widget,              /* widget to use as parent */
                             ALPOP_HANG_BELOW,           /* where to popup   */
			     the_rsbrowser->the_display,
			     ALPOP_CANCEL | ALPOP_OK | ALPOP_HELP)))
     (the_rsbrowser->exit_function)(the_rsbrowser, 0);
     
 };          /* end of AlRsb_quit_callback()  */


void AlRsb_save_callback(widget, closure, call_data)
     Widget widget;
     caddr_t closure;
     caddr_t call_data;
 { AlRSBrowser *the_rsbrowser;
   AlRuleLink  *rule_link;
   unsigned d_len;

   the_rsbrowser = (AlRSBrowser *) closure;

   /* Visibly show something happenning by changing cursor's shape  */
   /*  ------------------------------------------------------------ */
   MuSetWaitCursor(the_rsbrowser->shell_widget);

   /* Delete all rules from ruleset */
   /* ----------------------------- */
   for(d_len = AlRuleSet_number_of_rules(the_rsbrowser->the_ruleset);
       d_len > 0; d_len--)
     AlRuleSet_remove_rule(the_rsbrowser->the_ruleset, (unsigned) (d_len - 1));

   /* Replace ruleset with all the new rules */
   /* -------------------------------------- */
   for (rule_link = AlRsb_get_top_rule(the_rsbrowser);
	 rule_link != NULL;
	 rule_link = AlRsb_get_next_rule(rule_link))
       { if (rule_link->isdeleted != TRUE)
           AlRuleSet_add_rule_to_end(the_rsbrowser->the_ruleset,
                                     rule_link->rule);
       };

   if (AlRSreg_save(the_rsbrowser->ruleset_name) == Bool_FALSE)
     { AlRsb_errmsg2("Unable to save the RuleSet: ",
		     the_rsbrowser->ruleset_name);
     };

   the_rsbrowser->has_been_altered = FALSE;

   /* Set cursor back to normal shape to show saving is completed */
   /*  ---------------------------------------------------------- */
   MuSetStandardCursor(the_rsbrowser->shell_widget);

 };          /* end of AlRsb_save_callback()  */


void AlRsb_print_callback(widget, closure, call_data)
     Widget widget;
     caddr_t closure;
     caddr_t call_data;
 {   AlRSBrowser *the_rsbrowser;
     FILE *printer;
     int i;
     AlRule the_rule;
     AlRuleLink  *rule_link;
     char cmd_str[80];

     the_rsbrowser = (AlRSBrowser *) closure;

     /* Check that necessary environment variable is present */
     /* ---------------------------------------------------- */
     if (getenv("PRINTER") == NULL)
       { Al_warning2("Argus Rulebrowser: Unable to open printer. %s%s",
	   "Unix Environment variable \"PRINTER\" may not be set correctly.",
           " (see \"man setenv\")");
	 strcpy(cmd_str, "lpr -Pnil");
/*
         if (False == 
             MuGetString("What is the name of your printer?", 
              &(cmd_str[6]), 70,
              "Your Unix Environment variable \"PRINTER\" wasn't set. \n\
  Enter your printer name here.",  Mu_Popup_Pointer))
*/

         AlRsb_popup_errbox(the_rsbrowser, widget,
        "Can't find printer. You may need to \"setenv PRINTER yourprinter\"?");

           return;
       }
     else
       strcpy(cmd_str, "lpr ");

     if ((printer = popen(cmd_str, "w+")) == NULL)
       { Al_warning2("Argus Rulebrowser: Unable to open printer. %s%s",
	   "Unix Environment variable \"PRINTER\" may not be set correctly.",
           " (see \"man setenv\")");

         AlRsb_popup_errbox(the_rsbrowser, widget,
        "Can't find printer. You may need to \"setenv PRINTER yourprinter\"?");

         return;
       };

     /* Visibly show something happenning by changing cursor's shape  */
     /*  ------------------------------------------------------------ */
     MuSetWaitCursor(the_rsbrowser->shell_widget);

     /* Start by printing a header with the rule set name */
     /* ------------------------------------------------- */
     fprintf(printer,
             "      ------------------------------------------------------\n");
     fprintf(printer,
	     "                 Argus RuleSet = \"%s\"  \n", 
	     the_rsbrowser->ruleset_name);
     fprintf(printer,
           "      ------------------------------------------------------\n\n");
     i = 0;
     for(rule_link = AlRsb_get_top_rule(the_rsbrowser);
	 rule_link != NULL;
	 rule_link = AlRsb_get_next_rule(rule_link))
       { i++;
	 fprintf(printer, "[%d.] %s\n", i,
		 (rule_link->isdeleted == TRUE)
                   ? "(Marked for Deletion)" : " ");
	 fprintf(printer, "%s\n", rule_link->text);
       };

     fclose(printer);

     /* Set cursor back to normal shape to show printing is completed */
     /*  ------------------------------------------------------------ */
     MuSetStandardCursor(the_rsbrowser->shell_widget);

 };          /* end of AlRsb_print_callback()  */


void AlRsb_expunge_callback(widget, closure, call_data)
     Widget widget;
     caddr_t closure;
     caddr_t call_data;
 { int i;
   AlRSBrowser *the_rsbrowser;
   AlRuleLink  *rule_link, *next_rule;

   the_rsbrowser = (AlRSBrowser *) closure;
   XtUnmanageChild(the_rsbrowser->rulebox_form);

   i = 0;
   for (rule_link = AlRsb_get_top_rule(the_rsbrowser);
	 rule_link != NULL;
	 rule_link = next_rule)
       { next_rule = AlRsb_get_next_rule(rule_link);
	 if (rule_link->isdeleted == TRUE)
	   AlRsb_delete_rule(the_rsbrowser, rule_link);
	 i++;
       };

   AlRsb_renumber_rules(the_rsbrowser, AlRsb_get_top_rule(the_rsbrowser));
   the_rsbrowser->has_been_altered = TRUE;
   XtManageChild(the_rsbrowser->rulebox_form);

 };          /* end of AlRsb_expunge_callback()  */

void AlRsb_append_new_rule_callback(widget, closure, call_data)
     Widget widget;
     caddr_t closure;
     caddr_t call_data;
 { AlRule the_rule;
   AlRuleLink *last_rule_link, *new_rule_link;
   AlRSBrowser *the_rsbrowser;
   ArgPack argp;

   AlRsb_debug2(fprintf(stderr, 
		       " --> Entering AlRsb_append_new_rule_callback()\n"));
   the_rsbrowser = (AlRSBrowser *) closure;
   the_rule = AlRule_create_default_rule();
   last_rule_link = the_rsbrowser->last_rule;

   AlRsb_debug2(fprintf(stderr, "last_rule_link = %d\n the_rule = %d\n",
			(int) last_rule_link, (int) the_rule));

   if (last_rule_link == NULL)
     new_rule_link = AlRsb_add_rule(the_rsbrowser, the_rule, 0);
   else
     new_rule_link = AlRsb_add_rule(the_rsbrowser, the_rule,
				    last_rule_link->rule_number + 1);

   /* Visually label rule as being newly created */
   /* ------------------------------------------ */
   argp = ArgPack_create();
   ArgPack_add_arg(argp, XmNlabelPixmap,
		  (XtArgVal) the_rsbrowser->new_icon);
   ArgPack_add_arg(argp, XmNarmPixmap,
		  (XtArgVal) the_rsbrowser->new_icon);
   XtSetValues(new_rule_link->state_label, 
	       ArgPack_the_args(argp), ArgPack_num_args(argp));
   ArgPack_delete(argp);

   the_rsbrowser->has_been_altered = TRUE;

   AlRsb_debug2(fprintf(stderr, 
		       " <-- Exiting AlRsb_append_new_rule_callback()\n"));

 };          /* end of AlRsb_append_new_rule_callback()  */


void AlRsb_popdown_help(widget, closure, call_data)
     Widget widget;
     caddr_t closure;
     caddr_t call_data;
 { 
   /* This is just a required dummy function */

 };          /* end of AlRsb_popup_help()  */


void AlRsb_popup_help(widget, closure, call_data)
     Widget widget;
     caddr_t closure;
     caddr_t call_data;
 { Widget help_popup;
   unsigned int mask;
   int move_x, move_y, win_x, win_y;
   Window root, child;
   AlRSBrowser *the_rsbrowser;
   struct _AlRsb_callback *callback_struct;
   ArgPack argp = ArgPack_create();

   callback_struct = (struct _AlRsb_callback *) closure;
   the_rsbrowser = callback_struct->the_rsbrowser;
   help_popup = callback_struct->menu;

   XQueryPointer(the_rsbrowser->the_display,
		 XtWindow(widget),
		 &root, &child, &move_x, &move_y,
		 &win_x, &win_y, &mask);

   ArgPack_add_arg(argp, XmNx, (XtArgVal) move_x);
   ArgPack_add_arg(argp, XmNy, (XtArgVal) move_y);
   XtSetValues(help_popup, ArgPack_the_args(argp), ArgPack_num_args(argp));

   ArgPack_delete(argp);

   XtManageChild(help_popup);

 };          /* end of AlRsb_popup_help()  */


void AlRsb_popup_menu(widget, closure, call_data)
     Widget widget;
     caddr_t closure;
     caddr_t call_data;
 { Widget menu_popup;
   unsigned int mask;
   int move_x, move_y, win_x, win_y;
   Window root, child;
   AlRSBrowser *the_rsbrowser;
   struct _AlRsb_callback *callback_struct;
   ArgPack argp = ArgPack_create();

   callback_struct = (struct _AlRsb_callback *) closure;
   the_rsbrowser = callback_struct->the_rsbrowser;
   menu_popup = callback_struct->menu;

   XQueryPointer(the_rsbrowser->the_display,
		 XtWindow(widget),
		 &root, &child, &move_x, &move_y,
		 &win_x, &win_y, &mask);

   ArgPack_add_arg(argp, XmNx, (XtArgVal) move_x);
   ArgPack_add_arg(argp, XmNy, (XtArgVal) move_y);
   XtSetValues(menu_popup, ArgPack_the_args(argp), ArgPack_num_args(argp));

   ArgPack_delete(argp);

   XtManageChild(menu_popup);

 };          /* end of AlRsb_popup_menu()  */


void AlRsb_menu_action(widget, event, parm, n_parms)
     Widget widget;
     XEvent *event;
     char **parm;
     Cardinal n_parms;
 { struct _AlRsb_callback *closure;
   ArgPack gen_argp;

   gen_argp = ArgPack_create();
   ArgPack_add_arg(gen_argp, XmNuserData, (XtArgVal) &closure);
   XtGetValues(widget,
	       ArgPack_the_args(gen_argp), ArgPack_num_args(gen_argp));
   ArgPack_delete(gen_argp);

   AlRsb_popup_menu(widget, (caddr_t) closure, NULL);

 };         /* end of AlRsb_menu_action()  */


void AlRsb_detach_rule(the_rsbrowser, rule_link)
     AlRSBrowser *the_rsbrowser;
     AlRuleLink *rule_link;
 { AlRuleLink  *next, *prev;

   the_rsbrowser->has_been_altered = TRUE;

   if (rule_link == NULL)
     { AlRsb_errmsg2("NULL Rule passed to AlRsb_delete_rule(). ",
		     "Nothing to delete.");
       return;
     }
   else
     { AlRsb_lock_rule(rule_link);

       next = AlRsb_get_next_rule(rule_link);
       prev = AlRsb_get_prev_rule(rule_link);

       /* Re-Link back chains */
       if (next != NULL)
	 AlRsb_set_prev_rule(next, prev);
       if (prev == NULL)
	 { /* it is the first rule in list */
	   AlRsb_set_top_rule(the_rsbrowser, next);
	 }
       else
	 { /* Re-Link forward chains */
	   AlRsb_set_next_rule(prev, next);
	 };
       AlRsb_set_prev_rule(rule_link, NULL);
       AlRsb_set_next_rule(rule_link, NULL);

       AlRsb_unlock_rule(rule_link);
       return;
     };
 };          /* end of AlRsb_detach_rule()  */


void AlRsb_reattach_rule(the_rsbrowser, rule_link, rule_number)
     AlRSBrowser *the_rsbrowser;
     AlRuleLink *rule_link;
     int rule_number;
 { AlRuleLink  *next, *prev;

   AlRsb_debug(fprintf(stderr,
                " --> Entering AlRsb_reattach_rule(%d, %d, rule_number=%d)\n",
		(int) the_rsbrowser, (int) rule_link, (int) rule_number));

   the_rsbrowser->has_been_altered = TRUE;
   AlRsb_lock_rule(rule_link);

   rule_link->y_position  = rule_number
                              * (ALRB_SPACING + ALRB_HEIGHT);
   rule_link->rule_number = rule_number;

   AlRsb_renumber_rules(the_rsbrowser, AlRsb_get_top_rule(the_rsbrowser));

   /* Get next and previous rule links */
   /* -------------------------------- */
   if (rule_number > 0)
     { if ((prev = AlRsb_get_rule(the_rsbrowser, (rule_number - 1))) == NULL)
	 prev = the_rsbrowser->last_rule;
       next = AlRsb_get_next_rule(prev);
     }
   else
     { prev = NULL;
       next = AlRsb_get_top_rule(the_rsbrowser);
     };

   /* Set current, next, and previous rule links */
   /* ------------------------------------------ */

   /* Set current rule's links */
   AlRsb_set_prev_rule(rule_link, prev);
   AlRsb_set_next_rule(rule_link, next);

   /* Set next rule's links */
   if (next != NULL)
     AlRsb_set_prev_rule(next, rule_link);
   else
     the_rsbrowser->last_rule = rule_link;

   /* Set next rule's links */
   if (prev != NULL)
     AlRsb_set_next_rule(prev, rule_link);

   /* if first rule in linked list */
   if (AlRsb_get_top_rule(the_rsbrowser) == NULL)     
     AlRsb_set_top_rule(the_rsbrowser, rule_link);
   else if (prev == NULL)
     AlRsb_set_top_rule(the_rsbrowser, rule_link);

   AlRsb_unlock_rule(rule_link);

   AlRsb_debug(fprintf(stderr, " <-- Exiting AlRsb_reattach_rule()\n"));

   return;
 };          /* end of AlRsb_reattach_rule()  */


void AlRsb_hand_grab(widget, event, parm, n_parms)
     Widget widget;
     XEvent *event;
     char **parm;
     Cardinal n_parms;
 { struct _AlRsb_callback *closure;
   ArgPack gen_argp;

   gen_argp = ArgPack_create();
   ArgPack_add_arg(gen_argp, XmNuserData, (XtArgVal) &closure);
   XtGetValues(widget,
	       ArgPack_the_args(gen_argp), ArgPack_num_args(gen_argp));
   ArgPack_delete(gen_argp);

   AlRsb_moveby_hand(widget, (caddr_t) closure, NULL);

 };         /* end of AlRsb_hand_grab()  */

void AlRsb_moveby_hand(widget, closure, call_data)
     Widget widget;
     caddr_t closure;
     caddr_t call_data;
 { Widget hand_button, rulebox;
   Window rulebox_window, widget_window, rulearea_window;
   unsigned int mask;
   int start_x, start_y;
   int move_x, move_y, win_x, win_y, dx, dy;
   Window root, child;
   char str[10];
   ArgPack     gen_argp;
   AlRSBrowser *the_rsbrowser;
   AlRuleLink *rule_link, *prev, *next;
   struct _AlRsb_callback *callback_struct;
   long int y_position, prev_y_position, next_y_position;
   long int empty_y_position;   /* tracks the hole left by the moving rule */
   int min_dy, max_dy, rule_number, prev_rule_number, next_rule_number;
   int original_rule_number, total_dy = 0;
   XEvent report;
   unsigned int eventmask;
   int release_x, release_y;
   Bool moved = Bool_FALSE;

   /****************************************************************/
   /*                   !!!!! WARNING !!!!!                        */
   /* Extremely hairy code is used in this function. Make sure to  */
   /* REALLY understand events and event queuing before attempting */
   /* to modify this code.                                         */
   /****************************************************************/

   AlRsb_debug(fprintf(stderr,
    " --> Entering AlRsb_moveby_hand: widget=%d, closure=%d\n",
		       (int) widget, (int) closure));

   /* Visibly show something happenning by changing cursor's shape  */
   /*  ------------------------------------------------------------ */
   MuSetCursor(widget, UPDOWN_CURSOR);

   /* Initialize Closure related variables */
   /* ------------------------------------ */
   AlRsb_debug2(fprintf(stderr,
	      " -- Initializing Closure related variables.\n"));
   callback_struct = (struct _AlRsb_callback *) closure;
   the_rsbrowser = callback_struct->the_rsbrowser;
   rule_link = callback_struct->rule_link;
   hand_button = callback_struct->menu;
   rulebox = rule_link->rule_box;
   widget_window = XtWindow(widget);
   rulebox_window = XtWindow(rule_link->rule_box);
   rulearea_window = XtWindow(the_rsbrowser->rulebox_form);
   rule_number = rule_link->rule_number;
   original_rule_number = rule_number;
   y_position = rule_link->y_position;
   empty_y_position = y_position;
   min_dy = 0 - y_position;
   max_dy = (the_rsbrowser->last_rule)->y_position + 20;

   XUngrabPointer(the_rsbrowser->the_display, CurrentTime);

   /* Initialize relevent values for position locations */
   /* ------------------------------------------------- */
   AlRsb_debug(fprintf(stderr,
	      " -- Initializing relevent values for position locations.\n"));

   XQueryPointer(the_rsbrowser->the_display,
		 widget_window,
		 &root, &child, &start_x, &start_y,
		 &win_x, &win_y, &mask);

   /* Now we need to start getting pointer motion events. */
   /* --------------------------------------------------- */
   eventmask =  ExposureMask | VisibilityChangeMask | 
                PointerMotionMask | ButtonPressMask
                | ButtonReleaseMask
                | PointerMotionHintMask
                | EventMaskOfScreen(XtScreen(widget));

   XGrabPointer(the_rsbrowser->the_display,
		DefaultRootWindow(the_rsbrowser->the_display),
                False,
		eventmask,
                GrabModeAsync,
                GrabModeAsync, 
		rulearea_window,   /* confine to */
                None, CurrentTime);
   XChangeActivePointerGrab(the_rsbrowser->the_display, eventmask,
			    None,                     /* cursor */
			    CurrentTime);

   prev = rule_link->previous;
   next = rule_link->next;
   if (prev != NULL)
     { prev_rule_number = prev->rule_number;
       prev_y_position = prev->y_position;
     }
   else
     { prev_rule_number = rule_link->rule_number;
       prev_y_position = rule_link->y_position;
     };
   if (next != NULL)
     { next_rule_number = next->rule_number;
       next_y_position = next->y_position;
     }
   else
     { next_rule_number = rule_link->rule_number;
       next_y_position = rule_link->y_position;
     };

   /* Remove rule from ruleset while moving it */
   /* ---------------------------------------- */
   AlRsb_detach_rule(the_rsbrowser, rule_link); 

   /* Interactively move rulebox around, following vertical mouse movements */
   /* --------------------------------------------------------------------- */
   XRaiseWindow(the_rsbrowser->the_display, rulebox_window);  
   AlRsb_debug(fprintf(stderr, " -- About to enter interactive loop.\n"));
   for(; ;)
     { XFlush(the_rsbrowser->the_display);
       XNextEvent(the_rsbrowser->the_display, &report);
       switch(report.type)
	 { case ButtonPress:
	         AlRsb_debug(fprintf(stderr, " = Got a button press event\n"));
	         break;

	   case ButtonRelease:
	         AlRsb_debug(fprintf(stderr, 
				     " = Got a button release event\n"));
                 XUngrabPointer(the_rsbrowser->the_display,
					CurrentTime);

                 /* Set cursor back to normal shape */
                 /*  ------------------------------ */
                 MuSetStandardCursor(the_rsbrowser->shell_widget);

                 /* Re-attach the rule, linking it into its new position */
                 /* ---------------------------------------------------- */
		 AlRsb_reattach_rule(the_rsbrowser, rule_link, rule_number);

                 /* Move the rulebox into the old horizontal position */
                 /* ------------------------------------------------- */
	         gen_argp = ArgPack_create();
	         ArgPack_add_arg(gen_argp, XmNx, (XtArgVal) 0);
	         XtSetValues(rulebox,
		             ArgPack_the_args(gen_argp),
		             ArgPack_num_args(gen_argp));
	         ArgPack_delete(gen_argp);

                 /* Re-number and readjust positions of all rules to new fit */
                 /* -------------------------------------------------------- */
  		 AlRsb_renumber_rules(the_rsbrowser,
				      AlRsb_get_top_rule(the_rsbrowser));

		 AlRsb_debug(fprintf(stderr, 
	 " <-- Exiting AlRsb_moveby_hand: y_position = %d, rule_number = %d\n",
			 (int) y_position, rule_number));
		 return;
		 break;

	   case MotionNotify:
	         AlRsb_debug2(fprintf(stderr, 
				     " = Got a motion notify event: "));
	         AlRsb_debug2(fprintf(stderr, 
				     "%d ", (int) report.xmotion.is_hint));

		 /* Find out how far the rulebox is to be moved */
		 /* ------------------------------------------- */
		 XQueryPointer(the_rsbrowser->the_display,
			       widget_window,
			       &root, &child, &move_x, &move_y,
			       &win_x, &win_y, &mask);
		 dy = move_y - start_y;
		 dy = XmConvertUnits(rulebox, XmVERTICAL, XmPIXELS, dy, 
				     Xm100TH_MILLIMETERS);
		 start_y = move_y;

		 /* Move the rulebox (but keep inside rule workarea) */
		 /* ------------------------------------------------ */
                 if (((dy > 0) && (win_y < (hand_icon_height / 2)))
                     || ((dy < 0) && (win_y >= (hand_icon_height / 2))))
		   moved = Bool_FALSE;
		 else if (dy >= min_dy)
		   { y_position = y_position + dy;
		     if (!
			(((y_position <=  prev_y_position) && (prev == NULL))
		        || ((y_position > next_y_position) && (dy >= 0)
			    && (next == NULL))))
		       { total_dy += dy;
		         min_dy -= dy;
		         max_dy -= dy;

	                 /* Move the rulebox into the new position */
	                 gen_argp = ArgPack_create();
	                 ArgPack_add_arg(gen_argp, XmNx, (XtArgVal) 100);
	                 ArgPack_add_arg(gen_argp, XmNy,
                                     (XtArgVal) y_position);
	                 XtSetValues(rulebox,
		                     ArgPack_the_args(gen_argp),
		                     ArgPack_num_args(gen_argp));
	                 ArgPack_delete(gen_argp);
	                 moved = Bool_TRUE;
		       }
		     else
	               { y_position = y_position - dy;
	                 moved = Bool_FALSE;
		       };
	           };

		 /* Upward rule movement, check if swapping is needed */
		 /* ------------------------------------------------- */
                 if ((moved == Bool_TRUE) && (y_position <=  prev_y_position))
	           { AlRsb_debug(fprintf(stderr, 
	     " --: In AlRsb_moveby_hand: (y_position <= prev_y_position)\n"));
                     while((prev != NULL) && (moved == Bool_TRUE) 
                           && (y_position <=  prev_y_position))
	               { XUngrabPointer(the_rsbrowser->the_display,
					CurrentTime);

	                 /* Move the prev rulebox into the new position */
	                 /* ------------------------------------------- */
	                 gen_argp = ArgPack_create();
	                 ArgPack_add_arg(gen_argp, XmNx, (XtArgVal) 0);
	                 ArgPack_add_arg(gen_argp, XmNy,
					 (XtArgVal) empty_y_position);
	                 XtSetValues(prev->rule_box,
		                     ArgPack_the_args(gen_argp),
		                     ArgPack_num_args(gen_argp));
	                 ArgPack_delete(gen_argp);
	                 gen_argp = ArgPack_create();

			 /* Update all the relevent variables */
	                 /* --------------------------------- */
	                 prev->y_position = empty_y_position;
                         next = prev;
                         prev = prev->previous;
                         next_y_position = empty_y_position;
                         empty_y_position = prev_y_position;
                         prev_y_position = prev->y_position;
	                 rule_number--;
			 next_rule_number = rule_number + 1;
			 prev_rule_number = rule_number - 1;
	                 AlRsb_debug(fprintf(stderr,
                        " -- rule_number=%d, prev_rule_#=%d, next_rule_#=%d\n",
	                 rule_number, prev_rule_number, next_rule_number));

	                 /* Re-number the new next rule's number label */
	                 /* ------------------------------------------ */
	                 sprintf(str, "%d", next_rule_number + 1);
	                 ArgPack_add_arg(gen_argp, XmNlabelString,
			      (XtArgVal) XmStringCreate(str, ALFONTS_BUTTONS));
	                 XtSetValues(next->num_label, 
		                   ArgPack_the_args(gen_argp),
		                   ArgPack_num_args(gen_argp));
	                 ArgPack_delete(gen_argp);

	                 /* Re-label current rule_box's rule number label */
	                 /* --------------------------------------------- */
	                 gen_argp = ArgPack_create();
	                 /* Get the string form of the rule number        */
                         /*  Note: label is rule_link->rule_number + 1    */
                         /*  Because Darray is 0 based, but UI is 1 based */
	                 sprintf(str, "%d", rule_number + 1);
	                 ArgPack_add_arg(gen_argp, XmNlabelString,
			      (XtArgVal) XmStringCreate(str, ALFONTS_BUTTONS));
	                 XtSetValues(rule_link->num_label, 
		                   ArgPack_the_args(gen_argp),
		                   ArgPack_num_args(gen_argp));
	                 ArgPack_delete(gen_argp);
			 XGrabPointer(the_rsbrowser->the_display,
				      DefaultRootWindow(
			                   the_rsbrowser->the_display),
                                      False, eventmask,
                                      GrabModeAsync,
                                      GrabModeAsync, 
		                      rulearea_window,   /* confine to */
                                      None, CurrentTime);
			 XChangeActivePointerGrab(the_rsbrowser->the_display,
			    eventmask,
			    None,
			    CurrentTime);
		       };
	           }
		 /* Downward rule movement, check if swapping is needed */
		 /* --------------------------------------------------- */
                 else if ((moved == Bool_TRUE)
			  && (y_position > next_y_position))
	           { AlRsb_debug(fprintf(stderr, 
	       " --: In AlRsb_moveby_hand: (y_position > next_y_position)\n"));
                     while((next != NULL) && (moved == Bool_TRUE)
			   && (y_position > next_y_position))
	               { XUngrabPointer(the_rsbrowser->the_display,
					CurrentTime);

	                 /* Move the next rulebox into the new position */
	                 /* ------------------------------------------- */
	                 gen_argp = ArgPack_create();
	                 ArgPack_add_arg(gen_argp, XmNx, (XtArgVal) 0);
	                 ArgPack_add_arg(gen_argp, XmNy,
					 (XtArgVal) empty_y_position);
	                 XtSetValues(next->rule_box,
		                     ArgPack_the_args(gen_argp),
		                     ArgPack_num_args(gen_argp));
	                 ArgPack_delete(gen_argp);
	                 gen_argp = ArgPack_create();

			 /* Update all the relevent variables */
	                 /* --------------------------------- */
	                 next->y_position = empty_y_position;
                         prev = next;
                         next = next->next;
                         prev_y_position = empty_y_position;
                         empty_y_position = next_y_position;
                         next_y_position = next->y_position;
	                 rule_number++;
			 next_rule_number = rule_number + 1;
			 prev_rule_number = rule_number - 1;
	                 AlRsb_debug(fprintf(stderr,
                        " -- rule_number=%d, prev_rule_#=%d, next_rule_#=%d\n",
	                 rule_number, prev_rule_number, next_rule_number));

	                 /* Re-number the new prev's rule's number label */
	                 /* -------------------------------------------- */
	                 sprintf(str, "%d", prev_rule_number + 1);
	                 ArgPack_add_arg(gen_argp, XmNlabelString,
			      (XtArgVal) XmStringCreate(str, ALFONTS_BUTTONS));
	                 XtSetValues(prev->num_label, 
		                   ArgPack_the_args(gen_argp),
		                   ArgPack_num_args(gen_argp));
	                 ArgPack_delete(gen_argp);

	                 /* Re-label current rule_box's rule number label */
	                 /* --------------------------------------------- */
	                 gen_argp = ArgPack_create();
	                 /* Get the string form of the rule number        */
                         /*  Note: label is rule_link->rule_number + 1    */
                         /*  Because Darray is 0 based, but UI is 1 based */
	                 sprintf(str, "%d", rule_number + 1);
	                 ArgPack_add_arg(gen_argp, XmNlabelString,
			      (XtArgVal) XmStringCreate(str, ALFONTS_BUTTONS));
	                 XtSetValues(rule_link->num_label, 
		                   ArgPack_the_args(gen_argp),
		                   ArgPack_num_args(gen_argp));
	                 ArgPack_delete(gen_argp);

			 XGrabPointer(the_rsbrowser->the_display,
				      DefaultRootWindow(
			                   the_rsbrowser->the_display),
				      False, eventmask,
                                      GrabModeAsync,
                                      GrabModeAsync, 
		                      rulearea_window,  /* confine to window */
                                      None, CurrentTime);
			 XChangeActivePointerGrab(the_rsbrowser->the_display,
			    eventmask,
			    None,
			    CurrentTime);
		       };
	           }
                 else
                   { AlRsb_debug2(fprintf(stderr, 
	                       " --: In AlRsb_moveby_hand: y_position = %d\n",
			       (int) y_position));
	           };
		 break;

	   case Expose:
	         AlRsb_debug2(fprintf(stderr, " = Got an Expose event\n"));
		 XtDispatchEvent(&report);
                 break;

	   default:
	         AlRsb_debug2(fprintf(stderr, " = Got an unknown event\n"));
		 XtDispatchEvent(&report);
	 };    /* end of switch */
     };    /* end of interactive loop */

   /* Set cursor back to normal shape */
   /*  ------------------------------ */
   MuSetStandardCursor(the_rsbrowser->shell_widget);

   AlRsb_debug(fprintf(stderr, 
	" <-- Exiting AlRsb_moveby_hand: y_position = %d, rule_number = %d\n",
	(int) y_position, rule_number));

 };          /* end of AlRsb_moveby_hand()  */


void AlRsb_copy_callback(widget, closure, call_data)
     Widget widget;
     caddr_t closure;
     caddr_t call_data;
 { AlRule the_rule;
   AlRuleLink *rule_link, *new_rule_link;
   AlRSBrowser *the_rsbrowser;
   struct _AlRsb_callback *callback_struct;
   ArgPack argp;

   callback_struct = (struct _AlRsb_callback *) closure;
   rule_link = callback_struct->rule_link;
   the_rsbrowser = callback_struct->the_rsbrowser;
   XtUnmanageChild(callback_struct->menu);

   the_rule = AlRule_copy(rule_link->rule);
   new_rule_link = AlRsb_add_rule(the_rsbrowser, the_rule,
				  rule_link->rule_number);

   /* Visually label rule as being newly created */
   /* ------------------------------------------ */
   argp = ArgPack_create();
   ArgPack_add_arg(argp, XmNlabelPixmap,
		  (XtArgVal) the_rsbrowser->new_icon);
   ArgPack_add_arg(argp, XmNarmPixmap,
		  (XtArgVal) the_rsbrowser->new_icon);
   XtSetValues(new_rule_link->state_label, 
	       ArgPack_the_args(argp), ArgPack_num_args(argp));
   ArgPack_delete(argp);

   the_rsbrowser->has_been_altered = TRUE;

 };         /* end of AlRsb_copy_callback()  */


void AlRsb_insert_callback(widget, closure, call_data)
     Widget widget;
     caddr_t closure;
     caddr_t call_data;
 { AlRule the_rule;
   AlRuleLink *rule_link, *new_rule_link;
   AlRSBrowser *the_rsbrowser;
   struct _AlRsb_callback *callback_struct;
   ArgPack argp;
   void AlRsb_edit_callback();

   callback_struct = (struct _AlRsb_callback *) closure;
   rule_link = callback_struct->rule_link;
   the_rsbrowser = callback_struct->the_rsbrowser;
   XtUnmanageChild(callback_struct->menu);

   the_rule = AlRule_create_default_rule();
   new_rule_link = AlRsb_add_rule(the_rsbrowser, the_rule,
				  rule_link->rule_number);

   /* Visually label rule as being newly created */
   /* ------------------------------------------ */
   argp = ArgPack_create();
   ArgPack_add_arg(argp, XmNlabelPixmap,
		  (XtArgVal) the_rsbrowser->new_icon);
   ArgPack_add_arg(argp, XmNarmPixmap,
		  (XtArgVal) the_rsbrowser->new_icon);
   XtSetValues(new_rule_link->state_label, 
	       ArgPack_the_args(argp), ArgPack_num_args(argp));
   ArgPack_delete(argp);

   the_rsbrowser->has_been_altered = TRUE;

 };         /* end of AlRsb_insert_callback()  */


void AlRsb_edit_callback(widget, closure, call_data)
     Widget widget;
     caddr_t closure;
     caddr_t call_data;
 { AlRuleLink *rule_link;
   AlRSBrowser *the_rsbrowser;
   struct _AlRsb_callback *callback_struct;
   ArgPack argp;
   Pixmap borderPixmap = NULL, backgroundPixmap = NULL;
   void AlRsb_unedit_callback();
   void AlRsb_save_func();
   void AlRsb_quit_func();
   int dummy_argc = 0;
   char str[100];

   AlRsb_debug2(fprintf(stderr, " --> Entering AlRsb_edit_callback()\n"));

   callback_struct = (struct _AlRsb_callback *) closure;
   rule_link = callback_struct->rule_link;
   the_rsbrowser = callback_struct->the_rsbrowser;
   callback_struct->button = widget;
   XtUnmanageChild(callback_struct->menu);

   if (rule_link->isediting == TRUE)   /* It is already being edited. */
     return;

   rule_link->isediting = TRUE;

   argp = ArgPack_create();
   ArgPack_add_arg(argp, XmNlabelString,
	      (XtArgVal) XmStringCreate("Stop Editing Rule", ALFONTS_BUTTONS));
   XtSetValues(widget, 
	       ArgPack_the_args(argp), ArgPack_num_args(argp));
   ArgPack_delete(argp);

   XtRemoveAllCallbacks(widget, XmNactivateCallback);
   XtAddCallback(widget, XmNactivateCallback, 
		 AlRsb_unedit_callback, (caddr_t) closure);

   argp = ArgPack_create();
   ArgPack_add_arg(argp, XmNlabelPixmap,
		  (XtArgVal) the_rsbrowser->editor_icon);
   ArgPack_add_arg(argp, XmNarmPixmap,
		  (XtArgVal) the_rsbrowser->editor_icon);
   XtSetValues(rule_link->state_label, 
	       ArgPack_the_args(argp), ArgPack_num_args(argp));
   ArgPack_delete(argp);

   /* Choose some pixmaps to visually distiguish multiple ruleeditors apart */
   /* --------------------------------------------------------------------- */
   borderPixmap = AlRsb_get_grey_pixmap(
		     AlRsb_get_number_of_open_ruleeditors(the_rsbrowser));
   backgroundPixmap = AlRsb_get_grey_pixmap(
		     AlRsb_get_number_of_open_ruleeditors(the_rsbrowser));

   /* Set the pixmap on the rulebox's editor-graphical-id */
   /* --------------------------------------------------- */
   argp = ArgPack_create();
   ArgPack_add_arg(argp, XmNbackgroundPixmap,
		  (XtArgVal) borderPixmap);
   XtSetValues(rule_link->editor_gid,
	       ArgPack_the_args(argp), ArgPack_num_args(argp));
   ArgPack_delete(argp);

   sprintf(str, "Ruleset: %.30s,  Rule #%d%c", 
	   the_rsbrowser->ruleset_name,  1 + rule_link->rule_number, '\0');
   MuSetWaitCursor(the_rsbrowser->shell_widget);
   rule_link->editor_id = re_OpenEditor(the_rsbrowser->the_display,
					rule_link->rule,
					AlRsb_save_func, /* SaveFunction */
					AlRsb_quit_func, /* QuitFunction */
					&dummy_argc, NULL,
					str, NULL,
					callback_struct,
					borderPixmap,
					backgroundPixmap);

   AlRsb_add_number_of_open_ruleeditors(the_rsbrowser, 1);
   MuSetStandardCursor(the_rsbrowser->shell_widget);
   the_rsbrowser->has_been_altered = TRUE;

   AlRsb_debug2(fprintf(stderr, " <-- Exiting AlRsb_edit_callback()\n"));

 };         /* end of AlRsb_edit_callback()  */


void AlRsb_save_func(editor_id, rule, closure)
     reid editor_id;
     AlRule rule;
     VOIDP closure;
 { ArgPack argp;
   AlRuleLink *rule_link;
   AlRSBrowser *the_rsbrowser;
   struct _AlRsb_callback *callback_struct;
   int char_count, j;

   AlRsb_debug2(fprintf(stderr, " --> Entering AlRsb_save_func()\n"));

   callback_struct = (struct _AlRsb_callback *) closure;
   rule_link = callback_struct->rule_link;
   the_rsbrowser = callback_struct->the_rsbrowser;

   rule_link->rule = rule;

   /* Reset the text of the rulebox here */
   /* ---------------------------------- */

   Memory_free(rule_link->text);   /* free old string */
   rule_link->text        = (char *) Memory_allocate(ALRB_TEXTLENGTH + 1);

   /* Get the text of the rule */
   /* ------------------------ */
   char_count = -1;
   for(j = 0; (j < 50) && (char_count == -1); j++)
     { char_count = 
       Alruleprint(rule_link->text,                    /* buffer */
		   rule_link->text_buffer_size - 1,    /* buflen */
		   Bool_TRUE,                          /* print_type */
		   rule_link->rule);                   /* the rule */

       /* If the buffer isn't big enough, enlarge it, and try again. */
       rule_link->text = (char *) Memory_reallocate(rule_link->text,
			    rule_link->text_buffer_size + ALRB_TEXTLENGTH + 1);
       rule_link->text_buffer_size +=  (ALRB_TEXTLENGTH + 1);
     };

   /* Insure a null terminated string */
   /* ------------------------------- */
   *(rule_link->text + rule_link->text_buffer_size) = '\0';
	 
   argp = ArgPack_create();
   ArgPack_add_arg(argp, XmNlabelString,
	       (XtArgVal) XmStringLtoRCreate(rule_link->text, ALFONTS_TEXT));
   XtSetValues(rule_link->text_widget,
	       ArgPack_the_args(argp), ArgPack_num_args(argp));
   ArgPack_delete(argp);

   AlRsb_debug2(fprintf(stderr, " <-- Exiting AlRsb_save_func()\n"));

 };     /* end of AlRsb_save_func() */


void AlRsb_quit_func(editor_id, closure)
     reid editor_id;
     VOIDP closure;
 { ArgPack argp;
   Widget widget;
   AlRuleLink *rule_link;
   AlRSBrowser *the_rsbrowser;
   struct _AlRsb_callback *callback_struct;

   AlRsb_debug2(fprintf(stderr, " --> Entering AlRsb_quit_func()\n"));

   callback_struct = (struct _AlRsb_callback *) closure;
   rule_link = callback_struct->rule_link;
   the_rsbrowser = callback_struct->the_rsbrowser;
   widget = callback_struct->button;

   argp = ArgPack_create();
   ArgPack_add_arg(argp, XmNlabelPixmap,
		  (XtArgVal) the_rsbrowser->empty_icon);
   ArgPack_add_arg(argp, XmNarmPixmap,
		  (XtArgVal) the_rsbrowser->empty_icon);
   XtSetValues(rule_link->state_label, 
	       ArgPack_the_args(argp), ArgPack_num_args(argp));
   ArgPack_delete(argp);

   argp = ArgPack_create();
   ArgPack_add_arg(argp, XmNbackgroundPixmap,
		  (XtArgVal) the_rsbrowser->empty_icon);
   XtSetValues(rule_link->editor_gid,
	       ArgPack_the_args(argp), ArgPack_num_args(argp));
   ArgPack_delete(argp);

   if (widget != NULL)
     { argp = ArgPack_create();
       ArgPack_add_arg(argp, XmNlabelString,
	         (XtArgVal) XmStringCreate("Edit this Rule", ALFONTS_BUTTONS));
       XtSetValues(widget, ArgPack_the_args(argp), ArgPack_num_args(argp));
       ArgPack_delete(argp);

       XtRemoveAllCallbacks(widget, XmNactivateCallback);
       XtAddCallback(widget, XmNactivateCallback, 
		     AlRsb_edit_callback, (caddr_t) closure);
     };

   re_CloseEditor(rule_link->editor_id);
   rule_link->isediting = FALSE;
/*   AlRsb_add_number_of_open_ruleeditors(the_rsbrowser, -1); */

   AlRsb_debug2(fprintf(stderr, " <-- Exiting AlRsb_quit_func()\n"));

 };     /* end of AlRsb_quit_func() */


void AlRsb_unedit_callback(widget, closure, call_data)
     Widget widget;
     caddr_t closure;
     caddr_t call_data;
 { AlRuleLink *rule_link;
   AlRSBrowser *the_rsbrowser;
   struct _AlRsb_callback *callback_struct;
   ArgPack argp;
   void AlRsb_edit_callback();


   AlRsb_debug2(fprintf(stderr, " --> Entering AlRsb_unedit_callback()\n"));

   callback_struct = (struct _AlRsb_callback *) closure;
   rule_link = callback_struct->rule_link;
   the_rsbrowser = callback_struct->the_rsbrowser;
   XtUnmanageChild(callback_struct->menu);

   argp = ArgPack_create();
   ArgPack_add_arg(argp, XmNlabelString,
	      (XtArgVal) XmStringCreate("Edit this Rule", ALFONTS_BUTTONS));
   XtSetValues(widget, 
	       ArgPack_the_args(argp), ArgPack_num_args(argp));
   ArgPack_delete(argp);

   XtRemoveAllCallbacks(widget, XmNactivateCallback);
   XtAddCallback(widget, XmNactivateCallback, 
		 AlRsb_edit_callback, (caddr_t) closure);

   if (rule_link->isdeleted == TRUE)    /* replace with 'deleted' icon */
     { argp = ArgPack_create();
       ArgPack_add_arg(argp, XmNlabelPixmap,
		       (XtArgVal) the_rsbrowser->deleted_icon);
       ArgPack_add_arg(argp, XmNarmPixmap,
		       (XtArgVal) the_rsbrowser->deleted_icon);
       XtSetValues(rule_link->state_label, 
		   ArgPack_the_args(argp), ArgPack_num_args(argp));
       ArgPack_delete(argp);

       /* Update editor's graphical id patch */
       argp = ArgPack_create();
       ArgPack_add_arg(argp, XmNbackgroundPixmap,
		  (XtArgVal) the_rsbrowser->empty_icon);
       XtSetValues(rule_link->editor_gid,
		   ArgPack_the_args(argp), ArgPack_num_args(argp));
       ArgPack_delete(argp);
     }
   else                      /* replace with an empty icon */
     { argp = ArgPack_create();
       ArgPack_add_arg(argp, XmNlabelPixmap,
		       (XtArgVal) the_rsbrowser->empty_icon);
       ArgPack_add_arg(argp, XmNarmPixmap,
		       (XtArgVal) the_rsbrowser->empty_icon);
       XtSetValues(rule_link->state_label, 
		   ArgPack_the_args(argp), ArgPack_num_args(argp));
       ArgPack_delete(argp);

       /* Update editor's graphical id patch */
       argp = ArgPack_create();
       ArgPack_add_arg(argp, XmNbackgroundPixmap,
		  (XtArgVal) the_rsbrowser->empty_icon);
       XtSetValues(rule_link->editor_gid,
		   ArgPack_the_args(argp), ArgPack_num_args(argp));
       ArgPack_delete(argp);
     };

   re_CloseEditor(rule_link->editor_id);
   rule_link->isediting = FALSE;
/*   AlRsb_add_number_of_open_ruleeditors(the_rsbrowser, -1); */

   AlRsb_debug2(fprintf(stderr, " <-- Exiting AlRsb_unedit_callback()\n"));

 };         /* end of AlRsb_unedit_callback()  */


void AlRsb_delete_callback(widget, closure, call_data)
     Widget widget;
     caddr_t closure;
     caddr_t call_data;
 { AlRuleLink *rule_link;
   AlRSBrowser *the_rsbrowser;
   struct _AlRsb_callback *callback_struct;
   ArgPack argp;
   void AlRsb_undelete_callback();

   callback_struct = (struct _AlRsb_callback *) closure;
   rule_link = callback_struct->rule_link;
   the_rsbrowser = callback_struct->the_rsbrowser;
   XtUnmanageChild(callback_struct->menu);

   rule_link->isdeleted = TRUE;

   argp = ArgPack_create();
   ArgPack_add_arg(argp, XmNlabelString,
		 (XtArgVal) XmStringCreate("Un-Delete", ALFONTS_BUTTONS));
   XtSetValues(widget, 
	       ArgPack_the_args(argp), ArgPack_num_args(argp));
   ArgPack_delete(argp);

   XtRemoveAllCallbacks(widget, XmNactivateCallback);
   XtAddCallback(widget, XmNactivateCallback, 
		 AlRsb_undelete_callback, (caddr_t) closure);

   argp = ArgPack_create();
   ArgPack_add_arg(argp, XmNlabelPixmap,
		  (XtArgVal) the_rsbrowser->deleted_icon);
   ArgPack_add_arg(argp, XmNarmPixmap,
		  (XtArgVal) the_rsbrowser->deleted_icon);
   XtSetValues(rule_link->state_label, 
	       ArgPack_the_args(argp), ArgPack_num_args(argp));
   ArgPack_delete(argp);

   the_rsbrowser->has_been_altered = TRUE;

 };         /* end of AlRsb_delete_callback()  */


void AlRsb_undelete_callback(widget, closure, call_data)
     Widget widget;
     caddr_t closure;
     caddr_t call_data;
 { AlRuleLink *rule_link;
   AlRSBrowser *the_rsbrowser;
   struct _AlRsb_callback *callback_struct;
   ArgPack argp;

   callback_struct = (struct _AlRsb_callback *) closure;
   rule_link = callback_struct->rule_link;
   the_rsbrowser = callback_struct->the_rsbrowser;
   XtUnmanageChild(callback_struct->menu);

   rule_link->isdeleted = FALSE;

   argp = ArgPack_create();
   ArgPack_add_arg(argp, XmNlabelString,
		 (XtArgVal) XmStringCreate("Mark to Delete", ALFONTS_BUTTONS));
   XtSetValues(widget, 
	       ArgPack_the_args(argp), ArgPack_num_args(argp));
   ArgPack_delete(argp);

   XtRemoveAllCallbacks(widget, XmNactivateCallback);
   XtAddCallback(widget, XmNactivateCallback, 
		 AlRsb_delete_callback, (caddr_t) closure);

   if (rule_link->isediting == TRUE)    /* replace with 'editing' icon */
     { argp = ArgPack_create();
       ArgPack_add_arg(argp, XmNlabelPixmap,
		       (XtArgVal) the_rsbrowser->editor_icon);
       ArgPack_add_arg(argp, XmNarmPixmap,
		       (XtArgVal) the_rsbrowser->editor_icon);
       XtSetValues(rule_link->state_label, 
		   ArgPack_the_args(argp), ArgPack_num_args(argp));
       ArgPack_delete(argp);
     }
   else                      /* replace with an empty icon */
     { argp = ArgPack_create();
       ArgPack_add_arg(argp, XmNlabelPixmap,
		       (XtArgVal) the_rsbrowser->empty_icon);
       ArgPack_add_arg(argp, XmNarmPixmap,
		       (XtArgVal) the_rsbrowser->empty_icon);
       XtSetValues(rule_link->state_label, 
		   ArgPack_the_args(argp), ArgPack_num_args(argp));
       ArgPack_delete(argp);
     };

   the_rsbrowser->has_been_altered = TRUE;

 };         /* end of AlRsb_undelete_callback()  */


/*********************************************************************/
/**** Functions that operate on Rule Links (AlRuleLink structs) ******/
/*********************************************************************/

int AlRsb_islocked(rule_link)
     AlRuleLink  *rule_link;
 {
   return(rule_link->islocked);

 };         /* end of AlRsb_lock_rule()  */


NORET AlRsb_lock_rule(rule_link)
     AlRuleLink  *rule_link;
 {
   rule_link->islocked = TRUE;

 };         /* end of AlRsb_lock_rule()  */


NORET AlRsb_unlock_rule(rule_link)
     AlRuleLink  *rule_link;
 {
   rule_link->islocked = FALSE;

 };         /* end of AlRsb_unlock_rule()  */


AlRuleLink  *AlRsb_get_next_rule(rule_link)
     AlRuleLink  *rule_link;
 {
   return(rule_link->next);

 };         /* end of AlRsb_get_next_rule()  */


AlRuleLink  *AlRsb_get_prev_rule(rule_link)
     AlRuleLink  *rule_link;
 {
   return(rule_link->previous);

 };         /* end of AlRsb_get_next_rule()  */


NORET AlRsb_set_next_rule(rule_link, next)
     AlRuleLink  *rule_link;
     AlRuleLink  *next;
 {
   rule_link->next = next;

 };         /* end of AlRsb_set_next_rule()  */


NORET AlRsb_set_prev_rule(rule_link, prev)
     AlRuleLink  *rule_link;
     AlRuleLink  *prev;
 {
   rule_link->previous = prev;

 };         /* end of AlRsb_set_next_rule()  */


AlRuleLink *AlRsb_get_rule(the_rsbrowser, rule_number)
     AlRSBrowser *the_rsbrowser;
     int         rule_number;
 {
   AlRuleLink  *rule_link;

   AlRsb_debug2(fprintf(stderr, 
		       "  AlRsb_get_rule(%d), searching:", rule_number));

   /* Loop through each rule link looking for the requested rule number */
   /* ----------------------------------------------------------------- */
   for(rule_link = AlRsb_get_top_rule(the_rsbrowser);
       rule_link != NULL;
       rule_link = AlRsb_get_next_rule(rule_link))
     { AlRsb_debug2(fprintf(stderr, " %d,", rule_link->rule_number));

       if (rule_link->rule_number == rule_number)
	 { AlRsb_debug2(fprintf(stderr, 
			       "\n   AlRsb_get_rule(%d) <= returns rule %d\n",
			       rule_number, rule_link->rule_number));
	   return(rule_link);
	 };
     };

   /* If unable to find the rule, return NULL */
   /* --------------------------------------- */
   AlRsb_debug2(fprintf(stderr, 
		       "\n   AlRsb_get_rule(%d) <= failed, returns NULL\n",
		       rule_number, rule_link->rule_number));
   return(NULL);

 };         /* end of AlRsb_get_rule()  */


NORET AlRsb_addto_killring(the_rsbrowser, rule_link)
     AlRSBrowser *the_rsbrowser;
     AlRuleLink  *rule_link;
 {
   /* Push this rule link onto the front of the kill ring linked list */
   /* --------------------------------------------------------------- */
   AlRsb_set_next_rule(rule_link, the_rsbrowser->killring);
   AlRsb_set_prev_rule(rule_link, NULL);
   the_rsbrowser->killring = rule_link;

 };         /* end of AlRsb_addto_killring()  */


int AlRsb_rbox_height(rule_link)
   AlRuleLink  *rule_link;
 { Dimension   height;
   ArgPack     gen_argp;

   gen_argp = ArgPack_create();
   ArgPack_add_arg(gen_argp, XmNheight, 
		   (XtArgVal) &height);
   XtGetValues(rule_link->rule_box, 
	     ArgPack_the_args(gen_argp),
	     ArgPack_num_args(gen_argp));
   ArgPack_delete(gen_argp);

   return(height);

 };         /* end of AlRsb_rbox_height()  */


NORET AlRsb_renumber_rules(the_rsbrowser, first_rule_link)
     AlRSBrowser *the_rsbrowser;
     AlRuleLink  *first_rule_link;
 {
   ArgPack     gen_argp;
   AlRuleLink  *rule_link;
   int         rule_number;
   char        *str;
   long int    current_position;
   char str2[100];

   /* Renumber this rules in the linked list starting at rule_link */
   /* and reposition their rule_boxes and widgets.                 */
   /* ------------------------------------------------------------ */

   AlRsb_debug2(fprintf(stderr, " AlRsb_renumber_rules, renumbering:"));


   /* Set cursor shape to reflect a wait */
   /*  --------------------------------- */
   MuSetWaitCursor(the_rsbrowser->shell_widget);

   /* Do all rules, if starting rule isn't specified */
   if (first_rule_link == NULL)
     { first_rule_link = AlRsb_get_top_rule(the_rsbrowser);
       if (first_rule_link == NULL)
         return;
       else
         first_rule_link->rule_number = 0;
     };

   /* Initiate needed info */
   /* -------------------- */
   rule_number = 0;
   current_position = 0;

   /* Locate starting position */
   for(rule_link = AlRsb_get_top_rule(the_rsbrowser);
       rule_link != first_rule_link;
       rule_link = AlRsb_get_next_rule(rule_link))
     { rule_number++;
       current_position += (ALRB_SPACING + AlRsb_rbox_height(rule_link));
     };

   /* Renumber and reposition each rulebox */
   /* ------------------------------------ */
   for(rule_link = first_rule_link;
       rule_link != NULL;
       rule_link = AlRsb_get_next_rule(rule_link))
     { 
       AlRsb_debug2(fprintf(stderr, " %d->", rule_link->rule_number));

       XtUnmanageChild(rule_link->rule_box);

       /* Re-number the rule */
       /* ------------------ */
       rule_link->rule_number = rule_number++;

       AlRsb_debug2(fprintf(stderr, "%d,", rule_link->rule_number));

       /* Re-label the rule_box's rule number label */
       /* ----------------------------------------- */
       if (rule_link->num_label != NULL)
	 { 
	   gen_argp = ArgPack_create();
	   /* Get the string form of the rule number */
	   str = (char *) Memory_allocate(8);
           /* Note: label is rule_link->rule_number + 1    */
           /* Because Darray is 0 based, but UI is 1 based */
	   sprintf(str, "%d", rule_number);
	   ArgPack_add_arg(gen_argp, XmNlabelString,
			   (XtArgVal)XmStringCreate(str, ALFONTS_BUTTONS));
	   XtSetValues(rule_link->num_label, 
		     ArgPack_the_args(gen_argp),
		     ArgPack_num_args(gen_argp));
	   ArgPack_delete(gen_argp);
	 };

       /* Re-position the rule_box widget */
       /* ------------------------------- */
       current_position += ALRB_SPACING;
       rule_link->y_position  = current_position;
       current_position += AlRsb_rbox_height(rule_link);

       if (rule_link->rule_box != NULL)
	 { 
	   gen_argp = ArgPack_create();
	   ArgPack_add_arg(gen_argp, XmNy, 
			(XtArgVal) ((Dimension) 0));
	   ArgPack_add_arg(gen_argp, XmNy, 
			(XtArgVal) ((Dimension) rule_link->y_position));
	   ArgPack_add_arg(gen_argp, XmNtopOffset, 
			(XtArgVal) ((Dimension) rule_link->y_position));
	   XtSetValues(rule_link->rule_box, 
		     ArgPack_the_args(gen_argp),
		     ArgPack_num_args(gen_argp));
	   ArgPack_delete(gen_argp);
	 };
       XtManageChild(rule_link->rule_box);

       /* Re-Label the Ruleeditor title, if rule is being edited */
       /* ------------------------------------------------------ */
       if (rule_link->isediting  == TRUE)
         { sprintf(str2, "Ruleset: %.30s,  Rule #%d%c", 
		   the_rsbrowser->ruleset_name,
		   1 + rule_link->rule_number, '\0');
	   AlRsb_debug(fprintf(stderr,
			  "Rulebrowser: calling re_UpdateTitle(%d, \"%s\");\n",
			  rule_link->editor_id, str2));
	   re_UpdateTitle(rule_link->editor_id, str2);
	 };
     };

   /* Set cursor back to normal shape */
   /*  ------------------------------ */
   MuSetStandardCursor(the_rsbrowser->shell_widget);

   AlRsb_debug2(fprintf(stderr, "\n"));

 };         /* end of AlRsb_renumber_rules()  */


/******************************************************************/
/********** Most often invoked  AlRulelink functions **************/
/******************************************************************/


NORET AlRsb_delete_rule(the_rsbrowser, rule_link)
     AlRSBrowser *the_rsbrowser;
     AlRuleLink  *rule_link;
 {
   AlRuleLink  *next, *prev;
   struct _AlRsb_callback *closure;
   void AlRsb_quit_func();

   the_rsbrowser->has_been_altered = TRUE;

   if (rule_link == NULL)
     { AlRsb_errmsg2("NULL Rule passed to AlRsb_delete_rule(). ",
		     "Nothing to delete.");
       return;
     }
   else if (AlRsb_islocked(rule_link) == TRUE)
     { AlRsb_errmsg2("Rule is being edited. ",
		     "You must exit the RuleEditor before deleting the rule.");
       return;
     }
   else
     { AlRsb_lock_rule(rule_link);

       /* If its being edited, close the editor, first */
       if (rule_link->isediting == TRUE)
         { closure = AlRsb_create_callback_struct(the_rsbrowser, 
						     rule_link, NULL);
           AlRsb_quit_func(rule_link->editor_id, closure);
	 };

       /* Visibly remove the rule */
       XtUnmanageChild(rule_link->rule_box);

       next = AlRsb_get_next_rule(rule_link);
       prev = AlRsb_get_prev_rule(rule_link);

       /* Re-Link chains */
       /* -------------- */
       if (next == NULL)
         { /* it is the last rule in list */
	   the_rsbrowser->last_rule = prev;
	 }
       else
	 { /* Re-Link backward chains */
           AlRsb_set_prev_rule(next, prev);
	 };
       if (prev == NULL)
	 { /* it is the first rule in list */
	   AlRsb_set_top_rule(the_rsbrowser, next);
	 }
       else
	 { /* Re-Link forward chains */
	   AlRsb_set_next_rule(prev, next);
	 };
       AlRsb_set_prev_rule(rule_link, NULL);
       AlRsb_set_next_rule(rule_link, NULL);
       AlRsb_addto_killring(the_rsbrowser, rule_link);
       if (prev == NULL)
           /* renumber & reposition all widgets */
         AlRsb_renumber_rules(the_rsbrowser,
			      AlRsb_get_top_rule(the_rsbrowser));
       else
         AlRsb_renumber_rules(the_rsbrowser, prev); /* renumber & reposition */
       AlRsb_unlock_rule(rule_link);
       return;
     };
 };         /* end of AlRsb_delete_rule()  */


AlRuleLink *AlRsb_add_rule(the_rsbrowser, the_rule, rule_number)
     AlRSBrowser *the_rsbrowser;
     AlRule      the_rule;
     int         rule_number;
 {
   int j, char_count;
   AlRuleLink *rule_link, *next, *prev;

   rule_link = (AlRuleLink *) Memory_allocate(sizeof(AlRuleLink));

   AlRsb_lock_rule(rule_link);

   rule_link->rule        = the_rule;
   rule_link->y_position  = ALRB_SPACING + (rule_number
                              * (ALRB_SPACING + ALRB_HEIGHT));
   rule_link->rule_number = rule_number;
   rule_link->isediting   = FALSE;
   rule_link->isdeleted   = FALSE;
   rule_link->editor_id   = 0;
   rule_link->text        = (char *) Memory_allocate(ALRB_TEXTLENGTH + 1);
   rule_link->text_buffer_size = ALRB_TEXTLENGTH;
   rule_link->hand_button = NULL;
   rule_link->editor_gid = NULL;
   rule_link->state_label = NULL;
   rule_link->previous    = NULL;
   rule_link->next        = NULL;

   /* Get the text of the rule */
   /* ------------------------ */
   char_count = -1;
   for(j = 0; (j < 10) && (char_count == -1); j++)
     { char_count = 
               Alruleprint(rule_link->text,                    /* buffer */
		           rule_link->text_buffer_size - 1,    /* buflen */
		           Bool_TRUE,                          /* print_type */
		           rule_link->rule);                   /* the rule */

       /* If the buffer isn't big enough, enlarge it, and try again. */
       rule_link->text = (char *) Memory_reallocate(rule_link->text,
			    rule_link->text_buffer_size + ALRB_TEXTLENGTH + 1);
       rule_link->text_buffer_size +=  (ALRB_TEXTLENGTH + 1);
     };
	 
   /* Insure a null terminated string */
   /* ------------------------------- */
   *(rule_link->text + rule_link->text_buffer_size) = '\0';

   AlRsb_debug2(fprintf(stderr, "ruletext=\"%s\"\n", rule_link->text));

   /* Get next and previous rule links */
   /* -------------------------------- */
   if (rule_number > 0)
     { if ((prev = AlRsb_get_rule(the_rsbrowser, (rule_number - 1))) == NULL)
	 prev = the_rsbrowser->last_rule;
       next = AlRsb_get_next_rule(prev);
     }
   else
     { prev = NULL;
       next = AlRsb_get_top_rule(the_rsbrowser);
     };

   /* Set current, next, and previous rule links */
   /* ------------------------------------------ */

   /* Set current rule's links */
   AlRsb_set_prev_rule(rule_link, prev);
   AlRsb_set_next_rule(rule_link, next);

   /* Set next rule's links */
   if (next != NULL)
     AlRsb_set_prev_rule(next, rule_link);
   else
     the_rsbrowser->last_rule = rule_link;

   /* Set next rule's links */
   if (prev != NULL)
     AlRsb_set_next_rule(prev, rule_link);

   /* if first rule in linked list */
   if (AlRsb_get_top_rule(the_rsbrowser) == NULL)     
     AlRsb_set_top_rule(the_rsbrowser, rule_link);
   else if (prev == NULL)
     AlRsb_set_top_rule(the_rsbrowser, rule_link);

   /* mkrulebox will set rule_link->rule_box, num_label, & text_widget */
   /* ---------------------------------------------------------------- */
   AlRsb_mkrulebox(the_rsbrowser, rule_link, rule_link->text);
   if ((next != NULL) && (prev != NULL))
     AlRsb_renumber_rules(the_rsbrowser, prev);
   else if (next != NULL)
     AlRsb_renumber_rules(the_rsbrowser, rule_link);
   AlRsb_unlock_rule(rule_link);

   return(rule_link);

 };         /* end of AlRsb_add_rule()  */



/******************************************************************/
/************ AlRSBrowser object's basic functions ****************/
/******************************************************************/


NORET AlRsb_set_top_rule(the_rsbrowser, rule_link)
     AlRSBrowser *the_rsbrowser;
     AlRuleLink  *rule_link;
 {
   the_rsbrowser->top_rule = rule_link;
   if (rule_link != NULL)
     AlRsb_set_prev_rule(rule_link, NULL);

 };         /* end of AlRsb_AlRsb_set_top_rule()  */


AlRuleLink *AlRsb_get_top_rule(the_rsbrowser)
     AlRSBrowser *the_rsbrowser;
 {
   return(the_rsbrowser->top_rule);

 };         /* end of AlRsb_AlRsb_get_top_rule()  */


Widget AlRsb_create_main_form(shell)
     Widget shell;
 { 
   Widget main_form;

   main_form = XmCreateForm(shell, "main-form",
			    main_form_res, XtNumber(main_form_res));
   XtManageChild(main_form);
   return(main_form);

 };         /* end of AlRsb_create_main_form()  */


Widget AlRsb_create_title_bar(the_rsbrowser, main_form)
     AlRSBrowser *the_rsbrowser;
     Widget	 main_form;
 {
   Widget  title_bar;
   Widget  title;
   Widget  sub_title, sub_title2;
   ArgPack argp = ArgPack_create();

   title_bar = XmCreateForm(main_form, "title-bar-form", title_bar_res,
			    XtNumber(title_bar_res));
   ArgPack_add_arg(argp, XmNbottomAttachment, (XtArgVal) XmATTACH_FORM);
   ArgPack_add_arg(argp, XmNbottomOffset, (XtArgVal) 100);
   ArgPack_add_arg(argp, XmNalignment, (XtArgVal) XmALIGNMENT_BEGINNING);
   ArgPack_add_arg(argp, XmNfontList, (XtArgVal) (the_rsbrowser->fonts));
   ArgPack_add_arg(argp, XmNunitType, (XtArgVal) Xm100TH_MILLIMETERS);
   ArgPack_add_arg(argp, XmNlabelString, 
		   (XtArgVal)XmStringCreate("Rule Set Browser",
					    ALFONTS_MAJOR_HEADING));
   title = XmCreateLabel(title_bar, "title",
			 ArgPack_the_args(argp),
			 ArgPack_num_args(argp));
   ArgPack_delete(argp);


   argp = ArgPack_create();
   ArgPack_add_arg(argp, XmNleftAttachment, (XtArgVal) XmATTACH_WIDGET);
   ArgPack_add_arg(argp, XmNleftWidget, (XtArgVal) title);
   ArgPack_add_arg(argp, XmNleftOffset, (XtArgVal) 1050);
   ArgPack_add_arg(argp, XmNrightAttachment, (XtArgVal) XmATTACH_NONE);
   ArgPack_add_arg(argp, XmNtopAttachment, (XtArgVal) XmATTACH_NONE);
   ArgPack_add_arg(argp, XmNbottomAttachment, (XtArgVal) XmATTACH_FORM);
   ArgPack_add_arg(argp, XmNbottomOffset, (XtArgVal) 150);
   ArgPack_add_arg(argp, XmNalignment, (XtArgVal) XmALIGNMENT_END);
   ArgPack_add_arg(argp, XmNfontList, (XtArgVal) (the_rsbrowser->fonts));
   ArgPack_add_arg(argp, XmNunitType, (XtArgVal) Xm100TH_MILLIMETERS);
   ArgPack_add_arg(argp, XmNlabelString, 
		   (XtArgVal)XmStringCreate("Viewing Rule Set: ",
					    ALFONTS_MINOR_HEADING));
   sub_title = XmCreateLabel(title_bar, "subtitle",
			     ArgPack_the_args(argp),
			     ArgPack_num_args(argp));
   ArgPack_delete(argp);
		

   argp = ArgPack_create();
   ArgPack_add_arg(argp, XmNleftAttachment, (XtArgVal) XmATTACH_WIDGET);

   ArgPack_add_arg(argp, XmNleftWidget, (XtArgVal) sub_title);
   ArgPack_add_arg(argp, XmNleftOffset, (XtArgVal) 150);

   ArgPack_add_arg(argp, XmNrightAttachment, (XtArgVal) XmATTACH_FORM);
   ArgPack_add_arg(argp, XmNrightOffset, (XtArgVal) 150);
   ArgPack_add_arg(argp, XmNtopAttachment, (XtArgVal) XmATTACH_NONE);
   ArgPack_add_arg(argp, XmNbottomAttachment, (XtArgVal) XmATTACH_FORM);
   ArgPack_add_arg(argp, XmNbottomOffset, (XtArgVal) 150);
   ArgPack_add_arg(argp, XmNalignment, (XtArgVal) XmALIGNMENT_BEGINNING);
   ArgPack_add_arg(argp, XmNfontList, (XtArgVal) (the_rsbrowser->fonts));
   ArgPack_add_arg(argp, XmNunitType, (XtArgVal) Xm100TH_MILLIMETERS);
   ArgPack_add_arg(argp, XmNlabelString, 
		   (XtArgVal)XmStringCreate(the_rsbrowser->ruleset_name,
					    ALFONTS_MINOR_HEADING));
   sub_title2 = XmCreateLabel(title_bar, "subtitle2",
			     ArgPack_the_args(argp),
			     ArgPack_num_args(argp));
   ArgPack_delete(argp);
		
		
	  
   XtManageChild(title);
   XtManageChild(sub_title);
   XtManageChild(sub_title2);
   XtManageChild(title_bar);
   return(title_bar);

 };         /* end of AlRsb_create_title_bar()  */


Widget AlRsb_create_button_area(the_rsbrowser, main_form)
     AlRSBrowser *the_rsbrowser;
     Widget	 main_form;
 {
   Widget  quitB, printB, expungeB, appendB,
   helpB,
   saveB,
   buttons;
   ArgPack gen_argp = ArgPack_create(),
   q_argp,
   h_argp,
   p_argp,
   s_argp;

   ArgPack_add_arg(gen_argp, XmNheight, (XtArgVal) ALRB_BUTTON_HEIGHT);
   
   ArgPack_add_arg(gen_argp, XmNresizePolicy, (XtArgVal) XmRESIZE_NONE);
   ArgPack_add_arg(gen_argp, XmNtopAttachment, (XtArgVal) XmATTACH_NONE);
   ArgPack_add_arg(gen_argp, XmNbottomAttachment, (XtArgVal) XmATTACH_FORM);
   ArgPack_add_arg(gen_argp, XmNleftAttachment, (XtArgVal) XmATTACH_FORM);
   ArgPack_add_arg(gen_argp, XmNrightAttachment, (XtArgVal) XmATTACH_FORM);
   ArgPack_add_arg(gen_argp, XmNunitType, (XtArgVal) Xm100TH_MILLIMETERS);
   ArgPack_add_arg(gen_argp, XmNresizable, (XtArgVal) False);
   
   buttons = XmCreateForm(main_form, "button-form",
			  ArgPack_the_args(gen_argp),
			  ArgPack_num_args(gen_argp));
   ArgPack_delete(gen_argp);

  /* Create the Pixmaps for rule browser, if not already loaded */
  /* ---------------------------------------------------------- */
  if (the_rsbrowser->hand_icon == NULL)
    the_rsbrowser->hand_icon = AlRsb_make_pixmap(the_rsbrowser,
						 buttons,
						 hand_icon_bits,
						 hand_icon_width, 
						 hand_icon_height);
  if (the_rsbrowser->deleted_icon == NULL)
    the_rsbrowser->deleted_icon = AlRsb_make_pixmap(the_rsbrowser,
						 buttons,
						 deleted_icon_bits,
						 deleted_icon_width, 
						 deleted_icon_height);
  if (the_rsbrowser->menu_icon == NULL)
    the_rsbrowser->menu_icon = AlRsb_make_pixmap(the_rsbrowser,
						 buttons,
						 menu_icon_bits,
						 menu_icon_width, 
						 menu_icon_height);
  if (the_rsbrowser->editor_icon == NULL)
    the_rsbrowser->editor_icon = AlRsb_make_pixmap(the_rsbrowser,
						 buttons,
						 editor_icon_bits,
						 editor_icon_width, 
						 editor_icon_height);
  if (the_rsbrowser->new_icon == NULL)
    the_rsbrowser->new_icon = AlRsb_make_pixmap(the_rsbrowser,
						 buttons,
						 new_icon_bits,
						 new_icon_width, 
						 new_icon_height);
  if (the_rsbrowser->empty_icon == NULL)
    the_rsbrowser->empty_icon = AlRsb_make_pixmap(the_rsbrowser,
						 buttons,
						 empty_icon_bits,
						 empty_icon_width, 
						 empty_icon_height);

   /* -------------- */
   /* Create Buttons */
   /* -------------- */
   gen_argp = ArgPack_create();
   gen_argp = ArgPack_duplicate_args(gen_button_res);
   ArgPack_add_arg(gen_argp, XmNfontList, (XtArgVal) the_rsbrowser->fonts);
   
   /* Create Save Button */
   /* ------------------ */
   s_argp = ArgPack_create();
   s_argp = ArgPack_copy_and_append(s_argp, gen_argp);
   ArgPack_add_arg(s_argp, XmNleftAttachment, (XtArgVal) XmATTACH_FORM);
   ArgPack_add_arg(s_argp, XmNrightAttachment, (XtArgVal) XmATTACH_NONE);
   ArgPack_add_arg(s_argp, XmNlabelString,
		   (XtArgVal)XmStringCreate("Save", ALFONTS_BUTTONS));
   saveB = XmCreatePushButton(buttons, "save-button",
			      ArgPack_the_args(s_argp),
			      ArgPack_num_args(s_argp));
   ArgPack_delete(s_argp);
   XtAddCallback(saveB, XmNactivateCallback, 
		 AlRsb_save_callback, (caddr_t) the_rsbrowser);

   /* Create Quit Button */
   /* ------------------ */
   q_argp = ArgPack_create();
   q_argp = ArgPack_copy_and_append(q_argp, gen_argp);
   ArgPack_add_arg(q_argp, XmNleftAttachment, (XtArgVal) XmATTACH_WIDGET);
   ArgPack_add_arg(q_argp, XmNleftWidget, (XtArgVal) saveB);
   ArgPack_add_arg(q_argp, XmNrightAttachment, (XtArgVal) XmATTACH_NONE);
   ArgPack_add_arg(q_argp, XmNlabelString,
		   (XtArgVal)XmStringCreate("Quit", ALFONTS_BUTTONS));
   quitB = XmCreatePushButton(buttons, "quit-button",
			      ArgPack_the_args(q_argp),
			      ArgPack_num_args(q_argp));
   ArgPack_delete(q_argp);
   XtAddCallback(quitB, XmNactivateCallback, 
		 AlRsb_quit_callback, (caddr_t) the_rsbrowser);
   
   /* Create Print Button */
   /* ------------------- */
   p_argp = ArgPack_create();
   p_argp = ArgPack_copy_and_append(p_argp, gen_argp);
   ArgPack_add_arg(p_argp, XmNleftAttachment, (XtArgVal) XmATTACH_WIDGET);
   ArgPack_add_arg(p_argp, XmNleftWidget, (XtArgVal) quitB);
   ArgPack_add_arg(p_argp, XmNlabelString,
		   (XtArgVal) XmStringCreate("Print", ALFONTS_BUTTONS));
   printB = XmCreatePushButton(buttons, "print-button",
			      ArgPack_the_args(p_argp),
			      ArgPack_num_args(p_argp));
   ArgPack_delete(p_argp);
   XtAddCallback(printB, XmNactivateCallback, 
		 AlRsb_print_callback, (caddr_t) the_rsbrowser);

   /* Create Expunge Button */
   /* --------------------- */
   p_argp = ArgPack_create();
   p_argp = ArgPack_copy_and_append(p_argp, gen_argp);
   ArgPack_add_arg(p_argp, XmNleftAttachment, (XtArgVal) XmATTACH_WIDGET);
   ArgPack_add_arg(p_argp, XmNleftWidget, (XtArgVal) printB);
   ArgPack_add_arg(p_argp, XmNlabelString,
		   (XtArgVal) XmStringCreate("Expunge", ALFONTS_BUTTONS));
   expungeB = XmCreatePushButton(buttons, "expunge-button",
			      ArgPack_the_args(p_argp),
			      ArgPack_num_args(p_argp));
   ArgPack_delete(p_argp);
   XtAddCallback(expungeB, XmNactivateCallback, 
		 AlRsb_expunge_callback, (caddr_t) the_rsbrowser);

   /* Create Append New Rule Button */
   /* ----------------------------- */
   p_argp = ArgPack_create();
   p_argp = ArgPack_copy_and_append(p_argp, gen_argp);
   ArgPack_add_arg(p_argp, XmNleftAttachment, (XtArgVal) XmATTACH_WIDGET);
   ArgPack_add_arg(p_argp, XmNleftWidget, (XtArgVal) expungeB);
   ArgPack_add_arg(p_argp, XmNlabelString,
		(XtArgVal) XmStringCreate("Append Rule", ALFONTS_BUTTONS));
   appendB = XmCreatePushButton(buttons, "append-button",
			      ArgPack_the_args(p_argp),
			      ArgPack_num_args(p_argp));
   ArgPack_delete(p_argp);
   XtAddCallback(appendB, XmNactivateCallback, 
		 AlRsb_append_new_rule_callback, (caddr_t) the_rsbrowser);

   /* Create Help Button */
   /* ------------------ */
   h_argp = ArgPack_create();
   h_argp = ArgPack_copy_and_append(h_argp, gen_argp);
   ArgPack_add_arg(h_argp, XmNrightAttachment, (XtArgVal) XmATTACH_FORM);
   ArgPack_add_arg(h_argp, XmNlabelString,
		   (XtArgVal)XmStringCreate("Help", ALFONTS_BUTTONS));
   helpB = XmCreatePushButton(buttons, "help-button",
			      ArgPack_the_args(h_argp),
			      ArgPack_num_args(h_argp));
   ArgPack_delete(h_argp);
   AlRsb_help_attach(the_rsbrowser, helpB);

   ArgPack_delete(gen_argp);

   /* Manage all Children (maybe change to 1 ManageChildren call in future) */
   /* --------------------------------------------------------------------- */
   XtManageChild(saveB);
   XtManageChild(quitB);
   XtManageChild(printB);
   XtManageChild(expungeB);
   XtManageChild(appendB);
   XtManageChild(helpB);
   XtManageChild(buttons);
   return(buttons);

 };         /* end of AlRsb_create_button_area()  */


void AlRsb_attach_rules(the_rsbrowser)
   AlRSBrowser *the_rsbrowser;
{
  Darray the_darray;
  int d_len, i;

  the_darray = Darray_create();
  AlRuleSet_get_rules(the_rsbrowser->the_ruleset, the_darray);
  d_len = Darray_len(the_darray);

  for(i = 0; i < d_len; i++)
    { AlRsb_debug2(fprintf(stderr,
			  "attach rule #%d of %d rules in ruleset \"%s\"\n",
			  i, d_len, the_rsbrowser->ruleset_name));
      AlRsb_add_rule(the_rsbrowser,                          
		     Darray_get(the_darray, (unsigned) i),  /* the rule */
		     i);
    };

  Darray_destroy(the_darray);

 };         /* end of AlRsb_attach_rules()  */


Widget AlRsb_create_io(scrollW)
     Widget  scrollW;
 {
        Widget  io,
                tmp_line = (Widget) NULL;
        ArgPack argp = ArgPack_create();
        EntCode i;

	argp = ArgPack_duplicate_args(rule_working_area_res);

	ArgPack_add_arg(argp, XmNrightAttachment, (XtArgVal) XmATTACH_WIDGET);
	ArgPack_add_arg(argp, XmNrightWidget, (XtArgVal) scrollW);

	io = XmCreateRowColumn(scrollW, "working-area", ArgPack_the_args(argp),
                                 ArgPack_num_args(argp));
        ArgPack_delete(argp);

        return(io);

 };         /* end of AlRsb_create_io()  */

Widget AlRsb_create_rule_area(the_rsbrowser, main_form, above, below)
     AlRSBrowser *the_rsbrowser;
     Widget  main_form;
     Widget  above, below;
 {
   Widget  rule_area;
   ArgPack argp;

   argp = ArgPack_create();
   argp = ArgPack_duplicate_args(rule_area_res);
   ArgPack_add_arg(argp, XmNtopAttachment, (XtArgVal) XmATTACH_WIDGET);
   ArgPack_add_arg(argp, XmNtopWidget, (XtArgVal) above);
   ArgPack_add_arg(argp, XmNbottomAttachment, (XtArgVal) XmATTACH_WIDGET);
   ArgPack_add_arg(argp, XmNbottomWidget, (XtArgVal) below);
   rule_area = XmCreateScrolledWindow(main_form, "scroll-window",
			    ArgPack_the_args(argp), ArgPack_num_args(argp));
   ArgPack_delete(argp);

   /* Create a working area within the scrolled window */
   argp = ArgPack_create();
   ArgPack_add_arg(argp, XmNworkWindow, 
		   (XtArgVal) (the_rsbrowser->rulebox_form =
			       AlRsb_create_io(rule_area)));
   XtSetValues(rule_area, ArgPack_the_args(argp), ArgPack_num_args(argp));
   ArgPack_delete(argp);

   AlRsb_attach_rules(the_rsbrowser);
   XtManageChild(the_rsbrowser->rulebox_form);
   XtManageChild(rule_area);

   AlRsb_debug2(fprintf(stderr,
		       "Exiting AlRsb_create_rule_area: rule_area = %d\n",
		       (int)  rule_area));
   return(rule_area);

 };         /* end of AlRsb_create_rule_area()  */


AlRSBrowser *AlRsb_create(shell, ruleset_name, the_ruleset, 
			  AppCont, the_display,
			  exit_function)
     Widget        shell;
     char          *ruleset_name;
     AlRuleSet     the_ruleset;
     XtAppContext  AppCont;
     Display       *the_display;
     VOIDP_FUNCPTR exit_function;
 {
   int i;
   AlRSBrowser *the_rsbrowser;
   Widget      main_form;
   XtActionsRec action_list[] = {
     {"AlRsb_hand_grab",  AlRsb_hand_grab},
     {"AlRsb_menu_action",  AlRsb_menu_action},
     {NULL, NULL}};

   /* ------------------------------------------------------- */
   /* Create new Rule Set Browser and intialize its variables */
   /* ------------------------------------------------------- */

   the_rsbrowser = (AlRSBrowser *) Memory_allocate(sizeof(AlRSBrowser));
   XtAppAddActions(AppCont, action_list, 2);

   /* general variables */
   /* ----------------- */
   the_rsbrowser->errbox_intervalid = 0; /* interval id of popped up errbox */
   the_rsbrowser->ruleset_name = ruleset_name;
   the_rsbrowser->the_ruleset = the_ruleset;
   the_rsbrowser->number_of_open_ruleeditors = 0;
   the_rsbrowser->has_been_altered = FALSE;
   the_rsbrowser->top_rule = (AlRuleLink *) NULL;
   the_rsbrowser->last_rule = (AlRuleLink *) NULL;
   the_rsbrowser->killring = (AlRuleLink *) NULL;
   the_rsbrowser->exit_function = (VOIDP_FUNCPTR) exit_function;

   /* Pixmaps */
   /* ------- */
   the_rsbrowser->empty_icon = NULL;
   the_rsbrowser->new_icon = NULL;
   the_rsbrowser->editor_icon = NULL;
   the_rsbrowser->hand_icon = NULL;
   the_rsbrowser->menu_icon = NULL;
   the_rsbrowser->deleted_icon = NULL;

   /* general X info */
   /* -------------- */
   the_rsbrowser->AppCont = (XtAppContext) AppCont;
   the_rsbrowser->the_display = (Display *) the_display;
   the_rsbrowser->the_screen = (int) DefaultScreen(the_display);

   /* Widgets */
   /* ------- */
   the_rsbrowser->shell_widget = shell;
   the_rsbrowser->rulebox_form = (Widget) NULL;
   the_rsbrowser->errbox = (Widget) NULL;
   the_rsbrowser->errlabel = (Widget) NULL;

   main_form = AlRsb_create_main_form(shell);
   the_rsbrowser->fonts = AlFonts_get(shell);
   AlRsb_create_rule_area(the_rsbrowser, 
			  main_form, 
			  AlRsb_create_title_bar(the_rsbrowser, main_form),
			  AlRsb_create_button_area(the_rsbrowser, main_form));

  /* Create pixmaps for ruleeditor distinguishing borders */
  /* ---------------------------------------------------- */
  for(i = 0; i < ALRSB_NUM_OF_PIXMAP_NAMES; i++)
    { AlRsb_grey_pixmap[i] = AlRsb_make_greypixmap(the_rsbrowser,
					           main_form,
					           AlRsb_grey_bits[i],
					           AlRsb_grey_width, 
					           AlRsb_grey_height);
    };

   return(the_rsbrowser);

 };         /* end of AlRsb_create()  */


/*********************************************************************/
/*************************** Main Program ****************************/
/*********************************************************************/


main(argc, argv)
     int argc;
     char *argv[];
 {
   Widget shell;          /* the top level application shell      */
   XtAppContext AppCont;
   Display *the_display;
   extern void XtMainLoop();
   AlRSBrowser *the_rsbrowser;
   char *ruleset_name;
   AlRuleSet the_ruleset;
   int n_rs_flag = FALSE;
   ArgPack argp;
   int i = 1;
   AlH_MASK switch_type, switch_code;
   char *switch_arg;

   /* Intialize Argus */
   /* --------------- */
   Al_init();
   AlRsb_debug2(fprintf(stderr, "Al_init just executed.\n"));
   AlFonts_init();
   AlUI_Initialize(NULL);
  
   argp = ArgPack_create();

   /* Initialize a toplevel root shell widget */
   /* --------------------------------------- */
   XtToolkitInitialize();
   AppCont = XtCreateApplicationContext();
   the_display = XtOpenDisplay(AppCont, NULL, "rulebrowser", "Argus",
		    NULL, 0, &argc, argv); 
   if (the_display == NULL)
     { XtWarning("RuleBrowser: Unable to open the display. Exiting ...");
       exit(-1);
     };

   ArgPack_add_arg(argp, XmNkeyboardFocusPolicy, XmEXPLICIT);
   shell = XtAppCreateShell(argv[0], "Argus",
			    vendorShellWidgetClass, the_display,
			    ArgPack_the_args(argp),
			    ArgPack_num_args(argp));
   ArgPack_delete(argp);

   /* Initialize Mu (Motif Utilities) */
   /* ------------------------------- */
   MuInitialize(shell);

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

  if ((argc < 2) || (argc > 4))
    { AlHelp_non_standard_usage("rulebrowser [-force] ruleset");
      AlHelp_usage("rulebrowser",
		   (ALH_help | ALH_force), ALH_none,
		   ALH_none, ALH_none,
		   ALH_none, ALH_ruleset);
      exit(0);
    }
  else if (AlHelp_user_requested_help(argc, argv) ==  Bool_TRUE)
    { AlHelp_non_standard_usage("rulebrowser [-force] ruleset");
      AlHelp_info("rulebrowser",
		       (ALH_help | ALH_force), ALH_none,
		       ALH_none, ALH_none,
		       ALH_none, ALH_ruleset,
		       notes,
		       examples,
		       "rulebrowser -help");
      exit(0);
    }
  else 
   { i = 1;
     while(Bool_TRUE == AlHelp_get_arg(argv, argc, &i,
                                      &switch_type, &switch_code, &switch_arg))
      { 
	switch (switch_type)
          { case ALH_no_arg_switch:

		  switch(switch_code)
		    { case ALH_force:
			  /* ruleset is to be created new */
			    ruleset_name = switch_arg;
			    n_rs_flag = TRUE;
			    break;

		      default:
			    AlHelp_non_standard_usage(
                               "rulebrowser [-force] ruleset");
			    AlHelp_usage("rulebrowser",
					 (ALH_help | ALH_force), ALH_none,
					 ALH_none, ALH_none,
					 ALH_none, ALH_ruleset);
		            Al_fatal_error2(
		       "%s :: This switch is not valid for this program: %s\n",
			     argv[0],
			     AlHelp_mask_to_switch(ALH_object_arg_switch,
						   switch_code));
			    break;
		    };
	          break;

            case ALH_fixed_arg_switch:

		  AlHelp_non_standard_usage("rulebrowser [-force] ruleset");
		  AlHelp_usage("rulebrowser",
			       (ALH_help | ALH_force), ALH_none,
			       ALH_none, ALH_none,
			       ALH_none, ALH_ruleset);
		  Al_fatal_error2(
		       "%s :: This switch is not valid for this program: %s\n",
			     argv[0],
			     AlHelp_mask_to_switch(ALH_object_arg_switch,
						   switch_code));
		  break;

            case ALH_object_arg_switch:

		  switch(switch_code)
		    { case ALH_ruleset:

		            if (ruleset_name == NULL)
			      ruleset_name = switch_arg;
			    else 
			      { AlHelp_non_standard_usage(
                                   "rulebrowser [-force] ruleset");
				AlHelp_usage("rulebrowser",
					 (ALH_help | ALH_force), ALH_none,
					 ALH_none, ALH_none,
					 ALH_none, ALH_ruleset);
				Al_fatal_error2(
	    "rulebrowser :: Ruleset was specified twice, \"%s\" and \"%s\".\n",
			          ruleset_name, switch_arg);
			      };
			    break;

		      default:
			    AlHelp_non_standard_usage(
                                   "rulebrowser [-force] ruleset");
			    AlHelp_usage("rulebrowser",
					 (ALH_help | ALH_force), ALH_none,
					 ALH_none, ALH_none,
					 ALH_none, ALH_ruleset);
		            Al_fatal_error2(
		       "%s :: This switch is not valid for this program: %s\n",
			     argv[0],
			     AlHelp_mask_to_switch(ALH_object_arg_switch,
						   switch_code));
			    break;
		    };
	          break;

            case ALH_not_a_switch:

		  if (ruleset_name == NULL)
		    ruleset_name = switch_arg;
		  else
		    { AlHelp_non_standard_usage(
                                   "rulebrowser [-force] ruleset");
		      AlHelp_usage("rulebrowser",
					 (ALH_help | ALH_force), ALH_none,
					 ALH_none, ALH_none,
					 ALH_none, ALH_ruleset);
		      Al_fatal_error2(     /* Extra parameters, Fatal Error. */
		        "%s ::  Error: Invalid extra argument: %s\n",
			argv[0], switch_arg);
		    };
	          break;

            case ALH_bad_switch: 

                  AlHelp_non_standard_usage(
                                   "rulebrowser [-force] ruleset");
		  AlHelp_usage("rulebrowser",
			       (ALH_help | ALH_force), ALH_none,
			       ALH_none, ALH_none,
			       ALH_none, ALH_ruleset);
                  Al_fatal_error2(
                     "%s :: Invalid switch or switch argument specified: %s\n",
		     argv[0], switch_arg);
	          break;

            default:
		  AlHelp_non_standard_usage("rulebrowser [-force] ruleset");
		  AlHelp_info("rulebrowser",
			      (ALH_help | ALH_force), ALH_none,
			      ALH_none, ALH_none,
			      ALH_none, ALH_ruleset,
			      notes,
			      examples,
			      "rulebrowser -help");
                  Al_fatal_error2(
                     "%s :: Invalid switch or switch argument specified: %s\n",
		     argv[0], ((switch_arg == NULL) ? "?" : switch_arg));
		  break;
	  };
      };       /* end of while()  */
   };     /* end of else */

  /* Create a new rule set, if required. */   
  if (n_rs_flag == TRUE)
    { if ((the_ruleset = AlRSreg_find (ruleset_name)) == NULL)
	{ the_ruleset = AlRuleSet_create(
                            "New Ruleset comment string goes here.",
		            ruleset_name,
			    (time_t) 0, (time_t) 0, (Darray) NULL);
          if (the_ruleset == NULL)
	    { Al_fatal_error2(
	    "%s: Unable to create Rule Set. Bad rule set name specified: %s\n",
	        argv[0],
	        ruleset_name);
	    }
          else
	    AlRSreg_register(the_ruleset);
	};
    }
  else if ((the_ruleset = AlRSreg_find (ruleset_name)) == NULL)
    { AlHelp_non_standard_usage("rulebrowser [-force] ruleset");
      AlHelp_usage("rulebrowser",
		   (ALH_help | ALH_force), ALH_none,
		   ALH_none, ALH_none,
		   ALH_none, ALH_ruleset);
      Al_fatal_error2(
     "%s: Can't open Rule Set. To create a new ruleset, use \"-force %s\".\n",
		      argv[0],
		      ruleset_name);
    };
  


   the_rsbrowser = AlRsb_create(shell, ruleset_name, the_ruleset,
				AppCont, the_display,
			       (VOIDP_FUNCPTR) AlRsb_exit_function);

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

   MuSetStandardCursor(shell);

   XtAppMainLoop(AppCont);           /* Infinite event loop */

 };        /* end of main() */
