/***********************************
  (C) Copyright 1992-1993; dit/upm
  Distributed under the conditions stated in the
  TOPO General Public License (see file LICENSE)
  *********************************/

/******************************************************************
 *
 *   XLoLa. X Window Interface to LoLa.
 *   Version 0.0
 *   Javier Calle.
 *   Madrid 5-31-1993
 *
 *****************************************************************/
/*LINTLIBRARY*/

#ifdef XLOLA

#include <stdlib.h>
#include <string.h>
#include <signal.h>


#include "apxlola.h"

/* Files from LoLa */

#include "listdh.h"
#include "ligetlin.h"
#include "limisc.h"
#include "batables.h"
#include "bainit.h"
#include "bamove.h"
#include "batransl.h"
#include "badefca.h"
#include "incomm.h"
#include "listdout.h"
#include "inhelp.h"
#include "listrbk.h"
#include "baprint.h"
#include "basust_v.h"
#include "ststep.h"

/* Files of X Toolkit to develop the X Window Interface */

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

#include <X11/Xaw/AsciiText.h>
#include <X11/Xaw/Command.h>
#include <X11/Xaw/Form.h>
#include <X11/Xaw/Label.h>
#include <X11/Xaw/MenuButton.h>
#include <X11/Xaw/Paned.h>
#include <X11/Xaw/SimpleMenu.h>
#include <X11/Xaw/SmeBSB.h>
#include <X11/Xaw/Sme.h>
#include <X11/Xaw/SmeLine.h>
#include <X11/Xaw/Toggle.h>
#include <X11/Xaw/Viewport.h>
#include <X11/Xaw/Cardinals.h>


/******************************************************************
 *
 *                DECLARATION OF FUNCTIONS
 *
 *****************************************************************/

/* Functions to create the windows */

static void CreateWindows();
static void CreateMainWindow();
static void FirstPartMain();
static void SecPartMain();
static void PrintOptions();
static void MiscCommands();
static void ThirdPartMain();
static void CreateOutputArea();
static void CreateExpandWindow();
static void FirstPartExpand();
static void ExpandOptions();
static void SecPartExpand();
static void ThirdPartExpand();
static void InterOptions();
static void CreateTestingWindow();
static void FirstPartTesting();
static void SecPartTesting();
static void TestingOptions();
static void ThirdPartTesting();
static void CreateRewriteWindow();
static void CreateStepWindow();
static void HelpOptions();

/*  Function defined like an action in an Action Table for the
 *  Selection Window 
 */

static void GetLineNumberACT();

/* Callbacks associated to the widgets */

static void LoadCB();
static void PrintCB();
static void DataTableCB();
static void ExpandCB();
static void InterCB();
static void TestCB();
static void OneCB();
static void RewriteCB();
static void StartCB();
static void TransitionsCB();
static void RefusedCB();
static void UndoCB();
static void TraceCB();
static void ExitCB();
static void HelpCB();
static void StatisticCB();
static void QuitCB();

#ifdef SDEBUG
static void SaveCB();
#endif

static void MoveCursorToSpecCB();
static void MoveCursorToRootCB();
static void DisplaysProcessNamesCB();

static void PrintStateCB();
static void ExpStateCB();
static void InterStateCB();
static void TestStateCB();
static void OneStateCB();

static void ReadDataStepStartCB();
static void ReadDataStepBranchCB();

static void ShowWindowCB();
static void HideWindowCB();
static void HideRewriteCB();

static void CleanRewriteCB();
static void CleanOutputCB();

/* Auxiliary functions to integrate the interface with LoLa */

static void    CreateDataWindow();
static void    DestroyDataWindow();
static boolean ParseValues();

static void    PrintInWidget();
static void    CleanWindow();
static void    GotoFirstLine();

static void    ActualizeCursor();
static void    ActualizeMenu();
static void    ActualizeRefused();
static void    PrintHeadProcess();

static String  ReadText();
static int     ReadNum();
static String  CleanDataString();

static void    StartCB_cont();
static long    GetOptionNumber();

static Boolean GetState();
static int     SetOptions();
static void    CleanEventQueue();
static void    SetTranslations();

static void    BlockWidget();
static void    BlockByOpenedWindows();
static void    BlockByProcList();
static void    BlockByProcWhileStep();
static void    BlockStep();
static void    BlockStepData();


/* Values with the option numbers of LoLa Commands */

#define NPR 3
#define NEX 4
#define NEXF 2
#define NIN 3
#define NTE 7
#define NON 2

/* Default distance in pixels between widgets in a form widget */

#define DD 5

/* Labels to the Selection Window */

#define LABEL1  "--------      CURSOR SELECTION WINDOW      --------"
#define LABEL2  "--------      PROCESS SELECTION WINDOW     --------"
#define LABEL3  "--------    TRANSITION SELECTION WINDOW    --------"
#define LABEL4  "-- UNSUCCESSFUL SYNCHRONIZATION SELECTION WINDOW --"
#define LABEL5  "------------      OUTPUT  WINDOW      -------------"


/* Global Variables */

/*  Application Context
 */
static XtAppContext applcontext;

/*  Shell widgets and some composite children
 */
static Widget mainwindow,maincomp,expandwindow,
              expandcomp,testwindow,testcomp,rewrwindow,stepwindow,
              helpwindow,valwindow;

/*  Asciitext Widgets of Selection and Output Windows
 */
Widget Selection,output;

/*  Variables related with the window to read expressions in the Step mode.
 *
 *      varListStep: List with the descriptor of the variables to read.
 *      svTableStep: SV table with the pairs <var,expr>.
 *      optStep    : number of the transition to execute. 
 */
static ListTyp varListStep = NULL;
static SVdescriptorTyp svTableStep = NULL;
static int optStep;

/*  Variables to change data with the user
 */

static char *spec,
            *lib,
            *outfile,
            *evsuc,
            *testproc;

/*  Stores the command options activated by the user when invokes 
 *  the command
 */
static char commflags[8] = "\0";

/*  Store the size of a char of the font 
 */
static int WidthChar,HeightChar;

/*  Store the option state of each command (print,
 *  expand,inter,test and one)
 */
static Boolean PrintChoice[NPR],
               ExpChoice[NEX],
               InterChoice[NIN],
               TestChoice[NTE],
               OneChoice[NON];

/*  Strings with the characters which symbolize all command options
 */

static char printlist[] = "apt"; 
static char explist[]   = "iv";
static char interlist[] = "vdp"; 
static char testlist[]  = "adesyiv";
static char onelist[]   = "iv";


/*  Default values for some widget resources of the interface when
 *  there are not defined files with specifications of resources
 */

static String app_defaults[]={
  "*Label.BorderWidth:0",
  "*Label.InternalWidth:0",
  "*Command*ShapeStyle:oval",
  "*Command*Thickness:3",
  "*Command*borderWidth: 3",
  "*MenuButton*ShapeStyle:oval",
  "*MenuButton*Thickness:3",
  "*MenuButton*borderWidth: 3",
  "*Justify:center",
  "*Toggle*InternalHeight:2",
  "*Toggle*InternalWidth:2",
  "*Toggle*Thickness:3",
  "*Form.DefaultDistance:10",
  "*Paned*Form*Resizable:TRUE",
  "*Paned*ShowGrip:FALSE",
  "*cursoredit.cursor:hand2",
  NULL
};

/*  cursorState
 *  The cursor window can display the current behaviour or the process names.
 */
#define SHOW_BEHAVIOUR   1
#define SHOW_PROC_NAMES  2
#define TRANSITIONS      3
#define REFUSED          4

int cursorState;

/*  dataCreated
 *  Indicates if was created the Transition Data Window
 */
static Boolean dataCreated;

/*  AWindowOpened
 *  Indicates if was open the expansion, testing or step window
 */
static Boolean AWindowOpened;

/*  StepWorking
 *  It is true if a step-by-step simulation is working
 */
static Boolean StepWorking;

/*  Indicates the format of an integer value is no correct
 */
#define BADINTEGER  -23879

/*-----------------------     ACTION TABLE        ---------------------*/

/* Includes a new action to the Selection widget */

static XtActionsRec TableAct[]={
  { "GetLineNumberACT",GetLineNumberACT}
};

/*--------------------      TRANSLATION TABLES        ------------------*/

/*  TransDataString
 *  Translations to AsciiText Widgets which edit every data type
 */
static char TransDataString[]=
  "Ctrl<Key>D: delete-next-character()\n\
   Ctrl<Key>: no-op(RingBell)\n\
   Meta<Key>: no-op(RingBell)\n\
   <Key>Linefeed: no-op(RingBell)\n\
   <Key>Return: no-op(RingBell)";

/*  TransIntNum
 *  Translations to AsciiText Widgets which edit only integer numbers
 */
static char TransIntNum[]=
  "Ctrl<Key>D: delete-next-character()\n\
   <Key>1: insert-char()\n\
   <Key>2: insert-char()\n\
   <Key>3: insert-char()\n\
   <Key>4: insert-char()\n\
   <Key>5: insert-char()\n\
   <Key>6: insert-char()\n\
   <Key>7: insert-char()\n\
   <Key>8: insert-char()\n\
   <Key>9: insert-char()\n\
   <Key>0: insert-char()\n\
   <Key>-: insert-char()\n\
   <Key>Right: forward-character()\n\
   <Key>Left: backward-character()\n\
   <Key>Delete: delete-previous-character()\n\
   <Key>: no-op(RingBell)";

/* TransCur
*  Translations to Selection widget. It allows to select a text line in
*  the Selection Widget with the left button of the mouse
*/
static char TransCur[] =
  "<Btn1Down>,<Btn1Up>: GetLineNumberACT()";

/*  TransRadio
 *  Translations to a radio group of type "one of many"
 */
static char TransRadio[]=
  "<EnterWindow>:          highlight(Always)\n\
   <LeaveWindow>:          unhighlight()\n\
   <Btn1Down>, <Btn1Up>:   set() notify()";


/******************************************************************
 *
 *            AUXILIARY FUNCTIONS TO CREATE WIDGETS
 *
 *  These functions create a widget of appropiate class and 
 *  they give it a name
 *
 *****************************************************************/

/*  CreateLabel
 *  Creates a Label widget with a "name" and associates
 *  it the value "widLabel" to the label resource.
 */
static Widget CreateLabel(name,widLabel,parent,argu,n)
     String name,widLabel;
     Widget parent;
     Arg argu[];
     int n;
{
  XtSetArg(argu[n],XtNlabel,widLabel);   n++;
  return ( XtCreateManagedWidget(name,labelWidgetClass,parent,argu,n) );
}

/*----------------------------------------------------------------*/

/*  CreateComm
 *  Creates a Command widget with a "name" and associates
 *  it the value "widLabel" to the label resource.
 */
static Widget CreateComm(name,widLabel,parent,argu,n)
     String name,widLabel;
     Widget parent;
     Arg argu[];
     int n;
{
  XtSetArg(argu[n],XtNlabel,widLabel);   n++;
  return ( XtCreateManagedWidget(name,commandWidgetClass,parent,argu,n) );
}

/*----------------------------------------------------------------*/

/*  CreateMenuBut
 *  Creates a MenuButton widget with a "name" and associates
 *  it the value "widLabel" to the label resource.
 */
static Widget CreateMenuBut(name,widLabel,parent,argu,n)
     String name,widLabel;
     Widget parent;
     Arg argu[];
     int n;
{
  XtSetArg(argu[n],XtNlabel,widLabel);   n++;
  return ( XtCreateManagedWidget(name,menuButtonWidgetClass,parent,argu,n) );
}

/*----------------------------------------------------------------*/

/*  CreateSimpMenu
 *  Creates a SimpleMenu widget with a "name" and associates
 *  it the value "widLabel" to the label resource.
 */
static Widget CreateSimpMenu(name,widLabel,parent,argu,n)
     String name,widLabel;
     Widget parent;
     Arg argu[];
     int n;
{
  XtSetArg(argu[n],XtNlabel,widLabel);   n++;
  return ( XtCreatePopupShell(name,simpleMenuWidgetClass,parent,argu,n) );
}

/*----------------------------------------------------------------*/

/*  CreateSmeBSB
 *  Creates a SmeBSB Object with a "name" and associates
 *  it the value "widLabel" to the label resource.
 */
static Widget CreateSmeBSB(name,widLabel,parent,argu,n)
     String name,widLabel;
     Widget parent;
     Arg argu[];
     int n;
{
  XtSetArg(argu[n],XtNlabel,widLabel);   n++;
  return ( XtCreateManagedWidget(name,smeBSBObjectClass,parent,argu,n) );
}

/*----------------------------------------------------------------*/

/*  CreateTog
 *  Creates a Toggle widget with a "name" and associates
 *  it the value "widLabel" to the label resource.
 */
static Widget CreateTog(name,widLabel,parent,argu,n)
     String name,widLabel;
     Widget parent;
     Arg argu[];
     int n;
{
  XtSetArg(argu[n],XtNlabel,widLabel);   n++;
  return ( XtCreateManagedWidget(name,toggleWidgetClass,parent,argu,n) );
}

/*----------------------------------------------------------------*/

/*  CreateAsctext
 *  Creates a AsciiText widget with a "name".
 */
static Widget CreateAsctext(name,parent,argu,n)
     String name;
     Widget parent;
     Arg argu[];
     int n;
{
  return ( XtCreateManagedWidget(name,asciiTextWidgetClass,parent,argu,n) );
}

/*----------------------------------------------------------------*/

/*  CreateForm
 *  Creates a Form widget with a "name".
 */
static Widget CreateForm(name,parent,argu,n)
     String name;
     Widget parent;
     Arg argu[];
     int n;
{
  return ( XtCreateManagedWidget(name,formWidgetClass,parent,argu,n) );
}

/*----------------------------------------------------------------*/

/*  CreatePaned
 *  Creates a Paned widget with a "name".
 */
static Widget CreatePaned(name,parent,argu,n)
     String name;
     Widget parent;
     Arg argu[];
     int n;
{
  return ( XtCreateManagedWidget(name,panedWidgetClass,parent,argu,n) );
}

/*----------------------------------------------------------------*/

/*  CreateWindow
 *  Creates a Shell widget with a "name" and associates
 *  it the value "widiconName" to the iconName resource.
 */
static Widget CreateWindow(name,widIconName,parent,argu,n)
     String name,widIconName;
     Widget parent;
     Arg argu[];
     int n;
{
  XtSetArg(argu[n],XtNiconName,widIconName);   n++;
  return ( XtCreatePopupShell(name,topLevelShellWidgetClass,parent,argu,n) );
}

/******************************************************************
 *
 *              FUNCTIONS TO SET RESOURCE VALUES
 *
 *****************************************************************/

/*  SetWidgetInForm
 *  Places a child in his form parent to "horizDist" pixels 
 *  to the right of "left" widget and to "vertDist" pixels 
 *  under the "top" widget 
 */ 
static void SetWidgetInForm(argu,m,left,top,horizDist,vertDist)
     Arg argu[];
     int *m;
     Widget left,top;
     int horizDist,vertDist;
{
  if (left != (Widget)NULL)
    {
      XtSetArg(argu[*m],XtNfromHoriz,left);
      (*m)++;
    }
  if (top != (Widget)NULL)
    {
      XtSetArg(argu[*m],XtNfromVert,top);
      (*m)++;        
    }
  if (horizDist != DD)
    {
      XtSetArg(argu[*m],XtNhorizDistance,horizDist);
      (*m)++;
    }
  if (vertDist != DD)
    {
      XtSetArg(argu[*m],XtNvertDistance,vertDist);
      (*m)++;
    }
  return;
}

/*----------------------------------------------------------------*/

#define CHLEFT     XtChainLeft
#define CHRIGHT    XtChainRight
#define CHTOP      XtChainTop
#define CHBOTTOM   XtChainBottom

/*  SetChain
 *  Constrains the widget to maintain the position and size when 
 *  his form parent will be resized
 */ 
static void SetChain(argu,n,leftside,rightside,topside,bottomside)
     Arg argu[];
     int *n;
     XawEdgeType leftside,rightside,topside,bottomside;
{
  XtSetArg(argu[*n],XtNleft,     leftside);     (*n)++;
  XtSetArg(argu[*n],XtNright,   rightside);     (*n)++;
  XtSetArg(argu[*n],XtNtop,       topside);     (*n)++;
  XtSetArg(argu[*n],XtNbottom, bottomside);     (*n)++;
  return;
}

/*----------------------------------------------------------------*/

/*  SetTextMode
 *  Fixes the behaviour of a AsciiText Widget dedicated to receive
 *  the user's input
 */
static void SetTextMode(argu,n)
     Arg argu[];
     int *n;
{ 
  XtSetArg(argu[*n],XtNtype,     XawAsciiString);      (*n)++;
  XtSetArg(argu[*n],XtNeditType, XawtextEdit);         (*n)++;
  XtSetArg(argu[*n],XtNresize,   XawtextResizeWidth);  (*n)++;
  XtSetArg(argu[*n],XtNresizable,TRUE);                (*n)++;
  return;
}


/******************************************************************
 *
 *         FUNCTIONS TO CREATE THE INTERFACE WINDOWS 
 *
 *****************************************************************/

/*  CreateWindows
 *  Creates the Shell widgets which support the interface windows
 *  after to initialize the Toolkit 
 */
static void CreateWindows(argc,argv,context,window1,window2,
                          window3,window4,window5)
     int *argc;
     char **argv;
     XtAppContext *context;
     Widget *window1,*window2,*window3,*window4,*window5;
{
  Arg argu[3];
  int n;
  
  n=0;
     XtSetArg(argu[n],XtNiconName,"XLola");n++;
  *window1=XtAppInitialize(context,"XLola",NULL,0,argc,argv,
                               app_defaults,argu,n);
  n=0;
  *window2=CreateWindow("expandwin","Expansion",*window1,argu,n);
  n=0;
  *window3=CreateWindow("testwin","Testing",*window1,argu,n);
  n=0;
  *window4=CreateWindow("rew_window","Rewrite",*window1,argu,n);
  n=0;
  *window5=CreateWindow("stepwindow","Step",*window1,argu,n);

  /* Adds the new actions to the application */
  XtAppAddActions(*context,TableAct,XtNumber(TableAct));
  return;
}

/******************************************************************
 *
 *                      MAIN WINDOW. (XLola)
 *
 *****************************************************************/

/*  CreateMainWindow
 *  Creates the composite chidren which take part in the main window 
 */
static void CreateMainWindow(parent,load,print,quit,expansion,testing,
                             rewrite,step,help,nspec,nlibr,edit1,edit2)
     Widget parent,*load,*print,*quit,*expansion,*testing,
            *rewrite,*step,*help,*edit1,*edit2;
     char nspec[],nlibr[];
{
  Arg argu[2];
  int n;
  Widget leftpaned, rightpaned;

      XtSetArg(argu[0],XtNorientation,XtorientHorizontal);
  maincomp=CreatePaned("maincomp",parent,argu,1);
  leftpaned=CreatePaned("leftpaned",maincomp,(Arg *)NULL,0);
  
  n=0;
     XtSetArg(argu[n],XtNskipAdjust,True);   n++;
  rightpaned=CreatePaned("rightpaned",maincomp,argu,n);

  FirstPartMain(rightpaned,load,nspec,nlibr);
  SecPartMain(rightpaned,print);
  MiscCommands(rightpaned);
  ThirdPartMain(rightpaned,quit,expansion,testing,rewrite,step,help);
  CreateOutputArea(leftpaned,edit1,edit2);  
  return;
}

/*----------------------------------------------------------------*/

/*  FirstPartMain
 *  Creates the widgets to implement the Load command
 */
static void FirstPartMain(parent,load,nspec,nlibr)
     Widget parent,*load;
     char nspec[],nlibr[];
{
  Widget mainfirstform,spec_label,lib_label,specif,library;
  XFontStruct *wfont;
  Arg argu[12];
  int n;
  
  n=0;
     XtSetArg(argu[n],XtNmin,105);   n++;  
  mainfirstform=CreateForm("mainfirstform",parent,argu,n);

  n=0;
     SetWidgetInForm(argu,&n,(Widget)NULL,(Widget)NULL,DD,15);  
  *load=CreateComm("load"," Load ",mainfirstform,argu,n);

  n=0;
     SetWidgetInForm(argu,&n,(Widget)NULL,*load,DD,10);
  spec_label=CreateLabel("speclabel","Spec: ",mainfirstform,argu,n);

  n=0;
  XtSetArg(argu[n],XtNfont,&wfont); n++;
  XtGetValues(spec_label,argu,n);
  WidthChar=wfont->max_bounds.width;

  n=0;
     SetWidgetInForm(argu,&n,spec_label,*load,0,10);
     SetTextMode(argu,&n);
     XtSetArg(argu[n],XtNwidth,150);        n++;
     XtSetArg(argu[n],XtNresizable,TRUE);   n++;
     XtSetArg(argu[n],XtNstring,nspec);     n++; 
  specif=CreateAsctext("specif",mainfirstform,argu,n);
  SetTranslations(specif,TransDataString); 

  n=0;
     SetWidgetInForm(argu,&n,(Widget)NULL,spec_label,DD,10);
  lib_label=CreateLabel("liblabel","Libr: ",mainfirstform,argu,n);

  n=0;
     SetWidgetInForm(argu,&n,lib_label,spec_label,0,10);
     SetTextMode(argu,&n);
     XtSetArg(argu[n],XtNwidth,150);      n++;
     XtSetArg(argu[n],XtNstring,nlibr);   n++; 
  library=CreateAsctext("library",mainfirstform,argu,n);
  SetTranslations(library,TransDataString);

  XtAddCallback(*load,XtNcallback,LoadCB,(XtPointer)NULL);
  return;
}

/*----------------------------------------------------------------*/

/*  SecPartMain
 *  Creates the widgets to implement the Print command
 */ 
static void SecPartMain(parent,print)
     Widget parent,*print;
{
  Arg argu[6];
  int n;
  Widget mainsecform,print_options;

  n=0;
     XtSetArg(argu[n],XtNmin,185);   n++;
  mainsecform=CreateForm("mainsecform",parent,argu,n);
  
  n=0;
     SetWidgetInForm(argu,&n,(Widget)NULL,(Widget)NULL,DD,15);
  *print=CreateComm("print"," Print ",mainsecform,argu,n);

  n=0;
     SetWidgetInForm(argu,&n,(Widget)NULL,*print,DD,10);
     XtSetArg(argu[n],XtNinternalWidth,0);    n++;
     XtSetArg(argu[n],XtNinternalHeight,0);   n++;
  print_options=CreateForm("printoptions",mainsecform,argu,n);

  PrintOptions(print_options);
  XtAddCallback(*print,XtNcallback,PrintCB,(XtPointer)NULL);
  return;
} 

/*----------------------------------------------------------------*/

/*  PrintOptions
 *  Creates the widgets with options of print command
 */
static void PrintOptions(parent)
     Widget parent;
{
  Widget depth_label,out_label,printdepth,proc,typ,all,print_out;
  Arg argu[12];
  int n;
  
  n=0;
     SetWidgetInForm(argu,&n,(Widget)NULL,(Widget)NULL,DD,DD);
  depth_label=CreateLabel("depthlabel","Depth:  ",parent,argu,n);

  n=0;
     SetWidgetInForm(argu,&n,depth_label,(Widget)NULL,DD,DD);
     SetTextMode(argu,&n);     
     XtSetArg(argu[n],XtNwidth,50);     n++;
     XtSetArg(argu[n],XtNstring,"1");   n++;
  printdepth=CreateAsctext("depthPrint",parent,argu,n);
  SetTranslations(printdepth,TransIntNum);

  n=0;
     SetWidgetInForm(argu,&n,(Widget)NULL,depth_label,DD,DD);     
  out_label=CreateLabel("outlabel","Output: ",parent,argu,n);
  
  n=0;
     SetWidgetInForm(argu,&n,out_label,depth_label,DD,DD);
     SetTextMode(argu,&n);
     XtSetArg(argu[n],XtNwidth,150);   n++;
  print_out=CreateAsctext("printout",parent,argu,n);
  SetTranslations(print_out,TransDataString);
  
  n=0;
     SetWidgetInForm(argu,&n,(Widget)NULL,out_label,25,10);
  proc=CreateTog("process","       process       ",parent,argu,n);

  n=0;
     SetWidgetInForm(argu,&n,(Widget)NULL,proc,25,DD);
  typ=CreateTog("types","        types        ",parent,argu,n);

  n=0;   
     SetWidgetInForm(argu,&n,(Widget)NULL,typ,25,DD);
  all=CreateTog("wholespec"," whole specification ",parent,argu,n);

  /* Adds the callbacks to the toggle widgets, the "n" value indicates
     a position in the PrintChoice array */

  n=0;
  XtAddCallback(all,XtNcallback,PrintStateCB,(XtPointer)n);    n++;
  XtAddCallback(proc,XtNcallback,PrintStateCB,(XtPointer)n);   n++;
  XtAddCallback(typ,XtNcallback,PrintStateCB,(XtPointer)n);

  return;
}

/*----------------------------------------------------------------*/

/*  MiscCommands
 *  Creates the widgets to implement the save and datatable commands
 */

static void MiscCommands(parent)
     Widget parent;
{
#ifdef SDEBUG
  Widget formSave, save, labelSave, textSave;
#endif
  Widget formData, dataT,formFlags, labelLow, textLow, labelHigh,
         textHigh, sorts, var, oper, proc, gates;
  Arg argu[10];
  int n;
  
#ifdef SDEBUG

  formSave=CreateForm("formSave",parent,(Arg *)NULL,0);

  n=0;
     SetWidgetInForm(argu,&n,(Widget)NULL,(Widget)NULL,DD,15);
  save=CreateComm("save","  Save  ",formSave,argu,n);

  n=0;
     SetWidgetInForm(argu,&n,(Widget)NULL,save,DD,10);
  labelSave=CreateLabel("labelSave","Output File:",formSave,argu,n);

  n=0;
     SetWidgetInForm(argu,&n,labelSave,save,DD,10);
     SetTextMode(argu,&n);
  textSave=CreateAsctext("textSave",formSave,argu,n);
  SetTranslations(textSave,TransDataString);

  XtAddCallback(save,XtNcallback,SaveCB,(XtPointer)NULL);

#endif

  formData=CreateForm("formData",parent,(Arg *)NULL,0);

  n=0;
     SetWidgetInForm(argu,&n,(Widget)NULL,(Widget)NULL,DD,15);
  dataT=CreateComm("dataT"," DataTable ",formData,argu,n);

  n=0;
     SetWidgetInForm(argu,&n,(Widget)NULL,dataT,DD,10);
  formFlags=CreateForm("formFlags",formData,argu,n);

  n=0;
  labelLow=CreateLabel("labelLow","Low  Limit:  ",formFlags,argu,n);

  n=0;
     SetWidgetInForm(argu,&n,labelLow,(Widget)NULL,DD,DD);
     SetTextMode(argu,&n);
     XtSetArg(argu[n],XtNstring,"0");   n++;
  textLow=CreateAsctext("textLow",formFlags,argu,n);
  SetTranslations(textLow,TransIntNum);  

  n=0;
     SetWidgetInForm(argu,&n,(Widget)NULL,labelLow,DD,DD);
  labelHigh=CreateLabel("labelHigh","High Limit:  ",formFlags,argu,n);

  n=0;
     SetWidgetInForm(argu,&n,labelHigh,textLow,DD,DD);
     SetTextMode(argu,&n);
     XtSetArg(argu[n],XtNstring,"5");   n++;
  textHigh=CreateAsctext("textHigh",formFlags,argu,n);
  SetTranslations(textHigh,TransIntNum);
 
  n=0;
     SetWidgetInForm(argu,&n,(Widget)NULL,labelHigh,DD,10);
     XtSetArg(argu[n],XtNstate,TRUE);   n++;
  sorts=CreateTog("sorts","sorts",formFlags,argu,n);
  SetTranslations(sorts,TransRadio);

  n=0;
     SetWidgetInForm(argu,&n,sorts,labelHigh,0,10);
     XtSetArg(argu[n],XtNradioGroup,sorts);   n++;
  var=CreateTog("var","vars ",formFlags,argu,n);
  SetTranslations(var,TransRadio);

  n=0;
     SetWidgetInForm(argu,&n,var,labelHigh,0,10);
     XtSetArg(argu[n],XtNradioGroup,sorts);   n++;
  oper=CreateTog("oper","opers",formFlags,argu,n);
  SetTranslations(oper,TransRadio);

  n=0;
     SetWidgetInForm(argu,&n,oper,labelHigh,0,10);
     XtSetArg(argu[n],XtNradioGroup,sorts);   n++;
  proc=CreateTog("proc","procs",formFlags,argu,n);
  SetTranslations(proc,TransRadio);

  n=0;
     SetWidgetInForm(argu,&n,proc,labelHigh,0,10);
     XtSetArg(argu[n],XtNradioGroup,sorts);   n++;
  gates=CreateTog("gates","gates",formFlags,argu,n);
  SetTranslations(gates,TransRadio);

  XtAddCallback(dataT,XtNcallback,DataTableCB,(XtPointer)sorts);
  return;
}

/*----------------------------------------------------------------*/

/*  ThirdPartMain
 *  Creates the buttons to open the expansion, testing, 
 *  step and rewrite windows. The buttons of other miscelaneous 
 *  commands are create also (quit, help and statistic).
 */
static void ThirdPartMain(parent,quit,expansion,testing,rewrite,step,help)
     Widget parent,*quit,*expansion,*testing,*rewrite,*step,*help;
{
  Arg argu[12];
  int n;
  Widget mainthirdform, mainfourthform,mainfifthform,statistic;
  Dimension aux;

  n=0;
     XtSetArg(argu[n],XtNmin,80);   n++;
  mainthirdform=CreateForm("mainthirdform",parent,argu,n);

  n=0;
     XtSetArg(argu[n],XtNmin,40);   n++;
  mainfourthform=CreateForm("mainfourthform",parent,argu,n);

  mainfifthform=CreateForm("mainfifthform",parent,(Arg *)NULL,0);

  n=0;
     SetWidgetInForm(argu,&n,(Widget)NULL,(Widget)NULL,DD,10);
  *expansion=CreateComm("expansion","Expansion",mainthirdform,argu,n);

  n=0;
     SetWidgetInForm(argu,&n,*expansion,(Widget)NULL,DD,10);
  *testing=CreateComm("testing"," Testing ",mainthirdform,argu,n);

  n=0;
     SetWidgetInForm(argu,&n,(Widget)NULL,*expansion,DD,10);
  *rewrite=CreateComm("rewr"," Rewrite ",mainthirdform,argu,n);

  n=0;
     SetWidgetInForm(argu,&n,*rewrite,*expansion,DD,10);
     XtSetArg(argu[n],XtNmenuName,"menuw");   n++;
  *step=CreateComm("step","   Step  ",mainthirdform,argu,n);

  XtSetArg(argu[0],XtNwidth,&aux);
  XtGetValues(*step,argu,1);

  n=0;
     SetWidgetInForm(argu,&n,(Widget)NULL,(Widget)NULL,DD,10);
     XtSetArg(argu[n],XtNmenuName,"helpw");   n++;
  *help=CreateMenuBut("help","   Help  ",mainfourthform,argu,n);

  n=0;
     SetWidgetInForm(argu,&n,*help,(Widget)NULL,DD,10);
  statistic=CreateComm("quit","Statistic",mainfourthform,argu,n);

  n=0;
     SetWidgetInForm(argu,&n,(Widget)NULL,*help,45,10);
  *quit=CreateComm("quit","  Quit   ",mainfourthform,argu,n);

  n=0;
     SetWidgetInForm(argu,&n,(Widget)NULL,*help,DD,10);
  (void)CreateLabel("white","",mainfifthform,argu,n);     

  XtAddCallback(*expansion,XtNcallback,ShowWindowCB,
                (XtPointer)expandwindow);
  XtAddCallback(*testing,XtNcallback,ShowWindowCB,
                (XtPointer)testwindow);
  XtAddCallback(*rewrite,XtNcallback,XtCallbackNone,(XtPointer)rewrwindow);
  XtAddCallback(*step,XtNcallback,ShowWindowCB,(XtPointer)stepwindow);
  XtAddCallback(*quit,XtNcallback,QuitCB,(XtPointer)NULL);
  XtAddCallback(statistic,XtNcallback,StatisticCB,(XtPointer)NULL);
  return;
}   

/*----------------------------------------------------------------*/

/*  CreateOutputArea
 *  Creates the widgets which implement the Selection and 
 *  Output windows
 */
static void CreateOutputArea(parent,editor1,editor2)
     Widget parent,*editor1,*editor2;
{
  Arg argu[32];
  int n;
  Dimension dim;
  Widget cursorpart,outpart,to_spec,to_process,to_root,
         depthlabel,cursorlabel,depthcur,outlabel,clean,sink;
  XawTextSelectType *SelArray;
  
  SelArray=(XawTextSelectType *)malloc(2*sizeof(XawTextSelectType));
  *SelArray=XawselectPosition;

  n=0;
     XtSetArg(argu[n],XtNshowGrip,TRUE);   n++;
  cursorpart=CreateForm("cursorpart",parent,argu,n);

  n=0;
     XtSetArg(argu[n],XtNshowGrip,TRUE);   n++;
  outpart=CreateForm("outpart",parent,argu,n);

  n=0; 
     SetWidgetInForm(argu,&n,(Widget)NULL,(Widget)NULL,20,DD);     
     SetChain(argu,&n,CHLEFT,CHLEFT,CHTOP,CHTOP);
     XtSetArg(argu[n],XtNinternalHeight,4);   n++;
  to_spec=CreateComm("tospec"," Goto Spec ",cursorpart,argu,n);

  n=0; 
     SetWidgetInForm(argu,&n,to_spec,(Widget)NULL,15,DD);     
     SetChain(argu,&n,CHLEFT,CHLEFT,CHTOP,CHTOP);
     XtSetArg(argu[n],XtNinternalHeight,4);   n++;
  to_root=CreateComm("toroot"," Go Top ",cursorpart,argu,n);

  n=0;
     SetWidgetInForm(argu,&n,to_root,(Widget)NULL,15,DD);
     SetChain(argu,&n,CHLEFT,CHLEFT,CHTOP,CHTOP);
     XtSetArg(argu[n],XtNinternalHeight,4);   n++;
  to_process=CreateComm("toproc"," Proc List ",cursorpart,argu,n);

  n=0;
     SetWidgetInForm(argu,&n,to_process,(Widget)NULL,50,2*DD);
     SetChain(argu,&n,CHLEFT,CHLEFT,CHTOP,CHTOP);
  depthlabel=CreateLabel("depthc","Depth : ",cursorpart,argu,n);

  n=0;
     SetWidgetInForm(argu,&n,depthlabel,(Widget)NULL,0,2*DD);
     SetChain(argu,&n,CHLEFT,CHLEFT,CHTOP,CHTOP);
     SetTextMode(argu,&n);
     XtSetArg(argu[n],XtNwidth,30);     n++;
     XtSetArg(argu[n],XtNstring,"0");   n++;
  depthcur=CreateAsctext("depthcursor",cursorpart,argu,n);
  SetTranslations(depthcur,TransIntNum);
  
  n=0;
     SetWidgetInForm(argu,&n,(Widget)NULL,to_spec,2*DD,DD);
     SetChain(argu,&n,CHLEFT,CHRIGHT,CHTOP,CHTOP);
     XtSetArg(argu[n],XtNjustify,XtJustifyCenter);           n++;
     XtSetArg(argu[n],XtNwidth,(Dimension)(82*WidthChar));   n++;
  cursorlabel=CreateLabel("curslab",LABEL1,cursorpart,argu,n);

  n=0;
     SetWidgetInForm(argu,&n,(Widget)NULL,cursorlabel,DD,DD);       
     SetChain(argu,&n,CHLEFT,CHRIGHT,CHTOP,CHBOTTOM);
     XtSetArg(argu[n],XtNwidth,(Dimension)(82*WidthChar));        n++;
     XtSetArg(argu[n],XtNscrollVertical,XawtextScrollAlways);     n++;
     XtSetArg(argu[n],XtNscrollHorizontal,XawtextScrollAlways);   n++;
     XtSetArg(argu[n],XtNtype,XawAsciiString);                    n++;
     XtSetArg(argu[n],XtNeditType,XawtextRead);                   n++;
     XtSetArg(argu[n],XtNtopMargin,10);                           n++;
     XtSetArg(argu[n],XtNbottomMargin,10);                        n++;
     XtSetArg(argu[n],XtNselectTypes,SelArray);                   n++;
  *editor1=CreateAsctext("cursoredit",cursorpart,argu,n);
  SetTranslations(*editor1,TransCur);

  XtSetArg(argu[0],XtNtextSink,&sink);
  XtGetValues(*editor1,argu,1);
  HeightChar=XawTextSinkMaxHeight(sink,1);

  XtSetArg(argu[0],XtNheight,dim=(Dimension)(26*HeightChar+6));
  XtSetValues(*editor1,argu,1);  
  
  n=0;
     SetWidgetInForm(argu,&n,(Widget)NULL,(Widget)NULL,0,5);
     SetChain(argu,&n,CHLEFT,CHRIGHT,CHTOP,CHTOP);
     XtSetArg(argu[n],XtNjustify,XtJustifyCenter);           n++;
     XtSetArg(argu[n],XtNwidth,(Dimension)(80*WidthChar));   n++;
  outlabel=CreateLabel("outlabel",LABEL5,outpart,argu,n);

  n=0;
     SetWidgetInForm(argu,&n,(Widget)NULL,outlabel,5,30);
     SetChain(argu,&n,CHLEFT,CHRIGHT,CHTOP,CHBOTTOM);
     XtSetArg(argu[0],XtNheight,dim);                             n++;
     XtSetArg(argu[n],XtNwidth,(Dimension)(82*WidthChar));        n++;
     XtSetArg(argu[n],XtNscrollVertical,XawtextScrollAlways);     n++;
     XtSetArg(argu[n],XtNscrollHorizontal,XawtextScrollAlways);   n++;
     XtSetArg(argu[n],XtNtype,XawAsciiString);                    n++;
     XtSetArg(argu[n],XtNeditType,XawtextRead);                   n++;
     XtSetArg(argu[n],XtNtopMargin,10);                           n++;
     XtSetArg(argu[n],XtNbottomMargin,10);                        n++; 
  *editor2=CreateAsctext("out",outpart,argu,n);

  n=0;
     SetWidgetInForm(argu,&n,(Widget)NULL,*editor2,5,5);
     SetChain(argu,&n,CHLEFT,CHLEFT,CHBOTTOM,CHBOTTOM);
     XtSetArg(argu[n],XtNjustify,XtJustifyCenter);   n++;
  clean=CreateComm("cleanout","Clean Output",outpart,argu,n);

  XtAddCallback(to_process,XtNcallback,DisplaysProcessNamesCB,(XtPointer)NULL);
  XtAddCallback(to_root,XtNcallback,MoveCursorToRootCB,(XtPointer)NULL);
  XtAddCallback(to_spec,XtNcallback,MoveCursorToSpecCB,(XtPointer)NULL);
  XtAddCallback(clean,XtNcallback,CleanOutputCB,(XtPointer)NULL);
  
  return;
}

/******************************************************************
 *
 *                      EXPANSION WINDOW
 *
 *****************************************************************/

/*  CreateExpandWindow
 *  Calls the functions that create the widgets of this window
 */
static void CreateExpandWindow(parent,expand,inter)
     Widget parent,*expand,*inter;
{
  expandcomp=CreatePaned("expandcomp",parent,(Arg *)NULL,0);
  FirstPartExpand(expandcomp,expand);
  SecPartExpand(expandcomp,inter);
  ThirdPartExpand(expandcomp);
  return;
}

/*----------------------------------------------------------------*/

/*  FirstPartExpand
 *  Creates the widget to implement the Expand command
 */ 
static void FirstPartExpand(parent,expand)
     Widget parent,*expand;
{
  Arg argu[6];
  int n;
  Widget expandfirstform,expand_options;
  
  n=0;
     XtSetArg(argu[n],XtNmin,130);   n++;
  expandfirstform=CreateForm("expfirstform",parent,argu,n);
  
  n=0;
     SetWidgetInForm(argu,&n,(Widget)NULL,(Widget)NULL,DD,DD);
  *expand=CreateComm("expand"," Expand  ",expandfirstform,argu,n);
  
  n=0;
     SetWidgetInForm(argu,&n,(Widget)NULL,*expand,DD,4);
  expand_options=CreateForm("expand_options",expandfirstform,argu,n);
  
  ExpandOptions(expand_options);  
  
  XtAddCallback(*expand,XtNcallback,ExpandCB,(XtPointer)NULL);
  return;
} 

/*----------------------------------------------------------------*/

/*  ExpandOptions
 *  Creates the widgets with the options of the expand command
 */
static void ExpandOptions(parent)
     Widget parent;
{
  Widget depth_label,exp_depth,exp_verbose,exp_dupl,paramd,remove;
  Arg argu[12];
  int n;
  
  n=0;   
     SetWidgetInForm(argu,&n,(Widget)NULL,(Widget)NULL,18,DD);
     XtSetArg(argu[n],XtNstate,TRUE);   n++;
  remove=CreateTog("remove","Rem_Int_Acts",parent,argu,n);

  n=0;
     SetWidgetInForm(argu,&n,(Widget)NULL,remove,18,DD);
     XtSetArg(argu[n],XtNstate,TRUE);   n++;
  exp_verbose=CreateTog("verboseExpansion","   Verbose  ",parent,argu,n);

  n=0;
     SetWidgetInForm(argu,&n,(Widget)NULL,exp_verbose,18,DD);
     XtSetArg(argu[n],XtNstate,TRUE);   n++;
  exp_dupl=CreateTog("duplic_states","Dupli_States",parent,argu,n);

  n=0;   
     SetWidgetInForm(argu,&n,(Widget)NULL,exp_dupl,18,DD);
  paramd=CreateTog("paramet","Parameterized",parent,argu,n);

  n=0;
     SetWidgetInForm(argu,&n,(Widget)NULL,paramd,0,4);
  depth_label=CreateLabel("depth_exp_label","Depth:",parent,argu,n);

  n=0;
     SetWidgetInForm(argu,&n,depth_label,paramd,0,2);
     SetTextMode(argu,&n);
     XtSetArg(argu[n],XtNstring,"-1");   n++;
  exp_depth=CreateAsctext("depth_expan",parent,argu,n);
  SetTranslations(exp_depth,TransIntNum);

  n=0;
  XtAddCallback(remove,XtNcallback,ExpStateCB,(XtPointer)n);        n++;
  XtAddCallback(exp_verbose,XtNcallback,ExpStateCB,(XtPointer)n);   n++;
  XtAddCallback(exp_dupl,XtNcallback,ExpStateCB,(XtPointer)n);      n++;
  XtAddCallback(paramd,XtNcallback,ExpStateCB,(XtPointer)n);
  ExpChoice[0]=TRUE;
  ExpChoice[1]=TRUE;
  ExpChoice[2]=TRUE;
  return;
}

/*----------------------------------------------------------------*/

/*  SecPartExpand
 *  Creates the widgets to implement the inter command
 */
static void SecPartExpand(parent,inter)
     Widget parent,*inter;
{
  Arg argu[6];
  int n;
  Widget expandsecform,inter_options;

  n=0;
     XtSetArg(argu[n],XtNmin,100);   n++;
  expandsecform=CreateForm("expsecform",parent,argu,n);

  n=0;  
     SetWidgetInForm(argu,&n,(Widget)NULL,(Widget)NULL,DD,DD);
  *inter=CreateComm("inter","Inter",expandsecform,argu,n);

  n=0;
     SetWidgetInForm(argu,&n,(Widget)NULL,*inter,DD,4);
  inter_options=CreateForm("inter_options",expandsecform,argu,n);
  
  InterOptions(inter_options);
  
  XtAddCallback(*inter,XtNcallback,InterCB,(XtPointer)NULL);
  return;
} 

/*----------------------------------------------------------------*/

/*  InterOptions
 *  Creates the widgets with the options of the inter command
 */
static void InterOptions(parent)
     Widget parent;
{
  Widget /* int_depth, */ int_verbose,int_dupl,paramd;
  Arg argu[7];
  int n;
  
  n=0;
  SetWidgetInForm(argu,&n,(Widget)NULL,(Widget)NULL,18,DD);
  XtSetArg(argu[n],XtNstate,TRUE);   n++;
  int_verbose=CreateTog("verboseInter","   Verbose  ",parent,argu,n);
  
  n=0;
  SetWidgetInForm(argu,&n,(Widget)NULL,int_verbose,18,DD);
  XtSetArg(argu[n],XtNstate,TRUE);   n++;
  int_dupl=CreateTog("duplic_states","Dupli_States",parent,argu,n);

  n=0;   
  SetWidgetInForm(argu,&n,(Widget)NULL,int_dupl,18,DD);
  paramd=CreateTog("paramet","Parameterized",parent,argu,n);

  n=0;
  XtAddCallback(int_verbose,XtNcallback,InterStateCB,(XtPointer)n); n++;
  XtAddCallback(int_dupl   ,XtNcallback,InterStateCB,(XtPointer)n); n++;
  XtAddCallback(paramd     ,XtNcallback,InterStateCB,(XtPointer)n);
  InterChoice[0]=TRUE;
  InterChoice[1]=TRUE;
  InterChoice[2]=FALSE;
  return;
}

/*----------------------------------------------------------------*/

/*  ThirdPartExpand
 *  Creates a dismiss button 
 */
static void ThirdPartExpand(parent)
     Widget parent;
{
  Arg argu[6];
  int n;
  Widget expandthirdform,hide_exp;
  
  n=0;
     XtSetArg(argu[n],XtNmin,60);   n++;
  expandthirdform=CreateForm("expandthirdform",parent,argu,n);

  n=0;
     SetWidgetInForm(argu,&n,(Widget)NULL,(Widget)NULL,50,DD);
  hide_exp=CreateComm("disexp","Dismiss",expandthirdform,argu,n);

  XtAddCallback(hide_exp,XtNcallback,HideWindowCB,
                (XtPointer)(XtParent(parent)));
  return;
}  

/******************************************************************
 *
 *                       TESTING WINDOW
 *
 *****************************************************************/

/*  CreateTestingWindow
 *  Calls the functions which create the widgets of the window
 */
static void CreateTestingWindow(parent,test,one)
       Widget parent,*test,*one;
{
  Arg argu[1];
  
  XtSetArg(argu[0],XtNorientation,XtorientHorizontal);
  testcomp=CreatePaned("testcomp",parent,argu,1);
  FirstPartTesting(testcomp,test);
  SecPartTesting(testcomp,one);
  ThirdPartTesting(testcomp);
  return;
}

/*----------------------------------------------------------------*/

/*  FirstPartTesting
 *  Creates the widgets which implement the test command
 */
static void FirstPartTesting(parent,test)
     Widget parent,*test;
{
  Arg argu[6];
  int n;
  Widget testfirstform,test_options,opt_label;
  
  n=0;
     XtSetArg(argu[n],XtNmin,150);   n++;
  testfirstform=CreateForm("testfirstform",parent,argu,n);

  n=0;
     SetWidgetInForm(argu,&n,(Widget)NULL,(Widget)NULL,DD,DD);
  *test=CreateComm("test"," Test ",testfirstform,argu,n);
  
  n=0;
     SetWidgetInForm(argu,&n,(Widget)NULL,*test,0,DD);
  opt_label=CreateLabel("comment","-- Debug Options --",testfirstform,argu,n);
  
  n=0;
     SetWidgetInForm(argu,&n,(Widget)NULL,opt_label,10,2);
  test_options=CreateForm("test_options",testfirstform,argu,n);

  TestingOptions(test_options);
  
  XtAddCallback(*test,XtNcallback,TestCB,(XtPointer)NULL);
  return;
} 

/*----------------------------------------------------------------*/

/*  TestingOptions 
 *  Creates the widgets with the debug options of the test command
 */
static void TestingOptions(parent)
     Widget parent;
{
  Arg argu[7];
  int n;
  Widget actions,stops,exits,test_depth,full_expl;

  n=0;
     SetWidgetInForm(argu,&n,(Widget)NULL,(Widget)NULL,DD,DD);
  actions=CreateTog("actions","   Actions   ",parent,argu,n);

  n=0;
     SetWidgetInForm(argu,&n,(Widget)NULL,actions,2,2);
  stops=CreateTog("stops","    Stops    ",parent,argu,n);

  n=0;
     SetWidgetInForm(argu,&n,(Widget)NULL,stops,2,2);
  exits=CreateTog("exits","    Exits    ",parent,argu,n);

  n=0;
     SetWidgetInForm(argu,&n,(Widget)NULL,exits,DD,2);
  test_depth=CreateTog("testdepth","    Depth    ",parent,argu,n);

  n=0;   
     SetWidgetInForm(argu,&n,(Widget)NULL,test_depth,2,2);
  full_expl=CreateTog("fullexploration","Full_Explorat",parent,argu,n);

  n=0;
  XtAddCallback(actions,XtNcallback,TestStateCB,(XtPointer)n);   n++;
  XtAddCallback(test_depth,XtNcallback,TestStateCB,(XtPointer)n);   n++;
  XtAddCallback(exits,XtNcallback,TestStateCB,(XtPointer)n);   n++;
  XtAddCallback(stops,XtNcallback,TestStateCB,(XtPointer)n);   n++;
  XtAddCallback(full_expl,XtNcallback,TestStateCB,(XtPointer)n);
  return;
}

/*----------------------------------------------------------------*/

/*  SecPartTesting
 *  Creates the widgets to implement the one command
 */
static void SecPartTesting(parent,one)
     Widget parent,*one;
{
  Widget testsecpaned,testform1,testform2,seed_label,seed,dismiss;
  Arg argu[12];
  int n;

  n=0;
     XtSetArg(argu[n],XtNmin,160);   n++;
  testsecpaned=CreatePaned("testsecpaned",parent,argu,n);

  n=0;
     XtSetArg(argu[n],XtNmin,70);   n++;
  testform1=CreateForm("testform1",testsecpaned,argu,n);

  n=0;
     XtSetArg(argu[n],XtNmin,102);   n++;
  testform2=CreateForm("testform2",testsecpaned,argu,n);

  n=0;  
     SetWidgetInForm(argu,&n,(Widget)NULL,(Widget)NULL,2,DD);
  *one=CreateComm("one"," One ",testform1,argu,n);

  n=0;
     SetWidgetInForm(argu,&n,(Widget)NULL,*one,DD,10);
  seed_label=CreateLabel("seedlabel","Seed:",testform1,argu,n);

  n=0;
     SetTextMode(argu,&n);
     SetWidgetInForm(argu,&n,seed_label,*one,DD,10);
     XtSetArg(argu[n],XtNstring,"1");   n++;
  seed=CreateAsctext("seed",testform1,argu,n);
  SetTranslations(seed,TransIntNum);

  n=0;
     SetWidgetInForm(argu,&n,(Widget)NULL,(Widget)NULL,10,60);
  dismiss=CreateComm("distest","Dismiss",testform2,argu,n);

  XtAddCallback(*one,XtNcallback,OneCB,(XtPointer)NULL);
  XtAddCallback(dismiss,XtNcallback,HideWindowCB,
                (XtPointer)(testwindow));
  return;
}

/*----------------------------------------------------------------*/

/*  ThirdPartTesting
 *  Creates the widgets with the common options of the Test
 *  and One commands
 */
static void ThirdPartTesting(parent)
     Widget parent;
{
  Arg argu[10];
  int n;
  Widget testthirdform,comment,depth_label,ev_label,test_label,oth_depth,
         events,test_proc,test_verbose,no_remove;

  n=0;
     XtSetArg(argu[n],XtNmin,180);   n++;
  testthirdform=CreateForm("testthirdform",parent,argu,n);

  n=0;
     SetWidgetInForm(argu,&n,(Widget)NULL,(Widget)NULL,0,DD);
  comment=CreateLabel("comment","-- Common Options --",testthirdform,argu,n);

  n=0; 
     SetWidgetInForm(argu,&n,(Widget)NULL,comment,0,DD);
  depth_label=CreateLabel("depthlabel3","Depth:    ",testthirdform,argu,n);

  n=0;
     SetWidgetInForm(argu,&n,depth_label,comment,0,DD);
     SetTextMode(argu,&n);
     XtSetArg(argu[n],XtNstring,"10");   n++;
  oth_depth=CreateAsctext("oth_depth",testthirdform,argu,n);
  SetTranslations(oth_depth,TransIntNum);

  n=0;
     SetWidgetInForm(argu,&n,(Widget)NULL,depth_label,0,2);
  ev_label=CreateLabel("evlabel","Suc Event:",testthirdform,argu,n);

  n=0;
     SetWidgetInForm(argu,&n,ev_label,depth_label,0,4);
     SetTextMode(argu,&n);
     XtSetArg(argu[n],XtNstring,"success");   n++;
  events=CreateAsctext("events",testthirdform,argu,n);
  SetTranslations(events,TransDataString);

  n=0;
     SetWidgetInForm(argu,&n,(Widget)NULL,ev_label,0,4);
  test_label=CreateLabel("testlabel","Test Proc:",testthirdform,argu,n);

  n=0;
     SetWidgetInForm(argu,&n,test_label,ev_label,0,4);
     SetTextMode(argu,&n);
  test_proc=CreateAsctext("testprocess",testthirdform,argu,n);
  SetTranslations(test_proc,TransDataString);

  n=0;
     SetWidgetInForm(argu,&n,(Widget)NULL,test_proc,25,5);
     XtSetArg(argu[n],XtNstate,TRUE);   n++;
  test_verbose=CreateTog("verbtest","    Verbose    ",testthirdform,argu,n);

  n=0;
     SetWidgetInForm(argu,&n,(Widget)NULL,test_verbose,25,5);
  no_remove=CreateTog("noremove","No Rem_Int_Acts",testthirdform,argu,n);

  n=0;
  XtAddCallback(no_remove,XtNcallback,OneStateCB,(XtPointer)n);
  XtAddCallback(no_remove,XtNcallback,TestStateCB,(XtPointer)(n+5));   n++;
  XtAddCallback(test_verbose,XtNcallback,OneStateCB,(XtPointer)n);
  XtAddCallback(test_verbose,XtNcallback,TestStateCB,(XtPointer)(n+5));
  TestChoice[6]=TRUE;
  OneChoice[1]=TRUE;
  return;
}

/******************************************************************
 *
 *                          REWRITE WINDOW
 *
 *******************************************************************/

/*  CreateRewriteWindow
 *  Creates the widgets which implement the rewrite command into a 
 *  new window
 */
static void CreateRewriteWindow(parent)
     Widget parent;
{
  Widget rewcomp,rewtext,rewrite,clean,dismiss;
  int n;
  Arg argu[16];

  rewcomp=CreateForm("rewcomp",parent,(Arg *)NULL,0);

  n=0;
     SetChain(argu,&n,CHLEFT,CHRIGHT,CHTOP,CHBOTTOM);
     XtSetArg(argu[n],XtNwidth,(Dimension)(40*WidthChar));          n++;
     XtSetArg(argu[n],XtNheight,(Dimension)(4*HeightChar));         n++;
     XtSetArg(argu[n],XtNscrollVertical,XawtextScrollWhenNeeded);   n++;
     XtSetArg(argu[n],XtNwrap,XawtextWrapLine);                     n++;
     XtSetArg(argu[n],XtNtype,XawAsciiString);                      n++;
     XtSetArg(argu[n],XtNeditType,XawtextEdit);                     n++;
  rewtext=CreateAsctext("rewtext",rewcomp,argu,n);

  n=0;
     SetWidgetInForm(argu,&n,(Widget)NULL,rewtext,DD,DD);
     SetChain(argu,&n,CHLEFT,CHLEFT,CHBOTTOM,CHBOTTOM);
  rewrite=CreateComm("rewcom","Rewrite",rewcomp,argu,n);

  n=0;
     SetWidgetInForm(argu,&n,rewrite,rewtext,20,DD);
     SetChain(argu,&n,CHLEFT,CHLEFT,CHBOTTOM,CHBOTTOM);
  clean=CreateComm("rewclean","Clean",rewcomp,argu,n);  

  n=0;
     SetWidgetInForm(argu,&n,clean,rewtext,20,DD);
     SetChain(argu,&n,CHLEFT,CHLEFT,CHBOTTOM,CHBOTTOM);
  dismiss=CreateComm("rewdis","Dismiss",rewcomp,argu,n);

  XtAddCallback(rewrite,XtNcallback,RewriteCB,(XtPointer)NULL);
  XtAddCallback(dismiss,XtNcallback,HideRewriteCB,(XtPointer)rewrwindow);
  XtAddCallback(clean,XtNcallback,CleanRewriteCB,(XtPointer)rewtext);
  return;
}

/******************************************************************
 *
 *                        STEP WINDOW
 *
 *****************************************************************/

/*  CreateStepWindow
 *  Creates the widgets to realize a step-by-step simulation
 */
static void CreateStepWindow(parent,strings)
     Widget parent;
     char **strings;
{
  Widget steppan,stepform1,stepform2,succlabstep,succtextstep,
         testlabstep,testtextstep,psynclabstep,psynctextstep,
         start,menu,refused,undo,trace,sexit;
  int n;
  Arg argu[10];
  Dimension width,height;
  
  steppan=CreatePaned("steppan",parent,(Arg *)NULL,0);

  n=0;
     XtSetArg(argu[n],XtNmin,26); n++;
  stepform1=CreateForm("stepform1",steppan,argu,n);

  n=0;
     XtSetArg(argu[n],XtNmin,13); n++;
  stepform2=CreateForm("stepform2",steppan,argu,n);

  n=0;
  succlabstep=CreateLabel("succlabstep","Success Event:",stepform1,argu,n);

  n=0;
     SetWidgetInForm(argu,&n,succlabstep,(Widget)NULL,DD,DD);
     SetTextMode(argu,&n);
  succtextstep=CreateAsctext("succtextstep",stepform1,argu,n);
  SetTranslations(succtextstep,TransDataString);

  n=0;
     SetWidgetInForm(argu,&n,(Widget)NULL,succlabstep,DD,DD);
  testlabstep=CreateLabel("testlabstep","Test  Process:",stepform1,argu,n);

  n=0;
     SetWidgetInForm(argu,&n,testlabstep,succlabstep,DD,DD);
     SetTextMode(argu,&n);
  testtextstep=CreateAsctext("testtextstep",stepform1,argu,n);
  SetTranslations(testtextstep,TransDataString);

  n=0;
     SetWidgetInForm(argu,&n,(Widget)NULL,testlabstep,DD,DD);
  psynclabstep=CreateLabel("psynclabstep","Sync  Process:",stepform1,argu,n);

  n=0;
     SetWidgetInForm(argu,&n,psynclabstep,testlabstep,DD,DD);
     SetTextMode(argu,&n);
  psynctextstep=CreateAsctext("psynctextstep",stepform1,argu,n);
  SetTranslations(psynctextstep,TransDataString);

  n=0;
  start=CreateComm("start","Start",stepform2,argu,n);
  
  n=0;
     SetWidgetInForm(argu,&n,start,(Widget)NULL,DD,DD);
  menu=CreateComm("menu","Menu",stepform2,argu,n);
  
  n=0;
     SetWidgetInForm(argu,&n,menu,(Widget)NULL,DD,DD);
  refused=CreateComm("steprefused","Refused",stepform2,argu,n);
  
  n=0;
     SetWidgetInForm(argu,&n,refused,(Widget)NULL,DD,DD);
  undo=CreateComm("undo","Undo",stepform2,argu,n);
  
  n=0;
     SetWidgetInForm(argu,&n,undo,(Widget)NULL,DD,DD);
  trace=CreateComm("trace","Trace",stepform2,argu,n);
  
  n=0;
     SetWidgetInForm(argu,&n,trace,(Widget)NULL,DD,DD);
  sexit=CreateComm("exit","Exit",stepform2,argu,n);

  XtAddCallback(start,XtNcallback,StartCB,(XtPointer)NULL);
  XtAddCallback(menu,XtNcallback,TransitionsCB,(XtPointer)NULL);
  XtAddCallback(sexit,XtNcallback,ExitCB,(XtPointer)NULL);
  XtAddCallback(sexit,XtNcallback,HideWindowCB,(XtPointer)stepwindow);
  XtAddCallback(undo,XtNcallback,UndoCB,(XtPointer)NULL);
  XtAddCallback(trace,XtNcallback,TraceCB,(XtPointer)NULL);
  XtAddCallback(refused,XtNcallback,RefusedCB,(XtPointer)NULL);
  
  n=0;
  XtSetArg(argu[n],XtNwidth,&width);     n++;
  XtSetArg(argu[n],XtNheight,&height);   n++;
  XtGetValues(stepwindow,argu,n);
  
  n=0;
  XtSetArg(argu[n],XtNminWidth,width);    n++;
  XtSetArg(argu[n],XtNminHeight,height);  n++;
  XtSetValues(stepwindow,argu,n);
  return;
}

/******************************************************************
 *
 *                          HELP WINDOW
 *
 *****************************************************************/

/*  HelpOptions
 *  Implements the help menu
 */
static void HelpOptions(parent)
     Widget parent;
{
  int n;
  Arg argu[5];
  Widget load,print,stat,dataT,expansion,test,one,
         inter,rewrite,step,quit;

#ifdef SDEBUG
  Widget save;
#endif

  n=0;
  helpwindow=CreateSimpMenu("helpw","Help Options",parent,argu,n);
  (void)XtCreateManagedWidget("line",smeLineObjectClass,helpwindow,
                              (Arg *)NULL,0);
  n=0;
  load=CreateSmeBSB("loadhelp","Load",helpwindow,argu,n);

  n=0;
  print=CreateSmeBSB("printhelp","Print",helpwindow,argu,n);

  n=0;
  stat=CreateSmeBSB("stathelp","Statistic",helpwindow,argu,n);

#ifdef SDEBUG
  n=0;
  save=CreateSmeBSB("savehelp","Save",helpwindow,argu,n);
  XtAddCallback(save,XtNcallback,HelpCB,(XtPointer)'v');
#endif

  n=0;
  dataT=CreateSmeBSB("dataThelp","DataTable",helpwindow,argu,n);
  
  n=0;
     XtSetArg(argu[n],XtNheight,20);   n++;
  (void)XtCreateManagedWidget("blanco",smeObjectClass,helpwindow,argu,n);

  n=0;
  expansion=CreateSmeBSB("expandhelp","Expansion",helpwindow,argu,n);
 
  n=0;
  inter=CreateSmeBSB("Interhelp","Inter",helpwindow,argu,n);

  n=0;
     XtSetArg(argu[n],XtNheight,20);   n++;
  (void)XtCreateManagedWidget("blanco",smeObjectClass,helpwindow,argu,n);

  n=0;
  test=CreateSmeBSB("testhelp","Test",helpwindow,argu,n);

  n=0;
  one=CreateSmeBSB("onehelp","One",helpwindow,argu,n);

  n=0;
     XtSetArg(argu[n],XtNheight,20);   n++;
  (void)XtCreateManagedWidget("blanco",smeObjectClass,helpwindow,argu,n);

  n=0;
  rewrite=CreateSmeBSB("rewrhelp","Rewrite",helpwindow,argu,n);

  n=0;
  step=CreateSmeBSB("stephelp","Step",helpwindow,argu,n);

  n=0;
     XtSetArg(argu[n],XtNheight,20);   n++;
  (void)XtCreateManagedWidget("blanco",smeObjectClass,helpwindow,argu,n);

  n=0;
  quit=CreateSmeBSB("quithelp","Quit",helpwindow,argu,n);

  XtAddCallback(rewrite,  XtNcallback,HelpCB,(XtPointer)'r');
  XtAddCallback(load,     XtNcallback,HelpCB,(XtPointer)'l');
  XtAddCallback(print,    XtNcallback,HelpCB,(XtPointer)'p');
  XtAddCallback(stat,     XtNcallback,HelpCB,(XtPointer)'a');
  XtAddCallback(dataT,    XtNcallback,HelpCB,(XtPointer)'d');
  XtAddCallback(expansion,XtNcallback,HelpCB,(XtPointer)'e');
  XtAddCallback(inter,    XtNcallback,HelpCB,(XtPointer)'i');
  XtAddCallback(test,     XtNcallback,HelpCB,(XtPointer)'t');
  XtAddCallback(one,      XtNcallback,HelpCB,(XtPointer)'o');
  XtAddCallback(step,     XtNcallback,HelpCB,(XtPointer)'s');
  XtAddCallback(quit,     XtNcallback,HelpCB,(XtPointer)'q');
  return;
}

/******************************************************************
 *
 *                            ACTIONS
 *
 *****************************************************************/

/*  GetLineNumberACT
 *  Calculates in which line of the cursor window the left button 
 *  has been pressed.
 */
static void GetLineNumberACT(w,event,params,nparams)
     Widget w;
     XEvent *event;
     String *params;
     int nparams;
{
  XawTextPosition start,aux,pos;
  XawTextBlock searched;
  Widget src;
  int line;
  long opt=0;
  ListTyp lm;
  char *procsyncname;
  
  src=XawTextGetSource(w);
  searched.firstPos=0;
  searched.ptr="\n";
  searched.length=1;
  searched.format=FMT8BIT;
  start = XawTextGetInsertionPoint(w);
  pos=start;

  /* Counts the lines from the place where the left button was pressed
     to beginning of the buffer */

  line=1;
  while((aux=XawTextSourceSearch(src,start,XawsdLeft,&searched))
        !=  XawTextSearchError) {
    line++;
    start = aux;
  }
  switch (cursorState){
  case SHOW_BEHAVIOUR: 
    lm = GetMove(line);
    if ((lm!=NULL) && ((Length_list(lm)!=1)
                       || (LookInfo_list(lm)!=0))) {
      (void)Move(line,'l');
      ActualizeCursor();
    }
    break;
    
  case SHOW_PROC_NAMES:
    (void)MoveDProc( line );
    ActualizeCursor();
    if (StepWorking){
      BlockByProcWhileStep(FALSE);
      BlockWidget(stepwindow,"*start",FALSE);
      BlockStep(FALSE);
      if (dataCreated)
        BlockWidget(valwindow,"*conf",FALSE);
    }
    else{
      BlockByProcList(FALSE);
      BlockStep(TRUE);
    }
    break;
    
  case TRANSITIONS:
    if (!dataCreated) {
      opt = GetOptionNumber(src,pos);
      if (opt != 0) {
        procsyncname = ReadText(stepwindow,"*psynctextstep");
        ECstep_sync(opt,procsyncname);
        Disp_list(varListStep);
        varListStep = ECstep_branch_GetUnassignedVars(opt);
        if ( varListStep != NULL) {
          /* control goes to the data window */
          printMsgs("\n  Enter expressions for the variable definitions ");
          printMsgs("(Done for none):\n");
          optStep = opt;
          CreateDataWindow(varListStep,2);
        }
        else {
          LASSERT(svTableStep==NULL);
          svTableStep = CreateSV();
          ECstep_branch_exec((int)opt,svTableStep);
          FreeSV(&svTableStep);
          ActualizeMenu();
        }
      }
    }
    break;
    
  case REFUSED:
    opt = GetOptionNumber(src,pos);
    if (opt!=0) {
      procsyncname = ReadText(stepwindow,"*psynctextstep");
      ECstep_sync(opt,procsyncname);
    }
    break;
  }
}

/******************************************************************
 *
 *                         CALLBACKS 
 *
 *****************************************************************/

/*  LoadCB
 *  Loads a specification and a library.
 */
static void LoadCB(w,client_data,call_data)
     Widget w;
     XtPointer client_data,call_data;
{
  if (dataCreated)
    DestroyDataWindow();
  
  spec = ReadText(maincomp,"*specif");
  lib  = ReadText(maincomp,"*library");
  (void)ECload(spec,lib);
  CleanEventQueue(maincomp,"*load");
  if (cursorState == SHOW_PROC_NAMES){
    if (StepWorking){
      BlockByProcWhileStep(FALSE);
      BlockWidget(stepwindow,"*start",FALSE);
      BlockStep(TRUE);
      BlockStepData(FALSE);
    }
    else{
      BlockByProcList(FALSE);
      BlockStep(TRUE);
    }
  }
  else{
    BlockStep(TRUE);
    StepWorking=FALSE;
    BlockStepData(FALSE);
  }
  ActualizeCursor();
}

/*----------------------------------------------------------------*/

/*  PrintCB
 *  Prints the current behaviour into the Output window.
 */
static void PrintCB(w,client_data,call_data)
     Widget w;
     XtPointer client_data,call_data;
{
  int n,DepthValue;
  
  outfile     = ReadText(maincomp,"*printout");
  DepthValue  = ReadNum(maincomp,"*depthPrint",4);
  n           = SetOptions(PrintChoice,printlist,NPR,commflags);
  if (DepthValue != BADINTEGER){
    CleanWindow(output);
    if (cursorState == SHOW_BEHAVIOUR)
      ECprint(n,commflags,DepthValue,outfile,PrintStrInOutput);
    else
      ECstep_print(n,commflags,DepthValue,outfile,PrintStrInOutput);
    *commflags='\0';
    CleanEventQueue(maincomp,"*print");
  }
}


/*----------------------------------------------------------------*/

/*  DataTableCB
 *  Prints the internal tables used in XLOLA into the Output Window
 */
static void DataTableCB(w,client_data,call_data)
     Widget w;
     XtPointer client_data,call_data;
{
  String option;
  int hl,ll;
  char table;
  
  option=XawToggleGetCurrent((Widget)client_data);
  ll=ReadNum(mainwindow,"*textLow",0);
  hl=ReadNum(mainwindow,"*textHigh",5);
  table=option[0];
  if (ll != BADINTEGER && hl != BADINTEGER){
    ECdata(table,ll,hl);
  }
}

/*----------------------------------------------------------------*/

/*  ExpandCB
 *  Expands the current behaviour.
 */
static void ExpandCB(w,client_data,call_data)
     Widget w;
     XtPointer client_data,call_data;
{
  int n,DepthValue;
  
  if (cursorState == SHOW_BEHAVIOUR) {
    DepthValue = ReadNum(expandcomp,"*depth_expan",-1);
    n          = SetOptions(ExpChoice,explist,NEXF,commflags);
    if (DepthValue != BADINTEGER){
      if (ExpChoice[2]) {
                if (ExpChoice[3])
                  ECvar(DepthValue,n,commflags);
                else
                  ECexpand(DepthValue,n,commflags);
      }
      else
                ECfree(DepthValue,n,commflags);
      ActualizeCursor();
      *commflags='\0';
      CleanEventQueue(expandcomp,"*expand");
    }
  }
}

/*----------------------------------------------------------------*/

/*  InterCB
 *  Applies the interleaved expansion to the current behaviour.
 */
static void InterCB(w,client_data,call_data)
     Widget w;
     XtPointer client_data,call_data;
{
  int n;
  
  if (cursorState == SHOW_BEHAVIOUR) {
    n=SetOptions(InterChoice,interlist,NIN,commflags);
    ECit(n,-1,"\0","\0",commflags);
    ActualizeCursor();
    *commflags='\0';
    CleanEventQueue(expandcomp,"*inter");
  }
}

/*----------------------------------------------------------------*/

/*  TestCB
 *  Passes a test to the current behaviour.
 */
static void TestCB(w,client_data,call_data)
     Widget w;
     XtPointer client_data,call_data;
{
  int n,DepthValue;
  
  if (cursorState == SHOW_BEHAVIOUR) {
    DepthValue  = ReadNum(testcomp,"*oth_depth",-1);
    evsuc       = ReadText(testcomp,"*events");
    testproc    = ReadText(testcomp,"*testprocess");
    n           = SetOptions(TestChoice,testlist,NTE,commflags);
    if (DepthValue != BADINTEGER){
      ECtest(n,DepthValue,evsuc,testproc,commflags,"\0",UNDEFINED,0,100,0);
      *commflags='\0';
      ActualizeCursor();
      CleanEventQueue(testcomp,"*test");
    }
  }
}

/*----------------------------------------------------------------*/

/*  OneCB
 *  Applies OneExpand to the current behaviour.
 */
static void OneCB(w,client_data,call_data)
     Widget w;
     XtPointer client_data,call_data;
{
  int n,DepthValue,OSeed;
  
  if (cursorState == SHOW_BEHAVIOUR) {
    DepthValue = ReadNum(testcomp,"*oth_depth",-1);
    OSeed      = ReadNum(testcomp,"*seed",1);
    evsuc      = ReadText(testcomp,"*events");
    testproc   = ReadText(testcomp,"*testprocess");
    n          = SetOptions(OneChoice,onelist,NON,commflags);
    if (DepthValue != BADINTEGER && OSeed != BADINTEGER ){
      ECone(DepthValue,evsuc,testproc,OSeed,n,commflags,1);
      *commflags='\0';
      ActualizeCursor();
      CleanEventQueue(testcomp,"*one");
    }
  }  
}

/*----------------------------------------------------------------*/

/*  RewriteCB
 *  Calculates the normal form of an expression
 */
static void RewriteCB(w,client_data,call_data)
     Widget w;
     XtPointer client_data,call_data;
{
  char * exprstr;
  ExprTyp expr;
  
  exprstr = ReadText(rewrwindow,"*rewtext");
  if (StringToExpr(exprstr,&expr,0)) {
    ECrewrite(expr);
  }
  CleanEventQueue(rewrwindow,"*rewcom");
}

/*--------------------------------------------------------------*/

static DescriptorTyp sedSCB, procSCB;

/*  StartCB
 *  Initializes a step by step simulation of the current behaviour
 *  or the composition current behaviour - test if a test process 
 *  is provided 
 */
static void StartCB(w,client_data,call_data)
     Widget w;
     XtPointer call_data,client_data;
{
  char *successeventname, *testprocessname;
  
  successeventname = ReadText(stepwindow,"*succtextstep");
  testprocessname  = ReadText(stepwindow,"*testtextstep");
  
  if (ECstep_start_CheckBehEventTest(successeventname,testprocessname,
                                     &sedSCB,&procSCB)){
    Disp_list(varListStep);
    varListStep = ECstep_start_GetUnassignedVars();
    if (varListStep != NULL) {
      /* control goes to the data window */
      printMsgs("\n  Enter expressions for the variable definitions ");
      printMsgs("(Done for none):\n");
      CreateDataWindow(varListStep,1);
    }
    else {
      LASSERT(svTableStep==NULL);
      svTableStep = CreateSV();
      StartCB_cont();
      FreeSV(&svTableStep);
    }
    BlockStepData(TRUE);
    
  }
  else {
    BlockStep(TRUE);   /* if some value are bad it does anything*/
    StepWorking=FALSE;
  }
}

/*----------------------------------------------------------------*/

/*  TransitionsCB
 *  Displays the menu of transitions offered at the current state into 
 *  the Selection Window
 */
static void TransitionsCB(w,client_data,call_data)
     Widget w;
     XtPointer client_data,call_data;
{
  ActualizeMenu();
}

/*----------------------------------------------------------------*/

/*  RefusedCB
 *  Displays the menu of unsuccessful synchronizations at the current 
 *  state into the Selection Window
 */
static void RefusedCB(w,client_data,call_data)
     Widget w;
     XtPointer client_data,call_data;
{
  if (ECstep_ExistRefused()) 
    ActualizeRefused();
  else 
    ECstep_refused();
}


/*----------------------------------------------------------------*/

/*  UndoCB
 *  Undoes the last simulation step (back to previous state)
 */
static void UndoCB(w,client_data,call_data)
     Widget w;
     XtPointer client_data,call_data;
{
  if (ECstep_undo())
    ActualizeMenu();
}

/*----------------------------------------------------------------*/

/*  TraceCB
 *  Displays the sequence of transitions that lead to the current state
 */
static void TraceCB(w,client_data,call_data)
     Widget w;
     XtPointer client_data,call_data;
{
  ECstep_trace();
}

/*----------------------------------------------------------------*/

/*  ExitCB
 *  Quit simulation mode
 */
static void ExitCB(w,client_data,call_data)
     Widget w;
     XtPointer client_data,call_data;
{
  if (dataCreated)
    DestroyDataWindow();
  ECstep_exit();
  if (cursorState != SHOW_PROC_NAMES)
    ActualizeCursor();
  StepWorking=FALSE;
  BlockStepData(FALSE);
}

/*--------------------------------------------------------------*/

/*  HelpCB
 *  Prints the functionality of a specified command by the user
 *  into the Output Window
 */
static void HelpCB(w,client_data,call_data)
     Widget w;
     XtPointer call_data,client_data;
{
  switch ((char)client_data){
  case 'l': Load_XHelp();
    break;
  case 'p': Print_XHelp();
    break;
  case 'a': Stat_XHelp();
    break;

#ifdef SDEBUG
  case 'v': Save_XHelp();
    break;
#endif

  case 'd': Data_XHelp();
    break;
  case 'e': Expand_XHelp();
    break;
  case 'i': IT_XHelp();
    break;
  case 't':Test_XHelp();
    break;
  case 'o': One_XHelp();
    break;
  case 's':Step_XHelp();
    break;
  case 'r': Rewrite_XHelp();
    break;
  case 'q':Quit_XHelp();
    break;
  }
}

/*----------------------------------------------------------------*/

/*  StatisticCB
 *  Prints into the Output Window the memory and the CPU time used
 *  by XLOLA
 */
static void StatisticCB(w,client_data,call_data)
     Widget w;
     XtPointer client_data,call_data;
{
  ECstat();
}

/*----------------------------------------------------------------*/

/*  QuitCB
 *  Exits LOLA.
 */
static void QuitCB(w,client_data,call_data)
     Widget w;
     XtPointer client_data,call_data;
{
  XtDestroyApplicationContext(applcontext);
  ECquit();
}


#ifdef SDEBUG


/*----------------------------------------------------------------*/

/*  SaveCB
 *  Draws the behaviour pointed in the current position into the 
 *  Output Window or the Output File.
 */
static void SaveCB(w,client_data,call_data)
     Widget w;
     XtPointer client_data,call_data;
{
  String out_file;
  
  out_file=ReadText(mainwindow,"*textSave");
  ECsave(out_file,PrintStrInOutput);
}

#endif


/*----------------------------------------------------------------*/

/*  MoveCursorToSpecCB
 *  Moves the internal cursor of LOLA to the SpecificationC cell.
 */
static void MoveCursorToSpecCB(w,client_data,call_data)
     Widget w;
     XtPointer client_data,call_data;
{
  CleanWindow(Selection);
  (void)MoveRoot();
  CleanEventQueue(maincomp,"*tospec");
  if (cursorState == SHOW_PROC_NAMES){
    if (StepWorking){
      BlockByProcWhileStep(FALSE);
      BlockWidget(stepwindow,"*start",FALSE);
      BlockStep(FALSE);
      if (dataCreated)
        BlockWidget(valwindow,"*conf",FALSE);
    }
    else{
      BlockByProcList(FALSE);
      BlockStep(TRUE);
    }
  }
  ActualizeCursor();
}

/*----------------------------------------------------------------*/

/*  MoveCursorToRootCB
 *  Moves the internal cursor of LOLA to the root of the current process.
 */
static void MoveCursorToRootCB(w,client_data,call_data)
     Widget w;
     XtPointer client_data,call_data;
{
  if (cursorState != SHOW_PROC_NAMES){
    CleanWindow(Selection);
    MoveDProc(Current_Process());
    CleanEventQueue(maincomp,"*toroot");
    ActualizeCursor();
  }
}

/*----------------------------------------------------------------*/

/*  DisplaysProcessNamesCB
 *  Prints  a list with the process definition heads in the Cursor window.
 */
static void DisplaysProcessNamesCB(w,client_data,call_data)
     Widget w;
     XtPointer client_data,call_data;
{
  int i;
  StrBckTyp buffer;
  Arg argu[1];
  
  cursorState = SHOW_PROC_NAMES;
  XtSetArg(argu[0],XtNlabel,LABEL2);
  XtSetValues(XtNameToWidget(mainwindow,"*curslab"),argu,1);
  CleanWindow(Selection);
  buffer = CreateStrBck();
  for (i=1 ; i<=LastTableP() ; i++ ) 
    PrintHeadProcess(i,buffer);
  FreeStrBck(buffer);
  CleanEventQueue(maincomp,"*toproc");
  if (StepWorking){
    BlockByProcWhileStep(TRUE);
    BlockStep(TRUE);
    BlockWidget(stepwindow,"*start",TRUE);
    if (dataCreated)
      BlockWidget(valwindow,"*conf",TRUE);
  }
  else
    BlockByProcList(TRUE);
}

/*----------------------------------------------------------------*/

/*  PrintStateCB
 *  Stores the state (on/off) of a Toggle widget, which implements a
 *  command option, into a position of PrintChoice array.
 */
static void PrintStateCB(w,client_data,call_data)
     Widget w;
     XtPointer client_data,call_data;
{
  PrintChoice[(int)client_data]=GetState(w);
}

/*----------------------------------------------------------------*/

/*  ExpStateCB
 *  Like PrintStateCB but into a position of ExpChoice array.
 */
static void ExpStateCB(w,client_data,call_data)
     Widget w;
     XtPointer client_data,call_data;
{
  ExpChoice[(int)client_data]=GetState(w);
}

/*----------------------------------------------------------------*/

/*  InterStateCB
 *  Like PrintStateCB but into a position of InterChoice array.
 */
static void InterStateCB(w,client_data,call_data)
     Widget w;
     XtPointer client_data,call_data;
{
  InterChoice[(int)client_data]=GetState(w);
}

/*----------------------------------------------------------------*/

/*  TestStateCB
 *  Like PrintStateCB but into a position of TestChoice array.
 */
static void TestStateCB(w,client_data,call_data)
     Widget w;
     XtPointer client_data,call_data;
{
  TestChoice[(int)client_data]=GetState(w);
}

/*----------------------------------------------------------------*/

/*  OneStateCB
 *  Like PrintStateCB but into a position of OneChoice array.
 */
static void OneStateCB(w,client_data,call_data)
     Widget w;
     XtPointer client_data,call_data;
{
  OneChoice[(int)client_data]=GetState(w);
}

/*----------------------------------------------------------------*/

/*  ReadDataStepStartCB
 *  Reads the data entered by the user in the Transition Data Window
 *  after the Start button was pressed and before showing the transitions
 *  offered in the first state of the simulation
 */
static void ReadDataStepStartCB(w,client_data,call_data)
     Widget w;
     XtPointer client_data,call_data;
{
  /* DUDAS: - Cuando se libera la memoria de children.
   */
  
  Widget parent;
  WidgetList children;
  int numchil,j;
  char *content;
  ListTyp strexprList;
  Arg argu[2];
  
  parent=(Widget)client_data;
  XtSetArg(argu[0],XtNchildren,&children);
  XtSetArg(argu[1],XtNnumChildren,&numchil);
  XtGetValues(parent,argu,2);
  
  strexprList = Create_list();
  
  children++;
  for (j = 1 ; j <= numchil/2 ; j++) {
    XtSetArg(argu[0],XtNstring,&content);
    XtGetValues(*children,argu,1);
    strexprList = Add_list(CleanDataString(content),strexprList);
    children += 2;
  }

  svTableStep = CreateSV();
  if (ParseValues(strexprList)) {
    DestroyDataWindow();
    StartCB_cont();
  }
  FreeSV(&svTableStep);
  Free_list(strexprList,free);
}

/*----------------------------------------------------------------*/

/*  ReadDataStepBranchCB
 *  Reads the data entered by the user in the Transition Data Window
 *  corresponding to the selected transition 
 */
static void ReadDataStepBranchCB(w,client_data,call_data)
     Widget w;
     XtPointer client_data,call_data;
{
  /* DUDAS: - Cuando se libera la memoria de children.
   */

  Widget parent;
  WidgetList children;
  int numchil,j;
  char *content;
  ListTyp strexprList;
  Arg argu[2];
  
  parent=(Widget)client_data;
  XtSetArg(argu[0],XtNchildren,&children);
  XtSetArg(argu[1],XtNnumChildren,&numchil);
  XtGetValues(parent,argu,2);
  
  strexprList = Create_list();
  
  children++;
  for (j = 1 ; j <= numchil/2 ; j++) {
    XtSetArg(argu[0],XtNstring,&content);
    XtGetValues(*children,argu,1);
    strexprList = Add_list(CleanDataString(content),strexprList);
    children += 2;
  }
  
  svTableStep = CreateSV();
  if (ParseValues(strexprList)) {
    DestroyDataWindow();
    ECstep_branch_exec(optStep,svTableStep);
    ActualizeMenu();
  }
  FreeSV(&svTableStep);
  Free_list(strexprList,free);
}


/*----------------------------------------------------------------*/

/*  ShowWindowCB
 *  Shows into the screen the window associated to the w widget. 
 */
static void ShowWindowCB(w,client_data,call_data)
     Widget w;
     XtPointer call_data,client_data;
{
  XtPopup((Widget)client_data,XtGrabNone);
  BlockByOpenedWindows(TRUE);
  if (w == XtNameToWidget(maincomp,"*step"))
    BlockStep(TRUE);
  AWindowOpened=TRUE;
}


/*----------------------------------------------------------------*/

/*  HideWindowCB
 *  Removes of the screen the window associated to the w widget.
 */
static void HideWindowCB(w,client_data,call_data)
     Widget w;
     XtPointer call_data,client_data;
{
  XtPopdown((Widget)client_data);
  if (cursorState == SHOW_BEHAVIOUR){
    AWindowOpened=FALSE;
    BlockByOpenedWindows(FALSE);
  }
  else{
    AWindowOpened=TRUE;
    BlockByProcList(FALSE);
    BlockByProcWhileStep(TRUE);
    AWindowOpened=FALSE;
  }
}


/*----------------------------------------------------------------*/

/*  HideRewriteCB
 *  Removes of the screen the Rewrite window.
 */
static void HideRewriteCB(w,client_data,call_data)
     Widget w;
     XtPointer call_data,client_data;
{
  XtPopdown((Widget)client_data);
  BlockWidget(maincomp,"*rewr",FALSE);
}

/*----------------------------------------------------------------*/

/*  CleanRewriteCB
 *  Cleans the buffer of the AsciiText widget into Rewrite window 
 */
static void CleanRewriteCB(w,client_data,call_data)
     Widget w;
     XtPointer client_data,call_data;
{
  Arg argu[1];
  
  XtSetArg(argu[0],XtNstring,"");
  XtSetValues((Widget)client_data,argu,1);
}

/*----------------------------------------------------------------*/

/*  CleanOutputCB
 *  Cleans the buffer of the AsciiText widget named Output Window
 */
static void CleanOutputCB(w,client_data,call_data)
     Widget w;
     XtPointer client_data,call_data;
{
  CleanWindow(output);
}

/******************************************************************
 *
 *             AUXILIARY FUNCTIONS OF CALLBACKS        
 *
 *****************************************************************/

/*  CreateDataWindow
 *  This function creates a window to read values.
 *  These values are requested in the simulation mode when the start
 *  buttom is pressed or a transition is selected.
 *  This function is used in both cases.
 *  "who" is 1 when this function is called because the "start" buttom 
 *  was pressed.
 *  "who" is 2 when this function is called because a transition has
 *  been selected.
 */
static void CreateDataWindow(varlist,who)
     ListTyp varlist;
     int who;
{
  Widget ext,valview,valcomp,vert,conf;
  Arg argu[20];
  int n;

  LASSERT( (who == 1)  || (who == 2) );

  if ((dataCreated == FALSE) && (varlist != NULL)){
    XtSetArg(argu[0],XtNlabel,LABEL3);
    XtSetValues(XtNameToWidget(mainwindow,"*curslab"),argu,1);
    
    n=0;
    valwindow=CreateWindow("valores","Transition Data",mainwindow,argu,n);
    ext=CreateForm("valext",valwindow,(Arg *)NULL,0);
    
    n=0;
       SetWidgetInForm(argu,&n,(Widget)NULL,(Widget)NULL,DD,DD);
       SetChain(argu,&n,CHLEFT,CHRIGHT,CHTOP,CHBOTTOM);
       XtSetArg(argu[n],XtNwidth,(Dimension)(40*WidthChar+10));   n++;
       XtSetArg(argu[n],XtNheight,100);                           n++;
       XtSetArg(argu[n],XtNallowVert,TRUE);                       n++;
       XtSetArg(argu[n],XtNallowHoriz,TRUE);                      n++;
    valview=XtCreateManagedWidget("view",viewportWidgetClass,ext,argu,n);

    valcomp=CreateForm("valcomp",valview,(Arg *)NULL,0);

    n=0;
       SetWidgetInForm(argu,&n,(Widget)NULL,valview,DD,DD);
       SetChain(argu,&n,CHLEFT,CHLEFT,CHBOTTOM,CHBOTTOM);
    conf=CreateComm("conf","Done",ext,argu,n);

    vert=(Widget)NULL;

    while (varlist != NULL){
      n=0;
         SetWidgetInForm(argu,&n,(Widget)NULL,vert,DD,10);
         SetChain(argu,&n,CHLEFT,CHLEFT,CHTOP,CHTOP);
      vert=CreateLabel("label",
                       SPrintV((DescriptorTyp)LookInfo_list(varlist),TRUE),
                       valcomp,argu,n);
      n=0;
         SetWidgetInForm(argu,&n,(Widget)NULL,vert,DD,DD);
         SetChain(argu,&n,CHLEFT,CHRIGHT,CHTOP,CHTOP); 
         XtSetArg(argu[n],XtNwidth,(Dimension)(40*WidthChar));          n++;
         XtSetArg(argu[n],XtNheight,(Dimension)(3*HeightChar));         n++;
         XtSetArg(argu[n],XtNscrollVertical,XawtextScrollWhenNeeded);   n++;
         XtSetArg(argu[n],XtNwrap,XawtextWrapLine);                     n++;
         XtSetArg(argu[n],XtNtype,XawAsciiString);                      n++;
         XtSetArg(argu[n],XtNeditType,XawtextEdit);                     n++;
      vert=CreateAsctext("text",valcomp,argu,n);
      varlist = Next_list(varlist);
    }
    XtPopup(valwindow,XtGrabNone);
          if (who == 2)
            XtAddCallback(conf,XtNcallback,ReadDataStepBranchCB,(XtPointer)valcomp);
          else
            XtAddCallback(conf,XtNcallback,ReadDataStepStartCB,(XtPointer)valcomp);
    dataCreated=TRUE;
  }
}


/*----------------------------------------------------------------*/

/*  DestroyDataWindow
 *  Destroys the Transition Data Window.
 */
static void DestroyDataWindow()
{
  if (dataCreated)
    {
      XtDestroyWidget(XtNameToWidget(mainwindow,"*valores"));
      dataCreated=FALSE;
    }
}

/*----------------------------------------------------------------*/

/*  ParseValues
 *  Transforms the strings in "strexprList" in expressions.
 *  These expressions and the variables stored in "varListStep" are 
 *  saved in the global table "svTableStep".
 *  If there is any error  in "strexprList" then the table "svTableStep"
 *  is not filled and FALSE is returned.
 */
static boolean ParseValues(strexprList)
     ListTyp strexprList;
{
  ListTyp sel,vl;
  DescriptorTyp nv;
  char *prompt, *str;
  ExprTyp expr;
  boolean res;
  
  LASSERT(svTableStep==NULL);
  LASSERT(Length_list(varListStep)==Length_list(strexprList));
  res = TRUE;
  for (vl = varListStep , sel = strexprList ;
       vl != NULL ;
       vl = Next_list(vl) , sel = Next_list(sel) ) {
    nv = (DescriptorTyp)LookInfo_list(vl);
    str = SPrintV(nv,TRUE);
    prompt = (char*)emalloc(7+strlen(str));
    (void)sprintf(prompt,"   %s = ",str);
    (void)free(str);
    PrintInWidget(output,prompt);
    free(prompt);
    str = (char*)LookInfo_list(sel);
    PrintInWidget(output,str);
    PrintInWidget(output,"\n");
    if (str[0]!='\0') {
      if (StringToExpr(str,&expr,GetV_sort(nv))) {
        if (res)  
          InsertSV(nv,Rewrite(expr),&svTableStep);
      }
      else 
        res = FALSE;
    }
  }
  return res;
}

/*----------------------------------------------------------------*/

/*  PrintInWidget
 *  Prints a string in the specified widget.
 */
static void PrintInWidget(w,message)
     String message;
     Widget w;
{
  Arg argu[1];
  XawTextBlock text;
  XawTextPosition start;
  
  XtSetArg(argu[0],XtNeditType,XawtextAppend);
  XtSetValues(w,argu,1);
  start=XawTextGetInsertionPoint(w);
  
  text.firstPos=0;
  text.length=strlen(message);
  text.ptr=message;
  text.format=FMT8BIT;
  
  XawTextReplace(w,start,start+strlen(message),&text);
  XawTextSetInsertionPoint(w,start+strlen(message));
  XtSetArg(argu[0],XtNeditType,XawtextRead);
  XtSetValues(w,argu,1);
  return;
}   

/*----------------------------------------------------------------*/

/*  CleanWindow
 *  Cleans the buffer of an AsciiText Widget of read type.
 */
static void CleanWindow(w)
     Widget w;
{
  Arg argu[2];
  
  XtSetArg(argu[0],XtNeditType,XawtextEdit);
  XtSetArg(argu[1],XtNstring,"");
  XtSetValues(w,argu,2);
  XtSetArg(argu[0],XtNeditType,XawtextRead);
  XtSetValues(w,argu,1);
} 

/*----------------------------------------------------------------*/

/*  GotoFirstLine
 *  Moves the insertion point to the first line of the especified window.
 */
static void GotoFirstLine(w)
     Widget w;
{
  XawTextSetInsertionPoint(w,(XawTextPosition)0);
  XtCallActionProc(w,"redraw-display",NULL,NULL,0);
  return;
}

/*----------------------------------------------------------------*/

/*  ActualizeCursor
 *  Calculates the pairs <line,movement> and redisplay the current
 *  behaviour in the Cursor window.
 */
static void ActualizeCursor()
{
  Arg argu[1];
  int cdepth;
  
  CleanWindow(Selection);
  XtSetArg(argu[0],XtNlabel,LABEL1);
  XtSetValues(XtNameToWidget(maincomp,"*curslab"),argu,1);
  cursorState = SHOW_BEHAVIOUR;
  cdepth=ReadNum(maincomp,"*depthcursor",0);
  if (cdepth != BADINTEGER){
    if (GetCursor()!=NULL)
      PrintMoves(PrintStrInCursor,GetCursor(),cdepth,FALSE);
    GotoFirstLine(Selection);
  }
  else
    PrintStrInOutput("\n\n WARNING: Depth of Selection Window no correct. \n\n");
}

/*----------------------------------------------------------------*/

/*  ActualizeMenu
 *  Displays the current menu of transitions (STEP mode) in the Cursor window.
 */
static void ActualizeMenu()
{
  Arg argu[1];
  
  CleanWindow(Selection);
  XtSetArg(argu[0],XtNlabel,LABEL3);
  XtSetValues(XtNameToWidget(mainwindow,"*curslab"),argu,1);
  cursorState=TRANSITIONS;
  ECstep_menu();
  GotoFirstLine(Selection);
}

/*----------------------------------------------------------------*/

/*  ActualizeRefused
 *  Displays the menu of unsuccessful synchronizations (STEP mode) in 
 *  the Cursor window.
 */
static void ActualizeRefused()
{
  Arg argu[1];
  
  CleanWindow(Selection);
  XtSetArg(argu[0],XtNlabel,LABEL4);
  XtSetValues(XtNameToWidget(mainwindow,"*curslab"),argu,1);
  cursorState=REFUSED;
  ECstep_refused();
  GotoFirstLine(Selection);
}

/*----------------------------------------------------------------*/

/*  PrintHeadProcess
 *  Auxiliar function used by DisplaysProcessNamesCB to list all the
 *  process definitions.
 */
static void PrintHeadProcess(i,buffer)
     DescriptorTyp i;
     StrBckTyp buffer;
{
  char *aux;
  GateListTyp  gl;
  ExprListTyp  el;
  
  CleanStrBck(buffer);
  buffer = ConcatStrBck(buffer,"process ");
  buffer = ConcatStrBck(buffer,GetP_name(i));
  
  if ( gl=(GateListTyp)LookAInfo(LookA(GetP_def(i),GLA)) ) {
    buffer = ConcatStrBck(buffer," [");
    buffer = ConcatStrBck(buffer,aux=SPrintGL(gl));
    (void)free(aux);
    buffer = ConcatStrBck(buffer,"]");
  }
  
  if ( el=(ExprListTyp)LookAInfo(LookA(GetP_def(i),ELA))) {
    buffer = ConcatStrBck(buffer," (");
    buffer = ConcatStrBck(buffer,aux=SPrintVL(el));
    (void)free(aux);
    buffer = ConcatStrBck(buffer,")");
  }
  
  buffer = ConcatStrBck(buffer," : ");
  buffer = ConcatStrBck(buffer,aux=SPrint_Func(GetP_func(i)));
  (void)free(aux);
  if (i!=LastTableP())
    buffer = ConcatStrBck(buffer,"\n");
  PrintStrInCursor(LookStrStrBck(buffer));
}

/*----------------------------------------------------------------*/

/*  ReadText
 *  Reads the data entered by the user into an AsciiText widget
 */
static String ReadText(parent,name)
     Widget parent;
     String name;
{
  Arg argu[1];
  String aux;
  Widget textw;
  
  textw=XtNameToWidget(parent,name);
  XtSetArg(argu[0],XtNstring,&aux);
  XtGetValues(textw,argu,1);
  return CleanDataString(aux);
}

/*----------------------------------------------------------------*/

/*  ReadNum
 *  Reads the integer number entered by the user into an AsciiText widget
 *  labelled like "depth" or "seed"
 */
static int ReadNum(parent,name,defval)
     Widget parent;
     String name;
     int defval;
{
  Arg argu[1];
  String aux,dirt;
  Widget textw;
  int num,items;
  
  aux=ReadText(parent,name);
  if (aux[0]!='\0'){
    textw=XtNameToWidget(parent,name);
    items=sscanf(aux,"%d%s",&num,&dirt);
    if (items==1)
      return num;
    else 
      if (items > 1 || items == EOF || aux[1]=='-'){
        XtSetArg(argu[0],XtNstring,"");
        XtSetValues(textw,argu,1);
        XtCallActionProc(textw,"no-op",NULL,NULL,0);
        return BADINTEGER;
      }
      else
        return defval;
  }
  else
    return defval;
}

/*----------------------------------------------------------------*/

/*  CleanDataString
 *  Removes the newline characters which were introduced by the widget.
 */
static String CleanDataString(data)
     String data;
{
  char* str;
  int i;
  Boolean empty;
  
  empty=TRUE;
  str = (char*)emalloc(strlen(data));
  i=0;
  for (i=0 ; *data != '\0' ; i++,data++) 
    str[i] = *data == '\n' ? ' ' : *data;
  str[i]='\0';
  for (i=0 ; str[i]!= '\0' && empty ; i++)
    empty=str[i]==' ';
  if (empty)
    return "\0";
  else
    return str;
}

/*----------------------------------------------------------------*/

/*  StartCB_cont
 *  Initializes a step by step simulation showing the transition menu
 *  into the Selection Window corresponding to the first state
 */
static void StartCB_cont()
{
  BehTyp b,b_test;
  
  b = ECstep_start_Behaviour(&svTableStep);
  
  b_test = ECstep_start_ComposeWithTest( b, sedSCB, procSCB );
  if (b_test != NULL) {
    ECstep_start_Expan(b_test);
    ECstep_menu();
    ActualizeMenu();
  }
  BlockStep(FALSE);
  StepWorking=TRUE;
}

/*----------------------------------------------------------------*/

/*  GetOptionNumber
 *  Returns the option number selected by the user in the Selection window
 *  when it shows  the menu of transitions (or unsuccessful synchronizations)
 *  offered at the current state of the simulation
 */
static long GetOptionNumber(w,pos)
     Widget w;
     XawTextPosition pos;
{
  XawTextBlock corch,newl,text;
  XawTextPosition start,end,boline,eoline;
  long nopt;
  char *aux;
  int i;
  
  newl.firstPos=0;
  newl.length=1;
  newl.format=FMT8BIT;
  newl.ptr="\n";
  corch=newl;
  corch.ptr="[";
  
  do{  /* do */
    boline=XawTextSourceSearch(w,pos,XawsdLeft,&newl);
    if (boline == XawTextSearchError)
      boline=0;
    if (boline == pos)
      if ((pos-1)>=0){
        pos=pos-1;
        boline=XawTextSearchError;
      }
  }while(boline==XawTextSearchError); /* do */
  eoline=XawTextSourceSearch(w,pos,XawsdRight,&newl);
  start=XawTextSourceSearch(w,boline,XawsdRight,&corch);
  if (start != XawTextSearchError){  /* if start */
    corch.firstPos=0;
    corch.length=1;
    corch.format=FMT8BIT;
    corch.ptr="]";
    end=XawTextSourceSearch(w,start,XawsdRight,&corch);
    if (end != XawTextSearchError){  /* if end */
      if ((eoline != XawTextSearchError) 
          && ((start > eoline) || (end > eoline)))
        return 0;
      eoline=end+1;
      /*      (void)printf("encontrados start y end\n");*/
      XawTextSourceRead(w,eoline,&text,(XawTextPosition)15);
      if (strchr(text.ptr,'-') == NULL){     /* if strchr */
        XawTextSourceRead(w,start+1,&text,end-start-(XawTextPosition)1);
        /*      (void)printf("if del guion leo entre corchetes\n");*/
        if (sscanf(text.ptr,"%d",&nopt) <= 0)
          return 0;
        else
          return nopt;
      }      /* if strchr */
      else{    /* else strchr */
        aux=text.ptr;
        while (*aux == ' ')
          ++aux;
        if (*aux != '-'){
          XawTextSourceRead(w,start+1,&text,end-start-(XawTextPosition)1);
          /*        (void)printf("else del guion leo entre corchetes\n");*/
          if (sscanf(text.ptr,"%d",&nopt) <= 0)
            return 0;
          else
            return nopt;
        }
        else {
          for (i=0 ; i <= (strlen(text.ptr)-1); i++)
            text.ptr[i]='\000';
          return 0;
        }  
      } /* else strchr */
    } /* if end */
    else return 0;
  }  /* if start */
  else return 0;
}

/*----------------------------------------------------------------*/

/*  GetState
 *  Returns the state (on/off) of a Toggle widget
 */
static Boolean GetState(w)
     Widget w;
{
  Arg argu[1];
  Boolean aux;
  
  XtSetArg(argu[0],XtNstate,&aux);
  XtGetValues(w,argu,1);
  return aux;
}

/*----------------------------------------------------------------*/

/*  SetOptions
 *  Reads an array with the state of the command options invoked by 
 *  the user and returns the options activated into the out array
 *  and his number
 */
static int SetOptions(states,options,nopt,out)
     Boolean states[];
     char *options;
     int nopt;
     char *out;
{
  int i,j;
  
  j=0;
  for (i=0; i<=nopt-1; i++) {
    if (states[i]) {
      out[j]=options[i];
      j++;
    }
  }
  out[j]='\0';
  return j;  
}

/*----------------------------------------------------------------*/

/*  CleanEventQueue
 *  Cleans the queue of the events happened while the program is executing
 *  a command
 */
static void CleanEventQueue(parent,name)
     Widget parent;
     char *name;
{
  XEvent event;
  Widget aux;
  
  aux=XtNameToWidget(parent,name);
  while (XtAppPending(applcontext))
    {
      XtAppNextEvent(applcontext,&event);
      if ((event.xcrossing.window==XtWindow(aux)) && (event.type == LeaveNotify))
        XtDispatchEvent(&event);
    }
  return;
}

/*----------------------------------------------------------------*/

/*  SetTranslations
 *  Assigns a translation table to a widget
 */
static void SetTranslations(w,transltable)
     Widget w;
     String transltable;
{
  XtTranslations Table;
  
  Table=XtParseTranslationTable(transltable);
  XtOverrideTranslations(w,Table);
  return;
}

/******************************************************************
 *
 *    FUNCTIONS TO BLOCK WIDGETS WHILE SOME COMMANDS ARE WORKING
 *
 *****************************************************************/


/*  BlockWidget
 *  This function actualizes the sensitive resource of a widget 
 *  with the "block" value. The widget is referenced with his parent and
 *  his name
 */
static void BlockWidget(parent,name,block)
     Widget parent;
     char *name;
     Boolean block;
{ 
  XtSetSensitive(XtNameToWidget(parent,name),!block);
  return;
} 

/*----------------------------------------------------------------*/

/*  BlockByOpenedWindows
 *  Manages the access to the expansion, testing and step windows,
 *  blocking or unblocking theese buttons in the main window.
 */
static void BlockByOpenedWindows(block)
     Boolean block;
{
  BlockWidget(maincomp,"*expansion",block);
  BlockWidget(maincomp,"*testing",  block);
  BlockWidget(maincomp,"*step",     block);
  return;
}

/*----------------------------------------------------------------*/

/*  BlockByProcList
 *  Controls the sensibility state of certains buttons when it press
 *  the "Proc List" button
 */
static void BlockByProcList(block)
     Boolean block;
{
  if (AWindowOpened){
    BlockWidget(expandcomp,"*expand",block);
    BlockWidget(expandcomp,"*inter", block);
    BlockWidget(testcomp,"*test",    block);
    BlockWidget(testcomp,"*one",     block);
    BlockWidget(stepwindow,"*start", block);
    BlockStep(block);
  }
  else 
    BlockByOpenedWindows(block);
  if (dataCreated)
    BlockWidget(valwindow,"*conf",block);
  BlockByProcWhileStep(block);
  return;
}

/*----------------------------------------------------------------*/

/*  BlockByProcWhileStep
 *  Like BlockByProcList but when the step-by-step simulation is working
 */
static void BlockByProcWhileStep(block)
     Boolean block;
{
  BlockWidget(maincomp,"*print", block);
  BlockWidget(maincomp,"*toroot",block);
  BlockWidget(maincomp,"*toproc",block);
  return;
}

/*----------------------------------------------------------------*/

/*  BlockStep
 *  Manages the sensitive resources of Step Window buttons
 */
static void BlockStep(block)
     Boolean block;
{
  BlockWidget(stepwindow,"*menu",       block);
  BlockWidget(stepwindow,"*steprefused",block);
  BlockWidget(stepwindow,"*undo",       block);
  BlockWidget(stepwindow,"*trace",      block);
  return;
}

/*----------------------------------------------------------------*/

/*  BlockStepData
 *  Manages the data input in the AsciiText widgets of Step Window
 */
static void BlockStepData(block)
     Boolean block;
{
  BlockWidget(stepwindow,"*succlabstep", block);
  BlockWidget(stepwindow,"*succtextstep",block);
  BlockWidget(stepwindow,"*testlabstep", block);
  BlockWidget(stepwindow,"*testtextstep",block);
  return;
}

/******************************************************************
 *
 *      Miscellaneous functions to manage the Output window.
 *
 *****************************************************************/

/*  PrintStrInOutput
 *  Prints a string in the Output window.
 */
void PrintStrInOutput(s)
     char *s;
{
  PrintInWidget(output,s);
}

/*----------------------------------------------------------------*/

/*  PrintStrInOutputFlush
 *  Flushes a string in the Output window.
 */
void PrintStrInOutputFlush(s)
     char *s;
{
  PrintInWidget(output,s);
  XFlush(XtDisplay(output));
}

/*----------------------------------------------------------------*/

/*  FlushOutput
 *  Flushes the output window.
 */
void FlushOutput()
{
  XFlush(XtDisplay(output));
}


/*----------------------------------------------------------------*/

/*  ReplaceStrInOutput
 *  Allows to rewrite in real time a text line in the Output window.
 *  The function take two arguments: str is the string to print and
 *  pos which indicates the position where it must begins to print.
 *  Depending on the pos value the function works in three ways:
 *
 *  - pos = -1, inserts str on the current position of the insertion point
 *  - pos < -1, searchs the insertion point and it writes str on the beginning
 *    of the line which contains it.
 *  - pos >=0, prints str starting from the pos position. The position is 
 *    expressed in characters from the beginning of the buffer. The first character
 *    fills the zero position.
 */
XawTextPosition ReplaceStrInOutput(str,pos)
     char *str;
     XawTextPosition pos;
{
  Widget src;
  XawTextPosition firstchar,lastchar;
  XawTextBlock aux;
  Arg argu[1];
  
  if (pos<0){
    firstchar = XawTextGetInsertionPoint(output);
    if (pos < -1){
      src = XawTextGetSource(output);
      aux.firstPos = 0;
      aux.ptr      = "\n";
      aux.length   = 1;
      aux.format   = FMT8BIT;
      if ((firstchar = XawTextSourceSearch(src,firstchar,XawsdLeft,&aux)) 
                  == XawTextSearchError) {
                firstchar = 0;
      }
      else {
                firstchar += 1;
      }
    }
  }
  else 
    firstchar = pos;
  XtSetArg(argu[0],XtNeditType,XawtextEdit);
  XtSetValues(output,argu,1);
  
  aux.firstPos = 0;
  aux.ptr      = str;
  aux.length   = strlen(str);
  aux.format   = FMT8BIT;
  
  lastchar = firstchar+strlen(str);
  XawTextReplace(output,firstchar,lastchar,&aux);
  XawTextSetInsertionPoint(output,lastchar);
  XtSetArg(argu[0],XtNeditType,XawtextRead);
  XtSetValues(output,argu,1);
  return lastchar;
}

/******************************************************************
 *
 *  Miscellaneous functions to manage the Selection window.
 *
 *****************************************************************/

/* PrintStrInCursor
 *  Prints a string in the Selection window.
 */
void PrintStrInCursor(s)
     char *s;
{
  PrintInWidget(Selection,s);
}


/******************************************************************
 *
 *                      MAIN FUNCTION
 *
 *****************************************************************/

/*  XwindowsInt
 *  It calls every functions to create and initialize the interface
 */
void XwindowsInt(argc,argv,nspec,nlibr)
     int argc;
     char **argv;
     char nspec[],nlibr[];
{
  Widget load,print,quit,expansion,testing,rewrite,step,
         help,expand,inter,test,one;

  CreateWindows(&argc,argv,&applcontext,&mainwindow,&expandwindow,
                &testwindow,&rewrwindow,&stepwindow);
  CreateMainWindow(mainwindow,&load,&print,&quit,&expansion,&testing,
                   &rewrite,&step,&help,nspec,nlibr,&Selection,&output);  
  CreateExpandWindow(expandwindow,&expand,&inter);
  CreateTestingWindow(testwindow,&test,&one);
  CreateRewriteWindow(rewrwindow);
  CreateStepWindow(stepwindow,argv);
  HelpOptions(help);

  dataCreated=FALSE;
  AWindowOpened=FALSE;
  StepWorking=FALSE;

  XtRealizeWidget(mainwindow);
  ActualizeCursor();
  XtAppMainLoop(applcontext);
}

#endif /*XLOLA*/



