/*
 *  Copyright © 2016, 2017, Oracle and/or its affiliates. All rights reserved.
 *  This software is dual-licensed to you under the MIT License (MIT) and
 *  the Universal Permissive License (UPL). See the LICENSE file in the root
 *  directory for license terms. You may choose either license, or both.
 */

import UIKit

var gatewayDeviceSample:GatewayDeviceSample?

@objc class GatewayDeviceSampleView: UIViewController, UITextViewDelegate {
    
    //MARK: Properties
    @IBOutlet weak var humidityIdOutlet: UILabel!
    @IBOutlet weak var humidityOutlet: UILabel!
    @IBOutlet weak var humidityThresholdOutlet: UILabel!
    
    @IBOutlet weak var tempIdOutlet: UILabel!
    @IBOutlet weak var temperatureOutlet: UILabel!
    @IBOutlet weak var minMaxTempOutlet: UILabel!
    @IBOutlet weak var minMaxTempThresholdOutlet: UILabel!
    @IBOutlet weak var startTimeOutlet: UILabel!
    
    @IBOutlet weak var stopButtonOutlet: UIButton!
    
    @IBOutlet weak var resetButtonOutlet: UIButton! {
        didSet {
            if Provisioning.isProvisioningStatic() {
                resetButtonOutlet.isHidden = true
            }
        }
    }
    
    @IBOutlet weak var outputLabelOutlet: UILabel!
    @IBOutlet weak var outputTextViewOutlet: UITextView!
    @IBOutlet var ViewControllerOutlet: UIView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        outputTextViewOutlet.delegate = self
        UIGraphicsBeginImageContext(CGSize(width: self.view.frame.size.width,
                                           height: self.view.frame.size.width - 18))
        UIImage(named: "cloudes-sw.png")?.drawAsPattern(in: self.view.bounds)
        let image : UIImage = UIGraphicsGetImageFromCurrentImageContext()!
        UIGraphicsEndImageContext()
        ViewControllerOutlet.backgroundColor = UIColor(patternImage: image)
        
        self.navigationItem.title = "Gateway Device Sample"
    }
    
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        
        do {
            try gatewayDeviceSample = GatewayDeviceSample(
                path:Provisioning.getProvisioningFilePath(),
                password:Provisioning.getProvisioningPassword(),
                updateInterval:5, usePolicy:Provisioning.getWithPolicies(),
                updateCallback: updateGui,
                errorCallback: errorCallback,
                displayCallback: display)
            
            gatewayDeviceSample?.start()
        
        } catch {
            showError(controller: self, alertTitle: "GatewayDeviceSample startup failure",
                      message: "\(error)", actionTitle: "OK",
                      handler: { (action: UIAlertAction?) -> () in
                // Ensure that user can re-provision the device
                removeLastSettingsFile()
                self.navigationController?.popToRootViewController(animated: false)
            })
        }
    }
    
    override func viewDidAppear(_ animated: Bool) {
        if gatewayDeviceSample != nil {
            self.navigationItem.setHidesBackButton(true, animated: false)
        }
        super.viewDidAppear(animated)
    }

    // Close the data connector and all used resources,
    // gateway device, tam and communication channel
    static func terminate() {
        
    }

    private func display(text:String) {
        DispatchQueue.main.async(execute: {
            self.outputTextViewOutlet.text =
                self.outputTextViewOutlet.text + "\n" + text
            // Force text field to (invisibly) scroll until latest line is at bottom
            let bottom: NSRange = NSMakeRange(self.outputTextViewOutlet.text.count - 10, 1)
            self.outputTextViewOutlet.scrollRangeToVisible((bottom))
        })
    }
    
    private func errorCallback(str:String) {
        showError(controller: self, alertTitle: "Library Error",
                  message: str, actionTitle: "OK",
                  handler: { (action: UIAlertAction?) -> () in })
    }

    /*
     * We know there is only one HumiditySensor and one TemperatureSensor
     * The humidity data is obtained with key "humidity" as (String, Int, Int)
     * (endpointId,humidity,maxThreshold)
     * and temperature data is obtained with key "temperature"
     * as (String, Int64, Double, Double, Double, Int, Int)
     * (endpointId,startTime,temperature,minTemp,maxTemp,minThreshold,maxThreshold)
     */
    func updateGui(sensorData:[String:Any]) {
        
        // TODO: This should be done with discrete labels, not as a single
        // string in one label. This will allow updating the humidity or
        // temperature sensor independently

        if let anyData = sensorData["humidity"] {
            
            let hData:(endpointId:String,humidity:Int,maxThreshold:Int) =
                anyData as! (String,Int,Int)
            
            humidityIdOutlet.text = hData.endpointId
            humidityOutlet.text = hData.humidity.description + " %"
            humidityThresholdOutlet.text = hData.maxThreshold.description + " %"
        }
        
        if let anyData = sensorData["temperature"] {
            
            let tData:(endpointId:String,startTime:Int64,temp:Double,minTemp:Double,
                maxTemp:Double,minThreshold:Int,maxThreshold:Int) =
                anyData as! (String,Int64,Double,Double,Double,Int,Int)
            
            tempIdOutlet.text = tData.endpointId
            temperatureOutlet.text = String(format:"%.2f °C", tData.temp)

            minMaxTempOutlet.text = String(format:" %.2f / %.2f °C",
                                           tData.minTemp, tData.maxTemp)
            minMaxTempThresholdOutlet.text = String(format:" %d / %d °C",
                                                    tData.minThreshold,
                                                    tData.maxThreshold)

            let theDate = Date(timeIntervalSince1970: TimeInterval(tData.startTime))
            startTimeOutlet.text = formatDate(date: theDate)
        }
    }

    // MARK: Actions
    
    // Action for the button "Reset"
    @IBAction func onResetButton(_ sender: UIButton) {
        gatewayDeviceSample?.stop()
        // stop the loops
        outputTextViewOutlet.text = ""
        // Allow reprovisioning
        removeLastSettingsFile()
        self.navigationController?.popToRootViewController(animated: false)
        
    }
    
    // Action for the button "Stop"
    @IBAction func onStopButton(_ sender: UIButton) {
        gatewayDeviceSample?.stop()
        outputTextViewOutlet.text = ""
        saveSettingsFile(path: URL(fileURLWithPath: Provisioning.getProvisioningFilePath()).lastPathComponent,
            password: String(Provisioning.getProvisioningPassword()))
        exit(0)
    }
    
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
}
