use crate::geom::Size;

/// 按键
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum Key {
    Char(char),
    Enter,
    Esc,
    Backspace,
    Tab,
    Up,
    Down,
    Left,
    Right,
    Delete,
    Home,
    End,
    PageUp,
    PageDown,
}

/// 修饰键
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub struct Modifiers {
    pub ctrl: bool,
    pub alt: bool,
    pub shift: bool,
}

/// 按键事件
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct KeyEvent {
    pub key: Key,
    pub modifiers: Modifiers,
}

/// 鼠标事件类型
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum MouseKind {
    Down,
    Up,
    ScrollUp,
    ScrollDown,
}

/// 鼠标事件
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct MouseEvent {
    pub x: u16,
    pub y: u16,
    pub kind: MouseKind,
}

/// 事件传播阶段
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum EventPhase {
    /// 从根向目标传播
    Capture,
    /// 到达目标
    Target,
    /// 从目标向根冒泡
    Bubble,
}

/// Worker identifier.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct WorkerId(pub u64);

/// 框架事件
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum Event {
    Key(KeyEvent),
    Mouse(MouseEvent),
    Resize(Size),
    /// 获得焦点
    Focus,
    /// 失去焦点
    Blur,
    Tick,
    /// 后台任务完成，携带结果数据
    TaskComplete(String),
    /// Worker finished (success or cancelled). String is result or empty if cancelled.
    WorkerDone(WorkerId, String),
    /// 定时器触发，携带 timer id
    Timer(u64),
}

/// 组件可发送的预定义命令
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum Command {
    Quit,
    FocusNext,
    FocusPrev,
    Custom(String),
}

impl Event {
    /// 判断是否为指定按键事件（忽略修饰键）
    pub fn is_key(&self, key: Key) -> bool {
        matches!(self, Event::Key(KeyEvent { key: k, .. }) if *k == key)
    }
}
