<script lang="ts">
	import { onMount } from 'svelte';
	import { i18n } from '$lib/i18n';

	let frequency = 60;
	let playing = false;

	let audioCtx: AudioContext | undefined;
	let oscillatorL: OscillatorNode | undefined;
	let oscillatorR: OscillatorNode | undefined;

	onMount(() => {
		audioCtx = new window.AudioContext();
	});

	function start(mode: 'inPhase' | 'outOfPhase') {
		if (!audioCtx) return;
		oscillatorL?.stop();
		oscillatorR?.stop();

		oscillatorL = audioCtx.createOscillator();
		oscillatorR = audioCtx.createOscillator();
		const gainNode = audioCtx.createGain();

		const stereoPannerL = audioCtx.createStereoPanner();
		const stereoPannerR = audioCtx.createStereoPanner();

		oscillatorL.frequency.setValueAtTime(frequency, audioCtx.currentTime);
		oscillatorR.frequency.setValueAtTime(frequency, audioCtx.currentTime);

		stereoPannerL.pan.setValueAtTime(-1, audioCtx.currentTime);
		stereoPannerR.pan.setValueAtTime(1, audioCtx.currentTime);

		oscillatorL.connect(stereoPannerL).connect(audioCtx.destination);
		oscillatorR.connect(gainNode).connect(stereoPannerR).connect(audioCtx.destination);

		if (mode === 'inPhase') {
			gainNode?.gain.setValueAtTime(1, audioCtx.currentTime); // Normal phase
		} else {
			gainNode?.gain.setValueAtTime(-1, audioCtx.currentTime); // Invert phase
		}

		oscillatorL?.start();
		oscillatorR?.start();
		playing = true;
	}

	async function stop() {
		oscillatorL?.stop();
		oscillatorR?.stop();
		playing = false;
	}
</script>

<div class="test">
	<label>
		{$i18n.t('Frequency')}
		<input type="number" bind:value={frequency} min="20" max="20000" disabled={playing} />Hz
	</label>
	<div class="controls">
		<button on:click={() => start('inPhase')}>{$i18n.t('In Phase')}</button>
		<button on:click={() => start('outOfPhase')}>{$i18n.t('Out of Phase')}</button>
		<button class="stop" on:click={stop} disabled={!playing}>{$i18n.t('Stop')}</button>
	</div>
</div>

<style>
	.test {
		margin: 1em 0;
	}

	.controls {
		margin-top: 0.5em;
	}

	.stop {
		margin-left: 1em;

		&:not(:disabled) {
			background: darkred;
		}
	}

	input {
		width: 5em;
	}
</style>
