/*
 * 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/curses.c,v $
 *	$Id: curses.c,v 1.6 1992/04/05 17:08:37 probe Exp $
 *	$Author: probe $
 */

#ifndef lint
#ifndef SABER
static char *RCSid = "$Header: /afs/sipb.mit.edu/project/sipb-athena/repository/src/olh/ascii/curses.c,v 1.6 1992/04/05 17:08:37 probe Exp $";
#endif
#endif

#include "olh.h"

int 
  curses_init( )
{
  if (initscr() == (WINDOW *)ERR)
    {
      fprintf(stderr, "Unable to initialize the curses library.\n");
      return FALSE;
    }
  
  if ((LINES < MIN_LINES) || (COLS < MIN_COLS))
    {
      endwin();
      printf("\nTo use the On-Line Help service, you need to have a\n");
      printf("screen with at least %d columns by %d rows.\n\n",
	     MIN_COLS, MIN_LINES);
      return FALSE;
    }
  
  max_lines = max(LINES, max_lines);
  max_cols = max(COLS, max_cols);
  
  noecho();
  cbreak();
  
  return TRUE;
}


void 
  curses_shutdown( )
{
  echo();
  nocbreak();
  endwin();
}


void
  delete_char_from_buffer( ptr )
char** ptr;
{
  int x, y;
  
  if (*ptr <= current_input)
    {
      sound_bell();
      return;
    }
  
  *ptr = *ptr - 1;
  getyx(win_prompt, y, x);
  wmove(win_prompt, y, --x);
  wclrtoeol(win_prompt);
}


void
  sound_bell( )
{
  printf("\007");
}



void
  OLH_ui_viewer_wait( )
{
  wait_for_key(win_view_wait);
}


void
  wait_for_key( w )
WINDOW* w;
{
  wmove(w, 0, 0);
  wstandout(w);
  wprintw(w, "Press any key to continue... ");
  wstandend(w);
  wclrtoeol(w);
  wrefresh(w);
  wgetch(w);
  wclear(w);
  wrefresh(w);
}


void
  create_windows( )
{
  menu_lines = LINES - 12;
  
  scr[SCR_PRIM] = (scr_prim = newwin(0, 0, 0, 0));
  scr[SCR_VIEW] = (scr_view = newwin(0, 0, 0, 0));
  scr[SCR_SUGG] = (scr_sugg = newwin(0, 0, 0, 0));
  scount = SCR_MAX;
  
  wcount = 0;
  win[wcount++] = (win_heading = subwin(scr_prim, 1, 0, 0, 0));
  win[wcount++] = (win_instr = subwin(scr_prim, 5, 0, 1, 1));
  win[wcount++] = (win_label = subwin(scr_prim, 1, 0, 7, 3));
  win[wcount++] = (win_entries = subwin(scr_prim, menu_lines, 0, 9, 3));
  win[wcount++] = (win_above = subwin(scr_prim, 1, 0, 8, 40));
  win[wcount++] = (win_below = subwin(scr_prim, 1, 0, 9+menu_lines, 40));
  win[wcount++] = (win_prompt = subwin(scr_prim, 1, 0, LINES-2, 3));
  win[wcount++] = (win_message = subwin(scr_prim, 1, 0, LINES-1, 0));
  
  win[wcount++] = (win_view_wait = subwin(scr_view, 1, 0, LINES-1, 0));
  win[wcount++] = (win_sugg_wait = subwin(scr_sugg, 1, 0, LINES-1, 0));
}


void
  delete_windows( )
{
  register int i;
  
  for (i = wcount-1; i >= 0; i--)
    delwin(win[i]);
  
  for (i = scount-1; i >= 0; i--)
    delwin(scr[i]);
}

void
  paint_windows( )
{
  int start_col = (COLS/2) - (strlen(HEADER_TEXT)/2) - 5;
  
  wclear(scr_prim);
  wmove(win_heading, 0, (start_col > 0) ? start_col : 0);
  waddstr(win_heading, HEADER_TEXT);
  
  paint_instructions();
  
  prev_above = FALSE;
  prev_below = FALSE;
  
  paint_menu();
  paint_prompt();
  paint_message();
  paint_sugg();
}

void
  paint_menu( )
{
  int num;
  int i;
  int above;
  int below;
  Menu *m;
  int line;
  MenuEntry *e;
  char flag;

  m = menu[current_menu];
  
  num = size_menu(m) - 1;
  
  /*  Display the label  */
  
  wmove(win_label, 0, 0);
  waddstr(win_label, field_value(nth_entry(m, 0), NODE_LABEL));
  wclrtoeol(win_label);
  
  /*  Display each item  */
  
  for (i = 0; i < menu_lines; i++)
    {
      line = current_offset+i+1;
      wmove(win_entries, i, 0);
      if (line <= num) {
	e = nth_entry(m,line);

	flag = ((doing_keywords)?
	 (!strncasecmp(field_value(e, IN_KEYWORDS), "y", 1)?'*':' '):
	 ((is_menu(e))?'*':' '));

	wprintw(win_entries, "%c%3d%c %s",
		((line == current[current_menu]) ? '>' : ' '),
		line,
		flag,
		field_value(e, NODE_LABEL));
      }
      wclrtoeol(win_entries);
    }
  
  
  /*  Display "above" message, if necessary  */
  
  above = (current_offset > 0);
  wmove(win_above, 0, 0);
  
  if (above && ! prev_above) {
    if (doing_keywords)
      waddstr(win_above, "More topics above");
    else
      waddstr(win_above, "More topics above (press 'b')");
  }

  if (! above && prev_above)
    wclrtoeol(win_above);
  
  prev_above = above;
  
  
  /*  Display "below" message, if necessary  */
  
  below = (current_offset + menu_lines < num);
  wmove(win_below, 0, 0);
  
  if (below && ! prev_below) {
    if (doing_keywords)
      waddstr(win_below, "More topics below");
    else
      waddstr(win_below, "More topics below (press SPC)");
  }

  if (! below && prev_below)
    wclrtoeol(win_below);
  
  prev_below = below;
}

void
  paint_prompt( )
{
  wmove(win_prompt, 0, 0);
  if (current_prompt != NULL)
    waddstr(win_prompt, current_prompt);
  if (current_input != NULL)
    waddstr(win_prompt, current_input);
}


void
  paint_message( )
{
  wmove(win_message, 0, 0);
  wclrtoeol(win_message);
  if (current_message != NULL)
    waddstr(win_message, current_message);
}


void
  paint_sugg( )
{
  wclear(scr_sugg);
  waddstr(scr_sugg,
	  "Please type your suggestions for improving the On-Line Help service.");
  wmove(scr_sugg, 1, 0);
  waddstr(scr_sugg,
	  "Your suggestions will be forwarded to the person responsible for");
  wmove(scr_sugg, 2, 0);
  waddstr(scr_sugg,
	  "maintaining On-Line Help.  Your comments are appreciated.  Thanks!");
  wmove(scr_sugg, 4, 0);
  waddstr(scr_sugg,
	  "When you are done typing your suggestion, type Ctrl-D or '.' on a line");
  wmove(scr_sugg, 5, 0);
  waddstr(scr_sugg,
	  "by itself.");
  wmove(scr_sugg, 7, 0);
}
void
  paint_bugs( )
{
  wclear(scr_sugg);
  waddstr(scr_sugg,
	  "Please type your bug report for the On-Line Help software.");
  wmove(scr_sugg, 1, 0);
  waddstr(scr_sugg,
	  "Your bug report will be forwarded to the person responsible for");
  wmove(scr_sugg, 2, 0);
  waddstr(scr_sugg,
	  "maintaining On-Line Help.  Thanks for letting us know about any problems!");
  wmove(scr_sugg, 4, 0);
  waddstr(scr_sugg,
	  "When you are done typing your bug report, type Ctrl-D or '.' on a line");
  wmove(scr_sugg, 5, 0);
  waddstr(scr_sugg,
	  "by itself.");
  wmove(scr_sugg, 7, 0);
}


void
  set_current_screen( snumber )
int snumber;
{
  /*  Make sure previous screen is fully erased  */
  touchwin(stdscr);
  wrefresh(stdscr);
  wrefresh(curscr);
  
  /*  Bring up new screen  */
  
  current_screen = snumber;
  touchwin(scr[snumber]);
  wrefresh(scr[snumber]);
  
  /*  Special case:  Get cursor in right place  */
  
  switch (snumber)
    {
    case SCR_PRIM:
      touchwin(win_prompt);
      wrefresh(win_prompt);
      break;
    }
}
