// 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, FwIsoCtx};
use glib::{
    prelude::*,
    signal::{connect_raw, SignalHandlerId},
    translate::*,
};
use std::boxed::Box as Box_;

glib::wrapper! {
    /// An object to receive isochronous packet for several channels.
    ///
    /// [`FwIsoIrMultiple`][crate::FwIsoIrMultiple] receives isochronous packets for several channels by buffer-fill mode of
    /// IR context in 1394 OHCI.
    ///
    /// ## Properties
    ///
    ///
    /// #### `channels`
    ///  The array with elements to express isochronous channels to be listened to.
    ///
    /// Readable
    /// <details><summary><h4>FwIsoCtx</h4></summary>
    ///
    ///
    /// #### `bytes-per-chunk`
    ///  The number of bytes per chunk in buffer.
    ///
    /// Readable
    ///
    ///
    /// #### `chunks-per-buffer`
    ///  The number of chunks per buffer.
    ///
    /// Readable
    /// </details>
    ///
    /// ## Signals
    ///
    ///
    /// #### `interrupted`
    ///  Emitted when Linux FireWire subsystem generates interrupt event. There are two cases
    /// for Linux FireWire subsystem to generate the event:
    ///
    /// - When 1394 OHCI hardware generates hardware interrupt as a result to process the
    ///   isochronous packet for the buffer chunk marked to generate hardware interrupt.
    /// - When application calls [`FwIsoCtxExt::flush_completions()`][crate::prelude::FwIsoCtxExt::flush_completions()] explicitly.
    ///
    /// The handler of signal can retrieve the content of packet by call of
    /// [`FwIsoIrMultipleExtManual::payload()`][crate::prelude::FwIsoIrMultipleExtManual::payload()].
    ///
    ///
    /// <details><summary><h4>FwIsoCtx</h4></summary>
    ///
    ///
    /// #### `stopped`
    ///  Emitted when isochronous context is stopped.
    ///
    /// Action
    /// </details>
    ///
    /// # Implements
    ///
    /// [`FwIsoIrMultipleExt`][trait@crate::prelude::FwIsoIrMultipleExt], [`FwIsoCtxExt`][trait@crate::prelude::FwIsoCtxExt], [`FwIsoIrMultipleExtManual`][trait@crate::prelude::FwIsoIrMultipleExtManual], [`FwIsoCtxExtManual`][trait@crate::prelude::FwIsoCtxExtManual]
    #[doc(alias = "HinokoFwIsoIrMultiple")]
    pub struct FwIsoIrMultiple(Object<ffi::HinokoFwIsoIrMultiple, ffi::HinokoFwIsoIrMultipleClass>) @implements FwIsoCtx;

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

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

    /// Instantiate [`FwIsoIrMultiple`][crate::FwIsoIrMultiple] object and return the instance.
    ///
    /// # Returns
    ///
    /// an instance of [`FwIsoIrMultiple`][crate::FwIsoIrMultiple].
    #[doc(alias = "hinoko_fw_iso_ir_multiple_new")]
    pub fn new() -> FwIsoIrMultiple {
        unsafe { from_glib_full(ffi::hinoko_fw_iso_ir_multiple_new()) }
    }
}

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

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

/// Trait containing the part of [`struct@FwIsoIrMultiple`] methods.
///
/// # Implementors
///
/// [`FwIsoIrMultiple`][struct@crate::FwIsoIrMultiple]
pub trait FwIsoIrMultipleExt: IsA<FwIsoIrMultiple> + sealed::Sealed + 'static {
    /// Allocate an IR context to 1394 OHCI hardware for buffer-fill mode. A local node of the node
    /// corresponding to the given path is used as the hardware, thus any path is accepted as long as
    /// process has enough permission for the path.
    /// ## `path`
    /// A path to any Linux FireWire character device.
    /// ## `channels`
    /// an array for channels to listen
    ///       to. The value of each element should be up to 63.
    #[doc(alias = "hinoko_fw_iso_ir_multiple_allocate")]
    fn allocate(&self, path: &str, channels: &[u8]) -> Result<(), glib::Error> {
        let channels_length = channels.len() as _;
        unsafe {
            let mut error = std::ptr::null_mut();
            let is_ok = ffi::hinoko_fw_iso_ir_multiple_allocate(
                self.as_ref().to_glib_none().0,
                path.to_glib_none().0,
                channels.to_glib_none().0,
                channels_length,
                &mut error,
            );
            debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
            if error.is_null() {
                Ok(())
            } else {
                Err(from_glib_full(error))
            }
        }
    }

    /// Map an intermediate buffer to share payload of IR context with 1394 OHCI hardware.
    /// ## `bytes_per_chunk`
    /// The maximum number of bytes for payload of isochronous packet (not payload for
    ///          isochronous context).
    /// ## `chunks_per_buffer`
    /// The number of chunks in buffer.
    #[doc(alias = "hinoko_fw_iso_ir_multiple_map_buffer")]
    fn map_buffer(&self, bytes_per_chunk: u32, chunks_per_buffer: u32) -> Result<(), glib::Error> {
        unsafe {
            let mut error = std::ptr::null_mut();
            let is_ok = ffi::hinoko_fw_iso_ir_multiple_map_buffer(
                self.as_ref().to_glib_none().0,
                bytes_per_chunk,
                chunks_per_buffer,
                &mut error,
            );
            debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
            if error.is_null() {
                Ok(())
            } else {
                Err(from_glib_full(error))
            }
        }
    }

    /// Emitted when Linux FireWire subsystem generates interrupt event. There are two cases
    /// for Linux FireWire subsystem to generate the event:
    ///
    /// - When 1394 OHCI hardware generates hardware interrupt as a result to process the
    ///   isochronous packet for the buffer chunk marked to generate hardware interrupt.
    /// - When application calls [`FwIsoCtxExt::flush_completions()`][crate::prelude::FwIsoCtxExt::flush_completions()] explicitly.
    ///
    /// The handler of signal can retrieve the content of packet by call of
    /// [`FwIsoIrMultipleExtManual::payload()`][crate::prelude::FwIsoIrMultipleExtManual::payload()].
    /// ## `count`
    /// The number of packets available in this interrupt.
    #[doc(alias = "interrupted")]
    fn connect_interrupted<F: Fn(&Self, u32) + 'static>(&self, f: F) -> SignalHandlerId {
        unsafe extern "C" fn interrupted_trampoline<
            P: IsA<FwIsoIrMultiple>,
            F: Fn(&P, u32) + 'static,
        >(
            this: *mut ffi::HinokoFwIsoIrMultiple,
            count: libc::c_uint,
            f: glib::ffi::gpointer,
        ) {
            let f: &F = &*(f as *const F);
            f(
                FwIsoIrMultiple::from_glib_borrow(this).unsafe_cast_ref(),
                count,
            )
        }
        unsafe {
            let f: Box_<F> = Box_::new(f);
            connect_raw(
                self.as_ptr() as *mut _,
                b"interrupted\0".as_ptr() as *const _,
                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
                    interrupted_trampoline::<Self, F> as *const (),
                )),
                Box_::into_raw(f),
            )
        }
    }
}

impl<O: IsA<FwIsoIrMultiple>> FwIsoIrMultipleExt for O {}
