/* menu_text.c - Basic text menu implementation.  */
/*
 *  GRUB  --  GRand Unified Bootloader
 *  Copyright (C) 2003,2004,2005,2006,2007,2008,2009  Free Software Foundation, Inc.
 *
 *  GRUB is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  GRUB is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <grub/normal.h>
#include <grub/term.h>
#include <grub/misc.h>
#include <grub/loader.h>
#include <grub/mm.h>
#include <grub/time.h>
#include <grub/env.h>
#include <grub/menu_viewer.h>
#include <grub/i18n.h>
#include <grub/charset.h>

static grub_uint8_t grub_color_menu_normal;
static grub_uint8_t grub_color_menu_highlight;

struct menu_viewer_data
{
  int first, offset;
  struct grub_term_screen_geometry geo;
  enum { 
    TIMEOUT_UNKNOWN, 
    TIMEOUT_NORMAL,
    TIMEOUT_TERSE,
    TIMEOUT_TERSE_NO_MARGIN
  } timeout_msg;
  grub_menu_t menu;
  struct grub_term_output *term;
};

static inline int
grub_term_cursor_x (const struct grub_term_screen_geometry *geo)
{
  return (geo->first_entry_x + geo->entry_width);
}

grub_size_t
grub_getstringwidth (grub_uint32_t * str, const grub_uint32_t * last_position,
		     struct grub_term_output *term)
{
  grub_ssize_t width = 0;

  while (str < last_position)
    {
      struct grub_unicode_glyph glyph;
      glyph.ncomb = 0;
      str += grub_unicode_aglomerate_comb (str, last_position - str, &glyph);
      width += grub_term_getcharwidth (term, &glyph);
      grub_unicode_destroy_glyph (&glyph);
    }
  return width;
}

static int
grub_print_message_indented_real (const char *msg, int margin_left,
				  int margin_right,
				  struct grub_term_output *term, int dry_run)
{
  grub_uint32_t *unicode_msg;
  grub_uint32_t *last_position;
  grub_size_t msg_len = grub_strlen (msg) + 2;
  int ret = 0;

  unicode_msg = grub_malloc (msg_len * sizeof (grub_uint32_t));
 
  if (!unicode_msg)
    return 0;

  msg_len = grub_utf8_to_ucs4 (unicode_msg, msg_len,
			       (grub_uint8_t *) msg, -1, 0);
  
  last_position = unicode_msg + msg_len;
  *last_position = 0;

  if (dry_run)
    ret = grub_ucs4_count_lines (unicode_msg, last_position, margin_left,
				 margin_right, term);
  else
    grub_print_ucs4_menu (unicode_msg, last_position, margin_left,
			  margin_right, term, 0, -1, 0, 0);

  grub_free (unicode_msg);

  return ret;
}

void
grub_print_message_indented (const char *msg, int margin_left, int margin_right,
			     struct grub_term_output *term)
{
  grub_print_message_indented_real (msg, margin_left, margin_right, term, 0);
}

static void
draw_border (struct grub_term_output *term, const struct grub_term_screen_geometry *geo)
{
  int i;

  grub_term_setcolorstate (term, GRUB_TERM_COLOR_NORMAL);

  grub_term_gotoxy (term, (struct grub_term_coordinate) { geo->first_entry_x - 1,
	geo->first_entry_y - 1 });
  grub_putcode (GRUB_UNICODE_CORNER_UL, term);
  for (i = 0; i < geo->entry_width + 1; i++)
    grub_putcode (GRUB_UNICODE_HLINE, term);
  grub_putcode (GRUB_UNICODE_CORNER_UR, term);

  for (i = 0; i < geo->num_entries; i++)
    {
      grub_term_gotoxy (term, (struct grub_term_coordinate) { geo->first_entry_x - 1,
	    geo->first_entry_y + i });
      grub_putcode (GRUB_UNICODE_VLINE, term);
      grub_term_gotoxy (term,
			(struct grub_term_coordinate) { geo->first_entry_x + geo->entry_width + 1,
			    geo->first_entry_y + i });
      grub_putcode (GRUB_UNICODE_VLINE, term);
    }

  grub_term_gotoxy (term,
		    (struct grub_term_coordinate) { geo->first_entry_x - 1,
			geo->first_entry_y - 1 + geo->num_entries + 1 });
  grub_putcode (GRUB_UNICODE_CORNER_LL, term);
  for (i = 0; i < geo->entry_width + 1; i++)
    grub_putcode (GRUB_UNICODE_HLINE, term);
  grub_putcode (GRUB_UNICODE_CORNER_LR, term);

  grub_term_setcolorstate (term, GRUB_TERM_COLOR_NORMAL);

  grub_term_gotoxy (term,
		    (struct grub_term_coordinate) { geo->first_entry_x - 1,
			(geo->first_entry_y - 1 + geo->num_entries
			 + GRUB_TERM_MARGIN + 1) });
}

static int
print_message (int nested, int edit, struct grub_term_output *term, int dry_run)
{
  int ret = 0;
  grub_term_setcolorstate (term, GRUB_TERM_COLOR_NORMAL);

  if (edit)
    {
      ret += grub_print_message_indented_real (_("Minimum Emacs-like screen editing is \
supported. TAB lists completions. Press Ctrl-x or F10 to boot, Ctrl-c or F2 for a \
command-line or ESC to discard edits and return to the GRUB menu."),
					       STANDARD_MARGIN, STANDARD_MARGIN,
					       term, dry_run);
    }
  else
    {
      char *msg_translated;

      msg_translated = grub_xasprintf (_("Use the %C and %C keys to select which "
					 "entry is highlighted."),
				       GRUB_UNICODE_UPARROW,
				       GRUB_UNICODE_DOWNARROW);
      if (!msg_translated)
	return 0;
      ret += grub_print_message_indented_real (msg_translated, STANDARD_MARGIN,
					       STANDARD_MARGIN, term, dry_run);

      grub_free (msg_translated);

      if (nested)
	{
	  ret += grub_print_message_indented_real
	    (_("Press enter to boot the selected OS, "
	       "`e' to edit the commands before booting "
	       "or `c' for a command-line. ESC to return previous menu."),
	     STANDARD_MARGIN, STANDARD_MARGIN, term, dry_run);
	}
      else
	{
	  ret += grub_print_message_indented_real
	    (_("Press enter to boot the selected OS, "
	       "`e' to edit the commands before booting "
	       "or `c' for a command-line."),
	     STANDARD_MARGIN, STANDARD_MARGIN, term, dry_run);
	}	
    }
  return ret;
}

static void
print_entry (int y, int highlight, grub_menu_entry_t entry,
	     const struct menu_viewer_data *data)
{
  const char *title;
  grub_size_t title_len;
  grub_ssize_t len;
  grub_uint32_t *unicode_title;
  grub_ssize_t i;
  grub_uint8_t old_color_normal, old_color_highlight;

  title = entry ? entry->title : "";
  title_len = grub_strlen (title);
  unicode_title = grub_malloc (title_len * sizeof (*unicode_title));
  if (! unicode_title)
    /* XXX How to show this error?  */
    return;

  len = grub_utf8_to_ucs4 (unicode_title, title_len,
                           (grub_uint8_t *) title, -1, 0);
  if (len < 0)
    {
      /* It is an invalid sequence.  */
      grub_free (unicode_title);
      return;
    }

  old_color_normal = grub_term_normal_color;
  old_color_highlight = grub_term_highlight_color;
  grub_term_normal_color = grub_color_menu_normal;
  grub_term_highlight_color = grub_color_menu_highlight;
  grub_term_setcolorstate (data->term, highlight
			   ? GRUB_TERM_COLOR_HIGHLIGHT
			   : GRUB_TERM_COLOR_NORMAL);

  grub_term_gotoxy (data->term, (struct grub_term_coordinate) { 
      data->geo.first_entry_x, y });

  for (i = 0; i < len; i++)
    if (unicode_title[i] == '\n' || unicode_title[i] == '\b'
	|| unicode_title[i] == '\r' || unicode_title[i] == '\e')
      unicode_title[i] = ' ';

  if (data->geo.num_entries > 1)
    grub_putcode (highlight ? '*' : ' ', data->term);

  grub_print_ucs4_menu (unicode_title,
			unicode_title + len,
			0,
			data->geo.right_margin,
			data->term, 0, 1,
			GRUB_UNICODE_RIGHTARROW, 0);

  grub_term_setcolorstate (data->term, GRUB_TERM_COLOR_NORMAL);
  grub_term_gotoxy (data->term,
		    (struct grub_term_coordinate) { 
		      grub_term_cursor_x (&data->geo), y });

  grub_term_normal_color = old_color_normal;
  grub_term_highlight_color = old_color_highlight;

  grub_term_setcolorstate (data->term, GRUB_TERM_COLOR_NORMAL);
  grub_free (unicode_title);
}

static void
print_entries (grub_menu_t menu, const struct menu_viewer_data *data)
{
  grub_menu_entry_t e;
  int i;

  grub_term_gotoxy (data->term,
		    (struct grub_term_coordinate) { 
		      data->geo.first_entry_x + data->geo.entry_width
			+ data->geo.border + 1,
			data->geo.first_entry_y });

  if (data->geo.num_entries != 1)
    {
      if (data->first)
	grub_putcode (GRUB_UNICODE_UPARROW, data->term);
      else
	grub_putcode (' ', data->term);
    }
  e = grub_menu_get_entry (menu, data->first);

  for (i = 0; i < data->geo.num_entries; i++)
    {
      print_entry (data->geo.first_entry_y + i, data->offset == i,
		   e, data);
      if (e)
	e = e->next;
    }

  grub_term_gotoxy (data->term,
		    (struct grub_term_coordinate) { data->geo.first_entry_x + data->geo.entry_width
			+ data->geo.border + 1,
			data->geo.first_entry_y + data->geo.num_entries - 1 });
  if (data->geo.num_entries == 1)
    {
      if (data->first && e)
	grub_putcode (GRUB_UNICODE_UPDOWNARROW, data->term);
      else if (data->first)
	grub_putcode (GRUB_UNICODE_UPARROW, data->term);
      else if (e)
	grub_putcode (GRUB_UNICODE_DOWNARROW, data->term);
      else
	grub_putcode (' ', data->term);
    }
  else
    {
      if (e)
	grub_putcode (GRUB_UNICODE_DOWNARROW, data->term);
      else
	grub_putcode (' ', data->term);
    }

  grub_term_gotoxy (data->term,
		    (struct grub_term_coordinate) { grub_term_cursor_x (&data->geo),
			data->geo.first_entry_y + data->offset });
}

/* Initialize the screen.  If NESTED is non-zero, assume that this menu
   is run from another menu or a command-line. If EDIT is non-zero, show
   a message for the menu entry editor.  */
void
grub_menu_init_page (int nested, int edit,
		     struct grub_term_screen_geometry *geo,
		     struct grub_term_output *term)
{
  grub_uint8_t old_color_normal, old_color_highlight;
  int msg_num_lines;
  int bottom_message = 1;
  int empty_lines = 1;
  int version_msg = 1;

  geo->border = 1;
  geo->first_entry_x = 1 /* margin */ + 1 /* border */;
  geo->entry_width = grub_term_width (term) - 5;

  geo->first_entry_y = 2 /* two empty lines*/
    + 1 /* GNU GRUB version text  */ + 1 /* top border */;

  geo->timeout_lines = 2;

  /* 3 lines for timeout message and bottom margin.  2 lines for the border.  */
  geo->num_entries = grub_term_height (term) - geo->first_entry_y
    - 1 /* bottom border */
    - 1 /* empty line before info message*/
    - geo->timeout_lines /* timeout */
    - 1 /* empty final line  */;
  msg_num_lines = print_message (nested, edit, term, 1);
  if (geo->num_entries - msg_num_lines < 3
      || geo->entry_width < 10)
    {
      geo->num_entries += 4;
      geo->first_entry_y -= 2;
      empty_lines = 0;
      geo->first_entry_x -= 1;
      geo->entry_width += 1;
    }
  if (geo->num_entries - msg_num_lines < 3
      || geo->entry_width < 10)
    {
      geo->num_entries += 2;
      geo->first_entry_y -= 1;
      geo->first_entry_x -= 1;
      geo->entry_width += 2;
      geo->border = 0;
    }

  if (geo->entry_width <= 0)
    geo->entry_width = 1;

  if (geo->num_entries - msg_num_lines < 3
      && geo->timeout_lines == 2)
    {
      geo->timeout_lines = 1;
      geo->num_entries++;
    }

  if (geo->num_entries - msg_num_lines < 3)
    {
      geo->num_entries += 1;
      geo->first_entry_y -= 1;
      version_msg = 0;
    }

  if (geo->num_entries - msg_num_lines >= 2)
    geo->num_entries -= msg_num_lines;
  else
    bottom_message = 0;

  /* By default, use the same colors for the menu.  */
  old_color_normal = grub_term_normal_color;
  old_color_highlight = grub_term_highlight_color;
  grub_color_menu_normal = grub_term_normal_color;
  grub_color_menu_highlight = grub_term_highlight_color;

  /* Then give user a chance to replace them.  */
  grub_parse_color_name_pair (&grub_color_menu_normal,
			      grub_env_get ("menu_color_normal"));
  grub_parse_color_name_pair (&grub_color_menu_highlight,
			      grub_env_get ("menu_color_highlight"));

  if (version_msg)
    grub_normal_init_page (term, empty_lines);
  else
    grub_term_cls (term);

  grub_term_normal_color = grub_color_menu_normal;
  grub_term_highlight_color = grub_color_menu_highlight;
  if (geo->border)
    draw_border (term, geo);
  grub_term_normal_color = old_color_normal;
  grub_term_highlight_color = old_color_highlight;
  geo->timeout_y = geo->first_entry_y + geo->num_entries
    + geo->border + empty_lines;
  if (bottom_message)
    {
      grub_term_gotoxy (term,
			(struct grub_term_coordinate) { GRUB_TERM_MARGIN,
			    geo->timeout_y });

      print_message (nested, edit, term, 0);
      geo->timeout_y += msg_num_lines;
    }
  geo->right_margin = grub_term_width (term)
    - geo->first_entry_x
    - geo->entry_width - 1;
}

static void
menu_text_print_timeout (int timeout, void *dataptr)
{
  struct menu_viewer_data *data = dataptr;
  char *msg_translated = 0;

  grub_term_gotoxy (data->term,
		    (struct grub_term_coordinate) { 0, data->geo.timeout_y });

  if (data->timeout_msg == TIMEOUT_TERSE
      || data->timeout_msg == TIMEOUT_TERSE_NO_MARGIN)
    msg_translated = grub_xasprintf (_("%ds"), timeout);
  else
    msg_translated = grub_xasprintf (_("The highlighted entry will be executed automatically in %ds."), timeout);
  if (!msg_translated)
    {
      grub_print_error ();
      grub_errno = GRUB_ERR_NONE;
      return;
    }

  if (data->timeout_msg == TIMEOUT_UNKNOWN)
    {
      data->timeout_msg = grub_print_message_indented_real (msg_translated,
							    3, 1, data->term, 1)
	<= data->geo.timeout_lines ? TIMEOUT_NORMAL : TIMEOUT_TERSE;
      if (data->timeout_msg == TIMEOUT_TERSE)
	{
	  grub_free (msg_translated);
	  msg_translated = grub_xasprintf (_("%ds"), timeout);
	  if (grub_term_width (data->term) < 10)
	    data->timeout_msg = TIMEOUT_TERSE_NO_MARGIN;
	}
    }

  grub_print_message_indented (msg_translated,
			       data->timeout_msg == TIMEOUT_TERSE_NO_MARGIN ? 0 : 3,
			       data->timeout_msg == TIMEOUT_TERSE_NO_MARGIN ? 0 : 1,
			       data->term);
  grub_free (msg_translated);

  grub_term_gotoxy (data->term,
		    (struct grub_term_coordinate) { 
		      grub_term_cursor_x (&data->geo),
			data->geo.first_entry_y + data->offset });
  grub_term_refresh (data->term);
}

static void
menu_text_set_chosen_entry (int entry, void *dataptr)
{
  struct menu_viewer_data *data = dataptr;
  int oldoffset = data->offset;
  int complete_redraw = 0;

  data->offset = entry - data->first;
  if (data->offset > data->geo.num_entries - 1)
    {
      data->first = entry - (data->geo.num_entries - 1);
      data->offset = data->geo.num_entries - 1;
      complete_redraw = 1;
    }
  if (data->offset < 0)
    {
      data->offset = 0;
      data->first = entry;
      complete_redraw = 1;
    }
  if (complete_redraw)
    print_entries (data->menu, data);
  else
    {
      print_entry (data->geo.first_entry_y + oldoffset, 0,
		   grub_menu_get_entry (data->menu, data->first + oldoffset),
		   data);
      print_entry (data->geo.first_entry_y + data->offset, 1,
		   grub_menu_get_entry (data->menu, data->first + data->offset),
		   data);
    }
  grub_term_refresh (data->term);
}

static void
menu_text_fini (void *dataptr)
{
  struct menu_viewer_data *data = dataptr;

  grub_term_setcursor (data->term, 1);
  grub_term_cls (data->term);
  grub_free (data);
}

static void
menu_text_clear_timeout (void *dataptr)
{
  struct menu_viewer_data *data = dataptr;
  int i;

  for (i = 0; i < data->geo.timeout_lines;i++)
    {
      grub_term_gotoxy (data->term, (struct grub_term_coordinate) {
	  0, data->geo.timeout_y + i });
      grub_print_spaces (data->term, grub_term_width (data->term) - 1);
    }
  if (data->geo.num_entries <= 5 && !data->geo.border)
    {
      grub_term_gotoxy (data->term,
			(struct grub_term_coordinate) { 
			  data->geo.first_entry_x + data->geo.entry_width
			    + data->geo.border + 1,
			    data->geo.first_entry_y + data->geo.num_entries - 1
			    });
      grub_putcode (' ', data->term);

      data->geo.timeout_lines = 0;
      data->geo.num_entries++;
      print_entries (data->menu, data);
    }
  grub_term_gotoxy (data->term,
		    (struct grub_term_coordinate) {
		      grub_term_cursor_x (&data->geo),
			data->geo.first_entry_y + data->offset });
  grub_term_refresh (data->term);
}

grub_err_t 
grub_menu_try_text (struct grub_term_output *term, 
		    int entry, grub_menu_t menu, int nested)
{
  struct menu_viewer_data *data;
  struct grub_menu_viewer *instance;

  instance = grub_zalloc (sizeof (*instance));
  if (!instance)
    return grub_errno;

  data = grub_zalloc (sizeof (*data));
  if (!data)
    {
      grub_free (instance);
      return grub_errno;
    }

  data->term = term;
  instance->data = data;
  instance->set_chosen_entry = menu_text_set_chosen_entry;
  instance->print_timeout = menu_text_print_timeout;
  instance->clear_timeout = menu_text_clear_timeout;
  instance->fini = menu_text_fini;

  data->menu = menu;

  data->offset = entry;
  data->first = 0;

  grub_term_setcursor (data->term, 0);
  grub_menu_init_page (nested, 0, &data->geo, data->term);

  if (data->offset > data->geo.num_entries - 1)
    {
      data->first = data->offset - (data->geo.num_entries - 1);
      data->offset = data->geo.num_entries - 1;
    }

  print_entries (menu, data);
  grub_term_refresh (data->term);
  grub_menu_register_viewer (instance);

  return GRUB_ERR_NONE;
}
