<script lang="ts">
	import knobdrag, { makeValueStore } from '$lib/knob-drag';
	import { createEventDispatcher } from 'svelte';
	import mediumKnob from '../../images/medium-knob.png';

	export let value: number = 50;
	export let disabled: boolean = false;
	let min = 0;
	let max = 100;
	let step = 1;
	$: glowOpacity = 0.4 + (value / 100) * 0.6;

	let glowDiameter = 112;

	const dispatch = createEventDispatcher();
	const valueStore = makeValueStore(value, (newValue) => (value = newValue));
	$: valueStore.set(value);
	$: knobParams = { min, max, step, valueStore };

	const handleMouse = (event: MouseEvent) => {
		if (event.type === 'mousedown') {
			document.addEventListener('mouseup', handleMouse);
			document.body.classList.add('cursor-none');
			dispatch('update-start');
		} else if (event.type === 'mouseup') {
			document.removeEventListener('mouseup', handleMouse);
			dispatch('update-end');
			document.body.classList.remove('cursor-none');
		}
	};
</script>

<div class="relative h-[152px] w-[152px]">
	<img src={mediumKnob} class="absolute left-0 top-0 w-full" />
	<svg width="152" height="152" viewBox="0 0 152 152" class:disabled>
		<defs>
			<filter
				id="glowBlur"
				x="-50%"
				y="-50%"
				height="200%"
				width="200%"
				xmlns="http://www.w3.org/2000/svg"
			>
				<feGaussianBlur in="SourceGraphic" stdDeviation="12" />
			</filter>
			<filter
				id="reflectionBlur"
				x="-40%"
				y="-40%"
				height="180%"
				width="180%"
				xmlns="http://www.w3.org/2000/svg"
			>
				<feGaussianBlur in="SourceGraphic" stdDeviation="4" />
			</filter>
			<filter
				id="glintBlur"
				x="-40%"
				y="-40%"
				height="180%"
				width="180%"
				xmlns="http://www.w3.org/2000/svg"
			>
				<feGaussianBlur in="SourceGraphic" stdDeviation="2" />
			</filter>
		</defs>
		<circle
			class="glow-bg"
			r={glowDiameter / 2}
			cx="76"
			cy="76"
			style:stroke-dashoffset="0"
			style:stroke-dasharray={glowDiameter * Math.PI * 0.75}
			transform="rotate(135 0 0)"
			transform-origin="center center"
		/>

		<circle
			class="glow"
			r={glowDiameter / 2}
			cx="76"
			cy="76"
			style:stroke-dashoffset={glowDiameter * Math.PI -
				(glowDiameter * Math.PI * (value - min) * 0.75) / 100}
			style:stroke-dasharray={glowDiameter * Math.PI}
			transform="rotate(135 0 0)"
			transform-origin="center center"
			opacity={glowOpacity}
		/>

		<circle
			class="blur"
			r={glowDiameter / 2}
			cx="76"
			cy="76"
			style:stroke-dashoffset={glowDiameter * Math.PI -
				(glowDiameter * Math.PI * (value - min) * 0.75) / 100}
			style:stroke-dasharray={glowDiameter * Math.PI}
			transform="rotate(135 0 0)"
			transform-origin="center center"
			filter="url(#glowBlur)"
			opacity={glowOpacity}
		/>

		<circle
			class="glint"
			r={glowDiameter / 2}
			cx="76"
			cy="76"
			style:stroke-dashoffset={glowDiameter * Math.PI -
				(glowDiameter * Math.PI * (value - min) * 0.75) / 100}
			style:stroke-dasharray={glowDiameter * Math.PI}
			transform="rotate(135 0 0)"
			transform-origin="center center"
			filter="url(#glintBlur)"
		/>

		{#if !disabled}
			<circle
				class="inner"
				r="40"
				cx="76"
				cy="76"
				use:knobdrag={knobParams}
				on:mousedown={handleMouse}
			/>
		{/if}

		<path
			d="M76 56V62"
			class="notch"
			stroke-width="4"
			stroke-linecap="round"
			transform-origin="76 76"
			transform="rotate({-135 + (value / max) * 270} 0 0)"
		/>

		<circle
			class="reflection"
			r="28"
			cx="76"
			cy="76"
			style:stroke-dashoffset={56 * Math.PI - (56 * Math.PI * (value - min) * 0.75) / 100}
			style:stroke-dasharray={56 * Math.PI}
			transform="rotate(135 0 0)"
			transform-origin="center center"
			filter="url(#reflectionBlur)"
			opacity={0.5 + glowOpacity * 0.5}
		/>
	</svg>
</div>

<style>
	svg {
		@apply pointer-events-auto relative;
	}

	.reflection,
	.glow,
	.blur,
	.glint,
	.glow-bg {
		fill: none;
		stroke: #000;
		stroke-width: 8px;
		stroke-linecap: round;
	}
	.reflection,
	.blur,
	.glow {
		stroke: var(--fx-color);
	}

	.blur {
		stroke-width: 8px;
	}
	.glint {
		stroke: #fff;
		stroke-width: 2px;
		opacity: 0.4;
		/* mix-blend-mode: overlay; */
	}
	.reflection {
		stroke-width: 2px;
	}
	.inner {
		fill: #000;
		opacity: 0;
	}
	.notch {
		@apply transition-[stroke];
		stroke: #aaa;
	}
	svg.disabled {
		& .notch {
			stroke: #000;
		}
	}
	svg:not(.disabled):hover {
		& .notch {
			stroke: #fff;
		}
	}

	.glow,
	.notch,
	.blur,
	.reflection {
		@apply pointer-events-none;
	}
</style>
