//
//  QRCodeMaskView.swift
//  PaiAi-Guide
//
//  Created by zhengjianfei on 2017/1/20.
//  Copyright © 2017年 mac. All rights reserved.
//

import UIKit

let qrcodeAnimation = "com.QR.gradient"
class QRCodeMaskView: UIView {
    var configuration = QRCodeConfiguration() {
        didSet {
            layoutIfNeeded()
        }
    }
    fileprivate var cornerLineWidth: CGFloat {
        get {
            return configuration.cornerLineWidth
        }
    }
    fileprivate var cornerLineLength: CGFloat {
        get {
            return configuration.cornerLineLength
        }
    }
    fileprivate var cornerLineColor: UIColor {
        get {
            return configuration.cornerLineColor
        }
    }
    fileprivate var cornerLineSpace: CGFloat = 1.0
    fileprivate var cornerLineDistance: CGFloat = 1.0
    fileprivate var gradientColor: UIColor {
        get {
            return configuration.gradientColor
        }
    }
    fileprivate let animation = { () -> CABasicAnimation in
        let animation = CABasicAnimation(keyPath: "position.y")
        animation.repeatCount = 100000
        animation.isRemovedOnCompletion = false
        animation.duration = 2
        animation.fillMode = kCAFillModeForwards
        return animation
    }()

    fileprivate let gradientLayer = CAGradientLayer()

    func stopAnimation() {
        let pauseTime = gradientLayer.convertTime(CACurrentMediaTime(), to: nil)
        gradientLayer.speed = 0.0
        gradientLayer.timeOffset = pauseTime
    }

    func startAnimation() {
        let pauseTime = gradientLayer.timeOffset
        gradientLayer.speed = 1.0
        gradientLayer.timeOffset = 0.0
        gradientLayer.beginTime = 0.0
        let timeSincePause = gradientLayer.convertTime(CACurrentMediaTime(), to: nil) - pauseTime
        gradientLayer.beginTime = timeSincePause
    }

    override init(frame: CGRect) {
        super.init(frame: frame)
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }

    func setScanAnimation(clearRect: CGRect) {
        let view = UIView(frame: clearRect)
        view.clipsToBounds = true
        addSubview(view)
        gradientLayer.frame = CGRect(x: 0,
                                     y: -48,
                                     width: clearRect.width,
                                     height: 48)
        gradientLayer.colors = [UIColor(red: 150 / 255.0,
                                        green: 150 / 255.0,
                                        blue: 150 / 255.0,
                                        alpha: 0.0).cgColor,
                                gradientColor.cgColor]
        view.layer.addSublayer(gradientLayer)
        animation.toValue = clearRect.height
        gradientLayer.add(animation, forKey: qrcodeAnimation)
        stopAnimation()
    }

    override func draw(_ rect: CGRect) {
        let screenSize = CGSize(width: rect.width / 1.5,
                                height: rect.width / 1.5)

        let clearRect = CGRect(x: (bounds.width - screenSize.width) / 2,
                               y: (bounds.height - screenSize.height) / 2,
                               width: screenSize.width,
                               height: screenSize.height)
        setScanAnimation(clearRect: clearRect)
        //set masking
        let context = UIGraphicsGetCurrentContext()
        context?.setFillColor(UIColor(red: 40 / 255.0,
                                      green: 40 / 255.0,
                                      blue: 40 / 255.0,
                                      alpha: 0.2).cgColor)
        context?.fill(frame)
        context?.clear(clearRect)
        context?.setLineWidth(cornerLineWidth)
        context?.setStrokeColor(cornerLineColor.cgColor)

        //the upper left corner
        let pointUpperLeftA = [CGPoint(x: clearRect.origin.x - cornerLineDistance,
                                       y: clearRect.origin.y - cornerLineDistance),
                               CGPoint(x: clearRect.origin.x - cornerLineDistance,
                                       y: clearRect.origin.y + cornerLineLength  - cornerLineDistance)]
        let pointUpperLeftB = [CGPoint(x: clearRect.origin.x - cornerLineDistance - cornerLineSpace,
                                       y: clearRect.origin.y - cornerLineDistance),
                               CGPoint(x: clearRect.origin.x + cornerLineLength - cornerLineDistance + cornerLineSpace,
                                       y: clearRect.origin.y - cornerLineDistance)]

        context?.addLines(between: pointUpperLeftA)
        context?.addLines(between: pointUpperLeftB)

        //the lower left corner
        let pointLowerLeftA = [CGPoint(x: clearRect.origin.x - cornerLineDistance,
                                       y: clearRect.origin.y + screenSize.height + cornerLineDistance),
                               CGPoint(x: clearRect.origin.x - cornerLineDistance,
                                       y: clearRect.origin.y + screenSize.height - cornerLineLength + cornerLineDistance)]
        let pointLowerLeftB = [CGPoint(x: clearRect.origin.x - cornerLineDistance - cornerLineSpace,
                                       y: clearRect.origin.y + screenSize.height + cornerLineDistance),
                               CGPoint(x: clearRect.origin.x + cornerLineLength - cornerLineDistance + cornerLineSpace,
                                       y: clearRect.origin.y + screenSize.height + cornerLineDistance)]

        context?.addLines(between: pointLowerLeftA)
        context?.addLines(between: pointLowerLeftB)

        //the upper right corner
        let pointUpperRightA = [CGPoint(x: clearRect.origin.x + screenSize.width + cornerLineDistance + cornerLineSpace,
                                        y: clearRect.origin.y - cornerLineDistance),
                                CGPoint(x: clearRect.origin.x + screenSize.width - cornerLineLength + cornerLineDistance  - cornerLineSpace,
                                        y: clearRect.origin.y - cornerLineDistance)]
        let pointUpperRightB = [CGPoint(x: clearRect.origin.x + screenSize.width + cornerLineDistance,
                                        y: clearRect.origin.y - cornerLineDistance),
                                CGPoint(x: clearRect.origin.x + screenSize.width + cornerLineDistance,
                                        y: clearRect.origin.y + cornerLineLength - cornerLineDistance)]
        context?.addLines(between: pointUpperRightA)
        context?.addLines(between: pointUpperRightB)

        //the lower right corrner
        let pointLowerRightA = [CGPoint(x: clearRect.origin.x + screenSize.width + cornerLineDistance,
                                        y: clearRect.origin.y + screenSize.height + cornerLineDistance),
                                CGPoint(x: clearRect.origin.x +  screenSize.width + cornerLineDistance,
                                        y: clearRect.origin.y + screenSize.height - cornerLineLength + cornerLineDistance)]
        let pointLowerRightB = [CGPoint(x: clearRect.origin.x + screenSize.width + cornerLineDistance + cornerLineSpace,
                                        y: clearRect.origin.y + screenSize.height + cornerLineDistance),
                                CGPoint(x: clearRect.origin.x + screenSize.width - cornerLineLength + cornerLineDistance - cornerLineDistance,
                                        y: clearRect.origin.y + screenSize.height + cornerLineDistance)]
        context?.addLines(between: pointLowerRightA)
        context?.addLines(between: pointLowerRightB)
        context?.strokePath()
    }
}