
#include "closed.h"
#include "xthesaurus.h"
#include "hash.h"
#include <ctype.h>
#include <ndbm.h>
#include <ctype.h>
#include <sys/file.h>
#include <X11/keysym.h>

#define DEPTH 12


/* this is modeled to be like xwebster...  so 
great huge chunks of it are swiped from xwebster.  

*/


char *whoami;
Display *dpy;
int screen; 
GC gc, erase_gc;
XFontStruct *fontp;
XContext defwindow;
int fontwidth;
int fontheight;
int current_x, current_y;

Window help_window = (Window) NULL;

void Thesaurus_Set_Current_Size();
void Set_Default_Geometry();
void Typewriter();
void RTLib_Set_Initial_Geometry();
void RTLib_Create_Window();
void RTLib_Set_Properties();
Window Help();
struct sizes *popup();
void New_Word_Window();
void Punt_Window();
void Move_Window();
void Thesaurus_New_Character();
void Redisplay_Word();
char *lookup() ;
char* literal_search();
long pdb_fetch();
struct {
     int x, y;
     int xneg, yneg;
} initial_geometry;

struct sizes icons, wwindows, parents;

#define PROMPT "Word: "		/* prompt string in word window */
#define PROMPTLEN 6		/* why run strlen when I can count */
#define LEFT_MARGIN	5	/* 5-pixel left margin */
#define SHOW_SIZE		/* show the size of the window when resizing */

/* from init.c */
extern int rvflag;
extern int nohelpflag;

/*
 * points to our current position in wwindows.definition, which is actually
 * the current word.
 */
char *curword = (char *) NULL;

/* deal with the strings of the definition we're working on */
char *curstash = (char *) NULL;
char *curptr = (char *) NULL;	
int howlong = 0;		/* length of definition so far,in characters */
int maxdeflen = 0;		/* how much memory have we allowed? */

DBM* db;

void
define(word)
     char *word;
{
  char *string;

  string = lookup(word);
  
  popup("synonyms", string);
}

DBM* openlib()
{

  db = dbm_open(OFFSETSFILE, O_RDONLY, 0);
  return db;
}

main(argc, argv)
	int argc;
	char *argv[];
{
     XEvent  ev;
     XEvent	*xevent;
     struct sizes *stash;

     if ( openlib() == NULL ) {
       printf("Can't open thesaurus library file\n");
       exit(-1);
     }
     whoami = (whoami = rindex(argv[0], '/')) ? whoami + 1 : argv[0];

     RTLib_Initialize(whoami, &argc, argv);

     parents.win = RTLib_Parent_Window();

     RTLib_Parent_Size(parents.win, &parents.cur_width,
		       &parents.cur_height);
	
     /* give me the context number, please */

     defwindow = XUniqueContext();
	
     RTLib_Set_GC();
     	
     Create_Icon(argc, argv);

     XSelectInput(dpy, icons.win,
		  ExposureMask | StructureNotifyMask |
		  ButtonPressMask | ButtonReleaseMask);

     XMapWindow(dpy, icons.win);
     
     wwindows.win = 0;

     xevent = &ev;

     for(;;)      {
       Window ewindow;

       XNextEvent(dpy, xevent);
       ewindow = xevent->xany.window;

       if (XFindContext(dpy, ewindow, defwindow, (char **)&stash)
	   != 0)
	 continue;
		
	
       if(ewindow == icons.win) {
	 switch(xevent->type) {
	 /*case Expose:*/  /* bitmap is the background, so we don't worry*/
     
	 case ButtonRelease: 
	   switch (((XButtonReleasedEvent *)
		    xevent)->button)    {
	   case Button1:
	     if (! help_window)
	       help_window = Help();
	     break;
	   case Button2:
	     /* new word window */
	     New_Word_Window(&wwindows);
	     break;
	     
	   case Button3:
	     exit(0);
	     break;

	   default:
	     break;
	   }
	   break;

	 case ConfigureNotify:
	   Thesaurus_Set_Current_Size(xevent->xconfigure, stash);
	   break;
	 }
       }
       else if (ewindow == wwindows.win)
	  {			/* do word window processing */
	       switch(xevent->type & 0x7f)
	       {
	       case Expose:
		    if (xevent->xexpose.count == 0)
			 Redisplay_Word(stash);
		    break;

	       case ButtonRelease:
		    switch (((XButtonReleasedEvent *)
			     xevent)->button)
		    {
		    case Button1:
		    case Button2:
		    case Button3:
			 Punt_Window(stash, True);
			 break;
		    default:
			 break;
		    }
		    break;
				
	       case ConfigureNotify:
		    Thesaurus_Set_Current_Size(xevent->xconfigure,
					     stash);
		    break;
				
	       case KeyPress:
		    if (xevent->xany.window == wwindows.win)
			 Thesaurus_New_Character(&(xevent->xkey));
		    break;
			
	       default:
		    break;
	       }
	  }
	  else {		/* must be a definition window */
	       switch(xevent->type & 0x7f)
	       {
	       case Expose:
					
		    if (xevent->xexpose.count == 0)
			 Typewriter(stash);
		    break;

	       case ButtonRelease:
		    switch (((XButtonReleasedEvent *)
			     xevent)->button)
		    {
		    case Button1:
		    case Button2:
		    case Button3:
			 Punt_Window(stash, False);
			 if (ewindow == help_window)
			      help_window = (Window) NULL;
			 break;
		    default:
			 break;
		    }
		    break;
	       case ConfigureNotify:
		    Thesaurus_Set_Current_Size(xevent->xconfigure,
					     stash);
		    break;

	       case KeyPress:{
		    KeySym keysym = XKeycodeToKeysym(dpy, xevent->xkey.keycode,0);
		    Move_Window(keysym, xevent->xkey.window); 
		  }
		 break;
		      
	       default:
		    break;
	       }
	  }
     }
   }

void Move_Window(keysym, window)
     KeySym keysym;
     Window window;
{
  XWindowAttributes attr;

  XGetWindowAttributes(dpy, window, &attr);  
  if(keysym == XK_Down) 
    XMoveWindow(dpy, window,
	      attr.x,
	      attr.y + 100);
  else if(keysym == XK_Up)
    XMoveWindow(dpy, window,
		attr.x,
		attr.y - 100);

}
  
void
Set_Default_Geometry(stash, width, height)
	struct sizes *stash;
	unsigned int width, height;
{
	stash->min_width = stash->desired_width = width;
	stash->min_height = stash->desired_height = height;

	stash->desired_x = 0;
	stash->desired_y = parents.cur_height - (stash->desired_height
						 + (2 * RTLib_border_width()));
}



/* Set the current window width and height
 *   based on information from the ConfigureNotify event
 */

void
Thesaurus_Set_Current_Size(xconfigure, stash)
	XConfigureEvent  xconfigure;
	struct sizes *stash;
{
	stash->cur_width = xconfigure.width;
	stash->cur_height = xconfigure.height;
}

Create_Icon(argc, argv)
int argc;
char **argv;
{
     Pixmap iconpix;

     /* Get the geometry parameters specified on the command line */
     RTLib_Get_Initial_Geometry(&initial_geometry.x,
				&initial_geometry.y,
				&initial_geometry.xneg,
				&initial_geometry.yneg);
     
     /* used as the icon window's tile and icon */
     iconpix = RTLib_Create_Pixmap(closed_bits, (unsigned int) closed_width,
				   (unsigned int) closed_height);

     /* Deal with the default initial geometry */
     /* make the icon window exactly the size of its tile */

     icons.min_width = icons.desired_width = closed_width;
     icons.min_height = icons.desired_height = closed_height;

     if (initial_geometry.xneg)
	  icons.desired_x = parents.cur_width - icons.desired_width -
	       2 * RTLib_border_width() - initial_geometry.x;
     else
	  icons.desired_x = initial_geometry.x;
    if (initial_geometry.yneg)
	  icons.desired_y = parents.cur_height - icons.desired_height -
	       2 * RTLib_border_width() - initial_geometry.y;
     else
	  icons.desired_y = initial_geometry.y;

     /* Make sure it stays on screen */

     if ((icons.desired_x + icons.desired_width + 2 * RTLib_border_width())
	 > parents.cur_width) {
	  icons.desired_x = parents.cur_width - icons.min_width -
	       2 * RTLib_border_width();
	  icons.desired_width = icons.min_width;
	  if (initial_geometry.xneg)
	       initial_geometry.x = 0;
	  else
	       initial_geometry.x = icons.desired_x;
     }
      if ((icons.desired_y + icons.desired_height + 2 * RTLib_border_width())
	 > parents.cur_height) {
	  icons.desired_y = parents.cur_height - icons.min_height -
	       2 * RTLib_border_width();
	  icons.desired_height = icons.min_height;
	  if (initial_geometry.yneg)
	       initial_geometry.y = 0;
	  else
	       initial_geometry.y = icons.desired_y;
     }
     
     if (icons.desired_x < 0) {
	  icons.desired_x = 0;
	  icons.desired_width = icons.min_width;
	  if (initial_geometry.xneg)
	       initial_geometry.x = parents.cur_width -
		    icons.desired_x - 2 * RTLib_border_width();
	  else
	       initial_geometry.x = 0;
     }
     if (icons.desired_y < 0) {
	  icons.desired_y = 0;
	  icons.desired_height = icons.min_height;
	  if (initial_geometry.yneg)
	       initial_geometry.y = parents.cur_height -
		    icons.desired_y - 2 * RTLib_border_width();
	  else
	       initial_geometry.y = 0;
     }
     
     RTLib_Set_Initial_Geometry(&icons);
     RTLib_Create_Window(&icons);
     RTLib_Set_Properties(argv, argc, &icons, &iconpix, False);

     XSetWindowBackgroundPixmap(dpy, icons.win, iconpix);
}

Window
Help()
{
     struct sizes *retwin;
     
     int memerror();
     /* carefully set up beforehand, you bet */	
     char *string, *message = "XTHESAURUS INSTRUCTIONS:\n\n\
In the icon window:\n\
      Clicking the left button will get you this help message;\n\
      Clicking the middle button will pop up a 'word window';\n\
      Clicking the right button will cause xthesaurus to exit.\n\n\
In the word window:\n\
      Type in your word.  Control-C will clear everything you've\n\
      entered, and the backspace key works normally.  Hit Return when\n\
      you're done entering the word.  xthesaurus will pop up a\n\
      'synonym window' with synonyms of your word.\n\n\
      Clicking any button in the word window will cause it to disappear.\n\n\
In the synonym window:\n\n\
      Clicking any button in the synonym window will cause it to\n\
      disappear.\n\n\
      If the window is larger than the screen, the up and down arrows will\n\
      move the window up and down.\n\n\
If you're using an RT, which has no middle button, press both the\n\
buttons simultaneously instead.\n\n\
Clicking any button in this window will cause it to disappear.\n\n";

     string = malloc((unsigned) sizeof (char *) * (strlen(message) + 1));
     if (string == (char *) NULL)
	  memerror();
	
     strcpy(string, message);
	
     retwin = popup("Help", string);
     return (retwin ? retwin->win : (Window) NULL);
}

struct sizes *
popup(word, defarray)
	char *word, *defarray;
{
	int i = 0;
	int memerror();
	void Typewriter();
	void RTLib_Set_Initial_Geometry();
	void RTLib_Create_Window();
	void RTLib_Set_Properties();
	register char *cp = defarray;
	struct sizes *newwin = (struct sizes *) malloc((unsigned)
						       sizeof(struct sizes));
	if (newwin == (struct sizes *) NULL)
		memerror();
	else {
		newwin->definition = malloc ((unsigned) sizeof (char *));
		if (newwin->definition == (char *) NULL)
			memerror();
	}

	/*
	 * figure out how many lines (\n) there are in defarray.
	 * Multiply by max_height of font to get the height.  No line
	 * is more than 80 chars long, so 80 + (2 * LEFT_MARGIN) is
	 * the width.  default_x_pos is 0; default_y_pos is
	 * parent_height - icon_window_height - desired_height (ie,
	 * stack the definition just above the default icon window
	 * position).
	 */
	while ((cp = index(cp, '\n')) != (char *) NULL)
	       {
		       i++;
		       cp++;
	       }
	/* i + 2, for 1 blank line at the top and one at the bottom */
	newwin->desired_height = newwin->min_height = (i + 2)
		* fontheight;
	newwin->desired_width = newwin->min_width = (80 * fontwidth)
		+ (2 * LEFT_MARGIN);

	/* Give this the same geometry as the icon, offset so as not */
	/* to block it.						     */
	
	if (initial_geometry.xneg)
	     newwin->desired_x = parents.cur_width - newwin->min_width -
		  - initial_geometry.x - 2 * RTLib_border_width();
	else
	     newwin->desired_x = initial_geometry.x;

	if (initial_geometry.yneg)
	     newwin->desired_y = parents.cur_height - newwin->min_height -
		  icons.cur_height - initial_geometry.y -
		       4 * RTLib_border_width();
	else
	     newwin->desired_y =  initial_geometry.y + icons.cur_height +
		  2 * RTLib_border_width();
	
		
	/* Now make sure as much as possible is on the screen. */
	on_screen(newwin);
	newwin->definition = defarray;
	newwin->win_name = word;

	/* go and do thou likewise */
	RTLib_Set_Initial_Geometry(newwin);
	RTLib_Create_Window(newwin);
	RTLib_Set_Properties((char **)NULL, 0, newwin, (Pixmap *) NULL, True);
	XSelectInput(dpy, newwin->win, ExposureMask | StructureNotifyMask | 
		     KeyPressMask | ButtonPressMask | ButtonReleaseMask);
	XMapWindow(dpy, newwin->win);
	Typewriter(newwin);

	/* clean up the old definition */
	howlong = maxdeflen = 0;
	curstash = (char *) NULL;

	return(newwin);
} 

void
New_Word_Window(stash)
	struct sizes *stash;
{
	int memerror();
	unsigned int width, height;

	if (stash->win != 0)
		/*
		 * lost it, forgot it, something.  Anyway, punt it and
		 * start fresh.
		 */
		Punt_Window(stash, True);


	/*
	 * never let the word window get too small for a
	 * 20-letter word (really not that big), plus the prompt, plus
	 * a 10-pixel margin.
	 */
	{
		char *str = "20202020202020202020";
			
		width = 10 + XTextWidth(fontp, str, strlen(str)) +
			XTextWidth(fontp, PROMPT, PROMPTLEN);
		height = 10 + fontheight;
	}

	stash->min_width = stash->desired_width = width;
	stash->min_height = stash->desired_height = height;
	
	/* Put the word window to the right of the icon if the icon is */
	/* based at the left margin, or to the left of the icon if the */
	/* icon is based at the right margin.			       */

	if (initial_geometry.xneg)
	     stash->desired_x = parents.cur_width - width -
		  icons.cur_width - initial_geometry.x -
		       4 * RTLib_border_width();
	else
	     stash->desired_x = initial_geometry.x + icons.cur_width +
		  2 * RTLib_border_width();

	/* If the icon is based at the top margin, align the word */
	/* window with the top of the icon; if it is based at the */
	/* bottom, align the word with the bottom.		  */
	if (initial_geometry.yneg)
	     stash->desired_y = parents.cur_height - initial_geometry.y -
		  height - 2 * RTLib_border_width();
	else
	     stash->desired_y = initial_geometry.y;

	/* Now make sure it's totally on-screen */

	on_screen(stash);
	
	/*
	 * fiddle a bit with stash->desired_x; we want it to be to the
	 * right of the icon window.
	 */
	RTLib_Set_Initial_Geometry(stash);
	current_x = LEFT_MARGIN;
	current_y = stash->cur_height - (fontheight / 2);

	/* set the "name" of the window, for the icon */
	stash->win_name = "Word Window";
	
	/* 1024 characters ought to be enough for any word */
	curword = wwindows.definition = malloc((unsigned) sizeof(char *)
					      * BUFSIZ);
	if (curword == (char *) NULL)
		memerror();
	
	RTLib_Create_Window(stash);
	RTLib_Set_Properties((char **) NULL, 0, stash, (Pixmap *) NULL, True);

	XSelectInput(dpy, stash->win, ExposureMask |
		     StructureNotifyMask | ButtonPressMask |
		     ButtonReleaseMask | KeyPressMask);
	XMapWindow(dpy, stash->win);
	XDrawString(dpy, stash->win, gc, current_x, current_y,
		    PROMPT, PROMPTLEN);
	current_x = LEFT_MARGIN + (PROMPTLEN * fontwidth);
}

/*
 * if flag is true, we are dealing with a non-malloc'ed structure (ie,
 * wwindows), and may not free it.
 */
void
Punt_Window(stash, flag)
	struct sizes *stash;
	int flag;
{
	if (stash->definition) {
		free(stash->definition);
		stash->definition = (char *) NULL;
	}
	XDeleteContext(dpy, stash->win, defwindow);
	if (stash->win) {
		XDestroyWindow(dpy, stash->win);
		stash->win = 0;
	}
	if (!flag)
		free((char *)stash);
}

on_screen(stash)
struct sizes *stash;
{
     if ((stash->desired_x + stash->desired_width + 2 * RTLib_border_width())
	 > parents.cur_width) {
	  stash->desired_x = parents.cur_width - stash->min_width -
	       2 * RTLib_border_width();
	  stash->desired_width = stash->min_width;
     }
     if ((stash->desired_y + stash->desired_height + 2 * RTLib_border_width())
	 > parents.cur_height) {
	  stash->desired_y = parents.cur_height - stash->min_height -
	       2 * RTLib_border_width();
	  stash->desired_height = stash->min_height;
     }
     if (stash->desired_x < 0) {
	  stash->desired_x = 0;
	  stash->desired_width = stash->min_width;
     }
     if (stash->desired_y < 0) {
	  stash->desired_y = 0;
	  stash->desired_height = stash->min_height;
     }
}


void
Typewriter(stash)
	struct sizes *stash;
{
	int memerror();
	register char *cp, *print, *scrap;
	register int cur_x, cur_y;
	
	scrap = malloc((unsigned) sizeof (char)
		       * (strlen(stash->definition) + 1));
	if (scrap == (char *) NULL)
		memerror();
	
	(void)strcpy(scrap, stash->definition);
	
	cp = print = scrap;
	cur_x = LEFT_MARGIN;
	/*
	 * fontheight * 2; once for the font, and once for the blank
	 * line.  Sometimes I'd like to hang the person who created
	 * X11's notion of geometry from the highest yardarm available.
	 */
	cur_y = fontheight * 2;
	/*
	 * Don't bother clearing the window -- the first expose event will do
	 * that for us.
	 */
	while ((cp = index(cp, '\n')) != (char *) NULL)
	{
		*cp++ = '\0';
		XDrawString(dpy, stash->win, gc, cur_x, cur_y,
			    print, strlen(print));
		print = cp;
		cur_y += fontheight;
	}
	free(scrap);
}


/* this adds a new character to the word window */

void
Thesaurus_New_Character(key)
	XKeyEvent *key;
{
	int i;
	char *st, askey[10], toscreen[2];
	void define();
	
	i = XLookupString(key, askey, sizeof(askey), NULL, NULL);

	if (i == 0)
		/* it's a zero-length string, so don't worry about it */
		return;
	
	for (st = askey; i > 0; i--)
	{
		/* stash it */
		toscreen[0] = *st++;
		toscreen[1] = '\0';
		/* Is it ^C?
		 * If so, clear the window,
		 * 	redraw the prompt,
		 * 	set curword back to the beginning of
		 * 	wwindows.definition, and reset current_x.
		 */
		if (toscreen[0] == '\003')
		     clear_word();
		/*
		 * If it's ^? (backspace):
		 * 	current_x -= width,
		 * 	if (rvflag is set)
		 * 		use our special gc (black foreground &
		 * 			background),
		 * 		print a blank,
		 * 	else
		 * 		print a blank,
		 * 	do NOT update current_x,
		 * 	decrement curword.
		 *
		 * We also make sure that we aren't trying to
		 * backspace off of the front end of wwindows.definition.
		 */
		else if (toscreen[0] == '\177')
		     erase_character();
		/* Is it \n or \r?
		 * If so, end the wwindows.definition with \0 and
		 * check the length.  If it's greater than 0,
		 *      search... 
		 * 	then clear the word window and wwindows.definition,
		 * 	and reset current_x appropriately.
		 * else, fweep.
		 */
		else if ((toscreen[0] == '\n') || (toscreen[0] == '\r'))
		{
		        int len;
		     
			*curword = '\0';
			curword = wwindows.definition;
			/*
			 * Delete any blank spaces at the end of the
			 * word.
			 */
			while ((len = strlen(curword)) &&
			       (curword[len - 1] == ' '))
			     curword[len - 1] = '\0';
			if (strlen(curword))
			{
				define(curword);
				XClearWindow(dpy, wwindows.win);
				curword[0] = '\0';
				XDrawString(dpy, wwindows.win, gc, LEFT_MARGIN,
					    current_y, PROMPT, PROMPTLEN);
				current_x = LEFT_MARGIN +
					(PROMPTLEN * fontwidth);
				/*
				 * the old definition will be freed
				 * when its window is punted.
				 * curstash and curword should have
				 * already been reset, and will get
				 * more memory inside Define_Word, if
				 * they need it, so we don't deal with
				 * them here.
				 */
			} else
				XBell(dpy, 90);
		} 
		/* Is it an (upper- or lower-case) character?
		 * If so, add it to wwindows.definition,
		 * 	print it on the screen,
		 * 	and increment current_x appropriately.
		 */
		else if (isalpha(toscreen[0]) || toscreen[0] == '*' ||
			 toscreen[0] == '?' || toscreen[0] == '-' ||
			 toscreen[0] == ' ')
		{
			*curword++ = toscreen[0];
			XDrawString(dpy, wwindows.win, gc, current_x,
				    current_y, toscreen, 1);
			current_x += fontwidth;
		} 
		/* Else, fweep. */
		else
			XBell(dpy, 90);

	} 
	return;
} 

/*
 * Draw stash->definition (assumed to be one word), vertically
 * centered in the word window.
 */

void
Redisplay_Word(stash)
	struct sizes *stash;
{
	/* so that it's a null-terminated string, but don't increment,
	 * so that we can overwrite this when we get the next char. */
	*curword = '\0';
	/* looks like a handy time to recenter */
	current_y = stash->cur_height / 2;

	/* draw the prompt */
	XDrawString(dpy, stash->win, gc, LEFT_MARGIN, current_y,
		    PROMPT, PROMPTLEN);
	/* draw the word, if not null */
	if (*stash->definition != '\0')
		XDrawString(dpy, stash->win, gc, (LEFT_MARGIN +
						  (PROMPTLEN * fontwidth)),
			    current_y, stash->definition,
			    strlen(stash->definition));
}


clear_word()
{
     XClearWindow(dpy, wwindows.win);
     curword = wwindows.definition;
     XDrawString(dpy, wwindows.win, gc, LEFT_MARGIN,
		 current_y, PROMPT, PROMPTLEN);
     current_x = LEFT_MARGIN + (PROMPTLEN * fontwidth);
}


erase_character()
{
     char delt;
     
     /* Assumes fixed width font; Hell, the whole program does.  Fix */
     /* at some point in the future. 				     */
     if (curword - wwindows.definition) {
	  current_x -= fontwidth;
	  delt = *(--curword);
#ifdef DRAW_IMAGE_STRING
	  XDrawImageString(dpy, wwindows.win, erase_gc, current_x, current_y,
			   &delt, 1);
#else
	  XDrawString(dpy, wwindows.win, erase_gc, current_x, current_y,
		      &delt, 1);
#endif
     }
     else
	  XBell(dpy, 90);
}


memerror()
{
  puts("AAAAARRRRGHHHHHH!!!! Out of memory!!! ");
  exit(-1);
}


char* literal_search(word)
char* word;
{
  int entries[20];
  int count, i;
  int roget;

  char* ret_str;

  int cur_ptr = 0;
  int str_size = 1;
  ret_str = (char*)malloc(1); 

  count = get_entries(word, entries);

  if(!count) return("No matches found");
  
  roget = open(ROGETFILE, O_RDONLY, 0);

  for(i = 0; i < count; i++) {
    long offset;
    long nextoffset;
    int ent_size;
    int recs, tries = 0;

    offset = pdb_fetch(db,entries[i]);
    nextoffset = pdb_fetch(db, entries[i]+1);

    /* kludge.  we're at the end, hope the last entry fits in 10k*/
    if(nextoffset == -1) nextoffset = offset+10240; 
    ent_size = nextoffset - offset;
    str_size += ent_size;
    ret_str = (char*)realloc(ret_str, str_size);

/*    printf("%d %ld %ld %d\n", entries[i], offset, nextoffset, ent_size);*/
    lseek(roget, offset, L_SET);
    while((recs = read(roget, &ret_str[cur_ptr], ent_size)) == 0  && tries < 10)
      tries++;
/*    printf("%d = recs\n",recs);*/

    if(recs == EOF || tries == 10) {
      close(roget);
      return("Error trying to read  roget.txt");
    }
    cur_ptr += (recs);
    ret_str[cur_ptr] = 0;
/*    puts("****this is ret_str*****");
    puts(ret_str);
    puts("******this is ret_str[cur_ptr]*****");
    puts(&ret_str[cur_ptr]);
*/
  }
  ret_str[cur_ptr] = 0;
  close(roget);
  return ret_str;
}


char *lookup(word)
char *word;
{

  long indx = NULL;
  char *str;

  lower(word);
  if ( isliteral (word) ) {
    str = literal_search(word);
  } else {
    indx = glob_search(word);
    str = "Glob searching not implemented yet\n";
  }
  return str;
}


/*
literal_search(word)
char *word;
{
  int limit; 
  int indx;

  if((indxfptr = fopen(INDXFILE, "r")) == NULL) {
    popup("Error","Can't open thesaurus index file\n");   
    exit(-1);
  }

  fseek(indxfptr, 0, 2);
  debug_printf("%d = size\n", ftell(indxfptr));
  limit = ftell(indxfptr) / sizeof(struct entry_s);

  debug_printf("%d = limit\n", limit);

  indx = getindex(indxfptr, word, limit); 
  fclose(indxfptr);
  return indx;
}
*/

/* dummies */
int isliteral (word)
char *word;
{
  return (!(index(word, '*') || index(word, '?')));
}

glob_search()
{
}

long pdb_fetch(db, entry)
    DBM* db;
{
  datum data;
  char temp[20];
  sprintf(temp, "%d", entry);
  data = dbm_fetch(db, temp, strlen(temp));
  if(data.dsize == 0) return -1;
  bcopy( data.dptr, temp, data.dsize);
  return atol(temp);
}


get_entries(word, entries)
     char* word;
     int *entries;
{
  FILE* fptr;
  char buffer[1024];
  int filesize, partsize, location;
  int i, cmp;
  if(!(fptr = fopen(WORDINDEX, "r")))
    perror("fopen");

  lower(word);
  fseek(fptr, 0L, 2);
  filesize = ftell(fptr);
  partsize = filesize/2;
  location = partsize;
  fseek(fptr, location, 0);

  /* narrow down the search by binary splitting*/
  for(i = 0; i < DEPTH; i++) {
    
    if (location != 0) {
      /* if it's not at the beginning, eat a line first*/
      if(!fgets(buffer,1024,fptr)) return 0;
    }
    
    if(!fgets(buffer,1024,fptr))  return 0; /* get a word*/
    *index(buffer, ':') = 0;
    lower(buffer);

    cmp = strcmp(word, buffer);
    partsize /= 2;
    if(cmp > 0) 
      location += partsize;
    else
      location -= partsize;
    fseek(fptr,location, 0);
  }
  
  location -= partsize;
  if(location < partsize || location < 0) location = 0;
  fseek(fptr,location, 0);


  /* linear search*/
  if (location != 0) {
    /* if it's not at the beginning, eat a line first*/
    if(!fgets(buffer,1024,fptr))
      return 0;
  }
  
  for(;;) {
    if(!fgets(buffer, 1024, fptr)) return 0;
    *index(buffer, ':') = 0;
    lower(buffer);
    cmp = strcmp(word, buffer);
    if(cmp < 0) return 0; /* overpassed where it would be*/
    if(cmp == 0) { /* found it*/
      return chars2ints(buffer + strlen(buffer) + 1, entries);
    }
  }
  
}

chars2ints(str, entries)
char* str;
int* entries;
{
  int count = 0;
  for(;;) {
    while(*str && isspace(*str)) str++;
    if(!*str) return count;
    *entries = atoi(str);
    entries++;
    count++;
    while(*str && !isspace(*str)) str++;
    if(!*str) return count;
  }
}

lower(word)
     char* word;
{

  while(*word) {
    if(isupper(*word)) {
      *word = toupper(*word);
    }
    word++;
  }
}
