//
//  TextStyle.swift
//  
//  Copyright © 2016-2019 Apple Inc. All rights reserved.
//

import UIKit
import PlaygroundSupport
import SPCCore

/// `TextStyle` is a struct for specifying the style of text such as its font, size, color and alignment.
///
/// For example, you can use a text style to set the appearance of text in a `Label`:
/// ```
/// let label = Label()
/// label.textStyle = TextStyle(.Copperplate, fontSize: 48, color: .orange)
/// ```
///
/// - localizationKey: TextStyle
public struct TextStyle {
    
    /// The name of the font.
    ///
    /// - localizationKey: TextStyle.fontName
    public var fontName: FontName
    
    /// The size of the text in points. The default is 16 points.
    ///
    /// - localizationKey: TextStyle.fontSize
    public var fontSize: Double
    
    /// The color of the text. The default is black.
    ///
    /// - localizationKey: TextStyle.color
    public var color: Color
    
    /// The horizontal alignment of the text. The default is centered.
    ///
    /// - localizationKey: TextStyle.alignment
    public var alignment: TextAlignment
    
    var font: UIFont? {
        return UIFont(name: fontName.rawValue, size: CGFloat(fontSize))
    }
   
    /// Creates a text style using the specified parameters.
    ///
    /// - Parameter fontName: The name of the font.
    /// - Parameter fontSize: The size of the font in points (optional).
    /// - Parameter color: The color of the text (optional).
    /// - Parameter alignment: The horizontal alignment of the text (optional).
    ///
    /// - localizationKey: TextStyle(_:fontSize:color:alignment:)
    public init(_ fontName: FontName, fontSize: Double = 16, color: Color = .black, alignment: TextAlignment = .center) {
        self.fontName = fontName
        self.fontSize = fontSize
        self.color = color
        self.alignment = alignment
    }
}

extension TextStyle: PlaygroundValueTransformable {
    
    public var playgroundValue: PlaygroundValue? {
        guard let colorValue = color.playgroundValue else { return nil }
        return .array([.string(fontName.rawValue),
                       .floatingPoint(fontSize),
                       colorValue,
                       .integer(alignment.rawValue)
            ])
    }
    
    public static func from(_ playgroundValue: PlaygroundValue) -> PlaygroundValueTransformable? {
        guard
            case .array(let components) = playgroundValue,
            components.count == 4,
            case .string(let fontNameRawValue) = components[0], let fontName = FontName(rawValue: fontNameRawValue),
            case .floatingPoint(let fontSize) = components[1],
            let color = Color.from(components[2]) as? Color,
            case .integer(let alignmentRawValue) = components[3], let textAlignment = TextAlignment(rawValue: alignmentRawValue)
            else { return nil }
        
        return TextStyle(fontName, fontSize: fontSize, color: color, alignment: textAlignment)
    }
    
}
