from typing import List, Iterable

import solid as scad

import solidLib as sl

import numpy as np
import logging as log

log.basicConfig(level=log.INFO)


def rcube(dim: Iterable[float], radius: float):
    """
    creates a cube with rounded corners

    .. image:: img/rcube.png

    Args:
        dim: cube dimensions to base box on.
        radius: box radius.
        segments: circular object segments
    """

    corners = []
    for dx in [radius, dim[0] - radius]:
        for dy in [radius, dim[1] - radius]:
            for dz in [radius, dim[2] - radius]:
                corners.append(
                    scad.translate([dx, dy, dz])(
                        (scad.sphere(r=radius, segments=sl.settings.segments))
                    )
                )

    return scad.hull()(*corners)


def rfcube(dim: Iterable[float], r: float):
    """creates a round box with radius r and flat top/bottom

    .. image:: img/round_flat_box.png
    """
    box = scad.cube([dim[0] - 2 * r, dim[1] - 2 * r, dim[2] - 2 * r])
    wall = scad.cylinder(r=r, h=2 * r, segments=sl.settings.segments)

    return scad.translate([r, r, 0])(scad.minkowski()(box, wall))


def pill(ps: List[List[float]], r, segments: int = 36):
    """
    create a pill around given points

    .. image:: img/pill.png
    """
    if len(ps) < 2:
        raise Exception("requires 2 or more points")
    s = scad.sphere(r=r, segments=segments)

    spheres = []
    # log.info(ps)
    for p in ps:
        spheres.append(scad.translate(p)(s))

    return scad.hull()(*spheres)
