<script>
    import { createEventDispatcher } from 'svelte';
    import KeyCombo from '../KeyCombo.svelte';

    export let description;
    export let value;

    const id = Math.random().toString().slice(2);
    const dispatch = createEventDispatcher();
    const MODIFIERS = new Set(['Alt', 'AltGraph', 'Control', 'Fn', 'FnLock', 'Meta', 'Shift', 'Super', ]);


    let listening = false;
    let keysPressed = [];

    function addModifiers(event) {
        // add modifier key if it isn't already present
        if (MODIFIERS.has(event.key) && keysPressed.indexOf(event.key) === -1) {
            keysPressed.push(event.key);
        }
    }

    function addMainKey(event) {
        if (!MODIFIERS.has(event.key)) {
            keysPressed.push(event.key);
            
            value.keys = keysPressed.join('+');
            dispatch('update', {value});
            event.preventDefault();
            event.stopPropagation();

            unlisten();
        }
    }
    
    function listen() {
        // don't re-listen if we already are
        if (listening) return;

        listening = true;
        window.addEventListener('keydown', addModifiers);
        window.addEventListener('keyup', addMainKey);
        // setTimeout avoids reacting to the click event that we are currently processing
        setTimeout(() => window.addEventListener('click', unlisten), 0);
    }

    function unlisten() {
        listening = false;
        keysPressed = [];
        window.removeEventListener('keydown', addModifiers);
        window.removeEventListener('keyup', addMainKey);
        window.removeEventListener('click', unlisten);
    }
</script>


<input 
    {id} 
    type="checkbox"
    class="checkbox checkbox-primary"
    bind:checked={value.enabled}
    on:change={() => dispatch('update', {value})}
>
<label for={id} class="cursor-pointer ml-4 text-lg">{description}</label>

<button class="h-12 p-2 rounded border border-neutral cursor-pointer text-center" on:click={listen}>
    {#if listening}
        Click to cancel
    {:else}
        <KeyCombo keys={value.keys.split('+')} />
    {/if}
</button>
