/*
 *  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

@objc class DeviceDetailView: UIViewController, UITextViewDelegate {
    
    @IBOutlet weak var headLineLabelOutlet: UILabel! {
        didSet {
            headLineLabelOutlet.font = UIFont(name: (headLineLabelOutlet.font?.fontName)!,
                                              size: (headLineLabelOutlet.font?.pointSize)! * 1.2)
        }
    }
    @IBOutlet weak var beaconTypeLabelOutlet: UILabel! {
        didSet {
            beaconTypeLabelOutlet.isHidden = true
        }
    }

    @IBOutlet weak var currentValueLabelOutlet: UILabel!

    @IBOutlet weak var stopButtonOutlet: UIButton! {
        didSet {
            stopButtonOutlet.layer.cornerRadius = 6.0
            stopButtonOutlet.layer.borderColor = UIColor.lightGray.cgColor
            stopButtonOutlet.layer.borderWidth = 1.0
            stopButtonOutlet.layer.backgroundColor = UIColor(white: 0.90,
                                                             alpha: 1.0).cgColor
        }
    }
    
    @IBOutlet weak var resetButtonOutlet: UIButton! {
        didSet {
            resetButtonOutlet.layer.cornerRadius = 6.0
            resetButtonOutlet.layer.borderColor = UIColor.lightGray.cgColor
            resetButtonOutlet.layer.borderWidth = 1.0
            resetButtonOutlet.layer.backgroundColor = UIColor(white: 0.90,
                                                              alpha: 1.0).cgColor
            if Provisioning.isProvisioningStatic() {
                resetButtonOutlet.isHidden = true
            }
        }
    }
    
    
    @IBOutlet weak var backToViewController2: UIButton! {
        didSet {
            backToViewController2.layer.cornerRadius = 6.0
            backToViewController2.layer.borderColor = UIColor.lightGray.cgColor
            backToViewController2.layer.borderWidth = 1.0
            backToViewController2.layer.backgroundColor = UIColor(white: 0.90,
                                                                  alpha: 1.0).cgColor
        }
    }
    

    @IBOutlet weak var outputLabelOutlet: UILabel!
    
    @IBOutlet weak var outputScrollViewOutlet: UIScrollView! {
        didSet {
            outputScrollViewOutlet.layer.cornerRadius = 6.0
            outputScrollViewOutlet.layer.borderColor = UIColor.lightGray.cgColor
            outputScrollViewOutlet.layer.borderWidth = 1.0
            outputScrollViewOutlet.layer.backgroundColor = UIColor(white: 0.90,
                                                                   alpha: 1.0).cgColor
        }
    }
    
    @IBOutlet weak var outputTextViewOutlet: UITextView! {
        didSet {
            outputTextViewOutlet.layer.cornerRadius = 6.0
            outputTextViewOutlet.layer.borderColor = UIColor.lightGray.cgColor
            outputTextViewOutlet.layer.borderWidth = 1.0
            outputTextViewOutlet.layer.backgroundColor = UIColor(white: 0.90,
                                                                 alpha: 1.0).cgColor
        }
    }

    @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)
    }
    
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        
        if dataConnector != nil {
            headLineLabelOutlet.text = kGWwvHeadline
            stopButtonOutlet.setTitle(kStop, for: UIControlState())
            // TODO unhide exit button
            stopButtonOutlet.isHidden = true
            
            resetButtonOutlet.setTitle(kReset, for: UIControlState())
            outputLabelOutlet.text = kOutput
            outputTextViewOutlet.text = kNotAttached
            outputTextViewOutlet.isScrollEnabled = true
            outputTextViewOutlet.isEditable = false
            currentValueLabelOutlet.textAlignment = .left
            currentValueLabelOutlet.numberOfLines = 0
            writeDummyOutput()
            dataConnector!.resetOutputText()
            timer1 = Timer.scheduledTimer(timeInterval: 5.0, target: self,
                                          selector: #selector(DeviceDetailView.updateData),
                                          userInfo: nil, repeats: true)
        }
        
    }
    
    override func viewDidAppear(_ animated: Bool) {
        if dataConnector != nil {
            self.navigationItem.setHidesBackButton(true, animated: false)
        }
        super.viewDidAppear(animated)
    }
    
    @objc func writeDummyOutput() -> Void {
        let beaconType = selectedBeacon.getType()
        
        switch beaconType {
            case .IBEACON:
                
                if self.beaconTypeLabelOutlet.isHidden == true {
                    self.beaconTypeLabelOutlet.text = kGWSecodLineIBeacon
                    self.beaconTypeLabelOutlet.isHidden = false
                }
                break
            case .EDDYSTONE, .EDDYSTONE_TLM:
                
                if self.beaconTypeLabelOutlet.isHidden == true {
                    self.beaconTypeLabelOutlet.text = kGWSecodLineEddy
                    self.beaconTypeLabelOutlet.isHidden = false
                }
                break
            default:
                break
        }
        setDataText()
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
    
    // Close the data connector and all used resources, 
    // gateway device, tam and communication channel
    @objc func closeDataConnector() {
        dataConnector!.close()
    }
    // TODO: Hack to not crash when app is closed
    // Need to find out how this worked before the ChooserProvisioner screen
    // Since DeviceDetailView has never been the root screen
    static var _dataConnector: DataConnector!
    @objc static func closeDataConnector() {
        _dataConnector?.close()
    }
    
    @objc func setDataText() {
        let beaconType = selectedBeacon.getType()
        let attrsNormal = [NSAttributedStringKey.font : UIFont.systemFont(ofSize: 15)]
        
        switch beaconType {
        case .IBEACON:
            let boldIBeaconText = "UUID: " + selectedBeacon.getUUID() + "\n"
            let attributedString = NSMutableAttributedString(string: boldIBeaconText,
                                                             attributes: attrsNormal)
            let selectedIBeacon = selectedBeacon as! IBeacon
            let mText = "Major: " + selectedIBeacon.getMajorVersion() +
                ", Minor: " + selectedIBeacon.getMinorVersion() + "\n"
            
            let normalString3 = NSMutableAttributedString(string: mText,
                                                          attributes: attrsNormal)
            var normalText = kCurrentIBeaconMssiValue + ": " +
                selectedBeacon.getMssi().description + ", " +
                kCurrentIBeaconRssiValue + ": "
            var distLine = kCurrentIBeaconDistanceValue + ": "
            let rssi = selectedBeacon.getRssi()
            if (rssi != 0) {
                normalText += rssi.description + " \n"
                distLine += String(format: "%.3f m\n",
                                   selectedBeacon.getDistance())
            } else {
                normalText += "Unknown \n"
                distLine += "Unknown \n"
            }
            let normalString = NSMutableAttributedString(string: normalText,
                                                         attributes: attrsNormal)
            let normalString2 = NSMutableAttributedString(string: distLine,
                                                          attributes: attrsNormal)
            
            attributedString.append(normalString3)
            attributedString.append(normalString)
            attributedString.append(normalString2)
            
            currentValueLabelOutlet.attributedText = attributedString
            break
            
        case .EDDYSTONE, .EDDYSTONE_TLM:
            let boldEddyBeaconText = "Namespace: " + selectedBeacon.getUUID() + "\n"
            let attributedString = NSMutableAttributedString(string: boldEddyBeaconText,
                                                             attributes: attrsNormal)
            let instText = "Instance: " + selectedBeacon.getSerialNumber() + "\n"
            let normalString6 = NSMutableAttributedString(string: instText,
                                                          attributes: attrsNormal)
            var normalText2 = kCurrentEddystoneBeaconMssiValue + ": " +
                selectedBeacon.getMssi().description + ", " +
                kCurrentEddystoneBeaconRssiValue + ": "
            var distLine = kCurrentEddyBeaconDistanceValue + ": "
            let rssi = selectedBeacon.getRssi()
            if (rssi != 0) {
                normalText2 += rssi.description  + " \n"
                distLine += String(format: "%.3f m\n",
                                   selectedBeacon.getDistance())
            } else {
                normalText2 += "Unknown \n"
                distLine += "Unknown \n"
            }
            let normalString2 = NSMutableAttributedString(string: normalText2,
                                                          attributes: attrsNormal)
            let normalString5 = NSMutableAttributedString(string: distLine,
                                                          attributes: attrsNormal)
            let temperature = (selectedBeacon as! EddystoneBeacon).getTemperature() / 256.0
            let tempLine = kCurrentEddystoneBeaconTempValue + ": " +
                String(format: "%.3f C\n", temperature)
            let normalString3 = NSMutableAttributedString(string: tempLine,
                                                          attributes: attrsNormal)
            let voltLine = kCurrentEddystoneBeaconVoltValue + ": " +
                String(format: "%.3f V", (selectedBeacon as! EddystoneBeacon).getVoltage()/1000.0)
            let normalString4 = NSMutableAttributedString(string: voltLine,
                                                          attributes: attrsNormal)
            
            attributedString.append(normalString6)
            attributedString.append(normalString2)
            attributedString.append(normalString5)
            attributedString.append(normalString3)
            attributedString.append(normalString4)
            
            currentValueLabelOutlet.attributedText = attributedString
            break
            
        default:
            break
        }
    }
    
    @objc func askSensor() {
        if(!stopped) {
            setDataText()
            
            let str = dataConnector!.getOutputText()
            self.outputTextViewOutlet.text = str
            
            // 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))
        }
    }
    
    @objc func updateData() {
        self.askSensor()
    }
    
    // MARK: Actions
    
    // Action for the button "Reset"
    @IBAction func onResetButton(_ sender: UIButton) {
        dataConnector!.stop()
        stopped = true
        
        // stop the loops
        timer1.invalidate()
        
        outputTextViewOutlet.text = kNotAttached
        writeDummyOutput()
        self.navigationController?.popToRootViewController(animated: false)
    }
    
    // Action for the button "Stop"
    @IBAction func onStopButton(_ sender: UIButton) {
        dataConnector!.stop()
        stopped = true
        
        // stop the loops
        timer1.invalidate()

        outputTextViewOutlet.text = kNotAttached
        writeDummyOutput()
        saveSettingsFile(path: URL(fileURLWithPath: Provisioning.getProvisioningFilePath()).lastPathComponent,
            password: String(Provisioning.getProvisioningPassword()))
        exit(0)
    }
    
    // Action for the button "Back"
    @IBAction func onBackButton(_ sender: AnyObject) {
        
        dataConnector?.stop()
        timer1.invalidate()
        
        let secondViewController = self.storyboard?.instantiateViewController(
            withIdentifier: "BeaconSelectionView") as! BeaconSelectionView
        self.navigationController?.pushViewController(secondViewController,
                                                      animated: false)
    }
}
