pragma ComponentBehavior: Bound

import QtQuick
import QtQuick.Shapes
import ZShell.Components
import ZShell.Config
import qs.Services

Item {
	id: root

	readonly property real arcRadius: (size - padding - strokeWidth * (1 + waveAmplitude * 2)) / 2
	property color bgColor: Colors.palette.m3secondaryContainer
	property real clampedVal: Math.max(1 / 360, Math.min(1, isNaN(value) ? 0 : value))
	readonly property real dotAngleRad: (startAngle + sweepAngle - gapAngle * (sweepAngle < 360 ? 0 : 1)) * Math.PI / 180
	property color fgColor: Colors.palette.m3primary
	readonly property real gapAngle: ((spacing + strokeWidth) / (arcRadius || 1)) * (180 / Math.PI)
	property alias hasEndIndicator: dot.active
	property real implicitSize
	property int padding: 0
	readonly property real size: Math.min(width, height)
	property int spacing: Tokens.spacing.small
	property int startAngle: -90
	property int strokeWidth: Tokens.padding.extraSmall
	property int sweepAngle: 360
	readonly property real thickness: strokeWidth * (1 + waveAmplitude) * 2
	property real value
	property alias waveAmplitude: wave.amplitudeMultiplier
	property alias waveDuration: waveProgAnim.duration
	property alias waveFrequency: wave.frequency
	property bool wavePaused
	property bool wavy: false

	implicitHeight: implicitSize
	implicitWidth: implicitSize

	Shape {
		asynchronous: true
		opacity: Math.min(1, remainingArc.sweepAngle)
		preferredRendererType: Shape.CurveRenderer

		ShapePath {
			capStyle: ShapePath.RoundCap
			fillColor: "transparent"
			strokeColor: root.bgColor
			strokeWidth: Math.min(1, remainingArc.sweepAngle) * root.strokeWidth

			Behavior on strokeColor {
				CAnim {
				}
			}

			PathAngleArc {
				id: remainingArc

				centerX: root.size / 2
				centerY: root.size / 2
				radiusX: root.arcRadius
				radiusY: root.arcRadius
				startAngle: root.startAngle + root.clampedVal * root.sweepAngle + root.gapAngle
				sweepAngle: Math.max(1 / 360, root.sweepAngle * (1 - root.clampedVal) - root.gapAngle * (root.sweepAngle < 360 ? 1 : 2))
			}
		}
	}

	WavyLine {
		id: wave

		amplitudeMultiplier: root.wavy ? 0.5 : 0
		anchors.fill: parent
		anchors.margins: -lineWidth * amplitudeMultiplier
		color: root.fgColor
		frequency: 8
		fullAngle: root.sweepAngle
		lineWidth: root.strokeWidth
		pathType: WavyLine.Arc
		radius: root.arcRadius
		startAngle: root.startAngle
		value: root.clampedVal

		Behavior on amplitudeMultiplier {
			Anim {
				type: Anim.DefaultEffects
			}
		}
		Behavior on color {
			CAnim {
			}
		}
		Anim on waveProgress {
			id: waveProgAnim

			duration: 2000
			easing.type: Easing.Linear
			from: 0
			loops: Animation.Infinite
			paused: root.wavePaused || wave.amplitudeMultiplier === 0
			running: true
			to: 1
		}
	}

	Loader {
		id: dot

		x: root.size / 2 + root.arcRadius * Math.cos(root.dotAngleRad) - width / 2
		y: root.size / 2 + root.arcRadius * Math.sin(root.dotAngleRad) - height / 2

		sourceComponent: CustomRect {
			color: root.fgColor
			implicitHeight: Math.min(1, remainingArc.sweepAngle) * Math.min(4, root.strokeWidth)
			implicitWidth: Math.min(1, remainingArc.sweepAngle) * Math.min(4, root.strokeWidth)
			opacity: Math.min(1, remainingArc.sweepAngle)
			radius: Tokens.rounding.full
		}
	}
}
