/* ============================================================
   main.js - Boot, responsive sizing (50% / 80% / Full), and
   wiring everything together with graceful error handling.
   ============================================================ */
(function (ST) {
  "use strict";

  var ASPECT = 1600 / 985;     // console width / height
  var stage, consoleEl;
  var sizeMode = "80";         // "50" | "80" | "full"

  /* Fit the console to the stage at the chosen fraction. */
  function layout() {
    if (!stage || !consoleEl) return;
    var pad = 16;
    var availW = stage.clientWidth - pad;
    var availH = stage.clientHeight - pad;
    if (availW <= 0 || availH <= 0) return;

    // largest console that fits the stage, preserving aspect ratio
    var fitW = Math.min(availW, availH * ASPECT);
    var frac = sizeMode === "50" ? 0.62 : sizeMode === "full" ? 1.0 : 0.82;
    var w = Math.max(260, fitW * frac);
    // never overflow height
    if (w / ASPECT > availH) w = availH * ASPECT;

    consoleEl.style.width = w + "px";
    consoleEl.style.fontSize = (w / 100) + "px";   // 1em = 1% of console width
  }

  /* Show a "rotate to landscape" hint on phones held in portrait. */
  function updateRotateHint() {
    var el = document.getElementById("rotate-hint");
    if (!el) return;
    var small = window.matchMedia("(pointer: coarse), (max-width: 820px)").matches;
    var portrait = window.matchMedia("(orientation: portrait)").matches;
    var show = small && portrait;
    el.classList.toggle("show", show);
    el.setAttribute("aria-hidden", show ? "false" : "true");
  }

  function setSize(mode) {
    sizeMode = mode;
    document.querySelectorAll(".size-btn").forEach(function (b) {
      b.classList.toggle("is-active", b.getAttribute("data-size") === mode);
    });
    if (mode === "full") enterFullscreen(); else exitFullscreen();
    layout();
  }

  function enterFullscreen() {
    var el = document.documentElement;
    var fn = el.requestFullscreen || el.webkitRequestFullscreen || el.msRequestFullscreen;
    if (fn) { try { fn.call(el); } catch (e) { console.warn("[fs] request failed", e); } }
    stage.classList.add("is-full");
  }
  function exitFullscreen() {
    stage.classList.remove("is-full");
    if (document.fullscreenElement || document.webkitFullscreenElement) {
      var fn = document.exitFullscreen || document.webkitExitFullscreen || document.msExitFullscreen;
      if (fn) { try { fn.call(document); } catch (e) { /* ignore */ } }
    }
  }

  function bindSizeButtons() {
    document.querySelectorAll(".size-btn").forEach(function (b) {
      b.addEventListener("click", function () {
        ST.Sound.ui();
        setSize(b.getAttribute("data-size"));
      });
    });
    // keep in sync if user exits fullscreen via Esc/browser UI
    document.addEventListener("fullscreenchange", function () {
      if (!document.fullscreenElement && sizeMode === "full") { setSize("80"); }
    });
  }

  function boot() {
    try {
      stage = document.getElementById("stage");
      consoleEl = document.getElementById("console");
      var canvas = document.getElementById("lcd");
      if (!canvas || !canvas.getContext) {
        console.error("[main] Canvas not supported.");
        showFatal("Sorry, this browser can't run the game (no canvas support).");
        return;
      }

      // High-DPI crispness for the LCD
      var dpr = Math.min(window.devicePixelRatio || 1, 2);
      canvas.width = 600 * dpr; canvas.height = 400 * dpr;
      var ctx = canvas.getContext("2d");
      ctx.scale(dpr, dpr);
      // patch getContext so game.js uses the scaled context transparently
      canvas.getContext = function () { return ctx; };

      ST.Menu.init();
      ST.Input.init();

      bindSizeButtons();
      // Phones/touch devices default to the 100% view (80% is hidden there)
      var isMobile = window.matchMedia && window.matchMedia("(max-width: 820px), (pointer: coarse)").matches;
      if (isMobile) {
        sizeMode = "full";
        document.querySelectorAll(".size-btn").forEach(function (b) {
          b.classList.toggle("is-active", b.getAttribute("data-size") === "full");
        });
      }
      layout();
      updateRotateHint();
      window.addEventListener("resize", function () { layout(); updateRotateHint(); });
      window.addEventListener("orientationchange", function () { setTimeout(function () { layout(); updateRotateHint(); }, 200); });

      // Unlock audio on first interaction anywhere
      var unlock = function () { ST.Sound.unlock(); window.removeEventListener("pointerdown", unlock); window.removeEventListener("keydown", unlock); };
      window.addEventListener("pointerdown", unlock);
      window.addEventListener("keydown", unlock);

      // Preload the PNG graphics, then start the game. Loading is
      // fault-tolerant, so this callback always fires (even on errors).
      var startGame = function () {
        ST.Game.init(canvas);

        // Optional deep-link: ?game=a | ?game=b  (also #a / #b) to start immediately
        var q = ((location.search.match(/[?&]game=([ab])/i) || [])[1] ||
                 (location.hash.match(/^#(a|b)$/i) || [])[1] || "").toUpperCase();
        if (q === "A" || q === "B") { try { ST.Game.start(q); } catch (e) { console.warn("[main] autostart failed", e); } }

        console.log("[main] Snoopy Tennis ready. Press GAME A or GAME B to play.");
      };
      if (ST.Assets && ST.Assets.load) { ST.Assets.load(startGame); } else { startGame(); }
    } catch (e) {
      console.error("[main] Boot failed:", e);
      showFatal("Something went wrong starting the game. Please refresh the page.");
    }
  }

  function showFatal(msg) {
    var d = document.createElement("div");
    d.style.cssText = "position:fixed;inset:0;display:flex;align-items:center;justify-content:center;" +
      "background:#1b1a20;color:#eee;font:16px Arial;text-align:center;padding:30px;z-index:99";
    d.textContent = msg;
    document.body.appendChild(d);
  }

  if (document.readyState === "loading") {
    document.addEventListener("DOMContentLoaded", boot);
  } else {
    boot();
  }
})(window.ST = window.ST || {});
