module hexagon(r, h) {
    cylinder(r = r, h = h, center = 2, $fn = 6);
}

module pill(length, bevel) {
    hull() {
        translate([0, 0, (-length / 2) + bevel]) sphere(r = bevel);
        translate([0, 0, (length / 2) - bevel]) sphere(r = bevel);
    }
}

module rounded_cube(dimensions, bevel = 0) {
    x = dimensions[0];
    y = dimensions[1];
    z = dimensions[2];

    if (bevel > 0) {
        hull() {
            translate([-x / 2 + bevel, -y / 2 + bevel, -z / 2 + bevel]) sphere(r = bevel);
            translate([ x / 2 - bevel, -y / 2 + bevel, -z / 2 + bevel]) sphere(r = bevel);
            translate([ x / 2 - bevel,  y / 2 - bevel, -z / 2 + bevel]) sphere(r = bevel);
            translate([-x / 2 + bevel,  y / 2 - bevel, -z / 2 + bevel]) sphere(r = bevel);
            translate([-x / 2 + bevel, -y / 2 + bevel,  z / 2 - bevel]) sphere(r = bevel);
            translate([ x / 2 - bevel, -y / 2 + bevel,  z / 2 - bevel]) sphere(r = bevel);
            translate([ x / 2 - bevel,  y / 2 - bevel,  z / 2 - bevel]) sphere(r = bevel);
            translate([-x / 2 + bevel,  y / 2 - bevel,  z / 2 - bevel]) sphere(r = bevel);
        }
    } else {
        cube(dimensions, center = true);
    }
}

module box_face(dimensions, bevel = 0) {
    x = dimensions[0];
    y = dimensions[1];
    z = dimensions[2];

    if (bevel > 0) {
        translate([0, 0, z / 2])
        hull() {
            pill(z, bevel);
            translate([x, 0, 0])
                pill(z, bevel);
            translate([x, y, 0])
                pill(z, bevel);
            translate([0, y, 0])
                pill(z, bevel);
        }
    } else {
        cube(dimensions);
    }
}

module channel(length, width, height, bevel) {
    union() {
        box_face([length, width, wall_thickness], bevel);

        translate([0, wall_thickness - bevel, bevel])
            rotate([90, 0, 0])
            box_face([length, height, wall_thickness], bevel);

        translate([0, width + bevel, bevel])
            rotate([90, 0, 0])
            box_face([length, height, wall_thickness], bevel);
    }
}

module box(length, width, height, bevel = 0) {
    union() {
        channel(length, width, height, bevel);

        translate([-bevel, 0, bevel])
            rotate([90, 0, 0])
            rotate([0, 90, 0])
            box_face([width, height, wall_thickness], bevel);

        translate([length - wall_thickness + bevel, 0, bevel])
            rotate([90, 0, 0])
            rotate([0, 90, 0])
            box_face([width, height, wall_thickness], bevel);
    }
}

module box_side_slider(length, width, height) {
    difference() {
        box_face([width - wall_thickness * 2 + 4, height, wall_thickness], bevel);
        translate([-1, -1, 1]) cube([4-threshold, height+2, 4-threshold]);
        color("red") translate([width - wall_thickness * 2 + 1, -1, 1]) cube([4-threshold, height+2, 4-threshold]);
    }
}