//
//  WheelModel.swift
//  MVMCoreUI
//
//  Created by Scott Pfeil on 1/13/20.
//  Copyright © 2020 Verizon Wireless. All rights reserved.
//

import UIKit

public enum GraphSize: String, Codable {
    case small, medium, large
}

public enum GraphStyle: String, Codable {
    case unlimited, safetyMode
}

public class WheelModel: MoleculeModelProtocol {
    
    public static var identifier: String = "wheel"
    public var style: GraphStyle = .unlimited {
        didSet {
            updateStyle()
        }
    }
    
    public var size: GraphSize = .small {
        didSet {
            updateSize()
        }
    }
    public var diameter: CGFloat = 24
    public var lineWidth: CGFloat = 5
    public var clockwise: Bool = true
    public var duration : Double = 1.0
    public var colors = [Color]()
    public var backgroundColor: Color?
    
    public init() {
        updateStyle()
        updateSize()
    }
    
    private enum CodingKeys: String, CodingKey {
        case style
        case size
        case diameter
        case lineWidth
        case clockwise
        case duration
        case colors
        case backgroundColor
        case moleculeName
    }
    
    required public init(from decoder: Decoder) throws {
        let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
        if let style = try typeContainer.decodeIfPresent(GraphStyle.self, forKey: .style) {
            self.style = style
        }
        updateStyle()
        if let size = try typeContainer.decodeIfPresent(GraphSize.self, forKey: .size) {
            self.size = size
        }
        updateSize()
        if let diameter = try typeContainer.decodeIfPresent(CGFloat.self, forKey: .diameter) {
            self.diameter = diameter
        }
        if let lineWidth = try typeContainer.decodeIfPresent(CGFloat.self, forKey: .lineWidth) {
            self.lineWidth = lineWidth
        }
        if let clockwise = try typeContainer.decodeIfPresent(Bool.self, forKey: .clockwise) {
            self.clockwise = clockwise
        }
        if let duration = try typeContainer.decodeIfPresent(Double.self, forKey: .duration) {
            self.duration = duration
        }
        if let colors = try typeContainer.decodeIfPresent([Color].self, forKey: .colors) {
            self.colors = colors
        }
        backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor)
    }
              
    public func encode(to encoder: Encoder) throws {
        var container = encoder.container(keyedBy: CodingKeys.self)
        try container.encode(moleculeName, forKey: .moleculeName)
        try container.encode(style, forKey: .style)
        try container.encode(size, forKey: .size)
        try container.encode(diameter, forKey: .diameter)
        try container.encode(lineWidth, forKey: .lineWidth)
        try container.encode(clockwise, forKey: .clockwise)
        try container.encode(duration, forKey: .duration)
        try container.encode(colors, forKey: .colors)
        try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor)
    }
    
    func getCGColorsFromArray(_ colorArray: [String]) -> [Color] {
        return colorArray.map { (colorString) -> Color in
            return Color(uiColor: UIColor.mfGet(forHex: colorString))
        }
    }
    
    func updateStyle() {
        switch style {
        case .unlimited:
            duration = 1.0
            clockwise = true
            //current style, only the end part shows darker look
            colors = getCGColorsFromArray(["#007AB8","#007AB8","#033554"])
            break
        case .safetyMode:
            duration = 1.5
            clockwise = true
            colors = getCGColorsFromArray(["#CC4D0F","#CC4D0F","AB0309"])
            break
        }
    }
    
    func updateSize() {
        switch size {
        case .small:
            diameter = MFSizeObject(standardSize: 20)?.getValueBasedOnApplicationWidth() ?? 20
            lineWidth = MFSizeObject(standardSize: 4)?.getValueBasedOnApplicationWidth() ?? 4
            break
        case .medium:
            diameter = MFSizeObject(standardSize: 100)?.getValueBasedOnApplicationWidth() ?? 100
            lineWidth = MFSizeObject(standardSize: 8)?.getValueBasedOnApplicationWidth() ?? 8
            break
        case .large:
            diameter = MFSizeObject(standardSize: 180)?.getValueBasedOnApplicationWidth() ?? 180
            lineWidth = MFSizeObject(standardSize: 12)?.getValueBasedOnApplicationWidth() ?? 12
            break
        }
    }
}
