/* WIDE AREA INFORMATION SERVER SOFTWARE:
   No guarantees or restrictions.  See the readme file for the full standard
   disclaimer.

   This is part of the X user-interface for the WAIS software.  Do with it
   as you please.

   Version 0.82
   Wed Apr 24 1991

   jonathan@Think.COM

*/

#define MAIN
#define XWAIS_C
#include "xwais.h"
#include "xwais.bit"

#define offset(field) XtOffset(struct _app_resources*, field)
static XtResource resources[] = {
   {"questionDirectory", "QuestionDirectory", XtRString, sizeof(char *),
         offset(questionDirectory), XtRString, "~/wais-questions/"},
   {"userSourceDirectory", "UserSourceDirectory", XtRString, sizeof(char *),
         offset(userSourceDirectory), XtRString, "~/wais-sources/"},
   {"commonSourceDirectory", "CommonSourceDirectory", XtRString, sizeof(char *),
         offset(commonSourceDirectory), XtRString, ""},
   {"documentDirectory", "DocumentDirectory", XtRString, sizeof(char *),
         offset(documentDirectory), XtRString, "~/wais-documents/"},
   {"helpFile", "HelpFile", XtRString, sizeof(char *),
         offset(helpFile), XtRString, "./XwaisHELP"},
   {"removeSeekerCodes", "RemoveSeekerCodes", XtRString, sizeof(char *),
      offset(removeSeekerCodes), XtRString, "On"},
   {"rescanInterval", "RescanInterval", XtRString, sizeof(char *),
      offset(rescanInterval), XtRString, "1"},
   {"seedWords", "SeedWords", XtRString, sizeof(char *),
      offset(seedWords), XtRString, ""},
   {"initialSource", "initialSource", XtRString, sizeof(char *),
      offset(initialSource), XtRString, ""},
   {"questionName", "QuestionName", XtRString, sizeof(char *),
      offset(questionName), XtRString, ""},
   {"doSearch", "DoSearch", XtRBoolean, sizeof(Boolean),
      offset(doSearch), XtRBoolean, False},
   {"defaultsInstalled", "DefaultsInstalled",  XtRBoolean, sizeof(Boolean),
      offset(defaultsInstalled), XtRBoolean, False}
};
#undef offset

void SetIcon(parent)
Widget parent;
{
  Arg args[1];
  Pixmap icon_pixmap = None;

  XtSetArg (args[0], XtNiconPixmap, &icon_pixmap);
  XtGetValues(parent, args, ONE);
  if (icon_pixmap == None) {
    XtSetArg(args[0], XtNiconPixmap, 
	     XCreateBitmapFromData(XtDisplay(parent),
				   XtScreen(parent)->root,
				   xwais_bits, xwais_width, xwais_height));
    XtSetValues (parent, args, ONE);
  }
}

static quit;

void
ReadQuestionDirectory(directory)
char *directory;
{
#ifdef SYSV
  FILE *dirp;
#else
  DIR *dirp;
#endif
  struct dirent *dp;
  char filename[MAX_FILENAME_LEN], lastchar;
  FILE *fp;
  char config[STRINGSIZE];
  int i;
  float shown;

#ifdef SYSV
  if((dirp = fopen(directory, "r")) == NULL)
#else
  if((dirp = opendir(directory)) == NULL)
#endif
    {
      char booboo[STRINGSIZE];
      sprintf(booboo, "Error on open of questions directory: %s.\n", directory);
      XwaisPrintf(booboo);
      return;
    }

  for (i = 0;
       (i < NUMQUESTS) &&
#ifdef SYSV
       (fread((char *)dp,  sizeof( *dp), 1, dirp) == 1);
#else
       ((dp = readdir(dirp))!= NULL);
#endif
       ) {
    lastchar = dp->d_name[strlen(dp->d_name)-1];
    if (lastchar != '~' &&
	lastchar != '#' &&
	strcmp(dp->d_name, ".") &&
	strcmp(dp->d_name, "..")) {
      Question_items[i] = (char *) s_malloc(STRINGSIZE);
      strcpy(Question_items[i], dp->d_name);
      i++;
    }
  }
  NumQuestions = i;

#ifdef SYSV
    fclose(dirp);
#else /* ndef SYSV */
    closedir(dirp);
#endif
}

SortQuestions(n)
int n;
{
  Boolean Changed = TRUE;
  int i;
  char *qi;

  while(Changed) {
    Changed = FALSE;
    for(i = 0; i < n-1; i++)
      if(0 < strcmp(Question_items[i], Question_items[i+1])) {
	Changed = TRUE;
	qi = Question_items[i];
	Question_items[i] = Question_items[i+1];
	Question_items[i+1] = qi;
      }
  }
}

static time_t usersourcetime, commonsourcetime, questiontime;
static int rescanint;

void ScanDirs(closure, id)
     Opaque closure;
     XtIntervalId id;
{
  char **list_data;
  float top, shown;
  int CurrentQuestion, CurrentSource, i;
  struct stat buf;
  boolean rescan;
  char string[STRINGSIZE];

  rescan = FALSE;

  stat(app_resources.userSourceDirectory, &buf);

  if(buf.st_mtime != usersourcetime) {
    usersourcetime = buf.st_mtime;
    rescan = TRUE;
  }

  if(app_resources.commonSourceDirectory[0] != 0) {
    stat(app_resources.commonSourceDirectory, &buf);

    if(buf.st_mtime != commonsourcetime) {
      commonsourcetime = buf.st_mtime;
      rescan = TRUE;
    }
  }

  if (rescan) {
    rescan = FALSE;

    CurrentSource = get_selected_source();
    if (CurrentSource != NO_ITEM_SELECTED)
      strcpy(string, Source_items[CurrentSource]);

    FreeSources(Sources);
    NumSources = 0;
    Sources = NULL;

    ReadSourceDirectory(app_resources.userSourceDirectory, TRUE);
    if(app_resources.commonSourceDirectory[0] != 0)
      ReadSourceDirectory(app_resources.commonSourceDirectory, TRUE);

    SortSources();
    Source_items = buildSItemList(Sources);

    RebuildListWidget(sourcewindow, Source_items);

    if(CurrentSource != NO_ITEM_SELECTED) {
      for(i = 0;
	  Source_items[i] != NULL && 
	  strcmp(Source_items[i], string) != 0;
	  i++);
      if(i < NumSources) XawListHighlight(sourcewindow->ListWidget, i);
    }
  }

  stat(app_resources.questionDirectory, &buf);

  if(buf.st_mtime != questiontime) {
    questiontime = buf.st_mtime;
    rescan = TRUE;
  }

  if (rescan) {
    NumQuestions = 0;

    CurrentQuestion = get_selected_question();

    if (CurrentQuestion != NO_ITEM_SELECTED)
      strcpy(string, Question_items[CurrentQuestion]);

    ReadQuestionDirectory(app_resources.questionDirectory);
    Question_items[NumQuestions] = NULL;

    SortQuestions(NumQuestions);

    RebuildListWidget(questionwindow, Question_items);

    if(CurrentQuestion != NO_ITEM_SELECTED) {
      for(i = 0;
	  Question_items[i] != NULL &&
	  strcmp(Question_items[i], string) != 0;
	  i++);
      if(i < NumQuestions) XawListHighlight(questionwindow->ListWidget, i);
    }
  }

  rescantimerid = XtAddTimeOut(rescanint, ScanDirs, (Opaque) ScanDirs);
}

ExitCommand()
{
  exit(-1);
}

PopExit(parent, message)
Widget parent;
char *message;
{
  Widget shell, frame, labelwid, stringlabelwid;
  WidgetClass wclass;
  static String namestring;
  Arg		args[5];
  Position	x, y;
  Dimension	width, height;
  Cardinal	n;

  shell = XtCreatePopupShell("exitpopup", applicationShellWidgetClass,
			     parent, NULL, ZERO);
  frame = XtCreateManagedWidget("exitpopupform", formWidgetClass,
				shell, NULL, ZERO);

  labelwid = MakeLabel(frame, "exitlabel", message, NULL, NULL);

  MakeCommandButton(frame, "Ok", ExitCommand, labelwid, NULL, NULL);

  n = 0;
  XtSetArg(args[n], XtNx, 100); n++;
  XtSetArg(args[n], XtNy, 100); n++;
  XtSetArg(args[n], XtNtitle, "XWAIS Error"); n++;
  XtSetValues(shell, args, n);

  XtPopup(shell, XtGrabExclusive);
}

char *log_file_name = NULL;
FILE *logfile = NULL;

void
main(argc, argv)
     int argc;
     char *argv[];
{
  struct stat buf;
  long first_filename_number = 1; /* for indexing into the arglist */
  long count;

  Question_items[0] = NULL;

  NumSources = 0;

  double_click = FALSE;

  top = XtInitialize( "xwais", "Xwais", NULL, 0, &argc, argv);
  
  XtGetApplicationResources(top, &app_resources, resources,
			    XtNumber(resources), NULL, 0);

  {
    Arg		args[5];
    Cardinal	n;

    n = 0;
    XtSetArg(args[n], XtNtitle, "XWAIS"); n++;
    XtSetArg(args[n], XtNiconName, "XWAIS"); n++;
    XtSetValues(top, args, n);
  }

  SetIcon(top);

  if (app_resources.defaultsInstalled == False) {
    PopExit(top, "X resources not properly installed");
    XtMainLoop();
  }

  CurDpy = XtDisplay(top);

  form = SetupWaisDisplay(top);

  if(app_resources.documentDirectory[0] == '~') {
    char *home, *dir, *getenv();
    
    if((home = getenv("HOME")) != NULL) {
      if((dir = s_malloc(strlen(home) +
		       strlen(app_resources.documentDirectory) +
		       2)) == NULL) {
	fprintf(stderr, "Ran out of space trying to create directory name.\n");
	exit(-1);
      }
      strcpy(dir, home);
      strcat(dir, &app_resources.documentDirectory[1]);
      app_resources.documentDirectory=dir;
    }
  }

  if(app_resources.userSourceDirectory[0] == '~') {
    char *home, *dir, *getenv();
    
    if((home = getenv("HOME")) != NULL) {
      if((dir = s_malloc(strlen(home) +
		       strlen(app_resources.userSourceDirectory) +
		       2)) == NULL) {
	fprintf(stderr, "Ran out of space trying to create directory name.\n");
	exit(-1);
      }
      strcpy(dir, home);
      strcat(dir, &app_resources.userSourceDirectory[1]);
      app_resources.userSourceDirectory=dir;
    }
  }

  if(app_resources.questionDirectory[0] == '~') {
    char *home, *dir, *getenv();
    
    if((home = getenv("HOME")) != NULL) {
      if((dir = s_malloc(strlen(home) +
		       strlen(app_resources.questionDirectory) +
		       2)) == NULL) {
	fprintf(stderr, "Ran out of space trying to create directory name.\n");
	exit(-1);
      }
      strcpy(dir, home);
      strcat(dir, &app_resources.questionDirectory[1]);
      app_resources.questionDirectory=dir;
    }
  }

  /* let's see if user directories exist, if not, try to create them */
  {
    DIR *dirp;
    char *makedir;

    if((dirp = opendir(app_resources.questionDirectory)) == NULL) {
      if((makedir = s_malloc(strlen(app_resources.questionDirectory) + 12))
	 == NULL) {
	fprintf(stderr, "Ran out of space trying to create directory name.\n");
	exit(-1);
      }
      strcpy(makedir, "/bin/mkdir ");
      strcat(makedir, app_resources.questionDirectory);
      if(makedir[strlen(makedir)-1] == '/') makedir[strlen(makedir)-1] = 0;
      if(system(makedir) != 0)
	fprintf(stderr, "Error creating directory: %s\n",
		app_resources.questionDirectory);
    }
    else
      closedir(dirp);

    if((dirp = opendir(app_resources.userSourceDirectory)) == NULL) {
      if((makedir = s_malloc(strlen(app_resources.userSourceDirectory) + 12))
	 == NULL) {
	fprintf(stderr, "Ran out of space trying to create directory name.\n");
	exit(-1);
      }
      strcpy(makedir, "/bin/mkdir ");
      strcat(makedir, app_resources.userSourceDirectory);
      if(makedir[strlen(makedir)-1] == '/') makedir[strlen(makedir)-1] = 0;
      if(system(makedir) != 0)
	fprintf(stderr, "Error creating directory: %s\n",
		app_resources.userSourceDirectory);
    }
    else
      closedir(dirp);
  }
  
  stat(app_resources.userSourceDirectory, &buf);
  usersourcetime = buf.st_mtime;
  ReadSourceDirectory(app_resources.userSourceDirectory, TRUE);

  if(app_resources.commonSourceDirectory[0] != 0) {
    stat(app_resources.commonSourceDirectory, &buf);
    commonsourcetime = buf.st_mtime;
    ReadSourceDirectory(app_resources.commonSourceDirectory, TRUE);
  }

  SortSources();

  Source_items = buildSItemList(Sources);

  stat(app_resources.questionDirectory, &buf);
  questiontime = buf.st_mtime;
  ReadQuestionDirectory(app_resources.questionDirectory);

  Question_items[NumQuestions] = NULL;

  SortQuestions(NumQuestions);

  RebuildListWidget(questionwindow, Question_items);

  RebuildListWidget(sourcewindow, Source_items);

  /* and away we go! */

  rescanint = 1000 * atoi(app_resources.rescanInterval);

  rescantimerid = XtAddTimeOut(rescanint, ScanDirs, (Opaque) ScanDirs);

  XtRealizeWidget(top);

  XtMainLoop();
}

void
Feep()
{
  if (CurDpy != NULL)
    XBell(CurDpy, 0);
}

/* ARGSUSED */
void
DoQuit(w, closure, call_data)
Widget w;
XtPointer closure, call_data;
{
  char msg[STRINGSIZE], quest[STRINGSIZE];

  if(double_click && LastClicked == w) {
    exit(0); 
  }

  msg[0] = 0;

  XwaisPrintf("If you really want to quit, press Quit again.\n");
  Feep();
  double_click = TRUE;
  LastClicked = w;
}
