"""ALTO enclosure details; evaluated in the main model's centimetre workspace."""

def build_top_grille():
    g=group('top_grille');cx=-8.835
    parent(cube('Cooling / dark plenum',(cx,10.11,3.50),(14.46,4.16,.32),BLACK,.19),g)
    for i in range(28):
        x=cx-7.10+i*14.20/27
        parent(cube(f'Cooling / red louvre {i+1:02}',(x,10.11,DECK_HEIGHT-.03),(.25,4.10,.40),RED,.055),g)
    for i in range(17):
        parent(cube('Cooling / transverse mesh rib',(cx,8.22+i*.235,3.77),(14.35,.055,.04),BASE,.01),g)
    for x in (cx-7.28,cx+7.28):
        parent(cube('Cooling / end buttress',(x,10.11,DECK_HEIGHT-.04),(.20,4.13,.36),RED,.06),g)
    return g

def build_bay_doors():
    hinges=[]
    for index,y in enumerate((7.30,11.10),1):
        g=group(f'bay_0{index}_shutters');g.location=(8.46,y,DECK_HEIGHT+.025)
        for side,sign in (('front',-1),('rear',1)):
            hinge=group(f'bay_0{index}_door_{side}');parent(hinge,g);hinges.append(hinge)
            hinge.location.y=sign*.935
            cy=-sign*.451
            parent(cube('Bay / flush spring door',(0,cy,0),(12.384,.902,.10),RED,.036),hinge)
            if side=='front':
                parent(text('Bay / ASX mark','ASX',(-5.53,cy,.052),.43,WHITE,bold=True),hinge)
                parent(text('Bay / door identity','ARTISAN EXPANSION',(-3.93,cy,.052),.19,WHITE),hinge)
            else:
                parent(text('Bay / door specification','PCIe + OUTPUT',(-5.50,cy,.052),.19,WHITE),hinge)
                parent(text('Bay / door index',f'SLOT 0{index}',(5.50,cy,.052),.20,WHITE,align='RIGHT',bold=True),hinge)
            hinge.rotation_euler.x=sign*math.pi/2 if index==1 else 0
    return hinges

def build_rear_panel():
    rear=group('rear_connections');rear.location=(0,13.36,2.43);rear.rotation_euler=(rear_angle,0,math.pi)
    parent(cube('Rear / central connector strip',(0,.07,0),(21.50,.20,1.52),GRAPHITE,.16),rear)
    for i,x in enumerate((-9.35,-7.50,-5.65,-3.80,-1.95)):
        port=group(f'rear_usb_c_{i+1}');parent(port,rear);port.location.x=x
        usb_c_socket(port,'Rear / USB-C '+str(i+1),0,-.18,y=-.10,label='USB-C',label_z=.50)
        if i<3:
            face_text(port,'Rear / assignment',('POWER','CARTRIDGE 1','CARTRIDGE 2')[i],0,.19,.115,y=-.13,align='CENTER',bold=True)
            parent(cube('Rear / assignment rule',(0,-.132,.34),(1.55,.008,.014),WHITE,0),port)
        if i in (1,2):parent(cube('route_led_'+str(i),(.75,-.14,-.18),(.15,.025,.065),AMBER if i==1 else AMBER_DIM,.019),port)
    face_text(rear,'Rear / ASX routing caption','ASX / CARTRIDGE OUTPUT INTERFACE',-6.58,-.59,.118,y=-.13,align='CENTER')
    lan=group('rear_lan');parent(lan,rear);lan.location.x=.35
    rect_socket(lan,'Rear / Ethernet',0,-.17,1.53,.83,y=-.10,label='LAN',label_z=.47)
    for i in range(8):parent(cube('Rear / LAN contact',(-.42+i*.12,-.207,-.35),(.05,.038,.11),GOLD,.003),lan)
    hdmi=group('rear_hdmi');parent(hdmi,rear);hdmi.location.x=2.90
    rect_socket(hdmi,'Rear / HDMI',0,-.13,1.59,.59,y=-.10,label='HDMI',label_z=.47)
    parent(cube('Rear / HDMI tongue',(0,-.208,-.13),(1.23,.08,.14),BLACK,.055),hdmi)
    usb=group('rear_usb_a');parent(usb,rear);usb.location.x=5.35
    rect_socket(usb,'Rear / USB-A',0,-.13,1.47,.61,y=-.10,label='USB-A',label_z=.47)
    parent(cube('Rear / USB-A tongue',(0,-.22,-.16),(1.18,.10,.16),MOD,.024),usb)
    for i in range(4):parent(cube('Rear / USB-A contact',(-.37+i*.25,-.273,-.075),(.12,.04,.018),GOLD,.003),usb)
    audio=group('rear_audio');parent(audio,rear);audio.location.x=7.75
    round_socket(audio,'Rear / 3.5 mm audio',0,-.13,.285,y=-.13,label='AUDIO',label_z=.47)
    case_fasteners(rear,10.28,-.07,0)
    for side,x in (('left',13.85),('right',-13.85)):
        exhaust=group('rear_exhaust_'+side);parent(exhaust,rear);exhaust.location=(x,0,-.03)
        surround=cube('Cooling / nozzle surround',(0,.14,0),(5.53,.20,1.60),RED_DARK,.15)
        cut(surround,cube('Cooling / clear throat',(0,.14,0),(4.93,1,1.30),None,.12))
        parent(surround,exhaust)
        nozzle(exhaust,'Cooling / aft jet throat',5.08,1.45)
        face_text(exhaust,'Cooling / caution','CAUTION HOT',0,1.035,.205,y=-.16,align='CENTER',bold=True)
        for dx in (-1.99,1.99):
            parent(cube('Cooling / orange caution marker',(dx,-.165,1.035),(.40,.013,.10),ORANGE,.013),exhaust)
    finalize_cartridge(rear)
    return rear
