//
//  StatusFormat.swift
//  ComposeUI
//
//  Created by Shadowfacts on 1/12/19.
//  Copyright © 2019 Shadowfacts. All rights reserved.
//

import UIKit
import Pachyderm

enum StatusFormat: Int, CaseIterable {
    case bold, italics, strikethrough, code
    
    func insertionResult(for contentType: StatusContentType) -> FormatInsertionResult? {
        switch contentType {
        case .plain:
            return nil
        case .markdown:
            return Markdown.format(self)
        case .html:
            return HTML.format(self)
        }
    }
    
    var imageName: String? {
        switch self {
        case .italics:
            return "italic"
        case .bold:
            return "bold"
        case .strikethrough:
            return "strikethrough"
        default:
            return nil
        }
    }
    
    var title: (String, [NSAttributedString.Key: Any])? {
        if self == .code {
            return ("</>", [.font: UIFont(name: "Menlo", size: 17)!])
        } else {
            return nil
        }
    }
    
    var accessibilityLabel: String {
        switch self {
        case .italics:
            return NSLocalizedString("Italics", comment: "italics text format accessibility label")
        case .bold:
            return NSLocalizedString("Bold", comment: "bold text format accessibility label")
        case .strikethrough:
            return NSLocalizedString("Strikethrough", comment: "strikethrough text format accessibility label")
        case .code:
            return NSLocalizedString("Code", comment: "code text format accessibility label")
        }
    }
}

typealias FormatInsertionResult = (prefix: String, suffix: String, insertionPoint: Int)

fileprivate protocol FormatType {
    static func format(_ format: StatusFormat) -> FormatInsertionResult
}

extension StatusFormat {
    struct Markdown: FormatType {
        static var formats: [StatusFormat: String] = [
            .italics: "_",
            .bold: "**",
            .strikethrough: "~~",
            .code: "`"
        ]
        
        static func format(_ format: StatusFormat) -> FormatInsertionResult {
            let str = formats[format]!
            return (str, str, str.count)
        }
    }
    
    struct HTML: FormatType {
        static var tags: [StatusFormat: String] = [
            .italics: "em",
            .bold: "strong",
            .strikethrough: "del",
            .code: "code"
        ]
        
        static func format(_ format: StatusFormat) -> FormatInsertionResult {
            let tag = tags[format]!
            return ("<\(tag)>", "</\(tag)>", tag.count + 2)
        }
    }
}
