/*
 * This file is part of the OLH system.
 *
 *      Lucien Van Elsen
 *	MIT Project Athena
 *
 * Copyright (C) 1990 by the Massachusetts Institute of Technology.
 * For copying and distribution information, see the file "mit-copyright.h".
 *
 *	$Source: /afs/sipb.mit.edu/project/sipb-athena/repository/src/olh/ascii/get_keyword.c,v $
 *	$Id: get_keyword.c,v 1.1 1993/10/12 05:44:53 probe Exp $
 *	$Author: probe $
 */

#ifndef lint
#ifndef SABER
static char *RCSid = "$Header: /afs/sipb.mit.edu/project/sipb-athena/repository/src/olh/ascii/get_keyword.c,v 1.1 1993/10/12 05:44:53 probe Exp $";
#endif
#endif

#include "olh.h"
#include "help.h"

#define MAX_KEYWORD_LEN		70
int
get_keyword( )
{
  int done = FALSE;
  char* ptr = current_input;
  char ch;
  int pos = -1;
  char buffer[MAX_KEYWORD_LEN];
  char *old_prompt;

  old_prompt = current_prompt;
  current_prompt = "Keyword or token id: ";
  paint_prompt();
  current_instr = INSTR_KEYWORD_WORD;
  paint_instructions();
  wrefresh(win_instr);
  
  while (! done)
    {
      wrefresh(win_prompt);
      ch = wgetch(win_prompt);
      erase_message();
      
      switch (ch)
	{
	case CTRL_L:
	  wrefresh(curscr);
	  break;
	  
	case CTRL_G:
	  strcpy(current_input, "");
	  paint_prompt( );
	  pos = -1;
	  done = TRUE;
	  break;
	  
	case DELETE:
	  delete_char_from_buffer(&ptr);
	  *ptr = '\0';
	  if (current_input[0] != PATH_SEP_CHAR) {
	    /* Only do fancy scrolling if not entering token */
	    pos = find_keyword_index(current_input, FALSE);
	    if (pos > -1)
	      {
		current_offset = pos;
		paint_menu( );
		wrefresh(win_above);
		wrefresh(win_entries);
		wrefresh(win_below);
	      }
	    else
	      {
		sprintf(buffer,
			"No keywords begin with \"%s\".",
			current_input);
		sound_bell();
		OLH_ui_message(buffer);
	      }
	  }
	  break;
	  
	case CTRL_U:
	  ptr = current_input;
	  *ptr = END_OF_STRING;
	  paint_prompt( );
	  break;
	  
	case RETURN:
	case NEWLINE:
	  *ptr = END_OF_STRING;
	  if (current_input[0] == '\0')
	    {
	      sound_bell();
	      OLH_ui_message("Please type in a keyword to search for.");
	      break;
	    }
	  if (current_input[0] == PATH_SEP_CHAR) {
	    /* assign menupath to token, and go to it */
	    resize_menupath(strlen(current_input));
	    strcpy(menupath,current_input);
	    doing_keywords = 0;
	    keyword_level = 0;
	    construct_context(menupath);
	    OLH_ui_update_menus();
	    done = TRUE;
	    pos = -1;
	    break;
	  }
	  pos = find_keyword_index(current_input,TRUE);
	  if (pos > -1)
	    done = TRUE;
	  else
	    {
	      sprintf(buffer,
		      "More than one keyword begins with \"%s\".  ",
		      current_input);
	      strcat(buffer, "Please type more characters.");
	      sound_bell();
	      OLH_ui_message(buffer);
	    }
	  break;
	  
	default:
	  if ((ch >= ' ') && (ch <= '~'))
	    {
	      if (ptr-current_input < MAX_KEYWORD_LEN)
		{
		  *ptr++ = ch;
		  *ptr = END_OF_STRING;
		  if (current_input[0] == PATH_SEP_CHAR)
		    waddch(win_prompt, ch);
		  else {
		    /* Only do fancy scrolling if not entering token... */
		    pos = find_keyword_index(current_input, FALSE);
		    if (pos > -1)
		      {
			waddch(win_prompt, ch);
			current_offset = pos;
			paint_menu( );
			wrefresh(win_above);
			wrefresh(win_entries);
			wrefresh(win_below);
		      }
		    else
		      {
			--ptr;
			sprintf(buffer,
				"No keywords begin with \"%s\".",
				current_input);
			sound_bell();
			OLH_ui_message(buffer);
		      }
		    }
		}
	      else
		sound_bell();
	    }
	  else
	    sound_bell();
	  break;
	}
    }
  current_prompt = old_prompt;
  current_input[0] = '\0';
  paint_prompt();
  wrefresh(win_prompt);
  update_instructions();
  return(pos);
}

/* Looks for matches for "key" in the current menu (which should be of */
/* keywords)  If unique =0, the number of the first matching entry is */
/* returned, regardless if there are many matches.  If unique != 0, the */
/* number of the matching entry is returned if it is unique, and -1 */
/* otherwise.  -1 is returned if none match */

int
find_keyword_index(key,unique)
     char *key;
     int unique;
{
  Menu *m;
  MenuEntry *entry;
  int i;
  int found = 0;
  int n_found;
  int len;

  len = strlen(key);
  if (len == 0)
    return(0);
  m = menu[current_menu];
  for (i=1; i<=size_menu(m); i++) {
    entry = nth_entry(m,i);
    if (strncasecmp(field_value(entry, NODE_LABEL),key,len) == 0) {
      if (!unique)
	return(i-1);
      else {
	if (found)
	  return(-1);
	found = 1;
	n_found = i-1;
      }
    }
  }
  if (found)
    return(n_found);
  else
    return(-1);
}

void
display_keyword_menu()
{
  MenuEntry *e;
  Menu *m;
  long code;

  e = find_group("keywords");
  code = menu_load(e,&m);
  if (code) {
    com_err(program,code,"Loading keyword menu");
    return;
  }
  current_menu++;
  menu[current_menu] = m;
  menu_entry[current_menu] = e;
  current[current_menu] = 0;
  viewed[current_menu] = FALSE;
  current_offset = selection = 0;
  OLH_ui_update_menus();
  current_instr = INSTR_KEYWORD_NUM;
  update_instructions();
}

void
invoke_k_item(number)
     int number;
{
  Menu *m;
  MenuEntry *e,*e2;
  long code;
  char *ptr;
  
  m = menu[current_menu];
  e = nth_entry(m, number);
  
  if (is_menu(e))
    {
      code = menu_load(e, &m);
      if (code)
	{
	  com_err(program, code, "loading %s",
		  field_value(e, FILE_LOCATION));
	  return;
	}
      add_to_menupath(e);
      current_menu++;
      menu[current_menu] = m;
      menu_entry[current_menu] = e;
      current[current_menu] = 0;
      viewed[current_menu] = FALSE;
      current_offset = selection = 0;
      if (strncasecmp(field_value(e, IN_KEYWORDS), "y",1) != 0) {
	/* A non-keyword menu */
	doing_keywords = 0;
	ptr = field_value(e, POINTER);
	code = pointerEntry(ptr, &e2);
	if (code || (!e2)) {
	  com_err(program,code,"locating module, continuing.");
	  make_parents_menupath(e);
	}
	else {
	  make_parents_menupath(e2);
	  /* Hack! e2 won't have a pointer entry, so just muck with menupath */
	  /* directly */
	  resize_menupath(strlen(menupath) + strlen(ptr));
	  strcat(menupath,";");
	  strcat(menupath,ptr);
	}
	construct_context(menupath);
      }
      OLH_ui_update_menus();
      update_instructions();
    }
  else
    {
      make_parents_menupath(e);
      construct_context(menupath);
      set_current_screen(SCR_VIEW);
      nocbreak();
      echo();
      code = viewdoc(e, TTY, NULL);
      if (code != 0) {
	if (code == ERR_MENU_NOVIEWER) {
	  display_file(NOVIEWER_TEXT);
	  wait_for_key(win_sugg_wait);
	}
	else
	  com_err(program,code,"viewing %s", field_value(e, FILE_LOCATION));
      }
      cbreak();
      noecho();
      paint_menu();
      set_current_screen(SCR_PRIM);
    }
}

