//
//  MPPositive_PlayerSilder.swift
//  MusicPlayer
//
//  Created by Mr.Zhou on 2024/5/8.
//

import UIKit
///b面播放器进度条（展示缓存效果，聚焦时进行尺寸变化）
class MPPositive_PlayerSilder: UISlider {
    /// 触控扩展边距
    var hitTestEdgeInsets: UIEdgeInsets = UIEdgeInsets(top: -20*width, left: 0, bottom: -20*width, right: 0)
    /// 原始的Slider大小
    var originalFrame: CGRect?
    //滑块图片
    var thumbImage:UIImage = .init(named: "Player_Slider'logo")!
    //滑轨槽高度
    var trackHeight: CGFloat = 6*width
    //进度渐变色
    var minTrackColors: [UIColor]!
    //槽位渐变色
    var maxTrackColors:[UIColor]!
    //进度渐变色定位列表(与渐变色数量保持一致)
    var minTrackLocations:[CGFloat]!
    //槽位渐变色定位列表(与渐变色数量保持一致)
    var maxTrackLocations:[CGFloat]!

    //初始化
    override init(frame:CGRect) {
        super.init(frame: frame)
        setUpLayout()
//        print("调整Slider大小")
        originalFrame = self.frame
    }
    override func awakeFromNib() {
        super.awakeFromNib()
    }
    
    required init?(coder: NSCoder) {
        super.init(coder: coder)
    }
    private func setUpLayout() {
        layer.masksToBounds = false
        setThumbImage(thumbImage, for: .normal)
        //设置进度图片
        let minTrackImg = makeTrackImage(rect: frame, colors: [UIColor.white], locations: [0,1])
        setMinimumTrackImage(minTrackImg, for: .normal)
        // 设置槽位
        let maxTrackImg = makeTrackImage(rect: frame, colors: [UIColor(hex: "#FFFFFF", alpha: 0.1)], locations: [0,1])
        setMaximumTrackImage(maxTrackImg, for: .normal)
    }
    
    /// 滑块设置
    /// - Parameters:
    ///   - rect: 滑块大小
    ///   - color: 滑块颜色
    /// - Returns: 返回的滑块图片
    private func makeThumbImage(rect: CGRect, color:UIColor) -> UIImage {
        let lineWidth: CGFloat = 2
        //开始绘制
        UIGraphicsBeginImageContextWithOptions(rect.size, false, 0)
        //填充内部颜色
        color.setFill()
        //曲线路径
        let oval = UIBezierPath(ovalIn: rect)
        //填充路径
        oval.fill()
        //设置路径颜色为白色
        UIColor.white.setStroke()
        //路径宽度
        oval.lineWidth = lineWidth
        oval.stroke()
        //转为图片
        let thumbImg = UIGraphicsGetImageFromCurrentImageContext()!
        //转化结束
        UIGraphicsEndImageContext()
        return thumbImg
    }
    
    
    /// 生成滑轨图片
    /// - Parameters:
    ///   - rect: 滑轨大小
    ///   - colors: 颜色列表
    ///   - locations: 位置分布列表
    /// - Returns: 生成的图片
    private func makeTrackImage(rect: CGRect, colors:[UIColor], locations:[CGFloat]) -> UIImage {
        let rect = CGRect(x: rect.minX, y: rect.minY, width: rect.width, height: self.trackHeight)
        //开始绘制
        UIGraphicsBeginImageContextWithOptions(rect.size, false, 0)
        let ctx = UIGraphicsGetCurrentContext()!
        // 创建并设置路径
        let cornerRadius: CGFloat = rect.height * 0.5
        let path = UIBezierPath(roundedRect: rect, cornerRadius: cornerRadius).cgPath
        // 添加路径到图形上下文
        ctx.addPath(path)
        ctx.clip()
        // 使用rgb颜色空间
        let colorSpace = CGColorSpaceCreateDeviceRGB()
        //获取cgcolors
        var cgColors:[CGColor] = []
        colors.forEach { item in
            cgColors.append(item.cgColor)
        }
        // 定义渐变色
        let gradient:CGGradient = CGGradient(colorsSpace: colorSpace, colors: cgColors as CFArray, locations: locations)!
        // 渐变开始位置
        let start = CGPoint(x: self.bounds.minX, y: self.bounds.minY)
        // 渐变结束位置
        let end = CGPoint(x: self.bounds.maxX, y: self.bounds.minY)
        // 绘制渐变
        ctx.drawLinearGradient(gradient, start: start, end: end, options: .drawsBeforeStartLocation)
        //转为图片
        let trackImg = UIGraphicsGetImageFromCurrentImageContext()!
        UIGraphicsEndImageContext()
        return trackImg
    }
    // 重写【thumb】显示区域 方法
    override func thumbRect(forBounds bounds: CGRect, trackRect rect: CGRect, value: Float) -> CGRect {
        let rect = super.thumbRect(forBounds: bounds, trackRect: rect, value: value)
        // 设置thumb投影效果
        // (这样设置的投影效果，如果调用setValue(_:animated:)的时候，animated参数为true，会有阴影和thumb不同步的问题，目前还不知到怎么解决)
        self.layer.shadowColor = UIColor.black.cgColor
        self.layer.shadowOffset = CGSize(width: 0, height: 0)
        self.layer.shadowOpacity = 0.15
        self.layer.shadowRadius = 3
        self.layer.shadowPath = UIBezierPath(cgPath: CGPath(ellipseIn: rect.insetBy(dx: 3, dy: 3), transform: nil)).cgPath
        return rect
    }
    // 重写【track】显示区域 方法
    override func trackRect(forBounds bounds: CGRect) -> CGRect {
        return CGRect(x: 0, y: 0, width: bounds.width, height: self.trackHeight)
    }
    //MARK: - 交互代码
    //当用户点击时
    override func point(inside point: CGPoint, with event: UIEvent?) -> Bool {
        //对Slider添加一个边距范围
        let largerFrame: CGRect = self.bounds.inset(by: hitTestEdgeInsets)
        
        return largerFrame.contains(point)
    }
    //手势开始时
    override func beginTracking(_ touch: UITouch, with event: UIEvent?) -> Bool {
        let tracking = super.beginTracking(touch, with: event)
        if tracking == true {
            //增加高度
            focusOnSlider(true)
        }else {
            let touchPoint = touch.location(in: self)
            // 寻找触摸点在滑动条上的位置所占的相对比例
            let value = self.minimumValue + Float(touchPoint.x / self.bounds.width) * (self.maximumValue - self.minimumValue)
            // 更新滑块位置
            self.setValue(value, animated: false)
            //让播放器恢复状态
            MP_PlayerManager.shared.setEditProgressEnd(value)
        }
        return tracking
    }
    //手势途中
    override func continueTracking(_ touch: UITouch, with event: UIEvent?) -> Bool {
        //继续滑动
        return super.continueTracking(touch, with: event)
    }
    //手势继续
    override func endTracking(_ touch: UITouch?, with event: UIEvent?) {
        super.endTracking(touch, with: event)
        // 手势结束时恢复高度
        focusOnSlider(false)
    }
    //手势取消
    override func cancelTracking(with event: UIEvent?) {
        super.cancelTracking(with: event)
        // 手势取消时恢复高度
        focusOnSlider(false)
    }
    //当用户焦点汇聚到slider
    private func focusOnSlider(_ focusing:Bool) {
        guard let originalFrame = originalFrame else { return }
        //动画修改Slider高度
        UIView.animate(withDuration: 0.3) {
            if focusing {
                //聚焦状态，增加slider高度
                self.transform = CGAffineTransform(scaleX: 1.0, y: 1.5)
            }else {
                //失去焦点，恢复原状
                self.transform = .identity
            }
        }
    }
}
