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

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

extern_conformance!(
    unsafe impl NSCopying for UIViewPropertyAnimator {}
);

unsafe impl CopyingHelper for UIViewPropertyAnimator {
    type Result = Self;
}

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

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

#[cfg(feature = "UIViewAnimating")]
extern_conformance!(
    unsafe impl UIViewImplicitlyAnimating for UIViewPropertyAnimator {}
);

impl UIViewPropertyAnimator {
    extern_methods!(
        #[cfg(feature = "UITimingCurveProvider")]
        #[unsafe(method(timingParameters))]
        #[unsafe(method_family = none)]
        pub fn timingParameters(
            &self,
        ) -> Option<Retained<ProtocolObject<dyn UITimingCurveProvider>>>;

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

        /// Defaults to 0. This property is set when calling -[UIView startAnimationAfterDelay:].
        #[unsafe(method(delay))]
        #[unsafe(method_family = none)]
        pub fn delay(&self) -> NSTimeInterval;

        /// Defaults to YES. Raises if set on an active animator.
        #[unsafe(method(isUserInteractionEnabled))]
        #[unsafe(method_family = none)]
        pub fn isUserInteractionEnabled(&self) -> bool;

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

        /// Defaults to NO. Set if you need to manage the the hit-testing of animating view hierarchies
        #[unsafe(method(isManualHitTestingEnabled))]
        #[unsafe(method_family = none)]
        pub fn isManualHitTestingEnabled(&self) -> bool;

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

        /// Defaults to YES. Raises if set on an active animator.
        #[unsafe(method(isInterruptible))]
        #[unsafe(method_family = none)]
        pub fn isInterruptible(&self) -> bool;

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

        /// Defaults to YES. Provides the ability for an animator to pause and scrub either linearly or using the animator’s current timing.
        #[unsafe(method(scrubsLinearly))]
        #[unsafe(method_family = none)]
        pub fn scrubsLinearly(&self) -> bool;

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

        /// Defaults to NO. Provides the ability for an animator to pause on completion instead of transitioning to the .inactive state.
        #[unsafe(method(pausesOnCompletion))]
        #[unsafe(method_family = none)]
        pub fn pausesOnCompletion(&self) -> bool;

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

        /// Flush all pending updates (including traits, properties, and layout) whenever the animation context changes.
        /// This includes flushing updates:
        /// - Before entering an animation scope, for invalidations that happened previously without animation.
        /// - Before entering a nested animation scope, for invalidations that happened in the outer animation scope.
        /// - Before exiting any animation scope, for invalidations that happened in that animation scope.
        /// - Before disabling animations, for invalidations that happened in the animation scope with animations enabled.
        /// - Before re-enabling animations, for invalidations that happened in the scope with animations disabled.
        /// This behavior implicitly applies to any nested animation scopes, even if they don't explicitly specify this.
        #[unsafe(method(flushUpdates))]
        #[unsafe(method_family = none)]
        pub fn flushUpdates(&self) -> bool;

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

        #[cfg(feature = "UITimingCurveProvider")]
        #[unsafe(method(initWithDuration:timingParameters:))]
        #[unsafe(method_family = init)]
        pub fn initWithDuration_timingParameters(
            this: Allocated<Self>,
            duration: NSTimeInterval,
            parameters: &ProtocolObject<dyn UITimingCurveProvider>,
        ) -> Retained<Self>;

        #[cfg(all(feature = "UIView", feature = "block2"))]
        /// All convenience initializers return an animator which is not running.
        #[unsafe(method(initWithDuration:curve:animations:))]
        #[unsafe(method_family = init)]
        pub fn initWithDuration_curve_animations(
            this: Allocated<Self>,
            duration: NSTimeInterval,
            curve: UIViewAnimationCurve,
            animations: Option<&block2::DynBlock<dyn Fn()>>,
        ) -> Retained<Self>;

        #[cfg(all(feature = "block2", feature = "objc2-core-foundation"))]
        #[unsafe(method(initWithDuration:controlPoint1:controlPoint2:animations:))]
        #[unsafe(method_family = init)]
        pub fn initWithDuration_controlPoint1_controlPoint2_animations(
            this: Allocated<Self>,
            duration: NSTimeInterval,
            point1: CGPoint,
            point2: CGPoint,
            animations: Option<&block2::DynBlock<dyn Fn()>>,
        ) -> Retained<Self>;

        #[cfg(all(feature = "block2", feature = "objc2-core-foundation"))]
        #[unsafe(method(initWithDuration:dampingRatio:animations:))]
        #[unsafe(method_family = init)]
        pub fn initWithDuration_dampingRatio_animations(
            this: Allocated<Self>,
            duration: NSTimeInterval,
            ratio: CGFloat,
            animations: Option<&block2::DynBlock<dyn Fn()>>,
        ) -> Retained<Self>;

        #[cfg(all(feature = "UIView", feature = "UIViewAnimating", feature = "block2"))]
        /// This method provides compatibility with the old style [UIView
        /// animationWithDuration:...]  method. It is also useful for controlling
        /// how animations options are inherited.
        ///
        /// Creates a UIViewPropertyAnimator, sets the duration, options, etc. And starts the
        /// animation with the associated animation and completion blocks. The animator
        /// returned is interruptible only if it is not called from within the execution
        /// block of another animation (animator or legacy). Note that if it is called
        /// within the execution block of another animation it will inherit the duration
        /// and other characteristics of that animation UNLESS the appropriate override
        /// options have been specified. Also note that if is called within the execution
        /// block of another propertyAnimator that is interruptible, the implicit
        /// animations defined by this call will be tracked by the outer
        /// propertyAnimator.
        #[unsafe(method(runningPropertyAnimatorWithDuration:delay:options:animations:completion:))]
        #[unsafe(method_family = none)]
        pub fn runningPropertyAnimatorWithDuration_delay_options_animations_completion(
            duration: NSTimeInterval,
            delay: NSTimeInterval,
            options: UIViewAnimationOptions,
            animations: &block2::DynBlock<dyn Fn()>,
            completion: Option<&block2::DynBlock<dyn Fn(UIViewAnimatingPosition)>>,
            mtm: MainThreadMarker,
        ) -> Retained<Self>;

        #[cfg(all(feature = "block2", feature = "objc2-core-foundation"))]
        /// Animatable view properties that are set by the animation block will be
        /// animated to their new values. The animations will commence at delayFactor *
        /// animator.duration seconds into the animation. The duration of the animation
        /// will be (1 - delayFactor) * animator.duration seconds.
        #[unsafe(method(addAnimations:delayFactor:))]
        #[unsafe(method_family = none)]
        pub fn addAnimations_delayFactor(
            &self,
            animation: &block2::DynBlock<dyn Fn()>,
            delay_factor: CGFloat,
        );

        #[cfg(feature = "block2")]
        /// Animatable view properties that are set by the animation block will be
        /// animated to their new values. Starting an animator that does not contain any animation blocks
        /// will start the animator in a transient paused state. While in this state, submitting an animation
        /// block will automatically start animating any animatable view properties set therein. When the
        /// animator is stopped, either naturally completing or explicitly, any animation blocks and completion
        /// handlers are invalidated. Immediately calling `startAnimation` again on the animator, since there
        /// are no animation blocks, will start the animator in a transient paused state.
        #[unsafe(method(addAnimations:))]
        #[unsafe(method_family = none)]
        pub fn addAnimations(&self, animation: &block2::DynBlock<dyn Fn()>);

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

        #[cfg(all(feature = "UITimingCurveProvider", feature = "objc2-core-foundation"))]
        /// Provides a means to continue an animation in either the forward or reversed
        /// directions with new timing parameters and duration.  The durationFactor is in
        /// terms of a unit duration defined by the originally specified duration of the
        /// animator. It is used to specify the remaining time for the animation. When
        /// called, it behaves as if the animation was started from its current position
        /// with a new duration and timing parameters.
        #[unsafe(method(continueAnimationWithTimingParameters:durationFactor:))]
        #[unsafe(method_family = none)]
        pub fn continueAnimationWithTimingParameters_durationFactor(
            &self,
            parameters: Option<&ProtocolObject<dyn UITimingCurveProvider>>,
            duration_factor: CGFloat,
        );
    );
}

/// Methods declared on superclass `NSObject`.
impl UIViewPropertyAnimator {
    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>;
    );
}
