//
//  NewFaceShotControllrtExtentsion.swift
//  Gengmei
//
//  Created by 刘鹿杰 on 2019/11/7.
//  Copyright © 2019 更美互动信息科技有限公司. All rights reserved.
//

import Foundation

// 封装照相机的相关方法
@objc extension NewFaceShotController {
    
    // 输出音量设置为系统的 0.6
    func setOutputVolume() {
        //没有声音的时候设置声音
        do{
            try? AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback)
            try? AVAudioSession.sharedInstance().setActive(true)
        }
        if voiceNum < 0.6 {
            UserDefaults.standard.set(0.6, forKey: "humanVoice")
            DaiVolume.setVolume(0.6)
        } else {
            UserDefaults.standard.set(AVAudioSession.sharedInstance().outputVolume, forKey: "humanVoice")
            DaiVolume.setVolume(AVAudioSession.sharedInstance().outputVolume)
        }
    }
    
    // 闪光灯设置
    func changeCameraFlash(flashMode: AVCaptureDevice.FlashMode) {
        do {
            try self.device.lockForConfiguration()
        } catch _ {
            print("lockForConfiguration failed")
        }
        if self.device.isFlashModeSupported(flashMode) {
            self.device.flashMode = flashMode
        }
        self.device.unlockForConfiguration()
    }
    
    // 设置为原始音量
    func setOutputOrigenVolume() {
        guard (voiceNum != nil) else { return }
        DaiVolume.setVolume(voiceNum)
    }
    
    // 相机权限提醒
    func useCameraTips() -> Bool {
        let status = AVCaptureDevice.authorizationStatus(for: AVMediaType.video)
        if !canUseCamera() && status != .notDetermined{
            alertCameraTips()
            return true
        }
        return false
    }
    
    // 相机权限未开启提示框
    func alertCameraTips() {
        let alert = UIAlertController.showCustomAlert(withTitle: "请前往设置开启摄像权限", message: "")
        alert.addAction("取消", actionHandler: {
            self.navigationController?.popViewController(animated: true)
        })
        alert.addAction("去设置", actionHandler: {
            UIApplication.shared.openURL(URL(string: UIApplicationOpenSettingsURLString)!)
        })
    }
    
    func imageFormSampleBuffer(_ sampleBuffer:CMSampleBuffer) {
        let imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer)
        CVPixelBufferLockBaseAddress(imageBuffer!, CVPixelBufferLockFlags(rawValue: CVOptionFlags(0)))
        let height = CVPixelBufferGetHeight(imageBuffer!)
        imgWidth = CGFloat(height)
    }
    
    func saveToFileSystem(_ imageData: Data) {
        let dataProvider = CGDataProvider(data: imageData as CFData)
        var cgImage = CGImage(jpegDataProviderSource: dataProvider!, decode: nil, shouldInterpolate: true, intent: CGColorRenderingIntent.defaultIntent)!
        if cgImage.width > 3264 {
            cgImage = resizeCGImageBySize(cgImage: cgImage, width: 3264, height: 2448)
        }
        let takenImage = UIImage(cgImage: cgImage, scale: 1.0, orientation: UIImage.Orientation.up)
        let rotatedImage = takenImage.imageRotatedByDegrees(90, flip: false)
        let date = Date()
        // 存exif信息
        let container = ExifContainer()
        container.addCreationDate(Date.init(timeIntervalSinceNow: 0))
        container.addExifDictionary(self.exif as? [AnyHashable : Any])
        let imagedataWithExif = rotatedImage.addExif(container)
        let formatter = DateFormatter()
        formatter.dateFormat = "yyyyMMdd_HHmmss"
        timeString = formatter.string(from: date)
        if imagedataWithExif.count == 0 {
            DataHelper.SharedDataHelper.imageData = UIImageJPEGRepresentation(rotatedImage, 0.4)!
        } else {
            DataHelper.SharedDataHelper.imageData = imagedataWithExif
        }
    }
    
    //  MARK: resize CGimage
    func resizeCGImageBySize(cgImage: CGImage, width: Int, height: Int) -> CGImage {
        let bitsPerComponent = cgImage.bitsPerComponent
        let bytesPerRow = cgImage.bytesPerRow
        let colorSpace = cgImage.colorSpace
        let bitmapInfo = cgImage.bitmapInfo
        let context = CGContext(data: nil, width: width, height: height, bitsPerComponent: bitsPerComponent, bytesPerRow: bytesPerRow, space: colorSpace!, bitmapInfo: bitmapInfo.rawValue)
        context!.interpolationQuality = CGInterpolationQuality.high
        context?.draw(cgImage, in: CGRect(origin: CGPoint.zero, size: CGSize(width: CGFloat(width), height: CGFloat(height))))
        let cgImage = context?.makeImage()
        return cgImage!
    }
    
    //  实时判断人脸
    func captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) {
        if (isnoCheckFace || beginToTakePicture) { return }
        
        guard let imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer) else {return}
        let sourceImage = CIImage(cvPixelBuffer: imageBuffer)
        _ = imageFormSampleBuffer(sampleBuffer)
        options = [CIDetectorSmile : false as AnyObject, CIDetectorEyeBlink: true as AnyObject, CIDetectorImageOrientation : 6 as AnyObject]
        // MARK: - 识别图像人脸
        guard let face = self.faceDetector else {return}
        let features = face.features(in: sourceImage, options: options)
        // 未检测到人脸
        DispatchQueue.main.async {
            if (features.count == 0) {
                self.distanceNotRightSetStatus()
                self.faceStatePromter.stopPlayVoice()
                self.skinFrontAIView.tipsLaber.text = ""
                self.skinFrontAIView.closeEyeLabel.isHidden = true
            }
        }
        if (features.count != 0) {  // 如果等于0 就是未检测到人脸
            let feature = features[0] as! CIFaceFeature
            let faceWidth = feature.bounds.width
            
            var imgWidthMin = imgWidth * 0.6
            var imgWidthMax = imgWidth * 0.76
            if cameraDirection == .isCameraFront { // 前置摄像头的话，缩小光圈
                imgWidthMin = imgWidth * 0.5
                imgWidthMax = imgWidth * 0.66
            }
            if faceWidth > imgWidthMin && faceWidth < imgWidthMax {
                getFace += 1
                farFace = 0
                nearFace = 0
                rightFace += 1
            }else if faceWidth < imgWidthMin{
                getFace = 0
                farFace += 1
                nearFace = 0
                rightFace = 0
            }else if faceWidth > imgWidthMax {
                getFace = 0
                nearFace += 1
                farFace = 0
                rightFace = 0
            }
            
            switch UIDevice.current.modelName {
            case "iPhone 5","iPhone 5c","iPhone 5s","iPhone 6","iPhone 6 Plus":
                faceStatePromterType(distancecount: 2)
            default:
                faceStatePromterType(distancecount: 3)
            }
            
            if (self.getFace > 2 && !self.beginToTakePicture && !self.didTakePicture && distanceRight && isDelayShot) {
                isDelayShot = false
                DispatchQueue.main.async {
                    self.perform(#selector(self.distanceRightAndCloseEyes), with: nil, afterDelay: 5.0)
                }
            }
        }
    }
    
    // 设置距离不合适时的状态
    func distanceNotRightSetStatus() {
        NSObject.cancelPreviousPerformRequests(withTarget: self, selector:#selector(self.distanceRightAndCloseEyes), object: nil)
        self.isDelayShot = true
        self.distanceRight = false
    }
    
    // 距离合适且已经闭眼  符合拍照模式
    func distanceRightAndCloseEyes(){
        if (getFace > 2 && !beginToTakePicture && !didTakePicture && distanceRight) {
            self.isDelayShot = false
            self.beginToTakePicture = true
            self.faceStatePromter.initialAudioPlayer.stop()
            self.captureImage()
            self.device.unlockForConfiguration()
            self.setHumanVoice()
        } else {
            self.isDelayShot = true
        }
    }
    
    // 控制近一点、远一点、距离合适等操作
    func faceStatePromterType(distancecount:Int) {
        if cameraDirection == .isCameraFront {
            DispatchQueue.main.async {
                self.skinFrontAIView.closeEyeLabel.isHidden = true
                if self.farFace >= distancecount{
                    self.distanceNotRightSetStatus()
                    self.skinFrontAIView.tipsLaber.text = "【近一点】"
                    self.skinFrontAIView.tipsLaber.textColor = UIColor(hex: 0xEC4363).alpha(1.0)
                    self.faceStatePromter.state = FaceState.far
                }
                if self.nearFace >= distancecount {
                    self.distanceNotRightSetStatus()
                    self.skinFrontAIView.tipsLaber.text = "【远一点】"
                    self.skinFrontAIView.tipsLaber.textColor = UIColor(hex: 0xEC4363).alpha(1.0)
                    self.faceStatePromter.state = FaceState.near
                }
                if self.rightFace >= distancecount {
                    self.distanceRight = true
                    self.skinFrontAIView.tipsLaber.text = "【距离合适】"
                    self.skinFrontAIView.closeEyeLabel.isHidden = false
                    self.skinFrontAIView.tipsLaber.textColor = UIColor(hex: 0x4ABAB4).alpha(1.0)
                    if (!self.beginToTakePicture && !self.didTakePicture) {
                        self.faceStatePromter.state = FaceState.right
                    }
                }
            }
        } else {
            if farFace >= distancecount{
                self.distanceRight = false
                faceStatePromter.state = FaceState.far
            }
            if nearFace >= distancecount{
                self.distanceRight = false
                faceStatePromter.state = FaceState.near
            }
            if rightFace >= distancecount {
                self.distanceRight = true
                if (!self.beginToTakePicture && !self.didTakePicture) {
                    faceStatePromter.state = FaceState.right
                }
            }
        }
    }
    
    func setHumanVoice() {
        didSetHuman = false
        didSetNoHumam = false
        if !UserDefaults.standard.bool(forKey: "noHumanVoice") {
            // 人声 戴耳机 拍照后设置音量
            if isEarPhone() {
                if AVAudioSession.sharedInstance().outputVolume > 0.6 {
                    UserDefaults.standard.set(0.6, forKey: "humanVoice_earPhone")
                }else if AVAudioSession.sharedInstance().outputVolume < 0.1 {
                    UserDefaults.standard.set(0.1, forKey: "humanVoice_earPhone")
                }else {
                    UserDefaults.standard.set(AVAudioSession.sharedInstance().outputVolume, forKey: "humanVoice_earPhone")
                }
            } else {
                // 人声 无耳机 拍照后设置音量
                if AVAudioSession.sharedInstance().outputVolume > 0.9 {
                    UserDefaults.standard.set(0.9, forKey: "humanVoice")
                }else if AVAudioSession.sharedInstance().outputVolume < 0.3 {
                    UserDefaults.standard.set(0.3, forKey: "humanVoice")
                }else {
                    UserDefaults.standard.set(AVAudioSession.sharedInstance().outputVolume, forKey: "humanVoice")
                }
            }
        } else {
            if isEarPhone() {
                if AVAudioSession.sharedInstance().outputVolume > 0.6 {
                    UserDefaults.standard.set(0.6, forKey: "doVoice_earPhone")
                }else if AVAudioSession.sharedInstance().outputVolume < 0.1 {
                    UserDefaults.standard.set(0.1, forKey: "doVoice_earPhone")
                }else {
                    UserDefaults.standard.set(AVAudioSession.sharedInstance().outputVolume, forKey: "doVoice_earPhone")
                }
            } else {
                if AVAudioSession.sharedInstance().outputVolume < 0.3 {
                    UserDefaults.standard.set(0.3, forKey: "duVoice")
                }else if AVAudioSession.sharedInstance().outputVolume > 0.9 {
                    UserDefaults.standard.set(0.9, forKey: "duVoice")
                }else {
                    UserDefaults.standard.set(AVAudioSession.sharedInstance().outputVolume, forKey: "duVoice")
                }
                
            }
        }
    }
    
    // 自动拍照
    func captureImage(){
        if let videoConnection = imageOutPut!.connection(with: AVMediaType.video) {
            videoConnection.videoOrientation = AVCaptureVideoOrientation.portrait
            imageOutPut?.captureStillImageAsynchronously(from: videoConnection, completionHandler: {(sampleBuffer, error) in
                if  (error == nil) {
                    if (sampleBuffer != nil) {
                        self.session.stopRunning()
                        if (CMGetAttachment(sampleBuffer!, kCGImagePropertyExifDictionary, nil) != nil) {
                            //尝试捕捉
                            guard let buffer = sampleBuffer else { return }
                            self.exif = CMGetAttachment(buffer, kCGImagePropertyExifDictionary, nil) as! NSDictionary
                        }
                        guard let imageData = AVCaptureStillImageOutput.jpegStillImageNSDataRepresentation(sampleBuffer!) else { return }
                        self.saveToFileSystem(imageData)
                        self.didTakePicture = true
                        self.pushAction() // 跳转拍照页面
                    }
                }
            })
        }
    }
    
    func isEarPhone() -> Bool {
        let route = AVAudioSession.sharedInstance().currentRoute
        for desc in route.outputs {
            if desc.portType == AVAudioSessionPortHeadphones {
                return true
            }
        }
        return false
    }
}

@objc extension NewFaceShotController {
    // 弹框次数限制
    func isShowNewGuide(key: String, count: Int) -> Bool {
        var dict = GMCache.fetchObject(atDocumentPathWithkey: key)
        if dict == nil {
            dict = NSMutableDictionary()
        }
        var appDict = dict as! [String: String]
        let version = Bundle.main.infoDictionary!["CFBundleShortVersionString"] as! String
        
        if !appDict.values.contains(version) {  // 版本更新了， 删除之前的版本
            appDict.removeAll()
        }
        if appDict.keys.count >= count {  // 超过三次，不再弹出提示框
            return false
        }
        let date = Date()
        let dateFormatter = DateFormatter()
        dateFormatter.dateFormat = "yyyyMMdd"
        let dateStr = dateFormatter.string(from: date)
        
        if !appDict.keys.contains(dateStr) { // 保存数据
            appDict[dateStr] = version
            GMCache.storeObject(atDocumentPathWithkey: key, object: appDict as NSCoding)
            return true
        } else {
            return false
        }
    }
}
