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

/// [Apple's documentation](https://developer.apple.com/documentation/uikit/uiattachmentbehaviortype?language=objc)
// NS_ENUM
#[repr(transparent)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct UIAttachmentBehaviorType(pub NSInteger);
impl UIAttachmentBehaviorType {
    #[doc(alias = "UIAttachmentBehaviorTypeItems")]
    pub const Items: Self = Self(0);
    #[doc(alias = "UIAttachmentBehaviorTypeAnchor")]
    pub const Anchor: Self = Self(1);
}

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

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

/// [Apple's documentation](https://developer.apple.com/documentation/uikit/uifloatrange?language=objc)
#[cfg(feature = "objc2-core-foundation")]
#[repr(C)]
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct UIFloatRange {
    pub minimum: CGFloat,
    pub maximum: CGFloat,
}

#[cfg(feature = "objc2-core-foundation")]
unsafe impl Encode for UIFloatRange {
    const ENCODING: Encoding = Encoding::Struct("?", &[<CGFloat>::ENCODING, <CGFloat>::ENCODING]);
}

#[cfg(feature = "objc2-core-foundation")]
unsafe impl RefEncode for UIFloatRange {
    const ENCODING_REF: Encoding = Encoding::Pointer(&Self::ENCODING);
}

#[cfg(feature = "objc2-core-foundation")]
unsafe impl Send for UIFloatRange {}

#[cfg(feature = "objc2-core-foundation")]
unsafe impl Sync for UIFloatRange {}

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

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

#[cfg(feature = "objc2-core-foundation")]
impl UIFloatRange {
    #[doc(alias = "UIFloatRangeIsInfinite")]
    #[cfg(feature = "objc2-core-foundation")]
    #[inline]
    pub fn is_infinite(self) -> bool {
        extern "C-unwind" {
            fn UIFloatRangeIsInfinite(range: UIFloatRange) -> Bool;
        }
        unsafe { UIFloatRangeIsInfinite(self) }.as_bool()
    }

    // TODO: pub fn UIFloatRangeMake(minimum: CGFloat,maximum: CGFloat,) -> UIFloatRange;

    // TODO: pub fn UIFloatRangeIsEqualToRange(range: UIFloatRange,other_range: UIFloatRange,) -> Bool;
}

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

#[cfg(feature = "UIDynamicBehavior")]
extern_conformance!(
    unsafe impl NSObjectProtocol for UIAttachmentBehavior {}
);

#[cfg(feature = "UIDynamicBehavior")]
impl UIAttachmentBehavior {
    extern_methods!(
        #[cfg(feature = "objc2-core-foundation")]
        #[unsafe(method(initWithItem:attachedToAnchor:))]
        #[unsafe(method_family = init)]
        pub fn initWithItem_attachedToAnchor(
            this: Allocated<Self>,
            item: &ProtocolObject<dyn UIDynamicItem>,
            point: CGPoint,
        ) -> Retained<Self>;

        #[cfg(all(feature = "UIGeometry", feature = "objc2-core-foundation"))]
        #[unsafe(method(initWithItem:offsetFromCenter:attachedToAnchor:))]
        #[unsafe(method_family = init)]
        pub fn initWithItem_offsetFromCenter_attachedToAnchor(
            this: Allocated<Self>,
            item: &ProtocolObject<dyn UIDynamicItem>,
            offset: UIOffset,
            point: CGPoint,
        ) -> Retained<Self>;

        #[unsafe(method(initWithItem:attachedToItem:))]
        #[unsafe(method_family = init)]
        pub fn initWithItem_attachedToItem(
            this: Allocated<Self>,
            item1: &ProtocolObject<dyn UIDynamicItem>,
            item2: &ProtocolObject<dyn UIDynamicItem>,
        ) -> Retained<Self>;

        #[cfg(all(feature = "UIGeometry", feature = "objc2-core-foundation"))]
        #[unsafe(method(initWithItem:offsetFromCenter:attachedToItem:offsetFromCenter:))]
        #[unsafe(method_family = init)]
        pub fn initWithItem_offsetFromCenter_attachedToItem_offsetFromCenter(
            this: Allocated<Self>,
            item1: &ProtocolObject<dyn UIDynamicItem>,
            offset1: UIOffset,
            item2: &ProtocolObject<dyn UIDynamicItem>,
            offset2: UIOffset,
        ) -> Retained<Self>;

        #[cfg(feature = "objc2-core-foundation")]
        /// A sliding attachment allows for relative translation of two items along a specified axis with respect to the anchor point. A sliding
        /// attachment prevents all relative rotation of the dynamic items.
        ///
        /// Parameter `item1`: The first of two dynamic items connected by the attachment behavior.
        ///
        /// Parameter `item2`: The second of two dynamic items connected by the attachment behavior.
        ///
        /// Parameter `point`: The point for which each item will be attached. The anchor point will be converted to each items local coordinate system.
        ///
        /// Parameter `axis`: Axis of allowed relative translation between local anchor point. Must be a unit vector.
        ///
        /// See: attachmentRange, Represents the slidable range of the attachment with respect to the anchor point along the specified axis, this range must include 0
        #[unsafe(method(slidingAttachmentWithItem:attachedToItem:attachmentAnchor:axisOfTranslation:))]
        #[unsafe(method_family = none)]
        pub fn slidingAttachmentWithItem_attachedToItem_attachmentAnchor_axisOfTranslation(
            item1: &ProtocolObject<dyn UIDynamicItem>,
            item2: &ProtocolObject<dyn UIDynamicItem>,
            point: CGPoint,
            axis: CGVector,
        ) -> Retained<Self>;

        #[cfg(feature = "objc2-core-foundation")]
        /// A sliding attachment allows for translation of the item along a specified axis with respect to the anchor point. A sliding
        /// attachment prevents all relative rotation of the dynamic items.
        ///
        /// Parameter `item1`: The dynamic item connected by the attachment behavior.
        ///
        /// Parameter `point`: The point for the item will be anchored by the attachment.
        ///
        /// Parameter `axis`: Axis of allowed translation for the item. Must be a unit vector.
        ///
        /// See: attachmentRange, Represents the slidable range of the attachment with respect to the anchor point along the specified axis, this range must include 0
        #[unsafe(method(slidingAttachmentWithItem:attachmentAnchor:axisOfTranslation:))]
        #[unsafe(method_family = none)]
        pub fn slidingAttachmentWithItem_attachmentAnchor_axisOfTranslation(
            item: &ProtocolObject<dyn UIDynamicItem>,
            point: CGPoint,
            axis: CGVector,
        ) -> Retained<Self>;

        #[cfg(all(feature = "UIGeometry", feature = "objc2-core-foundation"))]
        /// A limit attachment imposes a maximum distance between two dynamic items, as if they were connected by a rope.
        ///
        /// Parameter `item1`: The first of two dynamic items connected by the attachment behavior.
        ///
        /// Parameter `offset1`: The point, within the dynamic item and described as an offset from its center point, for the attachment behavior.
        ///
        /// Parameter `item2`: The second of two dynamic items connected by the attachment behavior.
        ///
        /// Parameter `offset2`: The point, within the dynamic item and described as an offset from its center point, for the attachment behavior.
        ///
        /// See: length
        #[unsafe(method(limitAttachmentWithItem:offsetFromCenter:attachedToItem:offsetFromCenter:))]
        #[unsafe(method_family = none)]
        pub fn limitAttachmentWithItem_offsetFromCenter_attachedToItem_offsetFromCenter(
            item1: &ProtocolObject<dyn UIDynamicItem>,
            offset1: UIOffset,
            item2: &ProtocolObject<dyn UIDynamicItem>,
            offset2: UIOffset,
        ) -> Retained<Self>;

        #[cfg(feature = "objc2-core-foundation")]
        /// A fixed attachment fuses two dynamic items together at a reference point.
        /// Fixed attachments are useful for creating complex shapes that can be broken apart later.
        ///
        /// Parameter `item1`: The first of two dynamic items connected by the attachment behavior.
        ///
        /// Parameter `item2`: The second of two dynamic items connected by the attachment behavior.
        ///
        /// Parameter `point`: The point for which each item will be attached. The anchor point will be converted to each items local coordinate system.
        #[unsafe(method(fixedAttachmentWithItem:attachedToItem:attachmentAnchor:))]
        #[unsafe(method_family = none)]
        pub fn fixedAttachmentWithItem_attachedToItem_attachmentAnchor(
            item1: &ProtocolObject<dyn UIDynamicItem>,
            item2: &ProtocolObject<dyn UIDynamicItem>,
            point: CGPoint,
        ) -> Retained<Self>;

        #[cfg(feature = "objc2-core-foundation")]
        /// A pin attachment allows two dynamic items to independently rotate around the anchor point as if pinned together.
        /// You can configure how far the two objects may rotate and the resistance to rotation
        ///
        /// Parameter `item1`: The first of two dynamic items connected by the attachment behavior.
        ///
        /// Parameter `item2`: The second of two dynamic items connected by the attachment behavior.
        ///
        /// Parameter `point`: The point for which each item will be attached. The anchor point will be converted to each items local coordinate system
        ///
        /// See: frictionTorque, resistance to rotation
        #[unsafe(method(pinAttachmentWithItem:attachedToItem:attachmentAnchor:))]
        #[unsafe(method_family = none)]
        pub fn pinAttachmentWithItem_attachedToItem_attachmentAnchor(
            item1: &ProtocolObject<dyn UIDynamicItem>,
            item2: &ProtocolObject<dyn UIDynamicItem>,
            point: CGPoint,
        ) -> Retained<Self>;

        #[unsafe(method(items))]
        #[unsafe(method_family = none)]
        pub fn items(&self) -> Retained<NSArray<ProtocolObject<dyn UIDynamicItem>>>;

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

        #[cfg(feature = "objc2-core-foundation")]
        #[unsafe(method(anchorPoint))]
        #[unsafe(method_family = none)]
        pub fn anchorPoint(&self) -> CGPoint;

        #[cfg(feature = "objc2-core-foundation")]
        /// Setter for [`anchorPoint`][Self::anchorPoint].
        #[unsafe(method(setAnchorPoint:))]
        #[unsafe(method_family = none)]
        pub fn setAnchorPoint(&self, anchor_point: CGPoint);

        #[cfg(feature = "objc2-core-foundation")]
        #[unsafe(method(length))]
        #[unsafe(method_family = none)]
        pub fn length(&self) -> CGFloat;

        #[cfg(feature = "objc2-core-foundation")]
        /// Setter for [`length`][Self::length].
        #[unsafe(method(setLength:))]
        #[unsafe(method_family = none)]
        pub fn setLength(&self, length: CGFloat);

        #[cfg(feature = "objc2-core-foundation")]
        #[unsafe(method(damping))]
        #[unsafe(method_family = none)]
        pub fn damping(&self) -> CGFloat;

        #[cfg(feature = "objc2-core-foundation")]
        /// Setter for [`damping`][Self::damping].
        #[unsafe(method(setDamping:))]
        #[unsafe(method_family = none)]
        pub fn setDamping(&self, damping: CGFloat);

        #[cfg(feature = "objc2-core-foundation")]
        #[unsafe(method(frequency))]
        #[unsafe(method_family = none)]
        pub fn frequency(&self) -> CGFloat;

        #[cfg(feature = "objc2-core-foundation")]
        /// Setter for [`frequency`][Self::frequency].
        #[unsafe(method(setFrequency:))]
        #[unsafe(method_family = none)]
        pub fn setFrequency(&self, frequency: CGFloat);

        #[cfg(feature = "objc2-core-foundation")]
        #[unsafe(method(frictionTorque))]
        #[unsafe(method_family = none)]
        pub fn frictionTorque(&self) -> CGFloat;

        #[cfg(feature = "objc2-core-foundation")]
        /// Setter for [`frictionTorque`][Self::frictionTorque].
        #[unsafe(method(setFrictionTorque:))]
        #[unsafe(method_family = none)]
        pub fn setFrictionTorque(&self, friction_torque: CGFloat);

        #[cfg(feature = "objc2-core-foundation")]
        #[unsafe(method(attachmentRange))]
        #[unsafe(method_family = none)]
        pub fn attachmentRange(&self) -> UIFloatRange;

        #[cfg(feature = "objc2-core-foundation")]
        /// Setter for [`attachmentRange`][Self::attachmentRange].
        #[unsafe(method(setAttachmentRange:))]
        #[unsafe(method_family = none)]
        pub fn setAttachmentRange(&self, attachment_range: UIFloatRange);
    );
}

/// Methods declared on superclass `NSObject`.
#[cfg(feature = "UIDynamicBehavior")]
impl UIAttachmentBehavior {
    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>;
    );
}

#[cfg(feature = "objc2-core-foundation")]
#[deprecated = "renamed to `UIFloatRange::is_infinite`"]
#[inline]
pub extern "C-unwind" fn UIFloatRangeIsInfinite(range: UIFloatRange) -> bool {
    extern "C-unwind" {
        fn UIFloatRangeIsInfinite(range: UIFloatRange) -> Bool;
    }
    unsafe { UIFloatRangeIsInfinite(range) }.as_bool()
}
