//
//  BTConnectTableViewController.swift
//  DeviceOption_ATIDReader
//
//  Created by 류은주 on 2018. 2. 23..
//  Copyright © 2018년 류은주. All rights reserved.
//

import UIKit

class BTConnectTableViewController: UITableViewController, CBCentralManagerDelegate, CBPeripheralDelegate, EADeviceInitializeDelegate, EAReaderDelegate {
    
    @IBOutlet var btTableView: UITableView!
    var appDelegate = UIApplication.shared.delegate as! AppDelegate
    
    var mQueue: DispatchQueue?
    var peripheralArray: NSMutableArray = []
    var mDevice = EADeviceBluetoothLe()
    weak var readerDelegate: EAReaderDelegate?
    var wrongdeviceflag = 0;
    fileprivate let data = NSMutableData()

    var devicetype: Int = 0

    override func viewDidLoad() {
        super.viewDidLoad()

        // Uncomment the following line to preserve selection between presentations
        // self.clearsSelectionOnViewWillAppear = false

        // Uncomment the following line to display an Edit button in the navigation bar for this view controller.
        // self.navigationItem.rightBarButtonItem = self.editButtonItem
    }

    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        peripheralArray.removeAllObjects()
        mQueue = DispatchQueue(label: "com.atid.bluetooth")
        appDelegate.mCentralManager = CBCentralManager(delegate: self, queue: mQueue)
    }
    
    override func viewWillDisappear(_ animated: Bool) {
        super.viewDidAppear(animated)
        appDelegate.mCentralManager?.stopScan()
    }
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
    
    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?.range(of: "AT188") != nil) || ( peripheral.name?.range(of: "AT288") != nil) || ( peripheral.name?.range(of: "AT388") != nil) || ( peripheral.name?.range(of: "ATS100") != 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.btTableView.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.btTableView.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.peripheralArray.removeAllObjects()
                self.appDelegate.connectflag = true
//                if ( self.appDelegate.devicename?.range(of: "ATS100") != nil) {
//                    self.buttonNotiData = ["Beep", "Vibrate", "Ligth(Not Support)"]
//                } else {
//                    self.buttonNotiData = ["Beep", "Vibrate", "Ligth"]
//                }
                self.performSegue(withIdentifier: "DeviceOption", sender: nil)
                
            }else {
                self.wrongdeviceflag = 0;
                self.disconnect()
            }
//            self.viewWillAppear(true)
//            self.HUD.hide(true)
        })
    }
    

    // MARK: - Table view data source

    override func numberOfSections(in tableView: UITableView) -> Int {
        // #warning Incomplete implementation, return the number of sections
        return 1
    }

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        // #warning Incomplete implementation, return the number of rows
        return peripheralArray.count
    }

   
    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "BTCell", for: indexPath)

        // Configure the cell...
        cell.textLabel?.text = (peripheralArray[indexPath.item] as AnyObject).name
        return cell
    }
    override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        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
    }

    /*
    // Override to support conditional editing of the table view.
    override func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
        // Return false if you do not want the specified item to be editable.
        return true
    }
    */

    /*
    // Override to support editing the table view.
    override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
        if editingStyle == .delete {
            // Delete the row from the data source
            tableView.deleteRows(at: [indexPath], with: .fade)
        } else if editingStyle == .insert {
            // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
        }    
    }
    */

    /*
    // Override to support rearranging the table view.
    override func tableView(_ tableView: UITableView, moveRowAt fromIndexPath: IndexPath, to: IndexPath) {

    }
    */

    /*
    // Override to support conditional rearranging of the table view.
    override func tableView(_ tableView: UITableView, canMoveRowAt indexPath: IndexPath) -> Bool {
        // Return false if you do not want the item to be re-orderable.
        return 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.
    }
    */
    func disconnect() {
        appDelegate.mReader?.disconnect()
        
        appDelegate.mReader = nil
        
        // cc 종료 확인 필요........
        //        if appDelegate.mPeripheral != nil {
        appDelegate.mCentralManager?.cancelPeripheralConnection(appDelegate.mPeripheral!)
        appDelegate.mPeripheral = nil
        //        }
    }
}
