//! This file has been automatically generated by `objc2`'s `header-translator`.
//! DO NOT EDIT
use core::cell::UnsafeCell;
use core::ffi::*;
use core::marker::{PhantomData, PhantomPinned};
use core::ptr::NonNull;
#[cfg(feature = "objc2")]
use objc2::__framework_prelude::*;

use crate::*;

/// [Apple's documentation](https://developer.apple.com/documentation/corefoundation/cfnotificationname?language=objc)
// NS_TYPED_EXTENSIBLE_ENUM
pub type CFNotificationName = CFString;

/// [Apple's documentation](https://developer.apple.com/documentation/corefoundation/cfnotificationcenter?language=objc)
#[doc(alias = "CFNotificationCenterRef")]
#[repr(C)]
pub struct CFNotificationCenter {
    inner: [u8; 0],
    _p: UnsafeCell<PhantomData<(*const UnsafeCell<()>, PhantomPinned)>>,
}

cf_type!(
    unsafe impl CFNotificationCenter {}
);
#[cfg(feature = "objc2")]
cf_objc2_type!(
    unsafe impl RefEncode<"__CFNotificationCenter"> for CFNotificationCenter {}
);

/// [Apple's documentation](https://developer.apple.com/documentation/corefoundation/cfnotificationcallback?language=objc)
#[cfg(feature = "CFDictionary")]
pub type CFNotificationCallback = Option<
    unsafe extern "C-unwind" fn(
        *mut CFNotificationCenter,
        *mut c_void,
        *const CFNotificationName,
        *const c_void,
        *const CFDictionary,
    ),
>;

/// [Apple's documentation](https://developer.apple.com/documentation/corefoundation/cfnotificationsuspensionbehavior?language=objc)
// NS_ENUM
#[repr(transparent)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct CFNotificationSuspensionBehavior(pub CFIndex);
impl CFNotificationSuspensionBehavior {
    #[doc(alias = "CFNotificationSuspensionBehaviorDrop")]
    pub const Drop: Self = Self(1);
    #[doc(alias = "CFNotificationSuspensionBehaviorCoalesce")]
    pub const Coalesce: Self = Self(2);
    #[doc(alias = "CFNotificationSuspensionBehaviorHold")]
    pub const Hold: Self = Self(3);
    #[doc(alias = "CFNotificationSuspensionBehaviorDeliverImmediately")]
    pub const DeliverImmediately: Self = Self(4);
}

#[cfg(feature = "objc2")]
unsafe impl Encode for CFNotificationSuspensionBehavior {
    const ENCODING: Encoding = CFIndex::ENCODING;
}

#[cfg(feature = "objc2")]
unsafe impl RefEncode for CFNotificationSuspensionBehavior {
    const ENCODING_REF: Encoding = Encoding::Pointer(&Self::ENCODING);
}

unsafe impl ConcreteType for CFNotificationCenter {
    #[doc(alias = "CFNotificationCenterGetTypeID")]
    #[inline]
    fn type_id() -> CFTypeID {
        extern "C-unwind" {
            fn CFNotificationCenterGetTypeID() -> CFTypeID;
        }
        unsafe { CFNotificationCenterGetTypeID() }
    }
}

impl CFNotificationCenter {
    #[doc(alias = "CFNotificationCenterGetLocalCenter")]
    #[inline]
    pub fn local_center() -> Option<CFRetained<CFNotificationCenter>> {
        extern "C-unwind" {
            fn CFNotificationCenterGetLocalCenter() -> Option<NonNull<CFNotificationCenter>>;
        }
        let ret = unsafe { CFNotificationCenterGetLocalCenter() };
        ret.map(|ret| unsafe { CFRetained::retain(ret) })
    }

    #[doc(alias = "CFNotificationCenterGetDistributedCenter")]
    #[inline]
    pub fn distributed_center() -> Option<CFRetained<CFNotificationCenter>> {
        extern "C-unwind" {
            fn CFNotificationCenterGetDistributedCenter() -> Option<NonNull<CFNotificationCenter>>;
        }
        let ret = unsafe { CFNotificationCenterGetDistributedCenter() };
        ret.map(|ret| unsafe { CFRetained::retain(ret) })
    }

    #[doc(alias = "CFNotificationCenterGetDarwinNotifyCenter")]
    #[inline]
    pub fn darwin_notify_center() -> Option<CFRetained<CFNotificationCenter>> {
        extern "C-unwind" {
            fn CFNotificationCenterGetDarwinNotifyCenter() -> Option<NonNull<CFNotificationCenter>>;
        }
        let ret = unsafe { CFNotificationCenterGetDarwinNotifyCenter() };
        ret.map(|ret| unsafe { CFRetained::retain(ret) })
    }

    /// # Safety
    ///
    /// - `observer` must be a valid pointer.
    /// - `call_back` must be implemented correctly.
    /// - `name` might not allow `None`.
    /// - `object` must be a valid pointer.
    #[doc(alias = "CFNotificationCenterAddObserver")]
    #[cfg(feature = "CFDictionary")]
    #[inline]
    pub unsafe fn add_observer(
        &self,
        observer: *const c_void,
        call_back: CFNotificationCallback,
        name: Option<&CFString>,
        object: *const c_void,
        suspension_behavior: CFNotificationSuspensionBehavior,
    ) {
        extern "C-unwind" {
            fn CFNotificationCenterAddObserver(
                center: &CFNotificationCenter,
                observer: *const c_void,
                call_back: CFNotificationCallback,
                name: Option<&CFString>,
                object: *const c_void,
                suspension_behavior: CFNotificationSuspensionBehavior,
            );
        }
        unsafe {
            CFNotificationCenterAddObserver(
                self,
                observer,
                call_back,
                name,
                object,
                suspension_behavior,
            )
        }
    }

    /// # Safety
    ///
    /// - `observer` must be a valid pointer.
    /// - `name` might not allow `None`.
    /// - `object` must be a valid pointer.
    #[doc(alias = "CFNotificationCenterRemoveObserver")]
    #[inline]
    pub unsafe fn remove_observer(
        &self,
        observer: *const c_void,
        name: Option<&CFNotificationName>,
        object: *const c_void,
    ) {
        extern "C-unwind" {
            fn CFNotificationCenterRemoveObserver(
                center: &CFNotificationCenter,
                observer: *const c_void,
                name: Option<&CFNotificationName>,
                object: *const c_void,
            );
        }
        unsafe { CFNotificationCenterRemoveObserver(self, observer, name, object) }
    }

    /// # Safety
    ///
    /// `observer` must be a valid pointer.
    #[doc(alias = "CFNotificationCenterRemoveEveryObserver")]
    #[inline]
    pub unsafe fn remove_every_observer(&self, observer: *const c_void) {
        extern "C-unwind" {
            fn CFNotificationCenterRemoveEveryObserver(
                center: &CFNotificationCenter,
                observer: *const c_void,
            );
        }
        unsafe { CFNotificationCenterRemoveEveryObserver(self, observer) }
    }

    /// # Safety
    ///
    /// - `name` might not allow `None`.
    /// - `object` must be a valid pointer.
    /// - `user_info` generics must be of the correct type.
    /// - `user_info` might not allow `None`.
    #[doc(alias = "CFNotificationCenterPostNotification")]
    #[cfg(feature = "CFDictionary")]
    #[inline]
    pub unsafe fn post_notification(
        &self,
        name: Option<&CFNotificationName>,
        object: *const c_void,
        user_info: Option<&CFDictionary>,
        deliver_immediately: bool,
    ) {
        extern "C-unwind" {
            fn CFNotificationCenterPostNotification(
                center: &CFNotificationCenter,
                name: Option<&CFNotificationName>,
                object: *const c_void,
                user_info: Option<&CFDictionary>,
                deliver_immediately: Boolean,
            );
        }
        unsafe {
            CFNotificationCenterPostNotification(
                self,
                name,
                object,
                user_info,
                deliver_immediately as _,
            )
        }
    }
}

/// [Apple's documentation](https://developer.apple.com/documentation/corefoundation/kcfnotificationdeliverimmediately?language=objc)
pub const kCFNotificationDeliverImmediately: CFOptionFlags = 1 << 0;
/// [Apple's documentation](https://developer.apple.com/documentation/corefoundation/kcfnotificationposttoallsessions?language=objc)
pub const kCFNotificationPostToAllSessions: CFOptionFlags = 1 << 1;

impl CFNotificationCenter {
    /// # Safety
    ///
    /// - `name` might not allow `None`.
    /// - `object` must be a valid pointer.
    /// - `user_info` generics must be of the correct type.
    /// - `user_info` might not allow `None`.
    #[doc(alias = "CFNotificationCenterPostNotificationWithOptions")]
    #[cfg(feature = "CFDictionary")]
    #[inline]
    pub unsafe fn post_notification_with_options(
        &self,
        name: Option<&CFNotificationName>,
        object: *const c_void,
        user_info: Option<&CFDictionary>,
        options: CFOptionFlags,
    ) {
        extern "C-unwind" {
            fn CFNotificationCenterPostNotificationWithOptions(
                center: &CFNotificationCenter,
                name: Option<&CFNotificationName>,
                object: *const c_void,
                user_info: Option<&CFDictionary>,
                options: CFOptionFlags,
            );
        }
        unsafe {
            CFNotificationCenterPostNotificationWithOptions(self, name, object, user_info, options)
        }
    }
}

#[deprecated = "renamed to `CFNotificationCenter::local_center`"]
#[inline]
pub extern "C-unwind" fn CFNotificationCenterGetLocalCenter(
) -> Option<CFRetained<CFNotificationCenter>> {
    extern "C-unwind" {
        fn CFNotificationCenterGetLocalCenter() -> Option<NonNull<CFNotificationCenter>>;
    }
    let ret = unsafe { CFNotificationCenterGetLocalCenter() };
    ret.map(|ret| unsafe { CFRetained::retain(ret) })
}

#[deprecated = "renamed to `CFNotificationCenter::distributed_center`"]
#[inline]
pub extern "C-unwind" fn CFNotificationCenterGetDistributedCenter(
) -> Option<CFRetained<CFNotificationCenter>> {
    extern "C-unwind" {
        fn CFNotificationCenterGetDistributedCenter() -> Option<NonNull<CFNotificationCenter>>;
    }
    let ret = unsafe { CFNotificationCenterGetDistributedCenter() };
    ret.map(|ret| unsafe { CFRetained::retain(ret) })
}

#[deprecated = "renamed to `CFNotificationCenter::darwin_notify_center`"]
#[inline]
pub extern "C-unwind" fn CFNotificationCenterGetDarwinNotifyCenter(
) -> Option<CFRetained<CFNotificationCenter>> {
    extern "C-unwind" {
        fn CFNotificationCenterGetDarwinNotifyCenter() -> Option<NonNull<CFNotificationCenter>>;
    }
    let ret = unsafe { CFNotificationCenterGetDarwinNotifyCenter() };
    ret.map(|ret| unsafe { CFRetained::retain(ret) })
}

extern "C-unwind" {
    #[cfg(feature = "CFDictionary")]
    #[deprecated = "renamed to `CFNotificationCenter::add_observer`"]
    pub fn CFNotificationCenterAddObserver(
        center: &CFNotificationCenter,
        observer: *const c_void,
        call_back: CFNotificationCallback,
        name: Option<&CFString>,
        object: *const c_void,
        suspension_behavior: CFNotificationSuspensionBehavior,
    );
}

extern "C-unwind" {
    #[deprecated = "renamed to `CFNotificationCenter::remove_observer`"]
    pub fn CFNotificationCenterRemoveObserver(
        center: &CFNotificationCenter,
        observer: *const c_void,
        name: Option<&CFNotificationName>,
        object: *const c_void,
    );
}

extern "C-unwind" {
    #[deprecated = "renamed to `CFNotificationCenter::remove_every_observer`"]
    pub fn CFNotificationCenterRemoveEveryObserver(
        center: &CFNotificationCenter,
        observer: *const c_void,
    );
}

#[cfg(feature = "CFDictionary")]
#[deprecated = "renamed to `CFNotificationCenter::post_notification`"]
#[inline]
pub unsafe extern "C-unwind" fn CFNotificationCenterPostNotification(
    center: &CFNotificationCenter,
    name: Option<&CFNotificationName>,
    object: *const c_void,
    user_info: Option<&CFDictionary>,
    deliver_immediately: bool,
) {
    extern "C-unwind" {
        fn CFNotificationCenterPostNotification(
            center: &CFNotificationCenter,
            name: Option<&CFNotificationName>,
            object: *const c_void,
            user_info: Option<&CFDictionary>,
            deliver_immediately: Boolean,
        );
    }
    unsafe {
        CFNotificationCenterPostNotification(
            center,
            name,
            object,
            user_info,
            deliver_immediately as _,
        )
    }
}

extern "C-unwind" {
    #[cfg(feature = "CFDictionary")]
    #[deprecated = "renamed to `CFNotificationCenter::post_notification_with_options`"]
    pub fn CFNotificationCenterPostNotificationWithOptions(
        center: &CFNotificationCenter,
        name: Option<&CFNotificationName>,
        object: *const c_void,
        user_info: Option<&CFDictionary>,
        options: CFOptionFlags,
    );
}
