/**
 * Screens: the one on a desk and the one on a wall.
 *
 * Both have their glass at +Z, facing the person, and both are authored with
 * their origin on the floor. The monitor's foot sits at `y = 0` and a pack
 * raises it onto a desk with `Prop.elevation`; the wall display carries its own
 * `mount` height, because how high a display hangs is a property of the display
 * and not of the room it is in.
 *
 * Neither takes a `colorKey`. A screen is bezel and glass, and there is no part
 * of it that anybody wants to be the colour of a team.
 */

import { defineAsset } from "../kit.ts";
import { MeshBin } from "../parts.ts";
import { alongFacing } from "./common.ts";

type MonitorParams = {
  /** Bezel width, metres. 0.56 is a 24-inch panel. */
  width: number;
  height: number;
  /** Floor of the stand to the bottom of the bezel. */
  standHeight: number;
  /** Radians the panel leans back. */
  tilt: number;
};

export const screenMonitor = defineAsset<MonitorParams>({
  id: "tera:screen.monitor",
  label: "Monitor",
  defaults: { width: 0.56, height: 0.34, standHeight: 0.14, tilt: 0.07 },

  footprint(p) {
    return { width: p.width, depth: 0.19, height: p.standHeight + p.height + 0.02 };
  },

  build(p, ctx) {
    const P = ctx.parts;
    const bin = new MeshBin();
    const trim = ctx.materials.get("metalTrim");
    const bezel = ctx.materials.get("screenBezel");

    bin.add(P.box(), trim, { size: [p.width * 0.4, 0.016, 0.15] });
    // The neck runs a few centimetres past the bottom of the bezel, so the
    // joint is hidden behind the panel however far it is tilted.
    bin.add(P.box(), trim, { y: 0.01, z: -0.02, size: [0.055, p.standHeight + 0.07, 0.045] });

    const baseY = p.standHeight + 0.02;
    const pitch = -p.tilt;
    const front = alongFacing(pitch, 0.014);
    bin.add(P.roundedBox(0.03), bezel, {
      y: baseY,
      size: [p.width, p.height, 0.024],
      pitch,
    });
    bin.add(P.panel(), ctx.materials.get("screenDisplay"), {
      y: baseY + 0.012 + front.y,
      z: front.z,
      size: [p.width - 0.018, p.height - 0.026, 1],
      pitch,
    });

    return bin.build("screen.monitor");
  },
});

type WallDisplayParams = {
  width: number;
  height: number;
  /** Floor to the bottom edge of the screen. */
  mount: number;
};

export const screenWallDisplay = defineAsset<WallDisplayParams>({
  id: "tera:screen.wall-display",
  label: "Wall display",
  defaults: { width: 1.62, height: 0.94, mount: 0.86 },

  footprint(p) {
    // The depth is the whole assembly off the wall face, bracket included, so a
    // pack can push the prop `depth / 2` off the wall and have it sit flush.
    return { width: p.width, depth: 0.12, height: p.mount + p.height };
  },

  build(p, ctx) {
    const P = ctx.parts;
    const bin = new MeshBin();

    bin.add(P.box(), ctx.materials.get("metalTrim"), {
      y: p.mount + p.height / 2 - 0.16,
      z: -0.045,
      size: [0.44, 0.32, 0.04],
    });
    bin.add(P.roundedBox(0.02), ctx.materials.get("screenBezel"), {
      y: p.mount,
      size: [p.width, p.height, 0.05],
    });
    bin.add(P.panel(), ctx.materials.get("screenDisplay"), {
      y: p.mount + 0.014,
      z: 0.027,
      size: [p.width - 0.024, p.height - 0.028, 1],
    });

    return bin.build("screen.wall-display");
  },
});
