use <validation/validate.scad> include <constants/all.scad>

module hole(h, d, d1, d2, bottom_r=0, top_chamfer=0, top_r=0) {

function apothem(d, n) = d / 2 / cos (180 / n);

input_top_d = d1 ? d1 : d;
input_bot_d = d2 ? d2 : d;

n = max(round(input_top_d * 2), 12, $fn);

bot_d = apothem(input_bot_d, n)*2;
top_d = apothem(input_top_d, n)*2;

$fn = n;
height = h + epsilon;
d = d ? d : d1;
translate([0,0,-h]) hull() difference() {

  cylinder(h = height, d1=bot_d, d2=top_d, $fn = n);
  if(bottom_r > 0) {
    validate(bot_d >= 2*bottom_r, "bottom_r must be less than  half x-dimension");
    rotate_extrude($fn=n) translate([d/2-bottom_r, 0]) {
      difference() {
        translate([0, -2*epsilon]) square(bottom_r+2*epsilon);
        translate([0, bottom_r]) circle(r=bottom_r);
      }
    }
  }
}

validate(top_chamfer == 0 || top_r == 0, "cannot both chamfer and round top of a hole");
if(top_chamfer > 0){
  translate([0,0,-top_chamfer]) {
    // FIXME: this hull() is a hack to get around $fn mismatch
    hull()
      rotate_extrude()
        translate([d/2-epsilon,0])
          polygon([[0,0], [0,top_chamfer+epsilon], [top_chamfer+epsilon, top_chamfer+epsilon]]);
  }
} else if(top_r > 0) {
  // FIXME: extract profile like we did on circular_fillet
  translate([0,0,-top_r])
    rotate_extrude()
      translate([d/2-epsilon,0])
        difference() {
          square(top_r+epsilon);
          translate([top_r+epsilon,0]) circle(r=top_r);
        }
}

}