//! # DBus interface proxies for: `org.mpris.MediaPlayer2`, `org.mpris.MediaPlayer2.Player`
//!
//! This code was generated by `zbus-xmlgen` `1.0.0` from DBus introspection data.
//! Source: `11`.
//!
//! You may prefer to adapt it, instead of using it verbatim.
//!
//! More information can be found in the
//! [Writing a client proxy](https://zeenix.pages.freedesktop.org/zbus/client.html)
//! section of the zbus documentation.
//!
//! This DBus object implements
//! [standard DBus interfaces](https://dbus.freedesktop.org/doc/dbus-specification.html),
//! (`org.freedesktop.DBus.*`) for which the following zbus proxies can be used:
//!
//! * [`zbus::fdo::PropertiesProxy`]
//! * [`zbus::fdo::IntrospectableProxy`]
//! * [`zbus::fdo::PeerProxy`]
//!
//! â€¦consequently `zbus-xmlgen` did not generate code for the above interfaces.

use std::collections::HashMap;
use zbus::dbus_proxy;
use zbus::zvariant::{ObjectPath, OwnedValue, Type};

#[derive(Debug, Clone, Type)]
pub struct PlayerMetadata(pub HashMap<String, OwnedValue>);

impl TryFrom<OwnedValue> for PlayerMetadata {
    type Error = <HashMap<String, OwnedValue> as TryFrom<OwnedValue>>::Error;

    fn try_from(value: OwnedValue) -> Result<Self, Self::Error> {
        HashMap::try_from(value).map(Self)
    }
}

impl PlayerMetadata {
    pub fn title(&self) -> Option<String> {
        self.0
            .get("xesam:title")?
            .downcast_ref::<str>()
            .map(Into::into)
    }

    pub fn artist(&self) -> Option<String> {
        let mut artsts: Vec<String> = self.0.get("xesam:artist")?.clone().try_into().ok()?;
        artsts.pop()
    }
}

#[dbus_proxy(
    interface = "org.mpris.MediaPlayer2",
    default_path = "/org/mpris/MediaPlayer2"
)]
trait MediaPlayer2 {
    /// Quit method
    fn quit(&self) -> zbus::Result<()>;

    /// Raise method
    fn raise(&self) -> zbus::Result<()>;

    /// CanQuit property
    #[dbus_proxy(property)]
    fn can_quit(&self) -> zbus::Result<bool>;

    /// CanRaise property
    #[dbus_proxy(property)]
    fn can_raise(&self) -> zbus::Result<bool>;

    /// DesktopEntry property
    #[dbus_proxy(property)]
    fn desktop_entry(&self) -> zbus::Result<String>;

    /// HasTrackList property
    #[dbus_proxy(property)]
    fn has_track_list(&self) -> zbus::Result<bool>;

    /// Identity property
    #[dbus_proxy(property)]
    fn identity(&self) -> zbus::Result<String>;

    /// SupportedMimeTypes property
    #[dbus_proxy(property)]
    fn supported_mime_types(&self) -> zbus::Result<Vec<String>>;

    /// SupportedUriSchemes property
    #[dbus_proxy(property)]
    fn supported_uri_schemes(&self) -> zbus::Result<Vec<String>>;
}

#[dbus_proxy(
    interface = "org.mpris.MediaPlayer2.Player",
    default_path = "/org/mpris/MediaPlayer2"
)]
trait Player {
    /// Next method
    fn next(&self) -> zbus::Result<()>;

    /// OpenUri method
    fn open_uri(&self, uri: &str) -> zbus::Result<()>;

    /// Pause method
    fn pause(&self) -> zbus::Result<()>;

    /// Play method
    fn play(&self) -> zbus::Result<()>;

    /// PlayPause method
    fn play_pause(&self) -> zbus::Result<()>;

    /// Previous method
    fn previous(&self) -> zbus::Result<()>;

    /// Seek method
    fn seek(&self, offset: i64) -> zbus::Result<()>;

    /// SetPosition method
    fn set_position(&self, track_id: &ObjectPath<'_>, position: i64) -> zbus::Result<()>;

    /// Stop method
    fn stop(&self) -> zbus::Result<()>;

    /// Seeked signal
    #[dbus_proxy(signal)]
    fn seeked(&self, position: i64) -> zbus::Result<()>;

    /// CanControl property
    #[dbus_proxy(property)]
    fn can_control(&self) -> zbus::Result<bool>;

    /// CanGoNext property
    #[dbus_proxy(property)]
    fn can_go_next(&self) -> zbus::Result<bool>;

    /// CanGoPrevious property
    #[dbus_proxy(property)]
    fn can_go_previous(&self) -> zbus::Result<bool>;

    /// CanPause property
    #[dbus_proxy(property)]
    fn can_pause(&self) -> zbus::Result<bool>;

    /// CanPlay property
    #[dbus_proxy(property)]
    fn can_play(&self) -> zbus::Result<bool>;

    /// CanSeek property
    #[dbus_proxy(property)]
    fn can_seek(&self) -> zbus::Result<bool>;

    /// MaximumRate property
    #[dbus_proxy(property)]
    fn maximum_rate(&self) -> zbus::Result<f64>;

    /// Metadata property
    #[dbus_proxy(property)]
    fn metadata(&self) -> zbus::Result<PlayerMetadata>;

    /// MinimumRate property
    #[dbus_proxy(property)]
    fn minimum_rate(&self) -> zbus::Result<f64>;

    /// PlaybackStatus property
    #[dbus_proxy(property)]
    fn playback_status(&self) -> zbus::Result<String>;

    /// Position property
    #[dbus_proxy(property)]
    fn position(&self) -> zbus::Result<i64>;

    /// Rate property
    #[dbus_proxy(property)]
    fn rate(&self) -> zbus::Result<f64>;
    #[DBusProxy(property)]
    fn set_rate(&self, value: f64) -> zbus::Result<()>;

    /// Volume property
    #[dbus_proxy(property)]
    fn volume(&self) -> zbus::Result<f64>;
    #[DBusProxy(property)]
    fn set_volume(&self, value: f64) -> zbus::Result<()>;
}
