//
//  KMSyncDot.swift
//  PDF Reader Pro
//
//  Created by lizhe on 2024/2/29.
//

import Cocoa
import QuartzCore

class KMSyncDot: NSObject {
    var point: NSPoint
    var page: CPDFPage?
    private var phase: Int = 0
    private var timer: Timer?
    private var handler: ((Bool) -> Void)?

    init(point: NSPoint, page: CPDFPage?, updateHandler: ((Bool) -> Void)?) {
        self.point = point
        self.page = page
        self.handler = updateHandler
        super.init()
        setup()
    }

    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    private func setup() {
        timer = Timer.scheduledTimer(timeInterval: 0.05, target: self, selector: #selector(animate(_:)), userInfo: nil, repeats: true)
    }

    deinit {
        timer?.invalidate()
        handler = nil
    }

    @objc private func finish(_ timer: Timer) {
        timer.invalidate()
        if let handler = handler {
            handler(true)
        }
    }

    @objc private func animate(_ timer: Timer) {
        phase += 1
        if phase >= 10 {
            timer.invalidate()
            self.timer = Timer.scheduledTimer(timeInterval: 5.0, target: self, selector: #selector(finish(_:)), userInfo: nil, repeats: false)
        }
        if let handler = handler {
            handler(false)
        }
    }

    func invalidate() {
        timer?.invalidate()
    }
    
    func bounds() -> NSRect {
        return KMRectFromCenterAndSquareSize(center: point, size: 22.0) ?? .zero
    }

    func draw(in ctx: CGContext) {
        ctx.saveGState()

        var s: CGFloat = 6.0
        OSMemoryBarrier()
        if phase < 10 {
            s += 8.0 * sin(CGFloat(phase) * 0.1 * .pi)
            let components: [CGFloat] = [1.0, 0.3, 0.3, 1.0, 1.0, 0.0, 0.0, 1.0]
            let locations: [CGFloat] = [0.0, 1.0]
            let colorspace = CGColorSpaceCreateDeviceRGB()
            if let gradient = CGGradient(colorSpace: colorspace, colorComponents: components, locations: locations, count: 2) {
                ctx.addEllipse(in: CGRect(x: point.x - 0.5 * s, y: point.y - 0.5 * s, width: s, height: s))
                ctx.clip()
                ctx.drawRadialGradient(gradient, startCenter: CGPoint(x: point.x, y: point.y + 0.35 * s), startRadius: 0.0, endCenter: CGPoint(x: point.x, y: point.y), endRadius: 0.5 * s, options: [])
            }
        } else {
            ctx.setBlendMode(.multiply)
            ctx.setFillColor(CGColor(red: 1.0, green: 0.0, blue: 0.0, alpha: 1.0))
            ctx.fillEllipse(in: CGRect(x: point.x - 0.5 * s, y: point.y - 0.5 * s, width: s, height: s))
        }

        ctx.restoreGState()
    }
}