/* 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 _C_UTIL

#define XWAIS
#include "xwais.h"

int get_selected_item(w)
Widget w;
{
  XawListReturnStruct *selected;

  if((selected = XawListShowCurrent(w)) == NULL)
    return NO_ITEM_SELECTED;
  else return selected->list_index;
}

int listlength(list)
List list;
{
  int num;
  List l;

  for(num = 0, l = list; l != NULL; num++, l = l->nextNode);

  return num;
}

int charlistlength(list)
char **list;
{
  int num;

  if(list) {
    for(num = 0; list[num] != NULL; num++);
    return num;
  }
  else 
    return 0;
}

void
PrintStatusW(str, w)
char * str;
Widget w;
{
  XawTextBlock text;
  static XawTextPosition pos = 0;

  if(w == NULL)
    fprintf(stderr, "Couldn't display status, invalid window.\n%s", str);
  else {
    text.length = strlen(str);
    text.ptr = str;
    text.firstPos = 0;
    text.format = FMT8BIT;

    XawTextReplace(w, pos, pos, &text);

    pos += text.length;
    XawTextSetInsertionPoint(w, pos);
    XSync(XtDisplay(w), False);
  }
}

void PrintStatus(str)
char *str;
{
  PrintStatusW(str, messwidget);
}

void
XwaisPrintf(str)
char * str;
{
  PrintStatusW(str, messwidget);
}

void
ReplaceText(w, str)
Widget w;
char * str;
{
  Arg args[1];
  Cardinal numargs;

  numargs = 0;
  XtSetArg(args[numargs], XtNstring, str); numargs++;
  XtSetValues(w, args, numargs);
}


Widget
MakeCommandButton(box, name, function, vlink, hlink, data)
Widget box, vlink, hlink;
char *name;
XtCallbackProc function;
caddr_t data;
{
  Widget w;
  Arg args[10];
  Cardinal numargs;

  numargs = 0;
  if(vlink != NULL) {
    XtSetArg(args[numargs], XtNfromVert, vlink); numargs++;
  }
  if(hlink != NULL) {
    XtSetArg(args[numargs], XtNfromHoriz, hlink); numargs++;
  }
  w = XtCreateManagedWidget(name, commandWidgetClass, box, args, numargs);
  if (function != NULL)
    XtAddCallback(w, XtNcallback, function, data);
  return w;
}

Widget
MakeListWidget(parent, name, list, callback, vlink, hlink)
Widget parent, vlink, hlink;
String name;
char **list;
XtCallbackProc callback;
{
  Arg args[10];
  Cardinal numargs;
  Widget ListW;

  numargs = 0;
  if (vlink != NULL) {
    XtSetArg(args[numargs], XtNfromVert, vlink); numargs++;
  }
  if (hlink != NULL) {
    XtSetArg(args[numargs], XtNfromHoriz, hlink); numargs++;
  }
  XtSetArg(args[numargs], XtNhorizDistance, 0); numargs++;
  XtSetArg(args[numargs], XtNlist, list); numargs++;
  XtSetArg(args[numargs], XtNforceColumns, True); numargs++;
  XtSetArg(args[numargs], XtNdefaultColumns, 1); numargs++;
  ListW = XtCreateManagedWidget(name, listWidgetClass,
				parent, args, numargs);

  if (callback != NULL) XtAddCallback(ListW, XtNcallback, callback, NULL);

  return ListW;
}  

void RebuildListWidget(s, list)
ScrollList s;
String *list;
{
  String t[1];
  Widget p = XtParent(s->ListWidget);

  t[0] = NULL;
  XtDestroyWidget(s->ListWidget);
  s->ListWidget = MakeListWidget(p, s->name, t, s->callback, NULL, NULL);
  if (list != NULL) XawListChange(s->ListWidget, list, 0, 0, True);
}

ScrollList
MakeScrollList(parent, name, items, callback, vlink, hlink)
Widget parent, vlink, hlink;
XtCallbackProc callback;
String name, *items;
{
  Arg arglist[10];
  Cardinal num_args;
  static char names[STRINGSIZE];
  ScrollList result;

  result = (ScrollList) s_malloc(sizeof(_ScrollList));

  result->name = s_strdup(name);
  result->callback = callback;

  num_args = 0;
  if(vlink != NULL) {
    XtSetArg(arglist[num_args], XtNfromVert, vlink); num_args++;
  }
  if(hlink != NULL) {
    XtSetArg(arglist[num_args], XtNfromHoriz, hlink); num_args++;
  }
  XtSetArg(arglist[num_args], XtNorientation, XtorientVertical); num_args++;
  result->ListWidget = MakeListWidget(parent, name, items, 
				      callback, vlink, NULL);

  return(result);
}

Widget 
MakeStringBox(parent, name, string, vlink, hlink)
Widget parent, vlink, hlink;
String name, string;
{
  Arg args[5];
  Cardinal numargs = 0;
  Widget StringW;

  XtSetArg(args[numargs], XtNeditType, XawtextEdit); numargs++;
  XtSetArg(args[numargs], XtNstring, string); numargs++;
  if(vlink != NULL) {
    XtSetArg(args[numargs], XtNfromVert, vlink); numargs++;
  }
  if(hlink != NULL) {
    XtSetArg(args[numargs], XtNfromHoriz, hlink); numargs++;
  }

  StringW = XtCreateManagedWidget(name, asciiTextWidgetClass, 
				  parent, args, numargs);
  return(StringW);  
}
 
/*	Function Name: GetString
 *	Description: retrieves the string from a asciiText widget.
 *	Arguments: w - the ascii text widget.
 *	Returns: the filename.
 */

String
GetString(w)
Widget w;
{
  String str;
  Arg args[1];
  
  XtSetArg(args[0], XtNstring, &str);
  XtGetValues( w, args, ONE);
  return(str);
}

Widget MakeLabel(parent, name, label, vlink, hlink)
Widget parent, vlink, hlink;
char *name, *label;
{
  Arg args[5];
  Cardinal numargs;
  Widget labelwid;

  numargs = 0;
  XtSetArg(args[numargs], XtNlabel, label); numargs++;
  if(vlink != NULL) {
    XtSetArg(args[numargs], XtNfromVert, vlink); numargs++;
  }
  if(hlink != NULL) {
    XtSetArg(args[numargs], XtNfromHoriz, hlink); numargs++;
  }
  XtSetArg(args[numargs], XtNborderWidth, 0); numargs++;
  labelwid = XtCreateManagedWidget(name,labelWidgetClass, 
				   parent, args, numargs);
  return(labelwid);
}

#define BEFORE 1
#define DURING 2
#define QUOTE 5

/* ripped out of gmacs-ui.c */
int find_string_slot(source, key, value, value_size, delete_internal_quotes)
char *source, *key, *value;
long value_size;
boolean delete_internal_quotes;
{
  char ch;
  short state = BEFORE;
  long position = 0;  /* position in value */
  char *pos =strstr(source, key); /* address into source */

  value[0] = '\0';		/* initialize to nothing */

  if(NULL == pos)
    return(1);

  for(pos = pos + strlen(key); pos < source + strlen(source); pos++){
    ch = *pos;
    if((state == BEFORE) && (ch == '\"'))
      state = DURING;
    else if ((state == DURING) && (ch == '\\')){
      state = QUOTE;	
      if(!delete_internal_quotes){
	value[position] = ch;
	position++;
	if(position >= value_size){
	  value[value_size - 1] = '\0';
	  return(-1);
	}
      }
    }
    else if ((state == DURING) && (ch == '"')){	
      value[position] = '\0';
      return(0);
    }
    else if ((state == QUOTE) || (state == DURING)){
      if(state ==  QUOTE)
	state = DURING;
      value[position] = ch;
      position++;
      if(position >= value_size){
	value[value_size - 1] = '\0';
	return(-1);
      }
    }
    /* otherwise we are still before the start of the value */
  }
  value[position] = '\0';
  return(-1); /* error because we are in the middle of the string */
}

void find_value(source, key, value, value_size)
char *source, *key, *value;
int value_size;
{
  char ch;
  long position = 0;  /* position in value */
  char *pos =strstr(source, key); /* address into source */

  value[0] = '\0';		/* initialize to nothing */

  if(NULL == pos)
    return;

  pos = pos + strlen(key);
  ch = *pos;
  /* skip leading quotes and spaces */
  while((ch == '\"') || (ch == ' ')) {
    pos++; ch = *pos;
  }
  for(position = 0; pos < source + strlen(source); pos++){
    if((ch = *pos) == ' ') {
      value[position] = '\0';
      return;
    }
    value[position] = ch;
    position++;
    if(position >= value_size){
      value[value_size - 1] = '\0';
      return;
    }
  }
  value[position] = '\0';
}

void SortSources()
{
  Boolean Changed = TRUE;
  Source s;
  SList sl;

  while(Changed) {
    Changed = FALSE;
    for(sl = Sources; sl->nextSource != NULL; sl = sl->nextSource) {
      if(sl->nextSource->thisSource->name == NULL) {
	Changed = TRUE;
	sl->nextSource = sl->nextSource->nextSource;
      }
      else
	if(0 < strcmp(sl->thisSource->name, sl->nextSource->thisSource->name)) {
	  Changed = TRUE;
	  s = sl->thisSource;
	  sl->thisSource = sl->nextSource->thisSource;
	  sl->nextSource->thisSource = s;
	}
    }
  }
}

char *
get_filename(name)
char* name;
{
  char *result, *loc;
  long i;

  loc = strchr(name,' ');
  if (loc == NULL) return name;

  i = (long)loc - (long)name;
  
  result = s_malloc(i+1);
  strncpy(result, name, i);
  result[i] = 0;
  return result;
}

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

extern int alphasort();

char **
GetDirNames(directory)
char *directory;
{
  char **result;
  struct dirent **list;
  int i, j;

  if ((j = scandir(directory, &list, NULL, alphasort)) < 0) {
      char booboo[STRINGSIZE];
      sprintf(booboo, "Error on open of source directory: %s.\n", directory);
      PrintStatus(booboo);
      return NULL;
    }

  result = (char**) s_malloc((j+1) * sizeof(char*));

  for (i = 0; i < j; i++) {
    result[i] = s_strdup(list[i]->d_name);
    s_free(list[i]);
  }
  s_free(list);
  return result;
}
