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

/// Options for filtering texels within a mip level.
///
///
/// Select the single texel nearest to the sample point.
///
///
/// Select two texels in each dimension, and interpolate linearly between them.  Not all devices support linear filtering for all formats.  Integer textures can not use linear filtering on any device, and only some devices support linear filtering of Float textures.
///
/// See also [Apple's documentation](https://developer.apple.com/documentation/metal/mtlsamplerminmagfilter?language=objc)
// NS_ENUM
#[repr(transparent)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct MTLSamplerMinMagFilter(pub NSUInteger);
impl MTLSamplerMinMagFilter {
    #[doc(alias = "MTLSamplerMinMagFilterNearest")]
    pub const Nearest: Self = Self(0);
    #[doc(alias = "MTLSamplerMinMagFilterLinear")]
    pub const Linear: Self = Self(1);
}

unsafe impl Encode for MTLSamplerMinMagFilter {
    const ENCODING: Encoding = NSUInteger::ENCODING;
}

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

/// Options for selecting and filtering between mipmap levels
///
/// See also [Apple's documentation](https://developer.apple.com/documentation/metal/mtlsamplermipfilter?language=objc)
// NS_ENUM
#[repr(transparent)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct MTLSamplerMipFilter(pub NSUInteger);
impl MTLSamplerMipFilter {
    #[doc(alias = "MTLSamplerMipFilterNotMipmapped")]
    pub const NotMipmapped: Self = Self(0);
    #[doc(alias = "MTLSamplerMipFilterNearest")]
    pub const Nearest: Self = Self(1);
    #[doc(alias = "MTLSamplerMipFilterLinear")]
    pub const Linear: Self = Self(2);
}

unsafe impl Encode for MTLSamplerMipFilter {
    const ENCODING: Encoding = NSUInteger::ENCODING;
}

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

/// Options for what value is returned when a fetch falls outside the bounds of a texture.
///
///
/// Texture coordinates will be clamped between 0 and 1.
///
///
/// Mirror the texture while coordinates are within -1..1, and clamp to edge when outside.
///
///
/// Wrap to the other side of the texture, effectively ignoring fractional parts of the texture coordinate.
///
///
/// Between -1 and 1 the texture is mirrored across the 0 axis.  The image is repeated outside of that range.
///
///
/// ClampToZero returns transparent zero (0,0,0,0) for images with an alpha channel, and returns opaque zero (0,0,0,1) for images without an alpha channel.
///
///
/// Clamp to border color returns the value specified by the borderColor variable of the MTLSamplerDesc.
///
/// See also [Apple's documentation](https://developer.apple.com/documentation/metal/mtlsampleraddressmode?language=objc)
// NS_ENUM
#[repr(transparent)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct MTLSamplerAddressMode(pub NSUInteger);
impl MTLSamplerAddressMode {
    #[doc(alias = "MTLSamplerAddressModeClampToEdge")]
    pub const ClampToEdge: Self = Self(0);
    #[doc(alias = "MTLSamplerAddressModeMirrorClampToEdge")]
    pub const MirrorClampToEdge: Self = Self(1);
    #[doc(alias = "MTLSamplerAddressModeRepeat")]
    pub const Repeat: Self = Self(2);
    #[doc(alias = "MTLSamplerAddressModeMirrorRepeat")]
    pub const MirrorRepeat: Self = Self(3);
    #[doc(alias = "MTLSamplerAddressModeClampToZero")]
    pub const ClampToZero: Self = Self(4);
    #[doc(alias = "MTLSamplerAddressModeClampToBorderColor")]
    pub const ClampToBorderColor: Self = Self(5);
}

unsafe impl Encode for MTLSamplerAddressMode {
    const ENCODING: Encoding = NSUInteger::ENCODING;
}

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

/// Specify the color value that will be clamped to when the sampler address mode is MTLSamplerAddressModeClampToBorderColor.
///
///
/// Transparent black returns {0,0,0,0} for clamped texture values.
///
///
/// OpaqueBlack returns {0,0,0,1} for clamped texture values.
///
///
/// OpaqueWhite returns {1,1,1,1} for clamped texture values.
///
/// See also [Apple's documentation](https://developer.apple.com/documentation/metal/mtlsamplerbordercolor?language=objc)
// NS_ENUM
#[repr(transparent)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct MTLSamplerBorderColor(pub NSUInteger);
impl MTLSamplerBorderColor {
    #[doc(alias = "MTLSamplerBorderColorTransparentBlack")]
    pub const TransparentBlack: Self = Self(0);
    #[doc(alias = "MTLSamplerBorderColorOpaqueBlack")]
    pub const OpaqueBlack: Self = Self(1);
    #[doc(alias = "MTLSamplerBorderColorOpaqueWhite")]
    pub const OpaqueWhite: Self = Self(2);
}

unsafe impl Encode for MTLSamplerBorderColor {
    const ENCODING: Encoding = NSUInteger::ENCODING;
}

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

/// Configures how the sampler aggregates contributing samples to a final value.
///
/// See also [Apple's documentation](https://developer.apple.com/documentation/metal/mtlsamplerreductionmode?language=objc)
// NS_ENUM
#[repr(transparent)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct MTLSamplerReductionMode(pub NSUInteger);
impl MTLSamplerReductionMode {
    /// A reduction mode that adds together the product of each contributing sample value by its weight.
    #[doc(alias = "MTLSamplerReductionModeWeightedAverage")]
    pub const WeightedAverage: Self = Self(0);
    /// A reduction mode that finds the minimum contributing sample value by separately evaluating each channel.
    #[doc(alias = "MTLSamplerReductionModeMinimum")]
    pub const Minimum: Self = Self(1);
    /// A reduction mode that finds the maximum contributing sample value by separately evaluating each channel.
    #[doc(alias = "MTLSamplerReductionModeMaximum")]
    pub const Maximum: Self = Self(2);
}

unsafe impl Encode for MTLSamplerReductionMode {
    const ENCODING: Encoding = NSUInteger::ENCODING;
}

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

extern_class!(
    /// A mutable descriptor used to configure a sampler.  When complete, this can be used to create an immutable MTLSamplerState.
    ///
    /// See also [Apple's documentation](https://developer.apple.com/documentation/metal/mtlsamplerdescriptor?language=objc)
    #[unsafe(super(NSObject))]
    #[derive(Debug, PartialEq, Eq, Hash)]
    pub struct MTLSamplerDescriptor;
);

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

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

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

impl MTLSamplerDescriptor {
    extern_methods!(
        /// Filter option for combining texels within a mipmap level the sample footprint is larger than a pixel (minification).
        ///
        /// The default value is MTLSamplerMinMagFilterNearest.
        #[unsafe(method(minFilter))]
        #[unsafe(method_family = none)]
        pub fn minFilter(&self) -> MTLSamplerMinMagFilter;

        /// Setter for [`minFilter`][Self::minFilter].
        #[unsafe(method(setMinFilter:))]
        #[unsafe(method_family = none)]
        pub fn setMinFilter(&self, min_filter: MTLSamplerMinMagFilter);

        /// Filter option for combining texels within a mipmap level the sample footprint is smaller than a pixel (magnification).
        ///
        /// The default value is MTLSamplerMinMagFilterNearest.
        #[unsafe(method(magFilter))]
        #[unsafe(method_family = none)]
        pub fn magFilter(&self) -> MTLSamplerMinMagFilter;

        /// Setter for [`magFilter`][Self::magFilter].
        #[unsafe(method(setMagFilter:))]
        #[unsafe(method_family = none)]
        pub fn setMagFilter(&self, mag_filter: MTLSamplerMinMagFilter);

        /// Filter options for filtering between two mipmap levels.
        ///
        /// The default value is MTLSamplerMipFilterNotMipmapped
        #[unsafe(method(mipFilter))]
        #[unsafe(method_family = none)]
        pub fn mipFilter(&self) -> MTLSamplerMipFilter;

        /// Setter for [`mipFilter`][Self::mipFilter].
        #[unsafe(method(setMipFilter:))]
        #[unsafe(method_family = none)]
        pub fn setMipFilter(&self, mip_filter: MTLSamplerMipFilter);

        /// The number of samples that can be taken to improve quality of sample footprints that are anisotropic.
        ///
        /// The default value is 1.
        #[unsafe(method(maxAnisotropy))]
        #[unsafe(method_family = none)]
        pub fn maxAnisotropy(&self) -> NSUInteger;

        /// Setter for [`maxAnisotropy`][Self::maxAnisotropy].
        #[unsafe(method(setMaxAnisotropy:))]
        #[unsafe(method_family = none)]
        pub fn setMaxAnisotropy(&self, max_anisotropy: NSUInteger);

        /// Set the wrap mode for the S texture coordinate.  The default value is MTLSamplerAddressModeClampToEdge.
        #[unsafe(method(sAddressMode))]
        #[unsafe(method_family = none)]
        pub fn sAddressMode(&self) -> MTLSamplerAddressMode;

        /// Setter for [`sAddressMode`][Self::sAddressMode].
        #[unsafe(method(setSAddressMode:))]
        #[unsafe(method_family = none)]
        pub fn setSAddressMode(&self, s_address_mode: MTLSamplerAddressMode);

        /// Set the wrap mode for the T texture coordinate.  The default value is MTLSamplerAddressModeClampToEdge.
        #[unsafe(method(tAddressMode))]
        #[unsafe(method_family = none)]
        pub fn tAddressMode(&self) -> MTLSamplerAddressMode;

        /// Setter for [`tAddressMode`][Self::tAddressMode].
        #[unsafe(method(setTAddressMode:))]
        #[unsafe(method_family = none)]
        pub fn setTAddressMode(&self, t_address_mode: MTLSamplerAddressMode);

        /// Set the wrap mode for the R texture coordinate.  The default value is MTLSamplerAddressModeClampToEdge.
        #[unsafe(method(rAddressMode))]
        #[unsafe(method_family = none)]
        pub fn rAddressMode(&self) -> MTLSamplerAddressMode;

        /// Setter for [`rAddressMode`][Self::rAddressMode].
        #[unsafe(method(setRAddressMode:))]
        #[unsafe(method_family = none)]
        pub fn setRAddressMode(&self, r_address_mode: MTLSamplerAddressMode);

        /// Set the color for the MTLSamplerAddressMode to one of the predefined in the MTLSamplerBorderColor enum.
        #[unsafe(method(borderColor))]
        #[unsafe(method_family = none)]
        pub fn borderColor(&self) -> MTLSamplerBorderColor;

        /// Setter for [`borderColor`][Self::borderColor].
        #[unsafe(method(setBorderColor:))]
        #[unsafe(method_family = none)]
        pub fn setBorderColor(&self, border_color: MTLSamplerBorderColor);

        /// Sets the reduction mode for filtering contributing samples.
        ///
        /// The property's default value is ``MTLSamplerReductionModeWeightedAverage``.
        /// The sampler ignores this property if any of the following property values are equal to a specific value:
        /// - The sampler's ``mipFilter`` property is equal to ``MTLSamplerMipFilterNotMipmapped``.
        /// - The sampler's ``mipFilter`` property is equal to ``MTLSamplerMipFilterNearest``.
        /// - The sampler's ``minFilter`` property is equal to ``MTLSamplerMinMagFilterNearest``.
        /// - The sampler's ``magFilter`` property is equal to ``MTLSamplerMinMagFilterNearest``.
        #[unsafe(method(reductionMode))]
        #[unsafe(method_family = none)]
        pub fn reductionMode(&self) -> MTLSamplerReductionMode;

        /// Setter for [`reductionMode`][Self::reductionMode].
        #[unsafe(method(setReductionMode:))]
        #[unsafe(method_family = none)]
        pub fn setReductionMode(&self, reduction_mode: MTLSamplerReductionMode);

        /// If YES, texture coordates are from 0 to 1.  If NO, texture coordinates are 0..width, 0..height.
        ///
        /// normalizedCoordinates defaults to YES.  Non-normalized coordinates should only be used with 1D and 2D textures with the ClampToEdge wrap mode, otherwise the results of sampling are undefined.
        #[unsafe(method(normalizedCoordinates))]
        #[unsafe(method_family = none)]
        pub fn normalizedCoordinates(&self) -> bool;

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

        /// The minimum level of detail that will be used when sampling from a texture.
        ///
        /// The default value of lodMinClamp is 0.0.  Clamp values are ignored for texture sample variants that specify an explicit level of detail.
        #[unsafe(method(lodMinClamp))]
        #[unsafe(method_family = none)]
        pub fn lodMinClamp(&self) -> c_float;

        /// Setter for [`lodMinClamp`][Self::lodMinClamp].
        #[unsafe(method(setLodMinClamp:))]
        #[unsafe(method_family = none)]
        pub fn setLodMinClamp(&self, lod_min_clamp: c_float);

        /// The maximum level of detail that will be used when sampling from a texture.
        ///
        /// The default value of lodMaxClamp is FLT_MAX.  Clamp values are ignored for texture sample variants that specify an explicit level of detail.
        #[unsafe(method(lodMaxClamp))]
        #[unsafe(method_family = none)]
        pub fn lodMaxClamp(&self) -> c_float;

        /// Setter for [`lodMaxClamp`][Self::lodMaxClamp].
        #[unsafe(method(setLodMaxClamp:))]
        #[unsafe(method_family = none)]
        pub fn setLodMaxClamp(&self, lod_max_clamp: c_float);

        /// If YES, an average level of detail will be used when sampling from a texture. If NO, no averaging is performed.
        ///
        /// lodAverage defaults to NO. This option is a performance hint. An implementation is free to ignore this property.
        #[unsafe(method(lodAverage))]
        #[unsafe(method_family = none)]
        pub fn lodAverage(&self) -> bool;

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

        /// Sets the level-of-detail (lod) bias when sampling from a texture.
        ///
        /// The property's default value is `0.0f`.
        /// The precision format is `S4.6`, and the range is `[-16.0, 15.999]`.
        #[unsafe(method(lodBias))]
        #[unsafe(method_family = none)]
        pub fn lodBias(&self) -> c_float;

        /// Setter for [`lodBias`][Self::lodBias].
        #[unsafe(method(setLodBias:))]
        #[unsafe(method_family = none)]
        pub fn setLodBias(&self, lod_bias: c_float);

        #[cfg(feature = "MTLDepthStencil")]
        /// Set the comparison function used when sampling shadow maps. The default value is MTLCompareFunctionNever.
        #[unsafe(method(compareFunction))]
        #[unsafe(method_family = none)]
        pub fn compareFunction(&self) -> MTLCompareFunction;

        #[cfg(feature = "MTLDepthStencil")]
        /// Setter for [`compareFunction`][Self::compareFunction].
        #[unsafe(method(setCompareFunction:))]
        #[unsafe(method_family = none)]
        pub fn setCompareFunction(&self, compare_function: MTLCompareFunction);

        /// true if the sampler can be used inside an argument buffer
        #[unsafe(method(supportArgumentBuffers))]
        #[unsafe(method_family = none)]
        pub fn supportArgumentBuffers(&self) -> bool;

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

        /// A string to help identify the created object.
        #[unsafe(method(label))]
        #[unsafe(method_family = none)]
        pub fn label(&self) -> Option<Retained<NSString>>;

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

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

extern_protocol!(
    /// An immutable collection of sampler state compiled for a single device.
    ///
    /// See also [Apple's documentation](https://developer.apple.com/documentation/metal/mtlsamplerstate?language=objc)
    pub unsafe trait MTLSamplerState: NSObjectProtocol + Send + Sync {
        /// A string to help identify this object.
        #[unsafe(method(label))]
        #[unsafe(method_family = none)]
        fn label(&self) -> Option<Retained<NSString>>;

        #[cfg(feature = "MTLDevice")]
        /// The device this resource was created against.  This resource can only be used with this device.
        #[unsafe(method(device))]
        #[unsafe(method_family = none)]
        fn device(&self) -> Retained<ProtocolObject<dyn MTLDevice>>;

        #[cfg(feature = "MTLTypes")]
        /// Handle of the GPU resource suitable for storing in an Argument Buffer
        #[unsafe(method(gpuResourceID))]
        #[unsafe(method_family = none)]
        fn gpuResourceID(&self) -> MTLResourceID;
    }
);
