//
//  NT+Speed.swift
//  NomadTools
//
//  Created by Justin Ackermann on 5/27/21.
//

import Foundation

// MARK: Actions
extension Nomad {
    /// Conversions
    static func howFast(is speed: Speed,
                        in unit: Speed.Unit) -> Speed {
        return speed.converted(to: unit)
    }
    
    /// Calculations
}

// MARK: Statements


// MARK: Speed
public class Speed {
    
    /// Variables
    private let originalValue: NSNumber
    private let originalUnit: Unit
    
    private var _value: NSNumber
    private var _unit: Unit
    
    public var value: Double
    { get { return _value.double }}
    
    public var unit: Unit
    { get { return _unit }}
    
    /// Quick Conversions
    
    /// Initialize
    init(is number: Int! = 0,
         in unit: Unit! = .mps)
    {
        _value = NSNumber(value: number)
        _unit = unit
        
        originalValue = _value
        originalUnit = _unit
    }
    
    init(is num: Double,
         in unit: Unit! = .mps)
    {
        _value = NSNumber(value: num)
        _unit = unit
        
        originalValue = _value
        originalUnit = _unit
    }
    
    /// Helpers
    private var baseline: Double
    { return _value.doubleValue / _unit.multiplier }
    
    func converted(to unit: Unit) -> Speed {
        let value = baseline * unit.multiplier
        _value = value.number
        _unit = unit
        return Speed(is: value.int, in: unit)
    }
    
    // TODO: More conversion, rounded etc
    func labeled(styled: UnitLabelStyle,
                 in unit: Unit? = nil,
                 whitespace: Bool! = true) -> String {
        let value = converted(to: unit ?? _unit)
        let num = value.value.int
        let unit = value.unit
        return "\(num)\(unit.label(with: styled, whitespace: whitespace))"
    }
    
    // MARK: Units
    public enum Unit: String, NomadUnit, Codable {
        
        // Imperial
        case fps
        case mph
        case kts
        
        case mach
        
        // Metric
        case mps
        case kph
        
        internal var multiplier: Double {
            switch self {
                
            // Imperial
            case .fps: return 3.2808
            case .mph: return 2.23694
            case .kts: return 1.94384
                
            case .mach: return 0.002915
                
            // Metric
            case .mps: return 1
            case .kph: return 3.6
            }
        }
        
        internal var labels: UnitStyleLabels {
            var labels: (String, String, String) {
                switch self {
                    
                // Imperial
                case .fps: return ("fps", "ft/sec", "feet per second")
                case .mph: return ("mph", "mi/hr", "miles per hour")
                case .kts: return ("kts", "kts.", "knots")
                    
                case .mach: return ("mach", "mach", "speed of sound")
                    
                // Metric
                case .mps: return ("m/s", "m/s", "meters per second")
                case .kph: return ("kph", "km/hr", "kilometers per hour")
                }
            }
            return UnitStyleLabels(compact: labels.0,
                                   short: labels.1,
                                   full: labels.2)
        }
        
        public func label(with style: UnitLabelStyle,
                          whitespace: Bool! = true) -> String {
            var r: String
            switch style {
            case .compact,
                 .brief: r = labels.compact
            case .short: r = labels.short
            case .full: r = labels.full
            }
            return (whitespace ? " " : "") + r
        }
    }
}
