use super::WrapElementState;
use bevy::{input::keyboard::KeyboardInput, prelude::KeyCode};
use serde::{Deserialize, Serialize};

#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct WrapKeyboardInput {
    //pub scan_code: u32, FIXME
    pub key_code: Option<WrapKeyCode>,
    pub state: WrapElementState,
}

#[derive(Debug, Copy, Clone, Serialize, Deserialize, PartialEq)]
pub enum WrapKeyCode {
    Key1,
    Key2,
    Key3,
    Key4,
    Key5,
    Key6,
    Key7,
    Key8,
    Key9,
    Key0,

    A,
    B,
    C,
    D,
    E,
    F,
    G,
    H,
    I,
    J,
    K,
    L,
    M,
    N,
    O,
    P,
    Q,
    R,
    S,
    T,
    U,
    V,
    W,
    X,
    Y,
    Z,

    Escape,

    F1,
    F2,
    F3,
    F4,
    F5,
    F6,
    F7,
    F8,
    F9,
    F10,
    F11,
    F12,
    F13,
    F14,
    F15,
    F16,
    F17,
    F18,
    F19,
    F20,
    F21,
    F22,
    F23,
    F24,

    Snapshot,
    Scroll,
    Pause,

    Insert,
    Home,
    Delete,
    End,
    PageDown,
    PageUp,

    Left,
    Up,
    Right,
    Down,

    Back,
    Return,
    Space,

    Compose,

    Caret,

    Numlock,
    Numpad0,
    Numpad1,
    Numpad2,
    Numpad3,
    Numpad4,
    Numpad5,
    Numpad6,
    Numpad7,
    Numpad8,
    Numpad9,

    AbntC1,
    AbntC2,
    NumpadAdd,
    Apostrophe,
    Apps,
    Asterisk,
    Plus,
    At,
    Ax,
    Backslash,
    Calculator,
    Capital,
    Colon,
    Comma,
    Convert,
    NumpadDecimal,
    NumpadDivide,
    Equals,
    Grave,
    Kana,
    Kanji,
    LAlt,
    LBracket,
    LControl,
    LShift,
    LWin,
    Mail,
    MediaSelect,
    MediaStop,
    Minus,
    NumpadMultiply,
    Mute,
    MyComputer,
    NavigateForward,
    NavigateBackward,
    NextTrack,
    NoConvert,
    NumpadComma,
    NumpadEnter,
    NumpadEquals,
    Oem102,
    Period,
    PlayPause,
    Power,
    PrevTrack,
    RAlt,
    RBracket,
    RControl,
    RShift,
    RWin,
    Semicolon,
    Slash,
    Sleep,
    Stop,
    NumpadSubtract,
    Sysrq,
    Tab,
    Underline,
    Unlabeled,
    VolumeDown,
    VolumeUp,
    Wake,
    WebBack,
    WebFavorites,
    WebForward,
    WebHome,
    WebRefresh,
    WebSearch,
    WebStop,
    Yen,
    Copy,
    Paste,
    Cut,
}

impl From<&WrapKeyboardInput> for KeyboardInput {
    fn from(inp: &WrapKeyboardInput) -> Self {
        KeyboardInput {
            scan_code: 0, // FIXME
            key_code: inp.key_code.map(|v| (&v).into()),
            state: (&inp.state).into(),
        }
    }
}

impl From<&KeyboardInput> for WrapKeyboardInput {
    fn from(inp: &KeyboardInput) -> Self {
        WrapKeyboardInput {
            // scan_code: 0, // FIXME
            key_code: inp.key_code.map(|v| (&v).into()),
            state: (&inp.state).into(),
        }
    }
}

impl From<&WrapKeyCode> for KeyCode {
    fn from(wrap_key_code: &WrapKeyCode) -> Self {
        match wrap_key_code {
            WrapKeyCode::Key1 => KeyCode::Key1,
            WrapKeyCode::Key2 => KeyCode::Key2,
            WrapKeyCode::Key3 => KeyCode::Key3,
            WrapKeyCode::Key4 => KeyCode::Key4,
            WrapKeyCode::Key5 => KeyCode::Key5,
            WrapKeyCode::Key6 => KeyCode::Key6,
            WrapKeyCode::Key7 => KeyCode::Key7,
            WrapKeyCode::Key8 => KeyCode::Key8,
            WrapKeyCode::Key9 => KeyCode::Key9,
            WrapKeyCode::Key0 => KeyCode::Key0,
            WrapKeyCode::A => KeyCode::A,
            WrapKeyCode::B => KeyCode::B,
            WrapKeyCode::C => KeyCode::C,
            WrapKeyCode::D => KeyCode::D,
            WrapKeyCode::E => KeyCode::E,
            WrapKeyCode::F => KeyCode::F,
            WrapKeyCode::G => KeyCode::G,
            WrapKeyCode::H => KeyCode::H,
            WrapKeyCode::I => KeyCode::I,
            WrapKeyCode::J => KeyCode::J,
            WrapKeyCode::K => KeyCode::K,
            WrapKeyCode::L => KeyCode::L,
            WrapKeyCode::M => KeyCode::M,
            WrapKeyCode::N => KeyCode::N,
            WrapKeyCode::O => KeyCode::O,
            WrapKeyCode::P => KeyCode::P,
            WrapKeyCode::Q => KeyCode::Q,
            WrapKeyCode::R => KeyCode::R,
            WrapKeyCode::S => KeyCode::S,
            WrapKeyCode::T => KeyCode::T,
            WrapKeyCode::U => KeyCode::U,
            WrapKeyCode::V => KeyCode::V,
            WrapKeyCode::W => KeyCode::W,
            WrapKeyCode::X => KeyCode::X,
            WrapKeyCode::Y => KeyCode::Y,
            WrapKeyCode::Z => KeyCode::Z,
            WrapKeyCode::Escape => KeyCode::Escape,
            WrapKeyCode::F1 => KeyCode::F1,
            WrapKeyCode::F2 => KeyCode::F2,
            WrapKeyCode::F3 => KeyCode::F3,
            WrapKeyCode::F4 => KeyCode::F4,
            WrapKeyCode::F5 => KeyCode::F5,
            WrapKeyCode::F6 => KeyCode::F6,
            WrapKeyCode::F7 => KeyCode::F7,
            WrapKeyCode::F8 => KeyCode::F8,
            WrapKeyCode::F9 => KeyCode::F9,
            WrapKeyCode::F10 => KeyCode::F10,
            WrapKeyCode::F11 => KeyCode::F11,
            WrapKeyCode::F12 => KeyCode::F12,
            WrapKeyCode::F13 => KeyCode::F13,
            WrapKeyCode::F14 => KeyCode::F14,
            WrapKeyCode::F15 => KeyCode::F15,
            WrapKeyCode::F16 => KeyCode::F16,
            WrapKeyCode::F17 => KeyCode::F17,
            WrapKeyCode::F18 => KeyCode::F18,
            WrapKeyCode::F19 => KeyCode::F19,
            WrapKeyCode::F20 => KeyCode::F20,
            WrapKeyCode::F21 => KeyCode::F21,
            WrapKeyCode::F22 => KeyCode::F22,
            WrapKeyCode::F23 => KeyCode::F23,
            WrapKeyCode::F24 => KeyCode::F24,
            WrapKeyCode::Snapshot => KeyCode::Snapshot,
            WrapKeyCode::Scroll => KeyCode::Scroll,
            WrapKeyCode::Pause => KeyCode::Pause,
            WrapKeyCode::Insert => KeyCode::Insert,
            WrapKeyCode::Home => KeyCode::Home,
            WrapKeyCode::Delete => KeyCode::Delete,
            WrapKeyCode::End => KeyCode::End,
            WrapKeyCode::PageDown => KeyCode::PageDown,
            WrapKeyCode::PageUp => KeyCode::PageUp,
            WrapKeyCode::Left => KeyCode::Left,
            WrapKeyCode::Up => KeyCode::Up,
            WrapKeyCode::Right => KeyCode::Right,
            WrapKeyCode::Down => KeyCode::Down,
            WrapKeyCode::Back => KeyCode::Back,
            WrapKeyCode::Return => KeyCode::Return,
            WrapKeyCode::Space => KeyCode::Space,
            WrapKeyCode::Compose => KeyCode::Compose,
            WrapKeyCode::Caret => KeyCode::Caret,
            WrapKeyCode::Numlock => KeyCode::Numlock,
            WrapKeyCode::Numpad0 => KeyCode::Numpad0,
            WrapKeyCode::Numpad1 => KeyCode::Numpad1,
            WrapKeyCode::Numpad2 => KeyCode::Numpad2,
            WrapKeyCode::Numpad3 => KeyCode::Numpad3,
            WrapKeyCode::Numpad4 => KeyCode::Numpad4,
            WrapKeyCode::Numpad5 => KeyCode::Numpad5,
            WrapKeyCode::Numpad6 => KeyCode::Numpad6,
            WrapKeyCode::Numpad7 => KeyCode::Numpad7,
            WrapKeyCode::Numpad8 => KeyCode::Numpad8,
            WrapKeyCode::Numpad9 => KeyCode::Numpad9,
            WrapKeyCode::AbntC1 => KeyCode::AbntC1,
            WrapKeyCode::AbntC2 => KeyCode::AbntC2,
            WrapKeyCode::NumpadAdd => KeyCode::NumpadAdd,
            WrapKeyCode::Apostrophe => KeyCode::Apostrophe,
            WrapKeyCode::Apps => KeyCode::Apps,
            WrapKeyCode::Asterisk => KeyCode::Asterisk,
            WrapKeyCode::Plus => KeyCode::Plus,
            WrapKeyCode::At => KeyCode::At,
            WrapKeyCode::Ax => KeyCode::Ax,
            WrapKeyCode::Backslash => KeyCode::Backslash,
            WrapKeyCode::Calculator => KeyCode::Calculator,
            WrapKeyCode::Capital => KeyCode::Capital,
            WrapKeyCode::Colon => KeyCode::Colon,
            WrapKeyCode::Comma => KeyCode::Comma,
            WrapKeyCode::Convert => KeyCode::Convert,
            WrapKeyCode::NumpadDecimal => KeyCode::NumpadDecimal,
            WrapKeyCode::NumpadDivide => KeyCode::NumpadDivide,
            WrapKeyCode::Equals => KeyCode::Equals,
            WrapKeyCode::Grave => KeyCode::Grave,
            WrapKeyCode::Kana => KeyCode::Kana,
            WrapKeyCode::Kanji => KeyCode::Kanji,
            WrapKeyCode::LAlt => KeyCode::LAlt,
            WrapKeyCode::LBracket => KeyCode::LBracket,
            WrapKeyCode::LControl => KeyCode::LControl,
            WrapKeyCode::LShift => KeyCode::LShift,
            WrapKeyCode::LWin => KeyCode::LWin,
            WrapKeyCode::Mail => KeyCode::Mail,
            WrapKeyCode::MediaSelect => KeyCode::MediaSelect,
            WrapKeyCode::MediaStop => KeyCode::MediaStop,
            WrapKeyCode::Minus => KeyCode::Minus,
            WrapKeyCode::NumpadMultiply => KeyCode::NumpadMultiply,
            WrapKeyCode::Mute => KeyCode::Mute,
            WrapKeyCode::MyComputer => KeyCode::MyComputer,
            WrapKeyCode::NavigateForward => KeyCode::NavigateForward,
            WrapKeyCode::NavigateBackward => KeyCode::NavigateBackward,
            WrapKeyCode::NextTrack => KeyCode::NextTrack,
            WrapKeyCode::NoConvert => KeyCode::NoConvert,
            WrapKeyCode::NumpadComma => KeyCode::NumpadComma,
            WrapKeyCode::NumpadEnter => KeyCode::NumpadEnter,
            WrapKeyCode::NumpadEquals => KeyCode::NumpadEquals,
            WrapKeyCode::Oem102 => KeyCode::Oem102,
            WrapKeyCode::Period => KeyCode::Period,
            WrapKeyCode::PlayPause => KeyCode::PlayPause,
            WrapKeyCode::Power => KeyCode::Power,
            WrapKeyCode::PrevTrack => KeyCode::PrevTrack,
            WrapKeyCode::RAlt => KeyCode::RAlt,
            WrapKeyCode::RBracket => KeyCode::RBracket,
            WrapKeyCode::RControl => KeyCode::RControl,
            WrapKeyCode::RShift => KeyCode::RShift,
            WrapKeyCode::RWin => KeyCode::RWin,
            WrapKeyCode::Semicolon => KeyCode::Semicolon,
            WrapKeyCode::Slash => KeyCode::Slash,
            WrapKeyCode::Sleep => KeyCode::Sleep,
            WrapKeyCode::Stop => KeyCode::Stop,
            WrapKeyCode::NumpadSubtract => KeyCode::NumpadSubtract,
            WrapKeyCode::Sysrq => KeyCode::Sysrq,
            WrapKeyCode::Tab => KeyCode::Tab,
            WrapKeyCode::Underline => KeyCode::Underline,
            WrapKeyCode::Unlabeled => KeyCode::Unlabeled,
            WrapKeyCode::VolumeDown => KeyCode::VolumeDown,
            WrapKeyCode::VolumeUp => KeyCode::VolumeUp,
            WrapKeyCode::Wake => KeyCode::Wake,
            WrapKeyCode::WebBack => KeyCode::WebBack,
            WrapKeyCode::WebFavorites => KeyCode::WebFavorites,
            WrapKeyCode::WebForward => KeyCode::WebForward,
            WrapKeyCode::WebHome => KeyCode::WebHome,
            WrapKeyCode::WebRefresh => KeyCode::WebRefresh,
            WrapKeyCode::WebSearch => KeyCode::WebSearch,
            WrapKeyCode::WebStop => KeyCode::WebStop,
            WrapKeyCode::Yen => KeyCode::Yen,
            WrapKeyCode::Copy => KeyCode::Copy,
            WrapKeyCode::Paste => KeyCode::Paste,
            WrapKeyCode::Cut => KeyCode::Cut,
        }
    }
}

impl From<&KeyCode> for WrapKeyCode {
    fn from(wrap_key_code: &KeyCode) -> Self {
        match wrap_key_code {
            KeyCode::Key1 => WrapKeyCode::Key1,
            KeyCode::Key2 => WrapKeyCode::Key2,
            KeyCode::Key3 => WrapKeyCode::Key3,
            KeyCode::Key4 => WrapKeyCode::Key4,
            KeyCode::Key5 => WrapKeyCode::Key5,
            KeyCode::Key6 => WrapKeyCode::Key6,
            KeyCode::Key7 => WrapKeyCode::Key7,
            KeyCode::Key8 => WrapKeyCode::Key8,
            KeyCode::Key9 => WrapKeyCode::Key9,
            KeyCode::Key0 => WrapKeyCode::Key0,
            KeyCode::A => WrapKeyCode::A,
            KeyCode::B => WrapKeyCode::B,
            KeyCode::C => WrapKeyCode::C,
            KeyCode::D => WrapKeyCode::D,
            KeyCode::E => WrapKeyCode::E,
            KeyCode::F => WrapKeyCode::F,
            KeyCode::G => WrapKeyCode::G,
            KeyCode::H => WrapKeyCode::H,
            KeyCode::I => WrapKeyCode::I,
            KeyCode::J => WrapKeyCode::J,
            KeyCode::K => WrapKeyCode::K,
            KeyCode::L => WrapKeyCode::L,
            KeyCode::M => WrapKeyCode::M,
            KeyCode::N => WrapKeyCode::N,
            KeyCode::O => WrapKeyCode::O,
            KeyCode::P => WrapKeyCode::P,
            KeyCode::Q => WrapKeyCode::Q,
            KeyCode::R => WrapKeyCode::R,
            KeyCode::S => WrapKeyCode::S,
            KeyCode::T => WrapKeyCode::T,
            KeyCode::U => WrapKeyCode::U,
            KeyCode::V => WrapKeyCode::V,
            KeyCode::W => WrapKeyCode::W,
            KeyCode::X => WrapKeyCode::X,
            KeyCode::Y => WrapKeyCode::Y,
            KeyCode::Z => WrapKeyCode::Z,
            KeyCode::Escape => WrapKeyCode::Escape,
            KeyCode::F1 => WrapKeyCode::F1,
            KeyCode::F2 => WrapKeyCode::F2,
            KeyCode::F3 => WrapKeyCode::F3,
            KeyCode::F4 => WrapKeyCode::F4,
            KeyCode::F5 => WrapKeyCode::F5,
            KeyCode::F6 => WrapKeyCode::F6,
            KeyCode::F7 => WrapKeyCode::F7,
            KeyCode::F8 => WrapKeyCode::F8,
            KeyCode::F9 => WrapKeyCode::F9,
            KeyCode::F10 => WrapKeyCode::F10,
            KeyCode::F11 => WrapKeyCode::F11,
            KeyCode::F12 => WrapKeyCode::F12,
            KeyCode::F13 => WrapKeyCode::F13,
            KeyCode::F14 => WrapKeyCode::F14,
            KeyCode::F15 => WrapKeyCode::F15,
            KeyCode::F16 => WrapKeyCode::F16,
            KeyCode::F17 => WrapKeyCode::F17,
            KeyCode::F18 => WrapKeyCode::F18,
            KeyCode::F19 => WrapKeyCode::F19,
            KeyCode::F20 => WrapKeyCode::F20,
            KeyCode::F21 => WrapKeyCode::F21,
            KeyCode::F22 => WrapKeyCode::F22,
            KeyCode::F23 => WrapKeyCode::F23,
            KeyCode::F24 => WrapKeyCode::F24,
            KeyCode::Snapshot => WrapKeyCode::Snapshot,
            KeyCode::Scroll => WrapKeyCode::Scroll,
            KeyCode::Pause => WrapKeyCode::Pause,
            KeyCode::Insert => WrapKeyCode::Insert,
            KeyCode::Home => WrapKeyCode::Home,
            KeyCode::Delete => WrapKeyCode::Delete,
            KeyCode::End => WrapKeyCode::End,
            KeyCode::PageDown => WrapKeyCode::PageDown,
            KeyCode::PageUp => WrapKeyCode::PageUp,
            KeyCode::Left => WrapKeyCode::Left,
            KeyCode::Up => WrapKeyCode::Up,
            KeyCode::Right => WrapKeyCode::Right,
            KeyCode::Down => WrapKeyCode::Down,
            KeyCode::Back => WrapKeyCode::Back,
            KeyCode::Return => WrapKeyCode::Return,
            KeyCode::Space => WrapKeyCode::Space,
            KeyCode::Compose => WrapKeyCode::Compose,
            KeyCode::Caret => WrapKeyCode::Caret,
            KeyCode::Numlock => WrapKeyCode::Numlock,
            KeyCode::Numpad0 => WrapKeyCode::Numpad0,
            KeyCode::Numpad1 => WrapKeyCode::Numpad1,
            KeyCode::Numpad2 => WrapKeyCode::Numpad2,
            KeyCode::Numpad3 => WrapKeyCode::Numpad3,
            KeyCode::Numpad4 => WrapKeyCode::Numpad4,
            KeyCode::Numpad5 => WrapKeyCode::Numpad5,
            KeyCode::Numpad6 => WrapKeyCode::Numpad6,
            KeyCode::Numpad7 => WrapKeyCode::Numpad7,
            KeyCode::Numpad8 => WrapKeyCode::Numpad8,
            KeyCode::Numpad9 => WrapKeyCode::Numpad9,
            KeyCode::AbntC1 => WrapKeyCode::AbntC1,
            KeyCode::AbntC2 => WrapKeyCode::AbntC2,
            KeyCode::NumpadAdd => WrapKeyCode::NumpadAdd,
            KeyCode::Apostrophe => WrapKeyCode::Apostrophe,
            KeyCode::Apps => WrapKeyCode::Apps,
            KeyCode::Asterisk => WrapKeyCode::Asterisk,
            KeyCode::Plus => WrapKeyCode::Plus,
            KeyCode::At => WrapKeyCode::At,
            KeyCode::Ax => WrapKeyCode::Ax,
            KeyCode::Backslash => WrapKeyCode::Backslash,
            KeyCode::Calculator => WrapKeyCode::Calculator,
            KeyCode::Capital => WrapKeyCode::Capital,
            KeyCode::Colon => WrapKeyCode::Colon,
            KeyCode::Comma => WrapKeyCode::Comma,
            KeyCode::Convert => WrapKeyCode::Convert,
            KeyCode::NumpadDecimal => WrapKeyCode::NumpadDecimal,
            KeyCode::NumpadDivide => WrapKeyCode::NumpadDivide,
            KeyCode::Equals => WrapKeyCode::Equals,
            KeyCode::Grave => WrapKeyCode::Grave,
            KeyCode::Kana => WrapKeyCode::Kana,
            KeyCode::Kanji => WrapKeyCode::Kanji,
            KeyCode::LAlt => WrapKeyCode::LAlt,
            KeyCode::LBracket => WrapKeyCode::LBracket,
            KeyCode::LControl => WrapKeyCode::LControl,
            KeyCode::LShift => WrapKeyCode::LShift,
            KeyCode::LWin => WrapKeyCode::LWin,
            KeyCode::Mail => WrapKeyCode::Mail,
            KeyCode::MediaSelect => WrapKeyCode::MediaSelect,
            KeyCode::MediaStop => WrapKeyCode::MediaStop,
            KeyCode::Minus => WrapKeyCode::Minus,
            KeyCode::NumpadMultiply => WrapKeyCode::NumpadMultiply,
            KeyCode::Mute => WrapKeyCode::Mute,
            KeyCode::MyComputer => WrapKeyCode::MyComputer,
            KeyCode::NavigateForward => WrapKeyCode::NavigateForward,
            KeyCode::NavigateBackward => WrapKeyCode::NavigateBackward,
            KeyCode::NextTrack => WrapKeyCode::NextTrack,
            KeyCode::NoConvert => WrapKeyCode::NoConvert,
            KeyCode::NumpadComma => WrapKeyCode::NumpadComma,
            KeyCode::NumpadEnter => WrapKeyCode::NumpadEnter,
            KeyCode::NumpadEquals => WrapKeyCode::NumpadEquals,
            KeyCode::Oem102 => WrapKeyCode::Oem102,
            KeyCode::Period => WrapKeyCode::Period,
            KeyCode::PlayPause => WrapKeyCode::PlayPause,
            KeyCode::Power => WrapKeyCode::Power,
            KeyCode::PrevTrack => WrapKeyCode::PrevTrack,
            KeyCode::RAlt => WrapKeyCode::RAlt,
            KeyCode::RBracket => WrapKeyCode::RBracket,
            KeyCode::RControl => WrapKeyCode::RControl,
            KeyCode::RShift => WrapKeyCode::RShift,
            KeyCode::RWin => WrapKeyCode::RWin,
            KeyCode::Semicolon => WrapKeyCode::Semicolon,
            KeyCode::Slash => WrapKeyCode::Slash,
            KeyCode::Sleep => WrapKeyCode::Sleep,
            KeyCode::Stop => WrapKeyCode::Stop,
            KeyCode::NumpadSubtract => WrapKeyCode::NumpadSubtract,
            KeyCode::Sysrq => WrapKeyCode::Sysrq,
            KeyCode::Tab => WrapKeyCode::Tab,
            KeyCode::Underline => WrapKeyCode::Underline,
            KeyCode::Unlabeled => WrapKeyCode::Unlabeled,
            KeyCode::VolumeDown => WrapKeyCode::VolumeDown,
            KeyCode::VolumeUp => WrapKeyCode::VolumeUp,
            KeyCode::Wake => WrapKeyCode::Wake,
            KeyCode::WebBack => WrapKeyCode::WebBack,
            KeyCode::WebFavorites => WrapKeyCode::WebFavorites,
            KeyCode::WebForward => WrapKeyCode::WebForward,
            KeyCode::WebHome => WrapKeyCode::WebHome,
            KeyCode::WebRefresh => WrapKeyCode::WebRefresh,
            KeyCode::WebSearch => WrapKeyCode::WebSearch,
            KeyCode::WebStop => WrapKeyCode::WebStop,
            KeyCode::Yen => WrapKeyCode::Yen,
            KeyCode::Copy => WrapKeyCode::Copy,
            KeyCode::Paste => WrapKeyCode::Paste,
            KeyCode::Cut => WrapKeyCode::Cut,
        }
    }
}
