//
//  LabelAttributeUnderlineModel.swift
//  MVMCoreUI
//
//  Created by Ryan on 11/21/19.
//  Copyright © 2019 Verizon Wireless. All rights reserved.
//

import UIKit


@objcMembers public class LabelAttributeUnderlineModel: LabelAttributeModel {
    //--------------------------------------------------
    // MARK: - Properties
    //--------------------------------------------------
    
    override public class var identifier: String { "underline" }
    
    /// This returns the NSUnderlineStyle used in NSAttributedValue. If there is a pattern, it will return
    /// a new NSUnderlineStyle derived from the bitmask of style | pattern.
    var underlineValue: NSUnderlineStyle {
        
        if let pattern = pattern?.value() {
            return NSUnderlineStyle(rawValue: style.value() | pattern)
        } else {
            return NSUnderlineStyle(rawValue: style.value())
        }
    }
    
    var color: Color?
    var style: UnderlineStyle = .single
    var pattern: UnderlineStyle.Pattern?
    
    //--------------------------------------------------
    // MARK: - Keys
    //--------------------------------------------------
    
    private enum CodingKeys: String, CodingKey {
        case color
        case style
        case pattern
    }
    
    required public init(from decoder: Decoder) throws {
        let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
        
        if let color = try typeContainer.decodeIfPresent(Color.self, forKey: .color) {
            self.color = color
        }
        
        if let style = try typeContainer.decodeIfPresent(UnderlineStyle.self, forKey: .style) {
            self.style = style
        }
        
        if let pattern = try typeContainer.decodeIfPresent(UnderlineStyle.Pattern.self, forKey: .pattern) {
            self.pattern = pattern
        }
        
        try super.init(from: decoder)
    }
    
    public override func encode(to encoder: Encoder) throws {
        try super.encode(to: encoder)
        var container = encoder.container(keyedBy: CodingKeys.self)
        try container.encodeIfPresent(color, forKey: .color)
        try container.encode(style, forKey: .style)
        try container.encodeIfPresent(pattern, forKey: .pattern)
    }
}

public enum UnderlineStyle: String, Codable {
    case none
    case single
    case thick
    case double
    
    func value() -> Int {
        switch self {
        case .none:
            return 0
            
        case .single:
            return NSUnderlineStyle.single.rawValue
            
        case .thick:
            return NSUnderlineStyle.thick.rawValue
            
        case .double:
            return NSUnderlineStyle.double.rawValue
        }
    }
    
    public enum Pattern: String, Codable {
        case dot
        case dash
        case dashDot
        case dashDotDot
        case byWord
        
        func value() -> Int {
            switch self {
            case .dot:
                return NSUnderlineStyle.patternDot.rawValue
                
            case .dash:
                return NSUnderlineStyle.patternDash.rawValue
                
            case .dashDot:
                return NSUnderlineStyle.patternDashDot.rawValue
                
            case .dashDotDot:
                return NSUnderlineStyle.patternDashDotDot.rawValue
                
            case .byWord:
                return NSUnderlineStyle.byWord.rawValue
            }
        }
    }
}
