// TurboWarp / PenguinMod unsandboxed extension skeleton for JESIM WebSocket.
// Load as a custom extension, then connect to ws://127.0.0.1:8765.
(function (Scratch) {
  'use strict';
  if (!Scratch.extensions.unsandboxed) throw new Error('This extension must run unsandboxed.');

  class JESIMWebSocket {
    constructor() {
      this.ws = null;
      this.connected = false;
      this.latest = '';
      this.latestKind = '';
      this.latestIssueTime = '';
    }
    getInfo() {
      return {
        id: 'jesimws',
        name: 'JESIM WS',
        blocks: [
          { opcode: 'connect', blockType: Scratch.BlockType.COMMAND, text: 'connect JESIM websocket [URL]', arguments: { URL: { type: Scratch.ArgumentType.STRING, defaultValue: 'ws://127.0.0.1:8765' } } },
          { opcode: 'isConnected', blockType: Scratch.BlockType.BOOLEAN, text: 'JESIM connected?' },
          { opcode: 'latestJson', blockType: Scratch.BlockType.REPORTER, text: 'latest JESIM json' },
          { opcode: 'latestKind', blockType: Scratch.BlockType.REPORTER, text: 'latest JESIM kind' },
          { opcode: 'latestIssueTime', blockType: Scratch.BlockType.REPORTER, text: 'latest JESIM issue time' }
        ]
      };
    }
    connect(args) {
      const url = args.URL || 'ws://127.0.0.1:8765';
      if (this.ws) this.ws.close();
      this.ws = new WebSocket(url);
      this.ws.onopen = () => { this.connected = true; };
      this.ws.onclose = () => { this.connected = false; };
      this.ws.onerror = () => { this.connected = false; };
      this.ws.onmessage = (ev) => {
        this.latest = String(ev.data || '');
        try {
          const obj = JSON.parse(this.latest);
          this.latestKind = obj.kind || '';
          this.latestIssueTime = obj.issue_time || '';
        } catch (e) {}
      };
    }
    isConnected() { return this.connected; }
    latestJson() { return this.latest; }
    latestKind() { return this.latestKind; }
    latestIssueTime() { return this.latestIssueTime; }
  }

  Scratch.extensions.register(new JESIMWebSocket());
})(Scratch);
