      /********************************************************/
      /*                   Widget-Builder               (3)   */
      /* This program was written by Brian R. Gardner, 1988.  */
      /* It was created as a visual, easy to use, technique   */
      /* for rapid proto-typing of user interfaces. It allows */
      /* its user to design the layout of an X-window based   */
      /* user interface, complete with sub-windows, buttons,  */
      /* labels, and other "widgets". This program will also  */
      /* serve as a programmer's aid by writing out to a file */
      /* the source code required to re-generate the created  */
      /* visual user interface. The code generated is usually */
      /* substantial, reflecting immense savings in the time  */
      /* neccessary to program using X-windows.               */
      /*    Note that this program is only a simple test      */
      /* version. It was the author's first introduction to   */
      /* the Athena environment, as well as X-windows and the */
      /*  X-Toolkit. It was written in 2 weeks.               */
      /*    This was written under the roof of Project Athena */
      /* at Massachusetts Institute of Technology, by         */
      /* Brian Gardner (DEC), and hence reasonably available. */
      /* Read that as "FREE"         :-)                      */
      /* with the usual friendly restrictions.                */
      /********************************************************/

     /************************************************************/
     /* Copyright 1988, Massachusetts Institute of Technology.   */
     /* See X(1) for a full statement of rights and permissions. */
     /************************************************************/

#include "wb_include.h"
#include "savemfileP.h"

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

void prstr_widget(buffer, node)
     MailBuffer *buffer;
     WidgetNode *node;
  {
    AlMB_beginfield(buffer);

    /* Load the keyword into the field */
    AlMB_prstring(buffer, "X-mmm-");
    AlMB_printeger(buffer, node->mmm_id);
    AlMB_prstring(buffer, ": ");

    AlMB_prstring(buffer, node->type);
    AlMB_prstring(buffer, ", ");

    AlMB_esc_prstring(buffer, node->name, ',');
    AlMB_prstring(buffer, ", ");

    AlMB_printeger(buffer, (node->parent_node != NULL)
                           ? (node->parent_node)->mmm_id
                           : -1);
    AlMB_prstring(buffer, ", ");

    /* Print all of the properties of the widget to the string buffer */
    (node->prstr_func)(buffer, node);

    AlMB_endfield(buffer);

  };        /* end of prstr_widget()  */

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

void prstr_vwidget(buffer, node)
     VOIDP buffer;
     WidgetNode * node;
  {
    prstr_widget((MailBuffer *) buffer, node);

  };        /* end of prstr_vwidget()  */

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

void set_mmm_id(id_ptr, node)
     VOIDP id_ptr;
     WidgetNode *node;
  { int *id;

    id = (int *) id_ptr;
    WN_set_mmm_id(node, *id);    /* Set the widget node's mmm_id */
    *id = *id + 1;

  };        /* end of prstr_vwidget()  */

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

void prstr_all_widgets(start_widget, buffer, start_mmm_id)
     WidgetNode *start_widget;
     MailBuffer *buffer;
     int start_mmm_id;
  { 
    void prstr_vwidget(), set_mmm_id();
    int mmm_id;

    /* Set a unique id for each widget to be printed */
    mmm_id = start_mmm_id;
    traverse_widgets_nodes(start_widget, set_mmm_id, (VOIDP) &mmm_id);

    /* Print each widget as a mail-field-looking str into string buffer */
    traverse_widgets_nodes(start_widget, prstr_vwidget, (VOIDP) buffer);

  };            /* end of prstr_all_widgets()  */

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

void prstr_basic_arg_list(buffer, node)
     MailBuffer *buffer;
     WidgetNode *node;
 { 
   /* Output all information gathered by load_basic_arg_list() */
   /* -------------------------------------------------------- */
   /* label */
   if ((strcmp(node->type, "form") != 0)
       && (strcmp(node->type, "box") != 0)
       && (strcmp(node->type, "viewport") != 0)
       && (strcmp(node->type, "vPane") != 0)
       && (strcmp(node->type, "ascii text") != 0))
     {
       AlMB_esc_prstring(buffer, XtNlabel, ',');
       AlMB_prstring(buffer, ", ");
       AlMB_esc_prstring(buffer, label, ',');
       AlMB_prstring(buffer, ", ");
     };
   /* textual justification */
   AlMB_esc_prstring(buffer, XtNjustify, ',');
   AlMB_prstring(buffer, ", ");
   if (justify == XtJustifyCenter)
     AlMB_prstring(buffer, "XtJustifyCenter");
   else if (justify == XtJustifyRight)
     AlMB_prstring(buffer, "XtJustifyRight");
   else
     AlMB_prstring(buffer, "XtJustifyLeft");
   AlMB_prstring(buffer, ", ");
   /* border width */
   AlMB_esc_prstring(buffer, XtNborderWidth, ',');
   AlMB_prstring(buffer, ", ");
   AlMB_printeger(buffer, borderwidth);
   AlMB_prstring(buffer, ", ");
   /* height */
   AlMB_esc_prstring(buffer, XtNheight, ',');
   AlMB_prstring(buffer, ", ");
   AlMB_printeger(buffer, height);
   AlMB_prstring(buffer, ", ");
   /* width */
   AlMB_esc_prstring(buffer, XtNwidth, ',');
   AlMB_prstring(buffer, ", ");
   AlMB_printeger(buffer, width);
   AlMB_prstring(buffer, ", ");
   /* x position */
   AlMB_esc_prstring(buffer, XtNx, ',');
   AlMB_prstring(buffer, ", ");
   AlMB_printeger(buffer, x);
   AlMB_prstring(buffer, ", ");
   /* y position */
   AlMB_esc_prstring(buffer, XtNy, ',');
   AlMB_prstring(buffer, ", ");
   AlMB_printeger(buffer, y);
   AlMB_prstring(buffer, ", ");
   /* thickness of highlight  */
   AlMB_esc_prstring(buffer, XtNhighlightThickness, ',');
   AlMB_prstring(buffer, ", ");
   AlMB_printeger(buffer, highlightThickness);
   AlMB_prstring(buffer, ", ");
   /* border color */
   AlMB_esc_prstring(buffer, XtNborderColor, ',');
   AlMB_prstring(buffer, ", ");
   AlMB_printeger(buffer, borderColor);
   AlMB_prstring(buffer, ", ");
   /* foreground color */
   AlMB_esc_prstring(buffer, XtNforeground, ',');
   AlMB_prstring(buffer, ", ");
   AlMB_printeger(buffer, foreground);
   AlMB_prstring(buffer, ", ");
   /* background color */
   AlMB_esc_prstring(buffer, XtNbackground, ',');
   AlMB_prstring(buffer, ", ");
   AlMB_printeger(buffer, background);
   AlMB_prstring(buffer, ", ");

  };            /* end of prstr_basic_arg_list()  */

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

void prstr_form_arg_list(buffer)
     MailBuffer *buffer;
  {
    WidgetNode *w;

   /* Output all information gathered by load_form_arg_list() */
   /* ------------------------------------------------------- */
   /* vertical distance */
   AlMB_esc_prstring(buffer, XtNvertDistance, ',');
   AlMB_prstring(buffer, ", ");
   AlMB_printeger(buffer, vertDistance);
   AlMB_prstring(buffer, ", ");
   /* horizontal distance */
   AlMB_esc_prstring(buffer, XtNhorizDistance, ',');
   AlMB_prstring(buffer, ", ");
   AlMB_printeger(buffer, horizDistance);
   AlMB_prstring(buffer, ", ");
   /* left linkage */
   AlMB_esc_prstring(buffer, XtNleft, ',');
   AlMB_prstring(buffer, ", ");
   AlMB_esc_prstring(buffer, chain(left), ',');
   AlMB_prstring(buffer, ", ");
   /* right linkage */
   AlMB_esc_prstring(buffer, XtNright, ',');
   AlMB_prstring(buffer, ", ");
   AlMB_esc_prstring(buffer, chain(right), ',');
   AlMB_prstring(buffer, ", ");
   /* top linkage */
   AlMB_esc_prstring(buffer, XtNtop, ',');
   AlMB_prstring(buffer, ", ");
   AlMB_esc_prstring(buffer, chain(top), ',');
   AlMB_prstring(buffer, ", ");
   /* bottom linkage */
   AlMB_esc_prstring(buffer, XtNbottom, ',');
   AlMB_prstring(buffer, ", ");
   AlMB_esc_prstring(buffer, chain(bottom), ',');
   AlMB_prstring(buffer, ", ");
   /* resizable, boolean */
   AlMB_esc_prstring(buffer, XtNresizable, ',');
   AlMB_prstring(buffer, ", ");
   AlMB_prstring(buffer, ((resizable == FALSE) ? "FALSE" : "TRUE"));
   AlMB_prstring(buffer, ", ");
   /* widget linked to horizontally */
   if (fromHoriz != NULL)
     {
       w = find_widgets_node(fromHoriz, HeadWidgetList);
       AlMB_esc_prstring(buffer, XtNfromHoriz, ',');
       AlMB_prstring(buffer, ", ");
       AlMB_printeger(buffer,
		      ((w == NULL) ? -1 : w->mmm_id));
       AlMB_prstring(buffer, ", ");
     };
   /* widget linked to vertically */
   if (fromVert != NULL)
     {
       w = find_widgets_node(fromVert, HeadWidgetList);
       AlMB_esc_prstring(buffer, XtNfromVert, ',');
       AlMB_prstring(buffer, ", ");
       AlMB_printeger(buffer,
		      ((w == NULL) ? -1 : w->mmm_id));
       AlMB_prstring(buffer, ", ");
     };

  };            /* end of prstr_form_arg_list()  */

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

void prstr_general_widget(buffer, node)
     MailBuffer *buffer;
     WidgetNode *node;
 { 
   int i;

   if (node->name == NULL)      /* If widget is un-named, name it first */
     node->name = genname();

   /* Gather useful information about this widget by querying the widget */
   /* ------------------------------------------------------------------ */
   /* load arg_list with useful properties */
   i = load_basic_arg_list(0);

   /* Load Form related instance variables, about placement */
   i = load_form_arg_list(i);
   XtSetArg(arg_list[i], NULL, NULL);

   /* Gather all this information from the current widget */
   XtGetValues(node->widget, arg_list, i);

   /* Print out varName property of this widget node */
   /* ---------------------------------------------- */
   AlMB_prstring(buffer, "varName, ");
   AlMB_esc_prstring(buffer,
		     (node->varName == NULL)
		       ? "NULL"
		       : node->varName,
		     ',');
   AlMB_prstring(buffer, ", ");

   /* Print out the information gathered */
   /* ---------------------------------- */
   prstr_basic_arg_list(buffer, node);
   prstr_form_arg_list(buffer);

   /* Print out information in WidgetNode (node) structure, & create widget */
   /* --------------------------------------------------------------------- */
   /* font info */
   AlMB_esc_prstring(buffer, XtNfont, ',');
   AlMB_prstring(buffer, ", ");
   AlMB_esc_prstring(buffer, 
		     ((node->font != NULL) ? node->font : "fixed"), ',');
   AlMB_prstring(buffer, ", ");
   /* string info */
   AlMB_esc_prstring(buffer, XtNstring, ',');
   AlMB_prstring(buffer, ", ");
   AlMB_esc_prstring(buffer, node->string, ',');
   AlMB_prstring(buffer, ", ");

 };             /* end of prstr_general_widget()  */

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