////////////////////////////////////////////////////////////////////////////////
// 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';

// Ribbon Tool v0.2
// Jonathan Puckey 2006
// www.jonathanpuckey.com

// change log
// v0.1 - initial release
// v0.2 - Rewrote everything, added friction / merge options
// v0.2.1 - 9 May 2009 - Rewritten for latest version of Scriptographer 

function onOptions() {
	friction.dialog();
}

function onMouseDown(event) {
	if(friction.active) friction.initialize(event.point);
	ribbon.oldPoint = event.point;
	ribbon.initialize(event.point);
}


function onMouseDrag(event) {
	if(friction.active) {
		ribbon.drag(friction.iterate(event.point));
	}else{
		ribbon.drag(event.point);
	}
}

function onMouseUp(event) {
	ribbon.end();
}

var ribbon = {
	count : 0,
	bg : RGBColor(0,0,0),
	direction : 0,
	oldDirection : 0,
	mergeOption : true,
	initialize : function(lp) {
		this.toMerge = [];
		this.set = [];
		this.oldPoint = lp;
		this.sval = 2.01-(w.value/100 * 1);
		this.curRibSeg = this.createPart([lp, new Point(lp.x+1,lp.y),new Point(lp.x+1,lp.y+1), lp]);
	},
	newRibSeg : function(lp,lp2) {
		return this.createPart([lp, new Point(lp.x+1,lp.y),new Point(lp.x+1,lp2.y), lp2]);
	},
	createPart : function(points) {
		var p = new Path();
		var l = points.length;
		for (var i = 0, l = points.length; i<l; i++) {
			p.segments.add(points[i]);
		}
		p.closed = true;
		return p;
	},
	drag : function(eventPoint) {
		var diffPoint = eventPoint - this.oldPoint;
		this.curRibSeg.segments[1].point.x = eventPoint.x;
		this.curRibSeg.segments[1].point.y = eventPoint.y-diffPoint.y/this.sval;
		this.curRibSeg.segments[2].point = eventPoint;
		this.count++;
		if(this.count>3) {
			this.direction = this.curRibSeg.segments[1].point.x - this.curRibSeg.segments[0].point.x;
			this.direction = this.direction/Math.abs(this.direction);
			if(this.oldDirection != this.direction) {
				//if(this.mergeOption) Pathfinder.merge(this.set);
				this.toMerge.push(this.set);
				this.set = [];
			};
			this.set.push(this.curRibSeg);
			this.oldDirection = this.direction;
			
			if(this.direction == -1) {
				this.curRibSeg.fillColor = this.bg;
			}
			this.count = 0;
			this.oldPoint = this.curRibSeg.segments[1].point;
			this.curRibSeg = this.newRibSeg(this.curRibSeg.segments[1].point,this.curRibSeg.segments[2].point);
		}
	},
	end : function () {
		if(this.curRibSeg.segments[0].point.x > this.curRibSeg.segments[1].point.x)
			this.curRibSeg.fillColor = this.bg;
		if(this.mergeOption) {
			this.toMerge.push(this.set);
			for(var i in this.toMerge) {
				if(this.toMerge[i].length > 1) {
					Pathfinder.unite(this.toMerge[i]);
				}
			}
		}
	}
}

//friction code adapted from friction.js by Juerg Lehni
var friction = {
	active : false,
	accel : 10,
	accelFriction : 0.8,
	friction : 0.4,
	initialize : function(eventPoint) {
		this.point = eventPoint;
		this.velocity = new Point();
		this.acceleration = new Point();
	},
	iterate : function(eventPoint) {
		var diff = eventPoint - this.point;
		var norm = diff.normalize();
		var len = norm.length;
		this.acceleration = (this.acceleration + (norm * (len * this.accel))) * this.accelFriction;
		this.velocity = (this.velocity + this.acceleration) * this.friction;
		this.point = this.point + this.velocity;
		return this.point;
	},
	turnOff : function () {
		this.active = false;
		tool.eventInterval = 0; // off	
	},
	turnOn : function () {
		this.active = true;
		tool.eventInterval = 1000 / 100; // 100 times a second;
		friction.dialog();
	},
	dialog : function () {
		var values = Dialog.prompt("Friction:", [
			{ value: friction.friction, description: "friction", width: 50 },
			{ value: friction.accel, description: "acceleration", width: 50 },
			{ value: friction.accelFriction, description: "acceleration friction", width: 50 }
		]);
		if (values) {
			this.friction = values[0];
			this.accel = values[1];
			this.accelFriction = values[2];
		}
	}
}

var dialog = new FloatingDialog('tabbed') {
	title: 'Ribbon Tool',
	size: [110, 25],
	visible: true,
	onClose: function () {
		this.destroy();
	}
};

var w = new Slider(dialog) {
	style: 'nonlinear',
	range: [0, 100],
	value: 50,
	size: [110, 20]
}

var pMenu = dialog.popupMenu;
var popFric = new ListEntry(pMenu) {
	text: 'friction',
	checked: false,
	onSelect: function () {
		if(popFric.checked) {
			popFric.checked = false;
			friction.turnOff();
		}else{
			popFric.checked = true;
			friction.turnOn();
		}
	}
}

new ListEntry(pMenu) {
	separator: true
}
var popMerge = new ListEntry(pMenu) {
	text: 'Merge segments',
	checked: true,
	onSelect: function () {
		this.checked = !this.checked;
		ribbon.mergeOption = popMerge.checked;
	}
}

pMenu.visible = true;



//	Jonathan Puckey 2006
//	http://www.jonathanpuckey.com