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

extern_class!(
    /// UIMotionEffect is an abstract superclass which declaratively represents a rendering
    /// effect that depends on the motion of the device. Given some device pose, subclassers
    /// provide relative values which are to be applied to the key paths of the target's view.
    ///
    /// Subclasses must implement conformance for NSCopying and NSCoding.
    ///
    /// See also [Apple's documentation](https://developer.apple.com/documentation/uikit/uimotioneffect?language=objc)
    #[unsafe(super(NSObject))]
    #[thread_kind = MainThreadOnly]
    #[derive(Debug, PartialEq, Eq, Hash)]
    pub struct UIMotionEffect;
);

extern_conformance!(
    unsafe impl NSCoding for UIMotionEffect {}
);

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

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

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

impl UIMotionEffect {
    extern_methods!(
        #[unsafe(method(init))]
        #[unsafe(method_family = init)]
        pub fn init(this: Allocated<Self>) -> 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>>;

        #[cfg(all(feature = "UIGeometry", feature = "objc2-core-foundation"))]
        /// Abstract method. Given the `viewerOffset`, this method should compute a set of key paths
        /// and relative values pairs which will represent the effect of the device's motion on
        /// the target view. The return value is a dictionary whose keys and values are these
        /// key paths (as NSStrings) and relative values, respectively.
        ///
        /// The `viewerOffset` is an estimate of the viewer's position relative to direction the
        /// screen's facing. Values in each dimension range from -1 to 1. Facing straight at the
        /// viewer is (0, 0). Tilting the phone to the right produces a more positive horizontal
        /// value; tilting the phone down produces a more positive vertical value.
        ///
        /// `keyPaths` should be expressed relative to the effect's target view. Only key paths
        /// which would animate if set in an animation block may be targeted by motion effects.
        ///
        /// Example return value: `
        /// @
        /// {
        /// "
        /// center": [NSValue
        /// valueFromCGPoint:CGPointMake(3.4, 1.2)],
        /// "
        /// layer.shadowOffset.x":
        /// @
        /// (-1.1) }`
        #[unsafe(method(keyPathsAndRelativeValuesForViewerOffset:))]
        #[unsafe(method_family = none)]
        pub fn keyPathsAndRelativeValuesForViewerOffset(
            &self,
            viewer_offset: UIOffset,
        ) -> Option<Retained<NSDictionary<NSString, AnyObject>>>;
    );
}

/// Methods declared on superclass `NSObject`.
impl UIMotionEffect {
    extern_methods!(
        #[unsafe(method(new))]
        #[unsafe(method_family = new)]
        pub fn new(mtm: MainThreadMarker) -> Retained<Self>;
    );
}

/// [Apple's documentation](https://developer.apple.com/documentation/uikit/uiinterpolatingmotioneffecttype?language=objc)
// NS_ENUM
#[repr(transparent)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct UIInterpolatingMotionEffectType(pub NSInteger);
impl UIInterpolatingMotionEffectType {
    /// Tracks the device being tilted left/right relative to the viewer. The minimum
    /// relative values maps to the device being tilted all the way to the left, the
    /// maximum to the right.
    #[doc(alias = "UIInterpolatingMotionEffectTypeTiltAlongHorizontalAxis")]
    pub const TiltAlongHorizontalAxis: Self = Self(0);
    /// Tracks the device being tilted up/down relative to the viewer. The minimum
    /// relative values maps to the device being tilted all the way down, the maximum
    /// all the way up.
    #[doc(alias = "UIInterpolatingMotionEffectTypeTiltAlongVerticalAxis")]
    pub const TiltAlongVerticalAxis: Self = Self(1);
}

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

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

extern_class!(
    /// This motion effect maps movement of a particular type (e.g. left/right tilt) to an
    /// interpolated output between two relative values provided by the client. Uses Core
    /// Animation's implementation of interpolation for all the standard types.
    ///
    /// `keyPath` should be expressed relative to the effect's target view.
    ///
    /// See also [Apple's documentation](https://developer.apple.com/documentation/uikit/uiinterpolatingmotioneffect?language=objc)
    #[unsafe(super(UIMotionEffect, NSObject))]
    #[thread_kind = MainThreadOnly]
    #[derive(Debug, PartialEq, Eq, Hash)]
    pub struct UIInterpolatingMotionEffect;
);

extern_conformance!(
    unsafe impl NSCoding for UIInterpolatingMotionEffect {}
);

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

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

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

impl UIInterpolatingMotionEffect {
    extern_methods!(
        #[unsafe(method(initWithKeyPath:type:))]
        #[unsafe(method_family = init)]
        pub fn initWithKeyPath_type(
            this: Allocated<Self>,
            key_path: &NSString,
            r#type: UIInterpolatingMotionEffectType,
        ) -> 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>>;

        #[unsafe(method(keyPath))]
        #[unsafe(method_family = none)]
        pub fn keyPath(&self) -> Retained<NSString>;

        #[unsafe(method(type))]
        #[unsafe(method_family = none)]
        pub fn r#type(&self) -> UIInterpolatingMotionEffectType;

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

        /// Setter for [`minimumRelativeValue`][Self::minimumRelativeValue].
        ///
        /// # Safety
        ///
        /// `minimum_relative_value` should be of the correct type.
        #[unsafe(method(setMinimumRelativeValue:))]
        #[unsafe(method_family = none)]
        pub unsafe fn setMinimumRelativeValue(&self, minimum_relative_value: Option<&AnyObject>);

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

        /// Setter for [`maximumRelativeValue`][Self::maximumRelativeValue].
        ///
        /// # Safety
        ///
        /// `maximum_relative_value` should be of the correct type.
        #[unsafe(method(setMaximumRelativeValue:))]
        #[unsafe(method_family = none)]
        pub unsafe fn setMaximumRelativeValue(&self, maximum_relative_value: Option<&AnyObject>);
    );
}

/// Methods declared on superclass `UIMotionEffect`.
impl UIInterpolatingMotionEffect {
    extern_methods!(
        #[unsafe(method(init))]
        #[unsafe(method_family = init)]
        pub fn init(this: Allocated<Self>) -> Retained<Self>;
    );
}

/// Methods declared on superclass `NSObject`.
impl UIInterpolatingMotionEffect {
    extern_methods!(
        #[unsafe(method(new))]
        #[unsafe(method_family = new)]
        pub fn new(mtm: MainThreadMarker) -> Retained<Self>;
    );
}

extern_class!(
    /// Behaves like CAAnimationGroup. Merges key/value pairs of constituent
    /// using Core Animation's implementations of addition for all the standard types.
    ///
    /// See also [Apple's documentation](https://developer.apple.com/documentation/uikit/uimotioneffectgroup?language=objc)
    #[unsafe(super(UIMotionEffect, NSObject))]
    #[thread_kind = MainThreadOnly]
    #[derive(Debug, PartialEq, Eq, Hash)]
    pub struct UIMotionEffectGroup;
);

extern_conformance!(
    unsafe impl NSCoding for UIMotionEffectGroup {}
);

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

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

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

impl UIMotionEffectGroup {
    extern_methods!(
        #[unsafe(method(motionEffects))]
        #[unsafe(method_family = none)]
        pub fn motionEffects(&self) -> Option<Retained<NSArray<UIMotionEffect>>>;

        /// Setter for [`motionEffects`][Self::motionEffects].
        ///
        /// This is [copied][objc2_foundation::NSCopying::copy] when set.
        #[unsafe(method(setMotionEffects:))]
        #[unsafe(method_family = none)]
        pub fn setMotionEffects(&self, motion_effects: Option<&NSArray<UIMotionEffect>>);
    );
}

/// Methods declared on superclass `UIMotionEffect`.
impl UIMotionEffectGroup {
    extern_methods!(
        #[unsafe(method(init))]
        #[unsafe(method_family = init)]
        pub fn init(this: Allocated<Self>) -> 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 `NSObject`.
impl UIMotionEffectGroup {
    extern_methods!(
        #[unsafe(method(new))]
        #[unsafe(method_family = new)]
        pub fn new(mtm: MainThreadMarker) -> Retained<Self>;
    );
}
