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

    let {
        editable = true,
        onclick  = evt => {},
        onSet    = newVal => {return true;},
        simple   = false,
        type     = 'div',
        value    = $bindable({source:null,rendered:null})
    } = $props();

    let editing   = $state(false);
    let editValue = $state({source:value.source,rendered:value.rendered});
    let start     = 0;
    let timer     = null;

    async function applyEdit(){
        let success = await onSet(editValue.source);
        if (success) {
            value.source   = editValue.source;
            value.rendered = editValue.rendered;
            editing        = false;
        } else resetEdit();
    }

    function doSave(){
        if (simple){
            onSet(editValue.source);
        } else applyEdit();
    }

    function resetEdit(){
        editing   = false;
        editValue = {source:value.source,rendered:value.rendered};
    }

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

    async function render(){
        const url  = api('markdown/render');
        const resp = await fetch(url,{
            credentials: 'include',
            method     : 'POST',
            body       : editValue.source
        });
        editValue.rendered = await resp.text();
    }

    function typed(ev){
        if (simple) {
            value.source   = editValue.source;
            value.rendered = editValue.rendered;
        }
        if (ev.keyCode == 13 && ev.ctrlKey) doSave();
        if (ev.keyCode == 27) resetEdit();

        if (timer) clearTimeout(timer);
        timer = setTimeout(render,500);
    }

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


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

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

    function onmouseup(evt){
        evt.preventDefault();
        measured(evt, evt.timeStamp - start);
    }

    function ontouchstart(evt){
        evt.preventDefault();
        start = evt.timeStamp;
    }

    function ontouchend(evt){
        evt.preventDefault();
        measured(evt, evt.timeStamp - start);
    }

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

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

<div class="markdown {editing?'editing':''}">
{#if editing}
    <div class="boundary">
        <textarea bind:value={editValue.source} onkeyup={typed} autofocus={!simple}></textarea>
        <span class="buttons">
            <button class="cancel" onclick={e => editing = false}>{t('cancel')}</button>
            <span>{t('markdown_supported')}</span>
            <button class="save" onclick={doSave}>{t('save')}</button>
        </span>
    </div>
{/if}
    <svelte:element this={type} {onclick} {oncontextmenu} class={{editable}} title={t('right_click_to_edit')} >{@html target(editValue.rendered)}</svelte:element>
</div>