// ----------------------------------------------------------------------------
//
// Copyright (C) Columbia University, 1994. All Rights Reserved.
// Sameer A. Nene, Shree K. Nayar, Hiroshi Murase
//
// See file LICENSE for details of software license agreement.
//
// ----------------------------------------------------------------------------
//
// xmanifoldcb.C
//
// Author:               Sameer Nene
// Date:                 09/12/94
// Version:              1.0.0
// Modification History:
//   10/26/94: (Post Release) Fixed bug which produced incorrect sampling
//             frequency and number of output projections after resampling.
//   04/10/96: Fixed scoping problem to work with new ANSI C++ definition.
//
// Notes:
//   X module for visualization/manipulation of manifolds/projections
//   
// ----------------------------------------------------------------------------

#define NO_XMSTRINGS

#include "errorscope.h"
#include "fileiter.h"
#include "handle.h"
#include "ioutil.h"
#include "list.h"
#include "vector.h"
#include "dataset.h"
#include "interpolation.h"
#include "persinterp.h"
#include "bsplinecurve.h"
#include "bsplinesurface.h"
#include "bsplinevolume.h"
#include "postscript.h"
#include "xreporter.h"
#include "ndataset.h"
#include "ninterpolation.h"
#include "xmanifold.h"
#include <ctype.h>
#include <strstream.h>
#include <math.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <X11/PEX5/PEXlib.h>
#include <Xm/FileSB.h>
#include <Xm/LabelG.h>
#include <Xm/List.h>
#include <Xm/MessageB.h>
#include <Xm/PushBG.h>
#include <Xm/TextF.h>

extern void objectSearchProc(Widget w, XtPointer p1, XtPointer);
extern void fillList(Widget listbox, const List<NamedDataSet* > &list);
extern void fillList(Widget listbox, const List<NamedInterpolation* > &list);
extern void addList(List<NamedDataSet* > *list, const NamedDataSet &ds);
extern void addList(List<NamedInterpolation* > *list,
		    const NamedInterpolation &ip);
extern void fillListWithVisible(Widget listbox);
extern void fillListWithInvisible(Widget listbox);
extern void fitToExtents();
extern void err_dlg(Widget parent, const char *s);
extern Widget create_load_dialog(Widget w);
extern Widget create_save_dialog(Widget w);
extern Widget create_project_dialog(Widget w);
extern Widget create_interpolate_dialog(Widget w);
extern Widget create_sample_dialog(Widget w);
extern void create_pref_dialog(Widget w);
extern void create_print_dialog(Widget w);
extern void create_view_dialog(Widget w);
extern void create_extent_dialog(Widget w);
extern Widget create_ortho_dialog(Widget w);
extern void createLabels(const PEXStructure &sid);
extern void redraw();
extern void get_path(XmFileSelectionBoxCallbackStruct *p1, char **dir,
		     char **name);
extern void sample(const Interpolation *ip, Vector &v, DataSetIter &it,
		   int level);
extern void setViewingParam(NamedInterpolation *nip);
extern void desenseMenu();
extern void sensitizeMenu();

#define GSO__ACCURACY .000001

void pulldown_cb(Widget w, XtPointer, XtPointer)
{
  XtPopdown(XtParent(XtParent(w)));
}

void pulldownSense_cb(Widget w, XtPointer, XtPointer)
{
  sensitizeMenu();
  XtPopdown(XtParent(XtParent(w)));
}

void pulldown3_cb(Widget w, XtPointer, XtPointer)
{
  sensitizeMenu();
  XtPopdown(XtParent(XtParent(XtParent(w))));
}

void destroy_cb(Widget w, XtPointer, XtPointer)
{
  sensitizeMenu();
  XtDestroyWidget(XtParent(XtParent(w)));
}

void destroy3_cb(Widget w, XtPointer, XtPointer)
{
  sensitizeMenu();
  XtDestroyWidget(XtParent(XtParent(XtParent(w))));
}

void new_toggled_cb(Widget w, XtPointer p1, XtPointer)
{
  RadioBoxLocal *data;
  XmString str1;
  WidgetList wlist;

  XtVaGetValues(XtParent(w), XmNuserData, &data, NULL);
  data -> d_sel = int(p1);
  switch(int(p1)) {
  case 0:
    XtSetSensitive(data -> d_type2, True);
    str1 = XmStringCreateSimple("*.prj");
    XtVaSetValues(data -> d_fileSelBox,
		  XmNpattern, str1,
		  NULL);
    XmStringFree(str1);
    break;
  case 1:
    XtSetSensitive(data -> d_type2, False);
    XtVaGetValues(data -> d_type1, XmNchildren, &wlist, NULL);
    str1 = XmStringCreateSimple("SLAM Binary");
    XtVaSetValues(wlist[1], XmNlabelString, str1, NULL);
    XmStringFree(str1);
    str1 = XmStringCreateSimple("*.sp?");
    XtVaSetValues(data -> d_fileSelBox,
		  XmNpattern, str1,
		  NULL);
    XmStringFree(str1);
  }
}

void load_toggled_cb(Widget w, XtPointer p1, XtPointer)
{
  RadioBoxLocal *data;

  XtVaGetValues(XtParent(w), XmNuserData, &data, NULL);
  data -> d_sel = int(p1);
}

void save_toggled_cb(Widget w, XtPointer p1, XtPointer)
{
  RadioBoxLocal *data;
  XmString str1;
  WidgetList wlist;

  XtVaGetValues(XtParent(w), XmNuserData, &data, NULL);
  data -> d_sel = int(p1);
  XtVaSetValues(XtParent(w), XmNuserData, data, NULL);
  switch(int(p1)) {
  case 0:
    XtSetSensitive(data -> d_toggleb, True);
    XtSetSensitive(data -> d_type2, True);
    str1 = XmStringCreateSimple("*.prj");
    XtVaSetValues(data -> d_fileSelBox, XmNpattern, str1, NULL);
    XmStringFree(str1);
    fillList(data -> d_list, Global::d_proj);
    break;
  case 1:
    XtSetSensitive(data -> d_toggleb, False);
    XtSetSensitive(data -> d_type2, False);
    XtVaGetValues(data -> d_type1, XmNchildren, &wlist, NULL);
    str1 = XmStringCreateSimple("SLAM Binary");
    XtVaSetValues(wlist[1], XmNlabelString, str1, NULL);
    XmStringFree(str1);
    str1 = XmStringCreateSimple("*.sp?");
    XtVaSetValues(data -> d_fileSelBox, XmNpattern, str1, NULL);
    XmStringFree(str1);
    fillList(data -> d_list, Global::d_manifold);
  }
}

void printBoxToggle_cb(Widget, XtPointer p1, XtPointer)
{
  PrintBoxLocal *data = (PrintBoxLocal*)p1;
  switch(data -> d_bpressed) {
  case False:
    data -> d_bpressed = True;
    XtSetSensitive(data -> d_text1, False);
    XtSetSensitive(data -> d_text2, True);
    break;
  case True:
    data -> d_bpressed = False;
    XtSetSensitive(data -> d_text1, True);
    XtSetSensitive(data -> d_text2, False);
  };
}

void labelToggle_cb(Widget, XtPointer, XtPointer)
{
  ExposeCbLocal *data;
  XtVaGetValues(Global::d_darea, XmNuserData, &data, NULL);
  data -> d_viewLabels = data -> d_viewLabels == True ? False : True;
  redraw();
}

void resize_cb(Widget w, XtPointer, XtPointer)
{
  int width, height;
  
  if(Global::d_pexavail == True) {
    XtVaGetValues(w, XmNwidth, &width, XmNheight, &height, NULL);
    XResizeWindow(Global::d_display, Global::d_drawin, width, height);
    redraw();
  }
}

void loadbox_ok_cb(Widget w, XtPointer p3, XtPointer p1)
{
  char *p2, *dir, *name, errmessg[256];
  ostrstream ostr(errmessg, 256);
  ErrorScope::Error error;
  NamedDataSet *ds;
  Interpolation *ip;
  NamedInterpolation *nip;
  RadioBoxLocal *data;
  Widget rbox = (Widget)p3;

  get_path((XmFileSelectionBoxCallbackStruct *)p1, &dir, &name);
  XtVaGetValues(rbox, XmNuserData, &data, NULL);
  
  switch(data -> d_sel) {
  case 0:
    {
      XReporter::showWaitCursor(Global::d_topshell);
      XReporter::showWaitCursor(Global::d_loadbox);
      
      ds = new NamedDataSet();
      strcat(strcpy(p2 = new char[strlen(dir) + strlen(name) + 1], dir), name);
      if((error = data -> d_typesel ? ds -> getText(p2) : IOUtil::get(ds, p2)) != ErrorScope::OK) {
	ostr << error << ": " << p2;
	err_dlg(w, errmessg);
	delete[] p2;
	delete ds;
	delete[] dir;
	delete[] name;
	XReporter::showNormalCursor(Global::d_topshell);
	XReporter::showNormalCursor(Global::d_loadbox);
	break;
      }

      ds -> rename(name);
      addList(&Global::d_proj, *ds);
      if(Global::d_pexavail == True) {
	ds -> constructPEXStruct();
	fitToExtents();
	redraw();
      }
      
      delete[] p2;
      delete[] dir;
      delete[] name;

      XReporter::showNormalCursor(Global::d_topshell);
      XReporter::showNormalCursor(Global::d_loadbox);
    }
    break;
  case 1:
    {
      XReporter::showWaitCursor(Global::d_topshell);
      XReporter::showWaitCursor(Global::d_loadbox);
      
      Handle h;
      nip = new NamedInterpolation();
      strcat(strcpy(p2 = new char[strlen(dir) + strlen(name) + 1], dir), name);
      if((error = IOUtil::get(&h, p2)) != ErrorScope::OK) {
	ostr << error << ": " << p2;
	err_dlg(w, errmessg);
	delete[] p2;
	delete nip;
	delete[] dir;
	delete[] name;
	XReporter::showNormalCursor(Global::d_topshell);
	XReporter::showNormalCursor(Global::d_loadbox);
	break;
      }

      if((ip = PersistentInterpolation::safeCast(h())) == 0) {
	ostr << ErrorScope::INCORRECT_FORMAT << ": " << p2;
	err_dlg(w, errmessg);
	delete[] p2;
	delete nip;
	delete[] dir;
	delete[] name;
	XReporter::showNormalCursor(Global::d_topshell);
	XReporter::showNormalCursor(Global::d_loadbox);
	break;
      }

      nip -> interpolation(ip);
      h.set(0);
      nip -> rename(name);
      addList(&Global::d_manifold, *nip);
      if(Global::d_pexavail == True) {
	setViewingParam(nip);
	nip -> constructPEXStruct();
	fitToExtents();
	redraw();
      }
      
      delete[] p2;
      delete[] dir;
      delete[] name;

      XReporter::showNormalCursor(Global::d_topshell);
      XReporter::showNormalCursor(Global::d_loadbox);
    }
    break;
  }
}

void savebox_ok_cb(Widget w, XtPointer p4, XtPointer p1)
{
  Boolean set;
  char *dir, *name, *p2, *p3, errmessg[256];
  ostrstream ostr(errmessg, 256);
  ErrorScope::Error error;
  int i, j, *pos_list = 0, pos_cnt;
  RadioBoxLocal *data;
  XmString *names;
  Widget rbox = (Widget)p4;

  get_path((XmFileSelectionBoxCallbackStruct *)p1, &dir, &name);
  for(p2 = name; isspace(*p2); ++p2);
  if(*p2 == '\0') {
    err_dlg(w, "Please select Filename");
    delete[] dir;
    delete[] name;
    return;
  }
  
  XtVaGetValues(rbox, XmNuserData, &data, NULL);
  strcat(strcpy(p2 = new char[strlen(dir) + strlen(name) + 1], dir), name);
  XmListGetSelectedPos(data -> d_list, &pos_list, &pos_cnt);
  XtVaGetValues(data -> d_list, XmNitems, &names, NULL);
  
  switch(data -> d_sel) {
  case 0:
    {
      XReporter::showWaitCursor(Global::d_topshell);
      XReporter::showWaitCursor(Global::d_savebox);
      
      XtVaGetValues(data -> d_toggleb, XmNset, &set, NULL);
      if(set == False) {
	for(ListIter<NamedDataSet* > it(Global::d_proj); it; ++it) {
	  XmStringGetLtoR(names[pos_list[0] - 1], XmSTRING_DEFAULT_CHARSET, &p3);
	  if(strcmp(it() -> dataName(), p3) == 0) {
	    if((error = data -> d_typesel ? it() -> putText(p2) : IOUtil::put(*(it()), p2)) != ErrorScope::OK) {
	      ostr << error << ": " << p2;
	      err_dlg(w, errmessg);
	      XtFree(p3);
	      break;
	    }
	  }
	  XtFree(p3);
	}
      }
      else {
	List<VectAry* > t;
	for(i = 0, j = 0; i < pos_cnt; ++i) {
	  XmStringGetLtoR(names[pos_list[i] - 1], XmSTRING_DEFAULT_CHARSET, &p3);
	  for(ListIter<NamedDataSet* > it(Global::d_proj); it; ++it)
	    if(strcmp(it() -> dataName(), p3) == 0) {
	      t += &((*(it()))());
	      j += ((*(it()))()).getSize();
	    }
	  XtFree(p3);
	}
	DataSet ds(1, j);
	ds.setSize(0, j);
	DataSetIter dsit(ds);
	for(ListIter<VectAry* > it(t); it; ++it)
	  for(VectAryIter it2(*(it())); it2; ++it2, ++dsit)
	    dsit() = it2();
	if((error = data -> d_typesel ? ds.putText(p2) : IOUtil::put(ds, p2)) != ErrorScope::OK) {
	  ostr << error << ": " << p2;
	  err_dlg(w, errmessg);
	}
      }
      
      XReporter::showNormalCursor(Global::d_topshell);
      XReporter::showNormalCursor(Global::d_savebox);	
    }
    break;
  case 1:
    {
      XReporter::showNormalCursor(Global::d_topshell);
      XReporter::showNormalCursor(Global::d_savebox);	
      
      for(ListIter<NamedInterpolation* > it(Global::d_manifold); it; ++it) {
	XmStringGetLtoR(names[pos_list[0] - 1], XmSTRING_DEFAULT_CHARSET, &p3);
	if(strcmp(it() -> dataName(), p3) == 0) {
	  if((error = IOUtil::put(*(PersistentInterpolation::safeCast(it() -> interpolation())), p2)) != ErrorScope::OK) {
	    ostr << error << ": " << p2;
	    err_dlg(w, errmessg);
	    XtFree(p3);
	    break;
	  }
	}
	XtFree(p3);
      }

      XReporter::showNormalCursor(Global::d_topshell);
      XReporter::showNormalCursor(Global::d_savebox);	
    }
  }
  XtFree((char *)pos_list);
  delete[] p2;
  delete[] dir;
  delete[] name;
}

void printbox_ok_cb(Widget w, XtPointer p1, XtPointer)
{
  char errmessg[256], *p2, *p3;
  ostrstream ostr(errmessg, 256);
  ErrorScope::Error error;
  int i, float_format = PEXGetProtocolFloatFormat(Global::d_display);
  ExposeCbLocal *data;
  PrintBoxLocal *data2 = (PrintBoxLocal*)p1;
  PEXStructureInfo info;
  FILE *file;
  
  XtVaGetValues(Global::d_darea, XmNuserData, &data, NULL);

  if(data2 -> d_bpressed == True) {
    if((file = fopen(p2 = XmTextFieldGetString(data2 -> d_text2), "w")) == NULL) {
      ostr << ErrorScope::FILE_OPEN_ERROR << ": " << p2;
      err_dlg(XtParent(w), errmessg);
      XtFree(p2);
      return;
    }
    XtFree(p2);
  }
  else
    if((file = fopen("/tmp/spool.ps", "w")) == NULL) {
      ostr << ErrorScope::FILE_OPEN_ERROR;
      err_dlg(XtParent(w), errmessg);
      return;
    }
  
  PEXtoPSstream psout(file, 8.5, 11., data -> d_min, data -> d_max);
  psout.setView(data -> d_view);

  if((error = psout.writeHeader()) != ErrorScope::OK) {
    ostr << error;
    err_dlg(XtParent(w), errmessg);
    fclose(file);
    return;
  }
  
  PEXGetStructureInfo(Global::d_display, data -> axisSid, float_format,
		      PEXNumElements, &info);
  for(i = 1; i <= info.element_count; ++i)
    if((error = psout.render(Global::d_display, data -> axisSid, i)) != ErrorScope::OK) {
      ostr << error;
      err_dlg(XtParent(w), errmessg);
      fclose(file);
      return;
    }
  if(data -> d_viewLabels == True) {
    PEXGetStructureInfo(Global::d_display, data -> labelsSid, float_format,
			PEXNumElements, &info);
    for(i = 1; i <= info.element_count; ++i)
      if((error = psout.render(Global::d_display, data -> labelsSid, i)) != ErrorScope::OK) {
	ostr << error;
	err_dlg(XtParent(w), errmessg);
	fclose(file);
	return;
      }
  }
  for(ListIter<NamedDataSet* > it1(Global::d_proj); it1; ++it1)
    if(it1() -> getVisibility() == NamedDataSet::VISIBLE) {
      PEXGetStructureInfo(Global::d_display, it1() -> getPEXStruct(),
			  float_format, PEXNumElements, &info);
      for(i = 1; i <= info.element_count; ++i)
	if((error = psout.render(Global::d_display, it1() -> getPEXStruct(), i)) != ErrorScope::OK) {
	  ostr << error;
	  err_dlg(XtParent(w), errmessg);
	  fclose(file);
	  return;
	} 
    }
  for(ListIter<NamedInterpolation* > it2(Global::d_manifold); it2; ++it2)
    if(it2() -> getVisibility() == NamedInterpolation::VISIBLE) {
      PEXGetStructureInfo(Global::d_display, it2() -> getPEXStruct(),
			  float_format, PEXNumElements, &info);
      for(i = 1; i <= info.element_count; ++i)
	if((error = psout.render(Global::d_display, it2() -> getPEXStruct(), i)) != ErrorScope::OK) {
	  ostr << error;
	  err_dlg(XtParent(w), errmessg);
	  fclose(file);
	  return;
	} 
    }
  if((error = psout.showPage()) != ErrorScope::OK) {
    ostr << error;
    err_dlg(XtParent(w), errmessg);
    fclose(file);
    return;
  } 

  if(fclose(file) != 0) {
    ostr << ErrorScope::FILE_CLOSE_ERROR;
    err_dlg(XtParent(w), errmessg);
    return;
  }

  if(data2 -> d_bpressed == False) {
    p2 = XmTextFieldGetString(data2 -> d_text1);
    strcat(strcat(strcpy(p3 = new char[256], "lpr -P"), p2), " /tmp/spool.ps");
    XtFree(p2);
    if(system(p3) == -1) {
      err_dlg(XtParent(w), "Unable to find lpr or spooling error");
      delete[] p3;
      return;
    }
    delete[] p3;
    if(unlink("/tmp/spool.ps") != 0) {
      err_dlg(XtParent(w), "Unable to delete spool file");
      return;
    }
  }

  sensitizeMenu();
  XtPopdown(Global::d_printBox);
}

void orthobox_ok_cb(Widget w, XtPointer, XtPointer)
{
  char *p2, errmessg[256];
  ostrstream ostr(errmessg, 256);
  ErrorScope::Error error;
  int i, j, k, l, m, n, o, p;
  double e;

  if(Global::d_dir == 0 || Global::d_name == 0) {
    err_dlg(XtParent(w), "Please select Filename for the orthogonal Eigenvector");
    return;
  }

  for(i = 0, j = 2, k = 0; i < j; ++i) {
    if(Global::d_va_p == 0) {
      err_dlg(XtParent(w), "Please select Eigenvectors to Orthogonalize");
      return;
    }
    k += Global::d_va_p[i] -> getSize();
  }

  XReporter::showWindow(Global::d_orthobox, "Orthogonalizing",
			XReporter::INTERRUPTIBLE);
  XReporter::showWaitCursor(Global::d_topshell);

  VectAry a(k), q(k);

  for(i = 0, n = 0; i < j; ++i) {
    if(XReporter::display_status() == XReporter::BUTTONPRESSED) {
      XReporter::destroyWindow();
      XReporter::showNormalCursor(Global::d_topshell);	
      return;
    }
    for(l = 0, m = Global::d_va_p[i] -> getSize(); l < m; ++l, ++n) {
      a[n] = (*(Global::d_va_p[i]))[l];
      for(o = 0, q[n].length(p = a[n].length()); o < p; ++o)
	q[n].element(o, 0);
    }
  }

  for(i = 0; i < k; ++i) {
    if(XReporter::display_status() == XReporter::BUTTONPRESSED) {
      XReporter::destroyWindow();
      XReporter::showNormalCursor(Global::d_topshell);	
      return;
    }
    Vector &t = a[i];
    e = 0.;
    do {
      for(j = 0; j < i; ++j)
	t -= q[j] * (q[j] * t);
      for(m = 0; m < i; ++m)
	if(fabs(e = t * q[m]) > GSO__ACCURACY)
	  break;
    }
    while(fabs(e) > GSO__ACCURACY);
    q[i] = t / t();
  }

  if(XReporter::display_status("Saving Eigenvector") == XReporter::BUTTONPRESSED) {
    XReporter::destroyWindow();
    XReporter::showNormalCursor(Global::d_topshell);	
    return;
  }

  strcat(strcpy(p2 = new char[strlen(Global::d_dir) + strlen(Global::d_name) + 1], Global::d_dir), Global::d_name);
  if((error = Global::d_ftype ? q.putText(p2) : IOUtil::put(q, p2)) != ErrorScope::OK) {
    ostr << error << ": " << p2;
    err_dlg(w, errmessg);
    delete[] p2;
    XReporter::destroyWindow();
    XReporter::showNormalCursor(Global::d_topshell);
    return;
  }
  
  XReporter::destroyWindow();
  XReporter::showNormalCursor(Global::d_topshell);
  
  sensitizeMenu();
  XtDestroyWidget(XtParent(XtParent(XtParent(w))));
}

void fmenu_cb(Widget, XtPointer p1, XtPointer)
{
  RadioBoxLocal *data;
  
  desenseMenu();
  switch(int(p1)) {
  case 0:
    XtPopup(Global::d_loadbox, XtGrabNone);
    break;
  case 1:
    data = Global::d_sbdata;
    if(data -> d_sel == 0)
      fillList(data -> d_list, Global::d_proj);
    else
      fillList(data -> d_list, Global::d_manifold);
    XtPopup(Global::d_savebox, XtGrabNone);
    break;
  case 2:
    XtPopup(Global::d_printBox, XtGrabNone);
    break;
  case 3:
    exit(0);
  }
}

void selnomatch_cb(Widget w, XtPointer, XtPointer)
{
  err_dlg(w, "Selection not found");
}

void project_cb(Widget w, XtPointer p1, XtPointer p2)
{
  Boolean useAvg;
  int i, n;
  char *buf, *p, errmessg[256];
  ostrstream ostr(errmessg, 256);
  ErrorScope::Error error;
  Vector v;
  NamedDataSet *ds;
  ProjectCbLocal *data = (ProjectCbLocal *)p1;

  if(Global::d_fl == 0) {
    err_dlg(w, "Vector Set not selected. Cannot Project");
    return;
  }

  if(Global::d_va_p[0] == 0) {
    err_dlg(w, "Eigenvectors not selected. Cannot Project");
    return;
  }
  
  buf = XmTextFieldGetString(data -> d_numVectorText);
  Global::d_numeigen = atoi(buf);
  XtFree(buf);

  if(Global::d_numeigen <= 0 || Global::d_numeigen > Global::d_va_p[0] -> getSize()) {
    err_dlg(w, "Invalid number of Eigenvectors");
    return;
  }

  XtVaGetValues(data -> d_useAvgBtn, XmNset, &useAvg, NULL);
  if(useAvg == True)
    if(Global::d_avg == 0) {
      err_dlg(w, "Average Vector not selected. Cannot Project");
      return;
    }

  Vector v2(Global::d_numeigen);

  XmStringGetLtoR(((XmSelectionBoxCallbackStruct *)p2) -> value,
		  XmSTRING_DEFAULT_CHARSET, &buf);
  for(p = buf; isspace(*p); ++p);
  if(*p == '\0') {
    err_dlg(w, "Please assign Projection Name");
    XtFree(buf);
    return;
  }
  
  ds = new NamedDataSet(buf, n = Global::d_fl -> getNumParam(),
			Global::d_fl -> getSize());
  for(i = 0; i < n; ++i)
    ds -> setSize(i, Global::d_fl -> getSize(i));

  XReporter::showWindow(Global::d_projbox, "Projecting Vectors",
			XReporter::INTERRUPTIBLE);
  XReporter::showWaitCursor(Global::d_topshell);	
  
  DataSetIter dsit(*ds);
  for(FileListIter it(*Global::d_fl); it; ++it, ++dsit) {
    if(XReporter::display_status() == XReporter::BUTTONPRESSED) {
      XReporter::destroyWindow();
      XReporter::showNormalCursor(Global::d_topshell);	
      return;
    }
    
    if((error = Global::d_typesel ? v.getText(it()) : IOUtil::get(&v, it())) != ErrorScope::OK) {
      ostr << error << ": " << it();
      XReporter::destroyWindow();
      XReporter::showNormalCursor(Global::d_topshell);	
      err_dlg(w, errmessg);
      delete ds;
      XtFree(buf);
      return;
    }

    if(useAvg == True)
      v -= *Global::d_avg;
    
    i = 0;
    for(VectAryIter it(*Global::d_va_p[0]); i < Global::d_numeigen; ++it, ++i)
      v2.element(i, v * it());
    dsit() = v2;
  }

  XReporter::destroyWindow();
  XReporter::showNormalCursor(Global::d_topshell);	

  addList(&Global::d_proj, *ds);
  if(Global::d_pexavail == True) {
    ds -> constructPEXStruct();
    fitToExtents();
    redraw();
  }

  XtFree(buf);
  sensitizeMenu();
  XtDestroyWidget(XtParent(XtParent(w)));
}

void arrow_down_cb(Widget, XtPointer p1, XtPointer)
{
  char *buf, buf2[256];
  int n;
  ProjectCbLocal *data = (ProjectCbLocal *)p1;
  if((n = atoi(buf = XmTextFieldGetString(data -> d_numVectorText))) > 0) {
    sprintf(buf2, "%d", n - 1);
    XmTextFieldSetString(data -> d_numVectorText, buf2);
  }
  XtFree(buf);
}

void arrow_up_cb(Widget, XtPointer p1, XtPointer)
{
  char *buf, buf2[256];
  ProjectCbLocal *data = (ProjectCbLocal *)p1;
  buf = XmTextFieldGetString(data -> d_numVectorText);
  sprintf(buf2, "%d", atoi(buf) + 1);
  XtFree(buf);
  XmTextFieldSetString(data -> d_numVectorText, buf2);
}

void listsel_cb(Widget, XtPointer p1, XtPointer p2)
{
  char *buf;

  XmStringGetLtoR(((XmListCallbackStruct *)p2) -> item,
		  XmSTRING_DEFAULT_CHARSET, &buf);
  XmTextFieldSetString(Widget(p1), buf);
  XtFree(buf);
}

void listselLabelSense_cb(Widget, XtPointer p1, XtPointer p2)
{
  char *buf;
  int i, j;
  FitManifoldCbLocal *data = (FitManifoldCbLocal*)p1;

  XmStringGetLtoR(((XmListCallbackStruct *)p2) -> item,
		  XmSTRING_DEFAULT_CHARSET, &buf);
  for(ListIter<NamedInterpolation* > it(Global::d_manifold); it; ++it)
    if(strcmp(it() -> dataName(), buf) == 0) {
      for(i = 0, j = it() -> interpolation() -> dimension(); i < 3; ++i)
	XtSetSensitive(data -> d_text[i], i < j ? True : False);
      break;
    }
  XmTextFieldSetString(data -> d_text2, buf);
  XtFree(buf);
}

void fitmfold_cb(Widget w, XtPointer p1, XtPointer)
{
  char *p4, *p2;
  NamedInterpolation *ip;
  FitManifoldCbLocal *data = (FitManifoldCbLocal *)p1;

  p4 = XmTextFieldGetString(data -> d_text1);
  for(p2 = p4; isspace(*p2); ++p2);
  if(*p2 == '\0') {
    err_dlg(XtParent(w), "Please supply Projection Name");
    XtFree(p4);
    return;
  }

  ListIter<NamedDataSet* > it(Global::d_proj);
  for(; it; ++it)
    if(strcmp(p4, it() -> dataName()) == 0)
      break;
  XtFree(p4);

  p4 = XmTextFieldGetString(data -> d_text2);
  for(p2 = p4; isspace(*p2); ++p2);
  if(*p2 == '\0') {
    err_dlg(XtParent(w), "Please supply Manifold Name");
    XtFree(p4);
    return;
  }

  XReporter::showWaitCursor(Global::d_topshell);
  XReporter::showWaitCursor(Global::d_fitbox);	
  
  switch(it() -> getSize()) {
  case 1:
    {
      BSplineCurve *spl = new BSplineCurve(it() -> getSize(0));
      spl -> fit((*(it()))());
      ip = new NamedInterpolation(p4, spl);
      addList(&Global::d_manifold, *ip);
      if(Global::d_pexavail == True) {
	setViewingParam(ip);
	ip -> constructPEXStruct();
	fitToExtents();
	redraw();
      }
      fillList(data -> d_list, Global::d_manifold);
    }
    break;
  case 2:
    {
      BSplineSurface *spl = new BSplineSurface(it() -> getSize(0), it() -> getSize(1));
      spl -> fit((*(it()))());
      ip = new NamedInterpolation(p4, spl);
      addList(&Global::d_manifold, *ip);
      if(Global::d_pexavail == True) {
	setViewingParam(ip);
	ip -> constructPEXStruct();
	fitToExtents();
	redraw();
      }
      fillList(data -> d_list, Global::d_manifold);
    }
    break;
  case 3:
    {
      BSplineVolume *spl = new BSplineVolume(it() -> getSize(0), it() -> getSize(1), it() -> getSize(2));
      spl -> fit((*(it()))());
      ip = new NamedInterpolation(p4, spl);
      addList(&Global::d_manifold, *ip);
      if(Global::d_pexavail == True) {
	setViewingParam(ip);
	ip -> constructPEXStruct();
	fitToExtents();
	redraw();
      }
      fillList(data -> d_list, Global::d_manifold);
    }
    break;
  default:
    err_dlg(XtParent(w), "Only 3 dimensional manifolds supported");
  }
  XtFree(p4);

  XReporter::showNormalCursor(Global::d_topshell);
  XReporter::showNormalCursor(Global::d_fitbox);	
}

void sample_cb(Widget w, XtPointer p1, XtPointer)
{
  int i, j, k;
  char *p2, *p4;
  NamedDataSet *ds;
  FitManifoldCbLocal *data = (FitManifoldCbLocal *)p1;

  p4 = XmTextFieldGetString(data -> d_text2);
  for(p2 = p4; isspace(*p2); ++p2);
  if(*p2 == '\0') {
    err_dlg(XtParent(w), "Please supply Manifold Name");
    XtFree(p4);
    return;
  }
  ListIter<NamedInterpolation* > it(Global::d_manifold);
  for(; it; ++it)
    if(strcmp(p4, it() -> dataName()) == 0)
      break;
  XtFree(p4);
  
  for(i = 0, j = it() -> interpolation() -> dimension(), k = 1; i < j; ++i) {
    p4 = XmTextFieldGetString(data -> d_text[i]);
    Global::d_sfreq[i] = atoi(p4);
    XtFree(p4);
    if(Global::d_sfreq[i] < 2) {
      err_dlg(XtParent(w), "Invalid Sampling Frequency");
      return;
    }
    k *= Global::d_sfreq[i] + 1;
  }

  p4 = XmTextFieldGetString(data -> d_text1);
  for(p2 = p4; isspace(*p2); ++p2);
  if(*p2 == '\0') {
    err_dlg(XtParent(w), "Please supply Projection Name");
    XtFree(p4);
    return;
  }

  XReporter::showWaitCursor(Global::d_topshell);
  XReporter::showWaitCursor(Global::d_samplebox);	
  
  ds = new NamedDataSet(p4, j, k);
  DataSetIter it2(*ds);
  for(i = 0; i < j; ++i)
    ds -> setSize(i, Global::d_sfreq[i] + 1);

  Vector v(j);
  sample(it() -> interpolation(), v, it2, 0);

  addList(&Global::d_proj, *ds);
  if(Global::d_pexavail == True) {
    ds -> constructPEXStruct();
    fitToExtents();
    redraw();
  }
  fillList(data -> d_list, Global::d_proj);
  
  XtFree(p4);

  XReporter::showNormalCursor(Global::d_topshell);
  XReporter::showNormalCursor(Global::d_samplebox);	
}

void smenu_cb(Widget w, XtPointer p1, XtPointer)
{
  desenseMenu();
  switch(int(p1)) {
  case 0:
    create_view_dialog(XtParent(w));
    break;
  case 1:
    create_pref_dialog(XtParent(w));
    break;
  case 2:
    create_extent_dialog(XtParent(w));
  }
}

void omenu_cb(Widget w, XtPointer p1, XtPointer)
{
  desenseMenu();
  switch(int(p1)) {
  case 0:
    Global::d_projbox = create_project_dialog(Global::d_topshell);
    break;
  case 1:
    Global::d_fitbox = create_interpolate_dialog(XtParent(w));
    break;
  case 2:
    Global::d_samplebox = create_sample_dialog(XtParent(w));
    break;
  case 3:
    Global::d_orthobox = create_ortho_dialog(XtParent(w));
  }
}

void hmenu_cb(Widget w, XtPointer, XtPointer)
{
  XmString mesg = XmStringCreateLtoR("Copyright \xA9 Columbia University, 1994. All Rights Reserved.\nSameer Nene, Shree Nayar, Hiroshi Murase", XmSTRING_DEFAULT_CHARSET);
  Widget dlg;

  dlg = XmCreateInformationDialog(XtParent(w), "About", NULL, 0);
  XtVaSetValues(dlg,
		XmNmessageString, mesg,
		XmNdialogStyle, XmDIALOG_PRIMARY_APPLICATION_MODAL,
		NULL);
  XtUnmanageChild(XmMessageBoxGetChild(dlg, XmDIALOG_CANCEL_BUTTON));
  XtUnmanageChild(XmMessageBoxGetChild(dlg, XmDIALOG_HELP_BUTTON));

  XmStringFree(mesg);
  XtManageChild(dlg);
}

void typeoptionB_cb(Widget, XtPointer p1, XtPointer)
{
  *((int *)p1) = 0;
}

void typeoptionT_cb(Widget, XtPointer p1, XtPointer)
{
  *((int *)p1) = 1;
}

void showAllProj_cb(Widget, XtPointer p1, XtPointer)
{
  ListSelCbLocal *data = (ListSelCbLocal *)p1;
  for(ListIter<NamedDataSet* > it(Global::d_proj); it; ++it)
    it() -> makeVisible();
  fillListWithVisible(data -> d_viList);
  fillListWithInvisible(data -> d_hdList);
  redraw();
}

void hideAllProj_cb(Widget, XtPointer p1, XtPointer)
{
  ListSelCbLocal *data = (ListSelCbLocal *)p1;
  for(ListIter<NamedDataSet* > it(Global::d_proj); it; ++it)
    it() -> makeInvisible();
  fillListWithVisible(data -> d_viList);
  fillListWithInvisible(data -> d_hdList);
  redraw();
}

void showAllMfold_cb(Widget, XtPointer p1, XtPointer)
{
  ListSelCbLocal *data = (ListSelCbLocal *)p1;
  for(ListIter<NamedInterpolation* > it(Global::d_manifold); it; ++it)
    it() -> makeVisible();
  fillListWithVisible(data -> d_viList);
  fillListWithInvisible(data -> d_hdList);
  redraw();
}

void hideAllMfold_cb(Widget, XtPointer p1, XtPointer)
{
  ListSelCbLocal *data = (ListSelCbLocal *)p1;
  for(ListIter<NamedInterpolation* > it(Global::d_manifold); it; ++it)
    it() -> makeInvisible();
  fillListWithVisible(data -> d_viList);
  fillListWithInvisible(data -> d_hdList);
  redraw();
}

void showListSel_cb(Widget w, XtPointer p1, XtPointer p2)
{
  char *p3;
  XmListCallbackStruct *cbs = (XmListCallbackStruct *)p2;

  XmStringGetLtoR(cbs -> item, XmSTRING_DEFAULT_CHARSET, &p3);

  for(ListIter<NamedDataSet* > it1(Global::d_proj); it1; ++it1)
    if(strcmp(it1() -> dataName(), p3) == 0) {
      it1() -> makeInvisible();
      XtFree(p3);
      fillListWithVisible(w);
      fillListWithInvisible(Widget(p1));
      redraw();
      return;
    }
  
  for(ListIter<NamedInterpolation* > it2(Global::d_manifold); it2; ++it2)
    if(strcmp(it2() -> dataName(), p3) == 0) {
      it2() -> makeInvisible();
      XtFree(p3);
      fillListWithVisible(w);
      fillListWithInvisible(Widget(p1));
      redraw();
      return;
    }

  XtFree(p3);
}

void hideListSel_cb(Widget w, XtPointer p1, XtPointer p2)
{
  char *p3;
  XmListCallbackStruct *cbs = (XmListCallbackStruct *)p2;

  XmStringGetLtoR(cbs -> item, XmSTRING_DEFAULT_CHARSET, &p3);
  
  for(ListIter<NamedDataSet* > it1(Global::d_proj); it1; ++it1)
    if(strcmp(it1() -> dataName(), p3) == 0) {
      it1() -> makeVisible();
      XtFree(p3);
      fillListWithInvisible(w);
      fillListWithVisible(Widget(p1));
      redraw();
      return;
    }
  
  for(ListIter<NamedInterpolation* > it2(Global::d_manifold); it2; ++it2)
    if(strcmp(it2() -> dataName(), p3) == 0) {
      it2() -> makeVisible();
      XtFree(p3);
      fillListWithInvisible(w);
      fillListWithVisible(Widget(p1));
      redraw();
      return;
    }

  XtFree(p3);
}

void par1MenuSel_cb(Widget w, XtPointer p1, XtPointer)
{
  PrefCbLocal *data;
  XtVaGetValues(XtParent(w), XmNuserData, &data, NULL);
  data -> d_dmap[0] = int(p1);
}

void par2MenuSel_cb(Widget w, XtPointer p1, XtPointer)
{
  PrefCbLocal *data;
  XtVaGetValues(XtParent(w), XmNuserData, &data, NULL);
  data -> d_dmap[1] = int(p1);
}

void parNMenuSel_cb(Widget w, XtPointer p1, XtPointer)
{
  PrefCbLocal *data;
  char *p2, buf[256];
  
  XtVaGetValues(XtParent(w), XmNuserData, &data, NULL);
  data -> d_param.element(data -> d_prevValue, atof(p2 = XmTextFieldGetString(data -> d_paramText[2])));
  XtFree(p2);
  sprintf(buf, "%lf", data -> d_param.element(data -> d_prevValue = int(p1)));
  XmTextFieldSetString(data -> d_paramText[2], buf);
}

void prefListSel_cb(Widget, XtPointer p1, XtPointer p2)
{
  int i, j, k, sfreq[2];
  Cardinal num;
  char *p3, buf[256];
  XmString str1;
  Widget button;
  WidgetList wlist;
  Arg args[10];
  XmListCallbackStruct *cbs = (XmListCallbackStruct *)p2;
  PrefCbLocal *data = (PrefCbLocal*)p1;
  NamedInterpolation *nip;
  static XtCallbackProc cbfuncs[3] = {par1MenuSel_cb, par2MenuSel_cb,
				      parNMenuSel_cb};

  XmStringGetLtoR(cbs -> item, XmSTRING_DEFAULT_CHARSET, &p3);

  for(ListIter<NamedInterpolation* > it2(Global::d_manifold); it2; ++it2)
    if(strcmp(it2() -> dataName(), p3) == 0) {
      data -> d_nip = nip = it2();
      nip -> getSamplingFreq(&sfreq[0], &sfreq[1]);
      nip -> getDimensionMap(&(data -> d_dmap[0]), &(data -> d_dmap[1]));
      data -> d_param = nip -> getSamplingParams();
      data -> d_prevValue = 0;
      XtVaSetValues(data -> d_selLabel, XmNlabelString, cbs -> item, NULL);
      for(i = 0, j = nip -> interpolation() -> dimension(); i < 3; ++i)
	if(i < j) {
	  sprintf(buf, "%u", sfreq[i]);
	  XmTextFieldSetString(data -> d_paramText[i], buf);
	  XtSetSensitive(data -> d_paramText[i], True);
	  XtVaGetValues(data -> d_optionType[i],
			XmNnumChildren, &num,
			XmNchildren, &wlist,
			NULL);
	  for(k = 0; k < num; ++k)
	    XtDestroyWidget(wlist[k]);
	  for(k = 0; k < j; ++k) {
	    sprintf(buf, "%u", k);
	    button = XtVaCreateManagedWidget(buf, xmPushButtonGadgetClass,
					     data -> d_optionType[i], NULL);
	    XtAddCallback(button, XmNactivateCallback, cbfuncs[i], (XtPointer)k);
	  }
	  XtSetSensitive(data -> d_optionMenu[i], True);
	  XtVaGetValues(data -> d_optionMenu[i], XmNchildren, &wlist,NULL);
	  sprintf(buf, "%u", data -> d_dmap[i]);
	  str1 = XmStringCreateSimple(buf);
	  XtVaSetValues(wlist[1], XmNlabelString, str1, NULL);
	  XmStringFree(str1);
	}
	else {
	  XtSetSensitive(data -> d_paramText[i], False);
	  XtSetSensitive(data -> d_optionMenu[i], False);
	}
      if(j > 2) {
	sprintf(buf, "%lf", data -> d_param.element(0));
	XmTextFieldSetString(data -> d_paramText[2], buf);
	XtSetSensitive(data -> d_paramText[2], True);
	XtVaGetValues(data -> d_optionType[2],
		      XmNnumChildren, &num,
		      XmNchildren, &wlist,
		      NULL);
	for(k = 0; k < num; ++k)
	  XtDestroyWidget(wlist[k]);
	for(k = 0; k < j; ++k) {
	  sprintf(buf, "%u", k);
	  XtVaCreateManagedWidget(buf, xmPushButtonGadgetClass,
				  data -> d_optionType[2], NULL);
	}
	XtSetSensitive(data -> d_optionMenu[2], True);
      }
      XtFree(p3);
      return;
    }
  XtFree(p3);
}

void mparChange_cb(Widget w, XtPointer p1, XtPointer)
{
  int i, j, sfreq[2];
  PrefCbLocal *data = (PrefCbLocal*)p1;
  char *p2;

  for(i = 0, j = data -> d_nip -> interpolation() -> dimension(); i < 2; ++i) {
    if(i < j) {
      if((sfreq[i] = atoi(p2 = XmTextFieldGetString(data -> d_paramText[i]))) == 0) {
	err_dlg(XtParent(w), "Error in number of samples");
	XtFree(p2);
	return;
      }
      XtFree(p2);
    }
  }
  
  data -> d_nip -> setSamplingFreq(sfreq[0], sfreq[1]);
  data -> d_nip -> setDimensionMap(data -> d_dmap[0], data -> d_dmap[1]);
  data -> d_nip -> setSamplingParams(data -> d_param);
  data -> d_nip -> constructPEXStruct();
  fitToExtents();
  redraw();
}

void axisChange_cb(Widget, XtPointer p1, XtPointer)
{
  PrefCbLocal *data = (PrefCbLocal*)p1;
  char *p2;
  ExposeCbLocal *data2;
  int i, dim[3];

  for(i = 0; i < 3; ++i) {
    dim[i] = atoi(p2 = XmTextFieldGetString(data -> d_axisText[i]));
    XtFree(p2);
  }

  Global::d_dim1 = dim[0];
  Global::d_dim2 = dim[1];
  Global::d_dim3 = dim[2];

  for(ListIter<NamedDataSet* > it1(Global::d_proj); it1; ++it1)
    it1() -> constructPEXStruct();
  for(ListIter<NamedInterpolation* > it2(Global::d_manifold); it2; ++it2)
    it2() -> constructPEXStruct();
  XtVaGetValues(Global::d_darea, XmNuserData, &data2, NULL);

  fitToExtents();
  redraw();
}

void loadVectorSet_cb(Widget, XtPointer, XtPointer)
{
  XtPopup(Global::d_loadVectorSetBox, XtGrabNone);
}

void loadVector_cb(Widget, XtPointer, XtPointer)
{
  XtPopup(Global::d_loadVectorBox, XtGrabNone);
}

void loadEigenVector_cb(Widget, XtPointer p1, XtPointer)
{
  Global::d_vaindex = int(p1);
  XtPopup(Global::d_loadEigenVectorBox, XtGrabNone);
}

void saveEigenVector_cb(Widget, XtPointer, XtPointer)
{
  XtPopup(Global::d_saveEigenVectorBox, XtGrabNone);
}

void loadVectorSetOk_cb(Widget w, XtPointer p3, XtPointer p1)
{
  char *dir, *name, errmessg[256];
  ostrstream ostr(errmessg, 256);
  ErrorScope::Error error;
  FileList *fl;
  FileListIter *it;

  get_path((XmFileSelectionBoxCallbackStruct *)p1, &dir, &name);

  fl = new FileList(dir, name, "vec");
  if((error = fl -> error()) != ErrorScope::OK) {
    ostr << error;
    err_dlg(w, errmessg);
    delete fl;
    delete[] dir;
    delete[] name;
    return;
  }

  it = new FileListIter(*fl);
  delete Global::d_fl;
  Global::d_fl = fl;
  delete Global::d_flit;
  Global::d_flit = it;
  Global::d_typesel = *((int *)p3);
  
  XmTextFieldSetString(Global::d_label1, name);

  delete[] Global::d_text1;
  strcpy(Global::d_text1 = new char[strlen(name) + 1], name);
  
  delete[] dir;
  delete[] name;

  XtPopdown(Global::d_loadVectorSetBox);
}

void loadVectorOk_cb(Widget w, XtPointer p3, XtPointer p1)
{
  char *p2, *dir, *name, errmessg[256];
  ostrstream ostr(errmessg, 256);
  ErrorScope::Error error;
  Vector *vec;

  get_path((XmFileSelectionBoxCallbackStruct *)p1, &dir, &name);
  
  strcat(strcpy(p2 = new char[strlen(dir) + strlen(name) + 1], dir), name);
  vec = new Vector;
  if((error = *((int *)p3) ? vec -> getText(p2) : IOUtil::get(vec, p2)) != ErrorScope::OK) {
    ostr << error << ": " << p2;
    err_dlg(w, errmessg);
    delete[] p2;
    delete[] dir;
    delete[] name;
    return;
  }
  
  delete Global::d_avg;
  Global::d_avg = vec;
    
  XmTextFieldSetString(Global::d_label2, name);

  delete[] Global::d_text2;
  strcpy(Global::d_text2 = new char[strlen(name) + 1], name);
    
  delete[] p2;
  delete[] dir;
  delete[] name;
  XtPopdown(Global::d_loadVectorBox);
}

void loadEigenVectorOk_cb(Widget w, XtPointer p3, XtPointer p1)
{
  char *p2, *dir, *name, errmessg[256];
  ostrstream ostr(errmessg, 256);
  ErrorScope::Error error;
  VectAry *va;

  XReporter::showWaitCursor(Global::d_topshell);
  XReporter::showWaitCursor(Global::d_loadEigenVectorBox);

  get_path((XmFileSelectionBoxCallbackStruct *)p1, &dir, &name);
  
  va = new VectAry;
  strcat(strcpy(p2 = new char[strlen(dir) + strlen(name) + 1], dir), name);
  if((error = *((int *)p3) ? va -> getText(p2) : IOUtil::get(va, p2)) != ErrorScope::OK) {
    ostr << error << ": " << p2;
    err_dlg(w, errmessg);
    delete[] p2;
    delete va;
    delete[] dir;
    delete[] name;
    XReporter::showNormalCursor(Global::d_topshell);
    XReporter::showNormalCursor(Global::d_loadEigenVectorBox);
    return;
  }
  delete Global::d_va_p[Global::d_vaindex];
  Global::d_va_p[Global::d_vaindex] = va;
    
  XmTextFieldSetString(Global::d_text4[Global::d_vaindex], name);

  delete[] Global::d_text3_p[Global::d_vaindex];
  strcpy(Global::d_text3_p[Global::d_vaindex] = new char[strlen(name) + 1], name);
    
  delete[] p2;
  delete[] dir;
  delete[] name;

  XReporter::showNormalCursor(Global::d_topshell);
  XReporter::showNormalCursor(Global::d_loadEigenVectorBox);
  
  XtPopdown(Global::d_loadEigenVectorBox);
}

void saveEigenVectorOk_cb(Widget, XtPointer p3, XtPointer p1)
{
  delete[] Global::d_dir;
  delete[] Global::d_name;

  get_path((XmFileSelectionBoxCallbackStruct *)p1, &Global::d_dir,
	   &Global::d_name);
  Global::d_ftype = *((int *)p3);

  XmTextFieldSetString(Global::d_text4[2], Global::d_name);

  delete[] Global::d_text3_p[2];
  strcpy(Global::d_text3_p[2] = new char[strlen(Global::d_name) + 1],
	 Global::d_name);

  XtPopdown(Global::d_saveEigenVectorBox);
}

void pref_arrow_down_cb(Widget, XtPointer p1, XtPointer)
{
  char *buf, buf2[256];
  int n;
  if((n = atoi(buf = XmTextFieldGetString(Widget(p1)))) > 0) {
    sprintf(buf2, "%d", n - 1);
    XmTextFieldSetString(Widget(p1), buf2);
  }
  XtFree(buf);
}

void pref_arrow_up_cb(Widget, XtPointer p1, XtPointer)
{
  char *buf, buf2[256];
  buf = XmTextFieldGetString(Widget(p1));
  sprintf(buf2, "%d", atoi(buf) + 1);
  XtFree(buf);
  XmTextFieldSetString(Widget(p1), buf2);
}
