/* screen.c - master screen routines for hubadmin
 **
 ** SWADMIN PROJECT
 ** Network Development
 **
 ** Copyright (c) 1994, 1996 - Carnegie Mellon University - All Rights Reserved
 **
 ** Erikas Aras Napjus (erikas@cmu.edu)
 */

/**********************************************************************
 *
 *           Copyright 1996 by Carnegie Mellon University
 * 
 *                       All Rights Reserved
 * 
 * Permission to use, copy, modify, and distribute this software and its
 * documentation for any purpose and without fee is hereby granted,
 * provided that the above copyright notice appear in all copies and that
 * both that copyright notice and this permission notice appear in
 * supporting documentation, and that the name of CMU not be
 * used in advertising or publicity pertaining to distribution of the
 * software without specific, written prior permission.
 * 
 * CMU DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
 * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
 * CMU BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
 * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
 * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
 * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
 * SOFTWARE.
 * 
 * Author: Ryan Troll <ryan+@andrew.cmu.edu>
 * 
 **********************************************************************/

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif /* HAVE_CONFIG_H */

#include <stdio.h>
#include <assert.h>

#ifdef HAVE_TERMIOS_H
# include <termios.h>
#endif /* HAVE_TERMIOS_H */

#include <curses.h>      /* Curses support */

#ifdef HAVE_STRINGS_H
# include <strings.h>
#else /* HAVE_STRINGS_H */
# include <string.h>
#endif /* HAVE_STRINGS_H */

#include "screen.h"
#include "swadmin.h"
#include "version.h"

static char rcsid[] = 
"$Id: screen.c,v 1.4 1997/02/17 16:20:52 ryan Exp $";

static int stack[25];
static int stack_counter=0;

static WINDOW *title, *menu, *help;
static char holder[80];
static char str[81];
static char legend[7][80];

void clear_stack(void)
{
  stack_counter = 0;
}

int popd(void)
{
  if (stack_counter > 0)
    return stack[stack_counter--];
  else
    return -1;
}

void pushd(int value)
{
  if (stack_counter < 25)
    stack[++stack_counter] = value;
  return;
}

char *highlight(char *string)
{
#ifdef A_REVERSE
  return (string);
#else /* A_REVERSE */

#ifdef __sun
  /* This works under sunos */
  char str[80];
  int incr;

  for (incr=0; string[incr] != NULL; incr++)
    str[incr] = string[incr]+128;
  str[incr] = NULL;
  return str;
#else /* __sun */
  
  /* No inverse */
  return(string);

#endif /* __sun */
#endif /* A_REVERSE */
}

void clear_legend(void)
{
  int incr;

  for (incr=0; incr<7; incr++)
    legend[incr][0] = 0;
}

void set_legend(int line, char *leger)
{
  int incr;

  for (incr=0; 
       (line < 7) && (incr < 80) && (leger[incr] != 0); 
       incr++)
    legend[line][incr] = leger[incr];

  return;
}

/* center - centers a line of text and place the output in holder
 **
 ** NOTE: the return value is *not* used; you must get it from holder
 **       this should be fixed in a future version
 */
char *center(char *str1)
{
  int incr, length, side;
  
  length = strlen(str1);
  length--; /* Get rid of NULL. */
  
  side = (int) (80 - length) / 2;

  for (incr = 0; incr < side; incr++)
    holder[incr] = ' ';
  
  for (; incr <= (length+side); incr++)
    holder[incr] = str1[incr-side];
  
  for (; incr < 80; incr++)
    holder[incr] = ' ';

  return holder;
}

/* screen_init_all - creates all of the primary system windows 
 */
void screen_init_all(void)
{
  title = newwin(3, 80, 0, 0);
  menu = newwin(1, 80, 4, 0);
  help = newwin(1, 80, 23, 0);

#ifdef A_REVERSE
  wattron(title, A_REVERSE);
  wattron(help, A_REVERSE);
#endif
}

/* screen_close_all - closes all of the primary system windows
 */
void screen_close_all(void)
{
  delwin(title);
  delwin(menu);
  delwin(help);
}

/* screen_init - creates the standard title header
 **
 ** (this appears on the first line of the screen)
 */
void screen_init(void)
{
  char buf[1024];

  sprintf(buf, "SWADMIN - Version %s", swadmin_Version());
  mvwprintw(title, 0, 0, highlight(center(buf)));
  wrefresh(title);
}

/* screen_area - specifies the "area" of the program currently in use
**
** (this appears on the second line of the screen)
*/
void screen_area(char *area)
{
  mvwprintw(title, 1, 0, highlight(center(area)));
  /*  wmove(title, 2, 0); */
  wclrtoeol(title);
  wrefresh(title);
  werase(menu);
  wrefresh(menu);
}

/* screen_hub - specifies the current hub (or building) selected
**
** (this appears on the third line of the screen)
*/
void screen_hub(char *hub)
{
  char temp[81];

  sprintf(temp, "< %s >", hub);

  mvwprintw(title, 2, 0, highlight(center(temp)));
  wrefresh(title);
}

/* screen_help_legend - this creates the legend for the port statistics
**
** (this appears on the last line of the screen)
*/
void screen_help_legend(void)
{
  mvwprintw(help, 0, 0,
	    highlight("O=LinkOn X=LinkOff   E=Enabled P=Partition A=AutoPartition   L=Local N=Network "));
  wclrtoeol(help);
  wrefresh(help);
}

/* screen_help_default - this creates the standard help line
**
** (this appears on the bottom of the screen)
*/
void screen_help_default(void)
{
  mvwprintw(help, 0, 0,
	    highlight("Q = Quit  T = Top  B = Back   Enter = Select   UpArrow = Up  DnArrow = Down    "));
  wclrtoeol(help);
  wrefresh(help);
}

/* screen_help - this displays an arbitrary value on the help line
**
** (this appears on the bottom line of the screen)
** NOTE: this is not currently used; see screen_help_legend above
*/
void screen_help(char *content)
{
  mvwprintw(help, 0, 0, highlight(content));
  wclrtoeol(help);
  wrefresh(help);
}

/* screen_error - this displays an error message (failure to contact hub)
**
** (this appears on the bottom line of the screen with a BEEP)
*/
void screen_error(char *content)
{
  WINDOW *error;

  error = newwin(3, 40, 10, 20);

  printf("\007");

  mvwprintw(error, 0, 0, highlight("                ERROR                  "));
  mvwprintw(error, 1, 2, "%s", content);
  mvwprintw(error, 2, 0, highlight("                                       "));
  mvwprintw(error, 1, 0, highlight(" "));
  mvwprintw(error, 1, 38, highlight(" "));

  wrefresh(error);
  sleep(5);

  werase(error);
  wrefresh(error);
  delwin(error);

/*  werase(help);
  printf("\007");
  mvwprintw(help, 0, 0, highlight("ERROR: %s", content));
  wrefresh(help);
  sleep(2);*/
}

/* screen_menu - this displays the "menu prompt" above the actual body
**
** (this appears on the fifth line immediately above the body, but below
**  the title bar)
*/
void screen_menu(int y, int x, char *content)
{
  mvwprintw(menu, y, x, content);
  wclrtoeol(menu);
  wrefresh(menu);
}

/* screen_menu - this displays the "menu prompt" above the actual body
**
** (this appears on the fifth line immediately above the body, but below
**  the title bar)
*/
void screen_menu_high(int y, int x, char *content)
{
  mvwprintw(menu, y, x, highlight(content));
  wclrtoeol(menu);
  wrefresh(menu);
}

/* screen_status - this displays the current status as specified in hubadmin.h
**
** (this appears in the upper right corner of the screen)
*/
void screen_status(int status)
{
  switch (status)
    {
    case STAT_READY:
      mvwprintw(title, 0, 73, highlight("READY "));
      break;
    case STAT_WAIT:
      mvwprintw(title, 0, 73, highlight("WAIT  "));
      break;
    case STAT_ACTIVE:
      mvwprintw(title, 0, 73, highlight("ACTIVE"));
      break;
    default:
      mvwprintw(title, 0, 73, highlight("HELP  "));
      break;
    }
  wrefresh(title);
}

void screen_legend(void)
{
  WINDOW *leg1, *leg2;
  int incr;

  leg1 = newwin(7, 80, 10, 0);

  mvwprintw(leg1, 0, 0, center("LEGEND"));
  for (incr=1; incr < 7; incr++)
    {
      mvwprintw(leg1, incr, 0, highlight(" "));
      mvwprintw(leg1, incr, 78, highlight(" "));
    }
  mvwprintw(leg1, 6, 0, center(" "));

  wrefresh(leg1);

  leg2 = newwin(5, 77, 11, 1);

  wclear(leg2);
  wrefresh(leg2);

  for (incr=0; incr < 7; incr++)
    mvwprintw(leg2, incr, 0, "%s", legend[incr]);

  wrefresh(leg2);

  getch();

  werase(leg1);
  wrefresh(leg1);
  delwin(leg1);
  werase(leg2);
  wrefresh(leg2);
  delwin(leg2);

}

