//
//  ReadMemoryViewController.swift
//  ReadMemory_EAReader
//
//  Created by 류은주 on 2018. 1. 11..
//  Copyright © 2018년 류은주. All rights reserved.
//
let READ_PICKER_VIEW_BANK = 0
let READ_PICKER_VIEW_OFFSET = 1
let READ_PICKER_VIEW_LENGTH = 2

let MSG_TAG_WAIT = "Tag memory to Access. Click the button."

import UIKit

class WriteMemoryViewController: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource, UITextFieldDelegate, EAReaderDelegate {

    @IBOutlet weak var connectBarItem: UIBarButtonItem!
    @IBOutlet weak var optionBarItem: UIBarButtonItem!
    @IBOutlet weak var paramPickerView: UIPickerView!
    @IBOutlet weak var paramTopView: UIView!
    @IBOutlet weak var blockView: UIView!
    @IBOutlet weak var bankTextField: UITextField!
    @IBOutlet weak var offsetTextField: UITextField!
    @IBOutlet weak var lengthTextField: UITextField!
    @IBOutlet weak var passwordTextField: UITextField!
    @IBOutlet weak var readResult: UILabel!
    @IBOutlet weak var epcData: UILabel!
    @IBOutlet weak var rssiData: UILabel!
    @IBOutlet weak var phaseData: UILabel!
    @IBOutlet weak var writedataTextField: UITextField!
    //    @IBOutlet weak var readData: UILabel!
    
    var appDelegate = UIApplication.shared.delegate as! AppDelegate
    
    var bankValue = 1
    var offsetValue = 2
    var lengthValue = 2
    var passwordValue = ""
    var writedataValue = ""
    
    var notiAlert: UIAlertController?
    
    var isActionResult = false
    
    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.
        
        DispatchQueue.global(qos: .default).async(execute: {() -> Void in
            // Do something...
            if self.appDelegate.mReader == nil {
                return
            }
            self.appDelegate.mReader?.continuousMode = false
        })
        
    }
    
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        appDelegate.mReader?.setDelegate(self)
        let center = NotificationCenter.default
        center.addObserver(self, selector: #selector(bluetoothDisconnected), name: NSNotification.Name.init(rawValue: "BluetoothDisconnected"), object: nil)
        if appDelegate.connectflag == true {
            connectBarItem.title = "Cancel"
            optionBarItem.isEnabled = true
            blockView.isHidden = true
            appDelegate.mReader?.setTagDataType(TAG_DATA_TYPE_ASCII)
        } else {
            connectBarItem.title = "Search"
            optionBarItem.isEnabled = false
            blockView.isHidden = false
        }
        paramTextSet()
    }
    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        if appDelegate.mReader?.getAction() != CommandStop {
            appDelegate.mReader?.stop()
        }
        NotificationCenter.default.removeObserver(self, name: NSNotification.Name(rawValue: "BluetoothDisconnected"), object: nil)
    }
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
    @objc func changedActionState(_ action: CommandType) {
        if action == CommandStop {
            notiAlert?.dismiss(animated: true) {() -> Void in }
            if isActionResult == false {
                epcData.text = MSG_TAG_WAIT
                readResult.text = "Fail to get a data"
//                readData.text = ""
                rssiData.text = String(format: "%.1f dB", 0.0)
                phaseData.text = String(format: "%.1f˚", 0.0)
            }
        }
    }
    @objc func tagAccessResult(_ error: ResultType, actionState action: CommandType, epc: String, data: String, rssi: Float, phase: Float) {
        print("RMV - Access Result : \(error), \(action), \(epc), \(data), \(rssi), \(phase)")

        isActionResult = true
        if error != ResultNoError {
            notiAlert?.dismiss(animated: true) {() -> Void in }
            epcData.text = MSG_TAG_WAIT
            readResult.text = EAResultType.msg(error)
//            readData.text = ""
            rssiData.text = String(format: "%.1f dB", 0.0)
            phaseData.text = String(format: "%.1f˚", 0.0)
            
            let alert = UIAlertController(title: "Error", message:EAResultType.msg(error), preferredStyle: .alert)
            
            let ok = UIAlertAction(title: "OK", style: .default, handler: {(_ action: UIAlertAction) -> Void in
                alert.dismiss(animated: true) {() -> Void in}
            })
            
            alert.addAction(ok)
            
            DispatchQueue.main.async(execute: {() -> Void in
                self.present(alert, animated: true) {() -> Void in }
            })
            return
        }
        epcData.text = epc
        readResult.text = "Success"
//        readData.text = data
        rssiData.text = String(format: "%.1f dB", rssi)
        phaseData.text = String(format: "%.1f˚", phase)
        notiAlert?.dismiss(animated: true) {() -> Void in }
        
    }
    func numberOfComponents(in pickerView: UIPickerView) -> Int {
        return 1
    }
    
    func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
        if(paramPickerView.tag == READ_PICKER_VIEW_BANK){
            return (DATA_BANK.count)
        } else if(paramPickerView.tag == READ_PICKER_VIEW_OFFSET){
            return (DATA_WORD.count)
        } else if(paramPickerView.tag == READ_PICKER_VIEW_LENGTH){
            return (DATA_WORD.count)
        }  else {
            return (DATA_WORD.count)
        }
    }
    
    func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
        if(paramPickerView.tag == READ_PICKER_VIEW_BANK){
            return DATA_BANK[row]
        } else if(paramPickerView.tag == READ_PICKER_VIEW_OFFSET){
            return "\(String(describing: DATA_WORD[row])) WORD"
        } else if(paramPickerView.tag == READ_PICKER_VIEW_LENGTH){
            return DATA_WORD[row]
        }  else {
            return DATA_WORD[row]
        }
    }
    func paramSettingShow(mode:Bool){
        paramTopView.isHidden = mode
        paramPickerView.isHidden = mode
    }
    func paramTextSet() {
        bankTextField.text = DATA_BANK[bankValue]
        offsetTextField.text = "\(String(describing: DATA_WORD[offsetValue])) WORD"
        lengthTextField.text = "\(String(describing: DATA_WORD[lengthValue])) WORD"
        passwordTextField.text = passwordValue
        
    }
    func cleanData() {
        readResult.text = "Result"
        epcData.text = "Tag Memory to Access. Click the button"
        rssiData.text = "0.0 dB"
        phaseData.text = "0.0˚"
//        readData.text = ""
    }
    func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
        let nonHex = CharacterSet(charactersIn: "0123456789ABCDEFabcdef").inverted
        let nonHexRange: NSRange = (string as NSString).rangeOfCharacter(from: nonHex)
        let isHex: Bool = nonHexRange.location == NSNotFound
        if isHex {
            let newString: String? = (textField.text as NSString?)?.replacingCharacters(in: range, with: string)
            textField.text = newString?.uppercased()
        }
        return false
    }
    @IBAction func connectBarItemTapped(_ sender: UIBarButtonItem) {
        if(appDelegate.connectflag == false){
            performSegue(withIdentifier: "bleconnect", sender: nil)
        } else {
            appDelegate.connectflag = false
            if appDelegate.mReader != nil {
                appDelegate.mReader?.disconnect()
                appDelegate.mReader = nil
            }
            if appDelegate.mPeripheral != nil {
                appDelegate.mCentralManager?.cancelPeripheralConnection(appDelegate.mPeripheral!)
                appDelegate.mPeripheral = nil
            }
            viewWillAppear(true)
        }
        
    }
    
    @IBAction func optionBarItemTapped(_ sender: UIBarButtonItem) {
        performSegue(withIdentifier: "OptionView", sender: nil)
    }
    @IBAction func paramTopViewCancel(_ sender: UIButton) {
        paramSettingShow(mode: true)
    }
    @IBAction func paramTopViewOK(_ sender: UIButton) {
        let idx = paramPickerView.selectedRow(inComponent: 0)
        if(paramPickerView.tag == READ_PICKER_VIEW_BANK){
            bankValue = idx
        } else if(paramPickerView.tag == READ_PICKER_VIEW_OFFSET){
            offsetValue = idx
        } else if(paramPickerView.tag == READ_PICKER_VIEW_LENGTH){
            lengthValue = idx
        }
        paramTextSet()
        paramSettingShow(mode: true)
    }
    @IBAction func bankBtnTapped(_ sender: UIButton) {
        paramPickerView.tag = READ_PICKER_VIEW_BANK
        self.paramPickerView.reloadAllComponents()
        paramPickerView.selectRow(bankValue, inComponent: 0, animated: false)
        paramSettingShow(mode: false)
    }
    @IBAction func offsetBtnTapped(_ sender: UIButton) {
        paramPickerView.tag = READ_PICKER_VIEW_OFFSET
        self.paramPickerView.reloadAllComponents()
        paramPickerView.selectRow(offsetValue, inComponent: 0, animated: false)
        paramSettingShow(mode: false)
    }
    @IBAction func lengthBtnTapped(_ sender: UIButton) {
        paramPickerView.tag = READ_PICKER_VIEW_LENGTH
        self.paramPickerView.reloadAllComponents()
        paramPickerView.selectRow(lengthValue, inComponent: 0, animated: false)
        paramSettingShow(mode: false)
    }
    @IBAction func passwordBtnTapped(_ sender: UIButton) {
        let alert = UIAlertController(title: "Password", message:"Please enter Password", preferredStyle: .alert)
        alert.addTextField(configurationHandler: {(_ textField: UITextField) -> Void in textField.keyboardType = .numberPad })
        let ok = UIAlertAction(title: "OK", style: .default, handler: {(_ action: UIAlertAction) -> Void in
            let textField: UITextField? = alert.textFields?.first
            self.passwordValue = (textField?.text)!
            self.paramTextSet()
            alert.dismiss(animated: true) {() -> Void in}
        })
        let cancel = UIAlertAction(title: "Cancel", style: .default, handler: {(_ action: UIAlertAction) -> Void in
            alert.dismiss(animated: true) {() -> Void in }
        })
        alert.addAction(cancel)
        alert.addAction(ok)
        
        DispatchQueue.main.async(execute: {() -> Void in
            self.present(alert, animated: true) {() -> Void in }
        })
    }
    @IBAction func writeDataBtnTapped(_ sender: UIButton) {
        let alert = UIAlertController(title: "Write Data:", message:"Please enter Write data.", preferredStyle: .alert)
        alert.addTextField(configurationHandler: {(_ textField: UITextField) -> Void in textField.keyboardType = .alphabet; textField.delegate = self as UITextFieldDelegate})
        let ok = UIAlertAction(title: "OK", style: .default, handler: {(_ action: UIAlertAction) -> Void in
            let textField: UITextField? = alert.textFields?.first
            self.writedataTextField.text = textField!.text
            self.writedataValue = textField!.text!
            alert.dismiss(animated: true) {() -> Void in}
        })
        let cancel = UIAlertAction(title: "Cancel", style: .default, handler: {(_ action: UIAlertAction) -> Void in
            alert.dismiss(animated: true) {() -> Void in }
        })
        alert.addAction(cancel)
        alert.addAction(ok)
        
        DispatchQueue.main.async(execute: {() -> Void in
            self.present(alert, animated: true) {() -> Void in }
        })
    }
    @IBAction func writeBtnTapped(_ sender: UIButton) {
        isActionResult = false
        epcData.text = "Write tag memory. Please wait…";
        appDelegate.mReader?.accessPassword = passwordValue
        appDelegate.mReader?.writeMemory(BankType(rawValue: BankType.RawValue(bankValue)), offset: Int32(offsetValue), value: writedataValue)
        
        notiAlert = UIAlertController(title: "Please wait...", message:"Write tag memory", preferredStyle: .alert)
        
        let ok = UIAlertAction(title: "OK", style: .default, handler: {(_ action: UIAlertAction) -> Void in
            
            //self.appDelegate.mReader?.stop
            self.notiAlert?.dismiss(animated: true) {() -> Void in}
        })
        
        notiAlert?.addAction(ok)
        
        DispatchQueue.main.async(execute: {() -> Void in
            self.present(self.notiAlert!, animated: true) {() -> Void in }
        })
    }
    @IBAction func clearBtnTapped(_ sender: UIButton) {
       cleanData()
    }
    @objc func bluetoothDisconnected(_ notification: Notification){
        appDelegate.mReader = nil
        appDelegate.mPeripheral = nil
        appDelegate.connectflag = false
        let dialog = UIAlertController(title: "Connect State", message: "BT Disconnected!!!", preferredStyle: .alert)
        let action = UIAlertAction(title: "OK", style: UIAlertAction.Style.default)
        dialog.addAction(action)
        self.present(dialog, animated: true, completion: nil)
        
        //        performSegue(withIdentifier: "BTConnect", sender: nil)
         viewWillAppear(true)
    }
    /*
    // MARK: - Navigation

    // In a storyboard-based application, you will often want to do a little preparation before navigation
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        // Get the new view controller using segue.destinationViewController.
        // Pass the selected object to the new view controller.
    }
    */

}
