<!doctype html>
<html>

<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <style>
    .cm-editor {
      height: 100%
    }

    .cm-scroller {
      overflow: auto
    }
  </style>
  <script src="https://cdn.tailwindcss.com"></script>
  <script type="importmap">
    {
      "imports": {
        "codemirror": "https://esm.sh/codemirror@v6.0.1?external=@codemirror/state,@codemirror/language,@codemirror/view",
        "@uiw/codemirror-themes-all": "https://esm.sh/@uiw/codemirror-themes-all@4.21.20",
        "@codemirror/state": "https://esm.sh/@codemirror/state@6.3.1",
        "@codemirror/language": "https://esm.sh/@codemirror/language@6.9.2",
        "@codemirror/view": "https://esm.sh/@codemirror/view@6.22.0",
        "codemirror-lang-liquidsoap": "https://esm.sh/codemirror-lang-liquidsoap@0.3.0?external=@codemirror/state,@codemirror/language,@codemirror/view",
        "prettier": "https://esm.sh/prettier@3.0.2/standalone.mjs",
        "liquidsoap-prettier": "https://esm.sh/liquidsoap-prettier@1.4.8/src/index.js"
      }
    }
  </script>
  <script type="module">
    import { basicSetup, EditorView } from "codemirror";
    import { Compartment } from "@codemirror/state";
    import * as allThemes from "@uiw/codemirror-themes-all";
    import { liquidsoap } from "codemirror-lang-liquidsoap";
    import * as prettier from "prettier";
    import prettierPluginLiquidsoap from "liquidsoap-prettier";

    const prettierPlugin = {
      ...prettierPluginLiquidsoap,
      parsers: {
        ...prettierPluginLiquidsoap.parsers,
        liquidsoap: {
          ...prettierPluginLiquidsoap.parsers.liquidsoap,
          parse: (s) => JSON.parse(s)
        }
      }
    };

    const themes = Object.keys(allThemes).reduce(
      (themes, key) => {
        if (/Init/.test(key) || /Settings/.test(key)) return themes;

        return { ...themes, [key]: allThemes[key] };
      }, {});

    const defaultTheme = "okaidia";

    const themeConfig = new Compartment;

    const select = document.getElementById("themes");

    Object.keys(themes).forEach((name) => {
      const option = document.createElement("option");
      option.text = name;
      option.value = name;
      select.appendChild(option);
    });

    select.value = defaultTheme;

    select.onchange = () => editor.dispatch({
      effects: themeConfig.reconfigure([
        liquidsoap(),
        themes[select.value]
      ])
    });

    window.formatLiqCode = (code, cb) =>
      prettier
        .format(code, {
          parser: "liquidsoap",
          plugins: [prettierPlugin],
        })
        .then(cb);

    let editor;

    window.getLiqCode = () => {
      if (!editor) return "";
      return editor.state.doc.toString();
    };

    window.setLiqCode = (code) => {
      if (!editor) return;
      editor.dispatch({
        changes: {
          from: 0,
          to: editor.state.doc.length,
          insert: code
        }
      });
    };

    window.onLiqLoaded = (version) => {
      const input = document.getElementById("input");
      const height = input.clientHeight;
      const width = input.clientWidth;
      input.innerHTML = null;
      input.style.minHeight = `${height}px`;
      input.style.maxHeight = `${height}px`;
      input.style.minWidth = `${width}px`;
      input.style.maxWidth = `${width}px`;

      editor = new EditorView({
        doc: `# ‚ú® Welcome to liquidsoap's online interpreter! ‚ú®
# ü§ñ Language version: ${version}
#  Write your code here:

`,
        extensions: [
          basicSetup,
          themeConfig.of([
            liquidsoap(),
            themes[defaultTheme]
          ])
        ],
        parent: input
      });
    };

    let showingResults = false;

    const switchDisplay = () => {
      const code = document.getElementById("code");
      const results = document.getElementById("results");

      if (showingResults) {
        code.style.display = "grid";
        results.style.display = "none";
      } else {
        code.style.display = "none";
        results.style.display = "grid";
      }

      showingResults = !showingResults;
    };

    window.addEventListener("load", () => {
      document.getElementById("switch-code").addEventListener("click", () => {
        switchDisplay();
      });

      document
        .getElementById("switch-results")
        .addEventListener("click", () => {
          switchDisplay();
        });

      document.getElementById("execute").addEventListener("click", () => {
        switchDisplay();
      });
    });
  </script>
  <script src="interactive_js.bc.js"></script>
</head>

<body class="px-4 lg:px-32 bg-zinc-900 text-slate-100">
  <header class="inset-x-0 top-0 z-50">
    <nav class="flex items-center justify-between p-6 lg:px-8" aria-label="Global">
      <div class="flex lg:flex-1">
        <a href="/" class="-m-1.5 p-1.5 font-semibold hover:text-slate-400">
          Liquidsoap playground
        </a>
      </div>
    </nav>
  </header>
  <main>
    <div class="grid grid-flow-row lg:grid-flow-col gap-1 justify-items-center">
      <div class="text-zinc-800 grid grid-flow-row lg:!grid w-full" id="code">
        <div class="grid grid-flow-row w-full lg:hidden">
          <div class="justify-self-start">
            <button class="my-2 px-4 py-2 font-semibold text-sm bg-cyan-500 text-white rounded-full shadow-sm"
              id="switch-results">
              See Results
            </button>
          </div>
        </div>
        <div id="input" class="caret-cyan-500 box-border w-full h-full">
          <textarea class="p-4 caret-cyan-500 box-border w-full text-white" style="
                background-color: #272822;
                text-shadow: 0px 0px 0px #000;
                border: none;
                outline: none;
                box-shadow: none;
                resize: none;
              " rows="20" cols="70">
# Interpreter loading.. ‚è≥
</textarea>
        </div>
        <div class="w-full grid grid-cols-2 grid-flow-col">
          <div class="justify-self-start flex my-2 px-4 py-2 font-semibold text-sm text-white">
            <span class="pr-3">Theme:</span>
            <select id="themes" class="flex text-sm text-black"></select>
          </div>
          <div class="justify-self-end">
            <button class="my-2 px-4 py-2 font-semibold text-sm bg-red-700 text-white rounded-full shadow-sm"
              id="clear">
              Clear
            </button>
            <button class="my-2 px-4 py-2 font-semibold text-sm bg-cyan-500 text-white rounded-full shadow-sm"
              id="format">
              Format
            </button>
            <button class="my-2 px-4 py-2 font-semibold text-sm bg-cyan-500 text-white rounded-full shadow-sm"
              id="execute">
              Execute
            </button>
          </div>
        </div>
      </div>
      <div class="hidden lg:!grid grid grid-flow-row w-full" id="results">
        <div class="grid grid-flow-row w-full lg:hidden">
          <div class="justify-self-start">
            <button
              class="my-2 px-4 py-2 font-semibold text-sm bg-cyan-500 text-white rounded-full shadow-sm flex lg:hidden"
              id="switch-code">
              See Code
            </button>
          </div>
        </div>
        <div>
          <textarea class="p-4 bg-slate-400 box-border w-full" style="
                text-shadow: 0px 0px 0px #000;
                border: none;
                outline: none;
                box-shadow: none;
                resize: none;
              " disabled="true" id="output" rows="20" cols="70"></textarea>
        </div>
      </div>
    </div>
  </main>
</body>

</html>
