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

extern "C" {
    /// [Apple's documentation](https://developer.apple.com/documentation/foundation/nsdefaultrunloopmode?language=objc)
    #[cfg(all(feature = "NSObjCRuntime", feature = "NSString"))]
    pub static NSDefaultRunLoopMode: &'static NSRunLoopMode;
}

extern "C" {
    /// [Apple's documentation](https://developer.apple.com/documentation/foundation/nsrunloopcommonmodes?language=objc)
    #[cfg(all(feature = "NSObjCRuntime", feature = "NSString"))]
    pub static NSRunLoopCommonModes: &'static NSRunLoopMode;
}

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

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

impl NSRunLoop {
    extern_methods!(
        #[unsafe(method(currentRunLoop))]
        #[unsafe(method_family = none)]
        pub fn currentRunLoop() -> Retained<NSRunLoop>;

        #[unsafe(method(mainRunLoop))]
        #[unsafe(method_family = none)]
        pub fn mainRunLoop() -> Retained<NSRunLoop>;

        #[cfg(all(feature = "NSObjCRuntime", feature = "NSString"))]
        #[unsafe(method(currentMode))]
        #[unsafe(method_family = none)]
        pub fn currentMode(&self) -> Option<Retained<NSRunLoopMode>>;

        #[cfg(feature = "objc2-core-foundation")]
        #[unsafe(method(getCFRunLoop))]
        #[unsafe(method_family = none)]
        pub fn getCFRunLoop(&self) -> Retained<CFRunLoop>;

        #[cfg(all(feature = "NSObjCRuntime", feature = "NSString", feature = "NSTimer"))]
        #[unsafe(method(addTimer:forMode:))]
        #[unsafe(method_family = none)]
        pub unsafe fn addTimer_forMode(&self, timer: &NSTimer, mode: &NSRunLoopMode);

        #[cfg(all(feature = "NSObjCRuntime", feature = "NSPort", feature = "NSString"))]
        #[unsafe(method(addPort:forMode:))]
        #[unsafe(method_family = none)]
        pub unsafe fn addPort_forMode(&self, a_port: &NSPort, mode: &NSRunLoopMode);

        #[cfg(all(feature = "NSObjCRuntime", feature = "NSPort", feature = "NSString"))]
        #[unsafe(method(removePort:forMode:))]
        #[unsafe(method_family = none)]
        pub unsafe fn removePort_forMode(&self, a_port: &NSPort, mode: &NSRunLoopMode);

        #[cfg(all(feature = "NSDate", feature = "NSObjCRuntime", feature = "NSString"))]
        #[unsafe(method(limitDateForMode:))]
        #[unsafe(method_family = none)]
        pub fn limitDateForMode(&self, mode: &NSRunLoopMode) -> Option<Retained<NSDate>>;

        #[cfg(all(feature = "NSDate", feature = "NSObjCRuntime", feature = "NSString"))]
        #[unsafe(method(acceptInputForMode:beforeDate:))]
        #[unsafe(method_family = none)]
        pub fn acceptInputForMode_beforeDate(&self, mode: &NSRunLoopMode, limit_date: &NSDate);
    );
}

/// Methods declared on superclass `NSObject`.
impl NSRunLoop {
    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 DefaultRetained for NSRunLoop {
    #[inline]
    fn default_retained() -> Retained<Self> {
        Self::new()
    }
}

/// NSRunLoopConveniences.
impl NSRunLoop {
    extern_methods!(
        #[unsafe(method(run))]
        #[unsafe(method_family = none)]
        pub fn run(&self);

        #[cfg(feature = "NSDate")]
        #[unsafe(method(runUntilDate:))]
        #[unsafe(method_family = none)]
        pub fn runUntilDate(&self, limit_date: &NSDate);

        #[cfg(all(feature = "NSDate", feature = "NSObjCRuntime", feature = "NSString"))]
        #[unsafe(method(runMode:beforeDate:))]
        #[unsafe(method_family = none)]
        pub fn runMode_beforeDate(&self, mode: &NSRunLoopMode, limit_date: &NSDate) -> bool;

        #[deprecated = "Not supported"]
        #[unsafe(method(configureAsServer))]
        #[unsafe(method_family = none)]
        pub fn configureAsServer(&self);

        #[cfg(all(
            feature = "NSArray",
            feature = "NSObjCRuntime",
            feature = "NSString",
            feature = "block2"
        ))]
        /// Schedules the execution of a block on the target run loop in given modes.
        /// - parameter: modes   An array of input modes for which the block may be executed.
        /// - parameter: block   The block to execute
        ///
        /// # Safety
        ///
        /// `block` block must be sendable.
        #[unsafe(method(performInModes:block:))]
        #[unsafe(method_family = none)]
        pub unsafe fn performInModes_block(
            &self,
            modes: &NSArray<NSRunLoopMode>,
            block: &block2::DynBlock<dyn Fn()>,
        );

        #[cfg(feature = "block2")]
        /// Schedules the execution of a block on the target run loop.
        /// - parameter: block   The block to execute
        ///
        /// # Safety
        ///
        /// `block` block must be sendable.
        #[unsafe(method(performBlock:))]
        #[unsafe(method_family = none)]
        pub unsafe fn performBlock(&self, block: &block2::DynBlock<dyn Fn()>);
    );
}

mod private_NSObjectNSDelayedPerforming {
    pub trait Sealed {}
}

/// Category "NSDelayedPerforming" on [`NSObject`].
///
/// **************     Delayed perform     *****************
#[doc(alias = "NSDelayedPerforming")]
pub unsafe trait NSObjectNSDelayedPerforming:
    ClassType + Sized + private_NSObjectNSDelayedPerforming::Sealed
{
    extern_methods!(
        #[cfg(all(
            feature = "NSArray",
            feature = "NSDate",
            feature = "NSObjCRuntime",
            feature = "NSString"
        ))]
        /// # Safety
        ///
        /// - `a_selector` must be a valid selector.
        /// - `an_argument` should be of the correct type.
        #[unsafe(method(performSelector:withObject:afterDelay:inModes:))]
        #[unsafe(method_family = none)]
        unsafe fn performSelector_withObject_afterDelay_inModes(
            &self,
            a_selector: Sel,
            an_argument: Option<&AnyObject>,
            delay: NSTimeInterval,
            modes: &NSArray<NSRunLoopMode>,
        );

        #[cfg(feature = "NSDate")]
        /// # Safety
        ///
        /// - `a_selector` must be a valid selector.
        /// - `an_argument` should be of the correct type.
        #[unsafe(method(performSelector:withObject:afterDelay:))]
        #[unsafe(method_family = none)]
        unsafe fn performSelector_withObject_afterDelay(
            &self,
            a_selector: Sel,
            an_argument: Option<&AnyObject>,
            delay: NSTimeInterval,
        );

        /// # Safety
        ///
        /// - `a_target` should be of the correct type.
        /// - `a_selector` must be a valid selector.
        /// - `an_argument` should be of the correct type.
        #[unsafe(method(cancelPreviousPerformRequestsWithTarget:selector:object:))]
        #[unsafe(method_family = none)]
        unsafe fn cancelPreviousPerformRequestsWithTarget_selector_object(
            a_target: &AnyObject,
            a_selector: Sel,
            an_argument: Option<&AnyObject>,
        );

        /// # Safety
        ///
        /// `a_target` should be of the correct type.
        #[unsafe(method(cancelPreviousPerformRequestsWithTarget:))]
        #[unsafe(method_family = none)]
        unsafe fn cancelPreviousPerformRequestsWithTarget(a_target: &AnyObject);
    );
}

impl private_NSObjectNSDelayedPerforming::Sealed for NSObject {}
unsafe impl NSObjectNSDelayedPerforming for NSObject {}

/// NSOrderedPerform.
impl NSRunLoop {
    extern_methods!(
        #[cfg(all(feature = "NSArray", feature = "NSObjCRuntime", feature = "NSString"))]
        /// # Safety
        ///
        /// - `a_selector` must be a valid selector.
        /// - `target` should be of the correct type.
        /// - `arg` should be of the correct type.
        #[unsafe(method(performSelector:target:argument:order:modes:))]
        #[unsafe(method_family = none)]
        pub unsafe fn performSelector_target_argument_order_modes(
            &self,
            a_selector: Sel,
            target: &AnyObject,
            arg: Option<&AnyObject>,
            order: NSUInteger,
            modes: &NSArray<NSRunLoopMode>,
        );

        /// # Safety
        ///
        /// - `a_selector` must be a valid selector.
        /// - `target` should be of the correct type.
        /// - `arg` should be of the correct type.
        #[unsafe(method(cancelPerformSelector:target:argument:))]
        #[unsafe(method_family = none)]
        pub unsafe fn cancelPerformSelector_target_argument(
            &self,
            a_selector: Sel,
            target: &AnyObject,
            arg: Option<&AnyObject>,
        );

        /// # Safety
        ///
        /// `target` should be of the correct type.
        #[unsafe(method(cancelPerformSelectorsWithTarget:))]
        #[unsafe(method_family = none)]
        pub unsafe fn cancelPerformSelectorsWithTarget(&self, target: &AnyObject);
    );
}
