/*
 *  GRUB  --  GRand Unified Bootloader
 *  Copyright (C) 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/mm.h>
#include <grub/loader.h>
#include <grub/command.h>
#include <grub/parser.h>
#include <grub/script_sh.h>
#include <grub/auth.h>
#include <grub/i18n.h>
#include <grub/charset.h>
#include <grub/safemath.h>

enum update_mode
  {
    NO_LINE,
    SINGLE_LINE,
    ALL_LINES
  };

struct line
{
  /* The line buffer.  */
  grub_uint32_t *buf;
  /* The length of the line.  */
  int len;
  /* The maximum length of the line.  */
  int max_len;
  struct grub_term_pos **pos;
};

struct per_term_screen
{
  struct grub_term_output *term;
  int y_line_start;
  struct grub_term_screen_geometry geo;
  /* Scratch variables used when updating. Having them here avoids
     loads of small mallocs.  */
  int orig_num;
  int down;
  enum update_mode mode;
};

struct screen
{
  /* The array of lines.  */
  struct line *lines;
  /* The number of lines.  */
  int num_lines;
  /* The current column.  */
  int column;
  /* The real column.  */
  int real_column;
  /* The current line.  */
  int line;
  /* The kill buffer.  */
  char *killed_text;
  /* The flag of a completion window.  */
  int completion_shown;

  int submenu;

  struct per_term_screen *terms;
  unsigned nterms;
};

/* Used for storing completion items temporarily.  */
static struct {
  char *buf;
  grub_size_t len;
  grub_size_t max_len;
} completion_buffer;
static int completion_type;

/* Initialize a line.  */
static int
init_line (struct screen *screen, struct line *linep)
{
  linep->len = 0;
  linep->max_len = 80;
  linep->buf = grub_calloc (linep->max_len + 1, sizeof (linep->buf[0]));
  linep->pos = grub_calloc (screen->nterms, sizeof (linep->pos[0]));
  if (! linep->buf || !linep->pos)
    {
      grub_free (linep->buf);
      grub_free (linep->pos);
      return 0;
    }

  return 1;
}

/* Allocate extra space if necessary.  */
static int
ensure_space (struct line *linep, int extra)
{
  if (linep->max_len < linep->len + extra)
    {
      grub_size_t sz0, sz1;

      if (grub_add (linep->len, extra, &sz0) ||
	  grub_mul (sz0, 2, &sz0) ||
	  grub_add (sz0, 1, &sz1) ||
	  grub_mul (sz1, sizeof (linep->buf[0]), &sz1))
	return 0;

      linep->buf = grub_realloc (linep->buf, sz1);
      if (! linep->buf)
	return 0;
      linep->max_len = sz0;
    }

  return 1;
}

/* Return the number of lines occupied by this line on the screen.  */
static int
get_logical_num_lines (struct line *linep, struct per_term_screen *term_screen)
{
  grub_size_t width = grub_getstringwidth (linep->buf, linep->buf + linep->len,
					   term_screen->term);

  /* Empty line still consumes space on screen */
  return width ? (width + (unsigned) term_screen->geo.entry_width - 1) /
		 (unsigned) term_screen->geo.entry_width
	       : 1;
}

static void
advance_to (struct screen *screen, int c)
{
  if (c > screen->lines[screen->line].len)
    c = screen->lines[screen->line].len;

  screen->column = grub_unicode_get_comb_end (screen->lines[screen->line].buf
					      + screen->lines[screen->line].len,
					      screen->lines[screen->line].buf
					      + c)
    - screen->lines[screen->line].buf;
}

/* Print an empty line.  */
static void
print_empty_line (int y, struct per_term_screen *term_screen)
{
  int i;

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

  for (i = 0; i < term_screen->geo.entry_width + 1; i++)
    grub_putcode (' ', term_screen->term);
}

static void
print_updown (int upflag, int downflag, struct per_term_screen *term_screen)
{
  grub_term_gotoxy (term_screen->term,
		    (struct grub_term_coordinate) { term_screen->geo.first_entry_x
			+ term_screen->geo.entry_width + 1
			+ term_screen->geo.border,
			term_screen->geo.first_entry_y });

  if (upflag && downflag)
    grub_putcode (GRUB_UNICODE_UPDOWNARROW, term_screen->term);
  else if (upflag)
    grub_putcode (GRUB_UNICODE_UPARROW, term_screen->term);
  else if (downflag)
    grub_putcode (GRUB_UNICODE_DOWNARROW, term_screen->term);
  else
    grub_putcode (' ', term_screen->term);
}

/* Print an up arrow.  */
static void
print_up (int flag, struct per_term_screen *term_screen)
{
  grub_term_gotoxy (term_screen->term,
		    (struct grub_term_coordinate) { term_screen->geo.first_entry_x
			+ term_screen->geo.entry_width + 1
			+ term_screen->geo.border,
			term_screen->geo.first_entry_y });

  if (flag)
    grub_putcode (GRUB_UNICODE_UPARROW, term_screen->term);
  else
    grub_putcode (' ', term_screen->term);
}

/* Print a down arrow.  */
static void
print_down (int flag, struct per_term_screen *term_screen)
{
  grub_term_gotoxy (term_screen->term,
		    (struct grub_term_coordinate) { term_screen->geo.first_entry_x
			+ term_screen->geo.entry_width + 1
			+ term_screen->geo.border,
			term_screen->geo.first_entry_y
			+ term_screen->geo.num_entries - 1 });

  if (flag)
    grub_putcode (GRUB_UNICODE_DOWNARROW, term_screen->term);
  else
    grub_putcode (' ', term_screen->term);
}

/* Draw the lines of the screen SCREEN.  */
static void
update_screen (struct screen *screen, struct per_term_screen *term_screen,
	       int region_start, int region_column __attribute__ ((unused)),
	       int up, int down, enum update_mode mode)
{
  int up_flag = 0;
  int down_flag = 0;
  int y;
  int i;
  struct line *linep;

  y = term_screen->y_line_start;
  linep = screen->lines;

  for (i = 0; i < screen->line; i++, linep++)
    y += get_logical_num_lines (linep, term_screen);
  linep = screen->lines + screen->line;
  grub_size_t t = grub_getstringwidth (linep->buf, linep->buf + screen->column,
				       term_screen->term);
  y += t / (unsigned) term_screen->geo.entry_width;
  if (t % (unsigned) term_screen->geo.entry_width == 0
      && t != 0 &&  screen->column == linep->len)
    y--;
  /* Check if scrolling is necessary.  */
  if (y < 0 || y >= term_screen->geo.num_entries)
    {
      int delta;
      if (y < 0)
	delta = -y;
      else
	delta = term_screen->geo.num_entries - 1 - y;
      term_screen->y_line_start += delta;

      region_start = 0;
      up = 1;
      down = 1;
      mode = ALL_LINES;
    }

  grub_term_setcursor (term_screen->term, 0);

  if (mode != NO_LINE)
    {
      /* Draw lines. This code is tricky, because this must calculate logical
	 positions.  */
      y = term_screen->y_line_start;
      i = 0;
      linep = screen->lines;
      while (1)
 	{
	  int add;
	  add = get_logical_num_lines (linep, term_screen);
	  if (y + add > 0)
	    break;
	  i++;
	  linep++;
	  y += add;
 	}

      if (y < 0 || i > 0)
	up_flag = 1;

      do
	{
	  struct grub_term_pos **pos;

	  if (linep >= screen->lines + screen->num_lines)
	    break;

	  pos = linep->pos + (term_screen - screen->terms);

	  if (!*pos)
	    *pos = grub_calloc (linep->len + 1, sizeof (**pos));

	  if (i == region_start || linep == screen->lines + screen->line
	      || (i > region_start && mode == ALL_LINES))
	    {
	      grub_term_gotoxy (term_screen->term,
				(struct grub_term_coordinate) { term_screen->geo.first_entry_x,
				    (y < 0 ? 0 : y)
				    + term_screen->geo.first_entry_y });

	      grub_print_ucs4_menu (linep->buf,
				    linep->buf + linep->len,
				    term_screen->geo.first_entry_x,
				    term_screen->geo.right_margin,
				    term_screen->term,
				    (y < 0) ? -y : 0,
				    term_screen->geo.num_entries
				    - ((y > 0) ? y : 0), '\\',
				    *pos);
	    }
	  y += get_logical_num_lines (linep, term_screen);
	  if (y >= term_screen->geo.num_entries)
	    {
	      if (i + 1 < screen->num_lines)
		down_flag = 1;
	    }

	  linep++;
	  i++;

	  if (mode == ALL_LINES && i == screen->num_lines)
	    for (; y < term_screen->geo.num_entries; y++)
	      print_empty_line (y, term_screen);
	}
      while (y < term_screen->geo.num_entries);

      /* Draw up and down arrows.  */
      
      if (term_screen->geo.num_entries == 1)
	{
	  if (up || down)
	    print_updown (up_flag, down_flag, term_screen);
	}
      else
	{
	  if (up)
	    print_up (up_flag, term_screen);
	  if (down)
	    print_down (down_flag, term_screen);
	}
    }

  /* Place the cursor.  */
  if (screen->lines[screen->line].pos[term_screen - screen->terms])
    {
      const struct grub_term_pos *cpos;
      for (cpos = &(screen->lines[screen->line].pos[term_screen - screen->terms])[screen->column];
	   cpos >= &(screen->lines[screen->line].pos[term_screen - screen->terms])[0];
	   cpos--)
	if (cpos->valid)
	  break;
      y = term_screen->y_line_start;
      for (i = 0; i < screen->line; i++)
	y += get_logical_num_lines (screen->lines + i, term_screen);
      if (cpos >= &(screen->lines[screen->line].pos[term_screen - screen->terms])[0])
	grub_term_gotoxy (term_screen->term, 
			  (struct grub_term_coordinate) { cpos->x + term_screen->geo.first_entry_x,
			      cpos->y + y
			      + term_screen->geo.first_entry_y });
      else
	grub_term_gotoxy (term_screen->term, 
			  (struct grub_term_coordinate) { term_screen->geo.first_entry_x,
			      y + term_screen->geo.first_entry_y });

    }

  grub_term_setcursor (term_screen->term, 1);

  grub_term_refresh (term_screen->term);
}

static void
update_screen_all (struct screen *screen,
		   int region_start, int region_column,
		   int up, int down, enum update_mode mode)
{
  unsigned i;
  for (i = 0; i < screen->nterms; i++)
    update_screen (screen, &screen->terms[i], region_start, region_column,
		   up, down, mode);
}

static int
insert_string (struct screen *screen, const char *s, int update)
{
  int region_start = screen->num_lines;
  int region_column = 0;
  unsigned i;

  for (i = 0; i < screen->nterms; i++)
    {
      screen->terms[i].down = 0;
      screen->terms[i].mode = NO_LINE;
    }

  while (*s)
    {
      if (*s == '\n')
	{
	  /* LF is special because it creates a new line.  */
	  struct line *current_linep;
	  struct line *next_linep;
	  int size;

	  /* Make a new line.  */
	  screen->num_lines++;
	  screen->lines = grub_realloc (screen->lines,
					screen->num_lines
					* sizeof (screen->lines[0]));
	  if (! screen->lines)
	    return 0;

	  /* Shift down if not appending after the last line. */
	  if (screen->line < screen->num_lines - 2)
	    grub_memmove (screen->lines + screen->line + 2,
			  screen->lines + screen->line + 1,
			  ((screen->num_lines - screen->line - 2)
			   * sizeof (struct line)));

	  if (! init_line (screen, screen->lines + screen->line + 1))
	    return 0;

	  /* Fold the line.  */
	  current_linep = screen->lines + screen->line;
	  next_linep = current_linep + 1;
	  size = current_linep->len - screen->column;

	  if (! ensure_space (next_linep, size))
	    return 0;

	  grub_memmove (next_linep->buf,
			current_linep->buf + screen->column,
			size * sizeof (next_linep->buf[0]));
	  current_linep->len = screen->column;
	  for (i = 0; i < screen->nterms; i++)
	    {
	      grub_free (current_linep->pos[i]);
	      current_linep->pos[i] = 0;
	    }
	  next_linep->len = size;

	  /* Update a dirty region.  */
	  if (region_start > screen->line)
	    {
	      region_start = screen->line;
	      region_column = screen->column;
	    }

	  for (i = 0; i < screen->nterms; i++)
	    {
	      screen->terms[i].mode = ALL_LINES;
	      screen->terms[i].down = 1; /* XXX not optimal.  */
	    }

	  /* Move the cursor.  */
	  screen->column = screen->real_column = 0;
	  screen->line++;
	  s++;
	}
      else
	{
	  /* All but LF.  */
	  const char *p;
	  struct line *current_linep;
	  int size;
	  grub_uint32_t *unicode_msg;

	  /* Find a string delimited by LF.  */
	  p = grub_strchr (s, '\n');
	  if (! p)
	    p = s + grub_strlen (s);

	  /* Insert the string.  */
	  current_linep = screen->lines + screen->line;
	  unicode_msg = grub_calloc (p - s, sizeof (grub_uint32_t));

	  if (!unicode_msg)
	    return 0;

	  size = grub_utf8_to_ucs4 (unicode_msg, (p - s),
				    (grub_uint8_t *) s, (p - s), 0);

	  if (! ensure_space (current_linep, size))
	    {
	      grub_free (unicode_msg);
	      return 0;
	    }

	  grub_memmove (current_linep->buf + screen->column + size,
			current_linep->buf + screen->column,
			(current_linep->len - screen->column)
			* sizeof (current_linep->buf[0]));
	  grub_memmove (current_linep->buf + screen->column,
			unicode_msg,
			size * sizeof (current_linep->buf[0]));
	  grub_free (unicode_msg);

	  for (i = 0; i < screen->nterms; i++)
	    {
	      grub_free (current_linep->pos[i]);
	      current_linep->pos[i] = 0;
	    }

	  for (i = 0; i < screen->nterms; i++)
	    screen->terms[i].orig_num = get_logical_num_lines (current_linep,
						 &screen->terms[i]);
	  current_linep->len += size;

	  /* Update the dirty region.  */
	  if (region_start > screen->line)
	    {
	      region_start = screen->line;
	      region_column = screen->column;
	    }

	  for (i = 0; i < screen->nterms; i++)
	    {
	      int new_num = get_logical_num_lines (current_linep,
						   &screen->terms[i]);
	      if (screen->terms[i].orig_num != new_num)
		{
		  screen->terms[i].mode = ALL_LINES;
		  screen->terms[i].down = 1; /* XXX not optimal.  */
		}
	      else if (screen->terms[i].mode != ALL_LINES)
		screen->terms[i].mode = SINGLE_LINE;
	    }

	  /* Move the cursor.  */
	  advance_to (screen, screen->column + size);

	  screen->real_column = screen->column;
	  s = p;
	}
    }

  if (update)
    for (i = 0; i < screen->nterms; i++)
      update_screen (screen, &screen->terms[i],
		     region_start, region_column, 0, screen->terms[i].down,
		     screen->terms[i].mode);

  return 1;
}

/* Release the resource allocated for SCREEN.  */
static void
destroy_screen (struct screen *screen)
{
  int i;

  if (screen->lines)
    for (i = 0; i < screen->num_lines; i++)
      {
	struct line *linep = screen->lines + i;

	if (linep)
	  {
	    unsigned j;
	    if (linep->pos)
	      for (j = 0; j < screen->nterms; j++)
		grub_free (linep->pos[j]);

	    grub_free (linep->buf);
	    grub_free (linep->pos);
	  }
      }

  grub_free (screen->killed_text);
  grub_free (screen->lines);
  grub_free (screen->terms);
  grub_free (screen);
}

/* Make a new screen.  */
static struct screen *
make_screen (grub_menu_entry_t entry)
{
  struct screen *screen;
  unsigned i;

  /* Initialize the screen.  */
  screen = grub_zalloc (sizeof (*screen));
  if (! screen)
    return 0;

  screen->submenu = entry->submenu;

  screen->num_lines = 1;
  screen->lines = grub_malloc (sizeof (struct line));
  if (! screen->lines)
    goto fail;

  /* Initialize the first line which must be always present.  */
  if (! init_line (screen, screen->lines))
    goto fail;

  insert_string (screen, (char *) entry->sourcecode, 0);

  /* Reset the cursor position.  */
  screen->column = 0;
  screen->real_column = 0;
  screen->line = 0;
  for (i = 0; i < screen->nterms; i++)
    {
      screen->terms[i].y_line_start = 0;
    }

  return screen;

 fail:
  destroy_screen (screen);
  return 0;
}

static int
forward_char (struct screen *screen, int update)
{
  struct line *linep;

  linep = screen->lines + screen->line;
  if (screen->column < linep->len)
    {
      screen->column = grub_unicode_get_comb_end (screen->lines[screen->line].buf
						  + screen->lines[screen->line].len,
						  screen->lines[screen->line].buf
						  + screen->column + 1)
	- screen->lines[screen->line].buf;
    }
  else if (screen->num_lines > screen->line + 1)
    {
      screen->column = 0;
      screen->line++;
    }

  screen->real_column = screen->column;

  if (update)
    update_screen_all (screen, screen->num_lines, 0, 0, 0, NO_LINE);
  return 1;
}

static int
backward_char (struct screen *screen, int update)
{
  if (screen->column > 0)
    {
      struct grub_unicode_glyph glyph;
      struct line *linep;

      linep = screen->lines + screen->line;

      screen->column--;
      screen->column = grub_unicode_get_comb_start (linep->buf, 
						    linep->buf + screen->column)
	- linep->buf;

      grub_unicode_aglomerate_comb (screen->lines[screen->line].buf + screen->column,
				    screen->lines[screen->line].len - screen->column,
				    &glyph);
      screen->column = grub_unicode_get_comb_start (linep->buf, 
						    linep->buf + screen->column)
	- linep->buf;

      grub_unicode_destroy_glyph (&glyph);
    }
  else if (screen->line > 0)
    {
      screen->line--;
      screen->column = screen->lines[screen->line].len;
    }

  screen->real_column = screen->column;

  if (update)
    update_screen_all (screen, screen->num_lines, 0, 0, 0, NO_LINE);

  return 1;
}

static int
previous_line (struct screen *screen, int update)
{
  if (screen->line > 0)
    {
      struct line *linep;
      int col;

      screen->line--;

      linep = screen->lines + screen->line;
      if (linep->len < screen->real_column)
	col = linep->len;
      else
	col = screen->real_column;

      screen->column = 0;
      advance_to (screen, col);
    }
  else
    {
      screen->column = 0;
    }

  if (update)
    update_screen_all (screen, screen->num_lines, 0, 0, 0, NO_LINE);

  return 1;
}

static int
next_line (struct screen *screen, int update)
{
  if (screen->line < screen->num_lines - 1)
    {
      struct line *linep;
      int c;

      /* How many physical lines from the current position
	 to the last physical line?  */
      linep = screen->lines + screen->line;

      screen->line++;
      if ((linep + 1)->len < screen->real_column)
	c = (linep + 1)->len;
      else
	c = screen->real_column;
      screen->column = 0;

      advance_to (screen, c);
    }
  else
    advance_to (screen, screen->lines[screen->line].len);

  if (update)
    update_screen_all (screen, screen->num_lines, 0, 0, 0, NO_LINE);

  return 1;
}

static int
beginning_of_line (struct screen *screen, int update)
{
  screen->column = screen->real_column = 0;

  if (update)
    update_screen_all (screen, screen->num_lines, 0, 0, 0, NO_LINE);

  return 1;
}

static int
end_of_line (struct screen *screen, int update)
{
  advance_to (screen, screen->lines[screen->line].len);

  if (update)
    update_screen_all (screen, screen->num_lines, 0, 0, 0, NO_LINE);

  return 1;
}

static int
delete_char (struct screen *screen, int update)
{
  struct line *linep;
  int start = screen->num_lines;
  int column = 0;

  linep = screen->lines + screen->line;
  if (linep->len > screen->column)
    {
      unsigned i;

      for (i = 0; i < screen->nterms; i++)
	screen->terms[i].orig_num = get_logical_num_lines (linep, &screen->terms[i]);

      grub_memmove (linep->buf + screen->column,
		    linep->buf + screen->column + 1,
		    (linep->len - screen->column - 1)
		    * sizeof (linep->buf[0]));
      linep->len--;

      for (i = 0; i < screen->nterms; i++)
	{
	  grub_free (linep->pos[i]);
	  linep->pos[i] = 0;
	}
      start = screen->line;
      column = screen->column;

      screen->real_column = screen->column;

      if (update)
	{
	  for (i = 0; i < screen->nterms; i++)
	    {
	      int new_num;
	      new_num = get_logical_num_lines (linep, &screen->terms[i]);
	      if (screen->terms[i].orig_num != new_num)
		update_screen (screen, &screen->terms[i],
			       start, column, 0, 0, ALL_LINES);
	      else
		update_screen (screen, &screen->terms[i],
			       start, column, 0, 0, SINGLE_LINE);
	    }
	}
    }
  else if (screen->num_lines > screen->line + 1)
    {
      struct line *next_linep;
      unsigned i;

      next_linep = linep + 1;
      if (! ensure_space (linep, next_linep->len))
	return 0;

      grub_memmove (linep->buf + linep->len, next_linep->buf,
		    next_linep->len * sizeof (linep->buf[0]));
      linep->len += next_linep->len;
      for (i = 0; i < screen->nterms; i++)
	{
	  grub_free (linep->pos[i]);
	  linep->pos[i] = 0;
	}

      grub_free (next_linep->buf);
      grub_memmove (next_linep,
		    next_linep + 1,
		    (screen->num_lines - screen->line - 2)
		    * sizeof (struct line));
      screen->num_lines--;

      start = screen->line;
      column = screen->column;

      screen->real_column = screen->column;
      if (update)
	update_screen_all (screen, start, column, 0, 1, ALL_LINES);
    }

  return 1;
}

static int
backward_delete_char (struct screen *screen, int update)
{
  int saved_column;
  int saved_line;

  saved_column = screen->column;
  saved_line = screen->line;

  if (! backward_char (screen, 0))
    return 0;

  if (saved_column != screen->column || saved_line != screen->line)
    if (! delete_char (screen, update))
      return 0;

  return 1;
}

static int
kill_line (struct screen *screen, int continuous, int update)
{
  struct line *linep;
  char *p;
  int size;
  int offset;

  p = screen->killed_text;
  if (! continuous && p)
    p[0] = '\0';

  linep = screen->lines + screen->line;
  size = linep->len - screen->column;

  if (p)
    offset = grub_strlen (p);
  else
    offset = 0;

  if (size > 0)
    {
      unsigned i;

      p = grub_realloc (p, offset + size + 1);
      if (! p)
	return 0;

      grub_memmove (p + offset, linep->buf + screen->column, size);
      p[offset + size] = '\0';

      screen->killed_text = p;

      for (i = 0; i < screen->nterms; i++)
	screen->terms[i].orig_num = get_logical_num_lines (linep, &screen->terms[i]);
      linep->len = screen->column;

      if (update)
	{
	  for (i = 0; i < screen->nterms; i++)
	    {
	      int new_num;
	      new_num = get_logical_num_lines (linep, &screen->terms[i]);
	      if (screen->terms[i].orig_num != new_num)
		update_screen (screen, &screen->terms[i],
			       screen->line, screen->column, 0, 1, ALL_LINES);
	      else
		update_screen (screen, &screen->terms[i],
			       screen->line, screen->column, 0, 0, SINGLE_LINE);
	    }
	}
    }
  else if (screen->line + 1 < screen->num_lines)
    {
      p = grub_realloc (p, offset + 1 + 1);
      if (! p)
	return 0;

      p[offset] = '\n';
      p[offset + 1] = '\0';

      screen->killed_text = p;

      return delete_char (screen, update);
    }

  return 1;
}

static int
yank (struct screen *screen, int update)
{
  if (screen->killed_text)
    return insert_string (screen, screen->killed_text, update);

  return 1;
}

static int
open_line (struct screen *screen, int update)
{
  if (! insert_string (screen, "\n", 0))
    return 0;

  if (! backward_char (screen, 0))
    return 0;

  if (update)
    update_screen_all (screen, screen->line, screen->column, 0, 1, ALL_LINES);

  return 1;
}

/* A completion hook to print items.  */
static void
store_completion (const char *item, grub_completion_type_t type,
		  int count __attribute__ ((unused)))
{
  char *p;

  completion_type = type;

  /* Make sure that the completion buffer has enough room.  */
  if (completion_buffer.max_len < (completion_buffer.len
				   + (int) grub_strlen (item) + 1 + 1))
    {
      grub_size_t new_len;

      new_len = completion_buffer.len + grub_strlen (item) + 80;
      p = grub_realloc (completion_buffer.buf, new_len);
      if (! p)
	{
	  /* Possibly not fatal.  */
	  grub_errno = GRUB_ERR_NONE;
	  return;
	}
      p[completion_buffer.len] = 0;
      completion_buffer.buf = p;
      completion_buffer.max_len = new_len;
    }

  p = completion_buffer.buf + completion_buffer.len;
  if (completion_buffer.len != 0)
    {
      *p++ = ' ';
      completion_buffer.len++;
    }
  grub_strcpy (p, item);
  completion_buffer.len += grub_strlen (item);
}

static int
complete (struct screen *screen, int continuous, int update)
{
  struct line *linep;
  int restore;
  char *insert;
  static int count = -1;
  unsigned i;
  grub_uint32_t *ucs4;
  grub_size_t buflen;
  grub_ssize_t ucs4len;
  char *u8;

  if (continuous)
    count++;
  else
    count = 0;

  completion_buffer.buf = 0;
  completion_buffer.len = 0;
  completion_buffer.max_len = 0;

  linep = screen->lines + screen->line;
  u8 = grub_ucs4_to_utf8_alloc (linep->buf, screen->column);
  if (!u8)
    return 1;

  insert = grub_normal_do_completion (u8, &restore, store_completion);
  
  if (completion_buffer.buf)
    {
      buflen = grub_strlen (completion_buffer.buf);
      ucs4 = grub_calloc (buflen + 1, sizeof (grub_uint32_t));
      
      if (!ucs4)
	{
	  grub_print_error ();
	  grub_errno = GRUB_ERR_NONE;
	  return 1;
	}

      ucs4len = grub_utf8_to_ucs4 (ucs4, buflen,
				   (grub_uint8_t *) completion_buffer.buf,
				   buflen, 0);
      ucs4[ucs4len] = 0;

      if (restore)
	for (i = 0; i < screen->nterms; i++)
	  {
	    unsigned width = grub_term_width (screen->terms[i].term);
	    if (width > 2)
	      width -= 2;
	    if (width > 15)
	      width -= 6;
	    unsigned num_sections = ((completion_buffer.len
				      + width - 1)
				     / width);
	    grub_uint32_t *endp;
	    struct grub_term_coordinate pos;
	    grub_uint32_t *p = ucs4;

	    pos = grub_term_getxy (screen->terms[i].term);

	    screen->completion_shown = 1;

	    grub_term_gotoxy (screen->terms[i].term,
			      (struct grub_term_coordinate) { 0,
				  screen->terms[i].geo.timeout_y });
	    if (screen->terms[i].geo.timeout_lines >= 2)
	      {
		grub_puts_terminal ("   ", screen->terms[i].term);
		switch (completion_type)
		  {
		  case GRUB_COMPLETION_TYPE_COMMAND:
		    grub_puts_terminal (_("Possible commands are:"),
					screen->terms[i].term);
		    break;
		  case GRUB_COMPLETION_TYPE_DEVICE:
		    grub_puts_terminal (_("Possible devices are:"),
					screen->terms[i].term);
		    break;
		  case GRUB_COMPLETION_TYPE_FILE:
		    grub_puts_terminal (_("Possible files are:"),
					screen->terms[i].term);
		    break;
		  case GRUB_COMPLETION_TYPE_PARTITION:
		    grub_puts_terminal (_("Possible partitions are:"),
					screen->terms[i].term);
		    break;
		  case GRUB_COMPLETION_TYPE_ARGUMENT:
		    grub_puts_terminal (_("Possible arguments are:"),
					screen->terms[i].term);
		    break;
		  default:
		    grub_puts_terminal (_("Possible things are:"),
					screen->terms[i].term);
		    break;
		  }

		grub_puts_terminal ("\n    ", screen->terms[i].term);
	      }

	    p += ((unsigned) count % num_sections) * width;
	    endp = p + width;

	    if (p != ucs4)
	      grub_putcode (GRUB_UNICODE_LEFTARROW, screen->terms[i].term);
	    else
	      grub_putcode (' ', screen->terms[i].term);

	    grub_print_ucs4 (p, ucs4 + ucs4len < endp ? ucs4 + ucs4len : endp,
			     0, 0, screen->terms[i].term);

	    if (ucs4 + ucs4len > endp)
	      grub_putcode (GRUB_UNICODE_RIGHTARROW, screen->terms[i].term);
	    grub_term_gotoxy (screen->terms[i].term, pos);
	  }
    }

  if (insert)
    {
      insert_string (screen, insert, update);
      count = -1;
      grub_free (insert);
    }
  else if (update)
    grub_refresh ();

  grub_free (completion_buffer.buf);
  return 1;
}

/* Clear displayed completions.  */
static void
clear_completions (struct per_term_screen *term_screen)
{
  struct grub_term_coordinate pos;
  unsigned j;
  int i;

  pos = grub_term_getxy (term_screen->term);
  grub_term_gotoxy (term_screen->term,
		    (struct grub_term_coordinate) { 0,
			term_screen->geo.timeout_y });

  for (i = 0; i < term_screen->geo.timeout_lines; i++)
    {
      for (j = 0; j < grub_term_width (term_screen->term) - 1; j++)
	grub_putcode (' ', term_screen->term);
      if (i + 1 < term_screen->geo.timeout_lines)
	grub_putcode ('\n', term_screen->term);
    }

  grub_term_gotoxy (term_screen->term, pos);
  grub_term_refresh (term_screen->term);
}

static void
clear_completions_all (struct screen *screen)
{
  unsigned i;

  for (i = 0; i < screen->nterms; i++)
    clear_completions (&screen->terms[i]);
}

/* Execute the command list in the screen SCREEN.  */
static int
run (struct screen *screen)
{
  char *script;
  int errs_before;
  grub_menu_t menu = NULL;
  char *dummy[1] = { NULL };

  grub_cls ();
  grub_printf ("  ");
  grub_printf_ (N_("Booting a command list"));
  grub_printf ("\n\n");

  errs_before = grub_err_printed_errors;

  if (screen->submenu)
    {
      grub_env_context_open ();
      menu = grub_zalloc (sizeof (*menu));
      if (! menu)
	return 0;
      grub_env_set_menu (menu);
    }

  /* Execute the script, line for line.  */
  {
    int i;
    grub_size_t size = 0, tot_size = 0;

    for (i = 0; i < screen->num_lines; i++)
      tot_size += grub_get_num_of_utf8_bytes (screen->lines[i].buf,
					      screen->lines[i].len) + 1;

    script = grub_malloc (tot_size + 1);
    if (! script)
      return 0;

    for (i = 0; i < screen->num_lines; i++)
      {
	size += grub_ucs4_to_utf8 (screen->lines[i].buf, screen->lines[i].len,
				   (grub_uint8_t *) script + size,
				   tot_size - size);
	script[size++] = '\n';
      }
    script[size] = '\0';
  }
  grub_script_execute_new_scope (script, 0, dummy);
  grub_free (script);

  if (errs_before != grub_err_printed_errors)
    grub_wait_after_message ();

  if (grub_errno == GRUB_ERR_NONE && grub_loader_is_loaded ())
    /* Implicit execution of boot, only if something is loaded.  */
    grub_command_execute ("boot", 0, 0);

  if (screen->submenu)
    {
      if (menu && menu->size)
	{
	  grub_show_menu (menu, 1, 0);
	  grub_normal_free_menu (menu);
	}
      grub_env_context_close ();
    }

  if (grub_errno != GRUB_ERR_NONE)
    {
      grub_print_error ();
      grub_errno = GRUB_ERR_NONE;
      grub_wait_after_message ();
    }

  return 1;
}

/* Edit a menu entry with an Emacs-like interface.  */
void
grub_menu_entry_run (grub_menu_entry_t entry)
{
  struct screen *screen;
  int prev_c;
  grub_err_t err = GRUB_ERR_NONE;
  unsigned i;
  grub_term_output_t term;

  err = grub_auth_check_authentication (NULL);

  if (err)
    {
      grub_print_error ();
      grub_errno = GRUB_ERR_NONE;
      return;
    }

  screen = make_screen (entry);
  if (! screen)
    return;

  screen->terms = NULL;

 refresh:
  grub_free (screen->terms);
  screen->nterms = 0;
  FOR_ACTIVE_TERM_OUTPUTS(term)
    screen->nterms++;

  for (i = 0; i < (unsigned) screen->num_lines; i++)
    {
      grub_free (screen->lines[i].pos);
      screen->lines[i].pos = grub_calloc (screen->nterms, sizeof (screen->lines[i].pos[0]));
      if (! screen->lines[i].pos)
	{
	  grub_print_error ();
	  destroy_screen (screen);
	  grub_errno = GRUB_ERR_NONE;
	  return;
	}
    }

  screen->terms = grub_calloc (screen->nterms, sizeof (screen->terms[0]));
  if (!screen->terms)
    {
      grub_print_error ();
      destroy_screen (screen);
      grub_errno = GRUB_ERR_NONE;
      return;
    }
  i = 0;
  FOR_ACTIVE_TERM_OUTPUTS(term)
  {
    screen->terms[i].term = term;
    screen->terms[i].y_line_start = 0;
    i++;
  }
  /* Draw the screen.  */
  for (i = 0; i < screen->nterms; i++)
    grub_menu_init_page (0, 1, &screen->terms[i].geo,
			 screen->terms[i].term);
  update_screen_all (screen, 0, 0, 1, 1, ALL_LINES);
  for (i = 0; i < screen->nterms; i++)
    grub_term_setcursor (screen->terms[i].term, 1);
  prev_c = '\0';

  while (1)
    {
      int c = grub_getkey ();

      if (screen->completion_shown)
	{
	  clear_completions_all (screen);
	  screen->completion_shown = 0;
	}

      if (grub_normal_exit_level)
	{
	  destroy_screen (screen);
	  return;
	}

      switch (c)
	{
	case GRUB_TERM_KEY_UP:
	case GRUB_TERM_CTRL | 'p':
	  if (! previous_line (screen, 1))
	    goto fail;
	  break;

	case GRUB_TERM_CTRL | 'n':
	case GRUB_TERM_KEY_DOWN:
	  if (! next_line (screen, 1))
	    goto fail;
	  break;

	case GRUB_TERM_CTRL | 'f':
	case GRUB_TERM_KEY_RIGHT:
	  if (! forward_char (screen, 1))
	    goto fail;
	  break;

	case GRUB_TERM_CTRL | 'b':
	case GRUB_TERM_KEY_LEFT:
	  if (! backward_char (screen, 1))
	    goto fail;
	  break;

	case GRUB_TERM_CTRL | 'a':
	case GRUB_TERM_KEY_HOME:
	  if (! beginning_of_line (screen, 1))
	    goto fail;
	  break;

	case GRUB_TERM_CTRL | 'e':
	case GRUB_TERM_KEY_END:
	  if (! end_of_line (screen, 1))
	    goto fail;
	  break;

	case GRUB_TERM_CTRL | 'i':
	case '\t':
	  if (! complete (screen, prev_c == c, 1))
	    goto fail;
	  break;

	case GRUB_TERM_CTRL | 'd':
	case GRUB_TERM_KEY_DC:
	  if (! delete_char (screen, 1))
	    goto fail;
	  break;

	case GRUB_TERM_CTRL | 'h':
	case '\b':
	  if (! backward_delete_char (screen, 1))
	    goto fail;
	  break;

	case GRUB_TERM_CTRL | 'k':
	  if (! kill_line (screen, prev_c == c, 1))
	    goto fail;
	  break;

	case GRUB_TERM_CTRL | 'u':
	  /* FIXME: What behavior is good for this key?  */
	  break;

	case GRUB_TERM_CTRL | 'y':
	  if (! yank (screen, 1))
	    goto fail;
	  break;

	case GRUB_TERM_CTRL | 'l':
	  /* FIXME: centering.  */
	  goto refresh;

	case GRUB_TERM_CTRL | 'o':
	  if (! open_line (screen, 1))
	    goto fail;
	  break;

	case '\n':
	case '\r':
	  if (! insert_string (screen, "\n", 1))
	    goto fail;
	  break;

	case '\e':
	  destroy_screen (screen);
	  return;

	case GRUB_TERM_CTRL | 'c':
	case GRUB_TERM_KEY_F2:
	  grub_cmdline_run (1, 0);
	  goto refresh;

	case GRUB_TERM_CTRL | 'x':
	case GRUB_TERM_KEY_F10:
	  run (screen);
	  goto refresh;

	case GRUB_TERM_CTRL | 'r':
	case GRUB_TERM_CTRL | 's':
	case GRUB_TERM_CTRL | 't':
	  /* FIXME */
	  break;

	default:
	  if (grub_isprint (c))
	    {
	      char buf[2];

	      buf[0] = c;
	      buf[1] = '\0';
	      if (! insert_string (screen, buf, 1))
		goto fail;
	    }
	  break;
	}

      prev_c = c;
    }

 fail:
  destroy_screen (screen);

  grub_cls ();
  grub_print_error ();
  grub_errno = GRUB_ERR_NONE;
  grub_xputs ("\n");
  grub_printf_ (N_("Press any key to continue..."));
  (void) grub_getkey ();
}
