//
//  SHInputController.swift
//  ShorthandMaster
//
//  Created by 张哲 on 2020/9/24.
//  Copyright © 2020 明津李. All rights reserved.
//

import UIKit
import Photos
import PDFGenerator

class SHInputController: SHBaseViewController
{
    // MARK: - property
    /// viewModel
    var viewModel: SHInputViewModel = SHInputViewModel()
    
    /// 文件夹model
    var folderModel : SHRecordFolderModel!
    
    /// 保存成功回调
    var saveSuccessCallBack:((SHRecordFolderModel)->Void)?
    
    /// 存储数据的model
    var dataModel: SHRecordModel = SHRecordModel()
    
    /// 未填写标题时的默认标题
    private let defaultTitle: String = "新建笔记"
    
    /// 标题
    private var inputTitle: String = ""
    
    /// 计时器
    let timer = DispatchSource.makeTimerSource(flags: [], queue: DispatchQueue.global())
    
    /// 音频播放器
    var audioPlayer: AVAudioPlayer?
    
    /// 播放计时器
    let playTimer = DispatchSource.makeTimerSource(flags: [], queue: DispatchQueue.global())
    
    /// 播放计算器是否正在计时
    var playTimerCounting = false
    
    /// 播放完成
    var playFinished = false
    
    
    /// 是否是编辑
    var isEdited = false
    
    /// 是否编辑过
    var didEdited = false
    
    
    /// 是否有音频
    var haveAudio = false
    
    private var shInputView: SHInputView!
    
    private let recorder_mp3: SHMp3RecordManager = SHMp3RecordManager.shared()
    
    // MARK: -
    override func viewDidLoad()
    {
        super.viewDidLoad()
        
        self.view.backgroundColor = UIColor.white

        let date = Date()
        let dateFormatter = DateFormatter()
        dateFormatter.dateFormat = "yyyy年MM月dd日"
        self.title = dateFormatter.string(from: date)
        
        self.navigationItem.rightBarButtonItem = UIBarButtonItem.init(image: UIImage(named: "record_nav_confirm")?.withRenderingMode(.alwaysOriginal), style: .plain, target: self, action: #selector(didSelectedNavRightButton))
        
        self.isEdited = self.dataModel.rename.length > 0
        
        // 初始化播放器
        if self.isEdited
        {
            self.initPlayer()
        }
        
        // 初始化录音计时器
        timer.schedule(deadline: .now(), repeating: 1)
        timer.setEventHandler {
            DispatchQueue.main.sync {
                
                self.dataModel.during += 1
                                
                self.shInputView.bottomView.audioTimeLabel.text = self.viewModel.getTimeStringWithSeconds(seconds: self.dataModel.during)
            }
        }
        
        // 初始化播放计时器
        self.initPlayTimer()
        
        self.addSubviews()
        
        self.setUpSubviewsLocation()
    }
    
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        
        // 禁用右滑返回
        self.navigationController?.interactivePopGestureRecognizer?.isEnabled = false
    }
    
    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        
        // 恢复右滑返回
        self.navigationController?.interactivePopGestureRecognizer?.isEnabled = true
    }
    
    override func viewDidDisappear(_ animated: Bool) {
        super.viewDidDisappear(animated)
        
        var isPush = false
        
        if let viewControllers = self.navigationController?.viewControllers
        {
            for controller in viewControllers
            {
                if controller.isKind(of: SHInputController.self)
                {
                    isPush = true
                }
            }
        }
        else
        {
            
        }
        
        if !isPush
        {
            self.timer.suspend()
            self.timer.cancel()
            recorder_mp3.stop()
            self.shInputView.bottomView.timer.suspend()
            self.shInputView.bottomView.timer.cancel()
            self.playTimer.suspend()
            self.playTimer.cancel()
            if self.audioPlayer != nil
            {
                self.audioPlayer!.stop()
            }
        }
    }
    
    // MARK: - UI
    func addSubviews()
    {
        self.shInputView = SHInputView.init(frame: .zero, isEdited: self.isEdited, haveAudio: self.haveAudio)
        self.shInputView.textView.delegate = self;
        self.shInputView.textView.shDelegate = self;
        self.view.addSubview(self.shInputView!)
        
        if self.isEdited
        {
            self.shInputView.bottomView.playView.timeLabel.text = self.viewModel.getTimeStringWithSeconds(seconds: NSInteger(self.audioPlayer?.duration ?? 0))
        }
        
        // 添加点击事件
        self.shInputView.bottomView.imageButton.addTarget(self, action: #selector(didSelectedImageButton(sender:)), for: UIControl.Event.touchUpInside)
        self.shInputView.bottomView.addAudioButton.addTarget(self, action: #selector(didSelectedAddAudioButton(sender:)), for: UIControl.Event.touchUpInside)
        self.shInputView.bottomView.pauseAudioButton.addTarget(self, action: #selector(didSelectedPauseAudioButton(sender:)), for: UIControl.Event.touchUpInside)
        self.shInputView.bottomView.goOnAudioButton.addTarget(self, action: #selector(didSelectedGoOnAudioButton(sender:)), for: UIControl.Event.touchUpInside)
        self.shInputView.bottomView.stopAudioButton.addTarget(self, action: #selector(didSelectedStopAudioButton(sender:)), for: UIControl.Event.touchUpInside)
        self.shInputView.bottomView.keyboardButton.addTarget(self, action: #selector(didSelectedKeyboardButton(sender:)), for: UIControl.Event.touchUpInside)
        self.shInputView.bottomView.progressView.beforeButton.addTarget(self, action: #selector(didSelectedBeforeButton(sender:)), for: .touchUpInside)
        self.shInputView.bottomView.progressView.laterButton.addTarget(self, action: #selector(didSelectedLaterButton(sender:)), for: .touchUpInside)
        self.shInputView.bottomView.progressView.slider.addTarget(self, action: #selector(sliderTouchBegin(sender:)), for: .touchDown)
        self.shInputView.bottomView.progressView.slider.addTarget(self, action: #selector(sliderMoving(sender:)), for: .valueChanged)
        self.shInputView.bottomView.progressView.slider.addTarget(self, action: #selector(sliderTouchEnd(sender:)), for: .touchUpInside)
        self.shInputView.bottomView.progressView.slider.addTarget(self, action: #selector(sliderTouchEnd(sender:)), for: .touchUpOutside)
        self.shInputView.bottomView.playView.playButton.addTarget(self, action: #selector(didSelectedPlayButton(sender:)), for: .touchUpInside)
        self.shInputView.bottomView.playView.speedButton.addTarget(self, action: #selector(didSelectedSpeedButton(sender:)), for: .touchUpInside)
        self.shInputView.bottomView.copyButton.addTarget(self, action: #selector(didSelectedCopyButton(sender:)), for: .touchUpInside)
        self.shInputView.bottomView.shareButton.addTarget(self, action: #selector(didSelectedShareButton(sender:)), for: .touchUpInside)
    
        // 有记录显示记录
        if self.isEdited
        {
            // 隐藏占位文字
            self.shInputView.placeholder.isHidden = true

            // 显示记录
            self.shInputView.textView.attributedText = self.viewModel.getAttributedStringWithSHRecordModel(recordModel: self.dataModel)
            
            self.inputTitle = self.dataModel.rename
            
            self.initPlayer()
            
            // 修改音频时间, 保存一次
            // 获取本地数据
            // 笔记本列表
            var recordList = CRUserDefaults.recordList
            
            // 当前笔记本下标
            var folderIndex = 0
            
            // 遍历笔记本列表找到当前笔记本下标
            for dict in recordList!
            {
                var folderModel = SHRecordFolderModel()
                folderModel = getDataDictWith(dict: dict)
                
                if folderModel.id.isEqualTo(self.folderModel.id)
                {
                    break
                }
                
                folderIndex += 1
            }
            
            // 当前笔记下标
            var recordIndex = 0
                
            // 遍历当前笔记本的笔记列表找到当前笔记下标
            for recordModel in self.folderModel.dataSources
            {
                if recordModel.pathFile.isEqualTo(self.dataModel.pathFile)
                {
                    
                    break
                }
                
                recordIndex += 1
            }

            
            // 保存数据
            self.folderModel.dataSources[recordIndex] = self.dataModel
            
            // 把添加数据后的文件夹保存到数组中
            recordList![folderIndex] = getDictWith(obj: self.folderModel!)
            
            CRUserDefaults.recordList = recordList
            
            self.saveSuccessCallBack?(self.folderModel)
        }
        else
        {
            // 默认文字样式
            self.shInputView.textView.typingAttributes = self.viewModel.titleAttributes() as! [NSAttributedString.Key : Any]
        }
    }
    
    // MARK: 设置控件位置
    func setUpSubviewsLocation()
    {
        self.shInputView?.mas_makeConstraints({ (make) in
            
            make?.top.left()?.right()?.bottom()?.mas_equalTo()(0);
            
        })
    }
    
    // MARK: - Events
    // MARK: 点击navigationBar左侧按钮
    override func goback()
    {
        if !didEdited
        {
            self.navigationController?.popViewController(animated: true)
        }
        else
        {
            if !isEdited
            {
                self.didSelectedPauseAudioButton(sender: self.shInputView.bottomView.pauseAudioButton)
            }
            
            let alert = UIAlertController(title: "确认退出编辑?", message: nil, preferredStyle: .alert)
            
            let leftAction = UIAlertAction(title: "直接退出", style: .destructive) { (action) in
                
                self.navigationController?.popViewController(animated: true)
                
            }
            alert.addAction(leftAction)
            
            let rightAction = UIAlertAction(title: "保存并退出", style: .default) { (action) in
                
                self.didSelectedNavRightButton()
                
            }
            alert.addAction(rightAction)
            
            self.present(alert, animated: true, completion: nil)
        }
    }
    
    // MARK: 点击navigationBar右侧按钮
    @objc func didSelectedNavRightButton()
    {
        self.saveData()
        
        self.navigationController?.popViewController(animated: true)
    }
    
    // MARK: 保存数据
    func saveData()
    {
        // 获取本地数据
        // 笔记本列表
        var recordList = CRUserDefaults.recordList
        
        // 当前笔记本下标
        var folderIndex = 0
        
        // 遍历笔记本列表找到当前笔记本下标
        for dict in recordList!
        {
            var folderModel = SHRecordFolderModel()
            folderModel = getDataDictWith(dict: dict)
            
            if folderModel.id.isEqualTo(self.folderModel.id)
            {
                break
            }
            
            folderIndex += 1
        }
        
        // 当前笔记下标
        var recordIndex = 0
        // 以前笔记上层文件夹
        var oldDocumentFilePath = ""
        // 以前笔记音频数据
        var oldPathFile = ""
        var oldPcmPathFile = ""
        
            
        if self.isEdited
        {
            // 遍历当前笔记本的笔记列表找到当前笔记下标
            for recordModel in self.folderModel.dataSources
            {
                if recordModel.pathFile.isEqualTo(self.dataModel.pathFile)
                {
                    oldDocumentFilePath = recordModel.pathFile.substring(0, length: 19)!
                    oldPathFile = recordModel.pathFile
                    oldPcmPathFile = recordModel.pcmPathFile
                    
                    break
                }
                
                recordIndex += 1
            }
        }
        
        self.dataModel.recordingType = 1
        
        self.dataModel.createDate = Date()
        self.dataModel.modifyDate = Date()
        
        // 重新遍历图片, 保存到新的位置
        let imageArray = self.viewModel.setUpImageArrayWithTextView(textView: self.shInputView.textView)
        
        self.dataModel.imagesPath = imageArray.imagesPathArray
        self.dataModel.imagesIndex = imageArray.imagesIndexArray
        
        if self.inputTitle.length == 0
        {
            self.dataModel.rename = defaultTitle
            
            self.inputTitle = defaultTitle
            
            self.shInputView.textView.text = defaultTitle
        }
        else
        {
            self.dataModel.rename = inputTitle
        }

        self.dataModel.txt = self.shInputView.textView.text.substring(self.inputTitle.length, length: self.shInputView.textView.text.length - self.inputTitle.length) ?? ""
        
        // 是否有录音都传, 用它来做为唯一表示
        self.dataModel.pathFile = self.viewModel.documentFilePath + RecordMp3
        self.dataModel.pcmPathFile = self.viewModel.documentFilePath + RecordCaf

        
        // 保存数据
        if isEdited
        {
            // 将音频文件保存到新的位置
            do
            {
                try FileManager.default.moveItem(atPath: DocumentPath + oldPathFile, toPath: DocumentPath + self.dataModel.pathFile)
            }
            catch let error
            {
                print(error)
            }
            
            do
            {
                try FileManager.default.moveItem(atPath: DocumentPath + oldPcmPathFile, toPath: DocumentPath + self.dataModel.pcmPathFile)
            }
            catch let error
            {
                print(error)
            }
            
            
            // 删除沙盒中之前的笔记的图片和音频资源
            do
            {
                try FileManager.default.removeItem(atPath: DocumentPath + oldDocumentFilePath)
            }
            catch let error
            {
                print(error)
            }
            
            self.folderModel.dataSources[recordIndex] = self.dataModel
        }
        else
        {
            self.folderModel.dataSources.append(self.dataModel)
        }
        
        // 把添加数据后的文件夹保存到数组中
        recordList![folderIndex] = getDictWith(obj: self.folderModel!)
        
        CRUserDefaults.recordList = recordList
        
        self.saveSuccessCallBack?(self.folderModel)
    }
    
    // MARK: 点击键盘按钮
    @objc func didSelectedKeyboardButton(sender : UIButton)
    {
        if self.shInputView.textView.isFirstResponder
        {
            self.shInputView.textView.resignFirstResponder()
        }
        else
        {
            self.shInputView.textView.becomeFirstResponder()
        }
    }
    
    // MARK: 点击复制按钮
    @objc func didSelectedCopyButton(sender: UIButton)
    {
        if self.shInputView.textView?.text.length == 0
        {
            return
        }
        MBProgressHUD.showMessage("文本已复制到剪切板", to: self.view)
        let board = UIPasteboard.general
        board.string = self.shInputView.textView?.text
    }
    
    // MARK: 点击分享按钮
    @objc func didSelectedShareButton(sender:UIButton)
    {
        
        if SHUserAccountManager.shared.isMember == false{
            self.goGoods("dialog_record_success_trans_pdf")
            return
        }
        
        do {
            let documentsFile = DocumentPath + self.viewModel.documentFilePath + "/\(self.inputTitle).pdf"
            
            try PDFGenerator.generate(self.shInputView.textView!, to: documentsFile)
            //此三方会把传入控件约束移除  需重新添加
            self.shInputView.textView.mas_makeConstraints({ (make) in
                make?.left.mas_equalTo()(20 - 5)
                make?.right.mas_equalTo()(0)
                make?.top.mas_equalTo()(0)
                make?.bottom.equalTo()(self.shInputView.bottomView.mas_top)
            })
            
//            let webvc = SHWebViewController.init()
//            webvc.url = documentsFile
//            self.navigationController?.pushViewController(webvc, animated: true)

            let fileURL = URL.init(fileURLWithPath: documentsFile)
            let data = try Data.init(contentsOf: fileURL)

            let activityVC = UIActivityViewController(activityItems: [data, fileURL], applicationActivities: nil)
            activityVC.completionWithItemsHandler = {
                activity, success, items, errot in
                // result
            }
            present(activityVC, animated: true, completion: nil)
            
        } catch let error {
            print(error)
        }
    }
}

// MARK: - 输入框
extension SHInputController: UITextViewDelegate, SHInputTextViewDelegate
{
    // MARK: - UITextView代理
    // MARK: 滑动
    func scrollViewDidScroll(_ scrollView: UIScrollView) {
        
        let vel = scrollView.panGestureRecognizer.velocity(in: scrollView)
        if vel.y > 20
        {
            if self.shInputView.textView.canResignFirstResponder
            {
                self.shInputView.textView.resignFirstResponder()
            }
        }
        
    }
    
    // MARK: 文字发生了变化
    func textViewDidChange(_ textView: UITextView)
    {
        self.didEdited = true
        
        self.shInputView.placeholder.isHidden = textView.text.length > 0
    }
    
    // MARK: 文字将要变化
    func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool
    {
//        let selectedRange = textView.markedTextRange;
//
//        if selectedRange == nil || selectedRange!.isEmpty
//        {
////            if self.hasEmoji(text: text)
////            {
////                return false
////            }
//        }
//        else
//        {
//
//        }
        
//        if text.isContainEmoji()
//        {
//            return false
//        }
        
        // 获取标题文字位置
        let titleRange = NSRange(location: 0, length: self.inputTitle.length)
        
        // 在标题位置输入的内容为标题
        if range.location <= titleRange.location + titleRange.length
        {
            // 使用标题字体
            textView.typingAttributes = self.viewModel.titleAttributes() as! [NSAttributedString.Key : Any]
            
            // 输入换行符即表示标题输入完成
            if (text.isEqualTo("\n"))
            {
                // 开始输入内容字体
                textView.typingAttributes = self.viewModel.contentAttributes() as! [NSAttributedString.Key : Any]
            }
            else
            {
                // 把将要添加的文字加到输入框文字中
                let textViewString : NSMutableString = NSMutableString(string: textView.text)
                textViewString.insert(text, at: range.location)
                
                // 保存标题文字
                self.inputTitle = textViewString.substring(with: NSRange(location: 0, length: range.location + text.length))
            }
        }
        else
        {
            // 使用内容字体
            textView.typingAttributes = self.viewModel.contentAttributes() as! [NSAttributedString.Key : Any]
        }
        
        return true
    }
    
    // MARK: 光标位置发生变化
    func textViewDidChangeSelection(_ textView: UITextView) {
        
        print(textView.selectedRange)
        
    }
    
    // MARK: 是否是emoji
    func hasEmoji(text: String)->Bool {
        
        let stringUtf8Length = text.lengthOfBytes(using: .utf8)
        if stringUtf8Length >= 4 && stringUtf8Length / text.length != 3
        {
            return true
        }
        else
        {
            return false
        }
    }
    
    // MARK: - SHInputTextView代理
    // MARK: 点击删除按钮
    func textViewDidDelete(textView: SHInputTextView)
    {
        
    }
    
    func testIFCANFIND()
    {
        
    }
}


// MARK: - 图片选择器
extension SHInputController: UIImagePickerControllerDelegate, UINavigationControllerDelegate
{
    // MARK: - 代理方法
    // MARK: 选中了一张照片/拍了一张照片
    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any])
    {
        self.didEdited = true
        
        if (info[UIImagePickerController.InfoKey.originalImage] != nil)
        {
            let image : UIImage = (info[UIImagePickerController.InfoKey.originalImage] as? UIImage)!
            
            self.insertImageInTextView(image: image)
            
            picker.dismiss(animated: true, completion: nil)
        }
        else
        {
            let imageAssetUrl : URL = info[UIImagePickerController.InfoKey.referenceURL] as! URL
            
            let result : PHFetchResult = PHAsset.fetchAssets(withALAssetURLs: [imageAssetUrl], options: nil)
            
            let asset : PHAsset = result.firstObject!
            
            let options = PHImageRequestOptions()
            options.isNetworkAccessAllowed = true
            
            weak var weakSelf = self
            
            PHImageManager.default().requestImageData(for: asset, options: options) { (imageData, dataUTI, orientation, info) in
                
                if imageData != nil
                {
                    let image : UIImage = UIImage(data: imageData!)!
                    weakSelf?.insertImageInTextView(image: image)
                    
                    picker.dismiss(animated: true, completion: nil)
                }
                
            }
            
            
        }
    }
    
    // MARK: 取消选择照片/取消拍照
    func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
        
        picker.dismiss(animated: true, completion: nil)
        
    }
    
    // MARK: - 输入框中插入图片方法
    func insertImageInTextView(image : UIImage)
    {
        // 调整图片大小, 宽相同, 高随比例变化
        let newWidth = kScreenWidth - 20 * 2
        let newHeight = newWidth * image.size.height / image.size.width
        let newSize = CGSize(width: newWidth, height: newHeight)
        
        
        // 如果没有标题添加默认标题
        if self.inputTitle.length == 0
        {
            // 标题
            let titleString = NSMutableAttributedString(string: self.defaultTitle, attributes: (self.viewModel.titleAttributes() as! [NSAttributedString.Key : Any]))
            self.shInputView.textView.attributedText = titleString

            self.shInputView.placeholder.isHidden = true

            self.inputTitle = titleString.string
        }
        
        // 如果占位文字未隐藏, 隐藏占位文字
        self.shInputView.placeholder.isHidden = true
        
        // 前文
        let textString = NSMutableAttributedString(attributedString: self.shInputView.textView.attributedText)
        
        // 图片
        let attachment = NSTextAttachment.init()
        attachment.image = image.scaled(to: newSize)
        attachment.bounds = CGRect(origin: CGPoint.zero, size: newSize)
        let imageString = NSMutableAttributedString(attachment: attachment)
        
        // 设置图片文字属性
        imageString.addAttributes((self.viewModel.contentAttributes() as? [NSAttributedString.Key : Any])!, range: NSRange(location: 0, length: imageString.length))
        // 设置图片间距
        let paragraphStyle = NSMutableParagraphStyle()
        paragraphStyle.lineSpacing = 18
        imageString.addAttribute(NSAttributedString.Key.paragraphStyle, value: paragraphStyle, range: NSRange(location: 0, length: imageString.length))
        
        // 图片前后增加换行符
        // 如果前文以换行符结尾, 图片前面不再加换行符
        if !textString.string.hasSuffix("\n")
        {
            imageString.insert(NSAttributedString(string: "\n", attributes: (self.viewModel.contentAttributes() as! [NSAttributedString.Key : Any])), at: 0)
        }
        imageString.insert(NSAttributedString(string: "\n", attributes: (self.viewModel.contentAttributes() as! [NSAttributedString.Key : Any])), at: imageString.length)
        
        // 合并内容
        textString.insert(imageString, at: self.shInputView.textView.selectedRange.location)
        
        self.shInputView.textView.attributedText = textString
        
        // 使用内容字体
        self.shInputView.textView.typingAttributes = self.viewModel.contentAttributes() as! [NSAttributedString.Key : Any]
    }
    
    // MARK: - Events
    // MARK: 点击选择图片按钮
    @objc func didSelectedImageButton(sender : UIButton)
    {
        if self.shInputView.textView.canResignFirstResponder
        {
            self.shInputView.textView.resignFirstResponder()
        }
        
        let alert = UIAlertController(title: nil, message: nil, preferredStyle: UIAlertController.Style.actionSheet)
        
        weak var weakSelf = self
        
        let albumAction = UIAlertAction(title: "相册", style: UIAlertAction.Style.default) { (action) in
            
            weakSelf?.openAlbum()
            
        }
        alert.addAction(albumAction)
        
        let cameraAction = UIAlertAction(title: "相机", style: UIAlertAction.Style.default) { (action) in
            
            weakSelf?.openCamera()
            
        }
        alert.addAction(cameraAction)
        
        let cancelAction = UIAlertAction(title: "取消", style: UIAlertAction.Style.cancel , handler: nil)
        alert.addAction(cancelAction)
        
        
        
        self.present(alert, animated: true, completion: nil)
    }
    
    // MARK: 打开相册, 判断相册权限
    func openAlbum()
    {
        let status : PHAuthorizationStatus = PHPhotoLibrary.authorizationStatus()
        
        switch status
        {
        // MARK: 此应用程序没有被授权访问的照片数据。可能是家长控制权限
        case PHAuthorizationStatus.restricted:
            let alert = UIAlertController(title: nil, message: "此应用程序没有被授权访问的照片数据。可能是家长控制权限", preferredStyle: UIAlertController.Style.alert)
            
            let sureAction = UIAlertAction(title: "确定", style: UIAlertAction.Style.default, handler: nil)
            alert.addAction(sureAction)
            
            self.present(alert, animated: true, completion: nil)
            
            break
        // MARK: 用户拒绝访问相册
        case PHAuthorizationStatus.denied:
            let alert = UIAlertController(title: "此功能需要相册授权", message: "请您在设置系统中打开授权开关", preferredStyle: UIAlertController.Style.alert)
            
            let cancelAction = UIAlertAction(title: "取消", style: UIAlertAction.Style.cancel, handler: nil)
            alert.addAction(cancelAction)
            
            let settingAction = UIAlertAction(title: "前往设置", style: UIAlertAction.Style.default) { (action) in
                
                UIApplication.shared.open(URL(string: UIApplication.openSettingsURLString)!, options: [:], completionHandler: nil)
                
            }
            alert.addAction(settingAction)
            
            
            self.present(alert, animated: true, completion: nil)
            
            break
        // MARK: 用户允许访问相册
        case PHAuthorizationStatus.authorized:
            if UIImagePickerController.isSourceTypeAvailable(UIImagePickerController.SourceType.photoLibrary)
            {
                self.showAlbum()
            }
            break
        // MARK: 用户还没有做出选择
        case PHAuthorizationStatus.notDetermined:
            weak var weakSelf = self
            
            PHPhotoLibrary.requestAuthorization { (status) in
                
                if status == PHAuthorizationStatus.authorized
                {
                    if UIImagePickerController.isSourceTypeAvailable(UIImagePickerController.SourceType.photoLibrary)
                    {
                        weakSelf?.showAlbum()
                    }
                }

            }
            break
        default:
            break
        }
    }
    
    // MARK: 显示相册
    func showAlbum()
    {
        DispatchQueue.main.async
        {
            let imagePickerController = UIImagePickerController()
            imagePickerController.sourceType = UIImagePickerController.SourceType.photoLibrary
            imagePickerController.delegate = self
            imagePickerController.modalPresentationStyle = UIModalPresentationStyle.fullScreen
            self.present(imagePickerController, animated: true, completion: nil)
        }
    }
    
    // MARK: 打开相机, 判断相机权限
    func openCamera()
    {
        let device : AVCaptureDevice? = AVCaptureDevice.default(for: AVMediaType.video)
        
        if device != nil
        {
            let status : AVAuthorizationStatus = AVCaptureDevice.authorizationStatus(for: AVMediaType.video)
            switch status
            {
            // MARK: 此应用程序没有被授权访问的照片数据。可能是家长控制权限。
            case AVAuthorizationStatus.restricted:
                let alert = UIAlertController(title: nil, message: "此应用程序没有被授权访问的相机数据。可能是家长控制权限。", preferredStyle: UIAlertController.Style.alert)
                
                let sureAction = UIAlertAction(title: "确定", style: UIAlertAction.Style.default, handler: nil)
                alert.addAction(sureAction)
                
                self.present(alert, animated: true, completion: nil)
                
                break
            // MARK: 用户拒绝当前应用访问相机
            case AVAuthorizationStatus.denied:
                let alert = UIAlertController(title: "此功能需要相机授权", message: "请您在设置系统中打开授权开关", preferredStyle: UIAlertController.Style.alert)
                
                let cancelAction = UIAlertAction(title: "取消", style: UIAlertAction.Style.cancel, handler: nil)
                alert.addAction(cancelAction)
                
                let settingAction = UIAlertAction(title: "前往设置", style: UIAlertAction.Style.default) { (action) in
                    
                    UIApplication.shared.open(URL(string: UIApplication.openSettingsURLString)!, options: [:], completionHandler: nil)
                    
                }
                alert.addAction(settingAction)
                
                
                self.present(alert, animated: true, completion: nil)
                
                break
            // MARK: 用户允许当前应用访问相机
            case AVAuthorizationStatus.authorized:
                if UIImagePickerController.isSourceTypeAvailable(UIImagePickerController.SourceType.camera)
                {
                    self.showCamera()
                }
                break
            // MARK: 用户还没有做出选择
            case AVAuthorizationStatus.notDetermined:
                weak var weakSelf = self
                
                PHPhotoLibrary.requestAuthorization { (status) in
                    
                    if status == PHAuthorizationStatus.authorized
                    {
                        if UIImagePickerController.isSourceTypeAvailable(UIImagePickerController.SourceType.camera)
                        {
                            weakSelf?.showCamera()
                        }
                    }

                }
                break
            default:
                break
            }
            
        }
        else
        {
            self.openAlbum()
        }
        
    }
    
    // MARK: 显示相机
    func showCamera()
    {
        DispatchQueue.main.async {
            
            let imagePickerController = UIImagePickerController()
            imagePickerController.sourceType = UIImagePickerController.SourceType.camera
            imagePickerController.delegate = self
            imagePickerController.modalPresentationStyle = UIModalPresentationStyle.fullScreen
            self.present(imagePickerController, animated: true, completion: nil)
            
        }
    }
}

// MARK: - 录音
extension SHInputController
{
    // MARK: 点击添加录音按钮, 先判断麦克风权限
    @objc func didSelectedAddAudioButton(sender : SHInputAudioButton)
    {
        let status : AVAuthorizationStatus = AVCaptureDevice.authorizationStatus(for: .audio)
        switch status
        {
        // MARK: 此应用程序未被授权, 可能是家长控制权限。
        case AVAuthorizationStatus.restricted:
            let alert = UIAlertController(title: nil, message: "此应用程序未被授权, 可能是家长控制权限。", preferredStyle: UIAlertController.Style.alert)
            
            let sureAction = UIAlertAction(title: "确定", style: UIAlertAction.Style.default, handler: nil)
            alert.addAction(sureAction)
            
            self.present(alert, animated: true, completion: nil)
            
            break
        // MARK: 用户拒绝当前应用访问麦克风
        case AVAuthorizationStatus.denied:
            let alert = UIAlertController(title: "此功能需要麦克风授权", message: "请您在设置系统中打开授权开关", preferredStyle: UIAlertController.Style.alert)
            
            let cancelAction = UIAlertAction(title: "取消", style: UIAlertAction.Style.cancel, handler: nil)
            alert.addAction(cancelAction)
            
            let settingAction = UIAlertAction(title: "前往设置", style: UIAlertAction.Style.default) { (action) in
                
                UIApplication.shared.open(URL(string: UIApplication.openSettingsURLString)!, options: [:], completionHandler: nil)
                
            }
            alert.addAction(settingAction)
            
            
            self.present(alert, animated: true, completion: nil)
            
            break
        // MARK: 用户允许当前应用访问麦克风
        case AVAuthorizationStatus.authorized:
            self.beginAddAudio()
            break
        // MARK: 用户还没有做出选择
        case AVAuthorizationStatus.notDetermined:
            
            AVCaptureDevice.requestAccess(for: .audio) { (flag) in
                
                if flag
                {
                    DispatchQueue.main.async {
                        self.beginAddAudio()
                    }
                }
                
            }
            break
        default:
            break
        }
        
    }
    
    // MARK: 开始录音
    func beginAddAudio()
    {
        self.shInputView.bottomView.addAudioButton.isHidden = true
        self.shInputView.bottomView.audioTimeBgView.isHidden = false
        self.shInputView.bottomView.pauseAudioButton.isHidden = false
        self.shInputView.bottomView.goOnAudioButton.isHidden = true
        self.shInputView.bottomView.stopAudioButton.isHidden = true
        self.shInputView.bottomView.playView.isHidden = true
        self.shInputView.bottomView.setUpSubviewsLocation()
        
        self.dataModel.pathFile = self.viewModel.documentFilePath + RecordMp3
        self.dataModel.pcmPathFile = self.viewModel.documentFilePath + RecordCaf
        let mp3Path : String = DocumentPath + self.dataModel.pathFile
        let pcmPath : String = DocumentPath + self.dataModel.pcmPathFile
        
        recorder_mp3.configMp3Path(mp3Path, pcmPath: pcmPath)
        recorder_mp3.start()
        
        // 开始计时
        self.dataModel.during = -1
        
        self.timer.resume()
        
        // 小红点
        self.shInputView.bottomView.setUpTimer()
        self.shInputView.bottomView.audioTimePointViewAnimation(animation: true)
    }
    
    // MARK: 点击暂停录音按钮
    @objc func didSelectedPauseAudioButton(sender : SHInputAudioButton)
    {
        self.shInputView.bottomView.addAudioButton.isHidden = true
        self.shInputView.bottomView.audioTimeBgView.isHidden = false
        self.shInputView.bottomView.pauseAudioButton.isHidden = true
        self.shInputView.bottomView.goOnAudioButton.isHidden = false
        self.shInputView.bottomView.stopAudioButton.isHidden = false
        self.shInputView.bottomView.playView.isHidden = true
        self.shInputView.bottomView.setUpSubviewsLocation()
        
        recorder_mp3.pause()
        
        self.timer.suspend()
        
        self.shInputView.bottomView.audioTimePointViewAnimation(animation: false)
    }
    
    // MARK: 点击继续录音按钮
    @objc func didSelectedGoOnAudioButton(sender : SHInputAudioButton)
    {
        self.shInputView.bottomView.addAudioButton.isHidden = true
        self.shInputView.bottomView.audioTimeBgView.isHidden = false
        self.shInputView.bottomView.pauseAudioButton.isHidden = false
        self.shInputView.bottomView.goOnAudioButton.isHidden = true
        self.shInputView.bottomView.stopAudioButton.isHidden = true
        self.shInputView.bottomView.playView.isHidden = true
        self.shInputView.bottomView.setUpSubviewsLocation()
        
        recorder_mp3.start()
        
        self.timer.resume()
        
        self.shInputView.bottomView.audioTimePointViewAnimation(animation: true)
    }
    
    // MARK: 点击结束录制按钮
    @objc func didSelectedStopAudioButton(sender : SHInputAudioButton)
    {
        self.didEdited = true
        
        recorder_mp3.pause()
        
        self.timer.suspend()
        
        self.shInputView.bottomView.audioTimePointViewAnimation(animation: false)
        
        let alert = UIAlertController(title: "提示", message: "结束录音后，不能再进行续录。", preferredStyle: .alert)
        
        let leftAction = UIAlertAction(title: "结束录音", style: .destructive) { (action) in
            
            self.shInputView.bottomView.addAudioButton.isHidden = true
            self.shInputView.bottomView.audioTimeBgView.isHidden = true
            self.shInputView.bottomView.pauseAudioButton.isHidden = true
            self.shInputView.bottomView.goOnAudioButton.isHidden = true
            self.shInputView.bottomView.stopAudioButton.isHidden = true
            self.shInputView.bottomView.playView.isHidden = false
            self.shInputView.bottomView.setUpSubviewsLocation()
            
            self.recorder_mp3.stop()
            
            self.timer.cancel()
            self.shInputView.bottomView.timer.cancel()
            
            self.initPlayer()
            
            self.shInputView.bottomView.playView.timeLabel.text = self.viewModel.getTimeStringWithSeconds(seconds: NSInteger(self.audioPlayer?.duration ?? 0))
            
            self.shInputView.setNeedsUpdateConstraints()
            
            UIView.animate(withDuration: 0.3) {
                
                self.shInputView.bottomView.mas_updateConstraints { (make) in
                    
                    make?.height.mas_equalTo()(100 + SafeAreaBottomHeight())
                    
                }
                
                self.shInputView.bottomView.progressView.alpha = 1;
                
                self.shInputView.bottomView.superview!.layoutIfNeeded()
                
            }
            
        }
        alert.addAction(leftAction)
        
        let rightAction = UIAlertAction(title: "暂不结束", style: .default) { (action) in
            
        }
        alert.addAction(rightAction)
        
        self.present(alert, animated: true, completion: nil)
    }
}

// MARK: - 播放
extension SHInputController: AVAudioPlayerDelegate {

    // MARK: 初始化播放计时器
    func initPlayTimer()
    {
        self.playTimer.schedule(deadline: .now(), repeating: 0.03)
        self.playTimer.setEventHandler {
            
            DispatchQueue.main.sync {
                
                print("计时中" + String(self.audioPlayer?.currentTime ?? 0))
                if Float(self.audioPlayer?.duration ?? 0) - Float(self.audioPlayer?.currentTime ?? 0) <= 0.1
                {
                    self.playFinished = true
                }
                
                if !self.playFinished
                {
                    self.shInputView.bottomView.progressView.slider.value = min(Float(self.audioPlayer?.currentTime ?? 0) / Float(self.audioPlayer?.duration ?? 0), 1)
                    
                    self.shInputView.bottomView.progressView.timeLabel.text = self.viewModel.getTimeStringWithSeconds(seconds: NSInteger(self.audioPlayer?.currentTime ?? 0))
                }
            }
        }
    }
    
    // MARK: 播放计时器开始计时
    func startPlayTimer()
    {
        if !playTimerCounting
        {
            self.playTimer.resume()
            
            playTimerCounting = true
        }
    }
    
    // MARK: 播放计时器暂停计时
    func pausePlayTimer()
    {
        if playTimerCounting
        {
            self.playTimer.suspend()
            
            playTimerCounting = false
        }
    }
    
    // MARK: 初始化播放器
    func initPlayer()
    {
        do
        {
            try self.audioPlayer = AVAudioPlayer(contentsOf: URL(fileURLWithPath: DocumentPath + self.dataModel.pathFile), fileTypeHint: AVFileType.mp3.rawValue)
        }
        catch let error
        {
            print(error)
            return
        }

        self.haveAudio = true
        
        self.audioPlayer?.prepareToPlay()
        self.audioPlayer?.numberOfLoops = 0 // 循环播放次数
        self.audioPlayer?.enableRate = true // 允许变速播放
        self.audioPlayer?.delegate = self
        
        self.dataModel.during = NSInteger(self.audioPlayer?.duration ?? 0)
        
        // 后台播放
        let session = AVAudioSession.sharedInstance()
        try? session.setCategory(AVAudioSession.Category.playAndRecord, options: .defaultToSpeaker)
    }
    
    // MARK: 点击播放/暂停按钮
    @objc func didSelectedPlayButton(sender: UIButton)
    {
        if (self.audioPlayer!.isPlaying)
        {
            // 暂停
            self.audioPlayer?.pause()
            
            self.pausePlayTimer()
            
            sender.setImage(UIImage(named: "input_audio_play"), for: .normal)
        }
        else
        {
            // 播放
            if self.playFinished
            {
                self.audioPlayer?.currentTime = 0;
                
                self.playFinished = false
            }
            
            self.audioPlayer?.play()
            
            self.startPlayTimer()
            
            sender.setImage(UIImage(named: "input_audio_pause"), for: .normal)
        }
    }
    
    // MARK: 后退10s
    @objc func didSelectedBeforeButton(sender: UIButton)
    {
        self.playFinished = false
        
        self.audioPlayer?.pause()
        
        self.pausePlayTimer()
        
        self.audioPlayer?.currentTime = max((self.audioPlayer?.currentTime ?? 0) - 10, 0)
        
        self.audioPlayer?.play()
        
        self.startPlayTimer()
        
        self.shInputView.bottomView.playView.playButton.setImage(UIImage(named: "input_audio_pause"), for: .normal)
    }
    
    // MARK: 前进10s
    @objc func didSelectedLaterButton(sender: UIButton)
    {
        self.playFinished = false
        
        self.audioPlayer?.pause()
        
        self.pausePlayTimer()
        
        // 最大时间直接等于self.audioPlayer?.duration音频会从第1s重新开始播放
        self.audioPlayer?.currentTime = min((self.audioPlayer?.currentTime ?? 0) + 10, TimeInterval(self.audioPlayer?.duration ?? 0) - 0.03)
        
        self.audioPlayer?.play()
        
        self.startPlayTimer()
        
        self.shInputView.bottomView.playView.playButton.setImage(UIImage(named: "input_audio_pause"), for: .normal)
    }
    
    // MARK: 开始拖动进度条
    @objc func sliderTouchBegin(sender: UISlider)
    {
        // 暂停
        self.audioPlayer?.pause()
        
        self.pausePlayTimer()
        
        self.shInputView.bottomView.playView.playButton.setImage(UIImage(named: "input_audio_play"), for: .normal)
    }
    
    // MARK: 拖动进度条
    @objc func sliderMoving(sender: UISlider)
    {
        let duration: Double = Double(self.audioPlayer?.duration ?? 0)
        
        self.shInputView.bottomView.progressView.timeLabel.text = self.viewModel.getTimeStringWithSeconds(seconds: NSInteger(Double(sender.value) * duration))
    }
    
    // MARK: 结束拖动进度条
    @objc func sliderTouchEnd(sender: UISlider)
    {
        self.playFinished = false
        
        // 播放
        // 最大时间直接等于self.audioPlayer?.duration音频会从第1s重新开始播放
        self.audioPlayer?.currentTime = min(TimeInterval(Double(sender.value) * Double(self.audioPlayer?.duration ?? 0)), Double(self.audioPlayer?.duration ?? 0) - 0.03)
        
        self.audioPlayer?.play()
        
        self.startPlayTimer()
        
        self.shInputView.bottomView.playView.playButton.setImage(UIImage(named: "input_audio_pause"), for: .normal)
    }
    
    // MARK: 切换倍速
    @objc func didSelectedSpeedButton(sender: UIButton)
    {
        if sender.titleLabel!.text!.isEqualTo("x1")
        {
            self.audioPlayer?.rate = 1.5
            sender.setTitle("x1.5", for: .normal)
        }
        else if sender.titleLabel!.text!.isEqualTo("x1.5")
        {
            self.audioPlayer?.rate = 2
            sender.setTitle("x2", for: .normal)
        }
        else if sender.titleLabel!.text!.isEqualTo("x2")
        {
            self.audioPlayer?.rate = 1
            sender.setTitle("x1", for: .normal)
        }
    }
    
    // MARK: - 代理
    // MARK: 播放完成
    func audioPlayerDidFinishPlaying(_ player: AVAudioPlayer, successfully flag: Bool) {
        
        print("播放完成")
        player.currentTime = player.duration
        self.shInputView.bottomView.playView.playButton.setImage(UIImage(named: "input_audio_play"), for: .normal)
        self.shInputView.bottomView.progressView.slider.value = 1;
        self.shInputView.bottomView.progressView.timeLabel.text = self.viewModel.getTimeStringWithSeconds(seconds: NSInteger(self.audioPlayer?.duration ?? 0))
        self.pausePlayTimer()
        
    }
}
