import UIKit
import UserNotifications

class DataManager {
    
    static let shared = DataManager()
    
    var StartC : StartController?
    var NuovaPartitaC : NuovaPartitaController?
    var AlertC : AlertController?
    var RuoloC : RuoloController?
    var ConfermaC : ConfermaController?
    var TimerC : TimerController?
    
    var stileGrafica = "c"
    var nGiocatori = 8
    var nSpie = 1
    var nMinuti = 8
    
    let nLocations = 60         // numero di location disponibili
    let nRuoli = 6              // numero di ruoli per ogni location
    
    var minGiocatori = 3        // numero minimo di giocatori
    var minMinuti = 5           // durata minima (minuti) partita
    var modSpie = 8             // 1 spia ogni tot giocatori (8)
    
    var curPlayer = 0           // giocatore iniziale
    var spies : [Int] = []      // array di spie
    var location = 0            // luogo da indovinare
    var locations : [Int] = []  // luoghi precedenti partite
    var noRepeat = 10           // luoghi salvati da non ripetere nelle partite successive
    var curRuolo = 0            // ruolo attuale (andrà a ciclare)
    
    let heavyGen = UIImpactFeedbackGenerator(style: .heavy)
    let mediumGen = UIImpactFeedbackGenerator(style: .medium)
    let lightGen = UIImpactFeedbackGenerator(style: .light)
    
    
    
    // MARK: - Metodi
    
    func startDataManager() {
        if UserDefaults.standard.object(forKey: "grafica") != nil {
            stileGrafica = UserDefaults.standard.object(forKey: "grafica") as! String
        }
        
        if UserDefaults.standard.object(forKey: "nGiocatori") != nil {
            nGiocatori = UserDefaults.standard.integer(forKey: "nGiocatori")
        }
        if UserDefaults.standard.object(forKey: "nSpie") != nil {
            nSpie = UserDefaults.standard.integer(forKey: "nSpie")
        }
        if UserDefaults.standard.object(forKey: "nMinuti") != nil {
            nMinuti = UserDefaults.standard.integer(forKey: "nMinuti")
        }
        
        if UserDefaults.standard.object(forKey: "locations") != nil {
            locations = UserDefaults.standard.object(forKey: "locations") as! [Int]
        }
        
        StoreReviewHelper.incrementAppOpenedCount()
        StoreReviewHelper.checkAndAskForReview()
    }
    
    func cambiaStile(stile: String) {
        UserDefaults.standard.set(stile, forKey: "grafica")
        
        stileGrafica = stile
        
        StartC?.sfondoView.image = UIImage(named:"intro_"+stile)
        NuovaPartitaC?.sfondoView.image = UIImage(named:"intro_"+stile)
        AlertC?.sfondoView.image = UIImage(named:"intro_"+stile)
        RuoloC?.sfondoView.image = UIImage(named:"intro_"+stile)
        ConfermaC?.sfondoView.image = UIImage(named:"intro_"+stile)
    }
    
    func salvaImpostazioni() {
        UserDefaults.standard.set(nGiocatori, forKey: "nGiocatori")
        UserDefaults.standard.set(nSpie, forKey: "nSpie")
        UserDefaults.standard.set(nMinuti, forKey: "nMinuti")
    }
    
    func avviaPartita() {
        // Genero N Spie
        spies = generateNumbers(repetitions: nSpie, maxValue: nGiocatori)
        print(spies)
                
        // Seleziono il Luogo (diverso dai precedenti N)
        repeat {
            location = random(maxValue: nLocations) + 1
        } while locations.contains(location)
        locations.append(location)
        
        print("Location: " + String(location))
        
        // Se ne ho già N, rimuovo il primo
        if locations.count > noRepeat {
            locations.removeFirst()
        }
        
        //location = 45 // per gli screenshots
        
        UserDefaults.standard.set(locations, forKey: "locations")
        
        curPlayer = 0
        curRuolo = random(maxValue: nRuoli)
    }
    
    func isSpy() -> Bool {
        print("turno: "+String(curPlayer))
        return spies.contains(curPlayer)
    }
    
    func generateNumbers(repetitions: Int, maxValue: Int) -> [Int] {
        guard maxValue >= repetitions else {
            fatalError("maxValue must be >= repetitions for the numbers to be unique")
        }
        
        var numbers: [Int] = []
        
        for _ in 1...repetitions {
            var n: Int
            repeat {
                n = random(maxValue: maxValue)
            } while numbers.contains(n)
            numbers.append(n)
        }
        
        return numbers
    }
    
    private func random(maxValue: Int) -> Int {
        return Int(arc4random_uniform(UInt32(maxValue)))
    }
    
    func rimuoviNotifiche() {
        //application.applicationIconBadgeNumber = 0 // For Clear Badge Counts
        let center = UNUserNotificationCenter.current()
        center.removeAllDeliveredNotifications() // To remove all delivered notifications
        center.removeAllPendingNotificationRequests() // To remove all pending notifications which are not delivered yet but scheduled.
    }
    
    
}

extension UIDevice {
    
    var modelName: String {
        var systemInfo = utsname()
        uname(&systemInfo)
        let machineMirror = Mirror(reflecting: systemInfo.machine)
        let identifier = machineMirror.children.reduce("") { identifier, element in
            guard let value = element.value as? Int8, value != 0 else { return identifier }
            return identifier + String(UnicodeScalar(UInt8(value)))
        }
        
        switch identifier {
        case "iPod5,1":                                 return "iPod Touch 5"
        case "iPod7,1":                                 return "iPod Touch 6"
        case "iPhone3,1", "iPhone3,2", "iPhone3,3":     return "iPhone 4"
        case "iPhone4,1":                               return "iPhone 4s"
        case "iPhone5,1", "iPhone5,2":                  return "iPhone 5"
        case "iPhone5,3", "iPhone5,4":                  return "iPhone 5c"
        case "iPhone6,1", "iPhone6,2":                  return "iPhone 5s"
        case "iPhone7,2":                               return "iPhone 6"
        case "iPhone7,1":                               return "iPhone 6 Plus"
        case "iPhone8,1":                               return "iPhone 6s"
        case "iPhone8,2":                               return "iPhone 6s Plus"
        case "iPad2,1", "iPad2,2", "iPad2,3", "iPad2,4":return "iPad 2"
        case "iPad3,1", "iPad3,2", "iPad3,3":           return "iPad 3"
        case "iPad3,4", "iPad3,5", "iPad3,6":           return "iPad 4"
        case "iPad4,1", "iPad4,2", "iPad4,3":           return "iPad Air"
        case "iPad5,3", "iPad5,4":                      return "iPad Air 2"
        case "iPad2,5", "iPad2,6", "iPad2,7":           return "iPad Mini"
        case "iPad4,4", "iPad4,5", "iPad4,6":           return "iPad Mini 2"
        case "iPad4,7", "iPad4,8", "iPad4,9":           return "iPad Mini 3"
        case "iPad5,1", "iPad5,2":                      return "iPad Mini 4"
        case "iPad6,7", "iPad6,8":                      return "iPad Pro"
        case "AppleTV5,3":                              return "Apple TV"
        case "i386", "x86_64":                          return "Simulator"
        default:                                        return identifier
        }
    }
}


extension UIImage {
    func makeImageWithColorAndSize(_ color: UIColor, size: CGSize) -> UIImage {
        UIGraphicsBeginImageContextWithOptions(size, false, 0)
        color.setFill()
        UIRectFill(CGRect(x: 0, y: 0, width: 100, height: 100))
        let image = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return image!
    }
    func imageWithColor(_ color1: UIColor) -> UIImage {
        UIGraphicsBeginImageContextWithOptions(self.size, false, self.scale)
        color1.setFill()
        
        let context = UIGraphicsGetCurrentContext()
        context?.translateBy(x: 0, y: self.size.height)
        context?.scaleBy(x: 1.0, y: -1.0);
        context?.setBlendMode(CGBlendMode.normal)
        
        let rect = CGRect(x: 0, y: 0, width: self.size.width, height: self.size.height) as CGRect
        context?.clip(to: rect, mask: self.cgImage!)
        context?.fill(rect)
        
        let newImage = UIGraphicsGetImageFromCurrentImageContext()! as UIImage
        UIGraphicsEndImageContext()
        
        return newImage
    }
}

extension UIColor
{
    convenience init(red: Int, green: Int, blue: Int)
    {
        let newRed = CGFloat(red)/255
        let newGreen = CGFloat(green)/255
        let newBlue = CGFloat(blue)/255
        
        self.init(red: newRed, green: newGreen, blue: newBlue, alpha: 1.0)
    }
}

extension UIView {
    
    func addDropShadow(){
        
        self.layer.masksToBounds = false
        self.layer.shadowColor = grigio.cgColor
        self.layer.shadowOffset = CGSize(width: 1, height: 1)
        self.layer.shadowOpacity = 1
        self.layer.shadowRadius = 0
    }
}

extension String {
    func leftPadding(toLength: Int, withPad character: Character) -> String {
        let stringLength = self.count
        if stringLength < toLength {
            return String(repeatElement(character, count: toLength - stringLength)) + self
        } else {
            return String(self.suffix(toLength))
        }
    }
}



class TableViewHelper {
    
    class func EmptyMessage(message:String, viewController:UITableViewController) {
        let messageLabel = UILabel(frame: CGRect(x: 20, y: 0, width: (viewController.view.bounds.size.width - 40), height: viewController.view.bounds.size.height))
        messageLabel.text = message
        messageLabel.textColor = grigio
        messageLabel.numberOfLines = 0;
        messageLabel.textAlignment = .center;
        messageLabel.font = UIFont(name: "font_testo", size: 10)
        messageLabel.sizeToFit()
        
        viewController.tableView.backgroundView = messageLabel;
        viewController.tableView.separatorStyle = .none;
    }
}
