////////////////////////////////////////////////////////////////////////////////
// Note from the Scriptographer.org Team
//
// In Scriptographer 2.9, we switched to a top-down coordinate system and
// degrees for angle units as an easier alternative to radians.
// 
// For backward compatibility we offer the possibility to still use the old
// bottom-up coordinate system and radians for angle units, by setting the two
// values bellow. Read more about this transition on our website:
// http://scriptographer.org/news/version-2.9.064-arrived/

script.coordinateSystem = 'bottom-up';
script.angleUnits = 'radians';

/*

				---==================================---
					Roulettes v1.0 by Håkan Lundgren
				---==================================---



*/

stator = 3;
rotor = 1;
rotorOffset = 1;
plotMultiplier = 10;
plotStep = 1;

rouletteType = { Epicycloid: false, Epitrochoid: false, Hypocycloid: false, Hypotrochoid: false };

specialcaseText = "Cardioid when k = 1   \nNephroid when k = 2      ";
var rType = 'Epicycloid';


function plotRoulette() {
	var step = (plotStep).toRadians();
	var path = new Path() { position: document.size / 2 };
	var theta = 0;

	var R = stator * plotMultiplier;
	var r = rotor * plotMultiplier;
	var d = rotorOffset * plotMultiplier;

	var i = 0;

	while(i <= 360 / plotStep * rotor) {
		if (rType == 'Epicycloid') {
			path.lineTo(new Point(
				( R + r ) * Math.cos( theta ) - r * Math.cos( ( R + r ) / r * theta ),
				( R + r ) * Math.sin( theta ) - r * Math.sin( ( R + r ) / r * theta )));
		}
		if (rType == 'Epitrochoid') {
			path.lineTo(new Point(	
				( R + r ) * Math.cos( theta ) - d * Math.cos( ( R + r ) / r * theta ),
				( R + r ) * Math.sin( theta ) - d * Math.sin( ( R + r ) / r * theta )));
		}
		if (rType == 'Hypocycloid') {
			path.lineTo(new Point(	
				( R - r ) * Math.cos( theta ) + r * Math.cos( ( R - r ) / r * theta ),
				( R - r ) * Math.sin( theta ) - r * Math.sin( ( R - r ) / r * theta )));
		}
		if (rType == 'Hypotrochoid') {
			path.lineTo(new Point(
				( R - r ) * Math.cos( theta ) + d * Math.cos( ( R - r ) / r * theta ),
				( R - r ) * Math.sin( theta ) - d * Math.sin( ( R - r ) / r * theta )));
		}
		theta += step;
		i++;
	}
	path.closed = true;
	path.position = document.size / 2;
}



// ==================================================================================
//									 DIALOG SETUP
// ==================================================================================


//==========  Main dialog palette  ==========
	dialog = new FloatingDialog('tabbed') {
		title: 'Roulettes v1.0',
		size: new Size(170,300),
		onClose: function() {
			dialog.destroy();
		}
	};
//================================================================

//==========  Roulette Type  ==========
	var frame = new Frame(dialog) {
		text: 'Type',
		font: 'palette-bold',
		size: [164, 89],
		position: new Point(3, 1)
	}

	var roulettetypeList = new PopupList(dialog) {
		bounds: [65, 10, 102, 20],
		onChange: function() {
			var t = this.activeEntry.text;
			rouletteType.Epitrochoid = (t == 'Epitrochoid') ? 1 : 0;
			rouletteType.Hypocycloid = (t == 'Hypocycloid') ? 1 : 0;
			rouletteType.Hypotrochoid = (t == 'Hypotrochoid') ? 1 : 0;
			switch ( t ) {
				case 'Epicycloid':
					rouletteDescription.text = "Cardioid when k = 1\nNephroid when k = 2";
					rType = 'Epicycloid';
					break;
				case 'Epitrochoid':
					rouletteDescription.text = "Limacon when R = r\nEpicycloid when d = r";
					rType = 'Epitrochoid';
					break;
				case 'Hypocycloid':
					rouletteDescription.text = "Deltoid when k = 3\nAstroid when k = 4";
					rType = 'Hypocycloid';
					break;
				case 'Hypotrochoid':
					rouletteDescription.text = "Hypocycloid when d = r\nEllipse when R = 2r";
					rType = 'Hypotrochoid';
					break;
			}
			if(	rouletteType.Epitrochoid || rouletteType.Hypotrochoid ) {
				rotoroffsetEdit.enabled = true;
			} else {
				rotoroffsetEdit.enabled = false;
			}
		}
	};

	roulettetypeList.add('Epicycloid').selected = true;
	roulettetypeList.add('Epitrochoid');
	roulettetypeList.add('Hypocycloid');
	roulettetypeList.add('Hypotrochoid');
//================================================================

//==========  Special Case Field  ==========
	var frame = new Frame(dialog) {
		text: 'Special cases',
		font: 'palette-bold',
		size: [156, 51],
		position: new Point(7, 35)
	}
	
	var rouletteDescription = new TextPane(dialog) {
		position: new Point(20, 52),
		text: specialcaseText
	}
//================================================================
	
//==========  Stator/rotor Ratio Field  ==========
	var frame = new Frame(dialog) {
		text: 'Stator/rotor Ratio (k)',
		font: 'palette-bold',
		size: [164, 65],
		position: new Point(3, 93)
	};
	
	var statorText = new TextPane(dialog) { text: 'Stator (R)', position: [20, 111] };
	
	var statorEdit = new SpinEdit(dialog) {
		position: [100, 108],
		size: [50, 20],
		range: [2, 101],
		value: stator
	};
	
	var rotorText = new TextPane(dialog) { text: 'Rotor (r)', position: [20, 134] };
	
	var rotorEdit = new SpinEdit(dialog) {
		position: [100, 131],
		size: [50, 20],
		range: [1, 100],
		value: rotor
	};
//================================================================

//==========  Rotor Offset Field  ==========
	var frame = new Frame(dialog) {
		text: 'Rotor Offset',
		font: 'palette-bold',
		size: [164, 42],
		position: new Point(3, 161)
	};

	var rotoroffsetText = new TextPane(dialog) { text: 'Rotor Offset (d)', position: [20, 180] };
	
	var rotoroffsetEdit = new SpinEdit(dialog) {
		enabled: false,
		position: [100, 176],
		size: [50, 20],
		increments: 0.1,
		range: [0, 100],
		value: rotorOffset
	};
	rotoroffsetEdit.enabled = false;
//================================================================

//==========  Appearance Values  ==========
	var frame = new Frame(dialog) {
		text: 'Appearance',
		font: 'palette-bold',
		size: [164, 64],
		position: new Point(3, 206)
	};

	var plotMultiplier = new TextPane(dialog) { text: 'Plot Size Multiplier', position: new Point(20, 225) };
	
	var plotmultiplierEdit = new TextEdit(dialog) {
	    bounds: [120, 221, 30, 20],
	    text: '10'
	};

	var plotStep = new TextPane(dialog) { text: 'Plot Every x Angle', position: new Point(20, 244) };

	var plotstepEdit = new TextEdit(dialog) {
	    bounds: [120, 240, 30, 20],
	    range: [1, 360],
	    units: 'none',
	    text: '1'
	};
//================================================================

//==========  Render Button  ==========
	var renderButton = new Button(dialog) {
	    text: 'Render',
	    position: new Point(109, 274),
	    onClick: function() {
	    	stator = statorEdit.value;
			rotor = rotorEdit.value;
	    	if (rotor > stator) {
		    	dialog.alert('Please make rotor smaller than stator!');
				return false;
	    	}
			rotorOffset = rotoroffsetEdit.value;
			plotMultiplier = parseInt(plotmultiplierEdit.text);
			plotStep = parseInt(plotstepEdit.text);
			plotRoulette();
	    }
	};
//================================================================