// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2016 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
//


extension MassFormatter {
    public enum Unit : Int {
        case gram
        case kilogram
        case ounce
        case pound
        case stone
    }
}
    
open class MassFormatter : Formatter {
    
    public override init() {
        numberFormatter = NumberFormatter()
        numberFormatter.numberStyle = .decimal
        unitStyle = .medium
        isForPersonMassUse = false
        super.init()
    }
    
    public required init?(coder: NSCoder) {
        numberFormatter = NumberFormatter()
        numberFormatter.numberStyle = .decimal
        unitStyle = .medium
        isForPersonMassUse = false
        super.init(coder:coder)
    }
    
    /*@NSCopying*/ open var numberFormatter: NumberFormatter! // default is NSNumberFormatter with NSNumberFormatterDecimalStyle
    open var unitStyle: UnitStyle // default is NSFormattingUnitStyleMedium
    
    open var isForPersonMassUse: Bool // default is NO; if it is set to YES, the number argument for -stringFromKilograms: and -unitStringFromKilograms: is considered as a person’s mass
    
    // Format a combination of a number and an unit to a localized string.
    open func string(fromValue value: Double, unit: Unit) -> String {
        // special case: stone shows fractional values in pounds
        if unit == .stone {
            let stone = value.rounded(.towardZero)
            let stoneString = singlePartString(fromValue: stone, unit: unit) // calling `string(fromValue: stone, unit: .stone)` would infinitely recur
            let pounds = abs(value.truncatingRemainder(dividingBy: 1.0)) * MassFormatter.poundsPerStone
            
            // if we don't have any fractional component, don't append anything
            if pounds == 0 {
                return stoneString
            } else {
                let poundsString = string(fromValue: pounds, unit: .pound)
                let separator = unitStyle == MassFormatter.UnitStyle.short ? " " : ", "
                
                return ("\(stoneString)\(separator)\(poundsString)")
            }
        }
        
        // normal case: kilograms and pounds
        return singlePartString(fromValue: value, unit: unit)
    }
    
    // Format a number in kilograms to a localized string with the locale-appropriate unit and an appropriate scale (e.g. 1.2kg = 2.64lb in the US locale).
    open func string(fromKilograms numberInKilograms: Double) -> String {
        //Convert to the locale-appropriate unit
        let unitFromKilograms = convertedUnit(fromKilograms: numberInKilograms)
        
        //Map the unit to UnitMass type for conversion later
        let unitMassFromKilograms = MassFormatter.unitMass[unitFromKilograms]!
        
        //Create a measurement object based on the value in kilograms
        let kilogramMeasurement = Measurement<UnitMass>(value:numberInKilograms, unit: .kilograms)
        
        //Convert the object to the locale-appropriate unit determined above
        let unitMeasurement = kilogramMeasurement.converted(to: unitMassFromKilograms)
        
        //Extract the number from the measurement
        let numberInUnit = unitMeasurement.value
        
        return string(fromValue: numberInUnit, unit: unitFromKilograms)
    }
    
    // Return a localized string of the given unit, and if the unit is singular or plural is based on the given number.
    open func unitString(fromValue value: Double, unit: Unit) -> String {
        if unitStyle == .short {
            return MassFormatter.shortSymbol[unit]!
        } else if unitStyle == .medium {
            return MassFormatter.mediumSymbol[unit]!
        } else if unit == .stone { // special case, see `unitStringDisplayedAdjacent(toValue:, unit:)`
            return MassFormatter.largeSingularSymbol[unit]!
        } else if value == 1.0 {
            return MassFormatter.largeSingularSymbol[unit]!
        } else {
            return MassFormatter.largePluralSymbol[unit]!
        }
    }
    
    // Return the locale-appropriate unit, the same unit used by -stringFromKilograms:.
    open func unitString(fromKilograms numberInKilograms: Double, usedUnit unitp: UnsafeMutablePointer<Unit>?) -> String {
        //Convert to the locale-appropriate unit
        let unitFromKilograms = convertedUnit(fromKilograms: numberInKilograms)
        unitp?.pointee = unitFromKilograms
        
        //Map the unit to UnitMass type for conversion later
        let unitMassFromKilograms = MassFormatter.unitMass[unitFromKilograms]!
        
        //Create a measurement object based on the value in kilograms
        let kilogramMeasurement = Measurement<UnitMass>(value:numberInKilograms, unit: .kilograms)
        
        //Convert the object to the locale-appropriate unit determined above
        let unitMeasurement = kilogramMeasurement.converted(to: unitMassFromKilograms)
        
        //Extract the number from the measurement
        let numberInUnit = unitMeasurement.value
        
        //Return the appropriate representation of the unit based on the selected unit style
        return unitString(fromValue: numberInUnit, unit: unitFromKilograms)
    }
    
    /// - Experiment: This is a draft API currently under consideration for official import into Foundation as a suitable alternative
    /// - Note: Since this API is under consideration it may be either removed or revised in the near future
    open override func objectValue(_ string: String) throws -> Any? { return nil }
    
    
    // MARK: - Private
    
    /// This method selects the appropriate unit based on the formatter’s locale,
    /// the magnitude of the value, and isForPersonMassUse property.
    ///
    /// - Parameter numberInKilograms: the magnitude in terms of kilograms
    /// - Returns: Returns the appropriate unit
    private func convertedUnit(fromKilograms numberInKilograms: Double) -> Unit {
        if numberFormatter.locale.usesMetricSystem {
            if numberInKilograms > 1.0 || numberInKilograms <= 0.0 {
                return .kilogram
            } else {
                return .gram
            }
        } else {
            let metricMeasurement = Measurement<UnitMass>(value:numberInKilograms, unit: .kilograms)
            let imperialMeasurement = metricMeasurement.converted(to: .pounds)
            let numberInPounds = imperialMeasurement.value
            
            if numberInPounds >= 1.0 || numberInPounds <= 0.0  {
                return .pound
            } else {
                return .ounce
            }
        }
    }
    
    /// Formats the given value and unit into a string containing one logical 
    /// value. This is intended for units like kilogram and pound where 
    /// fractional values are represented as a decimal instead of converted 
    /// values in another unit.
    ///
    /// - Parameter value: The mass's value in the given unit.
    /// - Parameter unit: The unit used in the resulting mass string.
    /// - Returns: A properly formatted mass string for the given value and unit.
    private func singlePartString(fromValue value: Double, unit: Unit) -> String {
        guard let formattedValue = numberFormatter.string(from:NSNumber(value: value)) else {
            fatalError("Cannot format \(value) as string")
        }
        
        let separator = unitStyle == MassFormatter.UnitStyle.short ? "" : " "
        
        return "\(formattedValue)\(separator)\(unitStringDisplayedAdjacent(toValue: value, unit: unit))"
    }
    
    /// Return the locale-appropriate unit to be shown adjacent to the given
    /// value.  In most cases this will match `unitStringDisplayedAdjacent(toValue:, unit:)` 
    /// however there are a few special cases:
    ///     - Imperial pounds with a short representation use "lb" in the
    ///       abstract and "#" only when shown with a numeral.
    ///     - Stones are are singular in the abstract and only plural when 
    ///       shown with a numeral.
    ///
    /// - Parameter value: The mass's value in the given unit.
    /// - Parameter unit: The unit used in the resulting mass string.
    /// - Returns: The locale-appropriate unit
    open func unitStringDisplayedAdjacent(toValue value: Double, unit: Unit) -> String {
        if unit == .pound && unitStyle == .short {
            return "#"
        } else if unit == .stone && unitStyle == .long {
            if value == 1.0 {
                return MassFormatter.largeSingularSymbol[unit]!
            } else {
                return MassFormatter.largePluralSymbol[unit]!
            }
        } else {
            return unitString(fromValue: value, unit: unit)
        }
    }
    

    
    /// The number of pounds in 1 stone
    private static let poundsPerStone = 14.0
    
    /// Maps MassFormatter.Unit enum to UnitMass class. Used for measurement conversion.
    private static let unitMass: [Unit: UnitMass] = [.gram: .grams,
                                                     .kilogram: .kilograms,
                                                     .ounce: .ounces,
                                                     .pound: .pounds,
                                                     .stone: .stones]
    
    /// Maps a unit to its short symbol. Reuses strings from UnitMass.
    private static let shortSymbol: [Unit: String] = [.gram: UnitMass.grams.symbol,
                                                      .kilogram: UnitMass.kilograms.symbol,
                                                      .ounce: UnitMass.ounces.symbol,
                                                      .pound: UnitMass.pounds.symbol, // see `unitStringDisplayedAdjacent(toValue:, unit:)`
                                                      .stone: UnitMass.stones.symbol]
    
    /// Maps a unit to its medium symbol. Reuses strings from UnitMass.
    private static let mediumSymbol: [Unit: String] = [.gram: UnitMass.grams.symbol,
                                                       .kilogram: UnitMass.kilograms.symbol,
                                                       .ounce: UnitMass.ounces.symbol,
                                                       .pound: UnitMass.pounds.symbol,
                                                       .stone: UnitMass.stones.symbol]
    
    /// Maps a unit to its large, singular symbol.
    private static let largeSingularSymbol: [Unit: String] = [.gram: "gram",
                                                              .kilogram: "kilogram",
                                                              .ounce: "ounce",
                                                              .pound: "pound",
                                                              .stone: "stone"]
    
    /// Maps a unit to its large, plural symbol.
    private static let largePluralSymbol: [Unit: String] = [.gram: "grams",
                                                            .kilogram: "kilograms",
                                                            .ounce: "ounces",
                                                            .pound: "pounds",
                                                            .stone: "stones"]
}
