//! This file has been automatically generated by `objc2`'s `header-translator`.
//! DO NOT EDIT
use core::ffi::*;
use core::ptr::NonNull;
use objc2::__framework_prelude::*;

use crate::*;

extern_protocol!(
    /// [Apple's documentation](https://developer.apple.com/documentation/foundation/nscoding?language=objc)
    pub unsafe trait NSCoding {
        #[cfg(feature = "NSCoder")]
        /// # Safety
        ///
        /// `coder` possibly has further requirements.
        #[unsafe(method(encodeWithCoder:))]
        #[unsafe(method_family = none)]
        unsafe fn encodeWithCoder(&self, coder: &NSCoder);

        #[cfg(feature = "NSCoder")]
        /// # Safety
        ///
        /// `coder` possibly has further requirements.
        #[unsafe(method(initWithCoder:))]
        #[unsafe(method_family = init)]
        unsafe fn initWithCoder(this: Allocated<Self>, coder: &NSCoder) -> Option<Retained<Self>>;
    }
);

extern_protocol!(
    /// [Apple's documentation](https://developer.apple.com/documentation/foundation/nssecurecoding?language=objc)
    pub unsafe trait NSSecureCoding: NSCoding {
        #[unsafe(method(supportsSecureCoding))]
        #[unsafe(method_family = none)]
        fn supportsSecureCoding() -> bool;
    }
);

mod private_NSObjectNSCoderMethods {
    pub trait Sealed {}
}

/// Category "NSCoderMethods" on [`NSObject`].
///
/// *********    Base class        **********
#[doc(alias = "NSCoderMethods")]
pub unsafe trait NSObjectNSCoderMethods:
    ClassType + Sized + private_NSObjectNSCoderMethods::Sealed
{
    extern_methods!(
        #[unsafe(method(version))]
        #[unsafe(method_family = none)]
        fn version() -> NSInteger;

        #[unsafe(method(setVersion:))]
        #[unsafe(method_family = none)]
        unsafe fn setVersion(a_version: NSInteger);

        #[unsafe(method(classForCoder))]
        #[unsafe(method_family = none)]
        fn classForCoder(&self) -> &'static AnyClass;

        #[cfg(feature = "NSCoder")]
        /// # Safety
        ///
        /// `coder` possibly has further requirements.
        #[unsafe(method(replacementObjectForCoder:))]
        #[unsafe(method_family = none)]
        unsafe fn replacementObjectForCoder(&self, coder: &NSCoder) -> Option<Retained<AnyObject>>;
    );
}

impl private_NSObjectNSCoderMethods::Sealed for NSObject {}
unsafe impl NSObjectNSCoderMethods for NSObject {}

extern_protocol!(
    /// *********    Discardable Content        **********
    ///
    /// See also [Apple's documentation](https://developer.apple.com/documentation/foundation/nsdiscardablecontent?language=objc)
    pub unsafe trait NSDiscardableContent {
        #[unsafe(method(beginContentAccess))]
        #[unsafe(method_family = none)]
        fn beginContentAccess(&self) -> bool;

        #[unsafe(method(endContentAccess))]
        #[unsafe(method_family = none)]
        fn endContentAccess(&self);

        #[unsafe(method(discardContentIfPossible))]
        #[unsafe(method_family = none)]
        fn discardContentIfPossible(&self);

        #[unsafe(method(isContentDiscarded))]
        #[unsafe(method_family = none)]
        fn isContentDiscarded(&self) -> bool;
    }
);

mod private_NSObjectNSDiscardableContentProxy {
    pub trait Sealed {}
}

/// Category "NSDiscardableContentProxy" on [`NSObject`].
#[doc(alias = "NSDiscardableContentProxy")]
pub unsafe trait NSObjectNSDiscardableContentProxy:
    ClassType + Sized + private_NSObjectNSDiscardableContentProxy::Sealed
{
    extern_methods!(
        #[unsafe(method(autoContentAccessingProxy))]
        #[unsafe(method_family = none)]
        fn autoContentAccessingProxy(&self) -> Retained<AnyObject>;
    );
}

impl private_NSObjectNSDiscardableContentProxy::Sealed for NSObject {}
unsafe impl NSObjectNSDiscardableContentProxy for NSObject {}

/// *********    Object Allocation / Deallocation        ******
///
/// # Safety
///
/// - `a_class` probably has further requirements.
/// - `zone` must be a valid pointer or null.
#[cfg(feature = "NSZone")]
#[inline]
pub unsafe extern "C-unwind" fn NSAllocateObject(
    a_class: &AnyClass,
    extra_bytes: NSUInteger,
    zone: *mut NSZone,
) -> Retained<AnyObject> {
    extern "C-unwind" {
        fn NSAllocateObject(
            a_class: &AnyClass,
            extra_bytes: NSUInteger,
            zone: *mut NSZone,
        ) -> *mut AnyObject;
    }
    let ret = unsafe { NSAllocateObject(a_class, extra_bytes, zone) };
    unsafe { Retained::retain_autoreleased(ret) }
        .expect("function was marked as returning non-null, but actually returned NULL")
}

extern "C-unwind" {
    /// # Safety
    ///
    /// `object` should be of the correct type.
    pub fn NSDeallocateObject(object: &AnyObject);
}

/// # Safety
///
/// - `object` should be of the correct type.
/// - `zone` must be a valid pointer or null.
#[cfg(feature = "NSZone")]
#[deprecated = "Not supported"]
#[inline]
pub unsafe extern "C-unwind" fn NSCopyObject(
    object: &AnyObject,
    extra_bytes: NSUInteger,
    zone: *mut NSZone,
) -> Retained<AnyObject> {
    extern "C-unwind" {
        fn NSCopyObject(
            object: &AnyObject,
            extra_bytes: NSUInteger,
            zone: *mut NSZone,
        ) -> *mut AnyObject;
    }
    let ret = unsafe { NSCopyObject(object, extra_bytes, zone) };
    unsafe { Retained::from_raw(ret) }
        .expect("function was marked as returning non-null, but actually returned NULL")
}

/// # Safety
///
/// - `an_object` should be of the correct type.
/// - `requested_zone` must be a valid pointer or null.
#[cfg(feature = "NSZone")]
#[inline]
pub unsafe extern "C-unwind" fn NSShouldRetainWithZone(
    an_object: &AnyObject,
    requested_zone: *mut NSZone,
) -> bool {
    extern "C-unwind" {
        fn NSShouldRetainWithZone(an_object: &AnyObject, requested_zone: *mut NSZone) -> Bool;
    }
    unsafe { NSShouldRetainWithZone(an_object, requested_zone) }.as_bool()
}

extern "C-unwind" {
    /// # Safety
    ///
    /// `object` should be of the correct type.
    pub fn NSIncrementExtraRefCount(object: &AnyObject);
}

/// # Safety
///
/// `object` should be of the correct type.
#[inline]
pub unsafe extern "C-unwind" fn NSDecrementExtraRefCountWasZero(object: &AnyObject) -> bool {
    extern "C-unwind" {
        fn NSDecrementExtraRefCountWasZero(object: &AnyObject) -> Bool;
    }
    unsafe { NSDecrementExtraRefCountWasZero(object) }.as_bool()
}

extern "C-unwind" {
    /// # Safety
    ///
    /// `object` should be of the correct type.
    pub fn NSExtraRefCount(object: &AnyObject) -> NSUInteger;
}
