/* ============================================================
   renderer.js - Draws the LCD: static coloured background art
   (tree, dog house, grass, Lucy's platform, nest) plus the live
   character sprites, score, clock and miss markers.
   ============================================================ */
(function (ST) {
  "use strict";

  var S = ST.Sprites;

  /* ---- LCD geometry (600 x 400 canvas space) ----
     Snoopy's three positions come from ST.SnoopyLevels so they can be
     tuned in config.js; everything else stays fixed here. */
  var SL = ST.SnoopyLevels;
  var Geo = {
    W: 600, H: 400,
    FACE_DY: SL.faceDY,
    charlie: { x: 116, y: 352 },
    charlieRacketY: 322,
    lucy: { x: 72, y: 187 },
    lucyHitPoint: { x: 92, y: 150 },   // where Lucy smashes
    score: { x: 40, y: 26, w: 24, h: 34 },
    clock: { x: 40, y: 26, w: 24, h: 34 },
    miss: { x: 300, y: 30 }
  };
  // per-level helpers (level 0=top, 1=mid, 2=bottom)
  Geo.levelX = function (l) { return SL.levels[l].x; };
  Geo.feetY  = function (l) { return SL.levels[l].feetY; };
  Geo.faceY  = function (l) { return SL.levels[l].feetY - SL.faceDY; };
  Geo.hitX   = function (l) { return SL.levels[l].x + SL.hitDX; };

  var COL = {
    tree:   "#b0472e",
    treeHi: "#e0952f",
    leaf:   "#5c9440",
    house:  "#b23528",
    houseDk:"#7f2318",
    grass:  "#4f8b3a",
    platform:"#b23528",
    nest:   "#4a3a28"
  };

  /* ---------- static artwork ----------
     Prefer PNG background pieces; fall back to the procedural
     vector artwork if the images aren't available. */
  function drawBackground(ctx) {
    if (ST.Assets && ST.Assets.isReady() && drawBackgroundImages(ctx)) return;
    drawBackgroundVector(ctx);
  }

  // draws each background PNG at its configured position; returns
  // true if at least one piece was drawn.
  function drawBackgroundImages(ctx) {
    var order = ST.BgOrder || [];
    var any = false;
    for (var i = 0; i < order.length; i++) {
      var key = order[i];
      var img = ST.Assets.get(key);
      if (!img) continue;
      var c = ST.cfg ? ST.cfg(key) : { scale: 1, dx: 0, dy: 0, x: 0, y: 0 };
      var s = c.scale || 1;
      ctx.drawImage(img, (c.x || 0) + (c.dx || 0), (c.y || 0) + (c.dy || 0),
                    img.naturalWidth * s, img.naturalHeight * s);
      any = true;
    }
    return any;
  }

  /* ---------- procedural (vector) artwork fallback ---------- */
  function drawBackgroundVector(ctx) {
    // Lucy's raised platform (red springboard, top-left)
    ctx.fillStyle = COL.platform;
    ctx.beginPath();
    ctx.moveTo(24, 196); ctx.lineTo(120, 196); ctx.lineTo(120, 186);
    ctx.lineTo(40, 186); ctx.lineTo(24, 168); ctx.closePath();
    ctx.fill();
    ctx.fillRect(28, 196, 8, 26);      // support post

    // Tree (right side) - trunk + branches with yellow accents
    ctx.strokeStyle = COL.tree;
    ctx.lineWidth = 16; ctx.lineCap = "round"; ctx.lineJoin = "round";
    ctx.beginPath();
    ctx.moveTo(540, 350);              // base near dog house
    ctx.lineTo(534, 250);
    ctx.lineTo(522, 150);
    ctx.stroke();
    ctx.lineWidth = 11;
    ctx.beginPath();                   // upper branches
    ctx.moveTo(522, 150); ctx.lineTo(548, 110);
    ctx.moveTo(522, 175); ctx.lineTo(470, 140);
    ctx.moveTo(534, 250); ctx.lineTo(470, 235);   // Snoopy's mid branch
    ctx.moveTo(536, 300); ctx.lineTo(486, 300);
    ctx.stroke();
    // yellow "bark" accents
    ctx.strokeStyle = COL.treeHi; ctx.lineWidth = 4;
    ctx.beginPath();
    ctx.moveTo(500, 300); ctx.lineTo(512, 285); ctx.lineTo(504, 272);
    ctx.moveTo(495, 235); ctx.lineTo(508, 222); ctx.lineTo(500, 210);
    ctx.stroke();
    // green leaf clusters
    ctx.fillStyle = COL.leaf;
    [[556,104,10],[540,92,9],[560,120,8],[476,132,9],[462,142,8],[500,150,7]].forEach(function (c) {
      ctx.beginPath(); ctx.arc(c[0], c[1], c[2], 0, Math.PI * 2); ctx.fill();
    });

    // Woodstock's nest
    ctx.fillStyle = COL.nest;
    ctx.beginPath(); ctx.ellipse(548, 98, 16, 7, 0, 0, Math.PI * 2); ctx.fill();

    // Dog house (bottom-right, red)
    ctx.fillStyle = COL.house;
    ctx.fillRect(508, 322, 74, 34);            // body
    ctx.beginPath();                            // roof
    ctx.moveTo(500, 322); ctx.lineTo(545, 296); ctx.lineTo(590, 322); ctx.closePath();
    ctx.fill();
    ctx.fillStyle = COL.houseDk;
    ctx.beginPath(); ctx.ellipse(545, 348, 13, 12, 0, Math.PI, 0, true); ctx.fill(); // door

    // Grass tufts along the bottom (little upward blades)
    ctx.strokeStyle = COL.grass; ctx.lineWidth = 3; ctx.lineCap = "round";
    for (var gx = 70; gx < 500; gx += 70) {
      ctx.beginPath();
      ctx.moveTo(gx - 7, 386); ctx.quadraticCurveTo(gx - 9, 376, gx - 8, 370);
      ctx.moveTo(gx - 2, 387); ctx.quadraticCurveTo(gx - 3, 375, gx - 2, 368);
      ctx.moveTo(gx + 3, 387); ctx.quadraticCurveTo(gx + 3, 375, gx + 4, 370);
      ctx.moveTo(gx + 8, 386); ctx.quadraticCurveTo(gx + 10, 377, gx + 9, 372);
      ctx.stroke();
    }
  }

  /* ---------- HUD: score / clock / misses ---------- */
  function drawHud(ctx, state) {
    if (state.mode === "clock") {
      // AM/PM clock - digits 25% smaller, HH:MM spaced normally
      var w = 16, h = 24, gap = 5;          // was 22 x 32
      ctx.fillStyle = S.SEG;
      ctx.font = "bold 14px Arial"; ctx.textBaseline = "top";
      ctx.fillText("AM", 18, 30);
      var hh = String(state.clock.h).padStart(2, " ");
      var mm = String(state.clock.m).padStart(2, "0");
      var x0 = 46;
      S.number(ctx, hh, x0, 26, w, h, gap);
      var colonX = x0 + hh.length * (w + gap) - gap + 5;   // just after HH
      // colon
      ctx.fillStyle = S.SEG;
      ctx.beginPath(); ctx.arc(colonX, 33, 2.4, 0, 6.3); ctx.arc(colonX, 47, 2.4, 0, 6.3); ctx.fill();
      S.number(ctx, mm, colonX + 9, 26, w, h, gap);
    } else {
      var str = String(state.score);
      S.number(ctx, str, Geo.score.x, Geo.score.y, Geo.score.w, Geo.score.h);
    }
    // MISS label + markers
    ctx.fillStyle = S.SEG;
    ctx.font = "bold 15px Arial"; ctx.textBaseline = "alphabetic";
    ctx.fillText("MISS", Geo.miss.x, Geo.miss.y);
    for (var i = 0; i < 3; i++) {
      S.missMark(ctx, Geo.miss.x + 42 + i * 26, Geo.miss.y, i >= state.misses);
    }
  }

  /* ---------- full scene ---------- */
  function drawScene(ctx, state) {
    ctx.clearRect(0, 0, Geo.W, Geo.H);
    drawBackground(ctx);

    // Woodstock (jumps when alarm—here just sits)
    S.woodstock(ctx, 542, 96, false);

    drawHud(ctx, state);

    if (state.mode === "clock") return;   // no players in clock mode

    // Lucy (only visible when active)
    if (state.lucy.visible) {
      S.lucy(ctx, Geo.lucy.x, Geo.lucy.y, state.lucy.frame, false);
    }

    // Charlie Brown
    S.charlie(ctx, Geo.charlie.x, Geo.charlie.y, state.charlie.frame, false);

    // "POW!" burst above Charlie when he serves
    if (state.charlie.pow > 0) {
      var pw = (ST.Gameplay && ST.Gameplay.pow) || { x: 116, y: 250 };
      ctx.save();
      ctx.fillStyle = S.SEG;
      ctx.font = "900 26px Arial Black, Arial";
      ctx.textAlign = "center";
      ctx.fillText("POW!", pw.x, pw.y);
      ctx.restore();
    }

    // Snoopy - asleep on the doghouse after a miss, else at his level
    if (state.snoopy.sleeping) {
      var sc = ST.cfg("snoopy_sleep");
      S.image(ctx, "snoopy_sleep", "snoopy_sleep", sc.x || 0, sc.y || 0, "topleft");
    } else {
      S.snoopy(ctx, Geo.levelX(state.snoopy.level), Geo.feetY(state.snoopy.level),
               state.snoopy.swing > 0 ? 1 : 0, false);
    }

    // Balls in flight
    for (var i = 0; i < state.balls.length; i++) {
      var b = state.balls[i];
      S.ball(ctx, b.x, b.y, 6, false);
    }

    // Game A / Game B indicator (small, light)
    drawGameLabel(ctx, state);

    // Bonus / chance-time banner
    if (state.bonus) {
      ctx.fillStyle = S.SEG; ctx.font = "bold 22px Arial"; ctx.textAlign = "center";
      ctx.fillText("CHANCE", Geo.W / 2, 210);
      ctx.textAlign = "left";
    }
  }

  // small light label showing which game is being played
  function drawGameLabel(ctx, state) {
    var GP = ST.Gameplay || {};
    var pos = state.type === "B" ? GP.gameLabelB : GP.gameLabelA;
    if (!pos) return;
    ctx.save();
    ctx.fillStyle = "#2b2b2688";           // light / faded ink
    ctx.font = "600 11px Arial";
    ctx.textAlign = "center";
    ctx.fillText(state.type === "B" ? "GAME B" : "GAME A", pos.x, pos.y);
    ctx.restore();
  }

  ST.Geo = Geo;
  ST.Renderer = { drawScene: drawScene, drawBackground: drawBackground };
})(window.ST = window.ST || {});
