from lib.config import *

from lib.util import convert_scad


def _recur_scad_config(fd, base, variables):

    if isinstance(variables, dict):
        for key, item in variables.items():
            if base == "":
                newbase = key
            else:
                newbase = base + "_" + key

            _recur_scad_config(fd, newbase, item)

            if base == "":
                fd.write("\n")

    elif isinstance(variables, (list, tuple)):

        fd.write(
            "{} = [{}];\n".
            format(base, ",".join(str(convert_scad(x)) for x in variables))
        )

    elif isinstance(variables, (int, float)):
        fd.write("{} = {};\n".format(base, convert_scad(variables)))

    elif isinstance(variables, str):
        fd.write("{} = \"{}\";\n".format(base, variables))

    else:
        raise Exception("unknown data", variables)


def generate_scad_config(filename, variables):
    print("generating scad file: " + filename)
    with open(filename, "w") as fd:
        fd.write("// rendered by script, do not edit manually!\n")
        _recur_scad_config(fd, "", variables)


def generate_pose(fd, cfg):
    fd.write("translate({})".format(convert_scad(cfg['pos'])))
    if 'rot' in cfg:
        fd.write("rotate({})".format(convert_scad(cfg['rot'])))


def generate_chain(fd, name, segments):

    cfg = segments[name]
    generate_pose(fd,cfg)
    fd.write("{\n")

    if 'scad' in cfg:
        module_args = cfg['scad']['args']
        module_args = ",".join([str(convert_scad(i)) for i in module_args])
        fd.write("  {}({});\n".format(cfg['scad']['module'], module_args))

    if 'next_segment' in cfg:
        generate_chain(fd, cfg['next_segment'], segments)

    fd.write("}\n")
    fd.write("\n")


def generate_scad_gimbal_pos(filename, gimbal):
    with open(filename, "w") as fd:
        fd.write("include <gimbal/gimbal.scad>")
        fd.write("module gimbal_pos(){\n")

        generate_chain(fd, gimbal['chain_root'], gimbal['segments'])

        fd.write("}\n")


def generate_scad_leg_pos(filename, legs):
    with open(filename, "w") as fd:
        fd.write("include <leg_modules.scad>;\n")
        for leg_key, leg in legs.items():

            fd.write("module {}_leg()".format(leg_key))
            generate_pose(fd, leg)
            fd.write("mirror({})".format(leg['mirror']))
            fd.write("{\n")

            generate_chain(fd, leg['chain_root'], leg['segments'])

            fd.write(";\n}\n")

        fd.write("module legs(){\n")
        for leg_key in legs.keys():
            fd.write(" {}_leg();\n".format(leg_key))
        fd.write("}\n")

        fd.write("module leg_pos(){\n")
        for leg_key, leg in legs.items():
            generate_pose(fd, leg)
            fd.write("mirror({})".format(leg['mirror']))
            fd.write("children();\n")

        fd.write("}\n")
