/*
 * Kangaroo Punch MultiPlayer Game Server Mark II
 * Copyright (C) 2020-2021  Scott Duensing
 *
 * This program 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.
 *
 * This program 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 this program.  If not, see <https://www.gnu.org/licenses/>.
 *
 */


#include "keyboard.h"


#define KEYBOARD_READ_EXTENDED   0x10
#define KEYBOARD_CHECK_EXTENDED  0x11
#define KEYBOARD_META_EXTENDED   0x12


enum MetaBitsE {
	META_SHIFT_RIGHT = 0,
	META_SHIFT_LEFT,
	META_CONTROL,
	META_ALT,
	META_SCROLL_LOCKED,
	META_NUM_LOCKED,
	META_CAPS_LOCKED,
	META_INSERT_LOCKED,
	META_CONTROL_LEFT,
	META_ALT_LEFT,
	META_CONTROL_RIGHT,
	META_ALT_RIGHT,
	META_SCROLL_LOCK,
	META_NUM_LOCK,
	META_CAPS_LOCK,
	META_SYSREQ
};


static int8_t  _extended = 0;
static int16_t _key      = 0;
static int16_t _meta     = 0;


uint8_t keyAltGet(void) {
	return 0 != (_meta & (1 << META_ALT)) + (_meta & (1 << META_ALT_LEFT)) + (_meta & (1 << META_ALT_RIGHT));
}


uint8_t keyASCIIGet(void) {
	return LOW_BYTE(_key);
}


uint8_t keyControlGet(void) {
	return 0 != (_meta & (1 << META_CONTROL)) + (_meta & (1 << META_CONTROL_LEFT)) + (_meta & (1 << META_CONTROL_RIGHT));
}


uint8_t keyExtendedGet(void) {
	return _extended;
}


uint8_t keyHit(void) {
	int16_t result = bioskey(KEYBOARD_CHECK_EXTENDED);
	int16_t meta   = bioskey(KEYBOARD_META_EXTENDED);

	if (result > 0) {
		_key  = bioskey(KEYBOARD_READ_EXTENDED);
		_meta = meta;

		// The value returned is a combination of the key's scan code in the high 8 bits
		// and its ASCII code in the low 8 bits. For non-alphanumeric keys, such as the
		// arrow keys, the low 8 bits are zeroed.
		// Extended keys have the E0h prefix in the low 8 bits.

		//logWrite("Raw key = %04X  High = %02X  Low = %02X\n", _key, HIGH_BYTE(_key), LOW_BYTE(_key));

		if (LOW_BYTE(_key) == 0xE0) {
			_extended = 1;
			_key = HIGH_BYTE(_key);
		} else {
			_extended = 0;
		}
		return 1;
	}

	_extended = 0;

	return 0;
}


uint8_t keyScanCodeGet(void) {
	return HIGH_BYTE(_key);
}


uint8_t keyShiftGet(void) {
	return 0 != (_meta & (1 << META_SHIFT_LEFT)) + (_meta & (1 << META_SHIFT_RIGHT));
}


void keyShutdown(void) {
	// Nada for DOS.
}


void keyStartup(void) {
	// Nada for DOS.
}
