import subprocess, os

from lib.util import convert_scad


def render(filename, scad_cfg, mirror):
    """ renders scad module defined by scad_cfg into stl 'filename' """
    assert filename[-1] == 'b'

    scad = "../scad/tmp.scad"
    with open(scad, "w") as fd:
        fd.write("include <model.scad>;\n $fn=32;")
        if mirror is not None:
            fd.write("mirror({})".format([int(x) for x in mirror]))
        args = ",".join([str(convert_scad(x)) for x in scad_cfg['args']])
        fd.write(scad_cfg['module'] + "(" + args + ");")

    tmp_stl = "../stl/tmp.stl"

    print("Rendering: ", filename)
    with open(os.devnull, 'wb') as devnull:
        subprocess.check_call(['openscad', '-o', tmp_stl, scad], stdout=devnull, stderr=devnull)
    subprocess.check_call(['ivcon', tmp_stl, filename])
    subprocess.check_call(["admesh", "--write-binary-stl=" + filename, "--scale=0.001", filename])

    os.remove(tmp_stl)
    os.remove(scad)


def render_chain(segments, name, folder, mirror):

    if not os.path.exists("../stl/" + folder):
        os.mkdir("../stl/" + folder)

    if 'scad' in segments[name]:
        render("../stl/" + folder + name + ".stlb", segments[name]['scad'], mirror)

    if 'next_segment' in segments[name]:
        render_chain(segments, segments[name]['next_segment'], folder, mirror)


def render_stl(cfg):


    render("../stl/base_link.stlb", {"module": "body", "args": []}, mirror=None)

    if not os.path.exists("../stl/leg/"):
        os.mkdir("../stl/leg")

    for leg, leg_cfg in cfg['legs'].items():

        mirror = None
        if 'mirror' in leg_cfg:
            mirror = leg_cfg['mirror']

        render_chain(
            leg_cfg['segments'],
            leg_cfg['chain_root'],
            folder="leg/" + leg + "/",
            mirror=mirror

        )

    render_chain(
        cfg['gimbal']['segments'], cfg['gimbal']['chain_root'], folder="gimbal/", mirror=None
    )
