text: import { Universe, Cell } from "wasm-game-of-life";
  import { memory } from "wasm-game-of-life/mg_game_of_life_bg";
  
  const CELL_SIZE = 5; // px
  const GRID_COLOR = "#CCCCCC";
  const DEAD_COLOR = "#FFFFFF";
  const ALIVE_COLOR = "#000000";
  
  const canvas = document.getElementById("game-of-life-canvas");
  const playPauseButton = document.getElementById("play-pause");
  const setDeadButton = document.getElementById("set-dead");
  const randomiseButton = document.getElementById("randomise");
  const tickRangeSlider = document.getElementById("tick-range");
  
  const universe = Universe.new();
  const width = universe.width();
  const height = universe.height();
  
  universe.parse_text_input();
  
  canvas.height = (CELL_SIZE + 1) * height + 1;
  canvas.width = (CELL_SIZE + 1) * width + 1;
  
  const ctx = canvas.getContext('2d');
  
  let animationId = null;
  let rangeValue = 1;
  let added = false;
  const renderLoop = () => {
      drawGrid();
      drawCells();
      
      for (let i = 0; i <= rangeValue; i++) {
          universe.tick();
      }
  
      if (!added) {
          universe.add_spaceship(10, 10);
          added = true;
      }
  
      animationId = requestAnimationFrame(renderLoop);
  };
  
  const isPaused = () => {
      return animationId === null;
  };
  
  
  const play = () => {
    playPauseButton.textContent = "⏸";
    renderLoop();
  };
  
  const pause = () => {
    playPauseButton.textContent = "▶";
    cancelAnimationFrame(animationId);
    animationId = null;
  };
  
  playPauseButton.addEventListener("click", event => {
    if (isPaused()) {
      play();
    } else {
      pause();
    }
  });
  
  setDeadButton.addEventListener('click', () => {
    universe.all_dead();
    drawCells();
  });
  
  setDeadButton.textContent = "💀";
  
  randomiseButton.addEventListener('click', () => {
    universe.randomise();
    drawCells();
  });
  
  randomiseButton.textContent = "🎲";
  
  
  const getIndex = (row, column) => {
      return row * width + column;
    };
  
  const drawGrid = () => {
      ctx.beginPath();
      ctx.strokeStyle = GRID_COLOR;
  
      // Vertical lines.
      for (let i = 0; i <= width; i++) {
          ctx.moveTo(i * (CELL_SIZE + 1) + 1, 0);
          ctx.lineTo(i * (CELL_SIZE + 1) + 1, (CELL_SIZE + 1) * height + 1);
      }
  
      // Horizontal lines.
      for (let j = 0; j <= height; j++) {
          ctx.moveTo(0,                           j * (CELL_SIZE + 1) + 1);
          ctx.lineTo((CELL_SIZE + 1) * width + 1, j * (CELL_SIZE + 1) + 1);
      }
  
      ctx.stroke();
  };
  
  const drawCells = () => {
      const cellsPtr = universe.cells();
      const cells = new Uint8Array(memory.buffer, cellsPtr, width * height);
  
      ctx.beginPath();
  
      for (let row = 0; row < height; row++) {
          for (let col = 0; col < width; col++) {
          const idx = getIndex(row, col);
  
          ctx.fillStyle = cells[idx] === Cell.Dead
              ? DEAD_COLOR
              : ALIVE_COLOR;
  
          ctx.fillRect(
              col * (CELL_SIZE + 1) + 1,
              row * (CELL_SIZE + 1) + 1,
              CELL_SIZE,
              CELL_SIZE
          );
          }
      }
  
      ctx.stroke();
  };
  
  tickRangeSlider.addEventListener('change', (event) => {
      rangeValue = event.target.value;
  })
  
  canvas.addEventListener("click", event => {
      const boundingRect = canvas.getBoundingClientRect();
    
      const scaleX = canvas.width / boundingRect.width;
      const scaleY = canvas.height / boundingRect.height;
    
      const canvasLeft = (event.clientX - boundingRect.left) * scaleX;
      const canvasTop = (event.clientY - boundingRect.top) * scaleY;
    
      const row = Math.min(Math.floor(canvasTop / (CELL_SIZE + 1)), height - 1);
      const col = Math.min(Math.floor(canvasLeft / (CELL_SIZE + 1)), width - 1);
  
      if(event.shiftKey) {
        universe.add_spaceship(row, col);
      } else {
        universe.toggle_cell(row, col);
      }
    
    
      drawGrid();
      drawCells();
    });
  
  drawGrid();
  drawCells();
  
  play();
  
  // renderLoop()