// The Witness eye for the Witness page.
//
// A calm centered eye. The pupil tracks the cursor (constrained inside
// the iris). Random slow blinks. Subtle iris breathing. Soft eyelid
// closes when the cursor leaves the viewport.
//
// The whole point is the moment the reader realizes the eye is them.

(function () {
  const root = document.getElementById("witness");
  if (!root) return;
  const svg   = root.querySelector("svg");
  const pupil = root.querySelector(".wt-pupil");
  const iris  = root.querySelector(".wt-iris");
  const hl    = root.querySelector(".wt-highlight");
  const lidT  = root.querySelector(".wt-lid-top");
  const lidB  = root.querySelector(".wt-lid-bottom");
  if (!svg || !pupil) return;

  // The eye is drawn around (200, 100) inside a 400x200 viewBox.
  const CX = 200, CY = 100;
  const MAX_PUPIL_OFFSET = 26; // pixels in SVG units

  function moveTo(x, y) {
    const rect = svg.getBoundingClientRect();
    if (rect.width === 0) return;
    const sx = ((x - rect.left) / rect.width)  * 400;   // svg X
    const sy = ((y - rect.top)  / rect.height) * 200;   // svg Y
    let dx = sx - CX;
    let dy = sy - CY;
    const dist = Math.hypot(dx, dy);
    if (dist > MAX_PUPIL_OFFSET) {
      const k = MAX_PUPIL_OFFSET / dist;
      dx *= k;
      dy *= k;
    }
    pupil.setAttribute("cx", (CX + dx).toFixed(2));
    pupil.setAttribute("cy", (CY + dy).toFixed(2));
    // Catchlight stays slightly offset from the pupil.
    hl.setAttribute("cx", (CX + dx - 7).toFixed(2));
    hl.setAttribute("cy", (CY + dy - 6).toFixed(2));
    iris.setAttribute("cx", (CX + dx * 0.25).toFixed(2));
    iris.setAttribute("cy", (CY + dy * 0.25).toFixed(2));
  }

  // Center on load.
  moveTo(window.innerWidth / 2, window.innerHeight / 2);

  window.addEventListener("mousemove", (e) => moveTo(e.clientX, e.clientY));
  window.addEventListener("touchmove",  (e) => {
    if (e.touches[0]) moveTo(e.touches[0].clientX, e.touches[0].clientY);
  }, { passive: true });

  // Random blinks. Two lids meet in the middle (each animated via class).
  let blinkTimer = null;
  function scheduleBlink() {
    const wait = 4000 + Math.random() * 5500;
    blinkTimer = setTimeout(() => {
      svg.classList.add("blinking");
      setTimeout(() => svg.classList.remove("blinking"), 220);
      scheduleBlink();
    }, wait);
  }
  function startBlinks() { if (!blinkTimer) scheduleBlink(); }
  function stopBlinks()  { if (blinkTimer) { clearTimeout(blinkTimer); blinkTimer = null; } }

  // Pause when not on the Witness view.
  const view = document.querySelector('.view[data-view="witness"]');
  function isActive() { return view && view.classList.contains("active"); }
  if (view && "MutationObserver" in window) {
    new MutationObserver(() => { if (isActive()) startBlinks(); else stopBlinks(); })
      .observe(view, { attributes: true, attributeFilter: ["class"] });
    if (isActive()) startBlinks();
  } else {
    startBlinks();
  }
  document.addEventListener("visibilitychange", () => {
    if (document.hidden) stopBlinks();
    else if (isActive()) startBlinks();
  });
})();
