include <heat_set_inserts.scad>

main_not_side = 0; // 0,1
plot = "full"; // [sideL|sideR|mid|roller|full]

base_len = main_not_side ? 180 : 60;
base_hight = 6;
base_width = main_not_side ? 50 : 45;

matt_thingness = 4;

roller_small_d = main_not_side ? 30 : 25;
roller_flansh_d = main_not_side ? 50 : 40;
roller_above_base = roller_flansh_d/2 + matt_thingness + 3;
roller_flansh_t = 3;
roller_side_tollerance = 0.5;

motor_shaft_d = 5;
motor_shaft_base_hole = 8.5;
motor_shaft_offCenter = 6;
motor_mount_sep = 31;

side_width = 50;
side_arch_r = 21;
side_arch_center_h = roller_above_base - 7;
side_mount_hole_sep = 35;
side_mount_hole_above_base = 1;
side_mount_hole_d = 4;
side_bearing_od = 10.1;

mid_arch_roler_cut_r = main_not_side ? 23 : 18;
mid_winch_flansh_space = roller_flansh_t + 1;
mid_winch_tollerance = 0.5;
mid_diagnal_ratio = 0.75;

// distance between left bottom of side and the center of the top arch
side_corner_to_archCenter = sqrt((side_width/2)^2 + side_arch_center_h^2);
// angle from center of arch between left bottom and trangent point
side_flat_a = acos(side_arch_r / side_corner_to_archCenter);
// angle from center of horizantal and trangent point
side_arch_trangent_a = side_flat_a - acos((side_width/2) / side_corner_to_archCenter);
// tangent point coordiates
side_flat_trangentPoint_x = (side_width/2) - (side_arch_r*cos(side_arch_trangent_a));
side_flat_trangentPoint_y = side_arch_center_h + (side_arch_r*sin(side_arch_trangent_a));

// mid top rounding
mid_topRounding_center_y = side_flat_trangentPoint_y*mid_diagnal_ratio;
mid_topRounding_side_x = side_flat_trangentPoint_x*mid_diagnal_ratio;
o = roller_above_base - mid_topRounding_center_y;
s = mid_arch_roler_cut_r;
mid_topRounding_inner_x = (side_width/2) - sqrt(pow(s, 2) - pow(o, 2));
mid_topRounding_d = mid_topRounding_inner_x - mid_topRounding_side_x;
mid_topRounding_center_x = mid_topRounding_side_x + mid_topRounding_d/2;

$fa=5;
$fs=0.1;

module motor_mount_2d(){
	union() {
		circle(d=motor_shaft_base_hole);
		translate([motor_mount_sep/2, -motor_shaft_offCenter])
			heatSetInsert_hole_2d_M4();
		translate([-(motor_mount_sep/2), -motor_shaft_offCenter])
			heatSetInsert_hole_2d_M4();
	}
}

module winch_side_2d(){
	difference() {
		union() {
			translate([side_width/2, side_arch_center_h]) 
				circle(r = side_arch_r);
			polygon(points = [
				[0, 0],
				[side_flat_trangentPoint_x, side_flat_trangentPoint_y],
				[side_width-side_flat_trangentPoint_x, side_flat_trangentPoint_y],
				[side_width, 0]
			]);
		}
		// translate([side_width/2, roller_above_base])
		// 	motor_mount_2d();
		translate([(side_width/2)-(side_mount_hole_sep/2), side_mount_hole_d/2 + side_mount_hole_above_base])
			heatSetInsert_hole_2d_M3();
		translate([(side_width/2)+(side_mount_hole_sep/2), side_mount_hole_d/2 + side_mount_hole_above_base])
			heatSetInsert_hole_2d_M3();
	}
}

module side_2d() {
	union() {
		translate([matt_thingness, base_hight]) {
			winch_side_2d();
			if (main_not_side)
			translate([base_len/2, 0])
				winch_side_2d();
		}
		square([base_len + 2*matt_thingness, base_hight]);
	}
}

module side_motor_2d() {
	difference() {
		side_2d();
		translate([matt_thingness+side_width/2, base_hight+roller_above_base])
			motor_mount_2d();
		translate([matt_thingness+base_len/2+side_width/2, base_hight+roller_above_base])
			motor_mount_2d();
	}
}

module side_bearing_2d() {
	difference() {
		side_2d();
		translate([matt_thingness+side_width/2, base_hight+roller_above_base])
			circle(r = side_bearing_od);
		translate([matt_thingness+base_len/2+side_width/2, base_hight+roller_above_base])
			circle(r = side_bearing_od);
	}
}

module mid_winch_2d() {
	difference() {
		union() {
			polygon(points = [
				[0, 0],
				[side_flat_trangentPoint_x*mid_diagnal_ratio, side_flat_trangentPoint_y*mid_diagnal_ratio],
				[side_width-side_flat_trangentPoint_x*mid_diagnal_ratio, side_flat_trangentPoint_y*mid_diagnal_ratio],
				[side_width, 0]
			]);
			translate([mid_topRounding_center_x, mid_topRounding_center_y])
				circle(d = mid_topRounding_d);
			translate([side_width-mid_topRounding_center_x, mid_topRounding_center_y])
				circle(d = mid_topRounding_d);
		}
		translate([side_width/2, roller_above_base])
			circle(r = mid_arch_roler_cut_r);
	}
}

module mid_3d() {
	mid_winch_width = base_width - mid_winch_flansh_space*2;
	difference() {
		union() {
			// base
			translate([0, 0, base_hight])
				cube([base_len+matt_thingness*2, base_width, matt_thingness]);
			translate([0, 0, 0]) 
				cube([matt_thingness, base_width, base_hight+matt_thingness]);
			translate([matt_thingness+base_len, 0, 0]) 
				cube([matt_thingness, base_width, base_hight+matt_thingness]);

			// winches
			translate([matt_thingness, mid_winch_width+mid_winch_flansh_space, base_hight])
			rotate([90, 0, 0])
			linear_extrude(mid_winch_width) {
				mid_winch_2d();
				if (main_not_side)
				translate([base_len/2, 0])
					mid_winch_2d();
			}

			// nibs over side
			winch_side_a_ratio = side_flat_trangentPoint_x / side_flat_trangentPoint_y;
			windh_side_mattThinkness_x = winch_side_a_ratio * matt_thingness;
			translate([0, base_width+matt_thingness, base_hight])
			rotate([90, 0, 0])
			linear_extrude(base_width+matt_thingness*2) {
				polygon(points = [
					[0, 0],
					[matt_thingness-mid_winch_tollerance, 0],
					[matt_thingness-mid_winch_tollerance+windh_side_mattThinkness_x, matt_thingness],
					[0, matt_thingness]
				]);
				if (main_not_side)
				translate([matt_thingness+side_width+mid_winch_tollerance, 0]) 
					polygon(points = [
						[0, 0],
						[base_len/2-side_width-mid_winch_tollerance*2, 0],
						[base_len/2-side_width-mid_winch_tollerance*2+windh_side_mattThinkness_x, matt_thingness],
						[-windh_side_mattThinkness_x, matt_thingness],
					]);
				if (main_not_side)
				translate([matt_thingness+base_len/2+side_width+mid_winch_tollerance, 0]) 
					polygon(points = [
						[0, 0],
						[base_len/2-side_width-mid_winch_tollerance+matt_thingness, 0],
						[base_len/2-side_width-mid_winch_tollerance+matt_thingness, matt_thingness],
						[-windh_side_mattThinkness_x, matt_thingness],
					]);
				if (main_not_side == 0)
				translate([matt_thingness+side_width+mid_winch_tollerance, 0]) 
					polygon(points = [
						[0, 0],
						[base_len-side_width-mid_winch_tollerance+matt_thingness, 0],
						[base_len-side_width-mid_winch_tollerance+matt_thingness, matt_thingness],
						[-windh_side_mattThinkness_x, matt_thingness],
					]);
			}
		}
		translate([0, base_width*1.5, base_hight])
		rotate([90, 0, 0]) {
			translate([matt_thingness+(side_width/2)-(side_mount_hole_sep/2), side_mount_hole_d/2 + side_mount_hole_above_base])
				cylinder(h = base_width*2, d = side_mount_hole_d+0.0001);
			translate([matt_thingness+(side_width/2)+(side_mount_hole_sep/2), side_mount_hole_d/2 + side_mount_hole_above_base])
				cylinder(h = base_width*2, d = side_mount_hole_d+0.0001);
			if (main_not_side)
			translate([matt_thingness+base_len/2+(side_width/2)-(side_mount_hole_sep/2), side_mount_hole_d/2 + side_mount_hole_above_base])
				cylinder(h = base_width*2, d = side_mount_hole_d+0.0001);
			if (main_not_side)
			translate([matt_thingness+base_len/2+(side_width/2)+(side_mount_hole_sep/2), side_mount_hole_d/2 + side_mount_hole_above_base])
				cylinder(h = base_width*2, d = side_mount_hole_d+0.0001);
		}
	}
}

module side_right() {
	translate([0, -0.0001, -0.0001])
	rotate([90, 0, 0])
	linear_extrude(matt_thingness)
		side_motor_2d();
}

module side_left() {
	translate([0, base_width+matt_thingness+0.0001, -0.0001])
	rotate([90, 0, 0])
	linear_extrude(matt_thingness)
		side_bearing_2d();
}

module roller_3d() {
	union() {
		rotate([-90, 0, 0])
			cylinder(d = roller_small_d, h = base_width - roller_side_tollerance*2);
		rotate([-90, 0, 0])
			cylinder(d = roller_flansh_d, h = roller_flansh_t);
		translate([0, base_width - roller_side_tollerance*2-roller_flansh_t])
		rotate([-90, 0, 0])
			cylinder(d = roller_flansh_d, h = roller_flansh_t);
	}
}

module roller_front() {
	translate([matt_thingness + side_width/2, 0, base_hight+roller_above_base])
	translate([0, roller_side_tollerance])
		roller_3d();
}

module roller_back() {
	translate([matt_thingness + base_len/2 + side_width/2, 0, base_hight+roller_above_base])
	translate([0, roller_side_tollerance])
		roller_3d();
}

module full() {
	side_right();
	side_left();
	mid_3d();
	roller_front();
	if (main_not_side)
		roller_back();
}

if (plot == "full")
	full();
if (plot == "sideL")
	rotate([-90, 0, 0])
	translate([0, -base_width-matt_thingness-0.0001, +0.0001])
		side_left();
if (plot == "sideR")
	rotate([-90, 0, 0])
		side_right();
if (plot == "mid")
	translate([0, 0, -base_hight])
		mid_3d();
if (plot == "roller")
	rotate([90, 0, 0])
		roller_3d();



