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

glib::wrapper! {
    /// A set of basic interfaces to operate isochronous context on 1394 OHCI hardware.
    ///
    /// [`FwIsoCtx`][crate::FwIsoCtx] includes interfaces to operate 1394 OHCI hardware for isochronous communication
    /// by any kind of contexts.
    ///
    /// ## Properties
    ///
    ///
    /// #### `bytes-per-chunk`
    ///  The number of bytes per chunk in buffer.
    ///
    /// Readable
    ///
    ///
    /// #### `chunks-per-buffer`
    ///  The number of chunks per buffer.
    ///
    /// Readable
    ///
    /// ## Signals
    ///
    ///
    /// #### `stopped`
    ///  Emitted when isochronous context is stopped.
    ///
    /// Action
    ///
    /// # Implements
    ///
    /// [`FwIsoCtxExt`][trait@crate::prelude::FwIsoCtxExt], [`FwIsoCtxExtManual`][trait@crate::prelude::FwIsoCtxExtManual]
    #[doc(alias = "HinokoFwIsoCtx")]
    pub struct FwIsoCtx(Interface<ffi::HinokoFwIsoCtx, ffi::HinokoFwIsoCtxInterface>);

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

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

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

/// Trait containing the part of [`struct@FwIsoCtx`] methods.
///
/// # Implementors
///
/// [`FwIsoCtx`][struct@crate::FwIsoCtx], [`FwIsoIrMultiple`][struct@crate::FwIsoIrMultiple], [`FwIsoIrSingle`][struct@crate::FwIsoIrSingle], [`FwIsoIt`][struct@crate::FwIsoIt]
pub trait FwIsoCtxExt: IsA<FwIsoCtx> + sealed::Sealed + 'static {
    /// Create [`glib::Source`][crate::glib::Source] for `GLib::MainContext` to dispatch events for isochronous
    /// context.
    ///
    /// # Returns
    ///
    /// TRUE if the overall operation finishes successfully, otherwise FALSE.
    ///
    /// ## `source`
    /// A [`glib::Source`][crate::glib::Source].
    #[doc(alias = "hinoko_fw_iso_ctx_create_source")]
    fn create_source(&self) -> Result<glib::Source, glib::Error> {
        unsafe {
            let mut source = std::ptr::null_mut();
            let mut error = std::ptr::null_mut();
            let is_ok = ffi::hinoko_fw_iso_ctx_create_source(
                self.as_ref().to_glib_none().0,
                &mut source,
                &mut error,
            );
            debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
            if error.is_null() {
                Ok(from_glib_full(source))
            } else {
                Err(from_glib_full(error))
            }
        }
    }

    /// Flush isochronous context until recent isochronous cycle. The call of function forces the
    /// context to queue any type of interrupt event for the recent isochronous cycle. Application can
    /// process the content of isochronous packet without waiting for actual hardware interrupt.
    ///
    /// # Returns
    ///
    /// TRUE if the overall operation finishes successfully, otherwise FALSE.
    #[doc(alias = "hinoko_fw_iso_ctx_flush_completions")]
    fn flush_completions(&self) -> Result<(), glib::Error> {
        unsafe {
            let mut error = std::ptr::null_mut();
            let is_ok = ffi::hinoko_fw_iso_ctx_flush_completions(
                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))
            }
        }
    }

    /// Release the contest from 1394 OHCI hardware.
    #[doc(alias = "hinoko_fw_iso_ctx_release")]
    fn release(&self) {
        unsafe {
            ffi::hinoko_fw_iso_ctx_release(self.as_ref().to_glib_none().0);
        }
    }

    /// Stop isochronous context.
    #[doc(alias = "hinoko_fw_iso_ctx_stop")]
    fn stop(&self) {
        unsafe {
            ffi::hinoko_fw_iso_ctx_stop(self.as_ref().to_glib_none().0);
        }
    }

    /// Unmap intermediate buffer shared with 1394 OHCI hardware for the context.
    #[doc(alias = "hinoko_fw_iso_ctx_unmap_buffer")]
    fn unmap_buffer(&self) {
        unsafe {
            ffi::hinoko_fw_iso_ctx_unmap_buffer(self.as_ref().to_glib_none().0);
        }
    }

    /// The number of bytes per chunk in buffer.
    #[doc(alias = "bytes-per-chunk")]
    fn bytes_per_chunk(&self) -> u32 {
        ObjectExt::property(self.as_ref(), "bytes-per-chunk")
    }

    /// The number of chunks per buffer.
    #[doc(alias = "chunks-per-buffer")]
    fn chunks_per_buffer(&self) -> u32 {
        ObjectExt::property(self.as_ref(), "chunks-per-buffer")
    }

    /// Emitted when isochronous context is stopped.
    /// ## `error`
    /// A [`glib::Error`][crate::glib::Error].
    #[doc(alias = "stopped")]
    fn connect_stopped<F: Fn(&Self, Option<&glib::Error>) + 'static>(
        &self,
        f: F,
    ) -> SignalHandlerId {
        unsafe extern "C" fn stopped_trampoline<
            P: IsA<FwIsoCtx>,
            F: Fn(&P, Option<&glib::Error>) + 'static,
        >(
            this: *mut ffi::HinokoFwIsoCtx,
            error: *mut glib::ffi::GError,
            f: glib::ffi::gpointer,
        ) {
            let f: &F = &*(f as *const F);
            f(
                FwIsoCtx::from_glib_borrow(this).unsafe_cast_ref(),
                Option::<glib::Error>::from_glib_borrow(error)
                    .as_ref()
                    .as_ref(),
            )
        }
        unsafe {
            let f: Box_<F> = Box_::new(f);
            connect_raw(
                self.as_ptr() as *mut _,
                b"stopped\0".as_ptr() as *const _,
                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
                    stopped_trampoline::<Self, F> as *const (),
                )),
                Box_::into_raw(f),
            )
        }
    }

    fn emit_stopped(&self, error: Option<&glib::Error>) {
        self.emit_by_name::<()>("stopped", &[&error]);
    }

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

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

impl<O: IsA<FwIsoCtx>> FwIsoCtxExt for O {}
