//
//  CameraCell.swift
//  ZLPhotoBrowser
//
//  Created by long on 2020/8/19.
//
//  Copyright (c) 2020 Long Zhang <495181165@qq.com>
//
//  Permission is hereby granted, free of charge, to any person obtaining a copy
//  of this software and associated documentation files (the "Software"), to deal
//  in the Software without restriction, including without limitation the rights
//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//  copies of the Software, and to permit persons to whom the Software is
//  furnished to do so, subject to the following conditions:
//
//  The above copyright notice and this permission notice shall be included in
//  all copies or substantial portions of the Software.
//
//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//  THE SOFTWARE.

import UIKit
import AVFoundation

class CameraCell: UICollectionViewCell {
    
    var imageView: UIImageView!
    
    var session: AVCaptureSession?
    
    var videoInput: AVCaptureDeviceInput?
    
    var photoOutput: AVCapturePhotoOutput?
    
    var previewLayer: AVCaptureVideoPreviewLayer?
    
    deinit {
        self.session?.stopRunning()
        self.session = nil
        debugPrint("ZLCameraCell deinit")
    }
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        self.setupUI()
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    override func layoutSubviews() {
        super.layoutSubviews()
        self.imageView.frame = CGRect(x: 0, y: 0, width: self.bounds.width / 3, height: self.bounds.width / 3)
        self.imageView.center = CGPoint(x: self.bounds.midX, y: self.bounds.midY)
        
        self.previewLayer?.frame = self.contentView.layer.bounds
    }
    
    func setupUI() {
        self.layer.masksToBounds = true

        self.imageView = UIImageView(image: UIImage(named: "camera"))
        self.imageView.contentMode = .scaleAspectFit
        self.imageView.clipsToBounds = true
        self.contentView.addSubview(self.imageView)
        self.backgroundColor = .lightGray
    }
    
    func startCapture() {
        let status = AVCaptureDevice.authorizationStatus(for: .video)
        
        if !UIImagePickerController.isSourceTypeAvailable(.camera) || status == .denied {
            return
        }
        
        if status == .notDetermined {
            AVCaptureDevice.requestAccess(for: .video) { (granted) in
                if granted {
                    DispatchQueue.main.async {
                        self.setupSession()
                    }
                }
            }
        } else {
            self.setupSession()
        }
    }
    
    func setupSession() {
        guard self.session == nil, (self.session?.isRunning ?? false) == false else {
            return
        }
        self.session?.stopRunning()
        if let input = self.videoInput {
            self.session?.removeInput(input)
        }
        if let output = self.photoOutput {
            self.session?.removeOutput(output)
        }
        self.session = nil
        self.previewLayer?.removeFromSuperlayer()
        self.previewLayer = nil
        
        guard let camera = self.backCamera() else {
            return
        }
        guard let input = try? AVCaptureDeviceInput(device: camera) else {
            return
        }
        self.videoInput = input
        self.photoOutput = AVCapturePhotoOutput()
        
        self.session = AVCaptureSession()
        
        if self.session?.canAddInput(input) == true {
            self.session?.addInput(input)
        }
        if self.session?.canAddOutput(self.photoOutput!) == true {
            self.session?.addOutput(self.photoOutput!)
        }
        
        self.previewLayer = AVCaptureVideoPreviewLayer(session: self.session!)
        self.contentView.layer.masksToBounds = true
        self.previewLayer?.frame = self.contentView.layer.bounds
        self.previewLayer?.videoGravity = .resizeAspectFill
        self.contentView.layer.insertSublayer(self.previewLayer!, at: 0)
        
        self.session?.startRunning()
    }
    
    func backCamera() -> AVCaptureDevice? {
        let devices = AVCaptureDevice.DiscoverySession(deviceTypes: [.builtInWideAngleCamera], mediaType: .video, position: .back).devices
        for device in devices {
            if device.position == .back {
                return device
            }
        }
        return nil
    }
    
}


extension CameraCell: AVCapturePhotoCaptureDelegate {
    
}
