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

use crate::*;

/// Options supported by methods that produce difference objects.
///
/// See also [Apple's documentation](https://developer.apple.com/documentation/foundation/nsorderedcollectiondifferencecalculationoptions?language=objc)
// NS_OPTIONS
#[repr(transparent)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct NSOrderedCollectionDifferenceCalculationOptions(pub NSUInteger);
bitflags::bitflags! {
    impl NSOrderedCollectionDifferenceCalculationOptions: NSUInteger {
/// Insertion changes do not store a reference to the inserted object.
        #[doc(alias = "NSOrderedCollectionDifferenceCalculationOmitInsertedObjects")]
        const OmitInsertedObjects = 1<<0;
/// Insertion changes do not store a reference to the removed object.
        #[doc(alias = "NSOrderedCollectionDifferenceCalculationOmitRemovedObjects")]
        const OmitRemovedObjects = 1<<1;
/// Assume objects that were uniquely removed and inserted were moved.
/// This is useful when diffing based on identity instead of equality.
        #[doc(alias = "NSOrderedCollectionDifferenceCalculationInferMoves")]
        const InferMoves = 1<<2;
    }
}

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

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

extern_class!(
    /// [Apple's documentation](https://developer.apple.com/documentation/foundation/nsorderedcollectiondifference?language=objc)
    #[unsafe(super(NSObject))]
    #[derive(Debug, PartialEq, Eq, Hash)]
    pub struct NSOrderedCollectionDifference<ObjectType: ?Sized = AnyObject>;
);

#[cfg(feature = "NSEnumerator")]
unsafe impl<ObjectType: ?Sized> NSFastEnumeration for NSOrderedCollectionDifference<ObjectType> {}

unsafe impl<ObjectType: ?Sized> NSObjectProtocol for NSOrderedCollectionDifference<ObjectType> {}

impl<ObjectType: Message> NSOrderedCollectionDifference<ObjectType> {
    extern_methods!(
        #[cfg(all(feature = "NSArray", feature = "NSOrderedCollectionChange"))]
        /// Creates a new difference representing the changes in the parameter.
        ///
        /// For clients interested in the difference between two collections, the
        /// collection's differenceFrom method should be used instead.
        ///
        /// To guarantee that instances are unambiguous and safe for compatible base
        /// states, this method requires that its parameter conform to the following
        /// requirements:
        ///
        /// 1) All insertion offsets are unique
        /// 2) All removal offsets are unique
        /// 3) All associated indexes match a change with the opposite parity.
        #[unsafe(method(initWithChanges:))]
        #[unsafe(method_family = init)]
        pub unsafe fn initWithChanges(
            this: Allocated<Self>,
            changes: &NSArray<NSOrderedCollectionChange<ObjectType>>,
        ) -> Retained<Self>;

        #[cfg(all(
            feature = "NSArray",
            feature = "NSIndexSet",
            feature = "NSOrderedCollectionChange"
        ))]
        #[unsafe(method(initWithInsertIndexes:insertedObjects:removeIndexes:removedObjects:additionalChanges:))]
        #[unsafe(method_family = init)]
        pub unsafe fn initWithInsertIndexes_insertedObjects_removeIndexes_removedObjects_additionalChanges(
            this: Allocated<Self>,
            inserts: &NSIndexSet,
            inserted_objects: Option<&NSArray<ObjectType>>,
            removes: &NSIndexSet,
            removed_objects: Option<&NSArray<ObjectType>>,
            changes: &NSArray<NSOrderedCollectionChange<ObjectType>>,
        ) -> Retained<Self>;

        #[cfg(all(feature = "NSArray", feature = "NSIndexSet"))]
        #[unsafe(method(initWithInsertIndexes:insertedObjects:removeIndexes:removedObjects:))]
        #[unsafe(method_family = init)]
        pub unsafe fn initWithInsertIndexes_insertedObjects_removeIndexes_removedObjects(
            this: Allocated<Self>,
            inserts: &NSIndexSet,
            inserted_objects: Option<&NSArray<ObjectType>>,
            removes: &NSIndexSet,
            removed_objects: Option<&NSArray<ObjectType>>,
        ) -> Retained<Self>;

        #[cfg(all(feature = "NSArray", feature = "NSOrderedCollectionChange"))]
        #[unsafe(method(insertions))]
        #[unsafe(method_family = none)]
        pub unsafe fn insertions(&self)
            -> Retained<NSArray<NSOrderedCollectionChange<ObjectType>>>;

        #[cfg(all(feature = "NSArray", feature = "NSOrderedCollectionChange"))]
        #[unsafe(method(removals))]
        #[unsafe(method_family = none)]
        pub unsafe fn removals(&self) -> Retained<NSArray<NSOrderedCollectionChange<ObjectType>>>;

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

        #[cfg(all(feature = "NSOrderedCollectionChange", feature = "block2"))]
        #[unsafe(method(differenceByTransformingChangesWithBlock:))]
        #[unsafe(method_family = none)]
        pub unsafe fn differenceByTransformingChangesWithBlock(
            &self,
            block: &block2::Block<
                dyn Fn(
                        NonNull<NSOrderedCollectionChange<ObjectType>>,
                    ) -> NonNull<NSOrderedCollectionChange<AnyObject>>
                    + '_,
            >,
        ) -> Retained<NSOrderedCollectionDifference<AnyObject>>;

        #[unsafe(method(inverseDifference))]
        #[unsafe(method_family = none)]
        pub unsafe fn inverseDifference(&self) -> Retained<Self>;
    );
}

/// Methods declared on superclass `NSObject`.
impl<ObjectType: Message> NSOrderedCollectionDifference<ObjectType> {
    extern_methods!(
        #[unsafe(method(init))]
        #[unsafe(method_family = init)]
        pub unsafe fn init(this: Allocated<Self>) -> Retained<Self>;

        #[unsafe(method(new))]
        #[unsafe(method_family = new)]
        pub unsafe fn new() -> Retained<Self>;
    );
}
