// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See http://swift.org/LICENSE.txt for license information
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//

import CoreFoundation

public class NSDateFormatter : NSFormatter {
    typealias CFType = CFDateFormatter
    private var __cfObject: CFType?
    private var _cfObject: CFType {
        guard let obj = __cfObject else {
            #if os(OSX) || os(iOS)
                let dateStyle = CFDateFormatterStyle(rawValue: CFIndex(self.dateStyle.rawValue))!
                let timeStyle = CFDateFormatterStyle(rawValue: CFIndex(self.timeStyle.rawValue))!
            #else
                let dateStyle = CFDateFormatterStyle(self.dateStyle.rawValue)
                let timeStyle = CFDateFormatterStyle(self.timeStyle.rawValue)
            #endif
            
            let obj = CFDateFormatterCreate(kCFAllocatorSystemDefault, locale._cfObject, dateStyle, timeStyle)
            _setFormatterAttributes(obj)
            if let dateFormat = _dateFormat {
                CFDateFormatterSetFormat(obj, dateFormat._cfObject)
            }
            __cfObject = obj
            return obj
        }
        return obj
    }

    public override init() {
        super.init()
    }

    public required init?(coder: NSCoder) {
        super.init(coder: coder)
    }

    public var formattingContext: NSFormattingContext = .Unknown // default is NSFormattingContextUnknown

    public func objectValue(string: String, range rangep: UnsafeMutablePointer<NSRange>) throws -> AnyObject? { NSUnimplemented() }

    public override func stringForObjectValue(obj: AnyObject) -> String? {
        guard let date = obj as? NSDate else { return nil }
        return stringFromDate(date)
    }

    public func stringFromDate(date: NSDate) -> String {
        return CFDateFormatterCreateStringWithDate(kCFAllocatorSystemDefault, _cfObject, date._cfObject)._swiftObject
    }

    public func dateFromString(string: String) -> NSDate? {
        var range = CFRange(location: 0, length: string.length)
        let date = withUnsafeMutablePointer(&range) { (rangep: UnsafeMutablePointer<CFRange>) -> NSDate? in
            guard let res = CFDateFormatterCreateDateFromString(kCFAllocatorSystemDefault, _cfObject, string._cfObject, rangep) else {
                return nil
            }
            return res._nsObject
        }
        return date
    }

    public class func localizedStringFromDate(date: NSDate, dateStyle dstyle: NSDateFormatterStyle, timeStyle tstyle: NSDateFormatterStyle) -> String {
        let df = NSDateFormatter()
        df.dateStyle = dstyle
        df.timeStyle = tstyle
        return df.stringForObjectValue(date)!
    }

    public class func dateFormatFromTemplate(tmplate: String, options opts: Int, locale: NSLocale?) -> String? {
        guard let res = CFDateFormatterCreateDateFormatFromTemplate(kCFAllocatorSystemDefault, tmplate._cfObject, CFOptionFlags(opts), locale?._cfObject) else {
            return nil
        }
        return res._swiftObject
    }

    public func setLocalizedDateFormatFromTemplate(dateFormatTemplate: String) {
        NSUnimplemented()
    }

    private func _reset() {
        __cfObject = nil
    }

    internal func _setFormatterAttributes(formatter: CFDateFormatter) {
        _setFormatterAttribute(formatter, attributeName: kCFDateFormatterIsLenient, value: lenient._cfObject)
        _setFormatterAttribute(formatter, attributeName: kCFDateFormatterTimeZone, value: timeZone?._cfObject)
        _setFormatterAttribute(formatter, attributeName: kCFDateFormatterCalendarName, value: _calendar?.calendarIdentifier._cfObject)
        _setFormatterAttribute(formatter, attributeName: kCFDateFormatterTwoDigitStartDate, value: _twoDigitStartDate?._cfObject)
        _setFormatterAttribute(formatter, attributeName: kCFDateFormatterDefaultDate, value: defaultDate?._cfObject)
        _setFormatterAttribute(formatter, attributeName: kCFDateFormatterCalendar, value: _calendar?._cfObject)
        _setFormatterAttribute(formatter, attributeName: kCFDateFormatterEraSymbols, value: _eraSymbols?._cfObject)
        _setFormatterAttribute(formatter, attributeName: kCFDateFormatterMonthSymbols, value: _monthSymbols?._cfObject)
        _setFormatterAttribute(formatter, attributeName: kCFDateFormatterShortMonthSymbols, value: _shortMonthSymbols?._cfObject)
        _setFormatterAttribute(formatter, attributeName: kCFDateFormatterWeekdaySymbols, value: _weekdaySymbols?._cfObject)
        _setFormatterAttribute(formatter, attributeName: kCFDateFormatterShortWeekdaySymbols, value: _shortWeekdaySymbols?._cfObject)
        _setFormatterAttribute(formatter, attributeName: kCFDateFormatterAMSymbol, value: _AMSymbol?._cfObject)
        _setFormatterAttribute(formatter, attributeName: kCFDateFormatterPMSymbol, value: _PMSymbol?._cfObject)
        _setFormatterAttribute(formatter, attributeName: kCFDateFormatterLongEraSymbols, value: _longEraSymbols?._cfObject)
        _setFormatterAttribute(formatter, attributeName: kCFDateFormatterVeryShortMonthSymbols, value: _veryShortMonthSymbols?._cfObject)
        _setFormatterAttribute(formatter, attributeName: kCFDateFormatterStandaloneMonthSymbols, value: _standaloneMonthSymbols?._cfObject)
        _setFormatterAttribute(formatter, attributeName: kCFDateFormatterShortStandaloneMonthSymbols, value: _shortStandaloneMonthSymbols?._cfObject)
        _setFormatterAttribute(formatter, attributeName: kCFDateFormatterVeryShortStandaloneMonthSymbols, value: _veryShortStandaloneMonthSymbols?._cfObject)
        _setFormatterAttribute(formatter, attributeName: kCFDateFormatterVeryShortWeekdaySymbols, value: _veryShortWeekdaySymbols?._cfObject)
        _setFormatterAttribute(formatter, attributeName: kCFDateFormatterStandaloneWeekdaySymbols, value: _standaloneWeekdaySymbols?._cfObject)
        _setFormatterAttribute(formatter, attributeName: kCFDateFormatterShortStandaloneWeekdaySymbols, value: _shortStandaloneWeekdaySymbols?._cfObject)
        _setFormatterAttribute(formatter, attributeName: kCFDateFormatterVeryShortStandaloneWeekdaySymbols, value: _veryShortStandaloneWeekdaySymbols?._cfObject)
        _setFormatterAttribute(formatter, attributeName: kCFDateFormatterQuarterSymbols, value: _quarterSymbols?._cfObject)
        _setFormatterAttribute(formatter, attributeName: kCFDateFormatterShortQuarterSymbols, value: _shortQuarterSymbols?._cfObject)
        _setFormatterAttribute(formatter, attributeName: kCFDateFormatterStandaloneQuarterSymbols, value: _standaloneQuarterSymbols?._cfObject)
        _setFormatterAttribute(formatter, attributeName: kCFDateFormatterShortStandaloneQuarterSymbols, value: _shortStandaloneQuarterSymbols?._cfObject)
        _setFormatterAttribute(formatter, attributeName: kCFDateFormatterGregorianStartDate, value: _gregorianStartDate?._cfObject)
    }

    internal func _setFormatterAttribute(formatter: CFDateFormatter, attributeName: CFString, value: AnyObject?) {
        if let value = value {
            CFDateFormatterSetProperty(formatter, attributeName, value)
        }
    }

    private var _dateFormat: String? { willSet { _reset() } }
    public var dateFormat: String! {
        get {
            guard let format = _dateFormat else {
                return __cfObject.map { CFDateFormatterGetFormat($0)._swiftObject } ?? ""
            }
            return format
        }
        set {
            _dateFormat = newValue
        }
    }

    public var dateStyle: NSDateFormatterStyle = .NoStyle { willSet { _dateFormat = nil; _reset() } }

    public var timeStyle: NSDateFormatterStyle = .NoStyle { willSet { _dateFormat = nil; _reset() } }

    /*@NSCopying*/ public var locale: NSLocale! = .currentLocale() { willSet { _reset() } }

    public var generatesCalendarDates = false { willSet { _reset() } }

    /*@NSCopying*/ public var timeZone: NSTimeZone! = .systemTimeZone() { willSet { _reset() } }

    /*@NSCopying*/ internal var _calendar: NSCalendar! { willSet { _reset() } }
    public var calendar: NSCalendar! {
        get {
            guard let calendar = _calendar else {
                return CFDateFormatterCopyProperty(_cfObject, kCFDateFormatterCalendar) as! NSCalendar
            }
            return calendar
        }
        set {
            _calendar = newValue
        }
    }

    public var lenient = false { willSet { _reset() } }

    /*@NSCopying*/ internal var _twoDigitStartDate: NSDate? { willSet { _reset() } }
    public var twoDigitStartDate: NSDate? {
        get {
            guard let startDate = _twoDigitStartDate else {
                return CFDateFormatterCopyProperty(_cfObject, kCFDateFormatterTwoDigitStartDate) as? NSDate
            }
            return startDate
        }
        set {
            _twoDigitStartDate = newValue
        }
    }

    /*@NSCopying*/ public var defaultDate: NSDate? { willSet { _reset() } }
    
    internal var _eraSymbols: [String]! { willSet { _reset() } }
    public var eraSymbols: [String]! {
        get {
            guard let symbols = _eraSymbols else {
                let cfSymbols = CFDateFormatterCopyProperty(_cfObject, kCFDateFormatterEraSymbols) as! NSArray
                return cfSymbols.bridge().map { ($0 as! NSString).bridge() }
            }
            return symbols
        }
        set {
            _eraSymbols = newValue
        }
    }
    
    internal var _monthSymbols: [String]! { willSet { _reset() } }
    public var monthSymbols: [String]! {
        get {
            guard let symbols = _monthSymbols else {
                let cfSymbols = CFDateFormatterCopyProperty(_cfObject, kCFDateFormatterMonthSymbols) as! NSArray
                return cfSymbols.bridge().map { ($0 as! NSString).bridge() }
            }
            return symbols
        }
        set {
            _monthSymbols = newValue
        }
    }

    internal var _shortMonthSymbols: [String]! { willSet { _reset() } }
    public var shortMonthSymbols: [String]! {
        get {
            guard let symbols = _shortMonthSymbols else {
                let cfSymbols = CFDateFormatterCopyProperty(_cfObject, kCFDateFormatterShortMonthSymbols) as! NSArray
                return cfSymbols.bridge().map { ($0 as! NSString).bridge() }
            }
            return symbols
        }
        set {
            _shortMonthSymbols = newValue
        }
    }
    

    internal var _weekdaySymbols: [String]! { willSet { _reset() } }
    public var weekdaySymbols: [String]! {
        get {
            guard let symbols = _weekdaySymbols else {
                let cfSymbols = CFDateFormatterCopyProperty(_cfObject, kCFDateFormatterWeekdaySymbols) as! NSArray
                return cfSymbols.bridge().map { ($0 as! NSString).bridge() }
            }
            return symbols
        }
        set {
            _weekdaySymbols = newValue
        }
    }

    internal var _shortWeekdaySymbols: [String]! { willSet { _reset() } }
    public var shortWeekdaySymbols: [String]! {
        get {
            guard let symbols = _shortWeekdaySymbols else {
                let cfSymbols = CFDateFormatterCopyProperty(_cfObject, kCFDateFormatterShortWeekdaySymbols) as! NSArray
                return cfSymbols.bridge().map { ($0 as! NSString).bridge() }
            }
            return symbols
        }
        set {
            _shortWeekdaySymbols = newValue
        }
    }

    internal var _AMSymbol: String! { willSet { _reset() } }
    public var AMSymbol: String! {
        get {
            guard let symbol = _AMSymbol else {
                return (CFDateFormatterCopyProperty(_cfObject, kCFDateFormatterAMSymbol) as! NSString)._swiftObject
            }
            return symbol
        }
        set {
            _AMSymbol = newValue
        }
    }

    internal var _PMSymbol: String! { willSet { _reset() } }
    public var PMSymbol: String! {
        get {
            guard let symbol = _PMSymbol else {
                return (CFDateFormatterCopyProperty(_cfObject, kCFDateFormatterPMSymbol) as! NSString)._swiftObject
            }
            return symbol
        }
        set {
            _PMSymbol = newValue
        }
    }

    internal var _longEraSymbols: [String]! { willSet { _reset() } }
    public var longEraSymbols: [String]! {
        get {
            guard let symbols = _longEraSymbols else {
                let cfSymbols = CFDateFormatterCopyProperty(_cfObject, kCFDateFormatterLongEraSymbols) as! NSArray
                return cfSymbols.bridge().map { ($0 as! NSString).bridge() }
            }
            return symbols
        }
        set {
            _longEraSymbols = newValue
        }
    }

    internal var _veryShortMonthSymbols: [String]! { willSet { _reset() } }
    public var veryShortMonthSymbols: [String]! {
        get {
            guard let symbols = _veryShortMonthSymbols else {
                let cfSymbols = CFDateFormatterCopyProperty(_cfObject, kCFDateFormatterVeryShortMonthSymbols) as! NSArray
                return cfSymbols.bridge().map { ($0 as! NSString).bridge() }
            }
            return symbols
        }
        set {
            _veryShortMonthSymbols = newValue
        }
    }

    internal var _standaloneMonthSymbols: [String]! { willSet { _reset() } }
    public var standaloneMonthSymbols: [String]! {
        get {
            guard let symbols = _standaloneMonthSymbols else {
                let cfSymbols = CFDateFormatterCopyProperty(_cfObject, kCFDateFormatterStandaloneMonthSymbols) as! NSArray
                return cfSymbols.bridge().map { ($0 as! NSString).bridge() }
            }
            return symbols
        }
        set {
            _standaloneMonthSymbols = newValue
        }
    }

    internal var _shortStandaloneMonthSymbols: [String]! { willSet { _reset() } }
    public var shortStandaloneMonthSymbols: [String]! {
        get {
            guard let symbols = _shortStandaloneMonthSymbols else {
                let cfSymbols = CFDateFormatterCopyProperty(_cfObject, kCFDateFormatterShortStandaloneMonthSymbols) as! NSArray
                return cfSymbols.bridge().map { ($0 as! NSString).bridge() }
            }
            return symbols
        }
        set {
            _shortStandaloneMonthSymbols = newValue
        }
    }

    internal var _veryShortStandaloneMonthSymbols: [String]! { willSet { _reset() } }
    public var veryShortStandaloneMonthSymbols: [String]! {
        get {
            guard let symbols = _veryShortStandaloneMonthSymbols else {
                let cfSymbols = CFDateFormatterCopyProperty(_cfObject, kCFDateFormatterVeryShortStandaloneMonthSymbols) as! NSArray
                return cfSymbols.bridge().map { ($0 as! NSString).bridge() }
            }
            return symbols
        }
        set {
            _veryShortStandaloneMonthSymbols = newValue
        }
    }

    internal var _veryShortWeekdaySymbols: [String]! { willSet { _reset() } }
    public var veryShortWeekdaySymbols: [String]! {
        get {
            guard let symbols = _veryShortWeekdaySymbols else {
                let cfSymbols = CFDateFormatterCopyProperty(_cfObject, kCFDateFormatterVeryShortWeekdaySymbols) as! NSArray
                return cfSymbols.bridge().map { ($0 as! NSString).bridge() }
            }
            return symbols
        }
        set {
            _veryShortWeekdaySymbols = newValue
        }
    }

    internal var _standaloneWeekdaySymbols: [String]! { willSet { _reset() } }
    public var standaloneWeekdaySymbols: [String]! {
        get {
            guard let symbols = _standaloneWeekdaySymbols else {
                let cfSymbols = CFDateFormatterCopyProperty(_cfObject, kCFDateFormatterStandaloneWeekdaySymbols) as! NSArray
                return cfSymbols.bridge().map { ($0 as! NSString).bridge() }
            }
            return symbols
        }
        set {
            _standaloneWeekdaySymbols = newValue
        }
    }

    internal var _shortStandaloneWeekdaySymbols: [String]! { willSet { _reset() } }
    public var shortStandaloneWeekdaySymbols: [String]! {
        get {
            guard let symbols = _shortStandaloneWeekdaySymbols else {
                let cfSymbols = CFDateFormatterCopyProperty(_cfObject, kCFDateFormatterShortStandaloneWeekdaySymbols) as! NSArray
                return cfSymbols.bridge().map { ($0 as! NSString).bridge() }
            }
            return symbols
        }
        set {
            _shortStandaloneWeekdaySymbols = newValue
        }
    }
    
    internal var _veryShortStandaloneWeekdaySymbols: [String]! { willSet { _reset() } }
    public var veryShortStandaloneWeekdaySymbols: [String]! {
        get {
            guard let symbols = _veryShortStandaloneWeekdaySymbols else {
                let cfSymbols = CFDateFormatterCopyProperty(_cfObject, kCFDateFormatterVeryShortStandaloneWeekdaySymbols) as! NSArray
                return cfSymbols.bridge().map { ($0 as! NSString).bridge() }
            }
            return symbols
        }
        set {
            _veryShortStandaloneWeekdaySymbols = newValue
        }
    }

    internal var _quarterSymbols: [String]! { willSet { _reset() } }
    public var quarterSymbols: [String]! {
        get {
            guard let symbols = _quarterSymbols else {
                let cfSymbols = CFDateFormatterCopyProperty(_cfObject, kCFDateFormatterQuarterSymbols) as! NSArray
                return cfSymbols.bridge().map { ($0 as! NSString).bridge() }
            }
            return symbols
        }
        set {
            _quarterSymbols = newValue
        }
    }
    
    internal var _shortQuarterSymbols: [String]! { willSet { _reset() } }
    public var shortQuarterSymbols: [String]! {
        get {
            guard let symbols = _shortQuarterSymbols else {
                let cfSymbols = CFDateFormatterCopyProperty(_cfObject, kCFDateFormatterShortQuarterSymbols) as! NSArray
                return cfSymbols.bridge().map { ($0 as! NSString).bridge() }
            }
            return symbols
        }
        set {
            _shortQuarterSymbols = newValue
        }
    }

    internal var _standaloneQuarterSymbols: [String]! { willSet { _reset() } }
    public var standaloneQuarterSymbols: [String]! {
        get {
            guard let symbols = _standaloneQuarterSymbols else {
                let cfSymbols = CFDateFormatterCopyProperty(_cfObject, kCFDateFormatterStandaloneQuarterSymbols) as! NSArray
                return cfSymbols.bridge().map { ($0 as! NSString).bridge() }
            }
            return symbols
        }
        set {
            _standaloneQuarterSymbols = newValue
        }
    }

    internal var _shortStandaloneQuarterSymbols: [String]! { willSet { _reset() } }
    public var shortStandaloneQuarterSymbols: [String]! {
        get {
            guard let symbols = _shortStandaloneQuarterSymbols else {
                let cfSymbols = CFDateFormatterCopyProperty(_cfObject, kCFDateFormatterShortStandaloneQuarterSymbols) as! NSArray
                return cfSymbols.bridge().map { ($0 as! NSString).bridge() }
            }
            return symbols
        }
        set {
            _shortStandaloneQuarterSymbols = newValue
        }
    }

    internal var _gregorianStartDate: NSDate? { willSet { _reset() } }
    public var gregorianStartDate: NSDate? {
        get {
            guard let startDate = _gregorianStartDate else {
                return CFDateFormatterCopyProperty(_cfObject, kCFDateFormatterGregorianStartDate) as? NSDate
            }
            return startDate
        }
        set {
            _gregorianStartDate = newValue
        }
    }

    public var doesRelativeDateFormatting = false { willSet { _reset() } }
}

public enum NSDateFormatterStyle : UInt {
    case NoStyle
    case ShortStyle
    case MediumStyle
    case LongStyle
    case FullStyle
}
