//! 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/appkit/nstabviewcontrollertabstyle?language=objc)
// NS_ENUM
#[repr(transparent)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct NSTabViewControllerTabStyle(pub NSInteger);
impl NSTabViewControllerTabStyle {
    /// Uses an NSSegmentedControl to show the UI for the tabs. The control is on the top of the view.
    #[doc(alias = "NSTabViewControllerTabStyleSegmentedControlOnTop")]
    pub const SegmentedControlOnTop: Self = Self(0);
    /// Uses an NSSegmentedControl to show the UI for the tabs. The control is on the bottom of the view.
    #[doc(alias = "NSTabViewControllerTabStyleSegmentedControlOnBottom")]
    pub const SegmentedControlOnBottom: Self = Self(1);
    /// Automatically pushes the tabs into the window's toolbar as toolbar items, if non-nil. This style will cause the TabViewController to set its containing window's toolbar to its own and become that toolbar's delegate. The toolbar items can be customized or supplemented by overriding the relevant NSToolbarDelegate methods.
    #[doc(alias = "NSTabViewControllerTabStyleToolbar")]
    pub const Toolbar: Self = Self(2);
    /// NSTabViewController will not provide any of its own tab control UI. Separate UI, such as a NSSegmentedControl or NSPopupButton, can be easily bound to the TabViewController. Or
    /// `tabView.tabViewType`can be changed for the TabView itself to draw the UI.
    #[doc(alias = "NSTabViewControllerTabStyleUnspecified")]
    pub const Unspecified: Self = Self(-1);
}

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

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

extern_class!(
    /// NSTabViewController is a container view controller that displays a single child view controller at a time from its
    /// `childViewControllers.`It provides standard tab-style UI for user selection of tabs, or allows custom UI to be easily created by providing targets for bindings.
    /// ChildViewControllers’ views are lazily loaded; they are only loaded once their tab is selected and visible.
    /// The NSTabViewController is set as the delegate of its managed NSTabView. Any overrides of NSTabViewDelegate methods must call super. Properties of the TabView such as the tabStyle can be directly manipulated, but calling methods that add and remove tabViewItems or changing the delegate is not allowed.
    /// NSViewController's methods
    /// `-addChildViewController:,``-insertViewController:atIndex:,`and
    /// `-removeChildViewControllerAtIndex:`can all be used as convience methods to add children; default TabViewItems will be appropriately created or destroyed. The default NSTabViewItem created with with +[NSTabViewItem tabViewItemForViewController:].
    ///
    /// See also [Apple's documentation](https://developer.apple.com/documentation/appkit/nstabviewcontroller?language=objc)
    #[unsafe(super(NSViewController, NSResponder, NSObject))]
    #[derive(Debug, PartialEq, Eq, Hash)]
    #[cfg(all(feature = "NSResponder", feature = "NSViewController"))]
    pub struct NSTabViewController;
);

#[cfg(all(feature = "NSResponder", feature = "NSViewController"))]
extern_conformance!(
    unsafe impl NSCoding for NSTabViewController {}
);

#[cfg(all(
    feature = "NSKeyValueBinding",
    feature = "NSResponder",
    feature = "NSViewController"
))]
extern_conformance!(
    unsafe impl NSEditor for NSTabViewController {}
);

#[cfg(all(feature = "NSResponder", feature = "NSViewController"))]
extern_conformance!(
    unsafe impl NSObjectProtocol for NSTabViewController {}
);

#[cfg(all(
    feature = "NSResponder",
    feature = "NSStoryboardSegue",
    feature = "NSViewController"
))]
extern_conformance!(
    unsafe impl NSSeguePerforming for NSTabViewController {}
);

#[cfg(all(
    feature = "NSResponder",
    feature = "NSTabView",
    feature = "NSViewController"
))]
extern_conformance!(
    unsafe impl NSTabViewDelegate for NSTabViewController {}
);

#[cfg(all(
    feature = "NSResponder",
    feature = "NSToolbar",
    feature = "NSViewController"
))]
extern_conformance!(
    unsafe impl NSToolbarDelegate for NSTabViewController {}
);

#[cfg(all(
    feature = "NSResponder",
    feature = "NSUserInterfaceItemIdentification",
    feature = "NSViewController"
))]
extern_conformance!(
    unsafe impl NSUserInterfaceItemIdentification for NSTabViewController {}
);

#[cfg(all(feature = "NSResponder", feature = "NSViewController"))]
impl NSTabViewController {
    extern_methods!(
        /// The style that this NSTabViewController displays its UI as. Defaults to
        /// `NSTabViewControllerTabStyleSegmentedControlOnTop.`
        #[unsafe(method(tabStyle))]
        #[unsafe(method_family = none)]
        pub fn tabStyle(&self) -> NSTabViewControllerTabStyle;

        /// Setter for [`tabStyle`][Self::tabStyle].
        #[unsafe(method(setTabStyle:))]
        #[unsafe(method_family = none)]
        pub fn setTabStyle(&self, tab_style: NSTabViewControllerTabStyle);

        #[cfg(all(feature = "NSTabView", feature = "NSView"))]
        /// Access to the tab view that the controller is controlling. To provide a custom NSTabView, assign the value anytime before
        /// `self.viewLoaded`is
        /// `YES.`Querying the value will create it on-demand, if needed. Check
        /// `self.viewLoaded`before querying the value to avoid prematurely creating the view. Note that the
        /// `-tabView`may not be equal to the
        /// `viewController.view.`Properties such as the tabStyle can be directly manipulated, but calling methods that add and remove tabViewItems or changing the delegate is not allowed. The NSTabViewController will be made the delegate of the NSTabView. Internally, the NSTabView is always used to switch between displayed childViewControllers, regardless of the style displayed.
        #[unsafe(method(tabView))]
        #[unsafe(method_family = none)]
        pub fn tabView(&self) -> Retained<NSTabView>;

        #[cfg(all(feature = "NSTabView", feature = "NSView"))]
        /// Setter for [`tabView`][Self::tabView].
        #[unsafe(method(setTabView:))]
        #[unsafe(method_family = none)]
        pub fn setTabView(&self, tab_view: &NSTabView);

        /// This defines how NSTabViewController transitions from one view to another. Transitions go through [self transitionFromViewController:toViewController:options:completionHandler:]. The default value is
        /// `NSViewControllerTransitionCrossfade|NSViewControllerTransitionAllowUserInteraction.`
        #[unsafe(method(transitionOptions))]
        #[unsafe(method_family = none)]
        pub fn transitionOptions(&self) -> NSViewControllerTransitionOptions;

        /// Setter for [`transitionOptions`][Self::transitionOptions].
        #[unsafe(method(setTransitionOptions:))]
        #[unsafe(method_family = none)]
        pub fn setTransitionOptions(&self, transition_options: NSViewControllerTransitionOptions);

        /// If YES and the receiving NSTabViewController has a nil title,
        /// `-title`will return its selected child ViewController's title. If NO, it will continue to return nil. The default value is
        /// `YES.`
        #[unsafe(method(canPropagateSelectedChildViewControllerTitle))]
        #[unsafe(method_family = none)]
        pub fn canPropagateSelectedChildViewControllerTitle(&self) -> bool;

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

        #[cfg(feature = "NSTabViewItem")]
        /// The array of tab view items that correspond to the current child view controllers. After a child view controller is added to the receiving TabViewController, a NSTabViewItem with the default values will be created for it. Once the child is removed, its corresponding tabViewItem will be removed from the tabViewItems array.
        #[unsafe(method(tabViewItems))]
        #[unsafe(method_family = none)]
        pub fn tabViewItems(&self) -> Retained<NSArray<NSTabViewItem>>;

        #[cfg(feature = "NSTabViewItem")]
        /// Setter for [`tabViewItems`][Self::tabViewItems].
        ///
        /// This is [copied][objc2_foundation::NSCopying::copy] when set.
        #[unsafe(method(setTabViewItems:))]
        #[unsafe(method_family = none)]
        pub fn setTabViewItems(&self, tab_view_items: &NSArray<NSTabViewItem>);

        /// Read and write the current selected TabViewItem that is being shown. This value is KVC compliant and can be the target of a binding. For instance, a NSSegmentedControl's selection can be bound to this value with:
        ///
        /// ```text
        ///  [segmentedControl bind:NSSelectedIndexBinding toObject:tabViewController withKeyPath:@“selectedTabViewItemIndex" options:nil];
        /// ```
        #[unsafe(method(selectedTabViewItemIndex))]
        #[unsafe(method_family = none)]
        pub fn selectedTabViewItemIndex(&self) -> NSInteger;

        /// Setter for [`selectedTabViewItemIndex`][Self::selectedTabViewItemIndex].
        #[unsafe(method(setSelectedTabViewItemIndex:))]
        #[unsafe(method_family = none)]
        pub fn setSelectedTabViewItemIndex(&self, selected_tab_view_item_index: NSInteger);

        #[cfg(feature = "NSTabViewItem")]
        /// Adds a TabViewItem to the end of the TabViewController. The tabViewItem’s viewController’s view will only be loaded once its tab is selected.
        ///
        /// Parameter `tabViewItem`: The TabViewItem to add. It must have a
        /// `viewController`set by the time it is added or an exception will be thrown. An exception will also be thrown if tabViewItem is nil.
        #[unsafe(method(addTabViewItem:))]
        #[unsafe(method_family = none)]
        pub fn addTabViewItem(&self, tab_view_item: &NSTabViewItem);

        #[cfg(feature = "NSTabViewItem")]
        /// Adds a TabViewItem to a given index in the TabViewController. The tabViewItem’s viewController’s view will only be loaded once its tab is selected.
        /// `-selectedTabViewItemIndex`will be adjusted if the insertion index is before it. Subclasses must call through
        /// `-insertTabViewItem:atIndex:`to add a TabViewItem.
        ///
        /// Parameter `tabViewItem`: The TabViewItem to add. It must have a
        /// `viewController`set by the time it is added or an exception will be thrown. An exception will also be thrown if tabViewItem is nil.
        ///
        /// Parameter `index`: The index to add the TabViewItem at. Will throw an exception if
        /// `index`<
        /// 0 or
        /// `index`>
        /// `tabViewItems.count`
        #[unsafe(method(insertTabViewItem:atIndex:))]
        #[unsafe(method_family = none)]
        pub fn insertTabViewItem_atIndex(&self, tab_view_item: &NSTabViewItem, index: NSInteger);

        #[cfg(feature = "NSTabViewItem")]
        /// Removes a TabViewItem from the receiver. If the removed tabViewItem currently selected, the next (or previous, if there is no next) tabViewItem will become selected. If this is the only tabViewItem in the TabViewController, the selectedTabViewItemIndex will become
        /// `-1.`Subclasses must call through
        /// `-removeTabViewItem:`to remove a TabViewItem.
        ///
        /// Parameter `tabViewItem`: The TabViewItem to remove. An exception will be thrown if
        /// `tabViewItem`is not in the NSTabViewController or if it is nil.
        #[unsafe(method(removeTabViewItem:))]
        #[unsafe(method_family = none)]
        pub fn removeTabViewItem(&self, tab_view_item: &NSTabViewItem);

        #[cfg(feature = "NSTabViewItem")]
        /// Convenience method for getting the associated tab view item for a particular childViewController.
        ///
        /// Parameter `viewController`: The ViewController to look up.
        ///
        /// Returns: The corresponding TabViewItem. Returns nil if
        /// `viewController`is not a child of the TabViewController.
        #[unsafe(method(tabViewItemForViewController:))]
        #[unsafe(method_family = none)]
        pub fn tabViewItemForViewController(
            &self,
            view_controller: &NSViewController,
        ) -> Option<Retained<NSTabViewItem>>;

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

        #[cfg(all(feature = "NSTabView", feature = "NSTabViewItem", feature = "NSView"))]
        #[unsafe(method(tabView:willSelectTabViewItem:))]
        #[unsafe(method_family = none)]
        pub fn tabView_willSelectTabViewItem(
            &self,
            tab_view: &NSTabView,
            tab_view_item: Option<&NSTabViewItem>,
        );

        #[cfg(all(feature = "NSTabView", feature = "NSTabViewItem", feature = "NSView"))]
        #[unsafe(method(tabView:didSelectTabViewItem:))]
        #[unsafe(method_family = none)]
        pub fn tabView_didSelectTabViewItem(
            &self,
            tab_view: &NSTabView,
            tab_view_item: Option<&NSTabViewItem>,
        );

        #[cfg(all(feature = "NSTabView", feature = "NSTabViewItem", feature = "NSView"))]
        #[unsafe(method(tabView:shouldSelectTabViewItem:))]
        #[unsafe(method_family = none)]
        pub fn tabView_shouldSelectTabViewItem(
            &self,
            tab_view: &NSTabView,
            tab_view_item: Option<&NSTabViewItem>,
        ) -> bool;

        #[cfg(all(feature = "NSToolbar", feature = "NSToolbarItem"))]
        #[unsafe(method(toolbar:itemForItemIdentifier:willBeInsertedIntoToolbar:))]
        #[unsafe(method_family = none)]
        pub fn toolbar_itemForItemIdentifier_willBeInsertedIntoToolbar(
            &self,
            toolbar: &NSToolbar,
            item_identifier: &NSToolbarItemIdentifier,
            flag: bool,
        ) -> Option<Retained<NSToolbarItem>>;

        #[cfg(feature = "NSToolbar")]
        #[unsafe(method(toolbarDefaultItemIdentifiers:))]
        #[unsafe(method_family = none)]
        pub fn toolbarDefaultItemIdentifiers(
            &self,
            toolbar: &NSToolbar,
        ) -> Retained<NSArray<NSToolbarItemIdentifier>>;

        #[cfg(feature = "NSToolbar")]
        #[unsafe(method(toolbarAllowedItemIdentifiers:))]
        #[unsafe(method_family = none)]
        pub fn toolbarAllowedItemIdentifiers(
            &self,
            toolbar: &NSToolbar,
        ) -> Retained<NSArray<NSToolbarItemIdentifier>>;

        #[cfg(feature = "NSToolbar")]
        #[unsafe(method(toolbarSelectableItemIdentifiers:))]
        #[unsafe(method_family = none)]
        pub fn toolbarSelectableItemIdentifiers(
            &self,
            toolbar: &NSToolbar,
        ) -> Retained<NSArray<NSToolbarItemIdentifier>>;
    );
}

/// Methods declared on superclass `NSViewController`.
#[cfg(all(feature = "NSResponder", feature = "NSViewController"))]
impl NSTabViewController {
    extern_methods!(
        #[cfg(feature = "NSNib")]
        #[unsafe(method(initWithNibName:bundle:))]
        #[unsafe(method_family = init)]
        pub fn initWithNibName_bundle(
            this: Allocated<Self>,
            nib_name_or_nil: Option<&NSNibName>,
            nib_bundle_or_nil: Option<&NSBundle>,
        ) -> Retained<Self>;

        /// # 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>>;
    );
}

/// Methods declared on superclass `NSResponder`.
#[cfg(all(feature = "NSResponder", feature = "NSViewController"))]
impl NSTabViewController {
    extern_methods!(
        #[unsafe(method(init))]
        #[unsafe(method_family = init)]
        pub fn init(this: Allocated<Self>) -> Retained<Self>;
    );
}

/// Methods declared on superclass `NSObject`.
#[cfg(all(feature = "NSResponder", feature = "NSViewController"))]
impl NSTabViewController {
    extern_methods!(
        #[unsafe(method(new))]
        #[unsafe(method_family = new)]
        pub fn new(mtm: MainThreadMarker) -> Retained<Self>;
    );
}
