import cadquery as cq
from cadquery import exporters

from modelo import (
    kbd_height,
    kbd_width,
    mounting_pillar_positions,
    shell_t,
    ti_depth,
    ti_radius,
)

# Size of the whole object
width = kbd_width + 2 * shell_t
height = 66
height_bottom = 59
thickness = 48  # Will be shorter after construction

# Visible screen size
vis_w = 220
vis_h = 58
viewport_cutout = cq.Sketch().trapezoid(vis_w, vis_h, 90, mode="a")

# Whole screen size
scr_w = 231
scr_h = 65
scr_thickness = 5.5
screen_cutout = cq.Sketch().trapezoid(scr_w, scr_h, 90, mode="a")

# Screen angle
scr_angle = 20

# Circuit board and cable hole.
# This is in the back of the screen, and is a bit shorter in height than the
# screen. It's wider so it removes enough material to make the shape simpler.
board_cutout = cq.Sketch().trapezoid(
    scr_w + 5,
    scr_h - 10,
    90,
    mode="a",
)

kbd_cable_hole = cq.Sketch().trapezoid(20, 9, 90, mode="a").vertices().fillet(1)

mounting_pillars = (
    cq.Sketch()
    .push(mounting_pillar_positions)
    .trapezoid(-12, 12, 90, mode="a")
    .circle(ti_radius, mode="s")
    .clean()
)


def model():
    return (
        cq.Workplane("XY")
        .workplane()
        .tag("mid_height")
        .box(width, height, thickness)
        # The screen goes rotated
        .faces(">Z")
        .transformed(rotate=(scr_angle, 0, 0))
        # Move the screen "lower" so it doesn't interfere
        # so much with the back
        .center(0, -2)
        .tag("slanted")
        # Arbitrary huge trapezoid to cut off the material *in front*
        # of the inclined screen
        .placeSketch(cq.Sketch().trapezoid(1000, 1000, 90, mode="a"))
        .cutBlind(1000)
        # Trim the top
        .workplaneFromTagged("mid_height")
        .workplane(offset=21)
        .placeSketch(cq.Sketch().trapezoid(1000, 1000, 90, mode="a"))
        .cutBlind(100)
        # Make bottom smaller to fit with base
        .faces(">X")
        .workplane(centerOption="CenterOfBoundBox")
        .center(-height / 2, -thickness / 2)
        .placeSketch(
            cq.Sketch()
            .polygon(
                [
                    (height_bottom, 0),
                    (height_bottom, thickness / 3),
                    (height, thickness - 21),
                    (height, thickness),
                    (height + 5, thickness + 5),
                    (height + 5, 0),
                    (height_bottom, 0),
                ]
            )
            .vertices()
            .fillet(3)
        )
        .cutBlind(-1000)
        # Fillet top of the object
        .edges("|X and >Z")
        .fillet(3)
        # Cut off viewport hole so we can see the screen
        .workplaneFromTagged("slanted")
        .placeSketch(viewport_cutout)
        .cutBlind(-shell_t)
        # Make hole for screen assembly so the whole screen fits
        .workplaneFromTagged("slanted")
        .workplane(offset=-shell_t, centerOption="CenterOfBoundBox")
        # Left bezel is wider than right one, so this hole is displaced to the left
        .center(-3, 0)
        .placeSketch(screen_cutout)
        .cutBlind(-scr_thickness)
        # Make it hollow
        .faces("<Z")
        # Can't be exactly shell_t because cq fails
        .shell(-shell_t + 0.01)
        # Cut hole for the screen board and cables
        .workplaneFromTagged("slanted")
        .workplane(offset=-scr_thickness, centerOption="CenterOfBoundBox")
        .placeSketch(board_cutout)
        .cutBlind(-6)
        # # Make small hole for the keyboard cable
        # # not needed with this keyboard
        # .faces("<Y")
        # .workplane(centerOption="CenterOfBoundBox")
        # .center(width / 2 - 175, -4)
        # .placeSketch(kbd_cable_hole)
        # .cutBlind(-height / 2)
        # Pillars to join with bottom half
        .workplaneFromTagged("mid_height")
        .workplane(offset=-thickness / 2, centerOption="CenterOfBoundBox")
        .center(-width / 2, height_bottom - height / 2)
        .placeSketch(mounting_pillars)
        .extrude(10)
    )


if __name__ == "__main__":

    print("Exporting")
    exporters.export(model(), "screen_mount.stl")

    offset_width = -width / 2

    right_side = (
        model()
        .faces(">X")
        .workplane(centerOption="CenterOfBoundBox", offset=offset_width)
        .split(keepTop=True)
    )

    exporters.export(right_side, "right_screen_mount.stl")

    left_side = (
        model()
        .faces(">X")
        .workplane(centerOption="CenterOfBoundBox", offset=offset_width)
        .split(keepBottom=True)
    )

    exporters.export(left_side, "left_screen_mount.stl")
