/*
 * 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 ==================== */

#ifdef 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 defined(CONFIG_LP_USB_HID) || defined(CONFIG_LP_PC_KEYBOARD) || defined(CONFIG_LP_SERIAL_CONSOLE)
	unsigned short c;
#endif

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

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

		if (_delay == 0)
			break;

		if (_delay > 0) {
			mdelay(1);
			_delay--;
		}


	} 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;
}

#ifdef 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

#ifdef 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

