
import Foundation
import UIKit
import RNCryptor

extension String {
    func contains(find: String) -> Bool{
        return self.range(of: find) != nil
    }
    func containsIgnoringCase(find: String) -> Bool{
        return self.range(of: find, options: .caseInsensitive) != nil
    }
    var isEmail: Bool {
        let emailRegEx = "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,20}"
        let emailTest  = NSPredicate(format:"SELF MATCHES %@", emailRegEx)
        return emailTest.evaluate(with: self)
    }
    var isPW: Bool {
        let pwRegEx = "^[a-zA-Z0-9!@.#$%^&*?_~]{4,16}$"
        let pwTest  = NSPredicate(format:"SELF MATCHES %@", pwRegEx)
        return pwTest.evaluate(with: self)
    }
    
    var hangul: String {
        get {
            let hangle = [
                ["ㄱ","ㄲ","ㄴ","ㄷ","ㄸ","ㄹ","ㅁ","ㅂ","ㅃ","ㅅ","ㅆ","ㅇ","ㅈ","ㅉ","ㅊ","ㅋ","ㅌ","ㅍ","ㅎ"],
                ["ㅏ","ㅐ","ㅑ","ㅒ","ㅓ","ㅔ","ㅕ","ㅖ","ㅗ","ㅘ","ㅙ","ㅚ","ㅛ","ㅜ","ㅝ","ㅞ","ㅟ","ㅠ","ㅡ","ㅢ","ㅣ"],
                ["","ㄱ","ㄲ","ㄳ","ㄴ","ㄵ","ㄶ","ㄷ","ㄹ","ㄺ","ㄻ","ㄼ","ㄽ","ㄾ","ㄿ","ㅀ","ㅁ","ㅂ","ㅄ","ㅅ","ㅆ","ㅇ","ㅈ","ㅊ","ㅋ","ㅌ","ㅍ","ㅎ"]
            ]
            
            return characters.reduce("") { result, char in
                if case let code = Int(String(char).unicodeScalars.reduce(0){$0 + $1.value}) - 44032{
                    if code > -1 && code < 11172{
                        let cho = code / 21 / 28, jung = code % (21 * 28) / 28, jong = code % 28;
                        return result + hangle[0][cho] + hangle[1][jung] + hangle[2][jong]
                    }
                }
                return result + String(char)
            }
        }
    }
    
    var localized: String {
        return NSLocalizedString(self, tableName: nil, bundle: Bundle.main, value: "", comment: "")
    }
    
}

extension String {
    var delComma: String {
        let number = Double(self)
        
        let formatter:NumberFormatter = NumberFormatter()
        formatter.numberStyle = .decimal
        formatter.groupingSeparator = ","
        let commoaString = formatter.string(for: number)
        return commoaString ?? "0"
    }
}

extension String {
    func fromDate(format:String) -> Date? {
        let formmater:DateFormatter = {
            let formatter = DateFormatter()
            formatter.locale = Locale.current
            formatter.dateFormat = format
            return formatter
        }()
        return formmater.date(from: self)
    }
}

extension String{
    
    func encryptWithKey(key:String) -> String? {
        guard let data = self.data(using: .utf8) else{ return nil }
        let encData = RNCryptor.encrypt(data: data, withPassword: key)
        return encData.base64EncodedString()
    }
    
    func decryptWithKey(key:String) -> String? {
        guard let data = Data(base64Encoded: self) else{ return nil }
        do{
            let decData = try RNCryptor.decrypt(data: data, withPassword: key)
            return String(data: decData, encoding: .utf8)
        }catch{
            print(error)
        }
        
        return nil
    }
}

extension String {
    subscript(value: NSRange) -> Substring {
        return self[value.lowerBound..<value.upperBound]
    }
}

extension String {
    subscript(value: CountableClosedRange<Int>) -> Substring {
        get {
            return self[index(at: value.lowerBound)...index(at: value.upperBound)]
        }
    }
    
    subscript(value: CountableRange<Int>) -> Substring {
        get {
            return self[index(at: value.lowerBound)..<index(at: value.upperBound)]
        }
    }
    
    subscript(value: PartialRangeUpTo<Int>) -> Substring {
        get {
            return self[..<index(at: value.upperBound)]
        }
    }
    
    subscript(value: PartialRangeThrough<Int>) -> Substring {
        get {
            return self[...index(at: value.upperBound)]
        }
    }
    
    subscript(value: PartialRangeFrom<Int>) -> Substring {
        get {
            return self[index(at: value.lowerBound)...]
        }
    }
    
    func index(at offset: Int) -> String.Index {
        return index(startIndex, offsetBy: offset)
    }
}

