//! 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::*;

/// [Apple's documentation](https://developer.apple.com/documentation/foundation/nskeyvalueobservingoptions?language=objc)
// NS_OPTIONS
#[repr(transparent)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct NSKeyValueObservingOptions(pub NSUInteger);
bitflags::bitflags! {
    impl NSKeyValueObservingOptions: NSUInteger {
        #[doc(alias = "NSKeyValueObservingOptionNew")]
        const New = 0x01;
        #[doc(alias = "NSKeyValueObservingOptionOld")]
        const Old = 0x02;
        #[doc(alias = "NSKeyValueObservingOptionInitial")]
        const Initial = 0x04;
        #[doc(alias = "NSKeyValueObservingOptionPrior")]
        const Prior = 0x08;
    }
}

unsafe impl Encode for NSKeyValueObservingOptions {
    const ENCODING: Encoding = NSUInteger::ENCODING;
}

unsafe impl RefEncode for NSKeyValueObservingOptions {
    const ENCODING_REF: Encoding = Encoding::Pointer(&Self::ENCODING);
}

/// [Apple's documentation](https://developer.apple.com/documentation/foundation/nskeyvaluechange?language=objc)
// NS_ENUM
#[repr(transparent)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct NSKeyValueChange(pub NSUInteger);
impl NSKeyValueChange {
    #[doc(alias = "NSKeyValueChangeSetting")]
    pub const Setting: Self = Self(1);
    #[doc(alias = "NSKeyValueChangeInsertion")]
    pub const Insertion: Self = Self(2);
    #[doc(alias = "NSKeyValueChangeRemoval")]
    pub const Removal: Self = Self(3);
    #[doc(alias = "NSKeyValueChangeReplacement")]
    pub const Replacement: Self = Self(4);
}

unsafe impl Encode for NSKeyValueChange {
    const ENCODING: Encoding = NSUInteger::ENCODING;
}

unsafe impl RefEncode for NSKeyValueChange {
    const ENCODING_REF: Encoding = Encoding::Pointer(&Self::ENCODING);
}

/// [Apple's documentation](https://developer.apple.com/documentation/foundation/nskeyvaluesetmutationkind?language=objc)
// NS_ENUM
#[repr(transparent)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct NSKeyValueSetMutationKind(pub NSUInteger);
impl NSKeyValueSetMutationKind {
    #[doc(alias = "NSKeyValueUnionSetMutation")]
    pub const UnionSetMutation: Self = Self(1);
    #[doc(alias = "NSKeyValueMinusSetMutation")]
    pub const MinusSetMutation: Self = Self(2);
    #[doc(alias = "NSKeyValueIntersectSetMutation")]
    pub const IntersectSetMutation: Self = Self(3);
    #[doc(alias = "NSKeyValueSetSetMutation")]
    pub const SetSetMutation: Self = Self(4);
}

unsafe impl Encode for NSKeyValueSetMutationKind {
    const ENCODING: Encoding = NSUInteger::ENCODING;
}

unsafe impl RefEncode for NSKeyValueSetMutationKind {
    const ENCODING_REF: Encoding = Encoding::Pointer(&Self::ENCODING);
}

/// [Apple's documentation](https://developer.apple.com/documentation/foundation/nskeyvaluechangekey?language=objc)
// NS_TYPED_ENUM
#[cfg(feature = "NSString")]
pub type NSKeyValueChangeKey = NSString;

extern "C" {
    /// [Apple's documentation](https://developer.apple.com/documentation/foundation/nskeyvaluechangekindkey?language=objc)
    #[cfg(feature = "NSString")]
    pub static NSKeyValueChangeKindKey: &'static NSKeyValueChangeKey;
}

extern "C" {
    /// [Apple's documentation](https://developer.apple.com/documentation/foundation/nskeyvaluechangenewkey?language=objc)
    #[cfg(feature = "NSString")]
    pub static NSKeyValueChangeNewKey: &'static NSKeyValueChangeKey;
}

extern "C" {
    /// [Apple's documentation](https://developer.apple.com/documentation/foundation/nskeyvaluechangeoldkey?language=objc)
    #[cfg(feature = "NSString")]
    pub static NSKeyValueChangeOldKey: &'static NSKeyValueChangeKey;
}

extern "C" {
    /// [Apple's documentation](https://developer.apple.com/documentation/foundation/nskeyvaluechangeindexeskey?language=objc)
    #[cfg(feature = "NSString")]
    pub static NSKeyValueChangeIndexesKey: &'static NSKeyValueChangeKey;
}

extern "C" {
    /// [Apple's documentation](https://developer.apple.com/documentation/foundation/nskeyvaluechangenotificationispriorkey?language=objc)
    #[cfg(feature = "NSString")]
    pub static NSKeyValueChangeNotificationIsPriorKey: &'static NSKeyValueChangeKey;
}

mod private_NSObjectNSKeyValueObserving {
    pub trait Sealed {}
}

/// Category "NSKeyValueObserving" on [`NSObject`].
#[doc(alias = "NSKeyValueObserving")]
pub unsafe trait NSObjectNSKeyValueObserving:
    ClassType + Sized + private_NSObjectNSKeyValueObserving::Sealed
{
    extern_methods!(
        #[cfg(all(feature = "NSDictionary", feature = "NSString"))]
        /// # Safety
        ///
        /// - `object` should be of the correct type.
        /// - `change` generic should be of the correct type.
        /// - `context` must be a valid pointer or null.
        #[unsafe(method(observeValueForKeyPath:ofObject:change:context:))]
        #[unsafe(method_family = none)]
        unsafe fn observeValueForKeyPath_ofObject_change_context(
            &self,
            key_path: Option<&NSString>,
            object: Option<&AnyObject>,
            change: Option<&NSDictionary<NSKeyValueChangeKey, AnyObject>>,
            context: *mut c_void,
        );
    );
}

impl private_NSObjectNSKeyValueObserving::Sealed for NSObject {}
unsafe impl NSObjectNSKeyValueObserving for NSObject {}

mod private_NSObjectNSKeyValueObserverRegistration {
    pub trait Sealed {}
}

/// Category "NSKeyValueObserverRegistration" on [`NSObject`].
#[doc(alias = "NSKeyValueObserverRegistration")]
pub unsafe trait NSObjectNSKeyValueObserverRegistration:
    ClassType + Sized + private_NSObjectNSKeyValueObserverRegistration::Sealed
{
    extern_methods!(
        #[cfg(feature = "NSString")]
        /// # Safety
        ///
        /// - `observer` should be of the correct type.
        /// - `context` must be a valid pointer or null.
        #[unsafe(method(addObserver:forKeyPath:options:context:))]
        #[unsafe(method_family = none)]
        unsafe fn addObserver_forKeyPath_options_context(
            &self,
            observer: &NSObject,
            key_path: &NSString,
            options: NSKeyValueObservingOptions,
            context: *mut c_void,
        );

        #[cfg(feature = "NSString")]
        /// # Safety
        ///
        /// - `observer` should be of the correct type.
        /// - `context` must be a valid pointer or null.
        #[unsafe(method(removeObserver:forKeyPath:context:))]
        #[unsafe(method_family = none)]
        unsafe fn removeObserver_forKeyPath_context(
            &self,
            observer: &NSObject,
            key_path: &NSString,
            context: *mut c_void,
        );

        #[cfg(feature = "NSString")]
        /// # Safety
        ///
        /// `observer` should be of the correct type.
        #[unsafe(method(removeObserver:forKeyPath:))]
        #[unsafe(method_family = none)]
        unsafe fn removeObserver_forKeyPath(&self, observer: &NSObject, key_path: &NSString);
    );
}

impl private_NSObjectNSKeyValueObserverRegistration::Sealed for NSObject {}
unsafe impl NSObjectNSKeyValueObserverRegistration for NSObject {}

/// NSKeyValueObserverRegistration.
#[cfg(feature = "NSArray")]
impl<ObjectType: Message> NSArray<ObjectType> {
    extern_methods!(
        #[cfg(all(feature = "NSIndexSet", feature = "NSString"))]
        /// # Safety
        ///
        /// - `observer` should be of the correct type.
        /// - `context` must be a valid pointer or null.
        #[unsafe(method(addObserver:toObjectsAtIndexes:forKeyPath:options:context:))]
        #[unsafe(method_family = none)]
        pub unsafe fn addObserver_toObjectsAtIndexes_forKeyPath_options_context(
            &self,
            observer: &NSObject,
            indexes: &NSIndexSet,
            key_path: &NSString,
            options: NSKeyValueObservingOptions,
            context: *mut c_void,
        );

        #[cfg(all(feature = "NSIndexSet", feature = "NSString"))]
        /// # Safety
        ///
        /// - `observer` should be of the correct type.
        /// - `context` must be a valid pointer or null.
        #[unsafe(method(removeObserver:fromObjectsAtIndexes:forKeyPath:context:))]
        #[unsafe(method_family = none)]
        pub unsafe fn removeObserver_fromObjectsAtIndexes_forKeyPath_context(
            &self,
            observer: &NSObject,
            indexes: &NSIndexSet,
            key_path: &NSString,
            context: *mut c_void,
        );

        #[cfg(all(feature = "NSIndexSet", feature = "NSString"))]
        /// # Safety
        ///
        /// `observer` should be of the correct type.
        #[unsafe(method(removeObserver:fromObjectsAtIndexes:forKeyPath:))]
        #[unsafe(method_family = none)]
        pub unsafe fn removeObserver_fromObjectsAtIndexes_forKeyPath(
            &self,
            observer: &NSObject,
            indexes: &NSIndexSet,
            key_path: &NSString,
        );

        #[cfg(feature = "NSString")]
        /// # Safety
        ///
        /// - `observer` should be of the correct type.
        /// - `context` must be a valid pointer or null.
        #[unsafe(method(addObserver:forKeyPath:options:context:))]
        #[unsafe(method_family = none)]
        pub unsafe fn addObserver_forKeyPath_options_context(
            &self,
            observer: &NSObject,
            key_path: &NSString,
            options: NSKeyValueObservingOptions,
            context: *mut c_void,
        );

        #[cfg(feature = "NSString")]
        /// # Safety
        ///
        /// - `observer` should be of the correct type.
        /// - `context` must be a valid pointer or null.
        #[unsafe(method(removeObserver:forKeyPath:context:))]
        #[unsafe(method_family = none)]
        pub unsafe fn removeObserver_forKeyPath_context(
            &self,
            observer: &NSObject,
            key_path: &NSString,
            context: *mut c_void,
        );

        #[cfg(feature = "NSString")]
        /// # Safety
        ///
        /// `observer` should be of the correct type.
        #[unsafe(method(removeObserver:forKeyPath:))]
        #[unsafe(method_family = none)]
        pub unsafe fn removeObserver_forKeyPath(&self, observer: &NSObject, key_path: &NSString);
    );
}

/// NSKeyValueObserverRegistration.
#[cfg(feature = "NSOrderedSet")]
impl<ObjectType: Message> NSOrderedSet<ObjectType> {
    extern_methods!(
        #[cfg(feature = "NSString")]
        /// # Safety
        ///
        /// - `observer` should be of the correct type.
        /// - `context` must be a valid pointer or null.
        #[unsafe(method(addObserver:forKeyPath:options:context:))]
        #[unsafe(method_family = none)]
        pub unsafe fn addObserver_forKeyPath_options_context(
            &self,
            observer: &NSObject,
            key_path: &NSString,
            options: NSKeyValueObservingOptions,
            context: *mut c_void,
        );

        #[cfg(feature = "NSString")]
        /// # Safety
        ///
        /// - `observer` should be of the correct type.
        /// - `context` must be a valid pointer or null.
        #[unsafe(method(removeObserver:forKeyPath:context:))]
        #[unsafe(method_family = none)]
        pub unsafe fn removeObserver_forKeyPath_context(
            &self,
            observer: &NSObject,
            key_path: &NSString,
            context: *mut c_void,
        );

        #[cfg(feature = "NSString")]
        /// # Safety
        ///
        /// `observer` should be of the correct type.
        #[unsafe(method(removeObserver:forKeyPath:))]
        #[unsafe(method_family = none)]
        pub unsafe fn removeObserver_forKeyPath(&self, observer: &NSObject, key_path: &NSString);
    );
}

/// NSKeyValueObserverRegistration.
#[cfg(feature = "NSSet")]
impl<ObjectType: Message> NSSet<ObjectType> {
    extern_methods!(
        #[cfg(feature = "NSString")]
        /// # Safety
        ///
        /// - `observer` should be of the correct type.
        /// - `context` must be a valid pointer or null.
        #[unsafe(method(addObserver:forKeyPath:options:context:))]
        #[unsafe(method_family = none)]
        pub unsafe fn addObserver_forKeyPath_options_context(
            &self,
            observer: &NSObject,
            key_path: &NSString,
            options: NSKeyValueObservingOptions,
            context: *mut c_void,
        );

        #[cfg(feature = "NSString")]
        /// # Safety
        ///
        /// - `observer` should be of the correct type.
        /// - `context` must be a valid pointer or null.
        #[unsafe(method(removeObserver:forKeyPath:context:))]
        #[unsafe(method_family = none)]
        pub unsafe fn removeObserver_forKeyPath_context(
            &self,
            observer: &NSObject,
            key_path: &NSString,
            context: *mut c_void,
        );

        #[cfg(feature = "NSString")]
        /// # Safety
        ///
        /// `observer` should be of the correct type.
        #[unsafe(method(removeObserver:forKeyPath:))]
        #[unsafe(method_family = none)]
        pub unsafe fn removeObserver_forKeyPath(&self, observer: &NSObject, key_path: &NSString);
    );
}

mod private_NSObjectNSKeyValueObserverNotification {
    pub trait Sealed {}
}

/// Category "NSKeyValueObserverNotification" on [`NSObject`].
#[doc(alias = "NSKeyValueObserverNotification")]
pub unsafe trait NSObjectNSKeyValueObserverNotification:
    ClassType + Sized + private_NSObjectNSKeyValueObserverNotification::Sealed
{
    extern_methods!(
        #[cfg(feature = "NSString")]
        #[unsafe(method(willChangeValueForKey:))]
        #[unsafe(method_family = none)]
        fn willChangeValueForKey(&self, key: &NSString);

        #[cfg(feature = "NSString")]
        #[unsafe(method(didChangeValueForKey:))]
        #[unsafe(method_family = none)]
        fn didChangeValueForKey(&self, key: &NSString);

        #[cfg(all(feature = "NSIndexSet", feature = "NSString"))]
        #[unsafe(method(willChange:valuesAtIndexes:forKey:))]
        #[unsafe(method_family = none)]
        fn willChange_valuesAtIndexes_forKey(
            &self,
            change_kind: NSKeyValueChange,
            indexes: &NSIndexSet,
            key: &NSString,
        );

        #[cfg(all(feature = "NSIndexSet", feature = "NSString"))]
        #[unsafe(method(didChange:valuesAtIndexes:forKey:))]
        #[unsafe(method_family = none)]
        fn didChange_valuesAtIndexes_forKey(
            &self,
            change_kind: NSKeyValueChange,
            indexes: &NSIndexSet,
            key: &NSString,
        );

        #[cfg(all(feature = "NSSet", feature = "NSString"))]
        /// # Safety
        ///
        /// `objects` generic should be of the correct type.
        #[unsafe(method(willChangeValueForKey:withSetMutation:usingObjects:))]
        #[unsafe(method_family = none)]
        unsafe fn willChangeValueForKey_withSetMutation_usingObjects(
            &self,
            key: &NSString,
            mutation_kind: NSKeyValueSetMutationKind,
            objects: &NSSet,
        );

        #[cfg(all(feature = "NSSet", feature = "NSString"))]
        /// # Safety
        ///
        /// `objects` generic should be of the correct type.
        #[unsafe(method(didChangeValueForKey:withSetMutation:usingObjects:))]
        #[unsafe(method_family = none)]
        unsafe fn didChangeValueForKey_withSetMutation_usingObjects(
            &self,
            key: &NSString,
            mutation_kind: NSKeyValueSetMutationKind,
            objects: &NSSet,
        );
    );
}

impl private_NSObjectNSKeyValueObserverNotification::Sealed for NSObject {}
unsafe impl NSObjectNSKeyValueObserverNotification for NSObject {}

mod private_NSObjectNSKeyValueObservingCustomization {
    pub trait Sealed {}
}

/// Category "NSKeyValueObservingCustomization" on [`NSObject`].
#[doc(alias = "NSKeyValueObservingCustomization")]
pub unsafe trait NSObjectNSKeyValueObservingCustomization:
    ClassType + Sized + private_NSObjectNSKeyValueObservingCustomization::Sealed
{
    extern_methods!(
        #[cfg(all(feature = "NSSet", feature = "NSString"))]
        #[unsafe(method(keyPathsForValuesAffectingValueForKey:))]
        #[unsafe(method_family = none)]
        fn keyPathsForValuesAffectingValueForKey(key: &NSString) -> Retained<NSSet<NSString>>;

        #[cfg(feature = "NSString")]
        #[unsafe(method(automaticallyNotifiesObserversForKey:))]
        #[unsafe(method_family = none)]
        fn automaticallyNotifiesObserversForKey(key: &NSString) -> bool;

        #[unsafe(method(observationInfo))]
        #[unsafe(method_family = none)]
        fn observationInfo(&self) -> *mut c_void;

        /// Setter for [`observationInfo`][Self::observationInfo].
        ///
        /// # Safety
        ///
        /// `observation_info` must be a valid pointer or null.
        #[unsafe(method(setObservationInfo:))]
        #[unsafe(method_family = none)]
        unsafe fn setObservationInfo(&self, observation_info: *mut c_void);
    );
}

impl private_NSObjectNSKeyValueObservingCustomization::Sealed for NSObject {}
unsafe impl NSObjectNSKeyValueObservingCustomization for NSObject {}
