import { RendererApi } from '../common/rendererApi';
import * as impl from './impl';
import Blockly, { Xml } from 'blockly';
const bct = require('@blockly/continuous-toolbox');
import './blockly-vex';

// DOMの取得
function throwError(msg: string): never {
  throw new Error(msg);
}
const consoleDom = document.getElementById('console') ?? throwError('console Not Found');
function escapeHTML(text: string): string {
  const map: { [key: string]: string } = {
    '<': '&lt;',
    '>': '&gt;',
    '&': '&amp;',
  };
  return text.replace(/[<>&]/g, x => map[x]);
}
// APIの実装
export const api: RendererApi = {
  cmd(c: string, args?: string[]): void {
    let text = c;
    if (args) {
      for (const a of args) {
        text += ' ' + a;
      }
    }
    consoleDom.innerHTML += `<p class='command'>${escapeHTML(text)}</p>`;
  },

  writeLine(text: string): void {
    consoleDom.innerHTML += `<p class='stdout'>${escapeHTML(text)}</p>`;
  },
  writeLineErr(text: string): void {
    consoleDom.innerHTML += `<p class='stderr'>${escapeHTML(text)}</p>`;
  },
  err(text: string): void {
    consoleDom.innerHTML += `<p class='error'>${escapeHTML(text)}</p>`;
  },
  log(text: string): void {
    consoleDom.innerHTML += `<p class='log'>${escapeHTML(text)}</p>`;
  }
};
app.register(api);



Blockly.HSV_SATURATION = 0.8;
Blockly.HSV_VALUE = 0.85;

const workspace = Blockly.inject('blockly-area', {
  plugins: {
    toolbox: bct.ContinuousToolbox,
    flyoutsVerticalToolbox: bct.ContinuousFlyout,
    metricsManager: bct.ContinuousMetrics,
  },
  toolbox: Xml.textToDom(require('./toolbox.xml?raw')),
  media: 'blockly-media/',
  renderer: 'zelos',
  theme: Blockly.Theme.defineTheme('ClassicHats', {
    base: Blockly.Themes.Classic,
    startHats: true,
  }),
});
window.addEventListener('resize', () => Blockly.svgResize(workspace));

function getWorkspaceText(): string {
  return Xml.domToText(Xml.workspaceToDom(workspace));
}

function setWorkspaceText(xmlText: string) {
  workspace.clear();
  Xml.domToWorkspace(Xml.textToDom(xmlText), workspace);
}


// イベントハンドラ
const runDom = <HTMLInputElement>document.getElementById('run') ?? throwError('Run Button Not Found');
runDom.addEventListener('click', async () => {
  if (runDom.disabled) return;
  runDom.disabled = true;
  try {
    await impl.runAction(api, app.main, app.os);
  } finally {
    runDom.disabled = false;
  }
});

let defaultFilePath = 'Hello.xml';
document.getElementById('save')?.addEventListener('click', async () => {
  const savePath = await app.main.showSaveFileDialog({
    defaultPath: defaultFilePath,
    filters: [{ name: 'XML', extensions: ['xml'] }],
  });
  if (!savePath) return;
  defaultFilePath = savePath;
  const text = getWorkspaceText();
  await app.main.saveTextFile(savePath, text);
});

document.getElementById('load')?.addEventListener('click', async () => {
  const loadPath = await app.main.showOpenFileDialog({
    defaultPath: defaultFilePath,
    filters: [{ name: 'XML', extensions: ['xml'] }],
  });
  if (!loadPath) return;
  const data = await app.main.readTextFile(loadPath);
  if (data === null) return;
  defaultFilePath = loadPath;
  setWorkspaceText(data);
});
