//
//  ScanView.swift
//  swiftScan
//
//  Created by xialibing on 15/12/8.
//  Copyright © 2015年 xialibing. All rights reserved.
//
//  对 swiftScan 库做的代码规范，修改部分代码，删除一些不需要的代码
//  原地址：https://github.com/CocoaPods/Specs.git

import UIKit

public class ScanView: UIView {
    //扫码区域各种参数
    var viewStyle:ScanViewStyle = ScanViewStyle()
    
    //扫码区域
    var scanRetangleRect:CGRect = CGRect.zero
    
    //线条扫码动画封装
    var scanLineAnimation:ScanLineAnimation?
    
    //网格扫码动画封装
    var scanNetAnimation:ScanNetAnimation?
    
    //线条在中间位置，不移动
    var scanLineStill:UIImageView?
    
    //启动相机时 菊花等待
    var activityView:UIActivityIndicatorView?
    
    //启动相机中的提示文字
    var labelReadying:UILabel?
    
    //记录动画状态
    var isAnimationing:Bool = false
    
    /**
     初始化扫描界面
     - parameter frame:  界面大小，一般为视频显示区域
     - parameter vstyle: 界面效果参数
     
     - returns: instancetype
     */
    public init(frame:CGRect, vstyle:ScanViewStyle) {
        viewStyle = vstyle
        
        switch (viewStyle.anmiationStyle) {
        case .LineMove:
            scanLineAnimation = ScanLineAnimation.instance()
            break
        case .NetGrid:
            scanNetAnimation = ScanNetAnimation.instance()
            break
        case .LineStill:
            scanLineStill = UIImageView()
            scanLineStill?.image = viewStyle.animationImage
            break
        default:
            break
        }
        
        var frameTmp = frame
        frameTmp.origin = CGPoint.zero
        super.init(frame: frameTmp)
        backgroundColor = UIColor.black.withAlphaComponent(0.3)
    }
    
    override init(frame: CGRect) {
        var frameTmp = frame
        frameTmp.origin = CGPoint.zero
        super.init(frame: frameTmp)
        backgroundColor = UIColor.black.withAlphaComponent(0.3)
    }
    
    required public init?(coder aDecoder: NSCoder) {
        self.init()
    }
    
    deinit {
        if let scanLine = scanLineAnimation {
            scanLine.stopStepAnimating()
        }
        
        if let scanNet = scanNetAnimation {
            scanNet.stopStepAnimating()
        }
    }
    
    /**
     *  开始扫描动画
     */
    func startScanAnimation() {
        if isAnimationing {
            return
        }
        isAnimationing = true
        
        let cropRect:CGRect = getScanRectForAnimation()
        switch viewStyle.anmiationStyle {
        case .LineMove:
            scanLineAnimation!.startAnimatingWithRect(animationRect: cropRect, parentView: self, image:viewStyle.animationImage )
            break
            
        case .NetGrid:
            scanNetAnimation!.startAnimatingWithRect(animationRect: cropRect, parentView: self, image:viewStyle.animationImage )
            break
            
        case .LineStill:
            let stillRect = CGRect(x: cropRect.origin.x+20,
                                   y: cropRect.origin.y + cropRect.size.height/2,
                                   width: cropRect.size.width-40,
                                   height: 2)
            self.scanLineStill?.frame = stillRect
            self.addSubview(scanLineStill!)
            self.scanLineStill?.isHidden = false
            break
            
        default: break
            
        }
    }
    
    /**
     *  开始扫描动画
     */
    func stopScanAnimation() {
        isAnimationing = false
        
        switch viewStyle.anmiationStyle {
        case .LineMove:
            scanLineAnimation?.stopStepAnimating()
            break
        case .NetGrid:
            scanNetAnimation?.stopStepAnimating()
            break
        case .LineStill:
            self.scanLineStill?.isHidden = true
            break
        default: break
            
        }
    }
    
    // Only override drawRect: if you perform custom drawing.
    // An empty implementation adversely affects performance during animation.
    override open func draw(_ rect: CGRect) {
        drawScanRect()
    }
    
    //MARK:----- 绘制扫码效果-----
    private func drawScanRect() {
        let XRetangleLeft = viewStyle.xScanRetangleOffset
        var sizeRetangle = CGSize(width: self.frame.size.width - XRetangleLeft*2.0, height: self.frame.size.width - XRetangleLeft*2.0)
        if viewStyle.whRatio != 1.0 {
            let w = sizeRetangle.width
            var h:CGFloat = w / viewStyle.whRatio
            
            let hInt:Int = Int(h)
            h = CGFloat(hInt)
            
            sizeRetangle = CGSize(width: w, height: h)
        }
        
        //扫码区域Y轴最小坐标
        let YMinRetangle = self.frame.size.height / 2.0 - sizeRetangle.height/2.0 - viewStyle.centerUpOffset
        let YMaxRetangle = YMinRetangle + sizeRetangle.height
        let XRetangleRight = self.frame.size.width - XRetangleLeft
        let context = UIGraphicsGetCurrentContext()!
        
        //非扫码区域半透明
        //设置非识别区域颜色
        context.setFillColor(viewStyle.color_NotRecoginitonArea.cgColor)
        //填充矩形
        //扫码区域上面填充
        var rect = CGRect(x: 0, y: 0, width: self.frame.size.width, height: YMinRetangle)
        context.fill(rect)
        
        //扫码区域左边填充
        rect = CGRect(x: 0, y: YMinRetangle, width: XRetangleLeft, height: sizeRetangle.height)
        context.fill(rect)
        
        //扫码区域右边填充
        rect = CGRect(x: XRetangleRight, y: YMinRetangle, width: XRetangleLeft,height: sizeRetangle.height)
        context.fill(rect)
        
        //扫码区域下面填充
        rect = CGRect(x: 0, y: YMaxRetangle, width: self.frame.size.width,height: self.frame.size.height - YMaxRetangle)
        context.fill(rect)
        //执行绘画
        context.strokePath()
        
        if viewStyle.isNeedShowRetangle {
            //中间画矩形(正方形)
            context.setStrokeColor(viewStyle.colorRetangleLine.cgColor)
            context.setLineWidth(1)
            
            context.addRect(CGRect(x: XRetangleLeft, y: YMinRetangle, width: sizeRetangle.width, height: sizeRetangle.height))
            context.strokePath()
        }
        scanRetangleRect = CGRect(x: XRetangleLeft, y:  YMinRetangle, width: sizeRetangle.width, height: sizeRetangle.height)
        
        //画矩形框4格外围相框角
        
        //相框角的宽度和高度
        let wAngle = viewStyle.photoframeAngleW
        let hAngle = viewStyle.photoframeAngleH
        
        //4个角的 线的宽度
        let linewidthAngle = viewStyle.photoframeLineW// 经验参数：6和4
        
        //画扫码矩形以及周边半透明黑色坐标参数
        var diffAngle = linewidthAngle/3
        diffAngle = linewidthAngle / 2 //框外面4个角，与框有缝隙
        diffAngle = linewidthAngle/2  //框4个角 在线上加4个角效果
        diffAngle = 0//与矩形框重合
        
        switch viewStyle.photoframeAngleStyle {
        case .Outer:
            diffAngle = linewidthAngle/3//框外面4个角，与框紧密联系在一起
            
        case .On:
            diffAngle = 0
            
        case .Inner:
            diffAngle = -viewStyle.photoframeLineW/2
        }
        
        context.setStrokeColor(viewStyle.colorAngle.cgColor)
        context.setFillColor(red: 1.0, green: 1.0, blue: 1.0, alpha: 1.0)
        context.setLineWidth(linewidthAngle)
        
        //
        let leftX = XRetangleLeft - diffAngle
        let topY = YMinRetangle - diffAngle
        let rightX = XRetangleRight + diffAngle
        let bottomY = YMaxRetangle + diffAngle
        
        //左上角水平线
        context.move(to: CGPoint(x: leftX-linewidthAngle/2, y: topY))
        context.addLine(to: CGPoint(x: leftX + wAngle, y: topY))
        
        //左上角垂直线
        context.move(to: CGPoint(x: leftX, y: topY-linewidthAngle/2))
        context.addLine(to: CGPoint(x: leftX, y: topY+hAngle))
        
        //左下角水平线
        context.move(to: CGPoint(x: leftX-linewidthAngle/2, y: bottomY))
        context.addLine(to: CGPoint(x: leftX + wAngle, y: bottomY))
        
        //左下角垂直线
        context.move(to: CGPoint(x: leftX, y: bottomY+linewidthAngle/2))
        context.addLine(to: CGPoint(x: leftX, y: bottomY - hAngle))
        
        //右上角水平线
        context.move(to: CGPoint(x: rightX+linewidthAngle/2, y: topY))
        context.addLine(to: CGPoint(x: rightX - wAngle, y: topY))
        
        //右上角垂直线
        context.move(to: CGPoint(x: rightX, y: topY-linewidthAngle/2))
        context.addLine(to: CGPoint(x: rightX, y: topY + hAngle))
        
        //        右下角水平线
        context.move(to: CGPoint(x: rightX+linewidthAngle/2, y: bottomY))
        context.addLine(to: CGPoint(x: rightX - wAngle, y: bottomY))
        
        //右下角垂直线
        context.move(to: CGPoint(x: rightX, y: bottomY+linewidthAngle/2))
        context.addLine(to: CGPoint(x: rightX, y: bottomY - hAngle))
        
        context.strokePath()
    }
    
    func getScanRectForAnimation() -> CGRect {
        let XRetangleLeft = viewStyle.xScanRetangleOffset
        var sizeRetangle = CGSize(width: self.frame.size.width - XRetangleLeft*2, height: self.frame.size.width - XRetangleLeft*2)
        
        if viewStyle.whRatio != 1 {
            let w = sizeRetangle.width
            var h = w / viewStyle.whRatio
            
            let hInt:Int = Int(h)
            h = CGFloat(hInt)
            
            sizeRetangle = CGSize(width: w, height: h)
        }
        
        //扫码区域Y轴最小坐标
        let YMinRetangle = self.frame.size.height / 2.0 - sizeRetangle.height/2.0 - viewStyle.centerUpOffset
        //扫码区域坐标
        let cropRect =  CGRect(x: XRetangleLeft, y: YMinRetangle, width: sizeRetangle.width, height: sizeRetangle.height)
        return cropRect
    }
    
    //根据矩形区域，获取识别区域
    static func getScanRectWithPreView(preView:UIView, style:ScanViewStyle) -> CGRect {
        let XRetangleLeft = style.xScanRetangleOffset
        var sizeRetangle = CGSize(width: preView.frame.size.width - XRetangleLeft*2, height: preView.frame.size.width - XRetangleLeft*2)
        
        if style.whRatio != 1 {
            let w = sizeRetangle.width
            var h = w / style.whRatio
            
            let hInt:Int = Int(h)
            h = CGFloat(hInt)
            
            sizeRetangle = CGSize(width: w, height: h)
        }
        
        //扫码区域Y轴最小坐标
        let YMinRetangle = preView.frame.size.height / 2.0 - sizeRetangle.height/2.0 - style.centerUpOffset
        //扫码区域坐标
        let cropRect =  CGRect(x: XRetangleLeft, y: YMinRetangle, width: sizeRetangle.width, height: sizeRetangle.height)
        
        //计算兴趣区域
        var rectOfInterest:CGRect
        
        //ref:http://www.cocoachina.com/ios/20141225/10763.html
        let size = preView.bounds.size
        let p1 = size.height/size.width
        
        let p2:CGFloat = 1920.0/1080.0 //使用了1080p的图像输出
        if p1 < p2 {
            let fixHeight = size.width * 1920.0 / 1080.0
            let fixPadding = (fixHeight - size.height)/2
            rectOfInterest = CGRect(x: (cropRect.origin.y + fixPadding)/fixHeight,
                                    y: cropRect.origin.x/size.width,
                                    width: cropRect.size.height/fixHeight,
                                    height: cropRect.size.width/size.width)
            
        } else {
            let fixWidth = size.height * 1080.0 / 1920.0
            let fixPadding = (fixWidth - size.width)/2
            rectOfInterest = CGRect(x: cropRect.origin.y/size.height,
                                    y: (cropRect.origin.x + fixPadding)/fixWidth,
                                    width: cropRect.size.height/size.height,
                                    height: cropRect.size.width/fixWidth)
        }
        return rectOfInterest
    }
    
    func getRetangeSize()-> CGSize {
        let XRetangleLeft = viewStyle.xScanRetangleOffset
        
        var sizeRetangle = CGSize(width: self.frame.size.width - XRetangleLeft*2, height: self.frame.size.width - XRetangleLeft*2)
        
        let w = sizeRetangle.width
        var h = w / viewStyle.whRatio
        
        let hInt:Int = Int(h)
        h = CGFloat(hInt)
        
        sizeRetangle = CGSize(width: w, height: h)
        return sizeRetangle
    }
    
    func deviceStartReadying(readyStr: String) {
        let XRetangleLeft = viewStyle.xScanRetangleOffset
        let sizeRetangle = getRetangeSize()

        //扫码区域Y轴最小坐标
        let YMinRetangle = self.frame.size.height / 2.0 - sizeRetangle.height/2.0 - viewStyle.centerUpOffset

        //设备启动状态提示
        if (activityView == nil) {
            self.activityView = UIActivityIndicatorView(frame: CGRect(x: 0, y: 0, width: 30, height: 30))

            activityView?.center = CGPoint(x: XRetangleLeft +  sizeRetangle.width/2 - 50, y: YMinRetangle + sizeRetangle.height/2)
            activityView?.style = UIActivityIndicatorView.Style.whiteLarge

            addSubview(activityView!)

            let labelReadyRect = CGRect(x: activityView!.frame.origin.x + activityView!.frame.size.width + 10, y: activityView!.frame.origin.y, width: 100, height: 30)
            self.labelReadying = UILabel(frame: labelReadyRect)
            labelReadying?.text = readyStr
            labelReadying?.backgroundColor = UIColor.clear
            labelReadying?.textColor = UIColor.white
            labelReadying?.font = UIFont.systemFont(ofSize: 18.0)
            addSubview(labelReadying!)
        }

        addSubview(labelReadying!)
        activityView?.startAnimating()
    }
    
    func deviceStopReadying() {
        if activityView != nil {
            activityView?.stopAnimating()
            activityView?.removeFromSuperview()
            labelReadying?.removeFromSuperview()
            
            activityView = nil
            labelReadying = nil
        }
    }
}
