pub use core_foundation_sys::timezone::*;
use core_foundation_sys::base::kCFAllocatorDefault;
use base::TCFType;
use date::{CFDate, CFTimeInterval};
use string::CFString;
#[cfg(feature = "with-chrono")]
use chrono::{FixedOffset, NaiveDateTime};
declare_TCFType!{
    CFTimeZone, CFTimeZoneRef
}
impl_TCFType!(CFTimeZone, CFTimeZoneRef, CFTimeZoneGetTypeID);
impl_CFTypeDescription!(CFTimeZone);
impl Default for CFTimeZone {
    fn default() -> CFTimeZone {
        unsafe {
            let tz_ref = CFTimeZoneCopyDefault();
            TCFType::wrap_under_create_rule(tz_ref)
        }
    }
}
impl CFTimeZone {
    #[inline]
    pub fn new(interval: CFTimeInterval) -> CFTimeZone {
        unsafe {
            let tz_ref = CFTimeZoneCreateWithTimeIntervalFromGMT(kCFAllocatorDefault, interval);
            TCFType::wrap_under_create_rule(tz_ref)
        }
    }
    #[inline]
    pub fn system() -> CFTimeZone {
        unsafe {
            let tz_ref = CFTimeZoneCopySystem();
            TCFType::wrap_under_create_rule(tz_ref)
        }
    }
    pub fn seconds_from_gmt(&self, date: CFDate) -> CFTimeInterval {
        unsafe {
            CFTimeZoneGetSecondsFromGMT(self.0, date.abs_time())
        }
    }
    #[cfg(feature = "with-chrono")]
    pub fn offset_at_date(&self, date: NaiveDateTime) -> FixedOffset {
        let date = CFDate::from_naive_utc(date);
        FixedOffset::east(self.seconds_from_gmt(date) as i32)
    }
    #[cfg(feature = "with-chrono")]
    pub fn from_offset(offset: FixedOffset) -> CFTimeZone {
        CFTimeZone::new(offset.local_minus_utc() as f64)
    }
    pub fn name(&self) -> CFString {
        unsafe {
            CFString::wrap_under_get_rule(CFTimeZoneGetName(self.0))
        }
    }
}
#[cfg(test)]
mod test {
    use super::CFTimeZone;
    #[cfg(feature = "with-chrono")]
    use chrono::{NaiveDateTime, FixedOffset};
    #[test]
    fn timezone_comparison() {
        let system = CFTimeZone::system();
        let default = CFTimeZone::default();
        assert_eq!(system, default);
    }
    #[test]
    #[cfg(feature = "with-chrono")]
    fn timezone_chrono_conversion() {
        let offset = FixedOffset::west(28800);
        let tz = CFTimeZone::from_offset(offset);
        let converted = tz.offset_at_date(NaiveDateTime::from_timestamp(0, 0));
        assert_eq!(offset, converted);
    }
}