<script lang="ts">
	import { onMount, onDestroy } from 'svelte';
	import { SolarSystem2DRenderer } from '$lib/render/canvas2d/SolarSystem2D';
	import { simulation } from '$lib/stores/simulation.svelte';
	import { getBodyPositions, getBodyVelocities, getBodyInfos, getOrbitPoints } from '$lib/wasm/bridge';

	let canvas: HTMLCanvasElement;
	let renderer: SolarSystem2DRenderer;
	let animFrameId: number;
	let orbitsComputed = false;

	function computeOrbits() {
		const bodyCount = simulation.bodyInfos.length;
		for (let i = 1; i < bodyCount; i++) {
			const points = getOrbitPoints(i, simulation.currentJD, 360);
			if (points.length > 0) {
				renderer.updateOrbit(i, points);
			}
		}
		orbitsComputed = true;
	}

	onMount(() => {
		renderer = new SolarSystem2DRenderer(canvas);

		if (simulation.wasmReady) {
			simulation.bodyInfos = getBodyInfos();
		}

		let lastTime = performance.now();
		let frameCount = 0;

		function mainLoop() {
			const now = performance.now();
			const dt = (now - lastTime) / 1000;
			lastTime = now;
			simulation.advanceTime(dt);

			if (simulation.wasmReady) {
				simulation.bodyPositions = getBodyPositions(simulation.currentJD);
				const velocities = getBodyVelocities(simulation.currentJD);
				renderer.updateBodies(simulation.bodyInfos, simulation.bodyPositions, velocities);

				// Compute orbits on first frame and refresh every 600 frames (~10s)
				if (!orbitsComputed || frameCount % 600 === 0) {
					computeOrbits();
				}
			}
			renderer.render();
			frameCount++;
			animFrameId = requestAnimationFrame(mainLoop);
		}

		mainLoop();
	});

	onDestroy(() => {
		if (animFrameId) cancelAnimationFrame(animFrameId);
		renderer?.destroy();
	});
</script>

<canvas
	bind:this={canvas}
	class="w-full h-full block"
	style="cursor: grab;"
></canvas>
