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

/// UINavigationController manages a stack of view controllers and a navigation bar.
/// It performs horizontal view transitions for pushed and popped views while keeping the navigation bar in sync.
///
/// Most clients will not need to subclass UINavigationController.
///
/// If a navigation controller is nested in a tab bar controller, it uses the title and toolbar attributes of the bottom view controller on the stack.
///
/// UINavigationController is rotatable if its top view controller is rotatable.
/// Navigation between controllers with non-uniform rotatability is currently not supported.
///
/// See also [Apple's documentation](https://developer.apple.com/documentation/uikit/uinavigationcontrolleroperation?language=objc)
// NS_ENUM
#[repr(transparent)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct UINavigationControllerOperation(pub NSInteger);
impl UINavigationControllerOperation {
    #[doc(alias = "UINavigationControllerOperationNone")]
    pub const None: Self = Self(0);
    #[doc(alias = "UINavigationControllerOperationPush")]
    pub const Push: Self = Self(1);
    #[doc(alias = "UINavigationControllerOperationPop")]
    pub const Pop: Self = Self(2);
}

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

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

extern "C" {
    /// [Apple's documentation](https://developer.apple.com/documentation/uikit/uinavigationcontrollerhideshowbarduration?language=objc)
    #[cfg(feature = "objc2-core-foundation")]
    pub static UINavigationControllerHideShowBarDuration: CGFloat;
}

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

#[cfg(all(feature = "UIResponder", feature = "UIViewController"))]
extern_conformance!(
    unsafe impl NSCoding for UINavigationController {}
);

#[cfg(all(feature = "UIResponder", feature = "UIViewController"))]
extern_conformance!(
    unsafe impl NSObjectProtocol for UINavigationController {}
);

#[cfg(all(
    feature = "UIAppearance",
    feature = "UIResponder",
    feature = "UIViewController"
))]
extern_conformance!(
    unsafe impl UIAppearanceContainer for UINavigationController {}
);

#[cfg(all(feature = "UIResponder", feature = "UIViewController"))]
extern_conformance!(
    unsafe impl UIContentContainer for UINavigationController {}
);

#[cfg(all(
    feature = "UIFocus",
    feature = "UIResponder",
    feature = "UIViewController"
))]
extern_conformance!(
    unsafe impl UIFocusEnvironment for UINavigationController {}
);

#[cfg(all(feature = "UIResponder", feature = "UIViewController"))]
extern_conformance!(
    unsafe impl UIResponderStandardEditActions for UINavigationController {}
);

#[cfg(all(
    feature = "UIResponder",
    feature = "UITraitCollection",
    feature = "UIViewController"
))]
extern_conformance!(
    unsafe impl UITraitEnvironment for UINavigationController {}
);

#[cfg(all(feature = "UIResponder", feature = "UIViewController"))]
impl UINavigationController {
    extern_methods!(
        /// # Safety
        ///
        /// - `navigation_bar_class` probably has further requirements.
        /// - `toolbar_class` probably has further requirements.
        #[unsafe(method(initWithNavigationBarClass:toolbarClass:))]
        #[unsafe(method_family = init)]
        pub unsafe fn initWithNavigationBarClass_toolbarClass(
            this: Allocated<Self>,
            navigation_bar_class: Option<&AnyClass>,
            toolbar_class: Option<&AnyClass>,
        ) -> Retained<Self>;

        #[unsafe(method(initWithRootViewController:))]
        #[unsafe(method_family = init)]
        pub fn initWithRootViewController(
            this: Allocated<Self>,
            root_view_controller: &UIViewController,
        ) -> Retained<Self>;

        #[unsafe(method(initWithNibName:bundle:))]
        #[unsafe(method_family = init)]
        pub fn initWithNibName_bundle(
            this: Allocated<Self>,
            nib_name_or_nil: Option<&NSString>,
            nib_bundle_or_nil: Option<&NSBundle>,
        ) -> Retained<Self>;

        /// # Safety
        ///
        /// `a_decoder` possibly has further requirements.
        #[unsafe(method(initWithCoder:))]
        #[unsafe(method_family = init)]
        pub unsafe fn initWithCoder(
            this: Allocated<Self>,
            a_decoder: &NSCoder,
        ) -> Option<Retained<Self>>;

        #[unsafe(method(pushViewController:animated:))]
        #[unsafe(method_family = none)]
        pub fn pushViewController_animated(
            &self,
            view_controller: &UIViewController,
            animated: bool,
        );

        #[unsafe(method(popViewControllerAnimated:))]
        #[unsafe(method_family = none)]
        pub fn popViewControllerAnimated(
            &self,
            animated: bool,
        ) -> Option<Retained<UIViewController>>;

        #[unsafe(method(popToViewController:animated:))]
        #[unsafe(method_family = none)]
        pub fn popToViewController_animated(
            &self,
            view_controller: &UIViewController,
            animated: bool,
        ) -> Option<Retained<NSArray<UIViewController>>>;

        #[unsafe(method(popToRootViewControllerAnimated:))]
        #[unsafe(method_family = none)]
        pub fn popToRootViewControllerAnimated(
            &self,
            animated: bool,
        ) -> Option<Retained<NSArray<UIViewController>>>;

        #[unsafe(method(topViewController))]
        #[unsafe(method_family = none)]
        pub fn topViewController(&self) -> Option<Retained<UIViewController>>;

        #[unsafe(method(visibleViewController))]
        #[unsafe(method_family = none)]
        pub fn visibleViewController(&self) -> Option<Retained<UIViewController>>;

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

        /// Setter for [`viewControllers`][Self::viewControllers].
        ///
        /// This is [copied][objc2_foundation::NSCopying::copy] when set.
        #[unsafe(method(setViewControllers:))]
        #[unsafe(method_family = none)]
        pub fn setViewControllers(&self, view_controllers: &NSArray<UIViewController>);

        #[unsafe(method(setViewControllers:animated:))]
        #[unsafe(method_family = none)]
        pub fn setViewControllers_animated(
            &self,
            view_controllers: &NSArray<UIViewController>,
            animated: bool,
        );

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

        /// Setter for [`isNavigationBarHidden`][Self::isNavigationBarHidden].
        #[unsafe(method(setNavigationBarHidden:))]
        #[unsafe(method_family = none)]
        pub fn setNavigationBarHidden(&self, navigation_bar_hidden: bool);

        #[unsafe(method(setNavigationBarHidden:animated:))]
        #[unsafe(method_family = none)]
        pub fn setNavigationBarHidden_animated(&self, hidden: bool, animated: bool);

        #[cfg(all(feature = "UINavigationBar", feature = "UIView"))]
        #[unsafe(method(navigationBar))]
        #[unsafe(method_family = none)]
        pub fn navigationBar(&self) -> Retained<UINavigationBar>;

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

        /// Setter for [`isToolbarHidden`][Self::isToolbarHidden].
        #[unsafe(method(setToolbarHidden:))]
        #[unsafe(method_family = none)]
        pub fn setToolbarHidden(&self, toolbar_hidden: bool);

        #[unsafe(method(setToolbarHidden:animated:))]
        #[unsafe(method_family = none)]
        pub fn setToolbarHidden_animated(&self, hidden: bool, animated: bool);

        #[cfg(all(feature = "UIToolbar", feature = "UIView"))]
        #[unsafe(method(toolbar))]
        #[unsafe(method_family = none)]
        pub fn toolbar(&self) -> Option<Retained<UIToolbar>>;

        #[unsafe(method(delegate))]
        #[unsafe(method_family = none)]
        pub fn delegate(
            &self,
        ) -> Option<Retained<ProtocolObject<dyn UINavigationControllerDelegate>>>;

        /// Setter for [`delegate`][Self::delegate].
        ///
        /// This is a [weak property][objc2::topics::weak_property].
        #[unsafe(method(setDelegate:))]
        #[unsafe(method_family = none)]
        pub unsafe fn setDelegate(
            &self,
            delegate: Option<&ProtocolObject<dyn UINavigationControllerDelegate>>,
        );

        #[cfg(feature = "UIGestureRecognizer")]
        /// The interactive pop gesture recognizes on the leading screen edge and initiates an interactive pop.
        /// This property should only be used to set up failure requirements with it.
        #[unsafe(method(interactivePopGestureRecognizer))]
        #[unsafe(method_family = none)]
        pub fn interactivePopGestureRecognizer(&self) -> Option<Retained<UIGestureRecognizer>>;

        #[cfg(feature = "UIGestureRecognizer")]
        /// The interactive content pop gesture recognizes on the entire content area of the navigation controller
        /// in cases that are not covered by the interactive pop gesture recognizer and initiates an interactive pop.
        /// This property should only be used to set up failure requirements with it.
        #[unsafe(method(interactiveContentPopGestureRecognizer))]
        #[unsafe(method_family = none)]
        pub fn interactiveContentPopGestureRecognizer(
            &self,
        ) -> Option<Retained<UIGestureRecognizer>>;

        /// # Safety
        ///
        /// `sender` should be of the correct type.
        #[unsafe(method(showViewController:sender:))]
        #[unsafe(method_family = none)]
        pub unsafe fn showViewController_sender(
            &self,
            vc: &UIViewController,
            sender: Option<&AnyObject>,
        );

        /// When the keyboard appears, the navigation controller's navigationBar toolbar will be hidden. The bars will remain hidden when the keyboard dismisses, but a tap in the content area will show them.
        #[unsafe(method(hidesBarsWhenKeyboardAppears))]
        #[unsafe(method_family = none)]
        pub fn hidesBarsWhenKeyboardAppears(&self) -> bool;

        /// Setter for [`hidesBarsWhenKeyboardAppears`][Self::hidesBarsWhenKeyboardAppears].
        #[unsafe(method(setHidesBarsWhenKeyboardAppears:))]
        #[unsafe(method_family = none)]
        pub fn setHidesBarsWhenKeyboardAppears(&self, hides_bars_when_keyboard_appears: bool);

        /// When the user swipes, the navigation controller's navigationBar
        /// &
        /// toolbar will be hidden (on a swipe up) or shown (on a swipe down). The toolbar only participates if it has items.
        #[unsafe(method(hidesBarsOnSwipe))]
        #[unsafe(method_family = none)]
        pub fn hidesBarsOnSwipe(&self) -> bool;

        /// Setter for [`hidesBarsOnSwipe`][Self::hidesBarsOnSwipe].
        #[unsafe(method(setHidesBarsOnSwipe:))]
        #[unsafe(method_family = none)]
        pub fn setHidesBarsOnSwipe(&self, hides_bars_on_swipe: bool);

        #[cfg(all(feature = "UIGestureRecognizer", feature = "UIPanGestureRecognizer"))]
        /// The gesture recognizer that triggers if the bars will hide or show due to a swipe. Do not change the delegate or attempt to replace this gesture by overriding this method.
        #[unsafe(method(barHideOnSwipeGestureRecognizer))]
        #[unsafe(method_family = none)]
        pub fn barHideOnSwipeGestureRecognizer(&self) -> Retained<UIPanGestureRecognizer>;

        /// When the UINavigationController's vertical size class is compact, hide the UINavigationBar and UIToolbar. Unhandled taps in the regions that would normally be occupied by these bars will reveal the bars.
        #[unsafe(method(hidesBarsWhenVerticallyCompact))]
        #[unsafe(method_family = none)]
        pub fn hidesBarsWhenVerticallyCompact(&self) -> bool;

        /// Setter for [`hidesBarsWhenVerticallyCompact`][Self::hidesBarsWhenVerticallyCompact].
        #[unsafe(method(setHidesBarsWhenVerticallyCompact:))]
        #[unsafe(method_family = none)]
        pub fn setHidesBarsWhenVerticallyCompact(&self, hides_bars_when_vertically_compact: bool);

        /// When the user taps, the navigation controller's navigationBar
        /// &
        /// toolbar will be hidden or shown, depending on the hidden state of the navigationBar. The toolbar will only be shown if it has items to display.
        #[unsafe(method(hidesBarsOnTap))]
        #[unsafe(method_family = none)]
        pub fn hidesBarsOnTap(&self) -> bool;

        /// Setter for [`hidesBarsOnTap`][Self::hidesBarsOnTap].
        #[unsafe(method(setHidesBarsOnTap:))]
        #[unsafe(method_family = none)]
        pub fn setHidesBarsOnTap(&self, hides_bars_on_tap: bool);

        #[cfg(all(feature = "UIGestureRecognizer", feature = "UITapGestureRecognizer"))]
        /// The gesture recognizer used to recognize if the bars will hide or show due to a tap in content. Do not change the delegate or attempt to replace this gesture by overriding this method.
        ///
        /// # Safety
        ///
        /// This is not retained internally, you must ensure the object is still alive.
        #[unsafe(method(barHideOnTapGestureRecognizer))]
        #[unsafe(method_family = none)]
        pub unsafe fn barHideOnTapGestureRecognizer(&self) -> Retained<UITapGestureRecognizer>;
    );
}

/// Methods declared on superclass `NSObject`.
#[cfg(all(feature = "UIResponder", feature = "UIViewController"))]
impl UINavigationController {
    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(mtm: MainThreadMarker) -> Retained<Self>;
    );
}

extern_protocol!(
    /// [Apple's documentation](https://developer.apple.com/documentation/uikit/uinavigationcontrollerdelegate?language=objc)
    pub unsafe trait UINavigationControllerDelegate:
        NSObjectProtocol + MainThreadOnly
    {
        #[cfg(all(feature = "UIResponder", feature = "UIViewController"))]
        #[optional]
        #[unsafe(method(navigationController:willShowViewController:animated:))]
        #[unsafe(method_family = none)]
        fn navigationController_willShowViewController_animated(
            &self,
            navigation_controller: &UINavigationController,
            view_controller: &UIViewController,
            animated: bool,
        );

        #[cfg(all(feature = "UIResponder", feature = "UIViewController"))]
        #[optional]
        #[unsafe(method(navigationController:didShowViewController:animated:))]
        #[unsafe(method_family = none)]
        fn navigationController_didShowViewController_animated(
            &self,
            navigation_controller: &UINavigationController,
            view_controller: &UIViewController,
            animated: bool,
        );

        #[cfg(all(
            feature = "UIOrientation",
            feature = "UIResponder",
            feature = "UIViewController"
        ))]
        #[optional]
        #[unsafe(method(navigationControllerSupportedInterfaceOrientations:))]
        #[unsafe(method_family = none)]
        fn navigationControllerSupportedInterfaceOrientations(
            &self,
            navigation_controller: &UINavigationController,
        ) -> UIInterfaceOrientationMask;

        #[cfg(all(
            feature = "UIOrientation",
            feature = "UIResponder",
            feature = "UIViewController"
        ))]
        #[optional]
        #[unsafe(method(navigationControllerPreferredInterfaceOrientationForPresentation:))]
        #[unsafe(method_family = none)]
        fn navigationControllerPreferredInterfaceOrientationForPresentation(
            &self,
            navigation_controller: &UINavigationController,
        ) -> UIInterfaceOrientation;

        #[cfg(all(
            feature = "UIResponder",
            feature = "UIViewController",
            feature = "UIViewControllerTransitioning"
        ))]
        #[optional]
        #[unsafe(method(navigationController:interactionControllerForAnimationController:))]
        #[unsafe(method_family = none)]
        fn navigationController_interactionControllerForAnimationController(
            &self,
            navigation_controller: &UINavigationController,
            animation_controller: &ProtocolObject<dyn UIViewControllerAnimatedTransitioning>,
        ) -> Option<Retained<ProtocolObject<dyn UIViewControllerInteractiveTransitioning>>>;

        #[cfg(all(
            feature = "UIResponder",
            feature = "UIViewController",
            feature = "UIViewControllerTransitioning"
        ))]
        #[optional]
        #[unsafe(method(navigationController:animationControllerForOperation:fromViewController:toViewController:))]
        #[unsafe(method_family = none)]
        fn navigationController_animationControllerForOperation_fromViewController_toViewController(
            &self,
            navigation_controller: &UINavigationController,
            operation: UINavigationControllerOperation,
            from_vc: &UIViewController,
            to_vc: &UIViewController,
        ) -> Option<Retained<ProtocolObject<dyn UIViewControllerAnimatedTransitioning>>>;
    }
);

/// UINavigationControllerItem.
#[cfg(all(feature = "UIResponder", feature = "UIViewController"))]
impl UIViewController {
    extern_methods!(
        #[cfg(feature = "UINavigationItem")]
        #[unsafe(method(navigationItem))]
        #[unsafe(method_family = none)]
        pub fn navigationItem(&self) -> Retained<UINavigationItem>;

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

        /// Setter for [`hidesBottomBarWhenPushed`][Self::hidesBottomBarWhenPushed].
        #[unsafe(method(setHidesBottomBarWhenPushed:))]
        #[unsafe(method_family = none)]
        pub fn setHidesBottomBarWhenPushed(&self, hides_bottom_bar_when_pushed: bool);

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

/// UINavigationControllerContextualToolbarItems.
#[cfg(all(feature = "UIResponder", feature = "UIViewController"))]
impl UIViewController {
    extern_methods!(
        #[cfg(all(feature = "UIBarButtonItem", feature = "UIBarItem"))]
        #[unsafe(method(toolbarItems))]
        #[unsafe(method_family = none)]
        pub fn toolbarItems(&self) -> Option<Retained<NSArray<UIBarButtonItem>>>;

        #[cfg(all(feature = "UIBarButtonItem", feature = "UIBarItem"))]
        /// Setter for [`toolbarItems`][Self::toolbarItems].
        #[unsafe(method(setToolbarItems:))]
        #[unsafe(method_family = none)]
        pub fn setToolbarItems(&self, toolbar_items: Option<&NSArray<UIBarButtonItem>>);

        #[cfg(all(feature = "UIBarButtonItem", feature = "UIBarItem"))]
        #[unsafe(method(setToolbarItems:animated:))]
        #[unsafe(method_family = none)]
        pub fn setToolbarItems_animated(
            &self,
            toolbar_items: Option<&NSArray<UIBarButtonItem>>,
            animated: bool,
        );
    );
}
