//
//  UIView+Ext.swift
//  DouYinSwift5
//
//  Created by lym on 2020/7/23.
//  Copyright © 2020 lym. All rights reserved.
//

import UIKit


public func adaptWidth(designWidth: CGFloat = 375.0, _ vale: CGFloat) -> CGFloat {
    return UIScreen.main.bounds.size.width / designWidth * vale
}

// MARK: - 属性

@objc extension UIView {
    /// 边框颜色
    @IBInspectable var borderColor: UIColor? {
        get {
            guard let color = layer.borderColor else { return nil }
            return UIColor(cgColor: color)
        }
        set {
            guard let color = newValue else {
                layer.borderColor = nil
                return
            }
            layer.borderColor = color.cgColor
        }
    }

    /// 边框宽度
    @IBInspectable var borderWidth: CGFloat {
        get { return layer.borderWidth }
        set { layer.borderWidth = newValue }
    }

    /// 圆角半径
    @IBInspectable var cornerRadius: CGFloat {
        get { return layer.cornerRadius }
        set {
            layer.cornerRadius = newValue
            layer.masksToBounds = true
        }
    }

    var size: CGSize {
        get { return frame.size }
        set { width = newValue.width; height = newValue.height }
    }

    var width: CGFloat {
        get { return frame.size.width }
        set { return frame.size.width = newValue }
    }

    var height: CGFloat {
        get { return frame.size.height }
        set { return frame.size.height = newValue }
    }

    var x: CGFloat {
        get { return frame.origin.x }
        set { frame.origin.x = newValue }
    }

    var y: CGFloat {
        get { return frame.origin.y }
        set { frame.origin.y = newValue }
    }

    var centerX: CGFloat {
        get { return center.x }
        set { center.x = newValue }
    }

    var centerY: CGFloat {
        get { return center.y }
        set { center.y = newValue }
    }

    var origin: CGPoint {
        get { return frame.origin }
        set { frame.origin = newValue }
    }
}

@objc public extension UIView {
   
    
    /// 删除所有的子视图
    func removeSubviews() {
        subviews.forEach { $0.removeFromSuperview() }
    }

    /// 添加阴影
    /// - Parameters:
    ///   - color: 颜色
    ///   - radius: 半径
    ///   - offset: 偏移
    ///   - opacity: 透明度
    func addShadow(ofColor color: UIColor = UIColor(red: 0.07, green: 0.47, blue: 0.57, alpha: 1.0),
                   radius: CGFloat = 3,
                   offset: CGSize = .zero,
                   opacity: Float = 0.5)
    {
        layer.shadowColor = color.cgColor
        layer.shadowOffset = offset
        layer.shadowRadius = radius
        layer.shadowOpacity = opacity
        layer.masksToBounds = false
    }

    /// 返回视图的控制器对象
    ///
    /// - Returns: 控制器对象，可能为空
    func viewController() -> UIViewController? {
        var view: UIView? = self
        repeat {
            if let nextResponder = view?.next {
                if nextResponder.isKind(of: UIViewController.self) {
                    return nextResponder as? UIViewController
                }
            }
            view = view?.superview
        } while view != nil

        return nil
    }
}

@objc extension UIView {
    @discardableResult
    /// 添加渐变背景
    func addGradientColor(startPoint: CGPoint,
                          endPoint: CGPoint,
                          locs: [NSNumber] = [0, 1],
                          colors: [Any],
                          cornerRadius: CGFloat = 0) -> CAGradientLayer?
    {
        guard startPoint.x >= 0,
              startPoint.x <= 1,
              startPoint.y >= 0,
              startPoint.y <= 1,
              endPoint.x >= 0,
              endPoint.x <= 1,
              endPoint.y >= 0,
              endPoint.y <= 1
        else {
            return nil
        }

        layoutIfNeeded()

        var gradientLayer: CAGradientLayer!

        removeGradientLayer()

        gradientLayer = CAGradientLayer()
        gradientLayer.frame = layer.bounds
        gradientLayer.startPoint = startPoint
        gradientLayer.endPoint = endPoint
        gradientLayer.colors = colors
        gradientLayer.cornerRadius = layer.cornerRadius
        gradientLayer.masksToBounds = true
        gradientLayer.locations = locs

        if cornerRadius > 0 {
            let shapeLayer = CAShapeLayer()
            shapeLayer.borderWidth = 1
            shapeLayer.path = UIBezierPath(roundedRect: gradientLayer.bounds, cornerRadius: cornerRadius).cgPath
            shapeLayer.fillColor = UIColor.clear.cgColor // 必须要设置成clearColor或者nil，默认是黑色
            shapeLayer.strokeColor = UIColor.white.cgColor // 随便设置一个非clearColor的颜色
            gradientLayer.mask = shapeLayer
        }

        // 渐变图层插入到最底层，避免在uibutton上遮盖文字图片
        layer.insertSublayer(gradientLayer, at: 0)
        backgroundColor = UIColor.clear
        // self如果是UILabel，masksToBounds设为true会导致文字消失
        // layer.masksToBounds = false
        return gradientLayer
    }

    public func removeGradientLayer() {
        if let sl = layer.sublayers {
            for layer in sl {
                if layer.isKind(of: CAGradientLayer.self) {
                    layer.removeFromSuperlayer()
                }
            }
        }
    }
    
    func addDashedBorder(to view: UIView, lineLength: CGFloat = 8, lineSpacing: CGFloat = 2, cornerRadius: CGFloat = 0) {
        let shapeLayer = CAShapeLayer()
        shapeLayer.name = "DashedBorder"
        let lineColor = UIColor.c.con
        // let lineColor = UIColor.red

        shapeLayer.bounds = view.bounds
        shapeLayer.position = CGPoint(x: view.bounds.width / 2, y: view.bounds.height / 2)
        shapeLayer.fillColor = UIColor.clear.cgColor
        shapeLayer.strokeColor = lineColor.cgColor
        shapeLayer.lineWidth = 1
        shapeLayer.lineJoin = .round
        shapeLayer.lineDashPattern = [NSNumber(value: Float(lineLength)), NSNumber(value: Float(lineSpacing))]

        let path = UIBezierPath(roundedRect: view.bounds, cornerRadius: cornerRadius)
        shapeLayer.path = path.cgPath

        // 先移除旧的虚线层（避免重复添加）
        view.layer.sublayers?.removeAll(where: { $0.name == "DashedBorder" })

        view.layer.addSublayer(shapeLayer)
    }

}

extension UIView{
    /// 将一个矩形区域从指定视图坐标系转换到当前视图或窗口坐标系
    ///
    /// 使用方法：
    /// ```
    /// CGRect rect = [self.view convertRect:_button.frame fromViewOrWindow:_button.superview];
    /// ```
    ///
    /// button的frame是相对于其superview来确定的，frame确定了button在其superview的位置和大小
    ///
    /// 一般来说，toView方法中，消息的接收者为被转换的frame所在的控件的superview；fromView方法中，消息的接收者为即将转到的目标view.
    ///
    /// - Parameters:
    ///   - rect: 矩形区域
    ///   - view: 指定视图或窗口
    /// - Returns: 当前坐标系的矩形区域
    func convertRect(rect: CGRect, fromViewOrWindow view: UIView?) -> CGRect {
        guard let view = view else {
            if isKind(of: UIWindow.self) {
                return (self as! UIWindow).convert(rect, from: nil)
            } else {
                return convert(rect, from: nil)
            }
        }

        if let from = view.isKind(of: UIWindow.self) ? (view as! UIWindow) : view.window,
           let to = isKind(of: UIWindow.self) ? (self as! UIWindow) : window, from != to {
            var r = rect
            r = from.convert(r, from: view)
            r = to.convert(r, from: from)
            r = convert(r, from: to)
            return r
        } else {
            return convert(rect, from: view)
        }
    }
}

extension UIView{
    /// 扩展UIView增加抖动方法
        ///
        /// - Parameters:
        ///   - isVertical: 抖动方向（默认是水平方向）
        ///   - times: 抖动次数（默认5次）
        ///   - interval: 每次抖动时间（默认0.1秒）
        ///   - delta: 抖动偏移量（默认2）
        ///   - completion: 抖动动画结束后的回调
        public func shake(_ isVertical: Bool = false,
                          _ times: Int = 5,
                          _ interval: TimeInterval = 0.1,
                          _ delta: CGFloat = 2,
                          _ completion: (() -> ())? = nil) {
            // 播放动画
            UIView.animate(withDuration: interval) {
                var transform = CGAffineTransform(translationX: 0, y: delta)
                if isVertical == true {
                    transform = CGAffineTransform(translationX: delta, y: 0)
                }
                self.layer.setAffineTransform(transform)
            } completion: {_ in
                // 如果当前是最后一次抖动，则将位置还原，并调用完成回调函数
                if (times == 0) {
                    UIView.animate(withDuration: interval) {
                        self.layer.setAffineTransform(CGAffineTransform.identity)
                    } completion: { _ in
                        completion?()
                    }
                }else {
                    // 如果当前不是最后一次抖动，则继续播放动画（总次数减1，偏移位置变成相反的）
                    self.shake(isVertical, times - 1, interval, -delta, completion)
                }
            }
        }
}

extension UIView {
    //将当前视图转为UIImage
    func asImage() -> UIImage {
        let renderer = UIGraphicsImageRenderer(bounds: bounds)
        return renderer.image { rendererContext in
            layer.render(in: rendererContext.cgContext)
        }
    }
    
    /// 获取视图在屏幕上的绝对坐标（相对于整个屏幕）
    var screenRect: CGRect? {
        guard let window = self.window else { return nil }
        return self.superview?.convert(self.frame, to: window)
    }
}
