<commit_before>//
//  AddAccountQRViewController.swift
//  EmonCMSiOS
//
//  Created by <NAME> on 12/09/2016.
//  Copyright © 2016 <NAME>. All rights reserved.
//

import UIKit
import AVFoundation

protocol AddAccountQRViewControllerDelegate: class {
  func addAccountQRViewController(controller: AddAccountQRViewController, didFinishWithAccount account: Account)
  func addAccountQRViewControllerDidCancel(controller: AddAccountQRViewController)
}

class AddAccountQRViewController: UIViewController {

  weak var delegate: AddAccountQRViewControllerDelegate?

  @IBOutlet var playerLayerView: UIView!

  var captureSession: AVCaptureSession?
  var videoPreviewLayer: AVCaptureVideoPreviewLayer?

  override func viewDidLoad() {
    super.viewDidLoad()

    self.title = "Scan Code"
    self.navigationItem.leftBarButtonItem = UIBarButtonItem(barButtonSystemItem: .cancel, target: self, action: #selector(cancel))
  }

  override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    self.checkCameraPermissionAndSetupStack()
    self.captureSession?.startRunning()
  }

  override func viewDidDisappear(_ animated: Bool) {
    super.viewDidDisappear(animated)
    self.captureSession?.stopRunning()
  }

  override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
    self.videoPreviewLayer?.frame = self.playerLayerView.bounds
  }

  private dynamic func cancel() {
    self.delegate?.addAccountQRViewControllerDidCancel(controller: self)
  }

  private func checkCameraPermissionAndSetupStack() {
    guard self.captureSession == nil else { return }

    let authStatus = AVCaptureDevice.authorizationStatus(forMediaType: AVMediaTypeVideo)
    switch authStatus {
    case .authorized:
      self.setupAVStack()
    case .notDetermined:
      self.askForCameraPermission()
    case .denied:
      self.presentCameraRequiredDialog()
    case .restricted:
      self.presentCameraRestrictedDialog()
    }
  }

  private func setupAVStack() {
    let captureDevice = AVCaptureDevice.defaultDevice(withMediaType: AVMediaTypeVideo)

    do {
      let captureSession = AVCaptureSession()

      let input = try AVCaptureDeviceInput(device: captureDevice)
      captureSession.addInput(input)

      let captureMetadataOutput = AVCaptureMetadataOutput()
      captureMetadataOutput.setMetadataObjectsDelegate(self, queue: DispatchQueue.main)
      captureSession.addOutput(captureMetadataOutput)
      captureMetadataOutput.metadataObjectTypes = [AVMetadataObjectTypeQRCode]

      if let videoPreviewLayer = AVCaptureVideoPreviewLayer(session: captureSession) {
        videoPreviewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill
        videoPreviewLayer.frame = self.playerLayerView.bounds
        self.videoPreviewLayer = videoPreviewLayer
        self.playerLayerView.layer.addSublayer(videoPreviewLayer)
      }

      self.captureSession = captureSession
      captureSession.startRunning()
    } catch {
      print("Error setting up AV stack: \(error)")
    }
  }

  private func askForCameraPermission() {
    AVCaptureDevice.requestAccess(forMediaType: AVMediaTypeVideo) { (enabled) in
      if enabled {
        self.setupAVStack()
      } else {
        self.presentCameraRequiredDialog()
      }
    }
  }

  private func presentCameraRequiredDialog() {
    let alert = UIAlertController(title: "Camera Required", message: "Camera access is required for QR code scanning to work. Turn on camera permission in Settings.", preferredStyle: .alert)
    alert.addAction(UIAlertAction(title: "Go to Settings", style: .default, handler: { _ in
      if let url = URL(string: UIApplicationOpenSettingsURLString) {<commit_msg>Make sure we're on the main thread - this completion block can be called on any thread<commit_after>//
//  AddAccountQRViewController.swift
//  EmonCMSiOS
//
//  Created by <NAME> on 12/09/2016.
//  Copyright © 2016 <NAME>. All rights reserved.
//

import UIKit
import AVFoundation

protocol AddAccountQRViewControllerDelegate: class {
  func addAccountQRViewController(controller: AddAccountQRViewController, didFinishWithAccount account: Account)
  func addAccountQRViewControllerDidCancel(controller: AddAccountQRViewController)
}

class AddAccountQRViewController: UIViewController {

  weak var delegate: AddAccountQRViewControllerDelegate?

  @IBOutlet var playerLayerView: UIView!

  var captureSession: AVCaptureSession?
  var videoPreviewLayer: AVCaptureVideoPreviewLayer?

  override func viewDidLoad() {
    super.viewDidLoad()

    self.title = "Scan Code"
    self.navigationItem.leftBarButtonItem = UIBarButtonItem(barButtonSystemItem: .cancel, target: self, action: #selector(cancel))
  }

  override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    self.checkCameraPermissionAndSetupStack()
    self.captureSession?.startRunning()
  }

  override func viewDidDisappear(_ animated: Bool) {
    super.viewDidDisappear(animated)
    self.captureSession?.stopRunning()
  }

  override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
    self.videoPreviewLayer?.frame = self.playerLayerView.bounds
  }

  private dynamic func cancel() {
    self.delegate?.addAccountQRViewControllerDidCancel(controller: self)
  }

  private func checkCameraPermissionAndSetupStack() {
    guard self.captureSession == nil else { return }

    let authStatus = AVCaptureDevice.authorizationStatus(forMediaType: AVMediaTypeVideo)
    switch authStatus {
    case .authorized:
      self.setupAVStack()
    case .notDetermined:
      self.askForCameraPermission()
    case .denied:
      self.presentCameraRequiredDialog()
    case .restricted:
      self.presentCameraRestrictedDialog()
    }
  }

  private func setupAVStack() {
    let captureDevice = AVCaptureDevice.defaultDevice(withMediaType: AVMediaTypeVideo)

    do {
      let captureSession = AVCaptureSession()

      let input = try AVCaptureDeviceInput(device: captureDevice)
      captureSession.addInput(input)

      let captureMetadataOutput = AVCaptureMetadataOutput()
      captureMetadataOutput.setMetadataObjectsDelegate(self, queue: DispatchQueue.main)
      captureSession.addOutput(captureMetadataOutput)
      captureMetadataOutput.metadataObjectTypes = [AVMetadataObjectTypeQRCode]

      if let videoPreviewLayer = AVCaptureVideoPreviewLayer(session: captureSession) {
        videoPreviewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill
        videoPreviewLayer.frame = self.playerLayerView.bounds
        self.videoPreviewLayer = videoPreviewLayer
        self.playerLayerView.layer.addSublayer(videoPreviewLayer)
      }

      self.captureSession = captureSession
      captureSession.startRunning()
    } catch {
      print("Error setting up AV stack: \(error)")
    }
  }

  private func askForCameraPermission() {
    AVCaptureDevice.requestAccess(forMediaType: AVMediaTypeVideo) { (enabled) in
      DispatchQueue.main.async {
        if enabled {
          self.setupAVStack()
        } else {
          self.presentCameraRequiredDialog()
        }
      }
    }
  }

  private func presentCameraRequiredDialog() {
    let alert = UIAlertController(title: "Camera Required", message: "Camera access is required for QR code scanning to work. Turn on camera permission in Settings.", preferredStyle: .alert)
    alert.addAction(UIAlertAction(title: "Go to Settings", style: .default, handler: { _ in
      if let url = URL(string: UIApplicationOpenSettingsURLString) {
{'fraction_non_alphanumeric': 0.07858861267040898, 'fraction_numerical': 0.0032076984763432237, 'mean_word_length': 4.192921582234559, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3129351', 'n_tokens_mistral': 2074, 'n_tokens_neox': 1987, 'n_words': 446}