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

/// [Apple's documentation](https://developer.apple.com/documentation/corefoundation/cftimeinterval?language=objc)
pub type CFTimeInterval = c_double;

/// [Apple's documentation](https://developer.apple.com/documentation/corefoundation/cfabsolutetime?language=objc)
pub type CFAbsoluteTime = CFTimeInterval;

#[inline]
pub extern "C-unwind" fn CFAbsoluteTimeGetCurrent() -> CFAbsoluteTime {
    extern "C-unwind" {
        fn CFAbsoluteTimeGetCurrent() -> CFAbsoluteTime;
    }
    unsafe { CFAbsoluteTimeGetCurrent() }
}

extern "C" {
    /// [Apple's documentation](https://developer.apple.com/documentation/corefoundation/kcfabsolutetimeintervalsince1970?language=objc)
    pub static kCFAbsoluteTimeIntervalSince1970: CFTimeInterval;
}

extern "C" {
    /// [Apple's documentation](https://developer.apple.com/documentation/corefoundation/kcfabsolutetimeintervalsince1904?language=objc)
    pub static kCFAbsoluteTimeIntervalSince1904: CFTimeInterval;
}

/// [Apple's documentation](https://developer.apple.com/documentation/corefoundation/cfdate?language=objc)
#[repr(C)]
pub struct CFDate {
    inner: [u8; 0],
    _p: UnsafeCell<PhantomData<(*const UnsafeCell<()>, PhantomPinned)>>,
}

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

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

impl CFDate {
    #[doc(alias = "CFDateCreate")]
    #[inline]
    pub fn new(allocator: Option<&CFAllocator>, at: CFAbsoluteTime) -> Option<CFRetained<CFDate>> {
        extern "C-unwind" {
            fn CFDateCreate(
                allocator: Option<&CFAllocator>,
                at: CFAbsoluteTime,
            ) -> Option<NonNull<CFDate>>;
        }
        let ret = unsafe { CFDateCreate(allocator, at) };
        ret.map(|ret| unsafe { CFRetained::from_raw(ret) })
    }

    #[doc(alias = "CFDateGetAbsoluteTime")]
    #[inline]
    pub fn absolute_time(self: &CFDate) -> CFAbsoluteTime {
        extern "C-unwind" {
            fn CFDateGetAbsoluteTime(the_date: &CFDate) -> CFAbsoluteTime;
        }
        unsafe { CFDateGetAbsoluteTime(self) }
    }

    #[doc(alias = "CFDateGetTimeIntervalSinceDate")]
    #[inline]
    pub fn time_interval_since_date(self: &CFDate, other_date: Option<&CFDate>) -> CFTimeInterval {
        extern "C-unwind" {
            fn CFDateGetTimeIntervalSinceDate(
                the_date: &CFDate,
                other_date: Option<&CFDate>,
            ) -> CFTimeInterval;
        }
        unsafe { CFDateGetTimeIntervalSinceDate(self, other_date) }
    }

    #[doc(alias = "CFDateCompare")]
    #[inline]
    pub unsafe fn compare(
        self: &CFDate,
        other_date: Option<&CFDate>,
        context: *mut c_void,
    ) -> CFComparisonResult {
        extern "C-unwind" {
            fn CFDateCompare(
                the_date: &CFDate,
                other_date: Option<&CFDate>,
                context: *mut c_void,
            ) -> CFComparisonResult;
        }
        unsafe { CFDateCompare(self, other_date, context) }
    }
}

/// [Apple's documentation](https://developer.apple.com/documentation/corefoundation/cftimezone?language=objc)
#[repr(C)]
pub struct CFTimeZone {
    inner: [u8; 0],
    _p: UnsafeCell<PhantomData<(*const UnsafeCell<()>, PhantomPinned)>>,
}

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

/// [Apple's documentation](https://developer.apple.com/documentation/corefoundation/cfgregoriandate?language=objc)
#[repr(C)]
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct CFGregorianDate {
    pub year: i32,
    pub month: i8,
    pub day: i8,
    pub hour: i8,
    pub minute: i8,
    pub second: c_double,
}

#[cfg(feature = "objc2")]
unsafe impl Encode for CFGregorianDate {
    const ENCODING: Encoding = Encoding::Struct(
        "?",
        &[
            <i32>::ENCODING,
            <i8>::ENCODING,
            <i8>::ENCODING,
            <i8>::ENCODING,
            <i8>::ENCODING,
            <c_double>::ENCODING,
        ],
    );
}

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

/// [Apple's documentation](https://developer.apple.com/documentation/corefoundation/cfgregorianunits?language=objc)
#[repr(C)]
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct CFGregorianUnits {
    pub years: i32,
    pub months: i32,
    pub days: i32,
    pub hours: i32,
    pub minutes: i32,
    pub seconds: c_double,
}

#[cfg(feature = "objc2")]
unsafe impl Encode for CFGregorianUnits {
    const ENCODING: Encoding = Encoding::Struct(
        "?",
        &[
            <i32>::ENCODING,
            <i32>::ENCODING,
            <i32>::ENCODING,
            <i32>::ENCODING,
            <i32>::ENCODING,
            <c_double>::ENCODING,
        ],
    );
}

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

/// [Apple's documentation](https://developer.apple.com/documentation/corefoundation/cfgregorianunitflags?language=objc)
// NS_OPTIONS
#[repr(transparent)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct CFGregorianUnitFlags(pub CFOptionFlags);
bitflags::bitflags! {
    impl CFGregorianUnitFlags: CFOptionFlags {
        #[doc(alias = "kCFGregorianUnitsYears")]
#[deprecated = "Use CFCalendar or NSCalendar API instead"]
        const UnitsYears = 1<<0;
        #[doc(alias = "kCFGregorianUnitsMonths")]
#[deprecated = "Use CFCalendar or NSCalendar API instead"]
        const UnitsMonths = 1<<1;
        #[doc(alias = "kCFGregorianUnitsDays")]
#[deprecated = "Use CFCalendar or NSCalendar API instead"]
        const UnitsDays = 1<<2;
        #[doc(alias = "kCFGregorianUnitsHours")]
#[deprecated = "Use CFCalendar or NSCalendar API instead"]
        const UnitsHours = 1<<3;
        #[doc(alias = "kCFGregorianUnitsMinutes")]
#[deprecated = "Use CFCalendar or NSCalendar API instead"]
        const UnitsMinutes = 1<<4;
        #[doc(alias = "kCFGregorianUnitsSeconds")]
#[deprecated = "Use CFCalendar or NSCalendar API instead"]
        const UnitsSeconds = 1<<5;
        #[doc(alias = "kCFGregorianAllUnits")]
#[deprecated = "Use CFCalendar or NSCalendar API instead"]
        const AllUnits = 0x00FFFFFF;
    }
}

#[cfg(feature = "objc2")]
unsafe impl Encode for CFGregorianUnitFlags {
    const ENCODING: Encoding = CFOptionFlags::ENCODING;
}

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

impl CFGregorianDate {
    #[doc(alias = "CFGregorianDateIsValid")]
    #[deprecated = "Use CFCalendar or NSCalendar API instead"]
    #[inline]
    pub unsafe fn is_valid(self: CFGregorianDate, unit_flags: CFOptionFlags) -> bool {
        extern "C-unwind" {
            fn CFGregorianDateIsValid(gdate: CFGregorianDate, unit_flags: CFOptionFlags)
                -> Boolean;
        }
        let ret = unsafe { CFGregorianDateIsValid(self, unit_flags) };
        ret != 0
    }

    #[doc(alias = "CFGregorianDateGetAbsoluteTime")]
    #[deprecated = "Use CFCalendar or NSCalendar API instead"]
    #[inline]
    pub unsafe fn absolute_time(self: CFGregorianDate, tz: Option<&CFTimeZone>) -> CFAbsoluteTime {
        extern "C-unwind" {
            fn CFGregorianDateGetAbsoluteTime(
                gdate: CFGregorianDate,
                tz: Option<&CFTimeZone>,
            ) -> CFAbsoluteTime;
        }
        unsafe { CFGregorianDateGetAbsoluteTime(self, tz) }
    }
}

extern "C-unwind" {
    #[deprecated = "Use CFCalendar or NSCalendar API instead"]
    pub fn CFAbsoluteTimeGetGregorianDate(
        at: CFAbsoluteTime,
        tz: Option<&CFTimeZone>,
    ) -> CFGregorianDate;
}

extern "C-unwind" {
    #[deprecated = "Use CFCalendar or NSCalendar API instead"]
    pub fn CFAbsoluteTimeAddGregorianUnits(
        at: CFAbsoluteTime,
        tz: Option<&CFTimeZone>,
        units: CFGregorianUnits,
    ) -> CFAbsoluteTime;
}

extern "C-unwind" {
    #[deprecated = "Use CFCalendar or NSCalendar API instead"]
    pub fn CFAbsoluteTimeGetDifferenceAsGregorianUnits(
        at1: CFAbsoluteTime,
        at2: CFAbsoluteTime,
        tz: Option<&CFTimeZone>,
        unit_flags: CFOptionFlags,
    ) -> CFGregorianUnits;
}

extern "C-unwind" {
    #[deprecated = "Use CFCalendar or NSCalendar API instead"]
    pub fn CFAbsoluteTimeGetDayOfWeek(at: CFAbsoluteTime, tz: Option<&CFTimeZone>) -> i32;
}

extern "C-unwind" {
    #[deprecated = "Use CFCalendar or NSCalendar API instead"]
    pub fn CFAbsoluteTimeGetDayOfYear(at: CFAbsoluteTime, tz: Option<&CFTimeZone>) -> i32;
}

extern "C-unwind" {
    #[deprecated = "Use CFCalendar or NSCalendar API instead"]
    pub fn CFAbsoluteTimeGetWeekOfYear(at: CFAbsoluteTime, tz: Option<&CFTimeZone>) -> i32;
}

#[deprecated = "renamed to `CFDate::new`"]
#[inline]
pub extern "C-unwind" fn CFDateCreate(
    allocator: Option<&CFAllocator>,
    at: CFAbsoluteTime,
) -> Option<CFRetained<CFDate>> {
    extern "C-unwind" {
        fn CFDateCreate(
            allocator: Option<&CFAllocator>,
            at: CFAbsoluteTime,
        ) -> Option<NonNull<CFDate>>;
    }
    let ret = unsafe { CFDateCreate(allocator, at) };
    ret.map(|ret| unsafe { CFRetained::from_raw(ret) })
}

#[deprecated = "renamed to `CFDate::absolute_time`"]
#[inline]
pub extern "C-unwind" fn CFDateGetAbsoluteTime(the_date: &CFDate) -> CFAbsoluteTime {
    extern "C-unwind" {
        fn CFDateGetAbsoluteTime(the_date: &CFDate) -> CFAbsoluteTime;
    }
    unsafe { CFDateGetAbsoluteTime(the_date) }
}

#[deprecated = "renamed to `CFDate::time_interval_since_date`"]
#[inline]
pub extern "C-unwind" fn CFDateGetTimeIntervalSinceDate(
    the_date: &CFDate,
    other_date: Option<&CFDate>,
) -> CFTimeInterval {
    extern "C-unwind" {
        fn CFDateGetTimeIntervalSinceDate(
            the_date: &CFDate,
            other_date: Option<&CFDate>,
        ) -> CFTimeInterval;
    }
    unsafe { CFDateGetTimeIntervalSinceDate(the_date, other_date) }
}

extern "C-unwind" {
    #[deprecated = "renamed to `CFDate::compare`"]
    pub fn CFDateCompare(
        the_date: &CFDate,
        other_date: Option<&CFDate>,
        context: *mut c_void,
    ) -> CFComparisonResult;
}

#[deprecated = "renamed to `CFGregorianDate::is_valid`"]
#[inline]
pub unsafe extern "C-unwind" fn CFGregorianDateIsValid(
    gdate: CFGregorianDate,
    unit_flags: CFOptionFlags,
) -> bool {
    extern "C-unwind" {
        fn CFGregorianDateIsValid(gdate: CFGregorianDate, unit_flags: CFOptionFlags) -> Boolean;
    }
    let ret = unsafe { CFGregorianDateIsValid(gdate, unit_flags) };
    ret != 0
}

extern "C-unwind" {
    #[deprecated = "renamed to `CFGregorianDate::absolute_time`"]
    pub fn CFGregorianDateGetAbsoluteTime(
        gdate: CFGregorianDate,
        tz: Option<&CFTimeZone>,
    ) -> CFAbsoluteTime;
}
