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

extern "C" {
    /// *************    Exceptions        **********
    ///
    /// See also [Apple's documentation](https://developer.apple.com/documentation/foundation/nsdecimalnumberexactnessexception?language=objc)
    #[cfg(all(feature = "NSObjCRuntime", feature = "NSString"))]
    pub static NSDecimalNumberExactnessException: &'static NSExceptionName;
}

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

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

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

extern_protocol!(
    /// [Apple's documentation](https://developer.apple.com/documentation/foundation/nsdecimalnumberbehaviors?language=objc)
    pub unsafe trait NSDecimalNumberBehaviors {
        #[cfg(feature = "NSDecimal")]
        #[unsafe(method(roundingMode))]
        #[unsafe(method_family = none)]
        fn roundingMode(&self) -> NSRoundingMode;

        #[unsafe(method(scale))]
        #[unsafe(method_family = none)]
        fn scale(&self) -> c_short;

        #[cfg(all(feature = "NSDecimal", feature = "NSValue"))]
        /// # Safety
        ///
        /// `operation` must be a valid selector.
        #[unsafe(method(exceptionDuringOperation:error:leftOperand:rightOperand:))]
        #[unsafe(method_family = none)]
        unsafe fn exceptionDuringOperation_error_leftOperand_rightOperand(
            &self,
            operation: Sel,
            error: NSCalculationError,
            left_operand: &NSDecimalNumber,
            right_operand: Option<&NSDecimalNumber>,
        ) -> Option<Retained<NSDecimalNumber>>;
    }
);

extern_class!(
    /// *************    NSDecimalNumber: the class        **********
    ///
    /// See also [Apple's documentation](https://developer.apple.com/documentation/foundation/nsdecimalnumber?language=objc)
    #[unsafe(super(NSNumber, NSValue, NSObject))]
    #[derive(Debug, PartialEq, Eq, Hash)]
    #[cfg(feature = "NSValue")]
    pub struct NSDecimalNumber;
);

#[cfg(feature = "NSValue")]
unsafe impl Send for NSDecimalNumber {}

#[cfg(feature = "NSValue")]
unsafe impl Sync for NSDecimalNumber {}

#[cfg(all(feature = "NSObject", feature = "NSValue"))]
extern_conformance!(
    unsafe impl NSCoding for NSDecimalNumber {}
);

#[cfg(all(feature = "NSObject", feature = "NSValue"))]
extern_conformance!(
    unsafe impl NSCopying for NSDecimalNumber {}
);

#[cfg(all(feature = "NSObject", feature = "NSValue"))]
unsafe impl CopyingHelper for NSDecimalNumber {
    type Result = Self;
}

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

#[cfg(all(feature = "NSObject", feature = "NSValue"))]
extern_conformance!(
    unsafe impl NSSecureCoding for NSDecimalNumber {}
);

#[cfg(feature = "NSValue")]
impl NSDecimalNumber {
    extern_methods!(
        #[unsafe(method(initWithMantissa:exponent:isNegative:))]
        #[unsafe(method_family = init)]
        pub fn initWithMantissa_exponent_isNegative(
            this: Allocated<Self>,
            mantissa: c_ulonglong,
            exponent: c_short,
            flag: bool,
        ) -> Retained<Self>;

        #[cfg(feature = "NSDecimal")]
        #[unsafe(method(initWithDecimal:))]
        #[unsafe(method_family = init)]
        pub fn initWithDecimal(this: Allocated<Self>, dcm: NSDecimal) -> Retained<Self>;

        #[cfg(feature = "NSString")]
        #[unsafe(method(initWithString:))]
        #[unsafe(method_family = init)]
        pub fn initWithString(
            this: Allocated<Self>,
            number_value: Option<&NSString>,
        ) -> Retained<Self>;

        #[cfg(feature = "NSString")]
        /// # Safety
        ///
        /// `locale` should be of the correct type.
        #[unsafe(method(initWithString:locale:))]
        #[unsafe(method_family = init)]
        pub unsafe fn initWithString_locale(
            this: Allocated<Self>,
            number_value: Option<&NSString>,
            locale: Option<&AnyObject>,
        ) -> Retained<Self>;

        #[cfg(feature = "NSString")]
        /// # Safety
        ///
        /// `locale` should be of the correct type.
        #[unsafe(method(descriptionWithLocale:))]
        #[unsafe(method_family = none)]
        pub unsafe fn descriptionWithLocale(
            &self,
            locale: Option<&AnyObject>,
        ) -> Retained<NSString>;

        #[cfg(feature = "NSDecimal")]
        #[unsafe(method(decimalValue))]
        #[unsafe(method_family = none)]
        pub fn decimalValue(&self) -> NSDecimal;

        #[unsafe(method(decimalNumberWithMantissa:exponent:isNegative:))]
        #[unsafe(method_family = none)]
        pub fn decimalNumberWithMantissa_exponent_isNegative(
            mantissa: c_ulonglong,
            exponent: c_short,
            flag: bool,
        ) -> Retained<NSDecimalNumber>;

        #[cfg(feature = "NSDecimal")]
        #[unsafe(method(decimalNumberWithDecimal:))]
        #[unsafe(method_family = none)]
        pub fn decimalNumberWithDecimal(dcm: NSDecimal) -> Retained<NSDecimalNumber>;

        #[cfg(feature = "NSString")]
        #[unsafe(method(decimalNumberWithString:))]
        #[unsafe(method_family = none)]
        pub fn decimalNumberWithString(
            number_value: Option<&NSString>,
        ) -> Retained<NSDecimalNumber>;

        #[cfg(feature = "NSString")]
        /// # Safety
        ///
        /// `locale` should be of the correct type.
        #[unsafe(method(decimalNumberWithString:locale:))]
        #[unsafe(method_family = none)]
        pub unsafe fn decimalNumberWithString_locale(
            number_value: Option<&NSString>,
            locale: Option<&AnyObject>,
        ) -> Retained<NSDecimalNumber>;

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

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

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

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

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

        #[unsafe(method(decimalNumberByAdding:))]
        #[unsafe(method_family = none)]
        pub fn decimalNumberByAdding(
            &self,
            decimal_number: &NSDecimalNumber,
        ) -> Retained<NSDecimalNumber>;

        #[unsafe(method(decimalNumberByAdding:withBehavior:))]
        #[unsafe(method_family = none)]
        pub fn decimalNumberByAdding_withBehavior(
            &self,
            decimal_number: &NSDecimalNumber,
            behavior: Option<&ProtocolObject<dyn NSDecimalNumberBehaviors>>,
        ) -> Retained<NSDecimalNumber>;

        #[unsafe(method(decimalNumberBySubtracting:))]
        #[unsafe(method_family = none)]
        pub fn decimalNumberBySubtracting(
            &self,
            decimal_number: &NSDecimalNumber,
        ) -> Retained<NSDecimalNumber>;

        #[unsafe(method(decimalNumberBySubtracting:withBehavior:))]
        #[unsafe(method_family = none)]
        pub fn decimalNumberBySubtracting_withBehavior(
            &self,
            decimal_number: &NSDecimalNumber,
            behavior: Option<&ProtocolObject<dyn NSDecimalNumberBehaviors>>,
        ) -> Retained<NSDecimalNumber>;

        #[unsafe(method(decimalNumberByMultiplyingBy:))]
        #[unsafe(method_family = none)]
        pub fn decimalNumberByMultiplyingBy(
            &self,
            decimal_number: &NSDecimalNumber,
        ) -> Retained<NSDecimalNumber>;

        #[unsafe(method(decimalNumberByMultiplyingBy:withBehavior:))]
        #[unsafe(method_family = none)]
        pub fn decimalNumberByMultiplyingBy_withBehavior(
            &self,
            decimal_number: &NSDecimalNumber,
            behavior: Option<&ProtocolObject<dyn NSDecimalNumberBehaviors>>,
        ) -> Retained<NSDecimalNumber>;

        #[unsafe(method(decimalNumberByDividingBy:))]
        #[unsafe(method_family = none)]
        pub fn decimalNumberByDividingBy(
            &self,
            decimal_number: &NSDecimalNumber,
        ) -> Retained<NSDecimalNumber>;

        #[unsafe(method(decimalNumberByDividingBy:withBehavior:))]
        #[unsafe(method_family = none)]
        pub fn decimalNumberByDividingBy_withBehavior(
            &self,
            decimal_number: &NSDecimalNumber,
            behavior: Option<&ProtocolObject<dyn NSDecimalNumberBehaviors>>,
        ) -> Retained<NSDecimalNumber>;

        #[unsafe(method(decimalNumberByRaisingToPower:))]
        #[unsafe(method_family = none)]
        pub fn decimalNumberByRaisingToPower(&self, power: NSUInteger)
            -> Retained<NSDecimalNumber>;

        #[unsafe(method(decimalNumberByRaisingToPower:withBehavior:))]
        #[unsafe(method_family = none)]
        pub fn decimalNumberByRaisingToPower_withBehavior(
            &self,
            power: NSUInteger,
            behavior: Option<&ProtocolObject<dyn NSDecimalNumberBehaviors>>,
        ) -> Retained<NSDecimalNumber>;

        #[unsafe(method(decimalNumberByMultiplyingByPowerOf10:))]
        #[unsafe(method_family = none)]
        pub fn decimalNumberByMultiplyingByPowerOf10(
            &self,
            power: c_short,
        ) -> Retained<NSDecimalNumber>;

        #[unsafe(method(decimalNumberByMultiplyingByPowerOf10:withBehavior:))]
        #[unsafe(method_family = none)]
        pub fn decimalNumberByMultiplyingByPowerOf10_withBehavior(
            &self,
            power: c_short,
            behavior: Option<&ProtocolObject<dyn NSDecimalNumberBehaviors>>,
        ) -> Retained<NSDecimalNumber>;

        #[unsafe(method(decimalNumberByRoundingAccordingToBehavior:))]
        #[unsafe(method_family = none)]
        pub fn decimalNumberByRoundingAccordingToBehavior(
            &self,
            behavior: Option<&ProtocolObject<dyn NSDecimalNumberBehaviors>>,
        ) -> Retained<NSDecimalNumber>;

        #[cfg(feature = "NSObjCRuntime")]
        #[unsafe(method(compare:))]
        #[unsafe(method_family = none)]
        pub fn compare(&self, decimal_number: &NSNumber) -> NSComparisonResult;

        #[unsafe(method(defaultBehavior))]
        #[unsafe(method_family = none)]
        pub fn defaultBehavior() -> Retained<ProtocolObject<dyn NSDecimalNumberBehaviors>>;

        /// Setter for [`defaultBehavior`][Self::defaultBehavior].
        #[unsafe(method(setDefaultBehavior:))]
        #[unsafe(method_family = none)]
        pub fn setDefaultBehavior(default_behavior: &ProtocolObject<dyn NSDecimalNumberBehaviors>);

        #[unsafe(method(objCType))]
        #[unsafe(method_family = none)]
        pub fn objCType(&self) -> NonNull<c_char>;

        #[unsafe(method(doubleValue))]
        #[unsafe(method_family = none)]
        pub fn doubleValue(&self) -> c_double;
    );
}

/// Methods declared on superclass `NSNumber`.
#[cfg(feature = "NSValue")]
impl NSDecimalNumber {
    extern_methods!(
        #[cfg(feature = "NSCoder")]
        /// # 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 `NSValue`.
#[cfg(feature = "NSValue")]
impl NSDecimalNumber {
    extern_methods!(
        /// # Safety
        ///
        /// - `value` must be a valid pointer.
        /// - `type` must be a valid pointer.
        #[unsafe(method(initWithBytes:objCType:))]
        #[unsafe(method_family = init)]
        pub unsafe fn initWithBytes_objCType(
            this: Allocated<Self>,
            value: NonNull<c_void>,
            r#type: NonNull<c_char>,
        ) -> Retained<Self>;
    );
}

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

#[cfg(feature = "NSValue")]
impl DefaultRetained for NSDecimalNumber {
    #[inline]
    fn default_retained() -> Retained<Self> {
        Self::new()
    }
}

extern_class!(
    /// *********    A class for defining common behaviors        ******
    ///
    /// See also [Apple's documentation](https://developer.apple.com/documentation/foundation/nsdecimalnumberhandler?language=objc)
    #[unsafe(super(NSObject))]
    #[derive(Debug, PartialEq, Eq, Hash)]
    pub struct NSDecimalNumberHandler;
);

unsafe impl Send for NSDecimalNumberHandler {}

unsafe impl Sync for NSDecimalNumberHandler {}

#[cfg(feature = "NSObject")]
extern_conformance!(
    unsafe impl NSCoding for NSDecimalNumberHandler {}
);

extern_conformance!(
    unsafe impl NSDecimalNumberBehaviors for NSDecimalNumberHandler {}
);

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

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

        #[cfg(feature = "NSDecimal")]
        #[unsafe(method(initWithRoundingMode:scale:raiseOnExactness:raiseOnOverflow:raiseOnUnderflow:raiseOnDivideByZero:))]
        #[unsafe(method_family = init)]
        pub fn initWithRoundingMode_scale_raiseOnExactness_raiseOnOverflow_raiseOnUnderflow_raiseOnDivideByZero(
            this: Allocated<Self>,
            rounding_mode: NSRoundingMode,
            scale: c_short,
            exact: bool,
            overflow: bool,
            underflow: bool,
            divide_by_zero: bool,
        ) -> Retained<Self>;

        #[cfg(feature = "NSDecimal")]
        #[unsafe(method(decimalNumberHandlerWithRoundingMode:scale:raiseOnExactness:raiseOnOverflow:raiseOnUnderflow:raiseOnDivideByZero:))]
        #[unsafe(method_family = none)]
        pub fn decimalNumberHandlerWithRoundingMode_scale_raiseOnExactness_raiseOnOverflow_raiseOnUnderflow_raiseOnDivideByZero(
            rounding_mode: NSRoundingMode,
            scale: c_short,
            exact: bool,
            overflow: bool,
            underflow: bool,
            divide_by_zero: bool,
        ) -> Retained<Self>;
    );
}

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

/// NSDecimalNumberExtensions.
///
/// *********    Extensions to other classes        ******
#[cfg(feature = "NSValue")]
impl NSNumber {
    extern_methods!(
        #[cfg(feature = "NSDecimal")]
        #[unsafe(method(decimalValue))]
        #[unsafe(method_family = none)]
        pub fn decimalValue(&self) -> NSDecimal;
    );
}

/// NSDecimalNumberScanning.
#[cfg(feature = "NSScanner")]
impl NSScanner {
    extern_methods!(
        #[cfg(feature = "NSDecimal")]
        /// # Safety
        ///
        /// `dcm` must be a valid pointer or null.
        #[unsafe(method(scanDecimal:))]
        #[unsafe(method_family = none)]
        pub unsafe fn scanDecimal(&self, dcm: *mut NSDecimal) -> bool;
    );
}
