//
//  AppDelegate.swift
//  NeoSpectraSwift
//
//  Created by doda on 10/19/16.
//  Copyright © 2016 siware. All rights reserved.
//

import UIKit
import Fabric
import Crashlytics
import CoreBluetooth

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, NSBluetoothManagerDelegate {

    enum MainViews
    {
        case HOME
        case SPECTRUM
        case PSD
        case NEWOPTICALGAIN
        case RESTORESETTINGS
        case RUNSELFCORR
        case RUNMATERIALCORR
        case BURNGAIN
        case BURNSELFCORR
        case BURNREFMATERIAL
        case BURNALL
    }
    
    var window: UIWindow?
    static var bluetoothManager    : NSBluetoothManager?
    var uartPeripheralName  : String?
    var homeDelegate : NSBluetoothManagerDelegate?
    var spectrumDelegate : NSBluetoothManagerDelegate?
    var psdDelegate : NSBluetoothManagerDelegate?
    var newOpticalGainDelegate : NSBluetoothManagerDelegate?
    var restoreSettingsDelegate : NSBluetoothManagerDelegate?
    var runSelfCorrDelegate : NSBluetoothManagerDelegate?
    var runMaterialCorrDelegate : NSBluetoothManagerDelegate?
    var burnGainDelegate : NSBluetoothManagerDelegate?
    var burnSelfDelegate : NSBluetoothManagerDelegate?
    var burnRefMaterialDelegate : NSBluetoothManagerDelegate?
    var burnAllDelegate : NSBluetoothManagerDelegate?

    static var on = false
    /*
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
        // Override point for customization after application launch.
        Fabric.with([Crashlytics.self])
        
         UITabBarItem.appearance().setTitleTextAttributes([NSForegroundColorAttributeName: self.hexStringToUIColor(hex:"#fa6405")], for:.selected)
        let font: UIFont = UIFont.systemFont(ofSize: 12)
        UITabBarItem.appearance().setTitleTextAttributes([NSFontAttributeName: font], for: .normal)
        return true
    }

    */
    func hexStringToUIColor (hex:String) -> UIColor {
        var cString:String = hex.trimmingCharacters(in: .whitespacesAndNewlines).uppercased()
        
        if (cString.hasPrefix("#")) {
            cString.remove(at: cString.startIndex)
        }
        
        if ((cString.characters.count) != 6) {
            return UIColor.gray
        }
        
        var rgbValue:UInt32 = 0
        Scanner(string: cString).scanHexInt32(&rgbValue)
        
        return UIColor(
            red: CGFloat((rgbValue & 0xFF0000) >> 16) / 255.0,
            green: CGFloat((rgbValue & 0x00FF00) >> 8) / 255.0,
            blue: CGFloat(rgbValue & 0x0000FF) / 255.0,
            alpha: CGFloat(1.0)
        )
    }
    
    func setBlueToothManager(withManager aManager: CBCentralManager, andPeripheral aPeripheral: CBPeripheral){
        AppDelegate.bluetoothManager = NSBluetoothManager(withManager: aManager)
        AppDelegate.bluetoothManager?.delegate = self
        AppDelegate.bluetoothManager?.connectPeripheral(peripheral: aPeripheral)
    }
    
    func disconnectDevice(){
        AppDelegate.bluetoothManager?.cancelPeriphralConnection()
    }
    
    func applicationWillResignActive(_ application: UIApplication) {
        
    }

    func applicationDidEnterBackground(_ application: UIApplication) {
     
    }

    func applicationWillEnterForeground(_ application: UIApplication) {
  
    }

    func applicationDidBecomeActive(_ application: UIApplication) {

    }

    func applicationWillTerminate(_ application: UIApplication) {

    }

    //MARK: - BluetoothManagerDelegate
    func peripheralReady() {
        print("Peripheral is ready")
    }
    func peripheralNotSupported() {
        print("Peripheral is not supported")
    }
    
    func didConnectPeripheral(deviceName aName: String) {
        self.uartPeripheralName = aName

        //Following if condition display user permission alert for background notification
        if UIApplication.instancesRespond(to: #selector(UIApplication.registerUserNotificationSettings(_:))){
            UIApplication.shared.registerUserNotificationSettings(UIUserNotificationSettings(types: [.sound, .alert], categories: nil))
        }
        
        NotificationCenter.default.addObserver(self, selector: #selector(self.applicationDidEnterBackgroundCallback), name: NSNotification.Name.UIApplicationDidEnterBackground, object: nil)
        NotificationCenter.default.addObserver(self, selector: #selector(self.applicationDidBecomeActiveCallback), name: NSNotification.Name.UIApplicationDidBecomeActive, object: nil)
        
        
        if(homeDelegate != nil){
            homeDelegate?.didConnectPeripheral(deviceName: aName)
        }
        if(spectrumDelegate != nil){
            spectrumDelegate?.didConnectPeripheral(deviceName: aName)
        }
        if(psdDelegate != nil){
            psdDelegate?.didConnectPeripheral(deviceName: aName)
        }
        
        if(newOpticalGainDelegate != nil){
            newOpticalGainDelegate?.didConnectPeripheral(deviceName: aName)
        }
        
        if(restoreSettingsDelegate != nil){
            restoreSettingsDelegate?.didConnectPeripheral(deviceName: aName)
        }
        
        if(runSelfCorrDelegate != nil){
            runSelfCorrDelegate?.didConnectPeripheral(deviceName: aName)
        }
        
        if(runMaterialCorrDelegate != nil){
            runMaterialCorrDelegate?.didConnectPeripheral(deviceName: aName)
        }
    
        if(burnGainDelegate != nil){
            burnGainDelegate?.didConnectPeripheral(deviceName: aName)
        }
        
        if(burnSelfDelegate != nil){
            burnSelfDelegate?.didConnectPeripheral(deviceName: aName)
        }
        
        if(burnRefMaterialDelegate != nil){
            burnRefMaterialDelegate?.didConnectPeripheral(deviceName: aName)
        }
        
        if(burnAllDelegate != nil){
            burnAllDelegate?.didConnectPeripheral(deviceName: aName)
        }
    }
    
    func didDisconnectPeripheral() {
        AppDelegate.bluetoothManager?.cancelPeriphralConnection()
        NotificationCenter.default.removeObserver(self, name: NSNotification.Name.UIApplicationDidBecomeActive, object: nil)
        NotificationCenter.default.removeObserver(self, name: NSNotification.Name.UIApplicationDidEnterBackground, object: nil)
        AppDelegate.bluetoothManager = nil

        if(homeDelegate != nil){
            homeDelegate?.didDisconnectPeripheral()
        }
        if(spectrumDelegate != nil){
            spectrumDelegate?.didDisconnectPeripheral()
        }
        if(psdDelegate != nil){
            psdDelegate?.didDisconnectPeripheral()
        }
        if(newOpticalGainDelegate != nil){
            newOpticalGainDelegate?.didDisconnectPeripheral()
        }
        
        if(restoreSettingsDelegate != nil){
            restoreSettingsDelegate?.didDisconnectPeripheral()
        }
        
        if(runSelfCorrDelegate != nil){
            runSelfCorrDelegate?.didDisconnectPeripheral()
        }
        
        if(runMaterialCorrDelegate != nil){
            runMaterialCorrDelegate?.didDisconnectPeripheral()
        }
        
        if(burnGainDelegate != nil){
            burnGainDelegate?.didDisconnectPeripheral()
        }
        
        if(burnSelfDelegate != nil){
            burnSelfDelegate?.didDisconnectPeripheral()
        }
        
        if(burnRefMaterialDelegate != nil){
            burnRefMaterialDelegate?.didDisconnectPeripheral()
        }
        
        if(burnAllDelegate != nil){
            burnAllDelegate?.didDisconnectPeripheral()
        }
        
        Constants.BlueToothConnected = false
    }

    
    func applicationDidEnterBackgroundCallback(){
        //NORAppUtilities.showBackgroundNotification(message: "You are still connected to \(uartPeripheralName)")
        //AppDelegate.bluetoothManager?.cancelPeriphralConnection()
        //AppDelegate.bluetoothManager = nil
    }
    
    func applicationDidBecomeActiveCallback(){
        UIApplication.shared.cancelAllLocalNotifications()
    }
    

    func receivedDoubleData(allData:[Double], sender:AppDelegate.MainViews)
    {
        switch sender {
            case .HOME:
                homeDelegate?.receivedDoubleData(allData: allData, sender: sender)
            case .SPECTRUM:
                spectrumDelegate?.receivedDoubleData(allData: allData, sender: sender)
            case .PSD:
                psdDelegate?.receivedDoubleData(allData: allData, sender: sender)
            case .NEWOPTICALGAIN:
                newOpticalGainDelegate?.receivedDoubleData(allData: allData, sender: sender)
            case .RESTORESETTINGS:
                restoreSettingsDelegate?.receivedDoubleData(allData: allData, sender: sender)
            case .RUNSELFCORR:
                runSelfCorrDelegate?.receivedDoubleData(allData: allData, sender: sender)
            case .RUNMATERIALCORR:
                runMaterialCorrDelegate?.receivedDoubleData(allData: allData, sender: sender)
            case .BURNGAIN:
                burnGainDelegate?.receivedDoubleData(allData: allData, sender: sender)
            case .BURNSELFCORR:
                burnSelfDelegate?.receivedDoubleData(allData: allData, sender: sender)
            case .BURNREFMATERIAL:
                burnRefMaterialDelegate?.receivedDoubleData(allData: allData, sender: sender)
            case .BURNALL:
                burnAllDelegate?.receivedDoubleData(allData: allData, sender: sender)
        }
    }
    
    func receivedFloatData(allData:[Float], sender:AppDelegate.MainViews)
    {
        switch sender {
            case .HOME:
                homeDelegate?.receivedFloatData(allData: allData, sender: sender)
            case .SPECTRUM:
                spectrumDelegate?.receivedFloatData(allData: allData, sender: sender)
            case .PSD:
                psdDelegate?.receivedFloatData(allData: allData, sender: sender)
            case .NEWOPTICALGAIN:
                newOpticalGainDelegate?.receivedFloatData(allData: allData, sender: sender)
            case .RESTORESETTINGS:
                restoreSettingsDelegate?.receivedFloatData(allData: allData, sender: sender)
            case .RUNSELFCORR:
                runSelfCorrDelegate?.receivedFloatData(allData: allData, sender: sender)
            case .RUNMATERIALCORR:
                runMaterialCorrDelegate?.receivedFloatData(allData: allData, sender: sender)
            case .BURNGAIN:
                burnGainDelegate?.receivedFloatData(allData: allData, sender: sender)
            case .BURNSELFCORR:
                burnSelfDelegate?.receivedFloatData(allData: allData, sender: sender)
            case .BURNREFMATERIAL:
                burnRefMaterialDelegate?.receivedFloatData(allData: allData, sender: sender)
            case .BURNALL:
                burnAllDelegate?.receivedFloatData(allData: allData, sender: sender)
        }
    }
    
    func reportError(error:UInt8, sender:AppDelegate.MainViews)
    {
        switch sender {
            case .HOME:
                homeDelegate?.reportError(error:error, sender:sender)
            case .SPECTRUM:
                spectrumDelegate?.reportError(error:error, sender:sender)
            case .PSD:
                psdDelegate?.reportError(error:error, sender:sender)
            case .NEWOPTICALGAIN:
                newOpticalGainDelegate?.reportError(error:error, sender:sender)
            case .RESTORESETTINGS:
                restoreSettingsDelegate?.reportError(error:error, sender:sender)
            case .RUNSELFCORR:
                runSelfCorrDelegate?.reportError(error: error, sender: sender)
            case .RUNMATERIALCORR:
                runMaterialCorrDelegate?.reportError(error: error, sender: sender)
            case .BURNGAIN:
                burnGainDelegate?.reportError(error: error, sender: sender)
            case .BURNSELFCORR:
                burnSelfDelegate?.reportError(error: error, sender: sender)
            case .BURNREFMATERIAL:
                burnRefMaterialDelegate?.reportError(error: error, sender: sender)
            case .BURNALL:
                burnAllDelegate?.reportError(error: error, sender: sender)
        }
    }
}

