width = 65;
length = 75;
height = 16;
wall_thickness = 2;
guide_thickness = 1;
power_width = 21;
output_width = 37.5;
half_wall_thickness = wall_thickness / 2;
standoff_thickness = 10;
hole_diameter = 3;
// The radius of a nut in mm. However, based on my measurements, I'm not actually sure I have this right. The short height of a nut is 7.86mm. Derive from there.
nut_radius = 8.5 * cos(30) / 2;
nut_height = 2.69; // mm
screw_radius = 2;
handlebar_radius = 15;
clasp_thickness = 4;
clasp_width = 35;
circular_face_count = 48;

module hexagon(r, h) {
    pi = 3.1415926;
    polyhedron(
        points=[
            [r, 0, 0],
            [r * cos(60), r * sin(60), 0],
            [r * cos(120), r * sin(120), 0],
            [r * cos(180), r * sin(180), 0],
            [r * cos(240), r * sin(240), 0],
            [r * cos(300), r * sin(300), 0],

            [r, 0, h],
            [r * cos(60), r * sin(60), h],
            [r * cos(120), r * sin(120), h],
            [r * cos(180), r * sin(180), h],
            [r * cos(240), r * sin(240), h],
            [r * cos(300), r * sin(300), h],
        ],
        faces=[
            [0, 1, 2, 3, 4, 5],
            [11, 10, 9, 8, 7, 6],
            [6, 7, 1, 0],
            [7, 8, 2, 1],
            [8, 9, 3, 2],
            [9, 10, 4, 3],
            [10, 11, 5, 4],
            [11, 6, 0, 5],
        ]
    );
}

// Nut holders are blocks that have a hole drilled through them and a hexagonal-shaped cavity. The idea is to 
module nut_holder() {
    difference() {
        translate([-4.5, -4.5, -2]) cube([9, 9, 4]);
        union() {
            translate([0, 0, -1]) hexagon(nut_radius, 2);
            cylinder(h = 6, r = screw_radius, center = true, $fn = 24);
        }
    }
}

module screw_hole() {
    union() {
        translate([0, 0, 4]) cylinder(h = 2.1, r = screw_radius * 2, center = true, $fn = 24);
        cylinder(h = 6, r = screw_radius, center = true, $fn = 24);
    }
}

module base() {
    cube([width, length, wall_thickness]);
}

module face() {
    union() {
        cube([width, length, wall_thickness / 2]);
        translate([wall_thickness, wall_thickness, wall_thickness / 2]) cube([width-wall_thickness*2, length-wall_thickness*2, wall_thickness / 2]);
        translate([4.5 + wall_thickness, 4.5 + wall_thickness, 4]) nut_holder();
        translate([width - 4.5 - wall_thickness, 4.5 + wall_thickness, 4]) nut_holder();
        translate([width - 4.5 - wall_thickness, length - 4.5 - wall_thickness, 4]) nut_holder();
        translate([4.5 + wall_thickness, length - 4.5 - wall_thickness, 4]) nut_holder();
    }
}

module wall(length) {
    cube([length, height, wall_thickness]);
}

module power_wall() {
    difference() {
        wall(65);
        translate([9, 2, -.5]) cube([power_width, height, wall_thickness + 1]);
    }
}

module output_wall() {
    difference() {
        wall(65);
        translate([9, 2, -.5]) cube([output_width, height, wall_thickness + 1]);
    }
}

// Use hexagons as cutouts into which I can install a hex nut. This isn't quite right yet, but close.
// hexagon(nut_radius, 1);

// cube([standoff_thickness, standoff_thickness, 2]);

/*
difference() {
    union() {
        base();
        rotate([90, 0, 90]) wall(75);
        // translate([width - wall_thickness, 0, 0]) rotate([90, 0, 90]) wall(length);
        // rotate([90, 0, 0]) power_wall();
        // translate([0, length, 0]) rotate([90, 0, 0]) output_wall();
        // translate([wall_thickness,
        //            wall_thickness,
        //            wall_thickness]) standoff();
        // translate([width - wall_thickness - standoff_thickness,
        //            wall_thickness,
        //            wall_thickness]) standoff();
        // translate([wall_thickness,
        //            length - wall_thickness - standoff_thickness,
        //            wall_thickness]) standoff();
        // translate([width - wall_thickness - standoff_thickness,
        //            length - wall_thickness - standoff_thickness,
        //            wall_thickness]) standoff();
    }
    // translate([-half_wall_thickness, -wall_thickness - half_wall_thickness, height - half_wall_thickness]) cube([wall_thickness, length + wall_thickness * 2, wall_thickness]);
    // translate([width - half_wall_thickness, -wall_thickness - half_wall_thickness, height - half_wall_thickness]) cube([wall_thickness, length + wall_thickness * 2, wall_thickness]);
    // translate([-half_wall_thickness, -half_wall_thickness, height - half_wall_thickness]) rotate([0, 0, 270]) cube([wall_thickness, width + wall_thickness * 2, wall_thickness]);
    // translate([-half_wall_thickness, length + half_wall_thickness, height - half_wall_thickness]) rotate([0, 0, 270]) cube([wall_thickness, width + wall_thickness * 2, wall_thickness]);
}
*/

module box() {
    difference() {
        union() {
            cube([width, length, wall_thickness * 2]);
            translate([0, 0, wall_thickness]) rotate([90, 0, 90]) wall(length);
            translate([width - wall_thickness, 0, wall_thickness]) rotate([90, 0, 90]) wall(length);
            translate([0, wall_thickness, wall_thickness]) rotate([90, 0, 0]) wall(width);
            translate([0, length, wall_thickness]) rotate([90, 0, 0]) wall(width);
        }
        translate([4.5 + wall_thickness, 4.5 + wall_thickness, 4]) rotate([180, 0, 0]) screw_hole();
        translate([width - 4.5 - wall_thickness, 4.5 + wall_thickness, 4]) rotate([180, 0, 0]) screw_hole();
        translate([width - 4.5 - wall_thickness, length - 4.5 - wall_thickness, 4]) rotate([180, 0, 0]) screw_hole();
        translate([4.5 + wall_thickness, length - 4.5 - wall_thickness, 4]) rotate([180, 0, 0]) screw_hole();
    }
}

module top_clasp() {
    difference() {
        union() {
            cylinder(h = clasp_width, r = handlebar_radius + clasp_thickness, center = true, $fn = circular_face_count);
            translate([0, 0, -clasp_width / 2]) cylinder(h = 1, r = handlebar_radius + clasp_thickness + 1, center = true, $fn = circular_face_count);
            translate([0, 0, -clasp_width / 2 + 4]) cylinder(h = 1, r = handlebar_radius + clasp_thickness + 1, center = true, $fn = circular_face_count);
            translate([0, 0, clasp_width / 2]) cylinder(h = 1, r = handlebar_radius + clasp_thickness + 1, center = true, $fn = circular_face_count);
            translate([0, 0, clasp_width / 2 - 4]) cylinder(h = 1, r = handlebar_radius + clasp_thickness + 1, center = true, $fn = circular_face_count);
            translate([-handlebar_radius-5, -10, -clasp_width / 2 + 6]) cube([6, 20, clasp_width - 12]);
        }
        translate([-0.5, 0, 0]) cylinder(h = clasp_width+2, r = handlebar_radius + 1, center = true, $fn = circular_face_count);
        translate([-0.5, -handlebar_radius - 10, -clasp_width / 2 - 1]) cube([handlebar_radius + 10, handlebar_radius * 2 + 20, clasp_width + 2]);
    }
}

module body() {
    union() {
        box();
        translate([width / 2, length / 2, -5 - handlebar_radius]) rotate([0, 90, 90]) top_clasp();
    }
}

body();
translate([width + 10, 0, 0]) face();