/* This code is designed to plot snmp datas in a file with a specified format. 
 * "e40-rtr-dungeon.eth" has the format used for this code. 
 * This code is implemented with athena toolkit intrinsics.
 * aplot.c is the original template of this code.
 */

#include <stdio.h> 
#include <stdlib.h>
#include <string.h>
#include <strings.h> 
#include <ctype.h> 

#include <X11/Intrinsic.h> 
#include <X11/StringDefs.h> 
#include <X11/Shell.h> 

#include <X11/At/Plotter.h>
#include <X11/At/XYAxis.h>
#include <X11/At/XYLinePlot.h>

#include <Xm/Xm.h>
#include <Xm/BulletinB.h>
#include <Xm/PushB.h>
#include <Xm/Label.h>
#include <Xm/Form.h>
#include <Xm/RowColumn.h>
#include <Xm/CascadeBG.h>
#include <Xm/XmP.h>
#include <Xm/ToggleB.h>
#include <Xm/Frame.h>
#include <Xm/MainW.h>
#include <Xm/Text.h>

#define ROWNUM 94 /* number of rows in the data file */
#define COLUMN 23 /* number of columns in the first line of the data file */ 

struct point {
  double xval;
  double yval;
}; /* each point has x and y coordinates */

typedef struct point points[ROWNUM]; /* each curve has ROWNUM(94) points */
points curve[5]; /* 5 : max number of courves */

static int num_line = -1;  /* number of lines to be plotted */
static int del_num;

static char *plotfilename = NULL;
static Widget data_pulldown;
static Widget addform;
static Widget warning;
Widget xpos_label = NULL;
Widget x_text = NULL;
Widget ypos_label = NULL;
Widget y_text = NULL;
Widget b_line[5];

char *snmp_names[] = { 
  "interface",
  "time",
  "year",
  "month", 
  "day" ,
  "wday", 
  "hour", 
  "min", 
  "sec", 
  "ifInOctets_5",
  "ifInUcastPkts_5" ,
  "ifInErrors_5",
  "ifOutOctets_5",
  "ifOutUcastPkts_5",
  "ifOutErrors_5", 
  "locIfInRunts_5",
  "locIfInGiants_5",
  "locIfInCRC_5", 
  "locIfInFrame_5", 
  "locIfInOverrun_5", 
  "locIfInIgnored_5", 
  "locIfInAbort_5", 
  "locIfResets_5"
};

static Widget plotter;

/* stores the chosen line's identification number */

static void MenuSelectD(w, client_data, cbs)
     Widget w;
     void *client_data;
     XmListCallbackStruct cbs;  /* call_data */
{ 

}

/*
 *  Reads in the data from the file
 *  Creates line widget and attach the data onto the line
 *  Attaches the newly created line to the existing linked lists of lines
 */

void MakeData(x_axis, y_axis)
     int x_axis, y_axis; /* column number of the data to be plotted 
			  * at x axis and y axis.
			  */
{ 
  FILE *fp;
  char *newline, nline[BUFSIZ]; /* pointers used to handle datas */
  int column_num, point_num = 0;
  char *data, *ptr;
  char *line_name;
  char tempbuf[50];
  
  fp = fopen(plotfilename,"r");
  fgets(nline, sizeof(nline), fp);  /* skips the first line of the file */
    
  while (fgets(nline, sizeof(nline), fp))/*gets a new line from the data file*/
    {
      column_num = 0; /* column number */
      newline = nline; 
      
      while (ptr = (char *)index(newline, ' '))  /* gets name */
        {
          *ptr++ = '\0';
          data = newline;
          
          /* attach the data to x - axis */
          if ( column_num == x_axis ) {
	    curve[num_line][point_num].xval = atoi(data);
	  }
	  
          /* attach the data to y - axis */
	  
	  if (column_num == y_axis) {
	    curve[num_line][point_num].yval = atoi(data);
	  }
	  
          if (column_num == (COLUMN - 1)) 
            ++point_num; /* increment y each time a new line is read */
	  
          newline = ptr;
          ++column_num;
        }
    }

  fclose(fp);
 
  /*
   *  makes a string for the line name with the snmp names stored in
   *  snmp_lines
   */

  line_name = malloc(sizeof(char)*
		     ((strlen(snmp_names[x_axis])+
		       strlen(snmp_names[y_axis]))+5));

  sprintf(line_name, "%s%s%s", snmp_names[x_axis],
	  " .vs ",snmp_names[y_axis]);
  printf("%s\n", line_name);

  
  sprintf(tempbuf, "line%d", num_line);

  b_line[num_line] = XtVaCreateWidget(tempbuf,
				      atXYLinePlotWidgetClass, plotter,
				      XtNlegendName, line_name,
				      XtNplotLineType, AtLineDOTTED,  
				      NULL);
  
  free(line_name);
  
  /*
   *      Attach the data to the lines 
   */
  
  printf("num_line: %d\n",num_line);
  AtXYLinePlotAttachData(b_line[num_line],
			 (XtPointer)&curve[num_line][0].xval, 
			 AtDouble, sizeof(struct point),
			 (XtPointer)&curve[num_line][0].yval, 
			 AtDouble, sizeof(struct point),
			 1, ROWNUM);
  
}

/*
 *      The plotter widgets
 */

static Widget xaxis, yaxis;
char *xname, *yname;

/*
 *      Create the plotter, the axes and the lines
 */

void select_callback(widget, client_data, call_data) /* ARGSUSED */
     Widget widget;
     XtPointer client_data;
     AtSelectCallbackData *call_data;
{
  char *r, *w;

  if(call_data->reason == AtSelectSELECTED) {
    r = "SELECTED";
    w = XtName(call_data->widget);
  }
  else {
    r = "DESELECTED";
    w = "-----";
  }
  printf("Select callback: widget: %s, reason: %s\n", w, r);
}

/*
 *      The button callbacks
 */

static Widget addform, deleteform;
static Widget file_selection;

void quit_callback()
{
  exit(0);
}

/*ARGSUSED*/
static void PopupFileSelection(w, client_data, call_data) /* ARGSUSED */
     Widget w;
     XtPointer client_data;/* cast to topLevel */
     XtPointer call_data;
{
  Widget topLevel = (Widget) client_data;
  XtSetSensitive(topLevel, FALSE);
  
  XtManageChild(file_selection);
  XtUnmanageChild( XmFileSelectionBoxGetChild( file_selection, 
					       XmDIALOG_HELP_BUTTON ) );
  XtUnmanageChild( XmFileSelectionBoxGetChild( file_selection, 
					       XmDIALOG_APPLY_BUTTON ) );
}     

void file_cancel_callback();
void CreateAddbutton();

void file_ok_callback(widget, client_data, call_data)
     Widget widget;
     XtPointer client_data;
     XmSelectionBoxCallbackStruct *call_data;
{ 
  Widget topLevel = (Widget) client_data;
  char *msg;
  XmString xms2[COLUMN];
  Arg args[2];
  Cardinal argcount;
  int i;
  
  XtRemoveCallback(file_selection, XmNokCallback, file_ok_callback, NULL);
  XtRemoveCallback(file_selection, XmNcancelCallback, 
		   file_cancel_callback, NULL);
  XmStringGetLtoR(call_data->value, XmSTRING_DEFAULT_CHARSET, &plotfilename);
  CreateAddbutton(topLevel);
  XtUnmanageChild(file_selection);
  XtSetSensitive(topLevel, TRUE);
}
 
void file_cancel_callback(widget, client_data, call_data)
  Widget widget;
  XtPointer client_data;
  XmSelectionBoxCallbackStruct *call_data;
{
  Widget topLevel = (Widget) client_data;

  XtRemoveCallback(file_selection, XmNokCallback, file_ok_callback, NULL);
  XtRemoveCallback(file_selection, XmNcancelCallback, 
		   file_cancel_callback, NULL);
  XtUnmanageChild(file_selection);
  XtSetSensitive(topLevel, TRUE);
}

static int x, y;

static void MenuSelectX(w, client_data, cbs) /* ARGSUSED */
     Widget w;
     void *client_data;
     XmListCallbackStruct cbs;  /* call_data */
{
  x = (int) cbs.item_position;  
  printf("X: %d \n", x);
}

static void MenuSelectY(w, client_data, cbs) /* ARGSUSED */
     Widget w;
     void *client_data;
     XmListCallbackStruct cbs;  /* call_data */
{
  y = (int) cbs.item_position;  
  printf("Y: %d \n", y);
}

void PopupAddForm(w, client_data, call_data) /* ARGSUSED */
     Widget w;
     XtPointer client_data; /* cast to topLevel */
     XtPointer call_data;
{
  Widget topLevel = (Widget) client_data;

  XtSetSensitive(topLevel, FALSE);
  
  if ( num_line < 4 )
    {XtManageChild(addform);}
  else 
    {XtManageChild(warning);}

}

/*ARGSUSED*/

void AddOK(w, client_data, call_data) /* ARGSUSED */
Widget w;
XtPointer client_data; /* cast to dialog */
XtPointer call_data;
{
  Widget dialog = (Widget) client_data;
  XtUnmanageChild(addform);
  XtSetSensitive(dialog, TRUE);
  printf("x: %d, y: %d\n", x, y);
  num_line = num_line + 1; 
  MakeData(x, y);
}

void AddformDone(w, client_data, call_data) /* ARGSUSED */
     Widget w;
     XtPointer client_data; /* cast to dialog */
     XtPointer call_data;
{
  Widget dialog = (Widget) client_data;
  XtUnmanageChild(addform);
  XtSetSensitive(dialog, TRUE);
}

void WarnOK(w, client_data, call_data) /* ARGSUSED */
     Widget w;
     XtPointer client_data; /* cast to dialog */
     XtPointer call_data;
{
  Widget dialog = (Widget) client_data;
  XtUnmanageChild(warning);
  XtSetSensitive(dialog, TRUE);
}


void PopupDeleteForm(w, client_data, call_data) /* ARGSUSED */
     Widget w;
     XtPointer client_data; /* cast to topLevel */
     XtPointer call_data;
{
  Widget topLevel = (Widget) client_data;
  XtSetSensitive(topLevel, False);
  XtManageChild(deleteform);
 
}


/*ARGSUSED*/
void DeleteOK(w, client_data, call_data)
     Widget w;
     XtPointer client_data; /* cast to dialog */
     XtPointer call_data;
{
  int i;

  Widget dialog = (Widget) client_data;
  XtUnmanageChild(deleteform);
  XtSetSensitive(dialog, TRUE);
  if (!(num_line == -1))
    {
      for (i=0; i <= num_line; i++)
	XtDestroyWidget(b_line[i]); 
            
      num_line = -1;
    }
}

void DeleteformDone(w, client_data, call_data) /* ARGSUSED */
     Widget w;
     XtPointer client_data; /* cast to dialog */
     XtPointer call_data;
{
  Widget dialog = (Widget) client_data;
  XtUnmanageChild(deleteform);
  XtSetSensitive(dialog, TRUE);
}

void legend_callback()
{
  Arg args[2];
  Boolean f;

  XtVaGetValues(plotter, XtNshowLegend, &f, NULL);
  f = f ? False : True;
  XtSetArg(args[0], XtNshowLegend, f);
  XtSetValues(plotter, args, 1);
}

/* axis_pulldown: grid_button */
void grid_callback()
{
  Arg aargs[2];
  Arg gargs[2];
  Boolean gx, gy;
  
  XtVaGetValues(xaxis, XtNdrawGrid, &gx, NULL);
  XtVaGetValues(yaxis, XtNdrawGrid, &gy, NULL);
      if(gx || gy) {
	XtSetArg(aargs[0], XtNdrawGrid, False);
	XtSetArg(gargs[0], XmNsensitive, False);
      }
      else {
	XtSetArg(aargs[0], XtNdrawGrid, True);
	XtSetArg(gargs[0], XmNsensitive, True);
      }
  XtSetValues(xaxis, aargs, 1);
  XtSetValues(yaxis, aargs, 1);

}

/* axis_pulldown: subgrid_button */
void subgrid_callback()
{
  Arg args[2];
  Boolean gx, gy, gn;
  
  XtVaGetValues(xaxis, XtNdrawSubgrid, &gx, NULL);
  XtVaGetValues(yaxis, XtNdrawSubgrid, &gy, NULL);
  gn = gx || gy ? False : True;
  XtSetArg(args[0], XtNdrawSubgrid, gn);
  XtSetValues(xaxis, args, 1);
  XtSetValues(yaxis, args, 1);
}

void origin_callback()
{
  Arg args[2];
  Boolean f;

  XtVaGetValues(xaxis, XtNdrawOrigin, &f, NULL);
  f = f ? False : True;
  XtSetArg(args[0], XtNdrawOrigin, f);
  XtSetValues(xaxis, args, 1);
  XtSetValues(yaxis, args, 1);
}

void frame_callback()
{
  Arg args[2];
  Boolean f;

  XtVaGetValues(xaxis, XtNdrawFrame, &f, NULL);
  f = f ? False : True;
  XtSetArg(args[0], XtNdrawFrame, f);
  XtSetValues(xaxis, args, 1);
  XtSetValues(yaxis, args, 1);
}

void get_motion_callback(widget, client_data, call_data)
  Widget widget;
  XtPointer client_data;
  AtPointCallbackData *call_data;
{
  static char xstr[64], ystr[64];
  Arg args[2];

  sprintf(xstr, "%.4lf", call_data->x1);
  XtSetArg(args[0], XmNvalue, xstr);
  XtSetValues(x_text, args, 1);
  sprintf(ystr, "%.4lf", call_data->y1);
  XtSetArg(args[0], XmNvalue, ystr);
  XtSetValues(y_text, args, 1);
}

void motion_callback()
{
  Arg args[2];
  static int t = 0;

  if(t) {
    XtRemoveAllCallbacks(plotter, XtNmotionCallback);
    printf("Motion callback: get motion 1 -> 0\n");
    t = 0;
  }
  else {
    XtAddCallback(plotter, XtNmotionCallback, get_motion_callback, NULL);
    printf("Motion callback: get motion 0 -> 1\n");
    XtSetSensitive(xpos_label, True);
    XtSetSensitive(ypos_label, True); 
    t = 1;
  }
}

static double oldxmin, oldxmax, oldymin, oldymax;

void get_drag_callback(widget, client_data, call_data)/* ARGSUSED */
  Widget widget;
  XtPointer client_data;
  AtRectangleCallbackData *call_data;
{
  Arg args[4];
  int n;
  static double x1, y1, x2, y2;
  AtTransform tx, ty;

  tx = AtAxisGetTransform((AtAxisCoreWidget) xaxis);
  ty = AtAxisGetTransform((AtAxisCoreWidget) yaxis);
  x1 = call_data->x11;
  x2 = call_data->x12;
  y1 = call_data->y11;
  y2 = call_data->y12;
  
  n = 0;
  XtSetArg(args[n], XtNmin, &x1);             n++;
  XtSetArg(args[n], XtNmax, &x2);             n++;
  XtSetArg(args[n], XtNautoScale, False);     n++;
  XtSetValues(xaxis, args, n);

  n = 0;
  XtSetArg(args[n], XtNmin, &y1);             n++;
  XtSetArg(args[n], XtNmax, &y2);             n++;
  XtSetArg(args[n], XtNautoScale, False);     n++;
  XtSetValues(yaxis, args, n);
  printf("Get drag callback: tx=%d x1=%lf x2=%lf ty=%d y1=%lf y2=%lf\n",
	  tx, x1, x2, ty, y1, y2);
}

void drag_callback()
{
  Arg args[4];
  int n;
  static int t = 0;

  if(t) {
    n = 0;
    XtSetArg(args[n], XtNmin, &oldxmin);       n++;
    XtSetArg(args[n], XtNmax, &oldxmax);       n++;
    XtSetArg(args[n], XtNautoScale, True);     n++;
    XtSetValues(xaxis, args, n);

    n = 0;
    XtSetArg(args[n], XtNmin, &oldymin);       n++;
    XtSetArg(args[n], XtNmax, &oldymax);       n++;
    XtSetArg(args[n], XtNautoScale, True);     n++;
    XtSetValues(yaxis, args, n);
    XtRemoveAllCallbacks(plotter, XtNdragCallback);
    printf("Drag callback: get drag 1 -> 0\n");
    t = 0;
  }
  else {
    XtVaGetValues(xaxis, XtNmin, &oldxmin, XtNmax, &oldxmax, NULL);
    XtVaGetValues(yaxis, XtNmin, &oldymin, XtNmax, &oldymax, NULL);
    XtAddCallback(plotter, XtNdragCallback, get_drag_callback, NULL);
    printf("Drag callback: get drag 0 -> 1\n");
    t = 1;
  }
}

/*
 ** Codegeneration for the Widget add_button
 */

void CreateAddbutton(parent)
     Widget parent;

{
  int i;
  Arg args[8];
  Cardinal argcount;
  XmString xms[1];
  XmString xms2[COLUMN];

  Widget add_button;
  Widget a_sublabel, a_subbox1, x_list, y_list;
  Widget a_okbutton, a_donebutton;
  Widget xlabel, ylabel, wlabel; 
  Widget w_okbutton;
  
  argcount = 0;
  xms[0] = (XmString) XmStringCreateLtoR( "Plot Data", 
					 XmSTRING_DEFAULT_CHARSET );
  XtSetArg( args[argcount], XmNlabelString, xms[0] ); argcount++;
  XtSetArg( args[argcount], XmNunitType, XmPIXELS ); argcount++;
  add_button = XmCreateCascadeButton( data_pulldown, "button", 
				     args, argcount );
  XtAddCallback( add_button, XmNactivateCallback, PopupAddForm, parent); 
  XtManageChild( add_button );
  XmStringFree( xms[0] );

  argcount = 0;
  xms[0] = (XmString) XmStringCreateLtoR( "Plot Data", 
					 XmSTRING_DEFAULT_CHARSET );
  XtSetArg( args[argcount], XmNdialogTitle, xms[0] ); argcount++;    
  addform = XmCreateBulletinBoardDialog
    (parent,     
     "adddialog", 
     args, 
     argcount);
  XmStringFree(xms[0]);
  
  argcount = 0;
  xms[0] = (XmString) XmStringCreateLtoR( "xaxis", 
					 XmSTRING_DEFAULT_CHARSET );
  XtSetArg( args[argcount], XmNlabelString, xms[0] ); argcount++;
  xlabel = XmCreateLabel(addform, "xlabel", args, argcount);
  XtManageChild(xlabel);
  XmStringFree(xms[0]);
  
  argcount = 0;
  XtSetArg( args[argcount], XmNitemCount, COLUMN); argcount++;
  for (i = 0; i < COLUMN ; i++) {
    xms2[i] = (XmString) XmStringCreateLtoR( snmp_names[i],
					    XmSTRING_DEFAULT_CHARSET ); }
  
  XtSetArg( args[argcount], XmNitems, &xms2[0]); argcount++;   
  
  XtSetArg( args[argcount], XmNselectionPolicy, XmSINGLE_SELECT);  argcount++;
  x_list = XmCreateScrolledList
    (addform,
     "a_selection1",
     args,
     argcount);
  XtManageChild(x_list);
  XtAddCallback(x_list, XmNsingleSelectionCallback, MenuSelectX, NULL);
  
  argcount = 0 ;
  xms[0] = (XmString) XmStringCreateLtoR( "yaxis", 
					 XmSTRING_DEFAULT_CHARSET );
  XtSetArg( args[argcount], XmNlabelString, xms[0] ); argcount++;
  ylabel = XmCreateLabel(addform, "ylabel", args, argcount);
  XtManageChild(ylabel);
  XmStringFree(xms[0]);

  argcount = 0;
  XtSetArg( args[argcount], XmNitemCount, COLUMN); argcount++;
  XtSetArg( args[argcount], XmNitems, &xms2[0]); argcount++;  
  XtSetArg( args[argcount], XmNselectionPolicy, XmSINGLE_SELECT); argcount++;  
  
  y_list = XmCreateScrolledList
    (addform,
     "a_selection2",
     args,
     argcount);
  
   for (i = 0; i < COLUMN ; i++) {
     XmStringFree( xms2[i] );
   }
  XtManageChild(y_list);
  XtAddCallback(y_list, XmNsingleSelectionCallback, MenuSelectY, NULL);
  
  argcount = 0;
  xms[0] = (XmString) XmStringCreateLtoR( "OK", 
					 XmSTRING_DEFAULT_CHARSET );
  XtSetArg( args[argcount], XmNlabelString, xms[0] ); argcount++;
  
  a_okbutton = XmCreatePushButton
    (addform,
     "a_okbutton",
     args,
     argcount);
  
  XtManageChild(a_okbutton);
  XtAddCallback(a_okbutton, XmNactivateCallback, AddOK, parent);
  XmStringFree(xms[0]);  

  argcount = 0;
  xms[0] = (XmString) XmStringCreateLtoR( "Cancel", 
					 XmSTRING_DEFAULT_CHARSET );
  XtSetArg( args[argcount], XmNlabelString, xms[0] ); argcount++;
  a_donebutton = XmCreatePushButton
    (addform,
     "a_donebutton",
     args,
     argcount);
  
  XtManageChild(a_donebutton);
  XtAddCallback(a_donebutton, XmNactivateCallback, AddformDone, parent);
  XmStringFree(xms[0]);

  argcount = 0;
  xms[0] = (XmString) XmStringCreateLtoR( "Plotter Warning", 
					 XmSTRING_DEFAULT_CHARSET );
  XtSetArg( args[argcount], XmNdialogTitle, xms[0] ); argcount++;    
  warning = XmCreateBulletinBoardDialog
    (parent,     
     "warndialog", 
     args, 
     argcount);
  XmStringFree(xms[0]);
  
  argcount = 0;
  xms[0] = (XmString) XmStringCreateLtoR( "Cannot plot more than 5 datas, try 'clear' option if you need to plot other datas", 
					  XmSTRING_DEFAULT_CHARSET );
  XtSetArg( args[argcount], XmNlabelString, xms[0] ); argcount++;
  wlabel = XmCreateLabel(warning, "wlabel", args, argcount);
  XtManageChild(wlabel);
  XmStringFree(xms[0]);
  
  argcount = 0;
  xms[0] = (XmString) XmStringCreateLtoR( "OK", 
					 XmSTRING_DEFAULT_CHARSET );
  XtSetArg( args[argcount], XmNlabelString, xms[0] ); argcount++; 
  w_okbutton = XmCreatePushButton
    (warning,
     "w_okbutton",
     args,
     argcount);
  
  XtManageChild(w_okbutton);
  XtAddCallback(w_okbutton, XmNactivateCallback, WarnOK, parent);
  XmStringFree(xms[0]);  
}

/*
 *      Create form, buttons, plotter(without datas attached)
 */

void MakeForm(parent)
     Widget parent;
     
{ int i;
  Arg args[8]; /* originally 16 */
  Cardinal argcount;
  XmString xms[2];
  XmString xms2[COLUMN];
  
  int n;
  int x, y; /* column numbers in the data file 
	     * these are to be used to select datas to be placed in
	     * x and y axis 
	     */
  char tempbuf[50];
  Widget mainwindow = NULL;
  
  Widget main_menubar = NULL;
  Widget file_pulldown = NULL;
  Widget read_button = NULL;
  Widget print_button = NULL;
  Widget quit_button = NULL;
  Widget file_button = NULL;  
  Widget add_button = NULL; 
  Widget delete_button = NULL;
  Widget data_button = NULL;
  Widget plot_pulldown = NULL;
  Widget motion_button = NULL;
  Widget legend_button = NULL;
  Widget drag_button = NULL;
  Widget grid_button = NULL;
  Widget subgrid_button = NULL;  
  Widget plot_button = NULL;
  Widget d_okbutton, d_donebutton;
  Widget dlabel;
  Widget main_form = NULL;
  Widget title_form = NULL;
  Widget title_frame = NULL;
  Widget title_label = NULL;
  Widget plotter_form = NULL;
  Widget plotter_frame = NULL;
  Widget message_form = NULL;
  Widget message_frame = NULL;
  Widget message_rowcolumn = NULL;
 
  /*
   ** Codegeneration for the Widget mainwindow
   */
  argcount = 0;
  XtSetArg( args[argcount], XmNunitType, XmPIXELS ); argcount++;
  mainwindow = XmCreateMainWindow( parent, "main_window", args, argcount );
  XtManageChild( mainwindow );
  
  /*
   ** Codegeneration for the Widget main_menubar
   */
  argcount = 0;
  XtSetArg( args[argcount], XmNshadowThickness, (Dimension) 3 ); argcount++;
  XtSetArg( args[argcount], XmNspacing, (Dimension) 8 ); argcount++;
  main_menubar = XmCreateMenuBar( mainwindow, "main_menubar", args, argcount );
  XtManageChild( main_menubar );

  /*
   ** Codegeneration for the Widget file_pulldown
   */
  argcount = 0;
  XtSetArg( args[argcount], XmNunitType, Xm100TH_FONT_UNITS ); argcount++;
  file_pulldown = XmCreatePulldownMenu( main_menubar, "pulldown", 
				       args, argcount );
  
  /*
   ** Codegeneration for the Widget read_button
   */
  argcount = 0;
  xms[0] = (XmString) XmStringCreateLtoR( "Read data", 
					 XmSTRING_DEFAULT_CHARSET );
  XtSetArg( args[argcount], XmNlabelString, xms[0] ); argcount++;
  XtSetArg( args[argcount], XmNunitType, XmPIXELS ); argcount++;
  read_button = XmCreateCascadeButton( file_pulldown, "button", 
				      args, argcount );
  XtAddCallback( read_button, XmNactivateCallback, 
		PopupFileSelection, parent); 
  XtManageChild( read_button );
  XmStringFree( xms[0] );
  
  argcount = 0;
  xms[0] = (XmString) XmStringCreateLtoR( "*.eth", XmSTRING_DEFAULT_CHARSET );
  XtSetArg( args[argcount], XmNpattern, xms[0] ); argcount++;
  xms[1] = (XmString) XmStringCreateLtoR("SNMP File Selection", 
					 XmSTRING_DEFAULT_CHARSET );
  XtSetArg( args[argcount], XmNdialogTitle, xms[1] ); argcount++;
  file_selection = XmCreateFileSelectionDialog
    (parent,
     "file_selection",
     args, argcount);
  XmStringFree( xms[1] );
  XmStringFree( xms[0] );
  
  XtAddCallback( file_selection, XmNokCallback, 
		file_ok_callback, parent );
  XtAddCallback( file_selection, XmNcancelCallback, 
		file_cancel_callback, parent);
 
  /*
   ** Codegeneration for the Widget quit_button
   */
  argcount = 0;
  xms[0] = (XmString) XmStringCreateLtoR( "Quit", 
					 XmSTRING_DEFAULT_CHARSET );
  XtSetArg( args[argcount], XmNlabelString, xms[0] ); argcount++;
  XtSetArg( args[argcount], XmNunitType, XmPIXELS ); argcount++;
  quit_button = XmCreateCascadeButton( file_pulldown, "button", 
				      args, argcount );
  XtAddCallback( quit_button, XmNactivateCallback, 
		quit_callback, (XtPointer) NULL ); 
  XtManageChild( quit_button );
  XmStringFree( xms[0] );
  
  /*
   ** Codegeneration for the Widget file_button
   */
  argcount = 0;
  xms[0] = (XmString) XmStringCreateLtoR( "File", XmSTRING_DEFAULT_CHARSET );
  XtSetArg( args[argcount], XmNlabelString, xms[0] ); argcount++;
  XtSetArg( args[argcount], XmNsubMenuId, file_pulldown ); argcount++;
  file_button = XmCreateCascadeButton( main_menubar, "button", 
				      args, argcount );
  XtManageChild( file_button );
  XmStringFree( xms[0] );
  
  /*
   ** Codegeneration for the Widget Data_pulldown
   */

  argcount = 0;
  XtSetArg( args[argcount], XmNunitType, Xm100TH_FONT_UNITS ); argcount++;
  data_pulldown = XmCreatePulldownMenu( main_menubar, "pulldown", args, argcount );

  /*
   ** Codegeneration for the Widget delete_button
   */

  argcount = 0;
  xms[0] = (XmString) XmStringCreateLtoR( "Clear Plotter", 
					 XmSTRING_DEFAULT_CHARSET );
  XtSetArg( args[argcount], XmNlabelString, xms[0] ); argcount++;
  XtSetArg( args[argcount], XmNunitType, XmPIXELS ); argcount++;
  delete_button = XmCreateCascadeButton( data_pulldown, "button", 
					args, argcount );
  XtAddCallback( delete_button, XmNactivateCallback, 
		PopupDeleteForm, parent); 
  XtManageChild( delete_button );
  XmStringFree( xms[0] );

  argcount = 0;  
  xms[0] = (XmString) XmStringCreateLtoR( "Clear Plotter", 
					 XmSTRING_DEFAULT_CHARSET );
  XtSetArg( args[argcount], XmNdialogTitle, xms[0] ); argcount++;
  deleteform = XmCreateBulletinBoardDialog
    (parent,
     "delete_dialog",
     args,
     argcount);
  XmStringFree( xms[0]);
  
  argcount = 0;
  xms[0] = (XmString) XmStringCreateLtoR( "Cleaning the plotter - Remove all datas from the plotter", 
					 XmSTRING_DEFAULT_CHARSET );
  XtSetArg( args[argcount], XmNlabelString, xms[0] ); argcount++;
  dlabel = XmCreateLabel(deleteform, "dlabel", args, argcount);
  XtManageChild(dlabel);
  XmStringFree( xms[0] ); 
 
  argcount = 0;
  xms[0] = (XmString) XmStringCreateLtoR( "Ok", 
					 XmSTRING_DEFAULT_CHARSET );
  XtSetArg( args[argcount], XmNlabelString, xms[0] ); argcount++;
  d_okbutton = XmCreatePushButton(deleteform, "d_okbutton", args, argcount);
  XtManageChild(d_okbutton);
  XtAddCallback(d_okbutton, XmNactivateCallback, DeleteOK, parent);
  XmStringFree( xms[0]);

  argcount = 0;
  xms[0] = (XmString) XmStringCreateLtoR( "Cancel", 
					 XmSTRING_DEFAULT_CHARSET );
  XtSetArg( args[argcount], XmNlabelString, xms[0] ); argcount++;
  d_donebutton = XmCreatePushButton(deleteform, "d_donebutton", 
				    args, argcount);
  XtManageChild(d_donebutton);
  XtAddCallback(d_donebutton, XmNactivateCallback, DeleteformDone, parent);
  XmStringFree(xms[0]);
  
  /*
   ** Codegeneration for the Widget Data_button
   */
  
  argcount = 0;
  xms[0] = (XmString) XmStringCreateLtoR( "Data", XmSTRING_DEFAULT_CHARSET );
  XtSetArg( args[argcount], XmNlabelString, xms[0] ); argcount++;
  XtSetArg( args[argcount], XmNsubMenuId, data_pulldown ); argcount++;
  data_button = XmCreateCascadeButton( main_menubar, "button", 
				      args, argcount );
  XtManageChild( data_button );
  XmStringFree( xms[0] );
  
  /*
   ** Codegeneration for the Widget plot_pulldown
   */
  argcount = 0;
  XtSetArg( args[argcount], XmNunitType, Xm100TH_FONT_UNITS ); argcount++;
  plot_pulldown = XmCreatePulldownMenu( main_menubar, "pulldown", args, argcount );

  /*
   ** Codegeneration for the Widget motion_button
   */
  argcount = 0;
  xms[0] = (XmString) XmStringCreateLtoR( "Motion", 
					 XmSTRING_DEFAULT_CHARSET );
  XtSetArg( args[argcount], XmNlabelString, xms[0] ); argcount++;
  XtSetArg( args[argcount], XmNunitType, XmPIXELS ); argcount++;
  XtSetArg( args[argcount], XmNindicatorType, XmN_OF_MANY ); argcount++;
  XtSetArg( args[argcount], XmNvisibleWhenOff, True ); argcount++;
  XtSetArg( args[argcount], XmNset, False ); argcount++;
  motion_button = XmCreateToggleButton( plot_pulldown, "button", 
				       args, argcount );
  XtAddCallback( motion_button, XmNvalueChangedCallback, 
		 motion_callback, (XtPointer) NULL ); 
  XtManageChild( motion_button );
  XmStringFree( xms[0] );
  
  /*
   ** Codegeneration for the Widget legend_button
   */
  argcount = 0;
  xms[0] = (XmString) XmStringCreateLtoR( "Legend", 
					 XmSTRING_DEFAULT_CHARSET );
  XtSetArg( args[argcount], XmNlabelString, xms[0] ); argcount++;
  XtSetArg( args[argcount], XmNunitType, XmPIXELS ); argcount++;
  XtSetArg( args[argcount], XmNindicatorType, XmN_OF_MANY ); argcount++;
  XtSetArg( args[argcount], XmNvisibleWhenOff, True ); argcount++;
  XtSetArg( args[argcount], XmNset, True ); argcount++;
  legend_button = XmCreateToggleButton( plot_pulldown, "button", 
				       args, argcount );
  XtAddCallback( legend_button, XmNvalueChangedCallback, 
		legend_callback, (XtPointer) NULL ); 
  XtManageChild( legend_button );
  XmStringFree( xms[0] );
  
   /*
   ** Codegeneration for the Widget drag_button
   */
  argcount = 0;
  xms[0] = (XmString) XmStringCreateLtoR( "Drag", 
  					 XmSTRING_DEFAULT_CHARSET );
  XtSetArg( args[argcount], XmNlabelString, xms[0] ); argcount++;
  XtSetArg( args[argcount], XmNunitType, XmPIXELS ); argcount++;
  XtSetArg( args[argcount], XmNindicatorType, XmN_OF_MANY ); argcount++;
  XtSetArg( args[argcount], XmNvisibleWhenOff, True ); argcount++;
  XtSetArg( args[argcount], XmNset, True ); argcount++;
  drag_button = XmCreateToggleButton( plot_pulldown, "button", 
				       args, argcount );
  XtAddCallback( drag_button, XmNvalueChangedCallback, 
		drag_callback, (XtPointer) NULL ); 
  XtManageChild( drag_button );
  XmStringFree( xms[0] );
  
  /*
   ** Codegeneration for the Widget grid_button
   */
  argcount = 0;
  xms[0] = (XmString) XmStringCreateLtoR( "Grid", XmSTRING_DEFAULT_CHARSET );
  XtSetArg( args[argcount], XmNlabelString, xms[0] ); argcount++;
  XtSetArg( args[argcount], XmNunitType, XmPIXELS ); argcount++;
  XtSetArg( args[argcount], XmNindicatorType, XmN_OF_MANY ); argcount++;
  XtSetArg( args[argcount], XmNvisibleWhenOff, True ); argcount++;
  XtSetArg( args[argcount], XmNset, True ); argcount++;
  grid_button = XmCreateToggleButton( plot_pulldown, "button", 
				     args, argcount );
  XtAddCallback( grid_button, XmNvalueChangedCallback, 
		grid_callback, (XtPointer) NULL ); 
  XtManageChild( grid_button );
  XmStringFree( xms[0] );
  
  /*
   ** Codegeneration for the Widget subgrid_button
   */
  argcount = 0;
  xms[0] = (XmString) XmStringCreateLtoR( "Subgrid", 
					 XmSTRING_DEFAULT_CHARSET );
  XtSetArg( args[argcount], XmNlabelString, xms[0] ); argcount++;
  XtSetArg( args[argcount], XmNunitType, XmPIXELS ); argcount++;
  XtSetArg( args[argcount], XmNindicatorType, XmN_OF_MANY ); argcount++;
  XtSetArg( args[argcount], XmNvisibleWhenOff, True ); argcount++;
  XtSetArg( args[argcount], XmNset, False ); argcount++;
  subgrid_button = XmCreateToggleButton( plot_pulldown, "button", 
					args, argcount );
  XtAddCallback( subgrid_button, XmNvalueChangedCallback, 
		subgrid_callback, (XtPointer) NULL ); 
  XtManageChild( subgrid_button );
  XmStringFree( xms[0] );
  
  /*
   ** Codegeneration for the Widget plot_button
   */
  argcount = 0;
  xms[0] = (XmString) XmStringCreateLtoR( "Plot", XmSTRING_DEFAULT_CHARSET );
  XtSetArg( args[argcount], XmNlabelString, xms[0] ); argcount++;
  XtSetArg( args[argcount], XmNsubMenuId, plot_pulldown ); argcount++;
  plot_button = XmCreateCascadeButton( main_menubar, "button", 
				      args, argcount );
  XtManageChild( plot_button );
  XmStringFree( xms[0] );
  
  /*
   ** Codegeneration for the Widget main_form
   */
  argcount = 0;
  XtSetArg( args[argcount], XmNresizePolicy, XmRESIZE_NONE ); argcount++;
  main_form = XmCreateForm( mainwindow, "main_form", args, argcount );
  XtManageChild( main_form );
  
  /*
   ** Codegeneration for the Widget title_form
   */
  argcount = 0;
  XtSetArg( args[argcount], XmNresizePolicy, XmRESIZE_NONE ); argcount++;
  title_form = XmCreateForm( main_form, "title_form", args, argcount );
  XtManageChild( title_form );
  
  /*
   ** Codegeneration for the Widget title_frame
   */
  argcount = 0;
  XtSetArg( args[argcount], XmNshadowThickness, (Dimension) 0 ); argcount++;
  XtSetArg( args[argcount], XmNshadowType, XmSHADOW_OUT ); argcount++;
  title_frame = XmCreateFrame( title_form, "title_frame", args, argcount );
  XtManageChild( title_frame );
  
  /*
   ** Codegeneration for the Widget title_label
   */
  argcount = 0;
  xms[0] = (XmString) XmStringCreateLtoR( "SNMP PLOT", 
					 XmSTRING_DEFAULT_CHARSET );
  XtSetArg( args[argcount], XmNlabelString, xms[0] ); argcount++;
  title_label = XmCreateLabel( title_frame, "title_label", args, argcount );
  XtManageChild( title_label );
  XmStringFree( xms[0] );
    
  /***** start form-attachments for 'title_form' *****/
  argcount = 0;
  XtSetArg( args[argcount], XmNtopAttachment, XmATTACH_FORM ); argcount++;
  XtSetArg( args[argcount], XmNbottomAttachment, XmATTACH_FORM ); argcount++;
  XtSetArg( args[argcount], XmNleftAttachment, XmATTACH_FORM ); argcount++;
  XtSetArg( args[argcount], XmNrightAttachment, XmATTACH_FORM ); argcount++;
  XtSetValues( title_frame, args, argcount );
  
  /***** stop form-attachments for 'title_form' *****/
  /*
   ** Codegeneration for the Widget plotter_form
   */
  argcount = 0;
  XtSetArg( args[argcount], XmNresizePolicy, XmRESIZE_ANY ); argcount++;
  plotter_form = XmCreateForm( main_form, "plotter_form", args, argcount );
  
  /*
  XtAddEventHandler( plotter_form, LeaveWindowMask, 
		    False, plotterform_callback, 
		    (XtPointer) NULL ); */
  
  XtManageChild( plotter_form );
  
  /*
   ** Codegeneration for the Widget plotter_frame
   */
  argcount = 0;
  XtSetArg( args[argcount], XmNshadowThickness, (Dimension) 6 ); argcount++;
  XtSetArg( args[argcount], XmNshadowType, XmSHADOW_OUT ); argcount++;
  plotter_frame = XmCreateFrame( plotter_form, "plotter_frame", 
				args, argcount );
  XtManageChild( plotter_frame );
  
  /***** start form-attachments for 'plotter_form' *****/
  argcount = 0;
  XtSetArg( args[argcount], XmNtopAttachment, XmATTACH_FORM ); argcount++;
  XtSetArg( args[argcount], XmNbottomAttachment, XmATTACH_FORM ); argcount++;
  XtSetArg( args[argcount], XmNleftAttachment, XmATTACH_FORM ); argcount++;
  XtSetArg( args[argcount], XmNrightAttachment, XmATTACH_FORM ); argcount++;
  XtSetValues( plotter_frame, args, argcount );
  
  /***** stop form-attachments for 'plotter_form' *****/

  /* Create the plotter */
  n = 0;
  XtSetArg(args[n], XtNwidth, 640); n++;
  XtSetArg(args[n], XtNheight, 480); n++;
  XtSetArg(args[n], XtNborderWidth, 0); n++;
  XtSetArg(args[n], XtNmarginWidth, 6); n++;
  XtSetArg(args[n], XtNmarginHeight, 6); n++;
  XtSetArg(args[n], XtNtitle, "SNMP PLOT"); n++;
  XtSetArg(args[n], XtNshowTitle, False); n++;
  XtSetArg(args[n], XtNshowLegend, True); n++;
  XtSetArg(args[n], XtNusePixmap, True); n++;
  plotter = XtCreateManagedWidget("plotter", atPlotterWidgetClass, 
				  plotter_frame, args, n);
  XtAddCallback(plotter, XtNselectCallback, select_callback, NULL);
  
  /* Create the X axis */
  n = 0;
  XtSetArg(args[n], XtNlabel, "xaxis"); n++;
  XtSetArg(args[n], XtNaxisWidth, 1); n++;
  xaxis = XtCreateWidget("xaxis", atXYAxisWidgetClass, plotter, args, n);
  
  /* Create the Y axis */
  n = 0;
  XtSetArg(args[n], XtNlabel, "yaxis"); n++;
  XtSetArg(args[n], XtNaxisWidth, 1); n++;
  XtSetArg(args[n], XtNvertical, True); n++;
  yaxis = XtCreateWidget("yaxis", atXYAxisWidgetClass, plotter, args, n);

  /* Attach X and Y axes to the plotter */
  n = 0;
  XtSetArg(args[n], XtNxAxis, xaxis); n++;
  XtSetArg(args[n], XtNyAxis, yaxis); n++;
  XtSetValues(plotter, args, n);

  
  /*
   ** Codegeneration for the Widget message_form
   */
  argcount = 0;
  XtSetArg( args[argcount], XmNresizePolicy, XmRESIZE_NONE ); argcount++;
  message_form = XmCreateForm( main_form, "message_form", args, argcount );
  XtManageChild( message_form );
  
  /*
   ** Codegeneration for the Widget message_frame
   */
  argcount = 0;
  XtSetArg( args[argcount], XmNshadowType, XmSHADOW_OUT ); argcount++;
  XtSetArg( args[argcount], XmNshadowThickness, (Dimension) 3 ); argcount++;
  message_frame = XmCreateFrame( message_form, "message_frame", args, argcount );
  XtManageChild( message_frame );
  
  /*
   ** Codegeneration for the Widget message_rowcolumn
   */
  argcount = 0;
  XtSetArg( args[argcount], XmNorientation, XmHORIZONTAL ); argcount++;
  message_rowcolumn = XmCreateRowColumn( message_frame, "message_rowcolumn", args, argcount );
  XtManageChild( message_rowcolumn );
  
  /*
   ** Codegeneration for the Widget xpos_label
   */
  argcount = 0;
  xms[0] = (XmString) XmStringCreateLtoR( "X:", XmSTRING_DEFAULT_CHARSET );
  XtSetArg( args[argcount], XmNlabelString, xms[0] ); argcount++;
  XtSetArg( args[argcount], XmNsensitive, False ); argcount++;
  xpos_label = XmCreateLabel( message_rowcolumn, "label", args, argcount );
  XtManageChild( xpos_label );
  XmStringFree( xms[0] );
  
  /*
   ** Codegeneration for the Widget x_text
   */
  argcount = 0;
  XtSetArg( args[argcount], XmNhighlightThickness, (Dimension) 0 ); argcount++;
  XtSetArg( args[argcount], XmNautoShowCursorPosition, False ); argcount++;
  XtSetArg( args[argcount], XmNeditable, False ); argcount++;
  XtSetArg( args[argcount], XmNpendingDelete, False ); argcount++;
  XtSetArg( args[argcount], XmNcursorPositionVisible, False ); argcount++;
  XtSetArg( args[argcount], XmNverifyBell, False ); argcount++;
  XtSetArg( args[argcount], XmNsensitive, False ); argcount++;
  x_text = XmCreateText( message_rowcolumn, "text", args, argcount );
  XtManageChild( x_text );
  
  /*
   ** Codegeneration for the Widget ypos_label
   */
  argcount = 0;
  xms[0] = (XmString) XmStringCreateLtoR( "Y:", XmSTRING_DEFAULT_CHARSET );
  XtSetArg( args[argcount], XmNlabelString, xms[0] ); argcount++;
  XtSetArg( args[argcount], XmNsensitive, False ); argcount++;
  ypos_label = XmCreateLabel( message_rowcolumn, "label", args, argcount );
  XtManageChild( ypos_label );
  XmStringFree( xms[0] );
  
  /*
   ** Codegeneration for the Widget y_text
   */
  argcount = 0;
  XtSetArg( args[argcount], XmNautoShowCursorPosition, False ); argcount++;
  XtSetArg( args[argcount], XmNeditable, False ); argcount++;
  XtSetArg( args[argcount], XmNpendingDelete, False ); argcount++;
  XtSetArg( args[argcount], XmNcursorPositionVisible, False ); argcount++;
  XtSetArg( args[argcount], XmNverifyBell, False ); argcount++;
  XtSetArg( args[argcount], XmNhighlightThickness, (Dimension) 0 ); argcount++;
  XtSetArg( args[argcount], XmNsensitive, False ); argcount++;
  y_text = XmCreateText( message_rowcolumn, "text", args, argcount );
  XtManageChild( y_text );
  

  /***** start form-attachments for 'message_form' *****/
  argcount = 0;
  XtSetArg( args[argcount], XmNtopAttachment, XmATTACH_FORM ); argcount++;
  XtSetArg( args[argcount], XmNbottomAttachment, XmATTACH_FORM ); argcount++;
  XtSetArg( args[argcount], XmNleftAttachment, XmATTACH_FORM ); argcount++;
  XtSetArg( args[argcount], XmNrightAttachment, XmATTACH_FORM ); argcount++;
  XtSetValues( message_frame, args, argcount );
  
  /***** stop form-attachments for 'message_form' *****/
  /***** start form-attachments for 'main_form' *****/
  argcount = 0;
  XtSetArg( args[argcount], XmNtopAttachment, XmATTACH_FORM ); argcount++;
  XtSetArg( args[argcount], XmNbottomAttachment, XmATTACH_NONE ); argcount++;
  XtSetArg( args[argcount], XmNleftAttachment, XmATTACH_FORM ); argcount++;
  XtSetArg( args[argcount], XmNrightAttachment, XmATTACH_FORM ); argcount++;
  XtSetValues( title_form, args, argcount );
  
  argcount = 0;
  XtSetArg( args[argcount], XmNtopWidget, title_form ); argcount++;
  XtSetArg( args[argcount], XmNtopAttachment, XmATTACH_WIDGET ); argcount++;
  XtSetArg( args[argcount], XmNbottomAttachment, XmATTACH_WIDGET ); argcount++;
  XtSetArg( args[argcount], XmNleftAttachment, XmATTACH_FORM ); argcount++;
  XtSetArg( args[argcount], XmNrightAttachment, XmATTACH_FORM ); argcount++;
  XtSetArg( args[argcount], XmNbottomWidget, message_form ); argcount++;
  XtSetValues( plotter_form, args, argcount );
  
  argcount = 0;
  XtSetArg( args[argcount], XmNtopAttachment, XmATTACH_NONE ); argcount++;
  XtSetArg( args[argcount], XmNbottomAttachment, XmATTACH_FORM ); argcount++;
  XtSetArg( args[argcount], XmNleftAttachment, XmATTACH_FORM ); argcount++;
  XtSetArg( args[argcount], XmNrightAttachment, XmATTACH_FORM ); argcount++;
  XtSetValues( message_form, args, argcount );
  
  /***** stop form-attachments for 'main_form' *****/
  
  XmMainWindowSetAreas( mainwindow, main_menubar, 
		       NULL, NULL, NULL, main_form );
  
}

/*
 *      Main
 */ 
 
main(argc, argv)
     int argc;
     char **argv;
{ 
  int i;
  Widget appShell;
  XtAppContext app; 
  
  appShell = XtVaAppInitialize(&app, "SNMP1", NULL, 0, 
			       &argc, argv, NULL, NULL);

  MakeForm(appShell);  
  XtRealizeWidget(appShell);
  XtAppMainLoop(app); 
  
  exit(0); 
}


