//
//  ST25DVI2CDemoViewController.swift
//  ST25NFCApp
//
//  Created by Vincent LATORRE on 8/1/19.
//  Copyright © 2019 STMicroelectronics. All rights reserved.
//

import UIKit
import CoreNFC

class ST25DVI2CDemoViewController: UIViewController,NFCTagReaderSessionDelegate,UITextFieldDelegate {

    // Reference the NFC session
    private var tagSession: NFCTagReaderSession!
    private var writeBuffer: Bool!
    
    @IBOutlet weak var readBufferTextView: UITextView!
    @IBOutlet weak var readWriteSwitch: UISwitch!
    @IBOutlet weak var bufferTextField: UITextField!
    
    @IBAction func handleReadWriteSwitch(_ sender: Any) {
       bufferTextField.isEnabled = self.readWriteSwitch.isOn
       writeBuffer = self.readWriteSwitch.isOn
    }
    
    @IBAction func handleStart(_ sender: Any) {
        var status = true
        var errorMessage:String = ""
        if (self.readWriteSwitch.isOn) {
            if (bufferTextField.text!.isEmpty) {
                errorMessage = "Buffer is empty !!!"
                status = false
            }
            if ((bufferTextField.text!.count % 2) != 0) {
                errorMessage = "Buffer should contain an even number of characters !!!"
                status = false
            }
        }
        if ( status == false ) {
            let alertController = UIAlertController(
                title: "ST25DV-I2C Start",
                message: errorMessage,
                preferredStyle: .alert
            )
            alertController.addAction(UIAlertAction(title: "OK", style: .default, handler: nil))
            self.present(alertController, animated: true, completion: nil)
            return
        }
            
        
        startSession()
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.
        self.bufferTextField.isEnabled = self.readWriteSwitch.isOn
        writeBuffer = self.readWriteSwitch.isOn
        
    }
    
    // UITextFieldDelegate method
    func textFieldShouldReturn(_ textField: UITextField) -> Bool // called when 'return' key pressed. return NO to ignore.
     {
        textField .resignFirstResponder()
        return true;
     }
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?)
    {
        self.view.endEditing(true)
    }
    
    
    func startSession() {
        guard NFCNDEFReaderSession.readingAvailable else {
                let alertController = UIAlertController(
                    title: "Scanning Not Supported",
                    message: "This device doesn't support tag scanning.",
                    preferredStyle: .alert
                )
                alertController.addAction(UIAlertAction(title: "OK", style: .default, handler: nil))
                self.present(alertController, animated: true, completion: nil)
                return
            }
            
            tagSession = NFCTagReaderSession(pollingOption: [.iso15693], delegate: self, queue: nil)
       
            tagSession?.alertMessage = "Hold your iPhone near an NFC tag to start ST25DV-PWM Demo."
            tagSession?.begin()
       }

    func tagRemovalDetect(_ tag: NFCTag) {
           self.tagSession?.connect(to: tag) { (error: Error?) in
               if error != nil || !tag.isAvailable {
         
                   self.tagSession?.restartPolling()
                   return
               }
               DispatchQueue.global().asyncAfter(deadline: DispatchTime.now() + .milliseconds(500), execute: {
                   self.tagRemovalDetect(tag)
               })
           }
       }
       
       // NFCTagReaderSessionDelegate
       func tagReaderSessionDidBecomeActive(_ session: NFCTagReaderSession) {
           // If necessary, you may perform additional operations on session start.
           // At this point RF polling is enabled.
       }
       
       func tagReaderSession(_ session: NFCTagReaderSession, didInvalidateWithError error: Error) {
           // If necessary, you may handle the error. Note session is no longer valid.
           // You must create a new session to restart RF polling.
           //session.restartPolling();
           session.invalidate();
       }
       
       func tagReaderSession(_ session: NFCTagReaderSession, didDetect tags: [NFCTag]) {
           if tags.count > 1 {
               tagSession.alertMessage = "More than 1 tags was found. Please present only 1 tag."
               //tagSession.restartPolling()
               self.tagRemovalDetect(tags.first!)
               return
           }
           
           var iso15693Tag: NFCISO15693Tag!
           
           switch tags.first! {
               case let .iso15693(tag):
                   iso15693Tag = tag .asNFCISO15693Tag()!
               break
               
          @unknown default:
               session.invalidate(errorMessage: "Tag not valid or not type5")
               //session.restartPolling()
               return
           }
        
            session.connect(to: tags.first!) { (error: Error?) in
                if error != nil {
                    session.invalidate(errorMessage: "Connection error. Please try again.")
                    return
                }
            
           /* Present PWD MB */
            iso15693Tag.customCommand(requestFlags: RequestFlag(rawValue: 0x02), customCommandCode: 0xB3, customRequestParameters: Data(bytes: [0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00])){ (response: Data, error: Error?) in
                if error != nil {
                    session.invalidate(errorMessage: "Present PWD. Please try again."+error!.localizedDescription)
                    print(error!.localizedDescription)
                    return
                }
            }
            /* Enable MB*/
            iso15693Tag.customCommand(requestFlags: RequestFlag(rawValue: 0x02), customCommandCode: 0xA1, customRequestParameters: Data(bytes: [0x0D,0x01])){ (response: Data, error: Error?) in
                if error != nil {
                    session.invalidate(errorMessage: "Enable Mail Box. Please try again."+error!.localizedDescription)
                    print(error!.localizedDescription)
                    return
                }
                print (response.toHexString())
                if (!response.isEmpty){
                    session.invalidate(errorMessage: "Response Enable Mail. Please try again.")
                    return
                }
            }
            /* Read full Buffer from MB*/
            iso15693Tag.customCommand(requestFlags: RequestFlag(rawValue: 0x02), customCommandCode: 0xAC, customRequestParameters: Data(bytes: [0x00,0x00])){ (response: Data, error: Error?) in
                if error != nil {
                    session.invalidate(errorMessage: "Read Buffer Mail Box. Please try again."+error!.localizedDescription)
                    print(error!.localizedDescription)
                    //return
                }
                DispatchQueue.main.sync {
                    self.readBufferTextView.text = response.toHexString().replacingOccurrences(of: " ", with: "")
                    
                }
                if (self.writeBuffer == false){
                    session.invalidate()
                }
            }
  
                if (self.writeBuffer) {
                    // Creating buffer to write
                    var bufferData:NSData!
                    DispatchQueue.main.sync {
                        let bufferIOSByteArray = ComStSt25sdkHelper.convertHexStringToByteArray(with: self.bufferTextField.text)
                        bufferData = bufferIOSByteArray?.toNSData() as NSData?
                    }
                    var data = Data(referencing: bufferData)
                    data.insert(Data.Element(bufferData.length-1), at: 0)

         
                    /* Write Buffer in MB*/
                    iso15693Tag.customCommand(requestFlags: RequestFlag(rawValue: 0x02), customCommandCode: 0xAA, customRequestParameters: data){ (response: Data, error: Error?) in
                        if error != nil {
                            session.invalidate(errorMessage: "Write Buffer Mail Box. Please try again."+error!.localizedDescription)
                            print(error!.localizedDescription)
                            return
                        }
                        print (response.toHexString())
                        if (!response.isEmpty){
                            session.invalidate(errorMessage: "Response Write Buffer Mail Box. Please try again.")
                            return
                        }else{
                           session.invalidate()
                            /*
                           DispatchQueue.main.sync {
                                       let alertController = UIAlertController(
                                                                           title: "CustomCommand",
                                                                           message: "UID = \(iso15693Tag.identifier.toHexString())\nresponse= \(response.toHexString()) ",
                                                                           preferredStyle: .alert
                                                                       )
                                                                       alertController.addAction(UIAlertAction(title: "OK", style: .default, handler: nil))
                                                                       self.present(alertController, animated: true, completion: nil)
                                                                       return
                                       }
                             */
                         } // else
                    } // custom command
             }// if switch
           }
       }


}
