use web_sys::KeyboardEvent;
use spectrusty::peripherals::{ZXKeyboardMap,
joystick::{JoystickInterface, Directions},
serial::KeypadKeys
};
type ZXk = ZXKeyboardMap;
pub fn map_direct_key(key: &str) -> ZXKeyboardMap {
match key {
"Digit1" => ZXk::N1,
"Digit2" => ZXk::N2,
"Digit3" => ZXk::N3,
"Digit4" => ZXk::N4,
"Digit5" => ZXk::N5,
"Digit6" => ZXk::N6,
"Digit7" => ZXk::N7,
"Digit8" => ZXk::N8,
"Digit9" => ZXk::N9,
"Digit0" => ZXk::N0,
"KeyA" => ZXk::A,
"KeyB" => ZXk::B,
"KeyC" => ZXk::C,
"KeyD" => ZXk::D,
"KeyE" => ZXk::E,
"KeyF" => ZXk::F,
"KeyG" => ZXk::G,
"KeyH" => ZXk::H,
"KeyI" => ZXk::I,
"KeyJ" => ZXk::J,
"KeyK" => ZXk::K,
"KeyL" => ZXk::L,
"KeyM" => ZXk::M,
"KeyN" => ZXk::N,
"KeyO" => ZXk::O,
"KeyP" => ZXk::P,
"KeyQ" => ZXk::Q,
"KeyR" => ZXk::R,
"KeyS" => ZXk::S,
"KeyT" => ZXk::T,
"KeyU" => ZXk::U,
"KeyV" => ZXk::V,
"KeyW" => ZXk::W,
"KeyX" => ZXk::X,
"KeyY" => ZXk::Y,
"KeyZ" => ZXk::Z,
"ShiftLeft"|"ShiftRight" => ZXk::CS,
"ControlLeft"|"ControlRight" => ZXk::SS,
"Space" => ZXk::BR,
"Enter" => ZXk::EN,
_ => ZXk::empty()
}
}
pub fn map_combined_keys(key: &str, pressed: bool, shift_down: bool) -> (ZXKeyboardMap, bool) {
let mut removecs = false;
let zxk = match key {
"ArrowLeft" => ZXk::CS|ZXk::N5,
"ArrowDown" => ZXk::CS|ZXk::N6,
"ArrowUp" => ZXk::CS|ZXk::N7,
"ArrowRight" => ZXk::CS|ZXk::N8,
"CapsLock" => ZXk::CS|ZXk::N2,
"Backspace" => ZXk::CS|ZXk::N0,
"AltLeft"|"AltRight" => ZXk::CS|ZXk::SS,
"BracketLeft" => ZXk::SS|ZXk::N8,
"BracketRight" => ZXk::SS|ZXk::N9,
"Backquote" => ZXk::SS|ZXk::X,
"Minus" if pressed => if shift_down {
removecs = true;
ZXk::SS|ZXk::N0
}
else {
ZXk::SS|ZXk::J
},
"Minus" => ZXk::SS|ZXk::J|ZXk::N0,
"Equal" if pressed => if shift_down {
removecs = true;
ZXk::SS|ZXk::K
}
else {
ZXk::SS|ZXk::L
},
"Equal" => ZXk::SS|ZXk::K|ZXk::L,
"Comma" if pressed => if shift_down {
removecs = true;
ZXk::SS|ZXk::R
}
else {
ZXk::SS|ZXk::N
},
"Comma" => ZXk::SS|ZXk::R|ZXk::N,
"Period" if pressed => if shift_down {
removecs = true;
ZXk::SS|ZXk::T
}
else {
ZXk::SS|ZXk::M
},
"Period" => ZXk::SS|ZXk::T|ZXk::M,
"Quote" if pressed => if shift_down {
removecs = true;
ZXk::SS|ZXk::P
}
else {
ZXk::SS|ZXk::N7
},
"Quote" => ZXk::SS|ZXk::P|ZXk::N7,
"Slash" if pressed => if shift_down {
removecs = true;
ZXk::SS|ZXk::C
}
else {
ZXk::SS|ZXk::V
},
"Slash" => ZXk::SS|ZXk::C|ZXk::V,
"Semicolon" if pressed => if shift_down {
removecs = true;
ZXk::SS|ZXk::Z
}
else {
ZXk::SS|ZXk::O
},
"Semicolon" => ZXk::SS|ZXk::Z|ZXk::O,
k => map_direct_key(k)
};
(zxk, removecs)
}
pub fn update_keymap(
mut cur: ZXKeyboardMap,
key: &str,
pressed: bool,
shift_down: bool,
ctrl_down: bool
) -> ZXKeyboardMap
{
let (chg, removecs) = map_combined_keys(key, pressed, shift_down);
if pressed {
cur.insert(chg);
if removecs {
cur.remove(ZXk::CS);
}
}
else {
cur.remove(chg);
}
if cur.is_empty() {
if shift_down {
cur.insert(ZXk::CS);
}
if ctrl_down {
cur.insert(ZXk::SS);
}
}
cur
}
pub fn update_keymap_with_event(
cur: ZXKeyboardMap,
event: &KeyboardEvent,
pressed: bool,
) -> ZXKeyboardMap
{
let shift_down = event.shift_key();
let ctrl_down = event.ctrl_key();
let key = event.code();
update_keymap(cur, &key, pressed, shift_down, ctrl_down)
}
pub fn map_keypad_key(key: &str, parens: bool) -> KeypadKeys {
match key {
"NumpadDivide" if parens => KeypadKeys::LPAREN,
"NumpadDivide" => KeypadKeys::DIVIDE,
"NumpadMultiply" if parens => KeypadKeys::RPAREN,
"NumpadMultiply" => KeypadKeys::MULTIPLY,
"NumpadSubtract" => KeypadKeys::MINUS,
"NumpadAdd" => KeypadKeys::PLUS,
"NumpadEnter" => KeypadKeys::ENTER,
"Numpad1" => KeypadKeys::N1,
"Numpad2" => KeypadKeys::N2,
"Numpad3" => KeypadKeys::N3,
"Numpad4" => KeypadKeys::N4,
"Numpad5" => KeypadKeys::N5,
"Numpad6" => KeypadKeys::N6,
"Numpad7" => KeypadKeys::N7,
"Numpad8" => KeypadKeys::N8,
"Numpad9" => KeypadKeys::N9,
"Numpad0" => KeypadKeys::N0,
"NumpadDecimal" => KeypadKeys::PERIOD,
_ => KeypadKeys::empty()
}
}
pub fn update_keypad_keys(mut cur: KeypadKeys, key: &str, pressed: bool, parens: bool) -> KeypadKeys {
let chg = map_keypad_key(key, parens);
if !chg.is_empty() {
cur.set(chg, pressed);
}
cur
}
#[inline]
pub fn update_keypad_keys_with_event(cur: KeypadKeys, event: &KeyboardEvent, pressed: bool) -> KeypadKeys {
let parens = event.get_modifier_state("NumLock");
let key = event.code();
update_keypad_keys(cur, &key, pressed, parens)
}
pub fn map_key_to_direction(key: &str) -> Directions {
match key {
"ArrowUp" => Directions::UP,
"ArrowRight" => Directions::RIGHT,
"ArrowDown" => Directions::DOWN,
"ArrowLeft" => Directions::LEFT,
_ => Directions::empty()
}
}
#[inline]
pub fn update_joystick_from_key_event<'a, J, F>(
key: &str,
pressed: bool,
fire_key: &str,
get_joy: F
) -> bool
where J: 'a + JoystickInterface + ?Sized,
F: FnOnce() -> Option<&'a mut J>
{
super::update_joystick_from_key_event(key, pressed, fire_key, map_key_to_direction, get_joy)
}