"""
The Button: the bridge box made longer, with one big lit dome that steps
through a written piece, and a small screen that shows the next cue. The
bridge's board, stop button, activate button, light and antenna are all in it.

Run from the cad/ folder:

    uv run button/model.py

It writes, for the site:
    site/public/files/button/stl/*.stl      the tub and the lid, laid flat for printing
    site/public/files/button/button-stl.zip
    site/public/files/button/button.step    the whole box, for editing
    site/public/files/button/button.glb     the 3D model shown on the page
    site/public/files/button/button-cad.py  this script, and console.py beside it
    site/src/content/instruments/button/drawings/button-render.svg

It builds the box with the bridge box's own script (cad/bridge-box/model.py),
only longer and with its own lid layout. Coordinates as there: X along the box
from the cable end, Y across it, Z up from the floor's underside.

All numbers are a first design, untested in print. Measure your dome button and
screen before printing and change the sizes below to match.
"""

from pathlib import Path
import importlib.util
import sys

HERE = Path(__file__).resolve().parent
sys.path.insert(0, str(HERE.parent))
import console as c  # noqa: E402

spec = importlib.util.spec_from_file_location("bridge_box", HERE.parent / "bridge-box" / "model.py")
bridge = importlib.util.module_from_spec(spec)
spec.loader.exec_module(bridge)

# ---------------------------------------------------------------------------
# The design, in one place
# ---------------------------------------------------------------------------

bridge.L, bridge.W = 180.0, 110.0  # longer and a little wider than the bridge box, for the dome
bridge.CY = bridge.W / 2
bridge.TIE_X = 131.0  # the board sits under the stop and the screen, clear of the dome's switch
L, W, H = bridge.L, bridge.W, bridge.H
TOP = H + bridge.LID_T
CY = W / 2

DOME = (45.0, CY)  # the dome, at the cable end, where the hand rests
DOME_HOLE = 28.0  # most 60 mm dome buttons mount in a 28 mm hole; measure yours
SCREEN = (106.0, 79.0, 30.0, 16.0)  # window: x, y, width, height, for a 1.3 inch module
RELEASE = (106.0, 30.0)
LIGHT = (130.0, 28.0)
STOP = (148.0, 60.0)
ANTENNA = (163.0, 95.0)

VIEW = (-170.0, -230.0, H + 260.0)  # from the dome's end, so the dome is nearest
# The cable leaves the end, drops to the desk and runs off behind the box, out of the hand's way
CABLE = [(-26, CY, 20), (-50, CY, 12), (-85, CY + 20, 2.6), (-95, CY + 65, 2.6), (-100, CY + 110, 2.6), (-105, CY + 155, 2.6)]

HOLES = [
    (*DOME, DOME_HOLE),
    (*RELEASE, bridge.RELEASE_D),
    (*LIGHT, bridge.LED_D),
    (*STOP, bridge.STOP_D),
    (*ANTENNA, bridge.SMA_D),
]


def at(shape, xy):
    return c.Pos(xy[0], xy[1], TOP) * shape


def bought_parts():
    z0 = bridge.FLOOR + 2  # on a strip of foam tape
    bx, by = bridge.TIE_X, CY
    return [
        ("dome-button", at(c.dome_button(), DOME), (0.85, 0.85, 0.82)),
        ("screen", at(c.screen(), SCREEN[:2]), (0.1, 0.12, 0.2)),
        ("release-button", at(c.push_button(), RELEASE), (0.15, 0.15, 0.15)),
        ("status-light", at(c.light(), LIGHT), (0.92, 0.92, 0.9)),
        ("stop-button", at(c.stop_button(), STOP), (0.8, 0.15, 0.12)),
        ("antenna", at(c.antenna(), ANTENNA), (0.12, 0.12, 0.12)),
        ("esp32-s3-board", c.Pos(bx, by, z0) * c.boards(), (0.1, 0.25, 0.15)),
        ("zip-tie", c.box(bx - 2, bx + 2, by - bridge.TIE_SPAN / 2, by + bridge.TIE_SPAN / 2, z0 + 17, z0 + 18.2), (0.9, 0.9, 0.85)),
        ("usb-cable", bridge.usb_cable(CABLE), (0.2, 0.2, 0.22)),
    ]


def main():
    printed = [
        ("tub", bridge.tub(), c.Rot(0, 0, 0)),
        ("lid", bridge.lid(holes=HOLES, windows=[SCREEN]), c.Rot(180, 0, 0)),
    ]
    c.export(
        "button",
        __file__,
        printed,
        bought_parts(),
        [(None, VIEW, (L / 2, W / 2, H / 2), "THE BOX: THE BIG DOME, THE NEXT-CUE SCREEN, ACTIVATE, THE STOP AND THE ANTENNA")],
        "The Button: the box",
    )


if __name__ == "__main__":
    main()
