/*
 *  GRUB  --  GRand Unified Bootloader
 *  Copyright (C) 2006,2007,2008  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/term.h>
#include <grub/misc.h>
#include <grub/types.h>
#include <grub/err.h>
#include <grub/efi/efi.h>
#include <grub/efi/api.h>
#include <grub/efi/console.h>

static grub_uint32_t
map_char (grub_uint32_t c)
{
  /* Map some unicode characters to the EFI character.  */
  switch (c)
    {
    case GRUB_UNICODE_LEFTARROW:
      c = GRUB_UNICODE_BLACK_LEFT_TRIANGLE;
      break;
    case GRUB_UNICODE_UPARROW:
      c = GRUB_UNICODE_BLACK_UP_TRIANGLE;
      break;
    case GRUB_UNICODE_RIGHTARROW:
      c = GRUB_UNICODE_BLACK_RIGHT_TRIANGLE;
      break;
    case GRUB_UNICODE_DOWNARROW:
      c = GRUB_UNICODE_BLACK_DOWN_TRIANGLE;
      break;
    case GRUB_UNICODE_HLINE:
      c = GRUB_UNICODE_LIGHT_HLINE;
      break;
    case GRUB_UNICODE_VLINE:
      c = GRUB_UNICODE_LIGHT_VLINE;
      break;
    case GRUB_UNICODE_CORNER_UL:
      c = GRUB_UNICODE_LIGHT_CORNER_UL;
      break;
    case GRUB_UNICODE_CORNER_UR:
      c = GRUB_UNICODE_LIGHT_CORNER_UR;
      break;
    case GRUB_UNICODE_CORNER_LL:
      c = GRUB_UNICODE_LIGHT_CORNER_LL;
      break;
    case GRUB_UNICODE_CORNER_LR:
      c = GRUB_UNICODE_LIGHT_CORNER_LR;
      break;
    }

  return c;
}

static void
grub_console_putchar (struct grub_term_output *term __attribute__ ((unused)),
		      const struct grub_unicode_glyph *c)
{
  grub_efi_char16_t str[2 + 30];
  grub_efi_simple_text_output_interface_t *o;
  unsigned i, j;

  if (grub_efi_is_finished)
    return;

  o = grub_efi_system_table->con_out;

  /* For now, do not try to use a surrogate pair.  */
  if (c->base > 0xffff)
    str[0] = '?';
  else
    str[0] = (grub_efi_char16_t)  map_char (c->base & 0xffff);
  j = 1;
  for (i = 0; i < c->ncomb && j + 1 < ARRAY_SIZE (str); i++)
    if (c->base < 0xffff)
      str[j++] = grub_unicode_get_comb (c)[i].code;
  str[j] = 0;

  /* Should this test be cached?  */
  if ((c->base > 0x7f || c->ncomb)
      && efi_call_2 (o->test_string, o, str) != GRUB_EFI_SUCCESS)
    return;

  efi_call_2 (o->output_string, o, str);
}

const unsigned efi_codes[] =
  {
    0, GRUB_TERM_KEY_UP, GRUB_TERM_KEY_DOWN, GRUB_TERM_KEY_RIGHT,
    GRUB_TERM_KEY_LEFT, GRUB_TERM_KEY_HOME, GRUB_TERM_KEY_END, GRUB_TERM_KEY_INSERT,
    GRUB_TERM_KEY_DC, GRUB_TERM_KEY_PPAGE, GRUB_TERM_KEY_NPAGE, GRUB_TERM_KEY_F1,
    GRUB_TERM_KEY_F2, GRUB_TERM_KEY_F3, GRUB_TERM_KEY_F4, GRUB_TERM_KEY_F5,
    GRUB_TERM_KEY_F6, GRUB_TERM_KEY_F7, GRUB_TERM_KEY_F8, GRUB_TERM_KEY_F9,
    GRUB_TERM_KEY_F10, GRUB_TERM_KEY_F11, GRUB_TERM_KEY_F12, '\e'
  };

static int
grub_efi_translate_key (grub_efi_input_key_t key)
{
  if (key.scan_code == 0)
    {
      /* Some firmware implementations use VT100-style codes against the spec.
	 This is especially likely if driven by serial.
       */
      if (key.unicode_char < 0x20 && key.unicode_char != 0
	  && key.unicode_char != '\t' && key.unicode_char != '\b'
	  && key.unicode_char != '\n' && key.unicode_char != '\r')
	return GRUB_TERM_CTRL | (key.unicode_char - 1 + 'a');
      else
	return key.unicode_char;
    }
  else if (key.scan_code < ARRAY_SIZE (efi_codes))
    return efi_codes[key.scan_code];

  if ((key.unicode_char >= 0x20 && key.unicode_char <= 0x7f)
      || key.unicode_char == '\t' || key.unicode_char == '\b'
      || key.unicode_char == '\n' || key.unicode_char == '\r')
    return key.unicode_char;

  return GRUB_TERM_NO_KEY;
}

static int
grub_console_getkey_con (struct grub_term_input *term __attribute__ ((unused)))
{
  grub_efi_simple_input_interface_t *i;
  grub_efi_input_key_t key;
  grub_efi_status_t status;

  i = grub_efi_system_table->con_in;
  status = efi_call_2 (i->read_key_stroke, i, &key);

  if (status != GRUB_EFI_SUCCESS)
    return GRUB_TERM_NO_KEY;

  return grub_efi_translate_key(key);
}

static int
grub_console_getkey_ex(struct grub_term_input *term)
{
  grub_efi_key_data_t key_data;
  grub_efi_status_t status;
  grub_efi_uint32_t kss;
  int key = -1;

  grub_efi_simple_text_input_ex_interface_t *text_input = term->data;

  status = efi_call_2 (text_input->read_key_stroke, text_input, &key_data);

  if (status != GRUB_EFI_SUCCESS)
    return GRUB_TERM_NO_KEY;

  kss = key_data.key_state.key_shift_state;
  key = grub_efi_translate_key(key_data.key);

  if (key == GRUB_TERM_NO_KEY)
    return GRUB_TERM_NO_KEY;

  if (kss & GRUB_EFI_SHIFT_STATE_VALID)
    {
      if ((kss & GRUB_EFI_LEFT_SHIFT_PRESSED
	   || kss & GRUB_EFI_RIGHT_SHIFT_PRESSED)
	  && (key & GRUB_TERM_EXTENDED))
	key |= GRUB_TERM_SHIFT;
      if (kss & GRUB_EFI_LEFT_ALT_PRESSED || kss & GRUB_EFI_RIGHT_ALT_PRESSED)
	key |= GRUB_TERM_ALT;
      if (kss & GRUB_EFI_LEFT_CONTROL_PRESSED
	  || kss & GRUB_EFI_RIGHT_CONTROL_PRESSED)
	key |= GRUB_TERM_CTRL;
    }

  return key;
}

static grub_err_t
grub_efi_console_input_init (struct grub_term_input *term)
{
  grub_efi_guid_t text_input_ex_guid =
    GRUB_EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL_GUID;

  if (grub_efi_is_finished)
    return 0;

  grub_efi_simple_text_input_ex_interface_t *text_input = term->data;
  if (text_input)
    return 0;

  text_input = grub_efi_open_protocol(grub_efi_system_table->console_in_handler,
				      &text_input_ex_guid,
				      GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL);
  term->data = (void *)text_input;

  return 0;
}

static int
grub_console_getkey (struct grub_term_input *term)
{
  if (grub_efi_is_finished)
    return 0;

  if (term->data)
    return grub_console_getkey_ex(term);
  else
    return grub_console_getkey_con(term);
}

static struct grub_term_coordinate
grub_console_getwh (struct grub_term_output *term __attribute__ ((unused)))
{
  grub_efi_simple_text_output_interface_t *o;
  grub_efi_uintn_t columns, rows;

  o = grub_efi_system_table->con_out;
  if (grub_efi_is_finished || efi_call_4 (o->query_mode, o, o->mode->mode,
					  &columns, &rows) != GRUB_EFI_SUCCESS)
    {
      /* Why does this fail?  */
      columns = 80;
      rows = 25;
    }

  return (struct grub_term_coordinate) { columns, rows };
}

static struct grub_term_coordinate
grub_console_getxy (struct grub_term_output *term __attribute__ ((unused)))
{
  grub_efi_simple_text_output_interface_t *o;

  if (grub_efi_is_finished)
    return (struct grub_term_coordinate) { 0, 0 };

  o = grub_efi_system_table->con_out;
  return (struct grub_term_coordinate) { o->mode->cursor_column, o->mode->cursor_row };
}

static void
grub_console_gotoxy (struct grub_term_output *term __attribute__ ((unused)),
		     struct grub_term_coordinate pos)
{
  grub_efi_simple_text_output_interface_t *o;

  if (grub_efi_is_finished)
    return;

  o = grub_efi_system_table->con_out;
  efi_call_3 (o->set_cursor_position, o, pos.x, pos.y);
}

static void
grub_console_cls (struct grub_term_output *term __attribute__ ((unused)))
{
  grub_efi_simple_text_output_interface_t *o;
  grub_efi_int32_t orig_attr;

  if (grub_efi_is_finished)
    return;

  o = grub_efi_system_table->con_out;
  orig_attr = o->mode->attribute;
  efi_call_2 (o->set_attributes, o, GRUB_EFI_BACKGROUND_BLACK);
  efi_call_1 (o->clear_screen, o);
  efi_call_2 (o->set_attributes, o, orig_attr);
}

static void
grub_console_setcolorstate (struct grub_term_output *term
			    __attribute__ ((unused)),
			    grub_term_color_state state)
{
  grub_efi_simple_text_output_interface_t *o;

  if (grub_efi_is_finished)
    return;

  o = grub_efi_system_table->con_out;

  switch (state) {
    case GRUB_TERM_COLOR_STANDARD:
      efi_call_2 (o->set_attributes, o, GRUB_TERM_DEFAULT_STANDARD_COLOR
		  & 0x7f);
      break;
    case GRUB_TERM_COLOR_NORMAL:
      efi_call_2 (o->set_attributes, o, grub_term_normal_color & 0x7f);
      break;
    case GRUB_TERM_COLOR_HIGHLIGHT:
      efi_call_2 (o->set_attributes, o, grub_term_highlight_color & 0x7f);
      break;
    default:
      break;
  }
}

static void
grub_console_setcursor (struct grub_term_output *term __attribute__ ((unused)),
			int on)
{
  grub_efi_simple_text_output_interface_t *o;

  if (grub_efi_is_finished)
    return;

  o = grub_efi_system_table->con_out;
  efi_call_2 (o->enable_cursor, o, on);
}

static grub_err_t
grub_efi_console_output_init (struct grub_term_output *term)
{
  grub_efi_set_text_mode (1);
  grub_console_setcursor (term, 1);
  return 0;
}

static grub_err_t
grub_efi_console_output_fini (struct grub_term_output *term)
{
  grub_console_setcursor (term, 0);
  grub_efi_set_text_mode (0);
  return 0;
}

static struct grub_term_input grub_console_term_input =
  {
    .name = "console",
    .getkey = grub_console_getkey,
    .init = grub_efi_console_input_init,
  };

static struct grub_term_output grub_console_term_output =
  {
    .name = "console",
    .init = grub_efi_console_output_init,
    .fini = grub_efi_console_output_fini,
    .putchar = grub_console_putchar,
    .getwh = grub_console_getwh,
    .getxy = grub_console_getxy,
    .gotoxy = grub_console_gotoxy,
    .cls = grub_console_cls,
    .setcolorstate = grub_console_setcolorstate,
    .setcursor = grub_console_setcursor,
    .flags = GRUB_TERM_CODE_TYPE_VISUAL_GLYPHS,
    .progress_update_divisor = GRUB_PROGRESS_FAST
  };

void
grub_console_init (void)
{
  /* FIXME: it is necessary to consider the case where no console control
     is present but the default is already in text mode.  */
  if (! grub_efi_set_text_mode (1))
    {
      grub_error (GRUB_ERR_BAD_DEVICE, "cannot set text mode");
      return;
    }

  grub_term_register_output ("console", &grub_console_term_output);
  grub_term_register_input ("console", &grub_console_term_input);
}

void
grub_console_fini (void)
{
  grub_term_unregister_input (&grub_console_term_input);
  grub_term_unregister_output (&grub_console_term_output);
}
