//! The MousePad plugin allows remote control of the pointer and keyboard.
use serde::{Deserialize, Serialize};

#[cfg(not(feature = "std"))]
use alloc::string::String;

/// This packet is an echo for a kdeconnect.mousepad.request packet.
///
/// <https://invent.kde.org/network/kdeconnect-meta/blob/master/protocol.md#kdeconnectmousepadecho>
#[derive(Serialize, Deserialize, Debug, Clone)]
#[serde(rename_all = "camelCase")]
pub struct MousepadEchoPacket {
    /// A request to press-release a single readable character, which may be a unicode character and thus more than one byte.
    #[serde(skip_serializing_if = "Option::is_none")]
    #[serde(default)]
    pub key: Option<String>,

    /// A request to press-release a single non-printable character, usually a control character or function key such as Backspace or F10.
    #[serde(skip_serializing_if = "Option::is_none")]
    #[serde(default)]
    pub special_key: Option<u8>,

    /// Indicates whether the Alt modifier should be applied to the associated key or specialKey.
    #[serde(skip_serializing_if = "Option::is_none")]
    #[serde(default)]
    pub alt: Option<bool>,

    /// Indicates whether the Control modifier should be applied to the associated key or specialKey.
    #[serde(skip_serializing_if = "Option::is_none")]
    #[serde(default)]
    pub ctrl: Option<bool>,

    /// Indicates whether the Shift modifier should be applied to the associated key or specialKey.
    #[serde(skip_serializing_if = "Option::is_none")]
    #[serde(default)]
    pub shift: Option<bool>,

    /// Indicates whether the Super modifier should be applied to the associated key or specialKey.
    #[serde(skip_serializing_if = "Option::is_none")]
    #[serde(default)]
    #[serde(rename = "super")]
    pub super_: Option<bool>,

    /// A single press-release of the primary pointer button.
    #[serde(skip_serializing_if = "Option::is_none")]
    #[serde(default)]
    pub singleclick: Option<bool>,

    /// A double press-release of the primary pointer button.
    #[serde(skip_serializing_if = "Option::is_none")]
    #[serde(default)]
    pub doubleclick: Option<bool>,

    /// A single press-release of the middle pointer button.
    #[serde(skip_serializing_if = "Option::is_none")]
    #[serde(default)]
    pub middleclick: Option<bool>,

    /// A single press-release of the secondary pointer button.
    #[serde(skip_serializing_if = "Option::is_none")]
    #[serde(default)]
    pub rightclick: Option<bool>,

    /// A single press of the primary pointer button.
    #[serde(skip_serializing_if = "Option::is_none")]
    #[serde(default)]
    pub singlehold: Option<bool>,

    /// A single release of the primary pointer button.
    #[serde(skip_serializing_if = "Option::is_none")]
    #[serde(default)]
    pub singlerelease: Option<bool>,

    /// A double precision integer indicating a relative position delta for the pointer on the X-axis.
    #[serde(skip_serializing_if = "Option::is_none")]
    #[serde(default)]
    pub dx: Option<i64>,

    /// A double precision integer indicating a relative position delta for the pointer on the Y-axis.
    #[serde(skip_serializing_if = "Option::is_none")]
    #[serde(default)]
    pub dy: Option<i64>,

    /// Whether the associated dx or dy movement is a scroll event.
    #[serde(skip_serializing_if = "Option::is_none")]
    #[serde(default)]
    pub scroll: Option<bool>,

    /// Indicates the packet is a confirmation of a request. Always true and always present.
    pub is_ack: bool,
}

/// This packet is a keyboard status update.
///
/// <https://invent.kde.org/network/kdeconnect-meta/blob/master/protocol.md#kdeconnectmousepadkeyboardstate>
#[derive(Serialize, Deserialize, Debug, Clone)]
#[serde(rename_all = "camelCase")]
pub struct MousepadKeyboardStatePacket {
    /// Indicates the keyboard is ready to receive keypress events.
    pub state: bool,
}

/// This packet is a request for a pointer or keyboard event.
///
/// <https://invent.kde.org/network/kdeconnect-meta/blob/master/protocol.md#kdeconnectmousepadrequest>
#[derive(Serialize, Deserialize, Debug, Clone)]
#[serde(rename_all = "camelCase")]
pub struct MousepadRequestPacket {
    /// A request to press-release a single readable character, which may be a unicode character and thus more than one byte.
    #[serde(skip_serializing_if = "Option::is_none")]
    #[serde(default)]
    pub key: Option<String>,

    /// A request to press-release a single non-printable character, usually a control character or function key such as Backspace or F10.
    #[serde(skip_serializing_if = "Option::is_none")]
    #[serde(default)]
    pub special_key: Option<u8>,

    /// Indicates whether the Alt modifier should be applied to the associated key or specialKey.
    #[serde(skip_serializing_if = "Option::is_none")]
    #[serde(default)]
    pub alt: Option<bool>,

    /// Indicates whether the Control modifier should be applied to the associated key or specialKey.
    #[serde(skip_serializing_if = "Option::is_none")]
    #[serde(default)]
    pub ctrl: Option<bool>,

    /// Indicates whether the Shift modifier should be applied to the associated key or specialKey.
    #[serde(skip_serializing_if = "Option::is_none")]
    #[serde(default)]
    pub shift: Option<bool>,

    /// Indicates whether the Super modifier should be applied to the associated key or specialKey.
    #[serde(skip_serializing_if = "Option::is_none")]
    #[serde(default)]
    #[serde(rename = "super")]
    pub super_: Option<bool>,

    /// A single press-release of the primary pointer button.
    #[serde(skip_serializing_if = "Option::is_none")]
    #[serde(default)]
    pub singleclick: Option<bool>,

    /// A double press-release of the primary pointer button.
    #[serde(skip_serializing_if = "Option::is_none")]
    #[serde(default)]
    pub doubleclick: Option<bool>,

    /// A single press-release of the middle pointer button.
    #[serde(skip_serializing_if = "Option::is_none")]
    #[serde(default)]
    pub middleclick: Option<bool>,

    /// A single press-release of the secondary pointer button.
    #[serde(skip_serializing_if = "Option::is_none")]
    #[serde(default)]
    pub rightclick: Option<bool>,

    /// A single press of the primary pointer button.
    #[serde(skip_serializing_if = "Option::is_none")]
    #[serde(default)]
    pub singlehold: Option<bool>,

    /// A single release of the primary pointer button.
    #[serde(skip_serializing_if = "Option::is_none")]
    #[serde(default)]
    pub singlerelease: Option<bool>,

    /// A double precision integer indicating a position delta on the X-axis.
    #[serde(skip_serializing_if = "Option::is_none")]
    #[serde(default)]
    pub dx: Option<i64>,

    /// A double precision integer indicating a position delta on the Y-axis.
    #[serde(skip_serializing_if = "Option::is_none")]
    #[serde(default)]
    pub dy: Option<i64>,

    /// Whether the associated dx or dy movement is a scroll event.
    #[serde(skip_serializing_if = "Option::is_none")]
    #[serde(default)]
    pub scroll: Option<bool>,

    /// Indicates that the devices wants a kdeconnect.mousepad.echo packet as confirmation of a keyboard event.
    #[serde(skip_serializing_if = "Option::is_none")]
    #[serde(default)]
    pub send_ack: Option<bool>,
}
