<script>
	import { onMount, createEventDispatcher } from "svelte";
	import {
		Html5QrcodeScanner,
		Html5QrcodeScanType,
		Html5QrcodeSupportedFormats,
		Html5QrcodeScannerState,
	} from "html5-qrcode";

	export let width;
	export let height;
	export let paused = false;

	const dispatch = createEventDispatcher();

	function onScanSuccess(decodedText, decodedResult) {
		dispatch("detect", { decodedText });
	}

	// usually better to ignore and keep scanning
	function onScanFailure(message) {
		dispatch("error", { message });
	}

	let scanner;
	onMount(() => {
		scanner = new Html5QrcodeScanner(
			"qr-scanner",
			{
				fps: 10,
				rememberLastUsedCamera: true,
				qrbox: { width, height },
				aspectRatio: 1,
				supportedScanTypes: [Html5QrcodeScanType.SCAN_TYPE_CAMERA],
				formatsToSupport: [
					Html5QrcodeSupportedFormats.CODE_39,
					Html5QrcodeSupportedFormats.EAN_8,
					Html5QrcodeSupportedFormats.EAN_13,
					Html5QrcodeSupportedFormats.QR_CODE,
					Html5QrcodeSupportedFormats.CODE_128,
				],
			},
			false // non-verbose
		);
		scanner.render(onScanSuccess, onScanFailure);
	});

	// pause/resume scanner to avoid unintended scans
	$: togglePause(paused);
	function togglePause(paused) {
		if (paused && scanner?.getState() === Html5QrcodeScannerState.SCANNING) {
			scanner?.pause();
		} else if (scanner?.getState() === Html5QrcodeScannerState.PAUSED) {
			scanner?.resume();
		}
	}
</script>

<div id="qr-scanner" class={$$props.class} />

<style>
	/* Hide unwanted icons */
	#qr-scanner :global(img[alt="Info icon"]),
	#qr-scanner :global(img[alt="Camera based scan"]) {
		display: none;
	}

	/* Change camera permission button text */
	#qr-scanner :global(#html5-qrcode-button-camera-permission) {
		visibility: hidden;
	}
	#qr-scanner :global(#html5-qrcode-button-camera-permission::after) {
		position: absolute;
		inset: auto 0 0;
		display: block;
		content: "Allow camera access";
		visibility: visible;
		padding: 10px 0;
	}
</style>
