// ═══════════════════════════════════════════════════════════════════════════
// OTTO, ALIVE
//
// Otto had no face anywhere in the deck: the question bar was an input and an
// arrow. He is the thing the deck is built around, so he now sits in that bar
// on every room, breathing, blinking and looking about.
//
// Drawn as vector rather than reusing heroes/otto.png, because a PNG cannot
// blink. Colours are sampled from that PNG so this is the same character:
// kraft #CCA878, navy #181848, card #E4D8B4. The motion vocabulary and its
// timings come from the Otto animation set: breathe 3.4s, blink 3.4s,
// dart 3.2s.
//
// Idle motion is deliberately near the threshold of noticing. It is on screen
// for the whole deck, so anything larger would become the thing you look at
// instead of the thing you glance at.
// ═══════════════════════════════════════════════════════════════════════════

function OttoAvatar({ size, busy, state }) {
  const s = size || 30;
  // `busy` is Otto actually working, so the eyes narrow and the pupils settle.
  const mood = busy ? 'think' : (state || 'idle');
  return (
    <span className="otto-av" data-mood={mood} style={{
      width: s, height: s, flexShrink: 0, display: 'block', lineHeight: 0,
    }} aria-hidden="true">
      <svg viewBox="0 0 64 64" width={s} height={s}>
        <g className="otto-body">
          {/* the box */}
          <rect x="9" y="17" width="46" height="38" rx="5"
                fill="#CCA878" stroke="#181848" strokeWidth="3" />
          {/* the flap, folded back over the top */}
          <path d="M20 17 L26 8 H44 L40 17 Z"
                fill="#E4D8B4" stroke="#181848" strokeWidth="3" strokeLinejoin="round" />
          {/* the seam across the carton */}
          <line x1="9" y1="26" x2="55" y2="26" stroke="#181848" strokeWidth="2.4" opacity="0.85" />

          <g className="otto-eyes">
            <circle cx="24" cy="37" r="7.6" fill="#F0F0F0" stroke="#181848" strokeWidth="2.6" />
            <circle cx="42" cy="37" r="7.6" fill="#F0F0F0" stroke="#181848" strokeWidth="2.6" />
            <g className="otto-pupils">
              <circle cx="24" cy="37" r="3.4" fill="#181848" />
              <circle cx="42" cy="37" r="3.4" fill="#181848" />
            </g>
          </g>

          {/* the tape strip */}
          <rect x="22" y="47" width="20" height="6" rx="1.5"
                fill="#E4D8B4" stroke="#181848" strokeWidth="2.2" />
        </g>
      </svg>
    </span>
  );
}

// The three dots that puff while an answer is being retrieved. Only ever on
// screen while Otto is genuinely working, so it reports state, not decoration.
function OttoThinking() {
  return (
    <span className="otto-think" aria-hidden="true">
      <i /><i /><i />
    </span>
  );
}

// ── Otto behind the shelf.
//    The ledge is a physical board with a shadow, so the natural place for
//    him is behind it: he rises, looks along the row, blinks, and drops back
//    out of sight. The container's bottom edge sits exactly on the top of the
//    ledge and clips him, which is what sells "behind" rather than "on top of".
//    He is up for about three seconds in every eleven, so a room is mostly
//    still and he is a thing you catch rather than a thing you watch.
function OttoPeek({ delay, size }) {
  return (
    <span className="otto-peek" style={{ '--peek-delay': (delay || 0) + 'ms' }} aria-hidden="true">
      <OttoAvatar size={size || 34} />
    </span>
  );
}

// Stable per room, so each one has him in a different place, and the deck
// does not develop a rhythm the eye starts predicting.
function ottoPeekIndex(room, n) {
  if (!room || !n) return 0;
  return room.length % n;
}

// ── Otto's steamboat, crossing the channel.
//    Used once in the whole deck, in the room called "a signed channel",
//    because a boat crossing a channel is the one place the metaphor is not
//    decoration. It rides behind the shelf ledge, which doubles as the
//    waterline, so the hull sits below the surface and only the boat above
//    it shows. Drawn in the deck's own tokens rather than the navy of the
//    source set: espresso line, tan hull, gold band, and Otto at the helm
//    in his own colours.
// ═══════════════════════════════════════════════════════════════════════════
// THE RIDES
//
// The artwork comes from the upgraded pack in otto-animations.js: dimensional
// SVG with its own idle loops, materials and shadows. What the pack does not
// carry is the thing this deck needs, which is the crossing: a vehicle that
// enters at the start of the shelf and leaves at the end of it rather than
// driving past. So the pack draws, and the wrapper below moves.
//
// The pack sizes each vehicle 250x200 at scale 1 and positions it absolutely
// against the bottom of its parent, so each ride gets a box of exactly that
// size to sit in and the box is what ottoSail translates.
// ═══════════════════════════════════════════════════════════════════════════

const RIDE_ART = {
  // The pack draws in a 250x200 frame, which is far taller relative to its
  // width than the artwork it replaces. Scaled to sit on the shelf without
  // burying the figure it passes.
  boat:   { C: () => window.OttoBoat_art,   scale: 0.40 },
  cart:   { C: () => window.OttoCoach_art,  scale: 0.40 },
  pigeon: { C: () => window.OttoPigeon_art, scale: 0.44 },
};

function OttoRide({ kind }) {
  const spec = RIDE_ART[kind];
  const Art = spec && spec.C();
  if (!Art) return null;
  const w = 250 * spec.scale, h = 200 * spec.scale;
  // A frozen render, for the PDF export and for anyone on reduced motion,
  // puts the vehicle a third of the way along the shelf rather than at the
  // start of a crossing that will never play.
  const still = window.__STATIC || (function () {
    try { return window.matchMedia('(prefers-reduced-motion: reduce)').matches; }
    catch (e) { return false; }
  })();
  return (
    <span className={'otto-ride otto-' + kind} data-still={still ? '1' : undefined} aria-hidden="true">
      <span className="otto-ride-in" style={still ? { left: '34%', animation: 'none' } : null}>
        <span className="otto-ride-box" style={{ width: w, height: h }}>
          <Art x={w / 2} scale={spec.scale} moving parcel />
        </span>
      </span>
    </span>
  );
}


// The pack's own components are kept under _art names so this file can wrap
// them without shadowing them, and the deck only ever mounts OttoRide.
window.OttoBoat_art   = window.OttoBoat;
window.OttoCoach_art  = window.OttoCoach;
window.OttoPigeon_art = window.OttoPigeon;
window.OttoTrain_art  = window.OttoTrain;
window.OttoRide = OttoRide;
window.OttoAvatar = OttoAvatar;
window.OttoThinking = OttoThinking;
window.OttoPeek = OttoPeek;
window.__ottoPeekIndex = ottoPeekIndex;
