
// the main shape of our wonderful device
#declare mainBodyShape = union {
	difference {
		box {
			<-mainWidth/2, -mainThick/2, mainHeight/2>, <mainWidth/2, mainThick/2, -mainHeight/2>
		}
		box {
			<-mainWidth, -mainThick, mainHeight>, <-mainWidth/2+mainEdgeRadius, -mainThick/2+mainEdgeRadius, -mainHeight>
		}
		box {
			<-mainWidth, mainThick, mainHeight>, <-mainWidth/2+mainEdgeRadius, mainThick/2-mainEdgeRadius, -mainHeight>
		}
		box {
			<mainWidth, -mainThick, mainHeight>, <mainWidth/2-mainEdgeRadius, -mainThick/2+mainEdgeRadius, -mainHeight>
		}
		box {
			<mainWidth, mainThick, mainHeight>, <mainWidth/2-mainEdgeRadius, mainThick/2-mainEdgeRadius, -mainHeight>
		}
		box {
			<-mainWidth, -mainThick, mainHeight>, <mainWidth, -mainThick/2+mainEdgeRadius, mainHeight/2-mainEdgeRadius>
		}
		box {
			<-mainWidth, mainThick, mainHeight>, <mainWidth, mainThick/2-mainEdgeRadius, mainHeight/2-mainEdgeRadius>
		}
		box {
			<-mainWidth, -mainThick, -mainHeight>, <mainWidth, -mainThick/2+mainEdgeRadius, -mainHeight/2+mainEdgeRadius>
		}
		box {
			<-mainWidth, mainThick, -mainHeight>, <mainWidth, mainThick/2-mainEdgeRadius, -mainHeight/2+mainEdgeRadius>
		}
		box {
			<-mainWidth,  -mainThick, -mainHeight>, <-mainWidth/2+mainEdgeRadius, mainThick, -mainHeight/2+mainEdgeRadius>
		}
		box {
			<mainWidth,  -mainThick, -mainHeight>, <mainWidth/2-mainEdgeRadius, mainThick, -mainHeight/2+mainEdgeRadius>
		}
		box {
			<-mainWidth,  -mainThick, mainHeight>, <-mainWidth/2+mainEdgeRadius, mainThick, mainHeight/2-mainEdgeRadius>
		}
		box {
			<mainWidth,  -mainThick, mainHeight>, <mainWidth/2-mainEdgeRadius, mainThick, mainHeight/2-mainEdgeRadius>
		}
	}
	cylinder {
		<-mainWidth/2+mainEdgeRadius, -mainThick/2+mainEdgeRadius, mainHeight/2-mainEdgeRadius>, <-mainWidth/2+mainEdgeRadius, -mainThick/2+mainEdgeRadius, -mainHeight/2+mainEdgeRadius>, mainEdgeRadius
	}
	cylinder {
		<-mainWidth/2+mainEdgeRadius, mainThick/2-mainEdgeRadius, mainHeight/2-mainEdgeRadius>, <-mainWidth/2+mainEdgeRadius, mainThick/2-mainEdgeRadius, -mainHeight/2+mainEdgeRadius>, mainEdgeRadius
	}
	cylinder {
		<mainWidth/2-mainEdgeRadius, -mainThick/2+mainEdgeRadius, mainHeight/2-mainEdgeRadius>, <mainWidth/2-mainEdgeRadius, -mainThick/2+mainEdgeRadius, -mainHeight/2+mainEdgeRadius>, mainEdgeRadius
	}
	cylinder {
		<mainWidth/2-mainEdgeRadius, mainThick/2-mainEdgeRadius, mainHeight/2-mainEdgeRadius>, <mainWidth/2-mainEdgeRadius, mainThick/2-mainEdgeRadius, -mainHeight/2+mainEdgeRadius>, mainEdgeRadius
	}
	cylinder {
		<-mainWidth/2+mainEdgeRadius, -mainThick/2+mainEdgeRadius, mainHeight/2-mainEdgeRadius>, <mainWidth/2-mainEdgeRadius, -mainThick/2+mainEdgeRadius, mainHeight/2-mainEdgeRadius>, mainEdgeRadius
	}
	cylinder {
		<-mainWidth/2+mainEdgeRadius, mainThick/2-mainEdgeRadius, mainHeight/2-mainEdgeRadius>, <mainWidth/2-mainEdgeRadius, mainThick/2-mainEdgeRadius, mainHeight/2-mainEdgeRadius>, mainEdgeRadius
	}
	cylinder {
		<-mainWidth/2+mainEdgeRadius, -mainThick/2+mainEdgeRadius, -mainHeight/2+mainEdgeRadius>, <mainWidth/2-mainEdgeRadius, -mainThick/2+mainEdgeRadius, -mainHeight/2+mainEdgeRadius>, mainEdgeRadius
	}
	cylinder {
		<-mainWidth/2+mainEdgeRadius, mainThick/2-mainEdgeRadius, -mainHeight/2+mainEdgeRadius>, <mainWidth/2-mainEdgeRadius, mainThick/2-mainEdgeRadius, -mainHeight/2+mainEdgeRadius>, mainEdgeRadius
	}
	cylinder {
		<-mainWidth/2+mainEdgeRadius, -mainThick/2+mainEdgeRadius, -mainHeight/2+mainEdgeRadius>, <-mainWidth/2+mainEdgeRadius, mainThick/2-mainEdgeRadius, -mainHeight/2+mainEdgeRadius>, mainEdgeRadius
	}
	cylinder {
		<mainWidth/2-mainEdgeRadius, -mainThick/2+mainEdgeRadius, -mainHeight/2+mainEdgeRadius>, <mainWidth/2-mainEdgeRadius, mainThick/2-mainEdgeRadius, -mainHeight/2+mainEdgeRadius>, mainEdgeRadius
	}
	cylinder {
		<-mainWidth/2+mainEdgeRadius, -mainThick/2+mainEdgeRadius, mainHeight/2-mainEdgeRadius>, <-mainWidth/2+mainEdgeRadius, mainThick/2-mainEdgeRadius, mainHeight/2-mainEdgeRadius>, mainEdgeRadius
	}
	cylinder {
		<mainWidth/2-mainEdgeRadius, -mainThick/2+mainEdgeRadius, mainHeight/2-mainEdgeRadius>, <mainWidth/2-mainEdgeRadius, mainThick/2-mainEdgeRadius, mainHeight/2-mainEdgeRadius>, mainEdgeRadius
	}
	sphere {
		<-mainWidth/2+mainEdgeRadius, -mainThick/2+mainEdgeRadius, -mainHeight/2+mainEdgeRadius>, mainEdgeRadius
	}
	sphere {
		<mainWidth/2-mainEdgeRadius, -mainThick/2+mainEdgeRadius, -mainHeight/2+mainEdgeRadius>, mainEdgeRadius
	}
	sphere {
		<-mainWidth/2+mainEdgeRadius, mainThick/2-mainEdgeRadius, -mainHeight/2+mainEdgeRadius>, mainEdgeRadius
	}
	sphere {
		<mainWidth/2-mainEdgeRadius, mainThick/2-mainEdgeRadius, -mainHeight/2+mainEdgeRadius>, mainEdgeRadius
	}
	sphere {
		<-mainWidth/2+mainEdgeRadius, -mainThick/2+mainEdgeRadius, mainHeight/2-mainEdgeRadius>, mainEdgeRadius
	}
	sphere {
		<mainWidth/2-mainEdgeRadius, -mainThick/2+mainEdgeRadius, mainHeight/2-mainEdgeRadius>, mainEdgeRadius
	}
	sphere {
		<-mainWidth/2+mainEdgeRadius, mainThick/2-mainEdgeRadius, mainHeight/2-mainEdgeRadius>, mainEdgeRadius
	}
	sphere {
		<mainWidth/2-mainEdgeRadius, mainThick/2-mainEdgeRadius, mainHeight/2-mainEdgeRadius>, mainEdgeRadius
	}
}

// the plastic part and the metal back part
#declare mainBody = union {
	difference {
		object {mainBodyShape
		}
		plane{ y, mainThick/2-plasticThickness }
		texture { mainBodyTexture }
	}
	difference {
		object {mainBodyShape
			scale <1-2*gapDepth/mainWidth, 0.9, 1-2*gapDepth/mainHeight>
		}
		plane {
			y, mainThick/2-plasticThickness-gapWidth-0.1
		}
		texture {mainBodyTexture}
	}
	difference {
		object{ mainBodyShape
			scale metalShrinkFactor
			texture { bodyMetal }
		}
		plane {
			-y, -(mainThick/2-plasticThickness-gapWidth)
		}
		cutaway_textures
	}
}

// cutting out the display
#local frameRad = frameWidth/(1-cos(pi/4));
#local temp = frameRad - frameWidth;
#local stampShape = merge{
		box {
			<-displayWidth/2-frameWidth, mainThick/2-displayDepth, -displayHeight/2+temp>, <displayWidth/2+frameWidth, mainThick, displayHeight/2-temp>
		}
		box {
			<-displayWidth/2+temp, mainThick/2-displayDepth, -displayHeight/2-frameWidth>, <displayWidth/2-temp, mainThick, displayHeight/2+frameWidth>
		}
		cylinder {
			<-displayWidth/2+temp, mainThick/2-displayDepth, -displayHeight/2+temp>, <-displayWidth/2+temp, mainThick, -displayHeight/2+temp>, frameRad
		}
		cylinder {
			<-displayWidth/2+temp, mainThick/2-displayDepth, displayHeight/2-temp>, <-displayWidth/2+temp, mainThick, displayHeight/2-temp>, frameRad
		}
		cylinder {
			<displayWidth/2-temp, mainThick/2-displayDepth, -displayHeight/2+temp>, <+displayWidth/2-temp, mainThick, -displayHeight/2+temp>, frameRad
		}
		cylinder {
			<displayWidth/2-temp, mainThick/2-displayDepth, displayHeight/2-temp>, <displayWidth/2-temp, mainThick, displayHeight/2-temp>, frameRad
		}
		
		// the edge gets extra treatment
		box {
			<-displayWidth/2-frameWidth-edgeRadius, mainThick/2-edgeRadius, -displayHeight/2+temp>, <displayWidth/2+frameWidth+edgeRadius, mainThick, displayHeight/2-temp>
		}
		box {
			<-displayWidth/2+temp, mainThick/2-edgeRadius, -displayHeight/2-frameWidth-edgeRadius>, <displayWidth/2-temp, mainThick, displayHeight/2+frameWidth+edgeRadius>
		}
		cylinder {
			<-displayWidth/2+temp, mainThick/2-edgeRadius, -displayHeight/2+temp>, <-displayWidth/2+temp, mainThick, -displayHeight/2+temp>, frameRad+edgeRadius
		}
		cylinder {
			<-displayWidth/2+temp, mainThick/2-edgeRadius, displayHeight/2-temp>, <-displayWidth/2+temp, mainThick, displayHeight/2-temp>, frameRad+edgeRadius
		}
		cylinder {
			<displayWidth/2-temp, mainThick/2-edgeRadius, -displayHeight/2+temp>, <+displayWidth/2-temp, mainThick, -displayHeight/2+temp>, frameRad+edgeRadius
		}
		cylinder {
			<displayWidth/2-temp, mainThick/2-edgeRadius, displayHeight/2-temp>, <displayWidth/2-temp, mainThick, displayHeight/2-temp>, frameRad+edgeRadius
		}
		texture { displayCutTexture}
}

#local roundedEdges = union {
	// straight parts
	cylinder {
		<-displayWidth/2+temp, mainThick/2-edgeRadius, -displayHeight/2-frameWidth-edgeRadius>, <displayWidth/2-temp, mainThick/2-edgeRadius, -displayHeight/2-frameWidth-edgeRadius>, edgeRadius
	}
	cylinder {
		<-displayWidth/2+temp, mainThick/2-edgeRadius, -(-displayHeight/2-frameWidth-edgeRadius)>, <displayWidth/2-temp, mainThick/2-edgeRadius, -(-displayHeight/2-frameWidth-edgeRadius)>, edgeRadius
	}
	cylinder {
		<-displayWidth/2-frameWidth-edgeRadius, mainThick/2-edgeRadius, -displayHeight/2+temp>, <-displayWidth/2-frameWidth-edgeRadius, mainThick/2-edgeRadius, displayHeight/2-temp>, edgeRadius
	}
	cylinder {
		<displayWidth/2+frameWidth+edgeRadius, mainThick/2-edgeRadius, -displayHeight/2+temp>, <displayWidth/2+frameWidth+edgeRadius, mainThick/2-edgeRadius, displayHeight/2-temp>, edgeRadius
	}
	// the round corners
	difference { 
		union {
			torus {
				frameRad+edgeRadius, edgeRadius
				translate <-displayWidth/2+temp, mainThick/2-edgeRadius, -displayHeight/2+temp>
			}
			torus {
				frameRad+edgeRadius, edgeRadius
				translate <displayWidth/2-temp, mainThick/2-edgeRadius, -displayHeight/2+temp>
			}
			torus {
				frameRad+edgeRadius, edgeRadius
				translate <-displayWidth/2+temp, mainThick/2-edgeRadius, displayHeight/2-temp>
			}
			torus {
				frameRad+edgeRadius, edgeRadius
				translate <displayWidth/2-temp, mainThick/2-edgeRadius, displayHeight/2-temp>
			}
		}
		box {
			<-mainWidth/2, mainThick/2-0.3, -displayHeight/2+temp>,  <mainWidth/2, mainThick/2+0.3, displayHeight/2-temp>
		}
		box {
			<-displayWidth/2+temp, mainThick/2-0.3, -mainHeight/2>,  <displayWidth/2-temp, mainThick/2+0.3, mainHeight/2>
		}
	}
	texture { mainBodyTexture }
}

// the display itself
#local lcDisplay = box {
	<-displayWidth/2, mainThick/2-displayDepth, -displayHeight/2>, <displayWidth/2, mainThick/2-(0.99*displayDepth), displayHeight/2>
}

// the glass of the display
#local displayGlass = difference {
	object { stampShape 
		translate y*1.1*edgeRadius
		scale <glassScaleFactor,1,glassScaleFactor>
	}
	box { <-mainWidth/2, mainThick/2, -mainHeight/2>, <mainWidth/2, mainThick+0.5, mainHeight/2> }
	box { <-mainWidth/2, mainThick/2-displayGlassThickness-0.3, -mainHeight/2>, <mainWidth/2, mainThick/2-displayGlassThickness, mainHeight/2> }
	hollow
	interior { ior 1.49}  // ior of PMMA is 1.49
	texture { displayGlassTexture }
}

#declare mainBody = union {
	difference {
		object { mainBody }
		object { stampShape
			translate <displayX, 0, displayZ>
		}
	}
	object { roundedEdges 
		translate <displayX, 0, displayZ>
	}
	object { lcDisplay 
		texture {lcDisplayTexture}
		translate <displayX, 0, displayZ>
	}
	object { displayGlass
		translate <displayX, 0, displayZ>
	}
}

// adding the touch pad
// for now we just take one button. to get the well known wheel uncomment the part below
#declare mainBody = union {
	difference {
		object { mainBody }
		cylinder {
			<touchpadX, mainThick/2-touchpadGapDepth, touchpadZ>, <touchpadX, mainThick, touchpadZ>, touchpadOuterRad-2*touchpadFrameRad
			texture { mainBodyTexture }
		}
		cylinder {
			<touchpadX, 0, touchpadZ>, <touchpadX, mainThick, touchpadZ>, touchpadOuterRad-2*touchpadFrameRad-touchpadGap
			texture { mainBodyTexture }
		}
	}
	difference {
		cylinder {
			<touchpadX, 0, touchpadZ>, <touchpadX, mainThick/2-touchpadIn, touchpadZ>, touchpadOuterRad-2*touchpadFrameRad-touchpadGap
		}
		sphere {
			#local concaveRadius = 0.5 * (touchpadConcave*touchpadConcave + touchpadOuterRad-2*touchpadFrameRad-touchpadGap)/touchpadConcave;
			<touchpadX, mainThick/2+concaveRadius-touchpadConcave-touchpadIn, touchpadZ>, concaveRadius
		}
		texture { touchpadTexture }
	}
	torus {
		touchpadOuterRad-touchpadFrameRad, touchpadFrameRad
		scale 0.5*y
		translate <touchpadX, mainThick/2, touchpadZ>
		texture {mainBodyTexture }
	}
}
/*
#declare mainBody = union {
	difference {
		object { mainBody }
		difference {
			cylinder {
				<touchpadX, mainThick/2-touchpadIn-touchpadGapDepth, touchpadZ>, <touchpadX, mainThick, touchpadZ>, touchpadOuterRad-2*touchpadFrameRad
			}
			cylinder {
				<touchpadX, 0, touchpadZ>, <touchpadX, mainThick/2+0.6, touchpadZ>, touchpadInnerRad+2*touchpadFrameRad
			}
			texture { mainBodyTexture }
		}
	}
	difference {
		cylinder {
			<touchpadX, 0, touchpadZ>, <touchpadX, mainThick/2-touchpadIn, touchpadZ>, touchpadOuterRad-2*touchpadFrameRad-touchpadGap
		}
		cylinder {
			<touchpadX, -0.1, touchpadZ>, <touchpadX, mainThick/2+0.6, touchpadZ>, touchpadInnerRad+2*touchpadFrameRad+touchpadGap
		}
		texture { touchpadTexture }
	}
	torus {
		touchpadOuterRad-touchpadFrameRad, touchpadFrameRad
		scale 0.5*y
		translate <touchpadX, mainThick/2, touchpadZ>
		texture {mainBodyTexture }
	}
	torus {
		touchpadInnerRad+touchpadFrameRad, touchpadFrameRad
		scale 0.5*y
		translate <touchpadX, mainThick/2, touchpadZ>
		texture {mainBodyTexture }
	}
}
*/


//designing the cylinder (external memory)
// it has 18 'tracks'. here come the positions of the pins, as <track, angle in degrees>

#local nippleNumber = 48;
#local nipple = array[nippleNumber]
#local nipple[0]  = < 1,   0>;
#local nipple[1]  = < 2,   8>;
#local nipple[2]  = < 3,   0>;
#local nipple[3]  = < 2, -22>;
#local nipple[4]  = < 3, -30>;
#local nipple[5]  = < 4, -72>;		// good with a guideElevation of 0.15
#local nipple[6]  = < 5,  20>;
#local nipple[7]  = < 6,  30>;
#local nipple[8]  = < 7, -72>;
#local nipple[9]  = < 8,  10>;
#local nipple[10] = < 9, -20>;
#local nipple[11] = <10,  30>;
#local nipple[12] = <11,   0>;
#local nipple[13] = <12, -10>;
#local nipple[14] = <13,  10>;
#local nipple[15] = <14, -30>;
#local nipple[16] = <15, -15>;
#local nipple[17] = <16, -76>;
#local nipple[18] = <17, -20>;
#local nipple[19] = <18,  10>;
#local nipple[20] = < 1, -65>;
#local nipple[21] = < 3, -65>;
#local nipple[22] = < 5,  45>;
#local nipple[23] = < 5,   0>;
#local nipple[24] = < 6, -17>;
#local nipple[25] = < 7,  -8>;
#local nipple[26] = < 8, -50>;
#local nipple[27] = < 9,  -4>;
#local nipple[28] = <10, -22>;
#local nipple[29] = < 4,  10>;
#local nipple[30] = < 4, -33>;
#local nipple[31] = <11, -65>;
#local nipple[32] = <12,  30>;
#local nipple[33] = <12, -52>;
#local nipple[34] = <13, -26>;
#local nipple[35] = < 5, -65>;
#local nipple[36] = <14,  33>;
#local nipple[37] = < 6, -50>;
#local nipple[38] = <18, -45>;
#local nipple[39] = <16, -52>;
#local nipple[40] = <14, -45>;
#local nipple[41] = <17,  41>;
#local nipple[42] = <16, -4>;
#local nipple[43] = <15,  50>;
#local nipple[44] = < 8, 54>;
#local nipple[45] = < 2, 35>;
#local nipple[46] = <11, 60>;
#local nipple[47] = <18, 70>;



#local cylinderOverallWidth = trackNumber*cylinderTrackWidth + 2*cylinderEndspace;
#local memoryCylinder = union{ 
	difference {
		cylinder {
			<-cylinderOverallWidth/2, 0, 0>, <cylinderOverallWidth/2, 0, 0>, cylinderRadius
		}
		cylinder {
			<-cylinderOverallWidth, 0, 0>, <cylinderOverallWidth, 0, 0>, cylinderRadius-cylinderMantleThick
		}
		// subtracting all the holes for the nipples
		#declare i=0;
		#while (i < nippleNumber)
			cylinder {
				<0, 0, 0>, <0, cylinderRadius+1, 0>, nippleBaseRad
				rotate x*nipple[i].v
				translate x* (-cylinderOverallWidth/2 + cylinderEndspace - cylinderTrackWidth/2  + nipple[i].u*cylinderTrackWidth)
			}
			#declare i=i+1;
		#end
		texture { cylinderOuterTexture }
	}
	
	// adding the nipples
		#declare i=0;
		#while (i < nippleNumber)
			cone {
				<0, 0, 0>, nippleBaseRad, <0, nippleLength+cylinderMantleThick, 0>, nippleTopRad
				translate y * (cylinderRadius-cylinderMantleThick)
				rotate x*nipple[i].v
				translate x* (-cylinderOverallWidth/2 + cylinderEndspace - cylinderTrackWidth/2  + nipple[i].u*cylinderTrackWidth)
				texture {nippleTexture}
			}
			#declare i=i+1;
		#end
	// at the end there are caps. One is a gear wheel
	cylinder {
		<-cylinderOverallWidth/2-endCapWidth/2, 0, 0>, <cylinderOverallWidth/2+endCapWidth/2, 0, 0>, cylinderRadius-endCapGapDepth
		texture { bodyMetal }
	}
	object {
		gearWheel(sprocketNumber, gearRadius, sprocketHeight, endCapWidth, sprocketRounding)
		texture { gearWheelTexture1 }
		translate <-(cylinderOverallWidth/2+endCapWidth/2+endCapGap),0,>
	}
	cylinder {
		<-(-cylinderOverallWidth/2-endCapWidth-endCapGap), 0, 0>, <-(-cylinderOverallWidth/2-endCapGap), 0, 0>, endCapRadius
		texture { bodyMetal }
	}
}


// and add an axis
#declare memoryCylinder = merge {
	object {memoryCylinder}
	cylinder {
		<-cylinderOverallWidth/2-endCapWidth-endCapGap-axisOuterLength, 0,0>, <-(-cylinderOverallWidth/2-endCapWidth-endCapGap-axisOuterLength), 0,0>, axisRadius
		texture { cylinderOuterTexture }
	}
}

// now let's cut out a part of the main body where we will place the cylinder.
// we try to do this whith a sophisticated stamp.
#declare cylinderGapStamp = difference {
	union {
		union {
			box {
				<-(cylinderGapWidth/2), -mainThick, mainHeight>, <cylinderGapWidth/2, mainThick, mainHeight/2-cylinderGapHeight+cylinderGapCornerRad>
			}
			box {
				<-cylinderGapWidth/2 + cylinderGapCornerRad, -mainThick, mainHeight>, 	<cylinderGapWidth/2-cylinderGapCornerRad, mainThick, mainHeight/2-cylinderGapHeight>
			}
			cylinder {
				<-(cylinderGapWidth/2-cylinderGapCornerRad),  -mainThick, mainHeight/2-cylinderGapHeight+cylinderGapCornerRad>, <-(cylinderGapWidth/2-cylinderGapCornerRad),  mainThick, mainHeight/2-cylinderGapHeight+cylinderGapCornerRad>, cylinderGapCornerRad
			}
			cylinder {
				<(cylinderGapWidth/2-cylinderGapCornerRad),  -mainThick, mainHeight/2-cylinderGapHeight+cylinderGapCornerRad>, <(cylinderGapWidth/2-cylinderGapCornerRad),  mainThick, mainHeight/2-cylinderGapHeight+cylinderGapCornerRad>, cylinderGapCornerRad
			}
		}
		difference {
			union {
				box {
					<-(cylinderGapWidth/2+cylinderGapEdgeRad), -mainThick, mainHeight>, <cylinderGapWidth/2+cylinderGapEdgeRad, mainThick, mainHeight/2-cylinderGapHeight+cylinderGapCornerRad-cylinderGapEdgeRad>
				}
				box {
					<-cylinderGapWidth/2 + cylinderGapCornerRad-cylinderGapEdgeRad, -mainThick, mainHeight>, 	<cylinderGapWidth/2-cylinderGapCornerRad+cylinderGapEdgeRad, mainThick, mainHeight/2-cylinderGapHeight-cylinderGapEdgeRad>
				}
				cylinder {
					<-(cylinderGapWidth/2-cylinderGapCornerRad),  -mainThick, mainHeight/2-cylinderGapHeight+cylinderGapCornerRad>, <-(cylinderGapWidth/2-cylinderGapCornerRad),  mainThick, mainHeight/2-cylinderGapHeight+cylinderGapCornerRad>, cylinderGapCornerRad+cylinderGapEdgeRad
				}
				cylinder {
					<(cylinderGapWidth/2-cylinderGapCornerRad),  -mainThick, mainHeight/2-cylinderGapHeight+cylinderGapCornerRad>, <(cylinderGapWidth/2-cylinderGapCornerRad),  mainThick, mainHeight/2-cylinderGapHeight+cylinderGapCornerRad>, cylinderGapCornerRad+cylinderGapEdgeRad
				}
			}
			box {
				<-mainWidth, -mainThick/2+cylinderGapEdgeRad, -mainHeight>, <mainWidth, mainThick/2-cylinderGapEdgeRad, mainHeight>
			}
		}
	}
	cylinder {
		<-(cylinderGapWidth/2+cylinderGapEdgeRad), mainThick/2-cylinderGapEdgeRad, mainHeight/2-cylinderGapHeight+cylinderGapCornerRad>, <-(cylinderGapWidth/2+cylinderGapEdgeRad), mainThick/2-cylinderGapEdgeRad, mainHeight>, cylinderGapEdgeRad	
	}
	cylinder {
		<(cylinderGapWidth/2+cylinderGapEdgeRad), mainThick/2-cylinderGapEdgeRad, mainHeight/2-cylinderGapHeight+cylinderGapCornerRad>, <(cylinderGapWidth/2+cylinderGapEdgeRad), mainThick/2-cylinderGapEdgeRad, mainHeight>, cylinderGapEdgeRad	
	}
	cylinder {
		<-(cylinderGapWidth/2-cylinderGapCornerRad),mainThick/2-cylinderGapEdgeRad, mainHeight/2-cylinderGapHeight-cylinderGapEdgeRad>, <(cylinderGapWidth/2-cylinderGapCornerRad),mainThick/2-cylinderGapEdgeRad, mainHeight/2-cylinderGapHeight-cylinderGapEdgeRad>, cylinderGapEdgeRad
	}
	difference {
		union{
			torus {
				cylinderGapCornerRad+cylinderGapEdgeRad, cylinderGapEdgeRad
				translate <-(cylinderGapWidth/2-cylinderGapCornerRad), mainThick/2-cylinderGapEdgeRad, mainHeight/2-cylinderGapHeight+cylinderGapCornerRad>
			}
			torus {
				cylinderGapCornerRad+cylinderGapEdgeRad, cylinderGapEdgeRad
				translate <(cylinderGapWidth/2-cylinderGapCornerRad),  mainThick/2-cylinderGapEdgeRad, mainHeight/2-cylinderGapHeight+cylinderGapCornerRad>
			}
		}
		box {
			<-mainWidth/2, -mainThick/2, mainHeight/2-cylinderGapHeight+cylinderGapCornerRad>, <mainWidth/2, mainThick/2+1, mainHeight>
		}
		box {
			<-(cylinderGapWidth/2-cylinderGapCornerRad), -mainThick/2, -mainHeight/2>, <(cylinderGapWidth/2-cylinderGapCornerRad), mainThick/2+1, mainHeight>
		}
	}

	difference {
		union{
			torus {
				cylinderGapCornerRad+cylinderGapEdgeRad, cylinderGapEdgeRad
				translate <-(cylinderGapWidth/2-cylinderGapCornerRad), -(mainThick/2-cylinderGapEdgeRad), mainHeight/2-cylinderGapHeight+cylinderGapCornerRad>
			}
			torus {
				cylinderGapCornerRad+cylinderGapEdgeRad, cylinderGapEdgeRad
				translate <(cylinderGapWidth/2-cylinderGapCornerRad),  -(mainThick/2-cylinderGapEdgeRad), mainHeight/2-cylinderGapHeight+cylinderGapCornerRad>
			}
		}
		box {
			<-mainWidth/2, -mainThick, mainHeight/2-cylinderGapHeight+cylinderGapCornerRad>, <mainWidth/2, 0, mainHeight>
		}
		box {
			<-(cylinderGapWidth/2-cylinderGapCornerRad), -mainThick, -mainHeight/2>, <(cylinderGapWidth/2-cylinderGapCornerRad), 0, mainHeight>
		}
	}
	cylinder {
		<-(cylinderGapWidth/2+cylinderGapEdgeRad), -mainThick/2+cylinderGapEdgeRad, mainHeight/2-cylinderGapHeight+cylinderGapCornerRad>, <-(cylinderGapWidth/2+cylinderGapEdgeRad), -mainThick/2+cylinderGapEdgeRad, mainHeight/2>, cylinderGapEdgeRad	
	}
	cylinder {
		<(cylinderGapWidth/2+cylinderGapEdgeRad), -mainThick/2+cylinderGapEdgeRad, mainHeight/2-cylinderGapHeight+cylinderGapCornerRad>, <(cylinderGapWidth/2+cylinderGapEdgeRad), -mainThick/2+cylinderGapEdgeRad, mainHeight/2>, cylinderGapEdgeRad	
	}
	cylinder {
		<-(cylinderGapWidth/2-cylinderGapCornerRad),-mainThick/2+cylinderGapEdgeRad, mainHeight/2-cylinderGapHeight-cylinderGapEdgeRad>, <(cylinderGapWidth/2-cylinderGapCornerRad),-mainThick/2+cylinderGapEdgeRad, mainHeight/2-cylinderGapHeight-cylinderGapEdgeRad>, cylinderGapEdgeRad
	}
	texture { mainBodyTexture }
}

#declare cylinderGapStamp = union {
	difference {
		object { cylinderGapStamp }
		box { <-mainWidth/2, -mainThick, -mainHeight/2>, <mainWidth/2, -mainThick/2+cylinderGapStepY, mainHeight>}
	}
	difference {
		object { cylinderGapStamp 
			translate <0,0, cylinderGapHeight-cylinderGapHeightLow>
		}
		box { <-mainWidth/2, -mainThick/2+cylinderGapStepY+0.0001, -mainHeight/2>, <mainWidth/2, mainThick, mainHeight>}
		
	}
	texture { mainBodyTexture }

}

#declare mainBody = difference {
	object {mainBody}
	object { cylinderGapStamp 
		translate x*cylinderGapX
	}
	cylinder {
		<-(cylinderGapWidth/2), gw2AxisY, gw2AxisZ>,<-(trackNumber/2*cylinderTrackWidth+endCapWidth), gw2AxisY, gw2AxisZ>, gw3radius+gw3sprocketHeight+0.05
	}
	cutaway_textures
}



// buiding up the music part of it all
// we need to do some calculations for that later,
// namely the bending radius for each guide
// trackNumber is set elsewhere. set the height of each nipple to which it is elevated
#local guideElevation = array[trackNumber];
#local guideElevation[0]  = 0;
#local guideElevation[1]  = 0;
#local guideElevation[2]  = 0;
#local guideElevation[3]  = 0.15;
#local guideElevation[4]  = 0;
#local guideElevation[5]  = 0;
#local guideElevation[6]  = 0.15;
#local guideElevation[7]  = 0;
#local guideElevation[8]  = 0;
#local guideElevation[9]  = 0;
#local guideElevation[10] = 0;
#local guideElevation[11] = 0;
#local guideElevation[12] = 0;
#local guideElevation[13] = 0;
#local guideElevation[14] = 0;
#local guideElevation[15] = 0.1;
#local guideElevation[16] = 0;
#local guideElevation[17] = 0;				// so we assumed a trackNumber of 18

// the endcap of all guides for nicer endings of those things, this is a high quality product!!
#declare guideEnd = union {
	box {
		<-guideWidth/2+guideEdgeRad, 0, 0> ,<guideWidth/2-guideEdgeRad, guideThick-guideEdgeRad, guideEdgeRad>
	}
	cylinder {
		<-guideWidth/2+guideEdgeRad, 0, 0>, <-guideWidth/2+guideEdgeRad, guideThick-guideEdgeRad, 0>, guideEdgeRad
	}
	cylinder {
		<guideWidth/2-guideEdgeRad, 0, 0>, <guideWidth/2-guideEdgeRad, guideThick-guideEdgeRad, 0>, guideEdgeRad
	}
	sphere {
		<-guideWidth/2+guideEdgeRad, guideThick-guideEdgeRad, 0>, guideEdgeRad
	}
	sphere {
		<guideWidth/2-guideEdgeRad, guideThick-guideEdgeRad, 0>, guideEdgeRad
	}
	cylinder {
		<-guideWidth/2+guideEdgeRad, guideThick-guideEdgeRad, 0>, <guideWidth/2-guideEdgeRad, guideThick-guideEdgeRad, 0>, guideEdgeRad
	}
}



#local guideLength = array[trackNumber];
#local guide      = array[trackNumber];

#declare i=0;
#while (i < trackNumber)
	#local guideLength[i]  = visibleGuideMax - guideEdgeRad - (visibleGuideMax - visibleGuideMin)/(nippleNumber-1) * i;
	// guideElevation of 0 means no bending
	#if (guideElevation[i] = 0)  // the unbended guides
		#declare guide[i] = union {
			box {
				<-guideWidth/2, 0, -negOffset> ,<guideWidth/2, guideThick-guideEdgeRad, guideLength[i]>
			}
			box {
				<-guideWidth/2+guideEdgeRad, 0, -negOffset> ,<guideWidth/2-guideEdgeRad, guideThick, guideLength[i]>
			}
			cylinder {
				<-guideWidth/2+guideEdgeRad, guideThick-guideEdgeRad, -negOffset>, <-guideWidth/2+guideEdgeRad, guideThick-guideEdgeRad, guideLength[i]>, guideEdgeRad
			}
			cylinder {
				<guideWidth/2-guideEdgeRad, guideThick-guideEdgeRad, -negOffset>, <guideWidth/2-guideEdgeRad, guideThick-guideEdgeRad, guideLength[i]>, guideEdgeRad
			}
			object {
				guideEnd
				translate z*guideLength[i]
			}
			texture {guideTexture}
		}
	#else	// if the guide is bended
		#local bendingRadius = 0.5* (guideElevation[i]*guideElevation[i] + guideLength[i]*guideLength[i])/(guideElevation[i]);
		#local bendingAngle = atan(guideLength[i]/(bendingRadius-guideElevation[i])) * 180/pi;
		
		#declare guide[i] = union {
			box {
				<-guideWidth/2, 0, -negOffset> ,<guideWidth/2, guideThick, 0>   // did not bother to implement edge rounding here
			}
			difference {
				union {
					difference {
						cylinder {
							<-guideWidth/2, bendingRadius, 0> ,<guideWidth/2, bendingRadius, 0>, bendingRadius
						}
						cylinder {
							<-guideWidth/2-1, bendingRadius, 0> ,<guideWidth/2+1, bendingRadius, 0>, bendingRadius-guideThick+guideEdgeRad
						}
					}
					difference {
						cylinder {
							<-guideWidth/2+guideEdgeRad, bendingRadius, 0> ,<guideWidth/2-guideEdgeRad, bendingRadius, 0>, bendingRadius
						}
						cylinder {
							<-guideWidth/2-1, bendingRadius, 0> ,<guideWidth/2+1, bendingRadius, 0>, bendingRadius-guideThick
						}
					}
					torus {
						bendingRadius-guideThick+guideEdgeRad, guideEdgeRad
						rotate z*90
						translate <(-guideWidth/2+guideEdgeRad), bendingRadius, 0>
					}
					torus {
						bendingRadius-guideThick+guideEdgeRad, guideEdgeRad
						rotate z*90
						translate <-(-guideWidth/2+guideEdgeRad), bendingRadius, 0>
					}
				}
				box {
					<-1, -2*bendingRadius-2, -2*bendingRadius-2>, <1, 2*bendingRadius+2,0>
				}
				box {
					<-1, -2*bendingRadius-2, 0>, <1, 2*bendingRadius+2, 2*bendingRadius+2>
					rotate -x*bendingAngle
					translate y*bendingRadius
				}
			}
			object {
				guideEnd
				translate -y*bendingRadius
				rotate -x*bendingAngle
				translate y*bendingRadius
			}
			texture {guideTexture}
		}
	
	#end
	#declare i=i+1;
#end


// the guides are placed relative to the cylinder
#declare musicBox = union {
	object { memoryCylinder 
		translate z*(visibleGuideMax+guideToCylinder+cylinderRadius)
	}
	#declare i=0;
	#while (i < trackNumber)
		object {
			guide[i]
			translate <-((trackNumber-1)*cylinderTrackWidth/2) + i*cylinderTrackWidth, guidesY, (visibleGuideMax - visibleGuideMin)/(nippleNumber-1) * i>			
		}
		#declare i=i+1;
	#end
	translate z*(mainHeight/2 - (visibleGuideMax+guideToCylinder+2*cylinderRadius))
	translate x*cylinderGapX
}

// now we model the plastic cover of the music box part
// therefore we first build a part that covers the whole gap and then
// cut out wat should be left out. For this cutting we will use a stamp
// like for the gap, but we will transform it to get the non orthogonal edges

// the part that covers the whole gap:
#declare plasticCover = union {
	cylinder {
		<-(cylinderGapWidth/2-gapToBody-cylinderGapEdgeRad), mainThick/2-mainEdgeRadius, mainHeight/2-mainEdgeRadius>,<(cylinderGapWidth/2-gapToBody-cylinderGapEdgeRad), mainThick/2-mainEdgeRadius, mainHeight/2-mainEdgeRadius>, mainEdgeRadius
		translate x*cylinderGapX
		texture {mainBodyTexture}
	}
	cylinder {
		<-(cylinderGapWidth/2-gapToBody-cylinderGapEdgeRad), -mainThick/2+mainEdgeRadius, mainHeight/2-mainEdgeRadius>,<(cylinderGapWidth/2-gapToBody-cylinderGapEdgeRad), -mainThick/2+mainEdgeRadius, mainHeight/2-mainEdgeRadius>, mainEdgeRadius
		translate x*cylinderGapX
		texture {mainBodyTexture}
	}
	box {
		<-(cylinderGapWidth/2-gapToBody-cylinderGapEdgeRad), -mainThick/2+mainEdgeRadius, mainHeight/2>, <(cylinderGapWidth/2-gapToBody-cylinderGapEdgeRad) , mainThick/2-mainEdgeRadius, mainHeight/2-2*mainEdgeRadius>
		texture {mainBodyTexture}
	}
	torus {
		mainEdgeRadius-cylinderGapEdgeRad, cylinderGapEdgeRad
		rotate 90*z
		translate <(  (cylinderGapWidth/2-gapToBody-cylinderGapEdgeRad)    +cylinderGapX),mainThick/2-mainEdgeRadius ,mainHeight/2-mainEdgeRadius>
		texture {mainBodyTexture}
	}
	torus {
		mainEdgeRadius-cylinderGapEdgeRad, cylinderGapEdgeRad
		rotate 90*z
		translate <( -(cylinderGapWidth/2-gapToBody-cylinderGapEdgeRad)    +cylinderGapX),mainThick/2-mainEdgeRadius ,mainHeight/2-mainEdgeRadius>
		texture {mainBodyTexture}
	}
	difference {
		union {
			box {
				<-(cylinderGapWidth/2-gapToBody), cylinderGapStepY-mainThick/2, mainHeight/2-cylinderGapHeight>,<cylinderGapWidth/2-gapToBody , mainThick/2-cylinderGapEdgeRad, mainHeight/2-mainEdgeRadius>
				texture { mainBodyTexture }
			}
			box {
				<-(cylinderGapWidth/2-gapToBody-cylinderGapEdgeRad), cylinderGapStepY-mainThick/2, mainHeight/2-cylinderGapHeight+cylinderGapCornerRad>,<cylinderGapWidth/2-gapToBody-cylinderGapEdgeRad , mainThick/2, mainHeight/2-mainEdgeRadius>
				texture { mainBodyTexture }
			}
			box {
				<-(cylinderGapWidth/2-cylinderGapCornerRad), cylinderGapStepY-mainThick/2, mainHeight/2-cylinderGapHeight+cylinderGapEdgeRad+gapToBody>, <(cylinderGapWidth/2-cylinderGapCornerRad), mainThick/2, mainHeight/2-mainEdgeRadius>
				texture { mainBodyTexture }
			}
			cylinder {
				< (cylinderGapWidth/2-cylinderGapCornerRad), cylinderGapStepY-mainThick/2, mainHeight/2-cylinderGapHeight+cylinderGapCornerRad>, <(cylinderGapWidth/2-cylinderGapCornerRad), mainThick/2, mainHeight/2-cylinderGapHeight+cylinderGapCornerRad>, cylinderGapCornerRad-gapToBody-cylinderGapEdgeRad
				texture { mainBodyTexture }
			}
			cylinder {
				<-(cylinderGapWidth/2-cylinderGapCornerRad), cylinderGapStepY-mainThick/2, mainHeight/2-cylinderGapHeight+cylinderGapCornerRad>, <-(cylinderGapWidth/2-cylinderGapCornerRad), mainThick/2, mainHeight/2-cylinderGapHeight+cylinderGapCornerRad>, cylinderGapCornerRad-gapToBody-cylinderGapEdgeRad
				texture { mainBodyTexture }
			}
			cylinder {
				<-(cylinderGapWidth/2-cylinderGapCornerRad), mainThick/2-cylinderGapEdgeRad, mainHeight/2-cylinderGapHeight+cylinderGapEdgeRad+gapToBody>, <(cylinderGapWidth/2-cylinderGapCornerRad), mainThick/2-cylinderGapEdgeRad, mainHeight/2-cylinderGapHeight+cylinderGapEdgeRad+gapToBody>, cylinderGapEdgeRad
				texture { mainBodyTexture }
			}
			cylinder {
				<(cylinderGapWidth/2-cylinderGapEdgeRad-gapToBody), mainThick/2-cylinderGapEdgeRad, mainHeight/2-cylinderGapHeight+cylinderGapCornerRad>, <(cylinderGapWidth/2-cylinderGapEdgeRad-gapToBody), mainThick/2-cylinderGapEdgeRad, mainHeight/2-mainEdgeRadius>, cylinderGapEdgeRad
				texture { mainBodyTexture }
			}
			cylinder {
				<-(cylinderGapWidth/2-cylinderGapEdgeRad-gapToBody), mainThick/2-cylinderGapEdgeRad, mainHeight/2-cylinderGapHeight+cylinderGapCornerRad>, <-(cylinderGapWidth/2-cylinderGapEdgeRad-gapToBody), mainThick/2-cylinderGapEdgeRad, mainHeight/2-mainEdgeRadius>, cylinderGapEdgeRad
				texture { mainBodyTexture }
			}
			torus {
				cylinderGapCornerRad-gapToBody-cylinderGapEdgeRad, cylinderGapEdgeRad
				translate <-(cylinderGapWidth/2-cylinderGapCornerRad), mainThick/2-cylinderGapEdgeRad, mainHeight/2-cylinderGapHeight+cylinderGapCornerRad>
				texture { mainBodyTexture }
			}
			torus {
				cylinderGapCornerRad-gapToBody-cylinderGapEdgeRad, cylinderGapEdgeRad
				translate <(cylinderGapWidth/2-cylinderGapCornerRad), mainThick/2-cylinderGapEdgeRad, mainHeight/2-cylinderGapHeight+cylinderGapCornerRad>
				texture { mainBodyTexture }
			}
		}
		box {
			<-(trackNumber/2 * cylinderTrackWidth), -mainThick/2, mainHeight/2-cylinderGapHeight+cylinderGapCornerRad>,<trackNumber/2 * cylinderTrackWidth, guidesY+guideThick, mainThick>
			texture { mainBodyTexture }
		}
	}
	translate x*cylinderGapX
}


//the stamp to cut out something
#declare coverStamp = difference {
	union {
		union {
			box {
				<-(coverGapWidth/2), -mainThick, mainHeight>, <coverGapWidth/2, mainThick, mainHeight/2-cylinderGapHeight+coverGapZOffset+coverGapCornerRad>
			}
			box {
				<-coverGapWidth/2 + coverGapCornerRad, -mainThick, mainHeight>, 	<coverGapWidth/2-coverGapCornerRad, mainThick, mainHeight/2-cylinderGapHeight+coverGapZOffset>
			}
			cylinder {
				<-(coverGapWidth/2-coverGapCornerRad),  -mainThick, mainHeight/2-cylinderGapHeight+coverGapZOffset+coverGapCornerRad>, <-(coverGapWidth/2-coverGapCornerRad),  mainThick, mainHeight/2-cylinderGapHeight+coverGapZOffset+coverGapCornerRad>, coverGapCornerRad
			}
			cylinder {
				<(coverGapWidth/2-coverGapCornerRad),  -mainThick, mainHeight/2-cylinderGapHeight+coverGapZOffset+coverGapCornerRad>, <(coverGapWidth/2-coverGapCornerRad),  mainThick, mainHeight/2-cylinderGapHeight+coverGapZOffset+coverGapCornerRad>, coverGapCornerRad
			}
		}
		difference {
			union {
				box {
					<-(coverGapWidth/2+coverGapEdgeRad), -mainThick, mainHeight>, <coverGapWidth/2+coverGapEdgeRad, mainThick, mainHeight/2-cylinderGapHeight+coverGapZOffset+coverGapCornerRad>
				}
				box {
					<-coverGapWidth/2 + coverGapCornerRad, -mainThick, mainHeight>, 	<coverGapWidth/2-coverGapCornerRad, mainThick, mainHeight/2-cylinderGapHeight+coverGapZOffset-coverGapEdgeRad>
				}
				cylinder {
					<-(coverGapWidth/2-coverGapCornerRad),  -mainThick, mainHeight/2-cylinderGapHeight+coverGapZOffset+coverGapCornerRad>, <-(coverGapWidth/2-coverGapCornerRad),  mainThick, mainHeight/2-cylinderGapHeight+coverGapZOffset+coverGapCornerRad>, coverGapCornerRad+coverGapEdgeRad
				}
				cylinder {
					<(coverGapWidth/2-coverGapCornerRad),  -mainThick, mainHeight/2-cylinderGapHeight+coverGapZOffset+coverGapCornerRad>, <(coverGapWidth/2-coverGapCornerRad),  mainThick, mainHeight/2-cylinderGapHeight+coverGapZOffset+coverGapCornerRad>, coverGapCornerRad+coverGapEdgeRad
				}
			}
			box {
				<-mainWidth, cylinderGapStepY-mainThick/2+coverGapEdgeRad, -mainHeight>, <mainWidth, mainThick/2-coverGapEdgeRad, mainHeight>
			}
		}
		
	}
	cylinder {
		<-(coverGapWidth/2+coverGapEdgeRad), mainThick/2-coverGapEdgeRad, mainHeight/2-cylinderGapHeight+coverGapZOffset+coverGapCornerRad>, <-(coverGapWidth/2+coverGapEdgeRad), mainThick/2-coverGapEdgeRad, mainHeight>, coverGapEdgeRad	
	}
	cylinder {
		<(coverGapWidth/2+coverGapEdgeRad), mainThick/2-coverGapEdgeRad, mainHeight/2-cylinderGapHeight+coverGapZOffset+coverGapCornerRad>, <(coverGapWidth/2+coverGapEdgeRad), mainThick/2-coverGapEdgeRad, mainHeight>, coverGapEdgeRad	
	}
	cylinder {
		<-(coverGapWidth/2-coverGapCornerRad),mainThick/2-coverGapEdgeRad, mainHeight/2-cylinderGapHeight+coverGapZOffset-coverGapEdgeRad>, <(coverGapWidth/2-coverGapCornerRad),mainThick/2-coverGapEdgeRad, mainHeight/2-cylinderGapHeight+coverGapZOffset-coverGapEdgeRad>, coverGapEdgeRad
	}
	difference {
		union{
			torus {
				coverGapCornerRad+coverGapEdgeRad, coverGapEdgeRad
				translate <-(coverGapWidth/2-coverGapCornerRad), mainThick/2-coverGapEdgeRad, mainHeight/2-cylinderGapHeight+coverGapZOffset+coverGapCornerRad>
			}
			torus {
				coverGapCornerRad+coverGapEdgeRad, coverGapEdgeRad
				translate <(coverGapWidth/2-coverGapCornerRad),  mainThick/2-coverGapEdgeRad, mainHeight/2-cylinderGapHeight+coverGapZOffset+coverGapCornerRad>
			}
		}
		box {
			<-mainWidth/2, cylinderGapStepY-mainThick/2, mainHeight/2-cylinderGapHeight+coverGapZOffset+coverGapCornerRad>, <mainWidth/2, mainThick/2+1, mainHeight>
		}
		box {
			<-(coverGapWidth/2-coverGapCornerRad), cylinderGapStepY-mainThick/2, -mainHeight/2>, <(coverGapWidth/2-coverGapCornerRad), mainThick/2+1, mainHeight>
		}
	}

	difference {
		union{
			torus {
				coverGapCornerRad+coverGapEdgeRad, coverGapEdgeRad
				translate <-(coverGapWidth/2-coverGapCornerRad), cylinderGapStepY-(mainThick/2-coverGapEdgeRad), mainHeight/2-cylinderGapHeight+coverGapZOffset+coverGapCornerRad>
			}
			torus {
				coverGapCornerRad+coverGapEdgeRad, coverGapEdgeRad
				translate <(coverGapWidth/2-coverGapCornerRad),  cylinderGapStepY-(mainThick/2-coverGapEdgeRad), mainHeight/2-cylinderGapHeight+coverGapZOffset+coverGapCornerRad>
			}
		}
		box {
			<-mainWidth/2, -mainThick, mainHeight/2-cylinderGapHeight+coverGapZOffset+coverGapCornerRad>, <mainWidth/2, mainThick, mainHeight>
		}
		box {
			<-(coverGapWidth/2-coverGapCornerRad), -mainThick, -mainHeight/2>, <(coverGapWidth/2-coverGapCornerRad), mainThick, mainHeight>
		}
	}
	cylinder {
		<-(coverGapWidth/2+coverGapEdgeRad), cylinderGapStepY-mainThick/2+coverGapEdgeRad, mainHeight/2-cylinderGapHeight+coverGapZOffset+coverGapCornerRad>, <-(coverGapWidth/2+coverGapEdgeRad), cylinderGapStepY-mainThick/2+coverGapEdgeRad, mainHeight/2-mainEdgeRadius>, coverGapEdgeRad	
	}
	cylinder {
		<(coverGapWidth/2+coverGapEdgeRad), cylinderGapStepY-mainThick/2+coverGapEdgeRad, mainHeight/2-cylinderGapHeight+coverGapZOffset+coverGapCornerRad>, <(coverGapWidth/2+coverGapEdgeRad), cylinderGapStepY-mainThick/2+coverGapEdgeRad, mainHeight/2-mainEdgeRadius>, coverGapEdgeRad	
	}
	cylinder {
		<-(coverGapWidth/2-coverGapCornerRad),cylinderGapStepY-mainThick/2+coverGapEdgeRad, mainHeight/2-cylinderGapHeight+coverGapZOffset-coverGapEdgeRad>, <(coverGapWidth/2-coverGapCornerRad),cylinderGapStepY-mainThick/2+coverGapEdgeRad, mainHeight/2-cylinderGapHeight+coverGapZOffset-coverGapEdgeRad>, coverGapEdgeRad
	}

	texture { mainBodyTexture }
}


#declare plasticCover = union{
	difference {
		object {plasticCover}
		object {coverStamp
			matrix <	1, 0, (visibleGuideMax-visibleGuideMin)/(trackNumber*cylinderTrackWidth),
						0, 1, 0,
						0, 0, 1,
						0, 0, 0 >
		}
		box{
			<-(coverGapWidth/2+coverGapEdgeRad), -mainThick, mainHeight>, <(coverGapWidth/2+coverGapEdgeRad), mainThick, mainHeight/2-mainEdgeRadius>
		}
		cutaway_textures
	}
	intersection {
		box{
			<-(coverGapWidth/2+coverGapEdgeRad), -mainThick, mainHeight>, <(coverGapWidth/2+coverGapEdgeRad), mainThick, mainHeight/2-mainEdgeRadius>
		}
		union{
			cylinder {
				<-(coverGapWidth/2+coverGapEdgeRad), mainThick/2-mainEdgeRadius, mainHeight/2-mainEdgeRadius>, <-coverGapWidth/2, mainThick/2-mainEdgeRadius, mainHeight/2-mainEdgeRadius>, mainEdgeRadius-coverGapEdgeRad
			}
			cylinder {
				<(coverGapWidth/2+coverGapEdgeRad), -mainThick/2+mainEdgeRadius, mainHeight/2-mainEdgeRadius>, <coverGapWidth/2, -mainThick/2+mainEdgeRadius, mainHeight/2-mainEdgeRadius>, mainEdgeRadius-coverGapEdgeRad
			}
			cylinder {
				<-(coverGapWidth/2+coverGapEdgeRad), -mainThick/2+mainEdgeRadius, mainHeight/2-mainEdgeRadius>, <-coverGapWidth/2, -mainThick/2+mainEdgeRadius, mainHeight/2-mainEdgeRadius>, mainEdgeRadius-coverGapEdgeRad
			}
			cylinder {
				<(coverGapWidth/2+coverGapEdgeRad), mainThick/2-mainEdgeRadius, mainHeight/2-mainEdgeRadius>, <coverGapWidth/2, mainThick/2-mainEdgeRadius, mainHeight/2-mainEdgeRadius>, mainEdgeRadius-coverGapEdgeRad
			}
			torus {
				mainEdgeRadius-coverGapEdgeRad, coverGapEdgeRad
				rotate 90*z
				translate <(coverGapWidth/2+coverGapEdgeRad), mainThick/2-mainEdgeRadius,mainHeight/2-mainEdgeRadius>
			}
			torus {
				mainEdgeRadius-coverGapEdgeRad, coverGapEdgeRad
				rotate 90*z
				translate <(coverGapWidth/2+coverGapEdgeRad), -mainThick/2+mainEdgeRadius,mainHeight/2-mainEdgeRadius>
			}
			torus {
				mainEdgeRadius-coverGapEdgeRad, coverGapEdgeRad
				rotate 90*z
				translate <-(coverGapWidth/2+coverGapEdgeRad), mainThick/2-mainEdgeRadius,mainHeight/2-mainEdgeRadius>
			}
			torus {
				mainEdgeRadius-coverGapEdgeRad, coverGapEdgeRad
				rotate 90*z
				translate <-(coverGapWidth/2+coverGapEdgeRad), -mainThick/2+mainEdgeRadius,mainHeight/2-mainEdgeRadius>
			}
		}
	}
	cylinder {
		<-(coverGapWidth/2+coverGapEdgeRad),-mainThick/2+mainEdgeRadius,mainHeight/2-coverGapEdgeRad>, <-(coverGapWidth/2+coverGapEdgeRad),mainThick/2-mainEdgeRadius,mainHeight/2-coverGapEdgeRad>, coverGapEdgeRad
	}
	cylinder {
		<(coverGapWidth/2+coverGapEdgeRad),-mainThick/2+mainEdgeRadius,mainHeight/2-coverGapEdgeRad>, <(coverGapWidth/2+coverGapEdgeRad),mainThick/2-mainEdgeRadius,mainHeight/2-coverGapEdgeRad>, coverGapEdgeRad
	}
	texture {mainBodyTexture}
}

// we need more gear Wheels to make the cylinder turn -- no just to make it look more mechanicallyishlike
#declare musicBox = union {
	object { musicBox }
	object { gearWheel(gw2sprocketNumber, gw2radius, gw2sprocketHeight, gw2thick, gw2rounding)
		texture { gearWheelTexture2 }
		rotate x*20.35
		translate <-(gw2thick/2+trackNumber/2*cylinderTrackWidth), gw2AxisY, gw2AxisZ>
	}
	difference {
		object { gearWheel(gw3sprocketNumber, gw3radius, gw3sprocketHeight, gw3thick, gw3rounding)
			rotate x*20.35
			translate <-(gw2thick+trackNumber/2*cylinderTrackWidth+gearWheelGap+gw3thick/2), gw2AxisY, gw2AxisZ>
		}
		cylinder {
			<-(cylinderGapWidth/2), gw2AxisY, gw2AxisZ>,<gw2AxisXend, gw2AxisY, gw2AxisZ>, gw2AxisRadius+gw2AxisGap	
		}
		texture { gearWheelTexture3 }
	}
	cylinder {
		<-(cylinderGapWidth/2), gw2AxisY, gw2AxisZ>,<gw2AxisXend, gw2AxisY, gw2AxisZ>, gw2AxisRadius
		texture { gearWheelAxisTexture }
	}
}

#declare iPodRetro = union {
	object {mainBody}
	object {musicBox}
	object {plasticCover}
	translate <0,mainThick/2,0>
}

