    <script>
    import { activeField } from './field_sync.svelte.js';
    import { t } from '../translations.svelte.js';

    let {
        simple   = false,
        editable = simple,
        href     = '#',
        onclick  = evt => { evt.preventDefault(); startEdit(); return false },
        onSet    = newVal => {return true;},
        title    = t('click_to_edit'),
        type     = 'text',
        value    = $bindable(null),
        wrapper  = 'div'
    } = $props();

    let editing   = $state(simple);
    let editValue = value;
    let start     = 0;
    let x         = 0;
    let y         = 0;

    async function applyEdit(){
        let success = await onSet(editValue);
        if (success) {
            if (success == 'reset'){
                editValue = value;
            } else {
                value   = editValue;
            }
            editing = false;
        } else {
            editValue = value;
        }
    }

    function ignore(evt){
        evt.preventDefault();
        evt.stopPropagation();
        return false;
    }

    function measured(evt,duration,d){
        if (d > 10) return;
        if (duration < 500){
            onclick(evt);
        } else {
            startEdit();
        }
    }

    function oncontextmenu(evt){
         startEdit();
         return ignore(evt);
    }

    function onmousedown(evt){
        start = evt.timeStamp;
        return ignore(evt);
    }

    function onmouseup(evt){
        measured(evt, evt.timeStamp - start,0);
        return ignore(evt);
    }

    function ontouchstart(evt){
        start = evt.timeStamp;
        x     = evt.touches[0].clientX;
        y     = evt.touches[0].clientY;
        return ignore(evt);
    }

    function ontouchend(evt){
        let d = Math.abs(x - evt.changedTouches[0].clientX) + Math.abs(y - evt.changedTouches[0].clientY);
        measured(evt, evt.timeStamp - start, d);
        return ignore(evt);
    }

    function resetEdit(){
        editing   = false;
        editValue = value;
    }

    function startEdit(){
        activeField.update((n) => n+1);
        editing = editable;
    }

    function typed(ev){
        if (ev.keyCode == 13) applyEdit();
        if (ev.keyCode == 27) resetEdit();
    }

    activeField.subscribe((val) => resetEdit());
    if (simple) startEdit();
</script>

<style>
    input{
        min-width: 40px;
        min-height: 20px;
    }
    div{
        min-width: 40px;
        min-height: 20px;
    }
    .editable:hover{
        border: 1px dotted;
    }
</style>

{#if editable && editing}
<input bind:value={editValue} onkeyup={typed} {title} {type} autofocus />
{:else}
<svelte:element this={wrapper} href={href} onclick={ignore} {onmousedown} {onmouseup} {ontouchstart} {ontouchend} {oncontextmenu} class={{editable}} {title} >{value}</svelte:element>
{/if}
