// This file was generated by gir (https://github.com/gtk-rs/gir)
// from
// from gir-files (https://github.com/gtk-rs/gir-files)
// DO NOT EDIT

use crate::{ffi, FwIsoResource};
use glib::{
    prelude::*,
    signal::{connect_raw, SignalHandlerId},
    translate::*,
};
use std::boxed::Box as Box_;

glib::wrapper! {
    /// An object to maintain allocated isochronous resource.
    ///
    /// [`FwIsoResourceAuto`][crate::FwIsoResourceAuto]is an object to maintain isochronous resource during the lifetime of
    /// the object. The allocated isochronous resource is kept even if the generation of the bus
    /// updates. The maintenance of allocated isochronous resource is done by Linux FireWire subsystem.
    ///
    /// ## Properties
    ///
    ///
    /// #### `bandwidth`
    ///  The allocated amount of bandwidth.
    ///
    /// Readable
    ///
    ///
    /// #### `channel`
    ///  The allocated channel number.
    ///
    /// Readable
    ///
    ///
    /// #### `is-allocated`
    ///  Whether to be allocate isochronous resource or not.
    ///
    /// Readable
    /// <details><summary><h4>FwIsoResource</h4></summary>
    ///
    ///
    /// #### `generation`
    ///  Readable
    /// </details>
    ///
    /// # Implements
    ///
    /// [`FwIsoResourceAutoExt`][trait@crate::prelude::FwIsoResourceAutoExt], [`FwIsoResourceExt`][trait@crate::prelude::FwIsoResourceExt]
    #[doc(alias = "HinokoFwIsoResourceAuto")]
    pub struct FwIsoResourceAuto(Object<ffi::HinokoFwIsoResourceAuto, ffi::HinokoFwIsoResourceAutoClass>) @implements FwIsoResource;

    match fn {
        type_ => || ffi::hinoko_fw_iso_resource_auto_get_type(),
    }
}

impl FwIsoResourceAuto {
    pub const NONE: Option<&'static FwIsoResourceAuto> = None;

    /// Allocate and return an instance of [`FwIsoResourceAuto`][crate::FwIsoResourceAuto]object.
    ///
    /// # Returns
    ///
    /// A [`FwIsoResourceAuto`][crate::FwIsoResourceAuto]
    #[doc(alias = "hinoko_fw_iso_resource_auto_new")]
    pub fn new() -> FwIsoResourceAuto {
        unsafe { from_glib_full(ffi::hinoko_fw_iso_resource_auto_new()) }
    }
}

impl Default for FwIsoResourceAuto {
    fn default() -> Self {
        Self::new()
    }
}

mod sealed {
    pub trait Sealed {}
    impl<T: super::IsA<super::FwIsoResourceAuto>> Sealed for T {}
}

/// Trait containing all [`struct@FwIsoResourceAuto`] methods.
///
/// # Implementors
///
/// [`FwIsoResourceAuto`][struct@crate::FwIsoResourceAuto]
pub trait FwIsoResourceAutoExt: IsA<FwIsoResourceAuto> + sealed::Sealed + 'static {
    /// Initiate deallocation of isochronous resource. When the deallocation is done,
    /// [`deallocated`][struct@crate::FwIsoResource#deallocated] signal is emit to notify the result, channel, and bandwidth.
    ///
    /// # Returns
    ///
    /// TRUE if the overall operation finished successfully, otherwise FALSE.
    #[doc(alias = "hinoko_fw_iso_resource_auto_deallocate")]
    fn deallocate(&self) -> Result<(), glib::Error> {
        unsafe {
            let mut error = std::ptr::null_mut();
            let is_ok = ffi::hinoko_fw_iso_resource_auto_deallocate(
                self.as_ref().to_glib_none().0,
                &mut error,
            );
            debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
            if error.is_null() {
                Ok(())
            } else {
                Err(from_glib_full(error))
            }
        }
    }

    /// Initiate deallocation of isochronous resource. When the deallocation is done,
    /// [`deallocated`][struct@crate::FwIsoResource#deallocated] signal is emit to notify the result, channel, and bandwidth.
    /// ## `timeout_ms`
    /// The timeout to wait for allocated event by milli second unit.
    ///
    /// # Returns
    ///
    /// TRUE if the overall operation finished successfully, otherwise FALSE.
    #[doc(alias = "hinoko_fw_iso_resource_auto_deallocate_wait")]
    fn deallocate_wait(&self, timeout_ms: u32) -> Result<(), glib::Error> {
        unsafe {
            let mut error = std::ptr::null_mut();
            let is_ok = ffi::hinoko_fw_iso_resource_auto_deallocate_wait(
                self.as_ref().to_glib_none().0,
                timeout_ms,
                &mut error,
            );
            debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
            if error.is_null() {
                Ok(())
            } else {
                Err(from_glib_full(error))
            }
        }
    }

    /// The allocated amount of bandwidth.
    fn bandwidth(&self) -> u32 {
        ObjectExt::property(self.as_ref(), "bandwidth")
    }

    /// The allocated channel number.
    fn channel(&self) -> u32 {
        ObjectExt::property(self.as_ref(), "channel")
    }

    /// Whether to be allocate isochronous resource or not.
    #[doc(alias = "is-allocated")]
    fn is_allocated(&self) -> bool {
        ObjectExt::property(self.as_ref(), "is-allocated")
    }

    #[doc(alias = "bandwidth")]
    fn connect_bandwidth_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
        unsafe extern "C" fn notify_bandwidth_trampoline<
            P: IsA<FwIsoResourceAuto>,
            F: Fn(&P) + 'static,
        >(
            this: *mut ffi::HinokoFwIsoResourceAuto,
            _param_spec: glib::ffi::gpointer,
            f: glib::ffi::gpointer,
        ) {
            let f: &F = &*(f as *const F);
            f(FwIsoResourceAuto::from_glib_borrow(this).unsafe_cast_ref())
        }
        unsafe {
            let f: Box_<F> = Box_::new(f);
            connect_raw(
                self.as_ptr() as *mut _,
                b"notify::bandwidth\0".as_ptr() as *const _,
                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
                    notify_bandwidth_trampoline::<Self, F> as *const (),
                )),
                Box_::into_raw(f),
            )
        }
    }

    #[doc(alias = "channel")]
    fn connect_channel_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
        unsafe extern "C" fn notify_channel_trampoline<
            P: IsA<FwIsoResourceAuto>,
            F: Fn(&P) + 'static,
        >(
            this: *mut ffi::HinokoFwIsoResourceAuto,
            _param_spec: glib::ffi::gpointer,
            f: glib::ffi::gpointer,
        ) {
            let f: &F = &*(f as *const F);
            f(FwIsoResourceAuto::from_glib_borrow(this).unsafe_cast_ref())
        }
        unsafe {
            let f: Box_<F> = Box_::new(f);
            connect_raw(
                self.as_ptr() as *mut _,
                b"notify::channel\0".as_ptr() as *const _,
                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
                    notify_channel_trampoline::<Self, F> as *const (),
                )),
                Box_::into_raw(f),
            )
        }
    }

    #[doc(alias = "is-allocated")]
    fn connect_is_allocated_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
        unsafe extern "C" fn notify_is_allocated_trampoline<
            P: IsA<FwIsoResourceAuto>,
            F: Fn(&P) + 'static,
        >(
            this: *mut ffi::HinokoFwIsoResourceAuto,
            _param_spec: glib::ffi::gpointer,
            f: glib::ffi::gpointer,
        ) {
            let f: &F = &*(f as *const F);
            f(FwIsoResourceAuto::from_glib_borrow(this).unsafe_cast_ref())
        }
        unsafe {
            let f: Box_<F> = Box_::new(f);
            connect_raw(
                self.as_ptr() as *mut _,
                b"notify::is-allocated\0".as_ptr() as *const _,
                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
                    notify_is_allocated_trampoline::<Self, F> as *const (),
                )),
                Box_::into_raw(f),
            )
        }
    }
}

impl<O: IsA<FwIsoResourceAuto>> FwIsoResourceAutoExt for O {}
