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

use crate::*;

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

impl<SectionIdentifierType: ?Sized + Message, ItemIdentifierType: ?Sized + Message>
    NSDiffableDataSourceSnapshot<SectionIdentifierType, ItemIdentifierType>
{
    /// Unchecked conversion of the generic parameters.
    ///
    /// # Safety
    ///
    /// The generics must be valid to reinterpret as the given types.
    #[inline]
    pub unsafe fn cast_unchecked<
        NewSectionIdentifierType: ?Sized + Message,
        NewItemIdentifierType: ?Sized + Message,
    >(
        &self,
    ) -> &NSDiffableDataSourceSnapshot<NewSectionIdentifierType, NewItemIdentifierType> {
        unsafe { &*((self as *const Self).cast()) }
    }
}

extern_conformance!(
    unsafe impl<SectionIdentifierType: ?Sized, ItemIdentifierType: ?Sized> NSCopying
        for NSDiffableDataSourceSnapshot<SectionIdentifierType, ItemIdentifierType>
    {
    }
);

unsafe impl<SectionIdentifierType: ?Sized + Message, ItemIdentifierType: ?Sized + Message>
    CopyingHelper for NSDiffableDataSourceSnapshot<SectionIdentifierType, ItemIdentifierType>
{
    type Result = Self;
}

extern_conformance!(
    unsafe impl<SectionIdentifierType: ?Sized, ItemIdentifierType: ?Sized> NSObjectProtocol
        for NSDiffableDataSourceSnapshot<SectionIdentifierType, ItemIdentifierType>
    {
    }
);

impl<SectionIdentifierType: Message, ItemIdentifierType: Message>
    NSDiffableDataSourceSnapshot<SectionIdentifierType, ItemIdentifierType>
{
    extern_methods!(
        #[unsafe(method(numberOfItems))]
        #[unsafe(method_family = none)]
        pub fn numberOfItems(&self) -> NSInteger;

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

        #[unsafe(method(sectionIdentifiers))]
        #[unsafe(method_family = none)]
        pub fn sectionIdentifiers(&self) -> Retained<NSArray<SectionIdentifierType>>;

        #[unsafe(method(itemIdentifiers))]
        #[unsafe(method_family = none)]
        pub fn itemIdentifiers(&self) -> Retained<NSArray<ItemIdentifierType>>;

        #[unsafe(method(numberOfItemsInSection:))]
        #[unsafe(method_family = none)]
        pub fn numberOfItemsInSection(
            &self,
            section_identifier: &SectionIdentifierType,
        ) -> NSInteger;

        #[unsafe(method(itemIdentifiersInSectionWithIdentifier:))]
        #[unsafe(method_family = none)]
        pub fn itemIdentifiersInSectionWithIdentifier(
            &self,
            section_identifier: &SectionIdentifierType,
        ) -> Retained<NSArray<ItemIdentifierType>>;

        #[unsafe(method(sectionIdentifierForSectionContainingItemIdentifier:))]
        #[unsafe(method_family = none)]
        pub fn sectionIdentifierForSectionContainingItemIdentifier(
            &self,
            item_identifier: &ItemIdentifierType,
        ) -> Option<Retained<SectionIdentifierType>>;

        #[unsafe(method(indexOfItemIdentifier:))]
        #[unsafe(method_family = none)]
        pub fn indexOfItemIdentifier(&self, item_identifier: &ItemIdentifierType) -> NSInteger;

        #[unsafe(method(indexOfSectionIdentifier:))]
        #[unsafe(method_family = none)]
        pub fn indexOfSectionIdentifier(
            &self,
            section_identifier: &SectionIdentifierType,
        ) -> NSInteger;

        #[unsafe(method(appendItemsWithIdentifiers:))]
        #[unsafe(method_family = none)]
        pub fn appendItemsWithIdentifiers(&self, identifiers: &NSArray<ItemIdentifierType>);

        #[unsafe(method(appendItemsWithIdentifiers:intoSectionWithIdentifier:))]
        #[unsafe(method_family = none)]
        pub fn appendItemsWithIdentifiers_intoSectionWithIdentifier(
            &self,
            identifiers: &NSArray<ItemIdentifierType>,
            section_identifier: &SectionIdentifierType,
        );

        #[unsafe(method(insertItemsWithIdentifiers:beforeItemWithIdentifier:))]
        #[unsafe(method_family = none)]
        pub fn insertItemsWithIdentifiers_beforeItemWithIdentifier(
            &self,
            identifiers: &NSArray<ItemIdentifierType>,
            item_identifier: &ItemIdentifierType,
        );

        #[unsafe(method(insertItemsWithIdentifiers:afterItemWithIdentifier:))]
        #[unsafe(method_family = none)]
        pub fn insertItemsWithIdentifiers_afterItemWithIdentifier(
            &self,
            identifiers: &NSArray<ItemIdentifierType>,
            item_identifier: &ItemIdentifierType,
        );

        #[unsafe(method(deleteItemsWithIdentifiers:))]
        #[unsafe(method_family = none)]
        pub fn deleteItemsWithIdentifiers(&self, identifiers: &NSArray<ItemIdentifierType>);

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

        #[unsafe(method(moveItemWithIdentifier:beforeItemWithIdentifier:))]
        #[unsafe(method_family = none)]
        pub fn moveItemWithIdentifier_beforeItemWithIdentifier(
            &self,
            from_identifier: &ItemIdentifierType,
            to_identifier: &ItemIdentifierType,
        );

        #[unsafe(method(moveItemWithIdentifier:afterItemWithIdentifier:))]
        #[unsafe(method_family = none)]
        pub fn moveItemWithIdentifier_afterItemWithIdentifier(
            &self,
            from_identifier: &ItemIdentifierType,
            to_identifier: &ItemIdentifierType,
        );

        #[unsafe(method(reloadItemsWithIdentifiers:))]
        #[unsafe(method_family = none)]
        pub fn reloadItemsWithIdentifiers(&self, identifiers: &NSArray<ItemIdentifierType>);

        #[unsafe(method(appendSectionsWithIdentifiers:))]
        #[unsafe(method_family = none)]
        pub fn appendSectionsWithIdentifiers(
            &self,
            section_identifiers: &NSArray<SectionIdentifierType>,
        );

        #[unsafe(method(insertSectionsWithIdentifiers:beforeSectionWithIdentifier:))]
        #[unsafe(method_family = none)]
        pub fn insertSectionsWithIdentifiers_beforeSectionWithIdentifier(
            &self,
            section_identifiers: &NSArray<SectionIdentifierType>,
            to_section_identifier: &SectionIdentifierType,
        );

        #[unsafe(method(insertSectionsWithIdentifiers:afterSectionWithIdentifier:))]
        #[unsafe(method_family = none)]
        pub fn insertSectionsWithIdentifiers_afterSectionWithIdentifier(
            &self,
            section_identifiers: &NSArray<SectionIdentifierType>,
            to_section_identifier: &SectionIdentifierType,
        );

        #[unsafe(method(deleteSectionsWithIdentifiers:))]
        #[unsafe(method_family = none)]
        pub fn deleteSectionsWithIdentifiers(
            &self,
            section_identifiers: &NSArray<SectionIdentifierType>,
        );

        #[unsafe(method(moveSectionWithIdentifier:beforeSectionWithIdentifier:))]
        #[unsafe(method_family = none)]
        pub fn moveSectionWithIdentifier_beforeSectionWithIdentifier(
            &self,
            from_section_identifier: &SectionIdentifierType,
            to_section_identifier: &SectionIdentifierType,
        );

        #[unsafe(method(moveSectionWithIdentifier:afterSectionWithIdentifier:))]
        #[unsafe(method_family = none)]
        pub fn moveSectionWithIdentifier_afterSectionWithIdentifier(
            &self,
            from_section_identifier: &SectionIdentifierType,
            to_section_identifier: &SectionIdentifierType,
        );

        #[unsafe(method(reloadSectionsWithIdentifiers:))]
        #[unsafe(method_family = none)]
        pub fn reloadSectionsWithIdentifiers(
            &self,
            section_identifiers: &NSArray<SectionIdentifierType>,
        );
    );
}

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

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

impl<SectionIdentifierType: Message, ItemIdentifierType: Message> DefaultRetained
    for NSDiffableDataSourceSnapshot<SectionIdentifierType, ItemIdentifierType>
{
    #[inline]
    fn default_retained() -> Retained<Self> {
        Self::new()
    }
}

/// [Apple's documentation](https://developer.apple.com/documentation/appkit/nscollectionviewdiffabledatasourcesupplementaryviewprovider?language=objc)
#[cfg(all(
    feature = "NSCollectionView",
    feature = "NSResponder",
    feature = "NSView",
    feature = "block2"
))]
pub type NSCollectionViewDiffableDataSourceSupplementaryViewProvider = *mut block2::DynBlock<
    dyn Fn(NonNull<NSCollectionView>, NonNull<NSString>, NonNull<NSIndexPath>) -> *mut NSView,
>;

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

impl<SectionIdentifierType: ?Sized + Message, ItemIdentifierType: ?Sized + Message>
    NSCollectionViewDiffableDataSource<SectionIdentifierType, ItemIdentifierType>
{
    /// Unchecked conversion of the generic parameters.
    ///
    /// # Safety
    ///
    /// The generics must be valid to reinterpret as the given types.
    #[inline]
    pub unsafe fn cast_unchecked<
        NewSectionIdentifierType: ?Sized + Message,
        NewItemIdentifierType: ?Sized + Message,
    >(
        &self,
    ) -> &NSCollectionViewDiffableDataSource<NewSectionIdentifierType, NewItemIdentifierType> {
        unsafe { &*((self as *const Self).cast()) }
    }
}

extern_conformance!(
    unsafe impl<SectionIdentifierType: ?Sized, ItemIdentifierType: ?Sized> NSObjectProtocol
        for NSCollectionViewDiffableDataSource<SectionIdentifierType, ItemIdentifierType>
    {
    }
);

impl<SectionIdentifierType: Message, ItemIdentifierType: Message>
    NSCollectionViewDiffableDataSource<SectionIdentifierType, ItemIdentifierType>
{
    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>;

        #[unsafe(method(snapshot))]
        #[unsafe(method_family = none)]
        pub fn snapshot(
            &self,
        ) -> Retained<NSDiffableDataSourceSnapshot<SectionIdentifierType, ItemIdentifierType>>;

        #[unsafe(method(applySnapshot:animatingDifferences:))]
        #[unsafe(method_family = none)]
        pub fn applySnapshot_animatingDifferences(
            &self,
            snapshot: &NSDiffableDataSourceSnapshot<SectionIdentifierType, ItemIdentifierType>,
            animating_differences: bool,
        );

        #[unsafe(method(itemIdentifierForIndexPath:))]
        #[unsafe(method_family = none)]
        pub fn itemIdentifierForIndexPath(
            &self,
            index_path: &NSIndexPath,
        ) -> Option<Retained<ItemIdentifierType>>;

        #[unsafe(method(indexPathForItemIdentifier:))]
        #[unsafe(method_family = none)]
        pub fn indexPathForItemIdentifier(
            &self,
            identifier: &ItemIdentifierType,
        ) -> Option<Retained<NSIndexPath>>;

        #[cfg(all(
            feature = "NSCollectionView",
            feature = "NSResponder",
            feature = "NSView",
            feature = "block2"
        ))]
        /// # Safety
        ///
        /// - The returned block's argument 1 must be a valid pointer.
        /// - The returned block's argument 2 must be a valid pointer.
        /// - The returned block's argument 3 must be a valid pointer.
        #[unsafe(method(supplementaryViewProvider))]
        #[unsafe(method_family = none)]
        pub unsafe fn supplementaryViewProvider(
            &self,
            mtm: MainThreadMarker,
        ) -> NSCollectionViewDiffableDataSourceSupplementaryViewProvider;

        #[cfg(all(
            feature = "NSCollectionView",
            feature = "NSResponder",
            feature = "NSView",
            feature = "block2"
        ))]
        /// Setter for [`supplementaryViewProvider`][Self::supplementaryViewProvider].
        ///
        /// This is [copied][objc2_foundation::NSCopying::copy] when set.
        ///
        /// # Safety
        ///
        /// `supplementary_view_provider` must be a valid pointer or null.
        #[unsafe(method(setSupplementaryViewProvider:))]
        #[unsafe(method_family = none)]
        pub unsafe fn setSupplementaryViewProvider(
            &self,
            supplementary_view_provider: NSCollectionViewDiffableDataSourceSupplementaryViewProvider,
        );
    );
}
