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

/// [Apple's documentation](https://developer.apple.com/documentation/uikit/uideferredmenuelementidentifier?language=objc)
// NS_TYPED_EXTENSIBLE_ENUM
pub type UIDeferredMenuElementIdentifier = NSString;

extern_class!(
    /// [Apple's documentation](https://developer.apple.com/documentation/uikit/uideferredmenuelement?language=objc)
    #[unsafe(super(UIMenuElement, NSObject))]
    #[thread_kind = MainThreadOnly]
    #[derive(Debug, PartialEq, Eq, Hash)]
    #[cfg(feature = "UIMenuElement")]
    pub struct UIDeferredMenuElement;
);

#[cfg(feature = "UIMenuElement")]
extern_conformance!(
    unsafe impl NSCoding for UIDeferredMenuElement {}
);

#[cfg(feature = "UIMenuElement")]
extern_conformance!(
    unsafe impl NSCopying for UIDeferredMenuElement {}
);

#[cfg(feature = "UIMenuElement")]
unsafe impl CopyingHelper for UIDeferredMenuElement {
    type Result = Self;
}

#[cfg(feature = "UIMenuElement")]
extern_conformance!(
    unsafe impl NSObjectProtocol for UIDeferredMenuElement {}
);

#[cfg(feature = "UIMenuElement")]
extern_conformance!(
    unsafe impl NSSecureCoding for UIDeferredMenuElement {}
);

#[cfg(feature = "UIMenuElement")]
impl UIDeferredMenuElement {
    extern_methods!(
        /// The identifier of this deferred menu element.
        #[unsafe(method(identifier))]
        #[unsafe(method_family = none)]
        pub fn identifier(&self) -> Retained<UIDeferredMenuElementIdentifier>;

        #[cfg(feature = "block2")]
        /// Returns a placeholder menu element that is replaced with the result of the block's
        /// completion handler. A loading UI takes the place of the element in the menu
        /// until it is fulfilled. While the element may be stored and re-used across menus, its block is
        /// called only once, when the element is first encountered in a menu.
        ///
        ///
        /// Parameter `elementProvider`: Called by the system to request the deferred menu items when the containing menu is presented.
        /// Call this block's completion handler when the menu items are available.
        ///
        /// # Safety
        ///
        /// `element_provider` block's argument block's argument must be a valid pointer.
        #[unsafe(method(elementWithProvider:))]
        #[unsafe(method_family = none)]
        pub unsafe fn elementWithProvider(
            element_provider: &block2::DynBlock<
                dyn Fn(NonNull<block2::DynBlock<dyn Fn(NonNull<NSArray<UIMenuElement>>)>>),
            >,
            mtm: MainThreadMarker,
        ) -> Retained<Self>;

        #[cfg(feature = "block2")]
        /// Returns a placeholder menu element that is replaced with the result of the block's
        /// completion handler. A loading UI takes the place of the element in the menu
        /// until it is fulfilled. Elements created using this initializer are "uncached",
        /// so their
        /// `elementProvider`block is called every time the element is displayed.
        ///
        ///
        /// Parameter `elementProvider`: Called by the system to request the deferred menu items when the containing menu is presented.
        /// Call this block's completion handler when the menu items are available.
        ///
        /// # Safety
        ///
        /// `element_provider` block's argument block's argument must be a valid pointer.
        #[unsafe(method(elementWithUncachedProvider:))]
        #[unsafe(method_family = none)]
        pub unsafe fn elementWithUncachedProvider(
            element_provider: &block2::DynBlock<
                dyn Fn(NonNull<block2::DynBlock<dyn Fn(NonNull<NSArray<UIMenuElement>>)>>),
            >,
            mtm: MainThreadMarker,
        ) -> Retained<Self>;

        /// Returns a placeholder menu element that is replaced with elements provided from the responder chain.
        /// A loading UI takes the place of the element in the menu until it is fulfilled. The element may be stored
        /// and re-used across menus.
        ///
        ///
        /// Parameter `identifier`: An identifier for this deferred element that responders can check to determine which elements
        /// to provide.
        ///
        /// Parameter `shouldCacheItems`: Whether or not the deferred element caches items. Passing in
        /// `YES`causes this deferred element to
        /// ask the responder chain for elements only once, when the element is first encountered in a menu.
        /// Passing in
        /// `NO`asks the responder chain for elements every time the element is displayed.
        #[unsafe(method(elementUsingFocusWithIdentifier:shouldCacheItems:))]
        #[unsafe(method_family = none)]
        pub fn elementUsingFocusWithIdentifier_shouldCacheItems(
            identifier: &UIDeferredMenuElementIdentifier,
            should_cache_items: bool,
            mtm: MainThreadMarker,
        ) -> Retained<Self>;
    );
}

/// Methods declared on superclass `UIMenuElement`.
#[cfg(feature = "UIMenuElement")]
impl UIDeferredMenuElement {
    extern_methods!(
        /// # Safety
        ///
        /// `coder` possibly has further requirements.
        #[unsafe(method(initWithCoder:))]
        #[unsafe(method_family = init)]
        pub unsafe fn initWithCoder(
            this: Allocated<Self>,
            coder: &NSCoder,
        ) -> Option<Retained<Self>>;

        #[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(mtm: MainThreadMarker) -> Retained<Self>;
    );
}

extern_class!(
    /// Represents an element provider for a deferred menu element.
    /// When the containing menu for a responder-based deferred element is presented, the system asks the
    /// responder chain for one of these element providers for the deferred element.
    ///
    /// See also [Apple's documentation](https://developer.apple.com/documentation/uikit/uideferredmenuelementprovider?language=objc)
    #[unsafe(super(NSObject))]
    #[thread_kind = MainThreadOnly]
    #[derive(Debug, PartialEq, Eq, Hash)]
    pub struct UIDeferredMenuElementProvider;
);

extern_conformance!(
    unsafe impl NSObjectProtocol for UIDeferredMenuElementProvider {}
);

impl UIDeferredMenuElementProvider {
    extern_methods!(
        #[cfg(all(feature = "UIMenuElement", feature = "block2"))]
        /// Creates a deferred menu element provider with an asynchronous block.
        ///
        ///
        /// Parameter `elementProvider`: An asynchronous element provider block. Call this block's completion handler when the responder's
        /// menu items are available.
        ///
        /// # Safety
        ///
        /// `element_provider` block's argument block's argument must be a valid pointer.
        #[unsafe(method(providerWithElementProvider:))]
        #[unsafe(method_family = none)]
        pub unsafe fn providerWithElementProvider(
            element_provider: &block2::DynBlock<
                dyn Fn(NonNull<block2::DynBlock<dyn Fn(NonNull<NSArray<UIMenuElement>>)>>),
            >,
            mtm: MainThreadMarker,
        ) -> Retained<Self>;

        #[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(mtm: MainThreadMarker) -> Retained<Self>;
    );
}
