import { Conductor } from "./conductor.js";

export class Renderer {
  timeIndicator;
  currStaveNumber;
  numStaves;
  sheetWindow;
  canvases = [];
  iconCache = [];
  iconScale = 0.20;

  constructor() {
    this.numStaves = 6;
    this.currStaveNumber = 1;

    this.timeIndicator = document.getElementById("time-indicator");
    this.sheetWindow = document.getElementById("music-window");

    window.addEventListener("resize", () => {
      this.redrawIcons();
    });

    this.timeIndicator.addEventListener("animationiteration", () => {
      this.currStaveNumber++;
      if (this.currStaveNumber > this.numStaves) {
        this.cleanUpAndRestart();
      }
    });

    for (let i = 1; i <= this.numStaves; i++) {
      const staveWrapper = document.createElement("div");
      staveWrapper.classList.add("stave-wrapper");
      staveWrapper.setAttribute("id", `stave-wrapper-${i}`);
      staveWrapper.style.position = "relative";
    
      const staveObject = document.createElement("object");
      staveObject.type = "image/svg+xml";
      staveObject.data = "assets/svg/stave.svg";
      staveObject.className = "stave-svg"; // Fixed className
    
      const canvas = document.createElement("canvas");
      canvas.id = `canvas-${i}`;
      canvas.className = "event-canvas";
    
      const ctx = canvas.getContext("2d");
      this.canvases.push({ canvas, ctx });
    
      staveWrapper.appendChild(staveObject);
      staveWrapper.appendChild(canvas);
      this.sheetWindow.appendChild(staveWrapper);
    
      // Your exact sizing method + minimal DPR adjustment
      requestAnimationFrame(() => {
        const dpr = window.devicePixelRatio || 1;
        
        // Keep your offset measurements
        const displayWidth = canvas.offsetWidth;
        const displayHeight = canvas.offsetHeight;
        
        // Apply to actual canvas buffer
        canvas.width = Math.round(displayWidth * dpr);
        canvas.height = Math.round(displayHeight * dpr);
        
        // Maintain your display size
        canvas.style.width = `${displayWidth }px`;
        canvas.style.height = `${displayHeight}px`;
        
        // Scale context to compensate
        ctx.scale(dpr , dpr);
      });
    }
  }

  async placeIcon(instrument) {
    if (this.currStaveNumber > this.numStaves) {
      this.currStaveNumber = 1;
      this.iconCache.length = 0;
    }

    const rect = this.timeIndicator.getBoundingClientRect();
    const sheetLeft = this.sheetWindow.getBoundingClientRect().left;
    const sheetRight = this.sheetWindow.getBoundingClientRect().right;
    const xPosition = rect.left + window.scrollX - sheetLeft;

    const canvasEntry = this.canvases[this.currStaveNumber - 1];
    const canvas = canvasEntry.canvas;
    const ctx = canvasEntry.ctx;

    const yPercent = parseFloat(instrument.yPos);
    const y = (yPercent / 100) * canvas.height;

    const width = instrument.width * this.iconScale;
    const height = instrument.height * this.iconScale;

    if(xPosition + width > sheetRight) xPosition -= width;

    ctx.drawImage(instrument.image, xPosition, y, width, height);

    this.iconCache.push({
      image: instrument.image,
      x: xPosition,
      y,
      width,
      height,
      stave: this.currStaveNumber,
    });
  }

  redrawIcons() {
    this.canvases.forEach(({ ctx, canvas }) => {
      ctx.clearRect(0, 0, canvas.width, canvas.height);
    });

    this.iconCache.forEach(({ image, x, y, width, height, stave }) => {
      const ctx = this.canvases[stave - 1].ctx;
      ctx.drawImage(image, x, y, width, height);
    });
  }

  cleanUpAndRestart(reload = false) {
    this.iconCache = [];
    this.currStaveNumber = 1;

    this.canvases.forEach(({ ctx, canvas }) => {
      ctx.clearRect(0, 0, canvas.width, canvas.height);
    });

    Conductor.setTitle();
    if (reload) location.reload();
  }
}
