<!doctype html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <title>Reveal.yaml Editor</title>
    <link rel="icon" href="{{ url_for('static', filename="img/icon.png") }}">
    <style>
        #copyright {
            text-align: right;
            font-family: "League Gothic", Impact, sans-serif;
        }

        #editor, #preview-layout {
            position: absolute;
            top: 0;
            right: 0;
            bottom: 0;
            left: 0;
            width: 50%;
            margin: 4px;
        }

        .layout {
            width: 100%;
            display: flex;
        }

        #preview-layout {
            left: 51%;
            width: 48%;
            flex-direction: column;
        }

        button, #preview {
            width: 100%;
            height: 100%;
        }

        button {
            height: 40px;
            margin: 4px;
        }
    </style>
</head>
<body>
<div>
    <pre id="editor">{{ saved }}</pre>
    <div class="layout" id="preview-layout">
        <div class="layout">
            <button id="compiler">Compile</button>
            <button id="uploader">Upload YAML</button>
            <button id="downloader">Download YAML</button>
            <button id="packer">Pack</button>
            <button id="cleaner">Clean saved</button>
            <button id="helper">Documentation</button>
        </div>
        <iframe id="preview" allowfullscreen></iframe>
        <p id="copyright">
            <a href="https://pypi.org/project/reveal-yaml/">
                <img src="https://img.shields.io/pypi/v/reveal-yaml.svg" alt="PyPI"></a>
            Reveal.yaml v{{ version }} by <a href="mailto:{{ email }}">{{ author }}</a> {{ copyright }}
        </p>
    </div>
</div>
<script src="{{ url_for('static', filename="js/jquery.min.js") }}"></script>
<script src="{{ url_for('static', filename="ace/ace.min.js") }}"></script>
<script src="{{ url_for('static', filename="ace/ext-searchbox.min.js") }}"></script>
<script src="{{ url_for('static', filename="ace/ext-whitespace.min.js") }}"></script>
<script src="{{ url_for('static', filename="ace/ext-language_tools.min.js") }}"></script>
<script src="{{ url_for('static', filename="ace/mode-yaml.min.js") }}"></script>
<script src="{{ url_for('static', filename="ace/theme-chrome.min.js") }}"></script>
<script src="{{ url_for('static', filename="ace/theme-monokai.min.js") }}"></script>
<script src="{{ url_for('static', filename="ace/js-yaml.min.js") }}"></script>
<script>
    $(document).ready(() => {
        ace.require("ace/ext/language_tools");
        const editor = ace.edit("editor");
        if (localStorage.getItem('saved'))
            editor.setValue(localStorage.getItem('saved'));
        editor.moveCursorTo(0, 0);
        editor.setTheme("ace/theme/chrome");
        editor.session.setMode("ace/mode/yaml");
        editor.setOptions({
            fontSize: "14pt",
            tabSize: 2,
            useSoftTabs: true,
            enableBasicAutocompletion: true,
            enableLiveAutocompletion: true,
            enableSnippets: true,
        });
        editor.commands.addCommands(ace.require("ace/ext/whitespace").commands);
        editor.commands.addCommand({
            name: "duplicateSelection",
            description: "Duplicate selection",
            bindKey: {win: "Ctrl-D", mac: "Command-D"},
            exec: editor => {
                editor.duplicateSelection();
                editor.navigateDown();
            },
            scrollIntoView: "cursor",
            multiSelectAction: "forEach"
        });
        editor.commands.addCommand({
            name: "removeline",
            description: "Remove line",
            bindKey: {win: "Ctrl-Shift-D", mac: "Command-Shift-D"},
            exec: editor => {
                editor.removeLines();
            },
            scrollIntoView: "cursor",
            multiSelectAction: "forEachLine"
        });
        editor.commands.addCommand({
            name: "backspace",
            description: "Backspace",
            bindKey: {
                win: "Shift-Backspace|Backspace",
                mac: "Ctrl-Backspace|Shift-Backspace|Backspace|Ctrl-H"
            },
            exec: editor => {
                const pos = editor.getCursorPosition();
                if (/^\s+$/.test(editor.session.getTextRange(new ace.Range(pos.row, 0, pos.row, pos.column))))
                    editor.removeToLineStart();
                editor.remove("left");
            },
            multiSelectAction: "forEach",
            scrollIntoView: "cursor"
        });
        const previewer = $('#preview');
        previewer.preview = id => {
            previewer.attr('src', window.location.href + 'preview/' + id);
        };
        const compiler = $('#compiler');
        compiler.mousedown(async () => {
            const pos = editor.getCursorPosition();
            editor.execCommand("trimTrailingSpace", {trimEmpty: true});
            editor.session.setValue(
                editor.getValue().replace(/\r?\n?$/, "")
                + editor.session.doc.getNewLineCharacter()
            );
            editor.moveCursorTo(pos.row, pos.column);
            compiler.id = Date.now().toString(10);
            const doc = editor.getValue();
            const data = jsyaml.safeLoad(doc);
            if (data === undefined) {
                alert("Blank content!");
                return;
            }
            $.ajax({
                method: "POST",
                url: '/preview/' + compiler.id,
                dataType: 'json',
                contentType: 'application/json',
                data: JSON.stringify(jsyaml.safeLoad(doc)),
                success: data => {
                    localStorage.setItem('saved', doc);
                    compiler.id = data['id'];
                    previewer.preview(compiler.id);
                },
                error: data => {
                    alert("Server error! Please wait for next response. (" + data['id'] + ")");
                }
            });
        });
        $('#uploader').mousedown(async () => {
            editor.setValue(await (async () => new Promise(resolve => {
                // create file input
                const uploader = document.createElement('input');
                uploader.type = 'file';
                uploader.style.display = 'none';
                // listen for files
                uploader.addEventListener('change', () => {
                    const files = uploader.files;
                    if (!files.length)
                        return;
                    const reader = new FileReader();
                    reader.addEventListener('load', () => {
                        uploader.parentNode.removeChild(uploader);
                        resolve(reader.result);
                    });
                    reader.readAsText(files[0]);
                });
                // trigger input
                document.body.appendChild(uploader);
                uploader.click();
                uploader.remove();
            }))());
        });
        $('#downloader').mousedown(() => {
            const link = document.createElement('a');
            link.setAttribute('href', "data:text/vnd.yaml;charset=utf-8," + encodeURIComponent(editor.getValue()));
            link.setAttribute('download', "reveal.yaml");
            link.click();
            link.remove();
        });
        $('#packer').mousedown(() => {
            if (compiler.id === undefined) {
                alert("Please compile first.");
                return;
            }
            window.location.replace(window.location.href + "pack/" + compiler.id);
        });
        $('#cleaner').mousedown(() => {
            localStorage.removeItem('saved');
            alert("Local storage cleaned!");
        });
        $('#helper').mousedown(() => {
            previewer.preview(0);
        }).trigger('mousedown');
    });
</script>
</body>
</html>
