//! This file has been automatically generated by `objc2`'s `header-translator`.
//! DO NOT EDIT
use core::cell::UnsafeCell;
use core::ffi::*;
use core::marker::{PhantomData, PhantomPinned};
use core::ptr::NonNull;
#[cfg(feature = "objc2")]
use objc2::__framework_prelude::*;
use objc2_core_foundation::*;

use crate::*;

/// [Apple's documentation](https://developer.apple.com/documentation/coregraphics/cgfunction?language=objc)
#[doc(alias = "CGFunctionRef")]
#[repr(C)]
pub struct CGFunction {
    inner: [u8; 0],
    _p: UnsafeCell<PhantomData<(*const UnsafeCell<()>, PhantomPinned)>>,
}

cf_type!(
    unsafe impl CGFunction {}
);
#[cfg(feature = "objc2")]
cf_objc2_type!(
    unsafe impl RefEncode<"CGFunction"> for CGFunction {}
);

/// [Apple's documentation](https://developer.apple.com/documentation/coregraphics/cgfunctionevaluatecallback?language=objc)
pub type CGFunctionEvaluateCallback =
    Option<unsafe extern "C-unwind" fn(*mut c_void, NonNull<CGFloat>, NonNull<CGFloat>)>;

/// [Apple's documentation](https://developer.apple.com/documentation/coregraphics/cgfunctionreleaseinfocallback?language=objc)
pub type CGFunctionReleaseInfoCallback = Option<unsafe extern "C-unwind" fn(*mut c_void)>;

/// [Apple's documentation](https://developer.apple.com/documentation/coregraphics/cgfunctioncallbacks?language=objc)
#[repr(C)]
#[allow(unpredictable_function_pointer_comparisons)]
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct CGFunctionCallbacks {
    pub version: c_uint,
    pub evaluate: CGFunctionEvaluateCallback,
    pub releaseInfo: CGFunctionReleaseInfoCallback,
}

#[cfg(feature = "objc2")]
unsafe impl Encode for CGFunctionCallbacks {
    const ENCODING: Encoding = Encoding::Struct(
        "CGFunctionCallbacks",
        &[
            <c_uint>::ENCODING,
            <CGFunctionEvaluateCallback>::ENCODING,
            <CGFunctionReleaseInfoCallback>::ENCODING,
        ],
    );
}

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

unsafe impl ConcreteType for CGFunction {
    #[doc(alias = "CGFunctionGetTypeID")]
    #[inline]
    fn type_id() -> CFTypeID {
        extern "C-unwind" {
            fn CGFunctionGetTypeID() -> CFTypeID;
        }
        unsafe { CGFunctionGetTypeID() }
    }
}

impl CGFunction {
    /// # Safety
    ///
    /// - `info` must be a valid pointer or null.
    /// - `domain` must be a valid pointer or null.
    /// - `range` must be a valid pointer or null.
    /// - `callbacks` must be a valid pointer or null.
    #[doc(alias = "CGFunctionCreate")]
    #[inline]
    pub unsafe fn new(
        info: *mut c_void,
        domain_dimension: usize,
        domain: *const CGFloat,
        range_dimension: usize,
        range: *const CGFloat,
        callbacks: *const CGFunctionCallbacks,
    ) -> Option<CFRetained<CGFunction>> {
        extern "C-unwind" {
            fn CGFunctionCreate(
                info: *mut c_void,
                domain_dimension: usize,
                domain: *const CGFloat,
                range_dimension: usize,
                range: *const CGFloat,
                callbacks: *const CGFunctionCallbacks,
            ) -> Option<NonNull<CGFunction>>;
        }
        let ret = unsafe {
            CGFunctionCreate(
                info,
                domain_dimension,
                domain,
                range_dimension,
                range,
                callbacks,
            )
        };
        ret.map(|ret| unsafe { CFRetained::from_raw(ret) })
    }
}

#[deprecated = "renamed to `CGFunction::new`"]
#[inline]
pub unsafe extern "C-unwind" fn CGFunctionCreate(
    info: *mut c_void,
    domain_dimension: usize,
    domain: *const CGFloat,
    range_dimension: usize,
    range: *const CGFloat,
    callbacks: *const CGFunctionCallbacks,
) -> Option<CFRetained<CGFunction>> {
    extern "C-unwind" {
        fn CGFunctionCreate(
            info: *mut c_void,
            domain_dimension: usize,
            domain: *const CGFloat,
            range_dimension: usize,
            range: *const CGFloat,
            callbacks: *const CGFunctionCallbacks,
        ) -> Option<NonNull<CGFunction>>;
    }
    let ret = unsafe {
        CGFunctionCreate(
            info,
            domain_dimension,
            domain,
            range_dimension,
            range,
            callbacks,
        )
    };
    ret.map(|ret| unsafe { CFRetained::from_raw(ret) })
}
