#include <sys/types.h>
#include <sys/file.h>
#include <sys/dir.h>
#include <sys/param.h>
#include <dictionary.h>
#include <ndbm.h>
#include <errno.h>
#include <strings.h>
#include <stdio.h>
#include <dictvariables.h>
#include <dicterrors.h>
#include <dict_errs.h>
#include <ctype.h>

/*
 * wordlookup -- print the raw definitions from the dictionary which
 * 		 contain a certain word
 *
 * Options are:
 *
 * -d level	set debugging level
 * -i dir	directory dictionary is in
 * -n name	file name of index
 * -l name	file name to read file list from
 * -h		help
 */

boolean_t	debugging	= 0;
char *		directory	= DICTIONARYDIR;
char *		index_name	= INDEXNAME;
char *		list_name	= FILELIST;
char *		whoami;

extern int 	optind;
extern char *	optarg;



main(argc, argv)
int argc;
char *argv[];
{
     initialize_dict_error_table();
     
     parseArgs(argc, argv);

     if (dictInitializePaths(directory, list_name, index_name)) {
	  dict_error("initializing dictionary paths");
	  exit(dict_error_occurred);
     }

     if (dictOpenDatabaseRead()) {
	  dict_error("opening the database");
	  exit(dict_error_occurred);
     }

     for (; optind < argc; optind++) {
	  if (doWord(argv[optind])) {
	       dict_error(argv[optind]);
	       exit(dict_error_occurred);
	  }
     }

     if (dictCloseDatabase()) {
	  dict_error("closing the database");
	  exit(dict_error_occurred);
     }

     exit(0);
}



/*
 * Parse the command-line arguments and set global variables to
 * indicate what options have been selected.
 */
parseArgs(argc, argv)
int argc;
char *argv[];
{
     extern char *	optarg;
     extern int		optind;
     int		c;

     whoami = (whoami = rindex(argv[0], '/')) ? whoami + 1 : argv[0];
     
     while ((c = getopt(argc, argv, "d:i:n:l:h")) != EOF) {
	  switch (c) {
	  case 'd':
	       debugging = atoi(optarg);
	       break;
	  case 'i':
	       directory = optarg;
	       break;
	  case 'n':
	       index_name = optarg;
	       break;
	  case 'l':
	       list_name = optarg;
	       break;
	  case 'h':
	       usage();
	       exit(0);
	  default:
	       usage();
	       exit(1);
	  }
     }

     if (optind == argc) {
	  fprintf(stderr, "%s: Must specify words(s) on command line\n",
		  whoami);
	  usage();
	  exit(1);
     }
}



usage()
{
     fprintf(stderr,
	     "Usage: %s [-d level] [-i directory] [-n name] [-l name] [-h] word ...",
	     whoami);
}



doWord(word)
char *word;
{
     indexEntry_t index_entry;
     int retval;
     int i;
     char *string;
     char **matches, **ptr;
     char *str;
     char *formatted;
     
     for (str = word; *str; str++)
	  if (isupper(*str))
	       *str = tolower(*str);

     str = index(word, DICT_WILD_ONE);
     if (! str)
	  str = index(word, DICT_WILD_ANY);

     if (! str) {
	  retval = dictFetchIndexEntry(word, &index_entry);

	  if (! retval) {
	       for (i = 0; i < index_entry.num_entries; i++) {
		    retval =
			 dictFetchDefinition(index_entry.entry[i].definition,
					     &string);
		    if (retval)
			 return(retval);
		    retval = dumbFormat(string, &formatted);
		    if (retval)
			 return(retval);
		    fprintf(stdout, "%s\n", formatted);
		    free(string);
		    free(formatted);
		    continue;
	       }
	       fputc('\n', stdout);
	  }
     
	  if (retval != DICT_NOT_FOUND)
	       return(retval);

	  retval = dictSearch(word, &matches);
	  if (! retval) {
	       fprintf(stdout, "%s not found.  Perhaps you meant:\n", word);
	       dictColumnOutput(matches);
	       for (ptr = matches; *ptr; free(*ptr++));
	       free(matches);
	       fputc('\n', stdout);
	  }

	  if (retval != DICT_NOT_FOUND)
	       return(retval);

	  fprintf(stdout, "%s not found.\n\n", word);
     }
     else {
	  retval = dictMatch(word, &matches);
	  if (retval) {
	       if (retval != DICT_NOT_FOUND)
		    return(retval);
	       fprintf(stdout, "%s has no matches.\n\n", word);
	  }
	  else {
	       fprintf(stdout, "Matches for %s are:\n", word);
	       dictColumnOutput(matches);
	       for (ptr = matches; *ptr; free(*ptr++));
	       free(matches);
	       fputc('\n', stdout);
	  }
     }
	       
     return(0);
}
	       
