//! 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::*;
#[cfg(feature = "objc2-core-foundation")]
use objc2_core_foundation::*;
use objc2_foundation::*;

use crate::*;

/// [Apple's documentation](https://developer.apple.com/documentation/uikit/uieditmenuarrowdirection?language=objc)
// NS_ENUM
#[repr(transparent)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct UIEditMenuArrowDirection(pub NSInteger);
impl UIEditMenuArrowDirection {
    #[doc(alias = "UIEditMenuArrowDirectionAutomatic")]
    pub const Automatic: Self = Self(0);
    #[doc(alias = "UIEditMenuArrowDirectionUp")]
    pub const Up: Self = Self(1);
    #[doc(alias = "UIEditMenuArrowDirectionDown")]
    pub const Down: Self = Self(2);
    #[doc(alias = "UIEditMenuArrowDirectionLeft")]
    pub const Left: Self = Self(3);
    #[doc(alias = "UIEditMenuArrowDirectionRight")]
    pub const Right: Self = Self(4);
}

unsafe impl Encode for UIEditMenuArrowDirection {
    const ENCODING: Encoding = NSInteger::ENCODING;
}

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

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

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

impl UIEditMenuConfiguration {
    extern_methods!(
        /// The unique identifier of the configuration.
        #[unsafe(method(identifier))]
        #[unsafe(method_family = none)]
        pub fn identifier(&self) -> Retained<ProtocolObject<dyn NSCopying>>;

        #[cfg(feature = "objc2-core-foundation")]
        /// The source location of the menu. The suggested actions menu elements will be derived from this location in the interaction's view.
        /// By default, the menu will be presented from this location. You can change the presentation source of the menu with the delegate
        /// method
        /// `editMenuInteraction:targetRectForConfiguration:`
        #[unsafe(method(sourcePoint))]
        #[unsafe(method_family = none)]
        pub fn sourcePoint(&self) -> CGPoint;

        /// The preferred arrow direction of the edit menu. Default is
        /// `UIEditMenuArrowDirectionAutomatic`
        #[unsafe(method(preferredArrowDirection))]
        #[unsafe(method_family = none)]
        pub fn preferredArrowDirection(&self) -> UIEditMenuArrowDirection;

        /// Setter for [`preferredArrowDirection`][Self::preferredArrowDirection].
        #[unsafe(method(setPreferredArrowDirection:))]
        #[unsafe(method_family = none)]
        pub fn setPreferredArrowDirection(
            &self,
            preferred_arrow_direction: UIEditMenuArrowDirection,
        );

        #[cfg(feature = "objc2-core-foundation")]
        /// Creates a new configuration with the specified source location.
        ///
        /// # Safety
        ///
        /// `identifier` should be of the correct type.
        #[unsafe(method(configurationWithIdentifier:sourcePoint:))]
        #[unsafe(method_family = none)]
        pub unsafe fn configurationWithIdentifier_sourcePoint(
            identifier: Option<&ProtocolObject<dyn NSCopying>>,
            source_point: CGPoint,
            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>;
    );
}

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

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

#[cfg(feature = "UIInteraction")]
extern_conformance!(
    unsafe impl UIInteraction for UIEditMenuInteraction {}
);

impl UIEditMenuInteraction {
    extern_methods!(
        /// The object that defines the delegate of the interaction.
        #[unsafe(method(delegate))]
        #[unsafe(method_family = none)]
        pub fn delegate(
            &self,
        ) -> Option<Retained<ProtocolObject<dyn UIEditMenuInteractionDelegate>>>;

        /// Creates a new edit menu interaction with the specified delegate.
        #[unsafe(method(initWithDelegate:))]
        #[unsafe(method_family = init)]
        pub fn initWithDelegate(
            this: Allocated<Self>,
            delegate: Option<&ProtocolObject<dyn UIEditMenuInteractionDelegate>>,
        ) -> Retained<Self>;

        /// Presents an edit menu with the specified
        /// `configuration`object.
        /// If a menu is already presented, it will be dismissed automatically before the new menu is presented.
        ///
        /// :
        /// `presentEditMenuWithConfiguration:`is not supported on Mac Catalyst.
        #[unsafe(method(presentEditMenuWithConfiguration:))]
        #[unsafe(method_family = none)]
        pub fn presentEditMenuWithConfiguration(&self, configuration: &UIEditMenuConfiguration);

        /// Dismiss the currently active menu if one is currently presented.
        #[unsafe(method(dismissMenu))]
        #[unsafe(method_family = none)]
        pub fn dismissMenu(&self);

        /// Reloads the visible menu. This menu has no effect if there is no menu presented. This method will query
        /// the menu again from the delegate method
        /// `editMenuInteraction:menuForConfiguration:suggestedActions:`and refresh the UI with the updated menu.
        #[unsafe(method(reloadVisibleMenu))]
        #[unsafe(method_family = none)]
        pub fn reloadVisibleMenu(&self);

        /// Updates the position of the currently visible menu, with an option to animate the action. This method
        /// has no effect if no menu is presented. This method will query the position from the delegate method
        /// `editMenuInteraction:targetRectForConfiguration:`if it is implemented.
        #[unsafe(method(updateVisibleMenuPositionAnimated:))]
        #[unsafe(method_family = none)]
        pub fn updateVisibleMenuPositionAnimated(&self, animated: bool);

        #[cfg(all(
            feature = "UIResponder",
            feature = "UIView",
            feature = "objc2-core-foundation"
        ))]
        /// Returns the interaction's location within the given view.
        #[unsafe(method(locationInView:))]
        #[unsafe(method_family = none)]
        pub fn locationInView(&self, view: Option<&UIView>) -> CGPoint;

        #[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_protocol!(
    /// [Apple's documentation](https://developer.apple.com/documentation/uikit/uieditmenuinteractionanimating?language=objc)
    pub unsafe trait UIEditMenuInteractionAnimating:
        NSObjectProtocol + MainThreadOnly
    {
        #[cfg(feature = "block2")]
        #[unsafe(method(addAnimations:))]
        #[unsafe(method_family = none)]
        fn addAnimations(&self, animations: &block2::DynBlock<dyn Fn()>);

        #[cfg(feature = "block2")]
        #[unsafe(method(addCompletion:))]
        #[unsafe(method_family = none)]
        fn addCompletion(&self, completion: &block2::DynBlock<dyn Fn()>);
    }
);

extern_protocol!(
    /// [Apple's documentation](https://developer.apple.com/documentation/uikit/uieditmenuinteractiondelegate?language=objc)
    pub unsafe trait UIEditMenuInteractionDelegate: NSObjectProtocol {
        #[cfg(all(feature = "UIMenu", feature = "UIMenuElement"))]
        /// Called when the interaction begins.
        ///
        ///
        /// Parameter `interaction`: The UIEditMenuInteraction.
        ///
        /// Parameter `configuration`: The UIEditMenuConfiguration object used to present the menu.
        ///
        /// Parameter `suggestedActions`: An array of suggested actions gathered from the UIResponder chain. You may
        /// include these actions in the hierarchy to display them in the resulting menu.
        ///
        ///
        /// Returns: Return a UIMenu describing the desired menu hierarchy. Return
        /// `nil`to present the default system menu.
        #[optional]
        #[unsafe(method(editMenuInteraction:menuForConfiguration:suggestedActions:))]
        #[unsafe(method_family = none)]
        fn editMenuInteraction_menuForConfiguration_suggestedActions(
            &self,
            interaction: &UIEditMenuInteraction,
            configuration: &UIEditMenuConfiguration,
            suggested_actions: &NSArray<UIMenuElement>,
        ) -> Option<Retained<UIMenu>>;

        #[cfg(feature = "objc2-core-foundation")]
        /// Called when the interaction begins, or when
        /// `updateVisibleMenuPosition(animated:)`is called.
        ///
        ///
        /// Parameter `interaction`: The UIEditMenuInteraction.
        ///
        /// Parameter `configuration`: The UIEditMenuConfiguration object used to present the menu.
        ///
        ///
        /// Returns: Return a rectangle relative to the interaction's view. The menu will be displayed around
        /// target rect, space permitting, with the arrow pointing at the edge of the target rectangle
        /// for the specified arrow direction of the configuration. By default, an empty-sized rectangle
        /// centered at
        /// `configuration.sourcePoint`will be used if this method is not implemented. Return
        /// `CGRectNull`to use the default rect.
        #[optional]
        #[unsafe(method(editMenuInteraction:targetRectForConfiguration:))]
        #[unsafe(method_family = none)]
        fn editMenuInteraction_targetRectForConfiguration(
            &self,
            interaction: &UIEditMenuInteraction,
            configuration: &UIEditMenuConfiguration,
        ) -> CGRect;

        /// Called when the interaction is about to present the menu.
        ///
        ///
        /// Parameter `interaction`: The UIEditMenuInteraction.
        ///
        /// Parameter `configuration`: The configuration object of the menu about to be presented by this interaction.
        ///
        /// Parameter `animator`: Appearance animator. Add animations to this object to run them alongside the appearance transition.
        #[optional]
        #[unsafe(method(editMenuInteraction:willPresentMenuForConfiguration:animator:))]
        #[unsafe(method_family = none)]
        fn editMenuInteraction_willPresentMenuForConfiguration_animator(
            &self,
            interaction: &UIEditMenuInteraction,
            configuration: &UIEditMenuConfiguration,
            animator: &ProtocolObject<dyn UIEditMenuInteractionAnimating>,
        );

        /// Called when the interaction is about to dismiss the menu.
        ///
        ///
        /// Parameter `interaction`: The UIEditMenuInteraction.
        ///
        /// Parameter `configuration`: The configuration object of the menu about to be dismissed by this interaction.
        ///
        /// Parameter `animator`: Dismiss animator. Add animations to this object to run them alongside the dismiss transition.
        #[optional]
        #[unsafe(method(editMenuInteraction:willDismissMenuForConfiguration:animator:))]
        #[unsafe(method_family = none)]
        fn editMenuInteraction_willDismissMenuForConfiguration_animator(
            &self,
            interaction: &UIEditMenuInteraction,
            configuration: &UIEditMenuConfiguration,
            animator: &ProtocolObject<dyn UIEditMenuInteractionAnimating>,
        );
    }
);
