// ----------------------------------------------------------------------------
//
// 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.
//
// ----------------------------------------------------------------------------
//
// ximgtoolcb.C
//
// Author:               Sameer Nene
// Date:                 09/12/94
// Version:              1.0.0
// Modification History:
//
// Notes:
//   X module for visualization/manipulation of images/vector/eigenvectors
//   
// ----------------------------------------------------------------------------

#define NO_XMSTRINGS

#include "errorscope.h"
#include "naming.h"
#include "ioutil.h"
#include "fileiter.h"
#include "vector.h"
#include "image.h"
#include "imageutil.h"
#include "ximgtool.h"
#include "xreporter.h"
#include <ctype.h>
#include <strstream.h>
#include <stdlib.h>
#include <Xm/Xm.h>
#include <Xm/FileSB.h>
#include <Xm/MessageB.h>
#include <Xm/SelectioB.h>
#include <Xm/TextF.h>
#include <Xm/ToggleBG.h>

extern void objectSearchProc(Widget w, XtPointer p1, XtPointer);
extern void err_dlg(Widget parent, const char *s);
extern void adjust_ximage(const Image &img);
extern void adjust_image(const Image &img, Image *current);
extern void adjust_image(const Image &img, Vector *v);
extern void adjust_vector(const Vector &v, Image *img, int xsize, int ysize);
extern void adjust_vector(const Vector &v, Vector *vec, int xsize, int ysize);
extern ErrorScope::Error it_next_image();
extern ErrorScope::Error it_next_vector();
extern void it_next_eigenvector();
void timerStepFront_cb(void *p1, unsigned long*);
void timerStepBack_cb(void *p1, unsigned long*);
				     
void pulldown_cb(Widget w, XtPointer, XtPointer)
{
  XtPopdown(XtParent(XtParent(w)));
}

void tmenu_cb(Widget, XtPointer, XtPointer)
{
}

void typeoption_cb(Widget, XtPointer p1, XtPointer)
{
  if(Global::d_ldsvflg == 0)
    Global::d_ldftype = int(p1);
  else
    Global::d_svftype = int(p1);
}

void toggled_cb(Widget w, XtPointer p1, XtPointer)
{
  XmString str1;
  Widget fileSelBox;
  WidgetList wlist, wlist2;

  if(Global::d_ldsvflg == 0) {
    XtVaGetValues(Global::d_optionType[0], XmNchildren, &wlist, NULL);
    XtVaGetValues(Global::d_optionMenu[0], XmNchildren, &wlist2, NULL);
  }
  else {
    XtVaGetValues(Global::d_optionType[1], XmNchildren, &wlist, NULL);
    XtVaGetValues(Global::d_optionMenu[1], XmNchildren, &wlist2, NULL);
  }

  switch(int(p1)) {
  case 0:
  case 1:
    XtSetSensitive(wlist[0], True);
    XtSetSensitive(wlist[1], False);
    XtSetSensitive(wlist[2], False);
    if(Global::d_ldsvflg == 0)
      Global::d_ldftype = 0;
    else
      Global::d_svftype = 0;
    str1 = XmStringCreateSimple("PGM");
    XtVaSetValues(wlist2[1], XmNlabelString, str1, NULL);
    XmStringFree(str1);
    break;
  case 2:
  case 3:
  case 4:
    XtSetSensitive(wlist[0], False);
    XtSetSensitive(wlist[1], True);
    XtSetSensitive(wlist[2], True);
    if(Global::d_ldsvflg == 0)
      Global::d_ldftype = 1;
    else
      Global::d_svftype = 1;
    str1 = XmStringCreateSimple("SLAM Binary");
    XtVaSetValues(wlist2[1], XmNlabelString, str1, NULL);
    XmStringFree(str1);
    break;
  }

  if(Global::d_ldsvflg == 0) {
    Global::d_ldtstat = int(p1);
    switch(Global::d_ldtstat) {
    case 0:
    case 1:
      XtVaSetValues(Global::d_sizeArea, XmNsensitive, False, NULL);
      XtVaSetValues(Global::d_text1, XmNsensitive, False, NULL);
      XtVaSetValues(Global::d_text2, XmNsensitive, False, NULL);
      break;
    case 2:
    case 3:
    case 4:
      XtVaSetValues(Global::d_sizeArea, XmNsensitive, True, NULL);
      if(Global::d_viewv != 0) {
	XtVaSetValues(Global::d_text1, XmNsensitive, True, NULL);
	XtVaSetValues(Global::d_text2, XmNsensitive, True, NULL);
      }
      else {
	XtVaSetValues(Global::d_text1, XmNsensitive, False, NULL);
	XtVaSetValues(Global::d_text2, XmNsensitive, False, NULL);
      }
    }
  }
  else {
    Global::d_svtstat = int(p1);
    switch(Global::d_ldtstat) {
    case 0:
    case 1:
      XtVaSetValues(Global::d_text3, XmNsensitive, False, NULL);
      XtVaSetValues(Global::d_text4, XmNsensitive, False, NULL);
      break;
    case 2:
    case 3:
      switch(Global::d_svtstat) {
      case 0:
      case 1:
	if(Global::d_viewv == 0) {
	  XtVaSetValues(Global::d_text3, XmNsensitive, True, NULL);
	  XtVaSetValues(Global::d_text4, XmNsensitive, True, NULL);
	  break;
	}
      case 2:
      case 3:
      case 4:
	XtVaSetValues(Global::d_text3, XmNsensitive, False, NULL);
	XtVaSetValues(Global::d_text4, XmNsensitive, False, NULL);
      }
      break;
    case 4:
      XtVaSetValues(Global::d_text3, XmNsensitive, False, NULL);
      XtVaSetValues(Global::d_text4, XmNsensitive, False, NULL);
    }
  }
  
  switch(int(p1)) {
  case 0:
    XtVaGetValues(XtParent(w), XmNuserData, &fileSelBox, NULL);
    XtSetSensitive(XmFileSelectionBoxGetChild(fileSelBox, XmDIALOG_FILTER_TEXT)
		   , True);
    str1 = XmStringCreateSimple("*.pgm");
    XtVaSetValues(fileSelBox,
		  XmNpattern, str1,
		  XmNfileSearchProc, Global::d_defFileSearchProc,
		  NULL);
    XmStringFree(str1);
    break;
  case 1:
    XtVaGetValues(XtParent(w), XmNuserData, &fileSelBox, NULL);
    XtSetSensitive(XmFileSelectionBoxGetChild(fileSelBox, XmDIALOG_FILTER_TEXT)
		   , False);
    str1 = XmStringCreateSimple("*.pgm");
    XtVaSetValues(fileSelBox,
		  XmNpattern, str1,
		  XmNfileSearchProc, objectSearchProc,
		  NULL);
    XmStringFree(str1);
    break;
  case 2:
    XtVaGetValues(XtParent(w), XmNuserData, &fileSelBox, NULL);
    XtSetSensitive(XmFileSelectionBoxGetChild(fileSelBox, XmDIALOG_FILTER_TEXT)
		   , True);
    str1 = XmStringCreateSimple("*.vec");
    XtVaSetValues(fileSelBox,
		  XmNpattern, str1,
		  XmNfileSearchProc, Global::d_defFileSearchProc,
		  NULL);
    XmStringFree(str1);
    break;
  case 3:
    XtVaGetValues(XtParent(w), XmNuserData, &fileSelBox, NULL);
    XtSetSensitive(XmFileSelectionBoxGetChild(fileSelBox, XmDIALOG_FILTER_TEXT)
		   , False);
    str1 = XmStringCreateSimple("*.vec");
    XtVaSetValues(fileSelBox,
		  XmNpattern, str1,
		  XmNfileSearchProc, objectSearchProc,
		  NULL);
    XmStringFree(str1);
    break;
  case 4:
    XtVaGetValues(XtParent(w), XmNuserData, &fileSelBox, NULL);
    XtSetSensitive(XmFileSelectionBoxGetChild(fileSelBox, XmDIALOG_FILTER_TEXT)
		   , False);
    str1 = XmStringCreateSimple("*.evc");
    XtVaSetValues(fileSelBox,
		  XmNpattern, str1,
		  XmNfileSearchProc, Global::d_defFileSearchProc,
		  NULL);
    XmStringFree(str1);
  }
}

void filesel_load_cb(Widget w, XtPointer, XtPointer p1)
{
  int i;
  char *p2, *p3, *dir, *name, buf[256], errmessg[256];
  ostrstream ostr(errmessg, 256);
  ErrorScope::Error error;
  Image *img, current;
  FileList *fl;
  FileListIter *it;
  VectAry *va;
  XmString str, *names;
  Vector vec;
  WidgetList wlist, wlist2;

  XmStringGetLtoR(((XmFileSelectionBoxCallbackStruct *)p1) -> dir,
		  XmSTRING_DEFAULT_CHARSET, &dir);
  XmStringGetLtoR(((XmFileSelectionBoxCallbackStruct *)p1) -> value,
		  XmSTRING_DEFAULT_CHARSET, &p2);
  if(*p2 == '/') {
    p3 = strrchr(p2, '/') + 1;
    strcpy(name = new char[strlen(p3) + 1], p3);
    *p3 = '\0';
    XtFree(dir);
    strcpy(dir = XtMalloc(strlen(p2) + 1), p2);
  }
  else {
    if((p3 = strrchr(p2, '/')) == NULL)
      p3 = p2;
    else
      ++p3;
    strcpy(name = new char[strlen(p3) + 1], p3);
  }
  XtFree(p2);

  for(p2 = name; isspace(*p2); ++p2);
  if(*p2 == '\0') {
    err_dlg(w, "Please supply Selection name");
    XtFree(dir);
    delete[] name;
    return;
  }

  XtVaGetValues(Global::d_saverbox, XmNchildren, &wlist, NULL);
  XtVaGetValues(Global::d_buttons, XmNchildren, &wlist2, NULL);

  switch(Global::d_ldtstat) {
  case 0:
    img = new Image;
    strcat(strcpy(p2 = new char[strlen(dir) + strlen(name) + 1], dir), name);
    if((error = ImageUtil::PGMGetFromDisk(img, p2)) != ErrorScope::OK) {
      ostr << error << ": " << p2;
      err_dlg(w, errmessg);
      delete[] p2;
      delete img;
      break;
    }
    delete[] p2;

    str = XmStringCreateSimple(name);
    XtVaSetValues(Global::d_label1, XmNlabelString, str, NULL);
    XmStringFree(str);
    str = XmStringCreateSimple("");
    XtVaSetValues(Global::d_label2, XmNlabelString, str, NULL);
    XmStringFree(str);
    
    delete Global::d_image;
    Global::d_image = img;
    XtManageChild(Global::d_darea);
    adjust_image(*img, &current);
    adjust_ximage(current);
    Global::d_ldsvflg = 1;
    toggled_cb(wlist[0], (XtPointer)0, 0);
    for(i = 0; i < 5; ++i)
      i == Global::d_ldsel ? XtVaSetValues(wlist[i], XmNset, True, NULL)
	: XtVaSetValues(wlist[i], XmNset, False, NULL);
    for(i = 0; i < 6; XtSetSensitive(wlist2[i++], False));
    XtSetSensitive(Global::d_segButton, True);
    XtSetSensitive(Global::d_sizeButton, True);
    XtSetSensitive(Global::d_prefButton, True);

    names = new XmString[1];
    names[0] = XmStringCreateSimple(name);
    XtVaSetValues(XmSelectionBoxGetChild(Global::d_selectBox, XmDIALOG_LIST),
		  XmNitems, names, XmNitemCount, 1, NULL);
    XmStringFree(names[0]);
    delete[] names;
    
    Global::d_ldsel = Global::d_ldtstat;
    
    delete[] Global::d_dir;
    delete[] Global::d_name;
    strcpy(Global::d_dir = new char[strlen(dir) + 1], dir);
    strcpy(Global::d_name = new char[strlen(name) + 1], name);
    XtPopdown(XtParent(XtParent(w)));
    break;
  case 1:
    {
      fl = new FileList(dir, name, "pgm");
      if((error = fl -> error()) != ErrorScope::OK) {
	ostr << error;
	err_dlg(w, errmessg);
	delete fl;
	break;
      }
      it = new FileListIter(*fl);

      str = XmStringCreateSimple(name);
      XtVaSetValues(Global::d_label2, XmNlabelString, str, NULL);
      XmStringFree(str);
      
      delete Global::d_fl;
      Global::d_fl = fl;
      delete Global::d_flit;
      Global::d_flit = it;
      XtManageChild(Global::d_darea);

      if((error = it_next_image()) != ErrorScope::OK) {
	ostr << error << ": " << (*Global::d_flit)();
	err_dlg(w, errmessg);
	break;
      }

      Global::d_ldsvflg = 1;
      toggled_cb(wlist[1], (XtPointer)1, 0);
      for(i = 0; i < 5; ++i)
	i == Global::d_ldsel ? XtVaSetValues(wlist[i], XmNset, True, NULL)
	  : XtVaSetValues(wlist[i], XmNset, False, NULL);
      for(i = 0; i < 6; XtSetSensitive(wlist2[i++], True));
      XtSetSensitive(Global::d_segButton, True);
      XtSetSensitive(Global::d_sizeButton, True);
      XtSetSensitive(Global::d_prefButton, True);

      FileListIter it2(*Global::d_fl);
      for(i = 0, names = new XmString[Global::d_fl -> getSize()]; it2; ++it2, ++i) {
	if((p3 = strrchr(it2(), '/')) == NULL)
	  p3 = (char *)it2();
	else
	  ++p3;
	names[i] = XmStringCreateSimple(p3);
      }
      XtVaSetValues(XmSelectionBoxGetChild(Global::d_selectBox, XmDIALOG_LIST),
		    XmNitems, names, XmNitemCount, i, NULL);
      while(i--)
	XmStringFree(names[i]);
      delete[] names;

      Global::d_ldsel = Global::d_ldtstat;
      delete[] Global::d_dir;
      delete[] Global::d_name;
      strcpy(Global::d_dir = new char[strlen(dir) + 1], dir);
      strcpy(Global::d_name = new char[strlen(name) + 1], name);
      XtPopdown(XtParent(XtParent(w)));
    }
    break;
  case 2:
    strcat(strcpy(p2 = new char[strlen(dir) + strlen(name) + 1], dir), name);
    if(Global::d_ldftype == 1) {
      if((error = IOUtil::get(&vec, p2)) != ErrorScope::OK) {
	ostr << error << ": " << p2;
	err_dlg(w, errmessg);
	delete[] p2;
	break;
      }
    }
    else {
      if((error = vec.getText(p2)) != ErrorScope::OK) {
	ostr << error << ": " << p2;
	err_dlg(w, errmessg);
	delete[] p2;
	break;
      }
    }
    delete[] p2;
    delete Global::d_vec_p;
    Global::d_vec_p = new Vector(vec);

    str = XmStringCreateSimple(name);
    XtVaSetValues(Global::d_label1, XmNlabelString, str, NULL);
    XmStringFree(str);
    str = XmStringCreateSimple("");
    XtVaSetValues(Global::d_label2, XmNlabelString, str, NULL);
    XmStringFree(str);
    
    if(Global::d_viewv != 0) {
      XtVaGetValues(Global::d_text1, XmNvalue, &p2, NULL);
      Global::d_vxsize = atoi(p2);
      XtVaGetValues(Global::d_text2, XmNvalue, &p2, NULL);
      Global::d_vysize = atoi(p2);
      XtManageChild(Global::d_darea);
      adjust_vector(vec, &current, Global::d_vxsize, Global::d_vysize);
      adjust_ximage(current);
    }
    else {
      str = XmStringCreateSimple("");
      XtVaSetValues(Global::d_label3, XmNlabelString, str, NULL);
      XmStringFree(str);
      XtUnmanageChild(Global::d_darea);
    }

    Global::d_ldsvflg = 1;
    toggled_cb(wlist[2], (XtPointer)2, 0);
    for(i = 0; i < 5; ++i)
      i == Global::d_ldsel ? XtVaSetValues(wlist[i], XmNset, True, NULL)
	: XtVaSetValues(wlist[i], XmNset, False, NULL);
    for(i = 0; i < 6; XtSetSensitive(wlist2[i++], False));
    if(Global::d_viewv != 0) {
      XtSetSensitive(Global::d_segButton, True);
      XtSetSensitive(Global::d_sizeButton, True);
      XtSetSensitive(Global::d_prefButton, True);
    }
    else {
      XtSetSensitive(Global::d_segButton, False);
      XtSetSensitive(Global::d_sizeButton, False);
      XtSetSensitive(Global::d_prefButton, False);
    }

    names = new XmString[1];
    names[0] = XmStringCreateSimple(name);
    XtVaSetValues(XmSelectionBoxGetChild(Global::d_selectBox, XmDIALOG_LIST),
		  XmNitems, names, XmNitemCount, 1, NULL);
    XmStringFree(names[0]);
    delete[] names;

    Global::d_ldsel = Global::d_ldtstat;

    delete[] Global::d_dir;
    delete[] Global::d_name;
    strcpy(Global::d_dir = new char[strlen(dir) + 1], dir);
    strcpy(Global::d_name = new char[strlen(name) + 1], name);
    XtPopdown(XtParent(XtParent(w)));
    break;
  case 3:
    {
      fl = new FileList(dir, name, "vec");
      if((error = fl -> error()) != ErrorScope::OK) {
	ostr << error;
	err_dlg(w, errmessg);
	delete fl;
	break;
      }
      it = new FileListIter(*fl);
      delete Global::d_fl;
      Global::d_fl = fl;
      delete Global::d_flit;
      Global::d_flit = it;

      str = XmStringCreateSimple(name);
      XtVaSetValues(Global::d_label2, XmNlabelString, str, NULL);
      XmStringFree(str);

      if(Global::d_viewv != 0) {
	XtVaGetValues(Global::d_text1, XmNvalue, &p2, NULL);
	Global::d_vxsize = atoi(p2);
	XtVaGetValues(Global::d_text2, XmNvalue, &p2, NULL);
	Global::d_vysize = atoi(p2);
	XtManageChild(Global::d_darea);
	if((error = it_next_vector()) != ErrorScope::OK) {
	  ostr << error << ": " << (*Global::d_flit)();
	  err_dlg(w, errmessg);
	  break;
	}
      }
      else {
	str = XmStringCreateSimple("");
	XtVaSetValues(Global::d_label1, XmNlabelString, str, NULL);
	XtVaSetValues(Global::d_label3, XmNlabelString, str, NULL);
	XmStringFree(str);
	XtUnmanageChild(Global::d_darea);
      }

      Global::d_ldsvflg = 1;
      toggled_cb(wlist[3], (XtPointer)3, 0);
      for(i = 0; i < 5; ++i)
	i == Global::d_ldsel ? XtVaSetValues(wlist[i], XmNset, True, NULL)
	  : XtVaSetValues(wlist[i], XmNset, False, NULL);
      for(i = 0; i < 6; XtSetSensitive(wlist2[i++], True));
      if(Global::d_viewv != 0) {
	XtSetSensitive(Global::d_segButton, True);
	XtSetSensitive(Global::d_sizeButton, True);
	XtSetSensitive(Global::d_prefButton, True);
      }
      else {
	XtSetSensitive(Global::d_segButton, False);
	XtSetSensitive(Global::d_sizeButton, False);
	XtSetSensitive(Global::d_prefButton, False);
      }

      FileListIter it2(*Global::d_fl);
      for(i = 0, names = new XmString[Global::d_fl -> getSize()]; it2; ++it2, ++i) {
	if((p3 = strrchr(it2(), '/')) == NULL)
	  p3 = (char *)it2();
	else
	  ++p3;
	names[i] = XmStringCreateSimple(p3);
      }
      XtVaSetValues(XmSelectionBoxGetChild(Global::d_selectBox, XmDIALOG_LIST),
		    XmNitems, names, XmNitemCount, i, NULL);
      while(i--)
	XmStringFree(names[i]);
      delete[] names;

      Global::d_ldsel = Global::d_ldtstat;

      delete[] Global::d_dir;
      delete[] Global::d_name;
      strcpy(Global::d_dir = new char[strlen(dir) + 1], dir);
      strcpy(Global::d_name = new char[strlen(name) + 1], name);
      XtPopdown(XtParent(XtParent(w)));
    }
    break;
  case 4:
    {
      va = new VectAry;
      strcat(strcpy(p2 = new char[strlen(dir) + strlen(name) + 1], dir), name);
      XReporter::showWaitCursor(Global::d_loadbox);
      XReporter::showWaitCursor(Global::d_topshell);
      if(Global::d_ldftype == 1) {
	if((error = IOUtil::get(va, p2)) != ErrorScope::OK) {
	  XReporter::showNormalCursor(Global::d_loadbox);
	  XReporter::showNormalCursor(Global::d_topshell);
	  ostr << error << ": " << p2;
	  err_dlg(w, errmessg);
	  delete[] p2;
	  delete va;
	  break;
	}
      }
      else {
	if((error = va -> getText(p2)) != ErrorScope::OK) {
	  XReporter::showNormalCursor(Global::d_loadbox);
	  XReporter::showNormalCursor(Global::d_topshell);
	  ostr << error << ": " << p2;
	  err_dlg(w, errmessg);
	  delete[] p2;
	  delete va;
	  break;
	}
      }
      delete[] p2;
      delete Global::d_va;
      Global::d_va = va;
      Global::d_vapos = 0;

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

      str = XmStringCreateSimple(name);
      XtVaSetValues(Global::d_label2, XmNlabelString, str, NULL);
      XmStringFree(str);
      
      if(Global::d_viewv != 0) {
	XtVaGetValues(Global::d_text1, XmNvalue, &p2, NULL);
	Global::d_vxsize = atoi(p2);
	XtVaGetValues(Global::d_text2, XmNvalue, &p2, NULL);
	Global::d_vysize = atoi(p2);
	XtManageChild(Global::d_darea);
	it_next_eigenvector();
      }
      else {
	str = XmStringCreateSimple("");
	XtVaSetValues(Global::d_label1, XmNlabelString, str, NULL);
	XtVaSetValues(Global::d_label3, XmNlabelString, str, NULL);
	XmStringFree(str);
	XtUnmanageChild(Global::d_darea);
      }

      Global::d_ldsvflg = 1;
      toggled_cb(wlist[4], (XtPointer)4, 0);
      for(i = 0; i < 5; ++i)
	i == Global::d_ldsel ? XtVaSetValues(wlist[i], XmNset, True, NULL)
	  : XtVaSetValues(wlist[i], XmNset, False, NULL);
      for(i = 0; i < 6; XtSetSensitive(wlist2[i++], True));
      if(Global::d_viewv != 0) {
	XtSetSensitive(Global::d_segButton, True);
	XtSetSensitive(Global::d_sizeButton, True);
	XtSetSensitive(Global::d_prefButton, True);
      }
      else {
	XtSetSensitive(Global::d_segButton, False);
	XtSetSensitive(Global::d_sizeButton, False);
	XtSetSensitive(Global::d_prefButton, False);
      }

      VectAryIter it2(*Global::d_va);
      for(i = 0, names = new XmString[Global::d_va -> getSize()]; it2; ++it2, ++i) {
	sprintf(buf, "%u", i);
	names[i] = XmStringCreateSimple(buf);
      }
      XtVaSetValues(XmSelectionBoxGetChild(Global::d_selectBox, XmDIALOG_LIST),
		    XmNitems, names, XmNitemCount, i, NULL);
      while(i--)
	XmStringFree(names[i]);
      delete[] names;

      Global::d_ldsel = Global::d_ldtstat;

      delete[] Global::d_dir;
      delete[] Global::d_name;
      strcpy(Global::d_dir = new char[strlen(dir) + 1], dir);
      strcpy(Global::d_name = new char[strlen(name) + 1], name);
      XtPopdown(XtParent(XtParent(w)));
    }
  }
  
  XtFree(dir);
  delete[] name;
}

void filesel_save_cb(Widget w, XtPointer, XtPointer p1)
{
  int i, x, y;
  char *p2, *p3, *dir, *name, buf[256], errmessg[256];
  ostrstream ostr(errmessg, 256);
  ErrorScope::Error error;
  Image current;
  Vector vec;

  XmStringGetLtoR(((XmFileSelectionBoxCallbackStruct *)p1) -> dir,
		  XmSTRING_DEFAULT_CHARSET, &dir);
  XmStringGetLtoR(((XmFileSelectionBoxCallbackStruct *)p1) -> value,
		  XmSTRING_DEFAULT_CHARSET, &p2);
  if(*p2 == '/') {
    p3 = strrchr(p2, '/') + 1;
    strcpy(name = new char[strlen(p3) + 1], p3);
    *p3 = '\0';
    XtFree(dir);
    strcpy(dir = XtMalloc(strlen(p2) + 1), p2);
  }
  else {
    if((p3 = strrchr(p2, '/')) == NULL)
      p3 = p2;
    else
      ++p3;
    strcpy(name = new char[strlen(p3) + 1], p3);
  }
  XtFree(p2);

  Global::d_svsel = Global::d_svtstat;

  for(p2 = name; isspace(*p2); ++p2);
  if(*p2 == '\0') {
    err_dlg(w, "Please supply Selection name");
    XtFree(dir);
    delete[] name;
    return;
  }
  
  switch(Global::d_ldsel) {
  case 0:
    strcat(strcpy(p2 = new char[strlen(dir) + strlen(name) + 1], dir), name);
    switch(Global::d_svsel) {
    case 0:
      adjust_image(*Global::d_image, &current);
      if((error = ImageUtil::PGMDumpToDisk(current, p2)) != ErrorScope::OK) {
	ostr << error << ": " << p2;
	err_dlg(w, errmessg);
      }
      else
	XtPopdown(XtParent(XtParent(w)));
      break;
    case 2:
      adjust_image(*Global::d_image, &vec);
      if(Global::d_svftype == 1) {
	if((error = IOUtil::put(vec, p2)) != ErrorScope::OK) {
	  ostr << error << ": " << p2;
	  err_dlg(w, errmessg);
	}
	else
	  XtPopdown(XtParent(XtParent(w)));  
      }
      else {
	if((error = vec.putText(p2)) != ErrorScope::OK){
	  ostr << error << ": " << p2;
	  err_dlg(w, errmessg);
	}
	else
	  XtPopdown(XtParent(XtParent(w)));
      }
      break;
    }
    delete[] p2;
    break;
  case 1:
    switch(Global::d_svsel) {
    case 1:
      {
	XReporter::showWindow(Global::d_savebox, "Saving as Images", XReporter::INTERRUPTIBLE);
	XReporter::showWaitCursor(Global::d_topshell);
	Image img;
	for(FileListIter it(*Global::d_fl); it; ++it) {
	  if(XReporter::display_status() == XReporter::BUTTONPRESSED) {
	    error = ErrorScope::DEVICE_FUNCTION_ERROR;
	    break;
	  }
	  if((error = ImageUtil::PGMGetFromDisk(&img, it())) != ErrorScope::OK) {
	    ostr << error << ": " << it();
	    err_dlg(w, errmessg);
	    break;
	  }
	  adjust_image(img, &current);
	  p3 = strrchr(it(), '/') + 1;
	  strcat(strcat(strcpy(p2 = new char[strlen(dir) + strlen(name) + (strlen(p3) - NamingScope::getNameLength(p3)) + 1], dir), name), p3 + NamingScope::getNameLength(p3));
	  if((error = ImageUtil::PGMDumpToDisk(current, p2)) != ErrorScope::OK) {
	    ostr << error << ": " << p2;
	    err_dlg(w, errmessg);
	    delete[] p2;
	    break;
	  }
	  delete[] p2;
	}
	XReporter::destroyWindow();
	XReporter::showNormalCursor(Global::d_topshell);
	if(error == ErrorScope::OK)
	  XtPopdown(XtParent(XtParent(w)));
      }
      break;
    case 3:
      {
	XReporter::showWindow(Global::d_savebox, "Converting and Saving as Vectors", XReporter::INTERRUPTIBLE);
	XReporter::showWaitCursor(Global::d_topshell);
	Image img;
	for(FileListIter it(*Global::d_fl); it; ++it) {
	  if(XReporter::display_status() == XReporter::BUTTONPRESSED) {
	    error = ErrorScope::DEVICE_FUNCTION_ERROR;
	    break;
	  }
	  if((error = ImageUtil::PGMGetFromDisk(&img, it())) != ErrorScope::OK) {
	    ostr << error << ": " << it();
	    err_dlg(w, errmessg);
	    break;
	  }
	  adjust_image(img, &vec);
	  p3 = strrchr(it(), '/') + 1;
	  strcat(strcat(strcpy(p2 = new char[strlen(dir) + strlen(name) + (strlen(p3) - NamingScope::getNameLength(p3)) + 1], dir), name), p3 + NamingScope::getNameLength(p3));
	  strcpy(p2 + strlen(p2) - 3, "vec");
	  if(Global::d_svftype == 1) {
	    if((error = IOUtil::put(vec, p2)) != ErrorScope::OK) {
	      ostr << error << ": " << p2;
	      err_dlg(w, errmessg);
	      delete[] p2;
	      break;
	    }
	  }
	  else {
	    if((error = vec.putText(p2)) != ErrorScope::OK) {
	      ostr << error << ": " << p2;
	      err_dlg(w, errmessg);
	      delete[] p2;
	      break;
	    }
	  }
	  delete[] p2;
	}
	XReporter::destroyWindow();
	XReporter::showNormalCursor(Global::d_topshell);
	if(error == ErrorScope::OK)
	  XtPopdown(XtParent(XtParent(w)));
      }
      break;
    }
    break;
  case 2:
    strcat(strcpy(p2 = new char[strlen(dir) + strlen(name) + 1], dir), name);
    switch(Global::d_svsel) {
    case 0:
      if(Global::d_viewv != 0)
	adjust_vector(*Global::d_vec_p, &current, Global::d_vxsize,
		      Global::d_vysize);
      else {
	XtVaGetValues(Global::d_text3, XmNvalue, &p3, NULL);
	x = atoi(p3);
	XtVaGetValues(Global::d_text4, XmNvalue, &p3, NULL);
	y = atoi(p3);
	adjust_vector(*Global::d_vec_p, &current, x, y);
      }
      if((error = ImageUtil::PGMDumpToDisk(current, p2)) != ErrorScope::OK) {
	ostr << error << ": " << p2;
	err_dlg(w, errmessg);
      }
      else
	XtPopdown(XtParent(XtParent(w)));
      break;
    case 2:
      if(Global::d_viewv != 0)
	adjust_vector(*Global::d_vec_p, &vec, Global::d_vxsize,
		      Global::d_vysize);
      else
	adjust_vector(*Global::d_vec_p, &vec, -1, -1);
      if(Global::d_svftype == 1) {
	if((error = IOUtil::put(vec, p2)) != ErrorScope::OK) {
	  ostr << error << ": " << p2;
	  err_dlg(w, errmessg);
	}
	else
	  XtPopdown(XtParent(XtParent(w)));
      }
      else {
	if((error = vec.putText(p2)) != ErrorScope::OK) {
	  ostr << error << ": " << p2;
	  err_dlg(w, errmessg);
	}
	else
	  XtPopdown(XtParent(XtParent(w)));
      }
    }
    delete[] p2;
    break;
  case 3:
    switch(Global::d_svsel) {
    case 1:
      {
	XReporter::showWindow(Global::d_savebox, "Converting and Saving as Images", XReporter::INTERRUPTIBLE);
	XReporter::showWaitCursor(Global::d_topshell);
	for(FileListIter it(*Global::d_fl); it; ++it) {
	  if(XReporter::display_status() == XReporter::BUTTONPRESSED) {
	    error = ErrorScope::DEVICE_FUNCTION_ERROR;
	    break;
	  }
	  if(Global::d_ldftype == 1) {
	    if((error = IOUtil::get(&vec, it())) != ErrorScope::OK) {
	      ostr << error << ": " << it();
	      err_dlg(w, errmessg);
	      break;
	    }
	  }
	  else {
	    if((error = vec.getText(it())) != ErrorScope::OK) {
	      ostr << error << ": " << it();
	      err_dlg(w, errmessg);
	      break;
	    }
	  }
	  if(Global::d_viewv != 0)
	    adjust_vector(vec, &current, Global::d_vxsize, Global::d_vysize);
	  else {
	    XtVaGetValues(Global::d_text3, XmNvalue, &p3, NULL);
	    x = atoi(p3);
	    XtVaGetValues(Global::d_text4, XmNvalue, &p3, NULL);
	    y = atoi(p3);
	    adjust_vector(vec, &current, x, y);
	  }   
	  p3 = strrchr(it(), '/') + 1;
	  strcat(strcat(strcpy(p2 = new char[strlen(dir) + strlen(name) + (strlen(p3) - NamingScope::getNameLength(p3)) + 1], dir), name), p3 + NamingScope::getNameLength(p3));
	  strcpy(p2 + strlen(p2) - 3, "pgm");
	  if((error = ImageUtil::PGMDumpToDisk(current, p2)) != ErrorScope::OK) {
	    ostr << error << ": " << p2;
	    err_dlg(w, errmessg);
	    delete[] p2;
	    break;
	  }
	  delete[] p2;
	}
	XReporter::destroyWindow();
	XReporter::showNormalCursor(Global::d_topshell);
	if(error == ErrorScope::OK)
	  XtPopdown(XtParent(XtParent(w)));
      }
      break;
    case 3:
      {
	XReporter::showWindow(Global::d_savebox, "Saving as Vectors", XReporter::INTERRUPTIBLE);
	XReporter::showWaitCursor(Global::d_topshell);
	Vector current;
	for(FileListIter it(*Global::d_fl); it; ++it) {
	  if(XReporter::display_status() == XReporter::BUTTONPRESSED) {
	    error = ErrorScope::DEVICE_FUNCTION_ERROR;
	    break;
	  }
	  if(Global::d_ldftype == 1) {
	    if((error = IOUtil::get(&vec, it())) != ErrorScope::OK) {
	      ostr << error << ": " << it();
	      err_dlg(w, errmessg);
	      break;
	    }
	  }
	  else {
	    if((error = vec.getText(it())) != ErrorScope::OK) {
	      ostr << error << ": " << it();
	      err_dlg(w, errmessg);
	      break;
	    }
	  }
	  if(Global::d_viewv != 0)
	    adjust_vector(vec, &current, Global::d_vxsize, Global::d_vysize);
	  else
	    adjust_vector(vec, &current, -1, -1);
	  p3 = strrchr(it(), '/') + 1;
	  strcat(strcat(strcpy(p2 = new char[strlen(dir) + strlen(name) + (strlen(p3) - NamingScope::getNameLength(p3)) + 1], dir), name), p3 + NamingScope::getNameLength(p3));
	  if(Global::d_svftype == 1) {
	    if((error = IOUtil::put(current, p2)) != ErrorScope::OK) {
	      ostr << error << ": " << p2;
	      err_dlg(w, errmessg);
	      delete[] p2;
	      break;
	    }
	  }
	  else {
	    if((error = current.putText(p2)) != ErrorScope::OK) {
	      ostr << error << ": " << p2;
	      err_dlg(w, errmessg);
	      delete[] p2;
	      break;
	    }
	  }
	  delete[] p2;
	}
	XReporter::destroyWindow();
	XReporter::showNormalCursor(Global::d_topshell);
	if(error == ErrorScope::OK)
	  XtPopdown(XtParent(XtParent(w)));
      }
      break;
    case 4:
      {
	XReporter::showWaitCursor(Global::d_topshell);
	XReporter::showWaitCursor(Global::d_savebox);
	strcat(strcpy(p2 = new char[strlen(dir) + strlen(name) + 1], dir), name);
	VectAry va(Global::d_fl -> getSize());
	VectAryIter it2(va);
	Image img;
	for(FileListIter it(*Global::d_fl); it; ++it, ++it2) {
	  if(Global::d_ldftype == 1) {
	    if((error = IOUtil::get(&vec, it())) != ErrorScope::OK) {
	      ostr << error << ": " << it();
	      err_dlg(w, errmessg);
	      break;
	    }
	  }
	  else
	    if((error = vec.getText(it())) != ErrorScope::OK) {
	      ostr << error << ": " << it();
	      err_dlg(w, errmessg);
	      break;
	    }
	  if(Global::d_viewv != 0) 
	    adjust_vector(vec, &(it2()), Global::d_vxsize, Global::d_vysize);
	  else
	    adjust_vector(vec, &(it2()), -1, -1);
	}
	if(error == ErrorScope::OK) {
	  if(Global::d_svftype == 1) {
	    if((error = IOUtil::put(va, p2)) != ErrorScope::OK) {
	      ostr << error << ": " << p2;
	      err_dlg(w, errmessg);
	    }
	    else
	      XtPopdown(XtParent(XtParent(w)));
	  }
	  else
	    if((error = va.putText(p2)) != ErrorScope::OK) {
	      ostr << error << ": " << p2;
	      err_dlg(w, errmessg);
	    }
	    else
	      XtPopdown(XtParent(XtParent(w)));
	}
	delete[] p2;
	XReporter::showNormalCursor(Global::d_topshell);
	XReporter::showNormalCursor(Global::d_savebox);
      }
    }
    break;
  case 4:
    switch(Global::d_svsel) {
    case 3:
      {
	XReporter::showWindow(Global::d_savebox, "Converting and Saving as Vectors", XReporter::INTERRUPTIBLE);
	XReporter::showWaitCursor(Global::d_topshell);
	VectAryIter it(*Global::d_va);
	for(i = 0; it; ++it, ++i) {
	  if(XReporter::display_status() == XReporter::BUTTONPRESSED) {
	    error = ErrorScope::DEVICE_FUNCTION_ERROR;
	    break;
	  }
	  if(Global::d_viewv != 0)
	    adjust_vector(it(), &vec, Global::d_vxsize, Global::d_vysize);
	  else
	    adjust_vector(it(), &vec, -1, -1);
	  sprintf(buf, "%s__%u.vec", name, i);
	  strcat(strcpy(p2 = new char[strlen(dir) + strlen(buf) + 1], dir), buf);
	  if(Global::d_svftype == 1) {
	    if((error = IOUtil::put(vec, p2)) != ErrorScope::OK) {
	      ostr << error << ": " << p2;
	      err_dlg(w, errmessg);
	      delete[] p2;
	      break;
	    }
	  }
	  else 
	    if((error = vec.putText(p2)) != ErrorScope::OK) {
	      ostr << error << ": " << p2;
	      err_dlg(w, errmessg);
	      delete[] p2;
	      break;
	    }
	  delete[] p2;
	}
	XReporter::destroyWindow();
	XReporter::showNormalCursor(Global::d_topshell);
	if(error == ErrorScope::OK)	
	  XtPopdown(XtParent(XtParent(w)));
      }
      break;
    case 4:
      {
	XReporter::showWaitCursor(Global::d_topshell);
	XReporter::showWaitCursor(Global::d_savebox);
	strcat(strcpy(p2 = new char[strlen(dir) + strlen(name) + 1], dir), name);
	VectAry va(Global::d_va -> getSize());
	VectAryIter it(*Global::d_va);
	for(VectAryIter it2(va); it; ++it, ++it2)
	  if(Global::d_viewv != 0)
	    adjust_vector(it(), &(it2()), Global::d_vxsize, Global::d_vysize);
	  else
	    adjust_vector(it(), &(it2()), -1, -1);
	if(Global::d_svftype == 1) {
	  if((error = IOUtil::put(va, p2)) != ErrorScope::OK) {
	    ostr << error << ": " << p2;
	    err_dlg(w, errmessg);
	  }
	  else
	    XtPopdown(XtParent(XtParent(w)));
	}
	else {
	  if((error = va.putText(p2)) != ErrorScope::OK) {
	    ostr << error << ": " << p2;
	    err_dlg(w, errmessg);
	  }
	  else
	    XtPopdown(XtParent(XtParent(w)));
	}
	delete[] p2;
	XReporter::showNormalCursor(Global::d_topshell);
	XReporter::showNormalCursor(Global::d_savebox);
      }
    }
  }
  
  XtFree(dir);
  delete[] name;
}

void viewv_cb(Widget, XtPointer, XtPointer)
{
  if((Global::d_viewv = ~Global::d_viewv) == 0) {
    XtVaSetValues(Global::d_text1, XmNsensitive, False, NULL);
    XtVaSetValues(Global::d_text2, XmNsensitive, False, NULL);
  }
  else {
    XtVaSetValues(Global::d_text1, XmNsensitive, True, NULL);
    XtVaSetValues(Global::d_text2, XmNsensitive, True, NULL);
  }
}

void fmenu_cb(Widget w, XtPointer p1, XtPointer)
{
  char *buf, p2[256];
  int i, j;
  WidgetList wlist;
  ErrorScope::Error error;
  char errmessg[256];
  ostrstream ostr(errmessg, 256);

  switch(int(p1)) {
  case 0:
    XtPopup(Global::d_loadbox, XtGrabNone);
    Global::d_ldsvflg = 0;
    break;
  case 1:
    switch(Global::d_ldsel) {
    case 0:
      {
	Image current;
	strcat(strcpy(buf = new char[strlen(Global::d_dir) +
				     strlen(Global::d_name) + 1],
		      Global::d_dir), Global::d_name);
	adjust_image(*Global::d_image, &current);
	if((error = ImageUtil::PGMDumpToDisk(current, buf)) != ErrorScope::OK) {
	  ostr << error << ": " << buf;
	  err_dlg(w, errmessg);
	}
	delete[] buf;
      }
      break;
    case 1:
      {
	XReporter::showWindow(Global::d_topshell, "Saving Images", XReporter::INTERRUPTIBLE);
	Image img, current;
	for(FileListIter it(*Global::d_fl); it; ++it) {
	  if(XReporter::display_status() == XReporter::BUTTONPRESSED)
	    break;
	  if((error = ImageUtil::PGMGetFromDisk(&img, it())) != ErrorScope::OK) {
	    ostr << error << ": " << it();
	    err_dlg(w, errmessg);
	    break;
	  }
	  adjust_image(img, &current);
	  if((error = ImageUtil::PGMDumpToDisk(current, it())) != ErrorScope::OK) {
	    ostr << error << ": " << it();
	    err_dlg(w, errmessg);
	    break;
	  }
	}
	XReporter::destroyWindow();
      }
      break;
    case 2:
      {
	Vector v;
	adjust_vector(*Global::d_vec_p, &v, Global::d_vxsize, Global::d_vysize);
	strcat(strcpy(buf = new char[strlen(Global::d_dir) +
				     strlen(Global::d_name) + 1],
		      Global::d_dir), Global::d_name);
	if(Global::d_ldftype == 1) {
	  if((error = IOUtil::put(v, buf)) != ErrorScope::OK) {
	    ostr << error << ": " << buf;
	    err_dlg(w, errmessg);
	  }
	}
	else {
	  if((error = v.putText(buf)) != ErrorScope::OK) {
	    ostr << error << ": " << buf;
	    err_dlg(w, errmessg);
	  }
	}
	delete[] buf;
      }
      break;
    case 3:
      {
	XReporter::showWindow(Global::d_topshell, "Saving Vectors", XReporter::INTERRUPTIBLE);
	Vector v, vec;
	for(FileListIter it(*Global::d_fl); it; ++it) {
	  if(XReporter::display_status() == XReporter::BUTTONPRESSED)
	    break;
	  if(Global::d_ldftype == 1) {
	    if((error = IOUtil::get(&v, it())) != ErrorScope::OK) {
	      ostr << error << ": " << it();
	      err_dlg(w, errmessg);
	      break;
	    }
	  }
	  else {
	    if((error = v.getText(it())) != ErrorScope::OK) {
	      ostr << error << ": " << it();
	      err_dlg(w, errmessg);
	      break;
	    }
	  }
	  adjust_vector(v, &vec, Global::d_vxsize, Global::d_vysize);
	  if(Global::d_ldftype == 1) {
	    if((error = IOUtil::put(vec, it())) != ErrorScope::OK) {
	      ostr << error << ": " << it();
	      err_dlg(w, errmessg);
	      break;
	    }
	  }
	  else {
	    if((error = vec.putText(it())) != ErrorScope::OK) {
	      ostr << error << ": " << it();
	      err_dlg(w, errmessg);
	      break;
	    }
	  }
	}
	XReporter::destroyWindow();
      }
      break;
    case 4:
      {
	XReporter::showWaitCursor(Global::d_topshell);
	Vector v;
	for(i = 0, j = Global::d_va -> getSize(); i < j; ++i) {
	  adjust_vector((*Global::d_va)[i], &v, Global::d_vxsize, 
			Global::d_vysize);
	  (*Global::d_va)[i] = v;
	}
	strcat(strcpy(buf = new char[strlen(Global::d_dir) +
				     strlen(Global::d_name) + 1],
		      Global::d_dir), Global::d_name);
	if(Global::d_ldftype == 1) {
	  if((error = IOUtil::put(*Global::d_va, buf)) != ErrorScope::OK) {
	    ostr << error << ": " << buf;
	    err_dlg(w, errmessg);
	  }
	}
	else {
	  if((error = Global::d_va -> putText(buf)) != ErrorScope::OK) {
	    ostr << error << ": " << buf;
	    err_dlg(w, errmessg);
	  }
	}
	XReporter::showNormalCursor(Global::d_topshell);
	delete[] buf;
      }
    }
    break;
  case 2:
    XtVaGetValues(Global::d_saverbox, XmNchildren, &wlist, NULL);
    switch(Global::d_ldsel) {
    case 0:
    case 2:
      // Set Default Entity      
      for(i = 0; i < 5; ++i)
	i == 0 ? XtVaSetValues(wlist[i], XmNset, True, NULL) : XtVaSetValues(wlist[i], XmNset, False, NULL);
      Global::d_svtstat = 0;
      XtVaSetValues(wlist[0], XmNsensitive, True, NULL);
      XtVaSetValues(wlist[1], XmNsensitive, False, NULL);
      XtVaSetValues(wlist[2], XmNsensitive, True, NULL);
      XtVaSetValues(wlist[3], XmNsensitive, False, NULL);
      XtVaSetValues(wlist[4], XmNsensitive, False, NULL);
      break;
    case 1:
    case 3:
      // Set Default Entity      
      for(i = 0; i < 5; ++i)
	i == 1 ? XtVaSetValues(wlist[i], XmNset, True, NULL) : XtVaSetValues(wlist[i], XmNset, False, NULL);
      Global::d_svtstat = 1;
      XtVaSetValues(wlist[0], XmNsensitive, False, NULL);
      XtVaSetValues(wlist[1], XmNsensitive, True, NULL);
      XtVaSetValues(wlist[2], XmNsensitive, False, NULL);
      XtVaSetValues(wlist[3], XmNsensitive, True, NULL);
      XtVaSetValues(wlist[4], XmNsensitive, True, NULL);
      break;
    case 4:
      // Set Default Entity      
      for(i = 0; i < 5; ++i)
	i == 3 ? XtVaSetValues(wlist[i], XmNset, True, NULL) : XtVaSetValues(wlist[i], XmNset, False, NULL);
      Global::d_svtstat = 3;
      XtVaSetValues(wlist[0], XmNsensitive, False, NULL);
      XtVaSetValues(wlist[1], XmNsensitive, False, NULL);
      XtVaSetValues(wlist[2], XmNsensitive, False, NULL);
      XtVaSetValues(wlist[3], XmNsensitive, True, NULL);
      XtVaSetValues(wlist[4], XmNsensitive, True, NULL);
    }
    sprintf(p2, "%u", Global::d_ximage -> width);
    XmTextFieldSetString(Global::d_text3, p2);
    sprintf(p2, "%u", Global::d_ximage -> height);
    XmTextFieldSetString(Global::d_text4, p2);
    XtPopup(Global::d_savebox, XtGrabNone);
    Global::d_ldsvflg = 1;
    break;    
  case 3:
    exit(0);
  }
}

void smenu_cb(Widget, XtPointer, XtPointer)
{
  XtManageChild(Global::d_selectBox);
}

void omenu_cb(Widget, XtPointer p1, XtPointer)
{
  Image current;
  
  switch(int(p1)) {
  case 0:
    Global::d_seg = ~Global::d_seg;
    break;
  case 1:
    Global::d_nsize = ~Global::d_nsize;
    break;
  case 2:
    Global::d_nbright = ~Global::d_nbright;
    break;
  case 3:
    XtPopup(Global::d_prefBox, XtGrabNone);
    return;
  }
  switch(Global::d_ldsel) {
  case 0:
  case 1:
    adjust_image(*Global::d_image, &current);
    break;
  case 2:
  case 3:
    adjust_vector(*Global::d_vec_p, &current, Global::d_vxsize,
		  Global::d_vysize);
    break;
  case 4:
    adjust_vector((*Global::d_va)[Global::d_vapos], &current,
		  Global::d_vxsize, Global::d_vysize);
  }
  adjust_ximage(current);
}

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 rewind_cb(Widget w, XtPointer, XtPointer)
{
  char errmessg[256];
  ostrstream ostr(errmessg, 256);
  ErrorScope::Error error;
  
  switch(Global::d_ldsel) {
  case 1:
    Global::d_flit -> reset();
    if((error = it_next_image()) != ErrorScope::OK) {
      timerStepBack_cb(0, 0);
      ostr << error << ": " << (*Global::d_flit)();
      err_dlg(XtParent(w), errmessg);      
    }
    break;
  case 3:
    Global::d_flit -> reset();
    if((error = it_next_vector()) != ErrorScope::OK) {
      timerStepBack_cb(0, 0);
      ostr << error << ": " << (*Global::d_flit)();
      err_dlg(XtParent(w), errmessg);
    }
    break;
  case 4:
    Global::d_vapos = 0;
    it_next_eigenvector();
  }
}

void fastfwd_cb(Widget w, XtPointer, XtPointer)
{
  int i, j;
  char errmessg[256];
  ostrstream ostr(errmessg, 256);
  ErrorScope::Error error;
  
  switch(Global::d_ldsel) {
  case 1:
    Global::d_flit -> reset();
    for(i = 0, j = Global::d_fl -> getSize() - 1; i < j;
	++i, ++(*Global::d_flit));
    if((error = it_next_image()) != ErrorScope::OK) {
      timerStepFront_cb(0, 0);
      ostr << error << ": " << (*Global::d_flit)();
      err_dlg(XtParent(w), errmessg);
    }
    break;
  case 3:
    Global::d_flit -> reset();
    for(i = 0, j = Global::d_fl -> getSize() - 1; i < j;
	++i, ++(*Global::d_flit));
    if((error = it_next_vector()) != ErrorScope::OK) {
      timerStepFront_cb(0, 0);
      ostr << error << ": " << (*Global::d_flit)();
      err_dlg(XtParent(w), errmessg);
    }
    break;
  case 4:
    Global::d_vapos = Global::d_va -> getSize() - 1;
    it_next_eigenvector();
  }
}

void stepback_cb(Widget w, XtPointer, XtPointer)
{
  char errmessg[256];
  ostrstream ostr(errmessg, 256);
  ErrorScope::Error error;
  
  switch(Global::d_ldsel) {
  case 1:
    --(*Global::d_flit);
    if(*Global::d_flit == 0) {
      fastfwd_cb(w, 0, 0);
      return;
    }
    if((error = it_next_image()) != ErrorScope::OK) {
      ostr << error << ": " << (*Global::d_flit)();
      err_dlg(XtParent(w), errmessg);
    }
    break;
  case 3:
    --(*Global::d_flit);
    if(*Global::d_flit == 0) {
      fastfwd_cb(w, 0, 0);
      return;
    }
    if((error = it_next_vector()) != ErrorScope::OK) {
      ostr << error << ": " << (*Global::d_flit)();
      err_dlg(XtParent(w), errmessg);
    }
    break;
  case 4:
    if(--Global::d_vapos < 0) {
      Global::d_vapos = Global::d_va -> getSize() - 1;
    }
    it_next_eigenvector();
  }
}

void stepfront_cb(Widget w, XtPointer, XtPointer)
{
  char errmessg[256];
  ostrstream ostr(errmessg, 256);
  ErrorScope::Error error;
  
  switch(Global::d_ldsel) {
  case 1:
    ++(*Global::d_flit);
    if(*Global::d_flit == 0)
      Global::d_flit -> reset();
    if((error = it_next_image()) != ErrorScope::OK) {
      ostr << error << ": " << (*Global::d_flit)();
      err_dlg(XtParent(w), errmessg);
    }
    break;
  case 3:
    ++(*Global::d_flit);
    if(*Global::d_flit == 0)
      Global::d_flit -> reset();
    if((error = it_next_vector()) != ErrorScope::OK) {
      ostr << error << ": " << (*Global::d_flit)();
      err_dlg(XtParent(w), errmessg);
    }
    break;
  case 4:
    Global::d_vapos = ++Global::d_vapos % Global::d_va -> getSize();
    it_next_eigenvector();
  }
}

void timerStepFront_cb(void *p1, unsigned long*)
{
  static XtIntervalId timer = 0;
    
  if(p1 != 0) {
    stepfront_cb(Global::d_buttons, 0, 0);
    timer = XtAppAddTimeOut(Global::d_app, (unsigned long)p1, timerStepFront_cb, p1);
  }
  else if(timer != 0)
    XtRemoveTimeOut(timer);
}

void animateStepFront_cb(Widget, XtPointer p1, XtPointer)
{
  if(p1 != 0)
    timerStepFront_cb(p1, 0);
  else
    timerStepFront_cb(0, 0);
}

void timerStepBack_cb(void *p1, unsigned long*)
{
  static XtIntervalId timer = 0;
    
  if(p1 != 0) {
    stepback_cb(Global::d_buttons, 0, 0);
    timer = XtAppAddTimeOut(Global::d_app, (unsigned long)p1, timerStepBack_cb, p1);
  }
  else if(timer != 0)
    XtRemoveTimeOut(timer);
}

void animateStepBack_cb(Widget, XtPointer p1, XtPointer)
{
  if(p1 != 0)
    timerStepBack_cb(p1, 0);
  else
    timerStepBack_cb(0, 0);
}

void selboxok_cb(Widget w, XtPointer, XtPointer p1)
{
  char *p2, errmessg[256];
  ostrstream ostr(errmessg, 256);
  ErrorScope::Error error;
  const char *p3;
  
  XmStringGetLtoR(((XmSelectionBoxCallbackStruct *)p1) -> value,
		  XmSTRING_DEFAULT_CHARSET, &p2);

  switch(Global::d_ldsel) {
  case 1:
  case 3:
    {
      for(Global::d_flit -> reset(); *Global::d_flit; ++(*Global::d_flit)) {
	if((p3 = strrchr((*Global::d_flit)(), '/')) == NULL)
	  p3 = (*Global::d_flit)();
	else
	  ++p3;
	if(strcmp(p3, p2) == 0)
	  break;
      }
      if(Global::d_ldsel == 1) {
	if((error = it_next_image()) != ErrorScope::OK) {
	  ostr << error << ": " << (*Global::d_flit)();
	  err_dlg(w, errmessg);
	}
      }
      else
	if((error = it_next_vector()) != ErrorScope::OK) {
	  ostr << error << ": " << (*Global::d_flit)();
	  err_dlg(w, errmessg);
	}
    }
    break;
  case 4:
    Global::d_vapos = atoi(p2);
    it_next_eigenvector();
  }
  XtFree(p2);
}

void prefbox_cb(Widget, XtPointer p1, XtPointer)
{
  char *p2;
  Image current;
  switch(int(p1)) {
  case 0:
    XtPopdown(Global::d_prefBox);
  case 1:
    p2 = XmTextFieldGetString(Global::d_text5);
    Global::d_nxsize = atoi(p2);
    XtFree(p2);
    if(Global::d_aspect == ImageUtil::NOPRESERVE_ASPECT) {
      p2 = XmTextFieldGetString(Global::d_text6);
      Global::d_nysize = atoi(p2);
      XtFree(p2);
    }
    else
      Global::d_nysize = Global::d_nxsize;
    p2 = XmTextFieldGetString(Global::d_text7);
    Global::d_thresh = atoi(p2);
    XtFree(p2);
    switch(Global::d_ldsel) {
    case 0:
    case 1:
      adjust_image(*Global::d_image, &current);
      break;
    case 2:
    case 3:
      adjust_vector(*Global::d_vec_p, &current, Global::d_vxsize,
		    Global::d_vysize);
      break;
    case 4:
      adjust_vector((*Global::d_va)[Global::d_vapos], &current,
		    Global::d_vxsize, Global::d_vysize);
    }
    adjust_ximage(current);
    break;
  case 2:
    XtPopdown(Global::d_prefBox);
  }
}

void aspectRatioToggle_cb(Widget, XtPointer p1, XtPointer)
{
  if(Global::d_aspect == ImageUtil::PRESERVE_ASPECT) {
    XtSetSensitive(Widget(p1), True);
    Global::d_aspect = ImageUtil::NOPRESERVE_ASPECT;
  }
  else {
    XtSetSensitive(Widget(p1), False);
    Global::d_aspect = ImageUtil::PRESERVE_ASPECT;
  }
}
