/*
 * This file is part of the libpayload project.
 *
 * Copyright (C) 2007 Uwe Hermann <uwe@hermann-uwe.de>
 * Copyright (C) 2008 Advanced Micro Devices, Inc.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. The name of the author may not be used to endorse or promote products
 *    derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

/*
 * This file handles reading keystrokes from serial and the console
 * and "cooking" them so that they are correct for curses.
 * Also, implement key related functions (mainly wgetch)
 *
 * TODO:
 * Actually cook the serial (handle special keys)
 */

#include <libpayload-config.h>
#include <usb/usb.h>
#include "local.h"

static int _halfdelay = 0;

/* ============== Serial ==================== */

#if IS_ENABLED(CONFIG_LP_SERIAL_CONSOLE)
/* We treat serial like a vt100 terminal.  For now we
   do the cooking in here, but we should probably eventually
   pass it to dedicated vt100 code */

static int getkeyseq(char *buffer, int len, int max)
{
	int i;

	while (1) {
		for(i = 0; i < 75; i++) {
			if (serial_havechar())
				break;
			mdelay(1);
		}

		if (i == 75)
			return len;

		buffer[len++] = serial_getchar();
		if (len == max)
			return len;
	}
}

static struct {
	const char *seq;
	int key;
} escape_codes[] = {
	{ "[A", KEY_UP },
	{ "[B", KEY_DOWN },
	{ "[C", KEY_RIGHT },
	{ "[D", KEY_LEFT },
	{ "[F", KEY_END },
	{ "[H", KEY_HOME },
	{ "[2~", KEY_IC },
	{ "[3~", KEY_DC },
	{ "[5~", KEY_PPAGE },
	{ "[6~", KEY_NPAGE },
	{ "OP", KEY_F(1) },
	{ "OQ", KEY_F(2) },
	{ "OR", KEY_F(3) },
	{ "OS", KEY_F(4) },
	{ "[15~", KEY_F(5) },
	{ "[17~", KEY_F(6) },
	{ "[18~", KEY_F(7) },
	{ "[19~", KEY_F(8) },
	{ "[20~", KEY_F(9) },
	{ "[21~", KEY_F(10) },
	{ "[23~", KEY_F(11) },
	{ "[24~", KEY_F(12) },
	{ NULL },
};

static int handle_escape(void)
{
	char buffer[5];
	int len = getkeyseq(buffer, 0, sizeof(buffer));
	int i, t;

	if (len == 0)
		return 27;

	for(i = 0; escape_codes[i].seq != NULL; i++) {
		const char *p = escape_codes[i].seq;

		for(t = 0; t < len; t++) {
			if (!*p || *p != buffer[t])
				break;
			p++;
		}

		if (t == len)
			return escape_codes[i].key;
	}

	return 0;
}

static int cook_serial(unsigned char ch)
{
	switch(ch) {
	case 8:
		return KEY_BACKSPACE;

	case 13:
		return KEY_ENTER;

	case 27:
		return handle_escape();

	default:
		return ch;
	}
}
#endif

/* ================ Keyboard ================ */

static int curses_getchar(int _delay)
{
#if IS_ENABLED(CONFIG_LP_USB_HID) || IS_ENABLED(CONFIG_LP_PC_KEYBOARD) || \
	IS_ENABLED(CONFIG_LP_SERIAL_CONSOLE)
	unsigned short c;
#endif

	do {
#if IS_ENABLED(CONFIG_LP_USB_HID)
		usb_poll();
		if ((curses_flags & F_ENABLE_CONSOLE) &&
		    usbhid_havechar()) {
			c = usbhid_getchar();
			if (c != 0) return c;
		}
#endif
#if IS_ENABLED(CONFIG_LP_PC_KEYBOARD)
		if ((curses_flags & F_ENABLE_CONSOLE) &&
		    keyboard_havechar()) {
			c = keyboard_getchar();
			if (c != 0) return c;
		}
#endif

#if IS_ENABLED(CONFIG_LP_SERIAL_CONSOLE)
		if ((curses_flags & F_ENABLE_SERIAL) &&
		    serial_havechar()) {
			c = serial_getchar();
			return cook_serial(c);
		}
#endif

		if (_delay == 0) {
			break;
		} else if (_delay >= 10) {
			mdelay(10);
			_delay -= 10;
		} else if (_delay > 0) {
			mdelay(_delay);
			_delay = 0;
		}
	} while (1);

	return ERR;
}

/* === Public functions === */

int wgetch(WINDOW *win)
{
	int _delay = -1;

	if (_halfdelay)
		_delay = _halfdelay;
	else
		_delay = win->_delay;

	return curses_getchar(_delay);
}

int nodelay(WINDOW *win, NCURSES_BOOL flag)
{
	win->_delay = flag ? 0 : -1;
	return 0;
}

int halfdelay(int tenths)
{
	if (tenths > 255)
		return ERR;

	_halfdelay = tenths;
	return 0;
}

int nocbreak(void)
{
	/* Remove half delay timeout. */
	_halfdelay = 0;
	return 0;
}

#if IS_ENABLED(CONFIG_LP_VGA_VIDEO_CONSOLE)
void curses_enable_vga(int state)
{
	if (state)
		curses_flags |= F_ENABLE_CONSOLE;
	else
		curses_flags &= ~F_ENABLE_CONSOLE;
}

int curses_vga_enabled(void)
{
	return (curses_flags & F_ENABLE_CONSOLE) != 0;
}
#else
void curses_enable_vga(int state) { }
int curses_vga_enabled(void) { return 0; }
#endif

#if IS_ENABLED(CONFIG_LP_SERIAL_CONSOLE)
void curses_enable_serial(int state)
{
	if (state)
		curses_flags |= F_ENABLE_SERIAL;
	else
		curses_flags &= ~F_ENABLE_SERIAL;
}

int curses_serial_enabled(void)
{
	return (curses_flags & F_ENABLE_SERIAL) != 0;
}

#else
void curses_enable_serial(int state) { }
int curses_serial_enabled(void) { return 0; }
#endif
