"""Ready-to-slice 3MF plates (parts already in print orientation, laid out on a 250 x 220 mm bed)."""
import os
from build123d import Mesher, Pos, Rot, Color
import coral_eye as ce
import accessories as ac

OUT = ce.OUT_DIR
BED_CX, BED_CY = 125.0, 110.0


def drop(shape, x, y, rz=0):
    """Centre the part's footprint on (x, y) of the bed, resting on z = 0."""
    s = Rot(0, 0, rz) * shape
    bb = s.bounding_box()
    return Pos(x - (bb.min.X + bb.max.X) / 2, y - (bb.min.Y + bb.max.Y) / 2, -bb.min.Z) * s


def case_parts():
    import shutter as sh
    body = ce.make_body()
    face = Pos(0, 0, ce.Z_FRONT) * Rot(180, 0, 0) * ce.make_face("skin")
    knob = ac.thumb_knob()
    plunger = ce.user_plunger_print()                           # flange down (checked)
    sp = sh.print_parts()                                       # shutter parts, already print-oriented
    coral, graphite, light = (255, 111, 97), (58, 62, 70), (232, 233, 228)
    return [("Body", drop(body, 75, 125), graphite),
            ("Face (hidden LEDs)", drop(face, 170, 125), light),
            ("Shutter bezel", drop(sp["CoralEye_Shutter_Bezel"], 40, 42), coral),
            ("Shutter twist ring", drop(sp["CoralEye_Shutter_TwistRing"], 85, 42), graphite),
            ("Shutter blade upper", drop(sp["CoralEye_Shutter_Blade_Upper"], 122, 34), coral),
            ("Shutter blade lower", drop(sp["CoralEye_Shutter_Blade_Lower"], 122, 52), coral),
            ("Stand knob", drop(knob, 152, 42), coral),
            ("USER button", drop(plunger, 178, 42), graphite)]


def mount_parts():
    parts = ac.all_parts()
    out = []
    pos = {"CoralEye_Stand": (75, 130), "CoralEye_Mount_GoPro": (160, 155),
           "CoralEye_Mount_Tripod": (205, 155), "CoralEye_Mount_Wall": (160, 75), "CoralEye_Mount_Magnet": (210, 75)}
    for name, (x, y) in pos.items():
        p = ac.PRINT_ORIENTATION[name] * parts[name]
        out.append((name.replace("CoralEye_", "").replace("_", " "), drop(p, x, y), (58, 62, 70)))
    return out


def write(path, items):
    m = Mesher()
    for i, (name, shp, rgb) in enumerate(items):
        # Mesher names each object after the solid it meshes (not after a wrapping compound)
        solids = shp.solids()
        assert len(solids) == 1, f"{name}: {len(solids)} solids"
        s = solids[0]
        s.label = name
        s.color = Color(rgb[0] / 255, rgb[1] / 255, rgb[2] / 255)
        m.add_shape(s, linear_deflection=0.01, angular_deflection=0.2, part_number=f"{i + 1:02d}")
    m.write(path)
    print("wrote", path)


if __name__ == "__main__":
    write(os.path.join(OUT, "CoralEye_Plate1_Case.3mf"), case_parts())
    write(os.path.join(OUT, "CoralEye_Plate2_Mounts.3mf"), mount_parts())
