# behuizing.py - een parametrische behuizing: alle maten volgen uit een handvol invoermaten
import math

RHO = 1.27                # g/cm³, PETG (hoofdstuk 17)
DEBIET = 3.0              # mm³/s, gemiddeld debiet van de printer (rekenwaarde)
PRIJS = 20.0              # euro per kg filament
BED = (220, 220, 250)     # bouwvolume van de printer in mm (rekenwaarde)


def hoekvlak(l, b, r):
    """Oppervlakte (mm²) van een rechthoek l x b met vier afgeronde hoeken met straal r."""
    return l * b - (4 - math.pi) * r ** 2


def ring(d_buiten, d_binnen, h):
    """Volume (mm³) van een buisje: een cilinder met een gat erin."""
    return math.pi / 4 * (d_buiten ** 2 - d_binnen ** 2) * h


def behuizing(plaat_l, plaat_b, comp_h, wand=2.0, speling=1.0, bus_h=6.0, plaat_d=3.0, boven=12.0,
              hoek_r=4.0, deksel_d=2.0, lip_h=5.0, lip_b=1.6, lip_speling=0.3, wartels=3, wartel_d=12.5):
    """Alle maten (mm), de volumes (mm³), de massa (g), de printtijd (h) en de prijs (euro)."""
    m = {}
    m["binnen_l"] = plaat_l + 2 * speling
    m["binnen_b"] = plaat_b + 2 * speling
    m["binnen_h"] = bus_h + plaat_d + comp_h + boven
    m["buiten_l"] = m["binnen_l"] + 2 * wand
    m["buiten_b"] = m["binnen_b"] + 2 * wand
    m["bak_h"] = m["binnen_h"] + wand                  # de bodem is even dik als de wand
    m["totaal_h"] = m["bak_h"] + deksel_d
    r_binnen = max(hoek_r - wand, 0.0)
    bak = (hoekvlak(m["buiten_l"], m["buiten_b"], hoek_r) * m["bak_h"]
           - hoekvlak(m["binnen_l"], m["binnen_b"], r_binnen) * m["binnen_h"])
    bak += 4 * ring(7.0, 2.5, bus_h)                   # vier afstandsbussen, gat voor een schroef M3
    bak -= wartels * ring(wartel_d, 0, wand)           # gaten voor de kabelwartels
    lip_l = m["binnen_l"] - 2 * lip_speling
    lip_bb = m["binnen_b"] - 2 * lip_speling
    r_lip = max(r_binnen - lip_speling, 0.0)
    deksel = hoekvlak(m["buiten_l"], m["buiten_b"], hoek_r) * deksel_d
    deksel += (hoekvlak(lip_l, lip_bb, r_lip)
               - hoekvlak(lip_l - 2 * lip_b, lip_bb - 2 * lip_b, max(r_lip - lip_b, 0.0))) * lip_h
    m["volume_bak"], m["volume_deksel"] = bak, deksel
    m["massa"] = (bak + deksel) / 1000 * RHO
    m["printtijd"] = (bak + deksel) / DEBIET / 3600
    m["prijs"] = m["massa"] / 1000 * PRIJS
    return m


def controleer(m, wand=2.0, wartels=3, wartel_d=12.5, lip_speling=0.3):
    """De ontwerpregels: geeft een lijst met wat niet klopt (een lege lijst = in orde)."""
    fout = []
    if wand < 1.2:
        fout.append("wand dunner dan drie lijnen van 0,4 mm")
    if max(m["buiten_l"], m["buiten_b"]) > BED[0] or m["bak_h"] > BED[2]:
        fout.append("past niet op de printer")
    if wartel_d + 10 > m["bak_h"]:
        fout.append("wand te laag voor het wartelgat")
    if wartels * (wartel_d + 10) > m["buiten_b"]:
        fout.append("te veel wartels voor de korte zijde")
    if lip_speling < 0.3:
        fout.append("deksel kan klemmen")
    return fout


varianten = {                      # naam: (plaat_l, plaat_b, comp_h, wartels)
    "meetkas (Uno)": (68.6, 53.4, 15, 2),
    "regelkast RK-1": (140, 90, 28, 3),
    "relaiskast": (100, 60, 20, 4),
    "alles samen": (220, 150, 30, 5),
}
print(f"{'variant':15} {'buiten (mm)':>17} {'massa':>7} {'print':>6} {'prijs':>6}  regels")
for naam, (l, b, h, n) in varianten.items():
    m = behuizing(l, b, h, wartels=n)
    fouten = controleer(m, wartels=n)
    maten = f"{m['buiten_l']:.0f} x {m['buiten_b']:.0f} x {m['totaal_h']:.0f}"
    print(f"{naam:15} {maten:>17} {m['massa']:5.0f} g {m['printtijd']:4.1f} h {m['prijs']:5.2f}  {'; '.join(fouten) or 'in orde'}")
