use bone_render::ViewportExtent;
use bone_ui::input::{KeyCode, ModifierMask, PointerButton};
use serde::{Deserialize, Serialize};

#[derive(Copy, Clone, Debug, PartialEq)]
pub struct WindowPoint {
    pub x: f64,
    pub y: f64,
}

impl WindowPoint {
    #[must_use]
    pub const fn new(x: f64, y: f64) -> Self {
        Self { x, y }
    }
}

#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)]
pub enum ScrollDelta {
    Lines { x: f32, y: f32 },
    Pixels { x: f64, y: f64 },
}

#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum NavKey {
    Left,
    Right,
    Up,
    Down,
    Zoom,
    ZoomIn,
    ZoomOut,
}

#[derive(Clone, Debug, PartialEq)]
pub struct KeyDown {
    pub code: Option<KeyCode>,
    pub nav: Option<NavKey>,
    pub text: Option<String>,
    pub repeat: bool,
}

#[derive(Clone, Debug, PartialEq)]
pub enum InputEvent {
    Resize(ViewportExtent),
    Focus(bool),
    Modifiers(ModifierMask),
    CursorMove(WindowPoint),
    CursorLeft,
    CursorEntered,
    Pointer {
        button: PointerButton,
        pressed: bool,
    },
    Wheel(ScrollDelta),
    KeyDown(KeyDown),
}

#[must_use = "input dispatch must be acknowledged via the redraw scheduler"]
pub struct InputDispatched(());

impl InputDispatched {
    pub(crate) const fn after_input() -> Self {
        Self(())
    }
}
