import Blockly, { WorkspaceSvg, Xml } from 'blockly';
const bct = require('@blockly/continuous-toolbox');
import 'blockly/javascript';
import './blockly-vex';

// Blockの読み込み
import './blocks/c-block';
import { Cpp } from './generators/cpp';

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

// continuous-toolboxの為のパッチ当て --------
class CppContinuousToolbox extends bct.ContinuousToolbox {
  constructor(w: WorkspaceSvg) {
    Cpp.createVariableCategory(w);
    super(w);
  }
};
// -------------------------------------------

export class BlocklyApp {
  readonly workspace: WorkspaceSvg;

  constructor(parent: string | Element, toolbox: string) {
    this.workspace = Blockly.inject(parent, {
      plugins: {
        toolbox: CppContinuousToolbox,
        flyoutsVerticalToolbox: bct.ContinuousFlyout,
        metricsManager: bct.ContinuousMetrics,
      },
      toolbox: Xml.textToDom(toolbox),
      media: 'blockly-media/',
      renderer: 'zelos',
      theme: Blockly.Theme.defineTheme('ClassicHats', {
        base: Blockly.Themes.Classic,
        startHats: true,
      }),
    });
    Cpp.createVariableCategory(this.workspace);
    window.addEventListener('resize', () => Blockly.svgResize(this.workspace));
    this.workspace.addChangeListener(Blockly.Events.disableOrphans);
    this.setWorkspaceText(require('./default-workspace.xml?raw'));
  }

  /**
   * Blocklyのワークスペースを文字列に変換します。
   * setWorkspaceTextを使うことで復元できます
   */
  getWorkspaceText(): string {
    return Xml.domToText(Xml.workspaceToDom(this.workspace));
  }

  /**
   * Blocklyのワークスペースを設定します
   */
  setWorkspaceText(xmlText: string) {
    this.workspace.clear();
    Xml.domToWorkspace(Xml.textToDom(xmlText), this.workspace);
  }

  getCode(): string {
    return Cpp.workspaceToCode(this.workspace);
  }

  setVisible(visible: boolean) {
    this.workspace.setVisible(visible);
  }
}
