// v2
// Reduced rail width from 2 to 1.7
// Adjust ethernet and micro-usb
// Ease assembly


$w=2.5;            // wall thickness
$wf=2;            // wall thickness for front and back faces
$g=.2;             // gap

$hl=123;           // heatsink length
$hw=100;           // heatsink width
$hrailh=1.7 - $g;  // heatsink rail height
$hrailw=1.7 - $g;  // heatsink rail witdth

$boxh=42.5;                 // box height
$boxw=$hw + 2 * ($w + $g);  // box width
$boxl=$hl / 2 + ($wf + $g);  // box length

$feeth=5.3;         // feet height

// ========================================


translate([0, -50, $boxl]) rotate([-90,0,0]) frontBox();

translate([0, 50, $boxl]) rotate([-90, 0, 180]) backBox();


// ================ MODULES ================

module frontBox() {
    difference() {  
        union() {
            box();
            // Uncomment for integrated 2.5" SATA SSD/HDD holder 
            // (when not using the SATA mounting kit from ODroid)
            //color("red") hdd(); 
        }
        frontHoles();
        frontScrewoles();
        frontLabel();
    }
}

module backBox() {
    difference() {  
        union() {
            color("orange") box();
            color("red") connectors();
        }
        backHoles();
        backScrewoles();
        backLabel();
    }
}


module frontLabel() {
    color("green") 
        translate([$boxw / 2 - 6, $boxl - 1.2, $feeth + 7.5])
        rotate([90, 0, 180])
        union() {
            translate([6,$boxh-45,0])
                linear_extrude(2) text("CHATONS.ORG", size=8);
        }
        translate([0, $boxl, $feeth + $boxh - 34]) 
            corners(13, 92);
}

module backLabel() {
    color("green") 
        translate([$boxw / 2 - 6, $boxl - 1.2, $feeth + 7.5])
        rotate([90, 0, 180])
        union() {
            translate([38,$boxh-26,0])
                linear_extrude(2) text("CLIC", size=10);
            translate([8.5,$boxh-45,0])
                linear_extrude(2) text("mose.distrilab.fr", size=8);
        }
        translate([0, $boxl, $feeth + $boxh - 34]) 
            corners(13, 92);
}

module frontScrewoles() {
    translate([0, 4.2, $feeth + $boxh - 25.3]) 
        rotate([0, 90, 0])
        cylinder(h=$boxw + 10, r=1.1, center=true, $fn=20);
    
    translate([37, 4.2, 0]) 
        rotate([0, 0, 90])
        cylinder(h=50, r=1.1, center=true, $fn=20);
    translate([-37, 4.2, 0]) 
        rotate([0, 0, 90])
        cylinder(h=50, r=1.1, center=true, $fn=20);
}

module backScrewoles() {
    translate([0, -4.2, $feeth + $boxh - 25.3]) 
        rotate([0, 90, 0])
        cylinder(h=$boxw + 10, r=0.8, center=true, $fn=20);
    translate([37, -4.2, 0]) 
        rotate([0, 0, 90])
        cylinder(h=50, r=0.8, center=true, $fn=20);
    translate([-37, -4.2, 0]) 
        rotate([0, 0, 90])
        cylinder(h=50, r=0.8, center=true, $fn=20);
}

module connectors() {
    difference() {
        union() {
            connector($boxw - 2 * $w);
            translate([-$boxw / 2, 0, $feeth + $w + ($boxh-15.5)/2+0.05])
                rotate([0, 90, 0]) 
                    connector($boxh-15.5, 0);
            translate([$boxw / 2, 0, $feeth + $w + ($boxh-15.5)/2+0.05])
                rotate([0, -90, 0]) 
                    connector($boxh-15.5, 0);
        }
        translate([$boxw / 2 - .5 * $w, -5, $feeth + $w])
            rotate([0, -45, 0])
            cube([10, 10, 2 * $w], center=true);    
        translate([-($boxw / 2 - .5 * $w), -5, $feeth + $w])
            rotate([0, 45, 0])
            cube([10, 10, 2 * $w], center=true);    

        translate([-($boxw / 2 - .5 * $w), -7.7, $feeth + $w])
            rotate([0, 45, 45])
            cube([10, 10, 2 * $w], center=true);    
        translate([$boxw / 2 - .5 * $w, -7.7, $feeth + $w])
            rotate([0, -45, -45])
            cube([10, 10, 2 * $w], center=true);    
    }
}

module connector($width, $z = $feeth) {
    difference() {
        union() {
            translate([0, 0, $z + 1.5 * $w])
                cube([$width, 18, $w], center=true);
            translate([0, 4.5, $z + $w])
                cube([$width, 9, $w], center=true);
        }
//        translate([0, -9.3, $z + 1.5 * $w])
//            rotate([45, 0, 0])
//            cube([$width + $g, 18, $w], center=true);
        translate([0, 9.3, $z + 1.5 * $w])
            rotate([-45, 0, 0])
            cube([$width + $g, 18, $w], center=true);        
        translate([0, -9.3, $z + 1.5 * $w])
            rotate([-45, 0, 0])
            cube([$width + $g, 18, $w], center=true);        
    }
}

module backHoles() {
    color("green") {
        translate([0, $boxl, $feeth + $boxh - 13.8]) 
            corners(24.26, 92);
        // sd card
        translate([31.9, $boxl, $boxh - 5]) 
            cube([12.8, 5+$w, 3.1], center=true);
        // ir receiver        
        translate([18.75, $boxl, $feeth + $boxh - 14.3]) 
            rotate([90, 0, 0])
            cylinder(h=5+$w, r=3, center=true, $fn=100);
        // audio jack
        translate([-32.16, $boxl, $feeth + $boxh - 9.4]) 
            rotate([90, 0, 0])
            cylinder(h=5+$w, r=3, center=true, $fn=100);
    }
}

module frontHoles() {
    color("green") {
        translate([0, $boxl, $feeth + $boxh - 13.8]) 
            corners(24.26, 92);
        // ethernet
        translate([34.42, $boxl, $feeth + $boxh - 14.5]) 
            cube([15.32, 5+$wf, 13.5], center=true);
        // usb
        translate([-2.87, $boxl, $feeth + $boxh - 16]) 
            cube([14.5, 5+$wf, 16], center=true);
        translate([-21, $boxl, $feeth + $boxh - 16]) 
            cube([14.5, 5+$wf, 16], center=true);
        // power
        translate([-38.64, $boxl, $feeth + $boxh - 14.07]) 
            rotate([90, 0, 0])
            cylinder(h=5+$wf, r=3.725, center=true, $fn=100);
        // hdmi
        translate([17.13, $boxl, $feeth + $boxh - 11.3]) {
            difference() {
                cube([15.35, 5+$wf, 6], center=true);
                translate([-10, 0, 3])
                    rotate([0, 45, 0]) 
                        cube([6, 6+$wf, 6], center=true);
                translate([10, 0, 3])
                    rotate([0, -45, 0]) 
                        cube([6, 6+$wf, 6], center=true);
            }
        }
        // micro-usb
        translate([-21.21, $boxl, $feeth + $boxh - 4.8]) 
            difference() {
                cube([8, 5+$wf, 3], center=true);
                translate([-5, 0, -1.5])
                rotate([0, -45, 0]) 
                cube([3, 6+$wf, 3], center=true);
                translate([5, 0, -1.5])
                rotate([0, 45, 0]) 
                cube([3, 6+$wf, 3], center=true);
            }

        translate([-39.5, $boxl - 3.5, $feeth + $boxh - 13.3]) 
            cube([11, 3.8, 13], center=true);
        translate([16.8, $boxl - 3.5, $feeth + $boxh - 11]) 
            cube([19, 3.8, 10], center=true);
    }
}

module corners($height = 0, $width = 0) {
    $r = 4;
    $h = $height - $r * 2;
    $w = $width - $r * 2;
    
    rotate([0, 90, 90]) 
        union() {
            translate([-$h / 2, -$w / 2, 0])
            difference() {
                cylinder(h=2.4, r=$r, center=true, $fn=100);
                cylinder(h=3, r=$r - 1, center=true, $fn=100);
                translate([0, 5, 0])
                    cube([20, 10, 3], center=true);
                translate([5, 0, 0])
                    cube([10, 20, 3], center=true);
            }
            translate([-$h / 2, $w / 2, 0])
            difference() {
                cylinder(h=2.4, r=$r, center=true, $fn=100);
                cylinder(h=3, r=$r - 1, center=true, $fn=100);
                translate([0, -5, 0])
                    cube([20, 10, 3], center=true);
                translate([5, 0, 0])
                    cube([10, 20, 3], center=true);
            }
            translate([$h / 2, -$w / 2, 0])
            difference() {
                cylinder(h=2.4, r=$r, center=true, $fn=100);
                cylinder(h=3, r=$r - 1, center=true, $fn=100);
                translate([0, 5, 0])
                    cube([20, 10, 3], center=true);
                translate([-5, 0, 0])
                    cube([10, 20, 3], center=true);
            }
            translate([$h / 2, $w / 2, 0])
            difference() {
                cylinder(h=2.4, r=$r, center=true, $fn=100);
                cylinder(h=3, r=$r - 1, center=true, $fn=100);
                translate([0, -5, 0])
                    cube([20, 10, 3], center=true);
                translate([-5, 0, 0])
                    cube([10, 20, 3], center=true);
            }
            translate([$h / 2 + $r - .5, 0, 0])
                cube([1, $w + .02, 2.4], center=true);
            translate([-($h / 2 + $r - .5), 0, 0])
                cube([1, $w + .02, 2.4], center=true);
            translate([0, $w / 2 + $r  - .5, 0])
                cube([$h + .02, 1, 2.4], center=true);
            translate([0, -($w / 2 + $r  - .5), 0])
                cube([$h + .02, 1, 2.4], center=true);
        }
}    

module hdd() {
    // vertical
    translate([37, $boxl / 2 + ($boxl - 53 - $w) / 2, $feeth + 7])
        cube([$w, 53, 13], center=true);
    difference() {
        // horizontal
        translate([$boxw / 2 - 12.5 - $w / 2, $boxl / 2 + ($boxl - 53 - $w) / 2, $feeth + 13])
            cube([25, 53, $w], center=true);
        // screw hole
        translate([61.72 / 2, $boxl - $w - 10, $feeth + 13.7])
            cylinder(h=10, r=1.85, center=true, $fn=20);
    }

    // vertical
    translate([-37, $boxl / 2 + ($boxl - 53 - $w) / 2, $feeth + 7])
        cube([$w, 53, 13], center=true);
    difference() {
        // horizontal
        translate([-($boxw / 2 - 12.5 - $w / 2), $boxl / 2 + ($boxl - 53 - $w) / 2, $feeth + 13])
            cube([25, 53, $w], center=true);
        // screw hole
        translate([-61.72 / 2, $boxl - $w - 10, $feeth + 13.7])
            cylinder(h=10, r=1.85, center=true, $fn=20);
    }
}

module box() {
    union() {  
        walls();            
        rails();            
        feet();
    }
}

module walls() {
    difference() {
        union() {          
            // front wall
            translate([0, $boxl - $wf / 2, $feeth + $boxh / 2])
                cube([$boxw, $wf, $boxh], center=true);
            // left wall
            translate([($boxw - $w) / 2, $boxl / 2, $feeth + $boxh / 2])
                cube([$w, $boxl, $boxh], center=true);
            // right wall
            translate([-($boxw - $w) / 2, $boxl / 2, $feeth + $boxh / 2])
                cube([$w, $boxl, $boxh], center=true);
        }

        // corners cuts
        translate([($boxw - $w) / 2 + 5, $boxl / 2, $feeth + $boxh + 0.6])
            rotate([0,45,0])
                cube([20, $boxl + 10, 15],center=true);
        translate([-(($boxw - $w) / 2 + 5), $boxl / 2, $feeth + $boxh + 0.6])
            rotate([0,-45,0])
                cube([20, $boxl + 10, 15],center=true);

        translate([0, 12, $feeth + $boxh - 15]) 
            rotate([0, 90, 0])
            cylinder(h=$boxw + 10, r=2.5, center=true, $fn=20);
        translate([0, 24, $feeth + $boxh - 15]) 
            rotate([0, 90, 0])
            cylinder(h=$boxw + 10, r=2.5, center=true, $fn=20);
        translate([0, 36, $feeth + $boxh - 15]) 
            rotate([0, 90, 0])
            cylinder(h=$boxw + 10, r=2.5, center=true, $fn=20);
        translate([0, 48, $feeth + $boxh - 15]) 
            rotate([0, 90, 0])
            cylinder(h=$boxw + 10, r=2.5, center=true, $fn=20);
    }

    // bottom wall
    difference() {
        translate([0, $boxl / 2, $feeth + $w / 2])
            cube([$boxw, $boxl, $w], center=true);

        // bottom cuts
        translate([0, $boxl / 2, $feeth + $w / 2])
            cube([3, 40, $w * 2], center=true);
        translate([10, $boxl / 2, $feeth + $w / 2])
            cube([3, 40, $w * 2], center=true);
        translate([-10, $boxl / 2, $feeth + $w / 2])
            cube([3, 40, $w * 2], center=true);
        translate([20, $boxl / 2, $feeth + $w / 2])
            cube([3, 40, $w * 2], center=true);
        translate([-20, $boxl / 2, $feeth + $w / 2])
            cube([3, 40, $w * 2], center=true);
        translate([30, $boxl / 2, $feeth + $w / 2])
            cube([3, 40, $w * 2], center=true);
        translate([-30, $boxl / 2, $feeth + $w / 2])
            cube([3, 40, $w * 2], center=true);
        translate([40, $boxl / 2, $feeth + $w / 2])
            cube([3, 40, $w * 2], center=true);
        translate([-40, $boxl / 2, $feeth + $w / 2])
            cube([3, 40, $w * 2], center=true);
    }
}

module rails() {
    translate([($boxw / 2  - $w) - ($hrailw - $w / 2) / 2, $boxl / 2, $feeth + $boxh-6.7])
        cube([$hrailw + $w / 2, $boxl - $w, $hrailh], center=true);
    translate([-(($boxw / 2  - $w) - ($hrailw - $w / 2) / 2), $boxl / 2, $feeth + $boxh-6.7])
        cube([$hrailw + $w / 2, $boxl - $w, $hrailh], center=true);
}

module feet() {
    $f = $feeth + $w / 2;
    
    difference() {
        translate([($boxw - $f * 2) / 2, $boxl - $w / 2, $f / 2])
        cube([$f * 2, $w, $f], center=true);

        translate([($boxw - $f) / 2 - 1.5 * $f, $boxl - $w / 2, 0])
            rotate([0, 45, 0])
        cube([$f * 2, $w * 2, $f * 2], center=true);
    }

    difference() {
        translate([-($boxw - $f * 2) / 2, $boxl - $w / 2, $f / 2])
        cube([$f * 2, $w, $f], center=true);

        translate([-($boxw - $f) / 2 + 1.5 * $f, $boxl - $w / 2, 0])
            rotate([0, 45, 0])
        cube([$f * 2, $w * 2, $f * 2], center=true);
    }

    difference() {
        translate([-($boxw - $w) / 2, $boxl - $f, $f / 2])
        cube([$w, $f * 2, $f], center=true);

        translate([-($boxw - $w) / 2, $boxl - $f / 2 - 1.5 * $f, 0])
            rotate([45, 0, 0])
        cube([$w * 2, $f * 2, $f * 2], center=true);
    }

    difference() {
        translate([($boxw - $w) / 2, $boxl - $f, $f / 2])
        cube([$w, $f * 2, $f], center=true);

        translate([($boxw - $w) / 2, $boxl - $f / 2 - 1.5 * $f, 0])
            rotate([45, 0, 0])
        cube([$w * 2, $f * 2, $f * 2], center=true);
    }
}

