//
//  StoredDataViewController.swift
//  StoredData_EAReader
//
//  Created by 류은주 on 2018. 1. 24..
//  Copyright © 2018년 류은주. All rights reserved.
//
let TABLE_VIEW_CONNECT = 0
let TABLE_VIEW_STOREDDATA = 1
    
import UIKit
    
class StoredDataViewController: UIViewController, CBCentralManagerDelegate, CBPeripheralDelegate, UITableViewDataSource,  UITableViewDelegate, EADeviceInitializeDelegate, EAReaderDelegate
{
        
    @IBOutlet weak var StoredTableView: UITableView!
    @IBOutlet weak var storedcountLabel: UILabel!
    @IBOutlet weak var countLabel: UILabel!
//    @IBOutlet weak var searchBtn: UIButton!
    @IBOutlet weak var StoredBtn: UIButton!
    @IBOutlet weak var clearBtn: UIButton!
    @IBOutlet weak var removeBtn: UIButton!
//    @IBOutlet weak var optionBarItem: UIBarButtonItem!
    @IBOutlet weak var cancelBarItem: UIBarButtonItem!
        
        var appDelegate = UIApplication.shared.delegate as! AppDelegate
        var mQueue: DispatchQueue?
        var peripheralArray: NSMutableArray = []
    
        var mapTags = [AnyHashable: Any]()
        var mapBarcodes = [AnyHashable: Any]()
        
        var mDevice = EADeviceBluetoothLe()
        weak var readerDelegate: EAReaderDelegate?
        
        var wrongdeviceflag = 0;
        
        fileprivate let data = NSMutableData()
        
        var totalcount = 0
//        var viewModeFlag = TABLE_VIEW_CONNECT
        var isRssiMode = false
        
        var HUD = MBProgressHUD()
        
        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)
//                viewModeFlag = TABLE_VIEW_STOREDDATA
                isRssiMode = (appDelegate.mReader?.rssiMode)!
            } else {
//                viewModeFlag = TABLE_VIEW_CONNECT
                viewmode(mode: false)
            }
            StoredTableView.reloadData()
        }
        
        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.
        }
        
        
        /*
         // 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 changedActionState(_ action: CommandType) {
            if appDelegate.mReader?.getAction() != CommandStop {
                self.StoredBtn.setTitle("STOP", for: UIControlState.normal)
                cancelBarItem.isEnabled = false
            } else {
                self.StoredBtn.setTitle("INVENTORY", for: UIControlState.normal)
                cancelBarItem.isEnabled = true
            }
        }
        
        @objc  func readTagResult(_ tag: String, rssi: Float, phase: Float) {

            var item = appDelegate.mapTags[tag] as? EATagItems
            if item != nil {
                item?.count += 1
                item?.updateRssi(rssi:rssi, phase: phase)
            }
            else {
                item = EATagItems()
                item = item?.itemWith(tag: tag, rssi: rssi, phase: phase)
                appDelegate.aryTags.append(item ?? EATagItems())
                appDelegate.mapTags[tag] = item
            }
            totalcount += 1
            //        tagCountLabel.text = "\(Int(aryTags.count))/\(mTotalTagCount)"
            print("readTagResult tag: \(tag)")
            countLabel.text = String (format:" %d / %d ",(appDelegate.aryTags.count),totalcount)
            StoredTableView.reloadData()
        }
        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 {
                            self.StoredTableView.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 {
                                self.StoredTableView.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 {
                NotificationCenter.default.post(name: NSNotification.Name("BluetoothDisconnected"), object: self)
                //            self.bluetoothDisconnected()
                //            self.connect.setTitle("Disconnecnt", for: UIControlState.disabled)
                //            self.connect.isHidden = true
            }
            print("Disconnect Success")
            viewinitial()
            viewmode(mode: false)
            //        InventoryTableView.reloadData()
        }
        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 {
                if(self.wrongdeviceflag == 0){
                    self.StoredBtn.setTitle("LOAD", for: UIControlState.normal)
//                    self.viewModeFlag = TABLE_VIEW_STOREDDATA
                    self.viewinitial()
                    self.viewmode(mode: true)
                    self.StoredTableView.reloadData()
                }else {
                    self.StoredBtn.setTitle("SEARCH", for: UIControlState.normal)
                    self.wrongdeviceflag = 0;
                }
                
                self.HUD.hide(true)
            }
        }
        func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
            if(StoredTableView.tag == TABLE_VIEW_STOREDDATA){
                return appDelegate.aryTags.count
            } else {
                return peripheralArray.count
            }
        }
        
        func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
            let cell : StoredTableViewCell = tableView.dequeueReusableCell(withIdentifier: "StoredCell", for: indexPath) as! StoredTableViewCell
            if(StoredTableView.tag == TABLE_VIEW_STOREDDATA){
                let item: EATagItems? = appDelegate.aryTags[indexPath.row] as? EATagItems
                if item != nil {
                    cell.tagValue.text = item?.tag
                    let tagcount = item!.count
                    //            let tagcountstr = String(describing: tagcount)
                    cell.tagCount.text = String(describing: tagcount)
                    //            cell.textLabel?.text = item?.tag
                    //            cell.tagcnt.text = "\(item.count)"
 
                        cell.codeID.text = ""
                }
                //        print("readTagResult item?.tag: \(String(describing: item?.tag)) item?.rssi: \(String(describing: item?.rssi))")
                //        cell.textLabel?.text = (aryTags[indexPath.item] as AnyObject).name
            } else {
                cell.tagValue.text = (peripheralArray[indexPath.item] as AnyObject).name
                cell.tagCount.text = ""
                cell.codeID.text = ""
            }
            return cell
        }
        func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
            if(StoredTableView.tag == TABLE_VIEW_CONNECT){
                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 {
                    //            self.settingIndicator.isHidden = false
                    //            self.settingIndicator.startAnimating()
                    //
                    //            let HUD = MBProgressHUD(view: navigationController?.view)
                    self.HUD = MBProgressHUD.showAdded(to: self.view, animated: true);
                    self.HUD.labelText = "Connecting..."
                    self.HUD.show(true)
                }
            }
        }
        func viewmode(mode:Bool){
            if(mode == true){
                self.StoredTableView.tag = TABLE_VIEW_STOREDDATA
//                viewModeFlag = TABLE_VIEW_STOREDDATA
            } else {
                self.StoredTableView.tag = TABLE_VIEW_CONNECT
//                viewModeFlag = TABLE_VIEW_CONNECT
            }
            //        DispatchQueue.global(qos: .default).async(execute: {() -> Void in
            
            DispatchQueue.main.async(execute: {() -> Void in
//                self.searchBtn.isHidden = mode
//                self.StoredBtn.isHidden = !mode
                self.clearBtn.isHidden = !mode
                self.removeBtn.isHidden = !mode
                self.cancelBarItem.isEnabled = mode
                self.countLabel.isHidden = !mode
                self.StoredTableView.reloadData()
            })
            //        })
        }
        func viewinitial(){
            countLabel.text = String (format:" %d / %d ",(appDelegate.aryTags.count),totalcount)
            self.appDelegate.aryTags.removeAll()
            self.appDelegate.mapTags.removeAll()
            self.totalcount = 0
            self.peripheralArray.removeAllObjects()
        }
        @objc func bluetoothDisconnected(_ notification: Notification){
            appDelegate.mReader = nil
            appDelegate.mPeripheral = nil
            let dialog = UIAlertController(title: "Connect State", message: "BT Disconnected!!!", preferredStyle: .alert)
            let action = UIAlertAction(title: "OK", style: UIAlertActionStyle.default)
            dialog.addAction(action)
            self.present(dialog, animated: true, completion: nil)
            
            //        performSegue(withIdentifier: "BTConnect", sender: nil)
        }
        //    func bluetoothDisconnected(){
        //        appDelegate.mReader = nil
        //        appDelegate.mPeripheral = nil
        //        let dialog = UIAlertController(title: "Connect State", message: "BT Disconnected!!!", preferredStyle: .alert)
        //        let action = UIAlertAction(title: "OK", style: UIAlertActionStyle.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
            }
        }
        
    @IBAction func LoadBtnTapped(_ sender: UIButton) {
        if (self.StoredTableView.tag == TABLE_VIEW_CONNECT) {
            if StoredBtn.currentTitle == "SEARCH" {
                peripheralArray.removeAllObjects()
                mQueue = DispatchQueue(label: "com.atid.bluetooth")
                appDelegate.mCentralManager = CBCentralManager(delegate: self, queue: mQueue)
                DispatchQueue.main.async {
                    self.StoredBtn.setTitle("STOP", for: UIControlState.normal)
                    
                }
            } else {
                appDelegate.mCentralManager?.stopScan()
                if peripheralArray.count >= 1{
                    for i in 0...peripheralArray.count-1 {
                        print("Array: \(peripheralArray[i])")
                    }
                }
                DispatchQueue.main.async {
                    self.StoredBtn.setTitle("SEARCH", for: UIControlState.normal)
                }
            }
        }
        if(self.StoredTableView.tag == TABLE_VIEW_STOREDDATA) {
            appDelegate.mReader?.loadStoredData
        }
    }

        @IBAction func ClearBtnTapped(_ sender: UIButton) {
            //        appDelegate.mReader?.stop()
            appDelegate.aryTags.removeAll()
            appDelegate.mapTags.removeAll()
            totalcount = 0
            countLabel.text = String (format:" %d / %d ",(appDelegate.aryTags.count),totalcount)
            StoredTableView.reloadData()
        }
    @IBAction func removeBtnTapped(_ sender: UIButton) {
      
    }
    @objc func wrongdeviceconnected(_ notification: Notification) {
            appDelegate.mReader?.disconnect()
            
            //        if appDelegate.mPeripheral != nil {
            //            appDelegate.mCentralManager?.cancelPeripheralConnection(appDelegate.mPeripheral!)
            //            appDelegate.mPeripheral = nil
            //        }
            wrongdeviceflag = 1
        }
}
//class EADataItem: NSObject {
//    var barcodeType = BarcodeType()
//    var barcode = ""
//    var doublecheck = ""
//    var tag = ""
//    var count: Int = 0
//}

