//
//  InventoryViewController.swift
//  
//
//  Created by 류은주 on 2017. 12. 7..
//
let TABLE_VIEW_CONNECT = 0
let TABLE_VIEW_TRIGGER = 1

import UIKit

class TriggerViewController: UIViewController, CBCentralManagerDelegate, CBPeripheralDelegate, UITableViewDataSource,  UITableViewDelegate, EADeviceInitializeDelegate, EAReaderDelegate
{
    
//    @IBOutlet weak var InventoryTableView: UITableView!
    @IBOutlet weak var TriggerTableView: UITableView!
    @IBOutlet weak var triggerCountLabel: UILabel!
    @IBOutlet weak var leftCountLabel: UILabel!
    @IBOutlet weak var rightCountLabel: UILabel!
    @IBOutlet weak var searchBtn: UIButton!
    @IBOutlet weak var cancelBarItem: UIBarButtonItem!
    
    var appDelegate = UIApplication.shared.delegate as! AppDelegate
    var mQueue: DispatchQueue?
    var peripheralArray: NSMutableArray = []
    var keystate = [AnyHashable]()
    
    var mDevice = EADeviceBluetoothLe()
    weak var readerDelegate: EAReaderDelegate?
    
     var wrongdeviceflag = 0;
    
    fileprivate let data = NSMutableData()
    
    var totalcount = 0
    var triggerupcount = 0
    var triggerdowncount = 0
    var leftupcount = 0
    var leftdowncount = 0
    var rightupcount = 0
    var rightdowncount = 0
    
    var HUD = MBProgressHUD()
    
    var isDeviceOn = false
    var connectprocess = false
    var connectName = ""

    
    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.
        
        
        let center = NotificationCenter.default
        center.addObserver(self, selector: #selector(bluetoothDisconnected), name: NSNotification.Name.init(rawValue: "BluetoothDisconnected"), object: nil)
        let wrongnoti = NotificationCenter.default
        wrongnoti.addObserver(self, selector: #selector(self.wrongdeviceconnected), name: NSNotification.Name.init(rawValue: "wrongdeviceconnected"), object: nil)
        
    }

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        if appDelegate.mPeripheral != nil{
            viewmode(mode: true)
        } else {
            viewmode(mode: false)
        }
        TriggerTableView.reloadData()
    }

    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        appDelegate.mReader?.setTagDataType(0)
        if appDelegate.mReader?.getAction() != CommandStop {
            appDelegate.mReader?.stop()
        }
         NotificationCenter.default.removeObserver(self, name: NSNotification.Name(rawValue: "BluetoothDisconnected"), object: nil)
        NotificationCenter.default.removeObserver(self, name: NSNotification.Name(rawValue: "wrongdeviceconnected"), object: nil)
    }
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
    

    /*
    // MARK: - Navigation

    // In a storybodard-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.
    }
    */
    @objc func opmodesetting(_ mode: Int) {
        if mode != 4 {
            let alert = UIAlertController(title: "Trigger Mode", message: "Trigger Mode Disabled. It can not detect trigger action", preferredStyle: .alert)
            let ok = UIAlertAction(title: "OK", style: .default, handler: {(_ action: UIAlertAction) -> Void in
                alert.dismiss(animated: true) {() -> Void in }
            })
            alert.addAction(ok)
            self.present(alert, animated: true, completion: nil)
        }
    }
    
    @objc func triggerKeyEvent(_ triggerKey: Int, event: Int){
         totalcount += 1
        var keyinput = 0
        if triggerKey == 0 {
            if event == 1 {
                keyinput = 1
                triggerdowncount += 1
            } else {
                keyinput = 0
                triggerupcount += 1
            }
        } else if triggerKey == 1 {
            if event == 1 {
                keyinput = 3
                leftdowncount += 1
            } else {
                keyinput = 2
                leftupcount += 1
            }
        } else if triggerKey == 2 {
            if event == 1 {
                keyinput = 5
                rightdowncount += 1
            } else {
                keyinput = 4
                rightupcount += 1
            }
        }
        keystate.append(keyinput)
        triggerCountLabel.text = String (format:"Trigger UP :  %d /  Trigger DOWN :  %d",triggerupcount,triggerdowncount)
//        leftCountLabel.text = String (format:"Left UP :  %d /  Left DOWN :  %d",leftupcount,leftdowncount)
//        rightCountLabel.text = String (format:"Right UP :  %d /  Right DOWN :  %d",rightupcount,rightdowncount)
        TriggerTableView.reloadData()
    }
/*    func usbConnectEvent(_ usbconnect: Int, event: Int) {
        print("InventoryView Trigger Key Event \(event)")
        //    if(usbconnect == 0){
        if event == 1 {
            print("usbConnectEvent Connect")
            usbConnect = 1
            usbConnectBtn.setTitle("STOP USB Charging", for: UIControlState.normal)
            usbConnectBtn.isEnabled = true
            let alert = UIAlertController(title: "USB Connected", message: """
 USB Connected select to start charging
 or
 Do Nothing
 """, preferredStyle: .alert)
            let Start = UIAlertAction(title: "OK", style: .default, handler: {(_ action: UIAlertAction) -> Void in
                
//              appDelegate.mReader

                alert.dismiss(animated: true) {() -> Void in }
            })
            let ok = UIAlertAction(title: "OK", style: .default, handler: {(_ action: UIAlertAction) -> Void in
                alert.dismiss(animated: true) {() -> Void in }
            })
            alert.addAction(ok)
        }
        else {
            print("usbConnectEvent Disconnect")
            usbConnect = 0
            usbConnectBtn.setTitle("START USB Charging", for: UIControlState.normal)
            usbConnectBtn.isEnabled = false
            let alert = UIAlertController(title: "USB Connection", message: "USB Disconnected", preferredStyle: .alert)
            let ok = UIAlertAction(title: "OK", style: .default, handler: {(_ action: UIAlertAction) -> Void in
                alert.dismiss(animated: true) {() -> Void in }
            })
            alert.addAction(ok)
        }
        //    }
    }*/
    func centralManagerDidUpdateState(_ central: CBCentralManager) {
        if central.state == .poweredOff {
            NotificationCenter.default.post(name: NSNotification.Name("BluetoothDisconnected"), object: self)
        }
        
        guard central.state  == .poweredOn else {
            // In a real app, you'd deal with all the states correctly
            return
        }
        // The state must be CBCentralManagerStatePoweredOn...
        // ... so start scanning
        scan()
    }
    
    /** Scan for peripherals - specifically for our service's 128bit CBUUID
     */
    func scan() {
        
        appDelegate.mCentralManager?.scanForPeripherals(withServices: nil, options: [
            CBCentralManagerScanOptionAllowDuplicatesKey : NSNumber(value: true as Bool)
            ]
        )
        
        print("Scanning started")
    }
    
    func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber) {
        if (peripheral.name == connectName) {
            isDeviceOn = true
        }
        if ( (peripheral.name?.range(of: "ATS100") != nil) || ((peripheral.name?.range(of: "ATS200") != nil)) )  {
            // Ok, it's in range - have we already seen it?
            
            if appDelegate.mPeripheral != peripheral {
                // Save a local copy of the peripheral, so CoreBluetooth doesn't get rid of it
                
                // And connect
                print("Discover to peripheral \(peripheral)")
                
                if peripheralArray.count < 1 {
                    peripheralArray.addObjects(from: [peripheral])
                    DispatchQueue.main.async(execute: {() -> Void in
                        self.TriggerTableView.reloadData()
                    })
                } else {
                    var check = 0
                    for i in 0...peripheralArray.count-1{
                        if peripheral.name == (peripheralArray[i] as AnyObject).name{
                            check = 1
                        }
                    }
                    
                    if check == 0 {
                        peripheralArray.addObjects(from: [peripheral])
                        DispatchQueue.main.async(execute: {() -> Void in
                            self.TriggerTableView.reloadData()
                        })
                    }
                }
            }
        }
    }
    
    func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral) {
        print("Peripheral Connected")
        
        data.length = 0
        
        mDevice = EADeviceBluetoothLe(peripheral: peripheral, delegate: self as EADeviceInitializeDelegate)
        // Stop scanning
        appDelegate.mCentralManager?.stopScan()
        
        print("Scanning stopped")
        
        
    }
    
    func centralManager(_ central: CBCentralManager, didDisconnectPeripheral peripheral: CBPeripheral, error: Error?) {
        DispatchQueue.main.async(execute: {() -> Void in
            NotificationCenter.default.post(name: NSNotification.Name("BluetoothDisconnected"), object: self)
        })
        print("Disconnect Success")
        viewinitial()
        viewmode(mode: false)
    }
    func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor characteristic: CBCharacteristic, error: Error?) {
        guard error == nil else {
            print("Error discovering services: \(error!.localizedDescription)")
            return
        }
        
        guard let stringFromData = NSString(data: characteristic.value!, encoding: String.Encoding.utf8.rawValue) else {
            print("Invalid data")
            return
        }
        
        // Have we got everything we need?
        if stringFromData.isEqual(to: "EOM") {
            // We have, so show the data,
            //            textView.text = String(data: data.copy() as! Data, encoding: String.Encoding.utf8)
            
            // Cancel our subscription to the characteristic
            peripheral.setNotifyValue(false, for: characteristic)
            
            // and disconnect from the peripehral
            appDelegate.mCentralManager?.cancelPeripheralConnection(peripheral)
        } else {
            // Otherwise, just add the data on to what we already have
            data.append(characteristic.value!)
            
            // Log it
            print("Received: \(stringFromData)")
        }
    }
    
    /** The peripheral letting us know whether our subscribe/unsubscribe happened or not
     */
    func peripheral(_ peripheral: CBPeripheral, didUpdateNotificationStateFor characteristic: CBCharacteristic, error: Error?) {
        print("Error changing notification state: \(String(describing: error?.localizedDescription))")
        
        // Exit if it's not the transfer characteristic
        //        guard characteristic.uuid.isEqual(transferCharacteristicUUID) else {
        //            return
        //        }
        
        // Notification has started
        if (characteristic.isNotifying) {
            print("Notification began on \(characteristic)")
        } else { // Notification has stopped
            print("Notification stopped on (\(characteristic))  Disconnecting")
            appDelegate.mCentralManager?.cancelPeripheralConnection(peripheral)
        }
    }
    func didCompleteInitialize(_ error: Error!) {
        appDelegate.mReader = EAReader(device: mDevice, delegate: readerDelegate)
        print("didCompleteInitialize finish")
        appDelegate.mReader?.setDelegate(self)
        
        DispatchQueue.main.async(execute: {() -> Void in
            if(self.wrongdeviceflag == 0){
                self.searchBtn.setTitle("CLEAR", for: UIControl.State.normal)
                self.viewinitial()
                self.viewmode(mode: true)
                self.appDelegate.mReader?.setTagDataType(TAG_DATA_TYPE_HEX)
                self.appDelegate.mReader?.isUseKeyAction = true
                self.appDelegate.mReader?.setPropBarcodeMode(4)
                self.TriggerTableView.reloadData()
                self.appDelegate.connectFlag = true
            }else {
                self.searchBtn.setTitle("SEARCH", for: UIControl.State.normal)
//                self.disconnect()
                self.wrongdeviceflag = 0;
            }
            
            self.HUD.hide(true)
        })
    }
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        if(TriggerTableView.tag == TABLE_VIEW_TRIGGER){
            return keystate.count
        } else {
            return peripheralArray.count
        }
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "TriggerCell", for: indexPath)
        
        if(TriggerTableView.tag == TABLE_VIEW_TRIGGER){
            let item = keystate[indexPath.row] as? Int
            if item != nil {
                DispatchQueue.main.async(execute: {() -> Void in
                    if item == 0 {
                        cell.textLabel?.text = "Trigger UP"
                    } else if item == 1 {
                        cell.textLabel?.text = "Trigger DOWN"
                    } else  if item == 2 {
                        cell.textLabel?.text = "Left UP"
                    } else if item == 3 {
                        cell.textLabel?.text = "Left DOWN"
                    } else  if item == 4 {
                        cell.textLabel?.text = "Right UP"
                    } else if item == 5 {
                        cell.textLabel?.text = "Right DOWN"
                    }
                })
            }
        } else {
            cell.textLabel?.text = (peripheralArray[indexPath.item] as AnyObject).name
        }
        return cell
    }
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        if(TriggerTableView.tag != TABLE_VIEW_CONNECT){
            return
        }
        
//        appDelegate.mCentralManager?.stopScan()
//        appDelegate.mCentralManager?.connect(peripheralArray[indexPath.item] as! CBPeripheral, options: nil)
//        appDelegate.mPeripheral = peripheralArray[indexPath.item] as? CBPeripheral
//        appDelegate.devicename = (peripheralArray[indexPath.item] as AnyObject).name
//
//        DispatchQueue.main.async(execute: {() -> Void in
//            self.HUD = MBProgressHUD.showAdded(to: self.view, animated: true);
//            self.HUD.labelText = "Connecting..."
//            self.HUD.show(true)
//        })
        isDeviceOn = false
        if(connectprocess == true) {
            return
        } else {
            connectprocess = true
            appDelegate.mCentralManager?.stopScan()
            connectName = (peripheralArray[indexPath.item] as AnyObject).name
            startScanDevice()
            DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + Double(1 * Double(NSEC_PER_SEC)) / Double(NSEC_PER_SEC), execute: {() -> Void in
                self.connectDevice(indexPath.row)
            })
        }
    }
    func viewmode(mode:Bool){
        if(mode == true){
            self.TriggerTableView.tag = TABLE_VIEW_TRIGGER
        } else {
            self.TriggerTableView.tag = TABLE_VIEW_CONNECT
        }
//        DispatchQueue.global(qos: .default).async(execute: {() -> Void in
        
                DispatchQueue.main.async(execute: {() -> Void in
                    if(mode == true){
                        self.searchBtn.setTitle("CLEAR", for: UIControl.State.normal)
                    } else {
                        self.searchBtn.setTitle("SEARCH", for: UIControl.State.normal)
                    }
//                    self.InventoryBtn.isHidden = !mode
                    self.cancelBarItem.isEnabled = mode
                    self.triggerCountLabel.isHidden = !mode
//                    self.leftCountLabel.isHidden = !mode
//                    self.rightCountLabel.isHidden = !mode
                    self.TriggerTableView.reloadData()
            })
//        })
    }
    func viewinitial(){
        triggerupcount = 0
        triggerdowncount = 0
        leftupcount = 0
        leftdowncount = 0
        rightupcount = 0
        rightdowncount = 0
        keystate.removeAll()
        self.totalcount = 0
        self.peripheralArray.removeAllObjects()
//        countLabel.text = String (format:"Key UP :  %d /  Key DOWN :  %d",upcount,downcount)
        DispatchQueue.main.async(execute: {() -> Void in
        self.triggerCountLabel.text = String (format:"Trigger UP :  %d /  Trigger DOWN :  %d",self.triggerupcount,self.triggerdowncount)
        })
//        leftCountLabel.text = String (format:"Left UP :  %d /  Left DOWN :  %d",leftupcount,leftdowncount)
//        rightCountLabel.text = String (format:"Right UP :  %d /  Right DOWN :  %d",rightupcount,rightdowncount)
    }
    func disconnect() {
        if appDelegate.mReader != nil {
            appDelegate.mReader?.disconnect()
            appDelegate.mReader = nil
        }

        // cc 종료 확인 필요........
        if appDelegate.mPeripheral != nil {
            appDelegate.mCentralManager?.cancelPeripheralConnection(appDelegate.mPeripheral!)
            appDelegate.mPeripheral = nil
        }
    }
    @objc func bluetoothDisconnected(_ notification: Notification){
        
        HUD.hide(true)
        HUD.removeFromSuperview()
        
        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)
    }

    @IBAction func cancelBarItemTapped(_ sender: UIBarButtonItem) {
//        appDelegate.mReader?.disconnect()
//
//        if appDelegate.mPeripheral != nil {
//            appDelegate.mCentralManager?.cancelPeripheralConnection(appDelegate.mPeripheral!)
//            appDelegate.mPeripheral = nil
//        }
        disconnect()
    }
    
    @IBAction func searchBtnTapped(_ sender: UIButton) {
        if(TriggerTableView.tag == TABLE_VIEW_CONNECT){
            if searchBtn.currentTitle == "SEARCH" {
                peripheralArray.removeAllObjects()
                mQueue = DispatchQueue(label: "com.atid.bluetooth")
                appDelegate.mCentralManager = CBCentralManager(delegate: self, queue: mQueue)
                DispatchQueue.main.async(execute: {() -> Void in
                    self.searchBtn.setTitle("STOP", for: UIControl.State.normal)
                    
                })
            } else if searchBtn.currentTitle == "STOP" {
                appDelegate.mCentralManager?.stopScan()
                DispatchQueue.main.async(execute: {() -> Void in
                    self.searchBtn.setTitle("SEARCH", for: UIControl.State.normal)
                })
            }
        } else {
            keystate.removeAll()
            totalcount = 0
//            upcount = 0
//            downcount = 0
//            countLabel.text = String (format:"Key UP :  %d /  Key DOWN :  %d",upcount,downcount)
            triggerupcount = 0
            triggerdowncount = 0
            leftupcount = 0
            leftdowncount = 0
            rightupcount = 0
            rightdowncount = 0
            triggerCountLabel.text = String (format:"Trigger UP :  %d /  Trigger DOWN :  %d",triggerupcount,triggerdowncount)
//            leftCountLabel.text = String (format:"Left UP :  %d /  Left DOWN :  %d",leftupcount,leftdowncount)
//            rightCountLabel.text = String (format:"Right UP :  %d /  Right DOWN :  %d",rightupcount,rightdowncount)
            TriggerTableView.reloadData()
        }
    }
    
    @objc func wrongdeviceconnected(_ notification: Notification) {
//        appDelegate.mReader?.disconnect()
        
        wrongdeviceflag = 1
    }
    func startScanDevice() {
        // Make Scan Peripheral Option...
        let options = [
            CBCentralManagerScanOptionAllowDuplicatesKey : (0)
        ]
        //        bleready = 1
        // Start Scan Peripheral Device
        appDelegate.mCentralManager?.scanForPeripherals(withServices: nil, options: options)
        //    }
    }
    func connectDevice(_ index: Int) {
        appDelegate.mCentralManager?.stopScan()
        DispatchQueue.main.async(execute: {() -> Void in
            self.searchBtn.setTitle("SEARCH", for: UIControl.State.normal)
        })
        if isDeviceOn != true {
            let Alert = UIAlertController(title: "Device Power Off", message: "Please check the power of device you want to connect", preferredStyle: .alert)
            let action = UIAlertAction(title: "OK", style: UIAlertAction.Style.default)
            Alert.addAction(action)
            self.present(Alert, animated: true, completion: nil)
            
            connectprocess = false
            
//            peripheralArray.removeAllObjects()
//            TriggerTableView.reloadData()
            return
        }
        
        navigationController?.view.addSubview(HUD)
        DispatchQueue.global(qos: .default).async(execute: {
            self.self.appDelegate.mCentralManager?.stopScan()
            self.appDelegate.mCentralManager?.connect(self.peripheralArray[index] as! CBPeripheral, options: nil)
            self.appDelegate.mPeripheral = self.peripheralArray[index] as? CBPeripheral
            self.appDelegate.devicename = (self.peripheralArray[index] as AnyObject).name
            
            DispatchQueue.main.async(execute: {() -> Void in
                self.HUD = MBProgressHUD.showAdded(to: self.view, animated: true);
                self.HUD.labelText = "Connecting..."
                self.HUD.show(true)
            })
            self.connectprocess = false
        })
    }
}



