/*
	^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
	O-----o-----o-----o-----o-----o-----o-----o-----O
	
	                   |                             
	,---.,---.,---.,---|,---.,---.,---.,---.  v2.00  
	|   |,---||    |   ||---'|   ||---'|             
	`---|`---^`    `---'`---'`   '`---'`             
	`---'                                            
	
	original version by pedro and rob.
	converted to sg 2.0 by the mighty graf salamander
	with the debugging eye of jürg lehni.
	used best with scriptographer 2.0
	
	gardener creates nice tendrils from a draw path.
	assign one of the scriptographer-tools to the
	gardener script and select some objects in your
	document. then start drawing your shape.
	the selected objects will be used in a random 
	order and size as the end objects of each created 
	branch. make sure you tweak the script options by 
	a doubleclick on the assigned scriptographer-tool.
	
	note:
	you need to smooth the small branches manually.
	(if you zoom in close, you'll find them very edgy.)
	do this by selecting all the created branches, then 
	go to the illustrator-menu >object>path>simplify.
	
	O-----o-----o-----o-----o-----o-----o-----o-----O
	.................................................
*/

var openDialog = false;
function optionDialog() 
{
	//////////////////////CONFIG//////////////////////////
	// dialog config stuff
	var dialogSize = new Size(200, 200);
	var dialogHelpSize = new Size(200, 450);
	var dialogTitle = "gardener 2.0 configuration";
		
	openDialog = true; // set dialog status to true/open
	
	// create dialog
	dialog = new FloatingDialog('tabbed') {
		title: dialogTitle,
		size: dialogSize,
		onClose: function() {
		        this.destroy();
				openDialog = false;
		}
	};
	
	// *start minScale value
	minScaleTextEdit = new TextEdit(dialog) {
		position: [145, 20],
		size: [40, 20],
		value: 5,
		units: 'none'
	};
	
	var minScaleText = new TextPane(dialog) {
		text: 'min branch scale:',
		position: [20, 23]
	};
	//------
	
	// *start maxScale value
	maxScaleTextEdit = new TextEdit(dialog) {
		position: [145, 40],
		size: [40, 20],
		value: 10,
		units: 'none'
	};
	
	var maxScaleText = new TextPane(dialog) {
		text: 'max branch scale:',
		position: [20, 43]
	};
	//------
	
	// *start rotationValue value
	rotationValueTextEdit = new TextEdit(dialog) {
		position: [145, 60],
		size: [40, 20],
		value: 0.2,
		units: 'none'
	};
	
	var rotationValueText = new TextPane(dialog) {
		text: 'branch rotation:',
		position: [20, 63]
	};
	//------
	
	// *start strength value
	strengthTextEdit = new TextEdit(dialog) {
		position: [145, 80],
		size: [40, 20],
		value: 0.2,
		units: 'none'
	};
	
	var strengthText = new TextPane(dialog) {
		text: 'branch strength:',
		position: [20, 83]
	};
	//------
	
	// *start minBranch value
	minBranchTextEdit = new TextEdit(dialog) {
		position: [145, 100],
		size: [40, 20],
		value: 2.0,
		units: 'none'
	};
	
	var minBranchText = new TextPane(dialog) {
		text: 'min branch count:',
		position: [20, 103]
	};
	//------
	
	// *start maxBranch value
	maxBranchTextEdit = new TextEdit(dialog) {
		position: [145, 120],
		size: [40, 20],
		value: 5.0,
		units: 'none'
	};
	
	var maxBranchText = new TextPane(dialog) {
		text: 'max branch count:',
		position: [20, 123]
	};
	//------
	
	// *start minSize value
	minSizeTextEdit = new TextEdit(dialog) {
		position: [145, 140],
		size: [40, 20],
		value: 0.5,
		units: 'none'
	};
	
	var minSizeText = new TextPane(dialog) {
		text: 'min endobject size factor:',
		position: [20, 143]
	};
	//------
	
	// *start minSize value
	maxSizeTextEdit = new TextEdit(dialog) {
		position: [145, 160],
		size: [40, 20],
		value: 1.5,
		units: 'none'
	};
	
	var maxSizeText = new TextPane(dialog) {
		text: 'max endobject size factor:',
		position: [20, 163]
	};
	//------
	
			
	// *start dropOut	
	var dropOut = dialog.popupMenu;
	dropOut.visible = true;
	var listHelp = new ListEntry(dropOut) {
		text: 'help',
		onSelect: function() {
			dialog.size = dialogHelpSize;
		}
	};
	var listCloseHelp = new ListEntry(dropOut) {
		text: 'close help',
		onSelect: function() {
			dialog.size = dialogSize;
		}
	};
	
	var helpText = new TextPane(dialog) {
		text: 'gardener creates nice tendrils from a draw path. assign one of the scriptographer-tools to the gardener script and select some objects in your document. then start drawing your shape. the selected objects will be used in a random order and size as the end objects of each created branch. \n \nnote: you need to smooth the small branches manually. (if you zoom in close, you\'ll find them very edgy.) do this by selecting all the created branches, then go to the illustrator menu > object > path > simplify.',
		size: [165, 200],
		position: [20, 220]
	};
	
	// *start configFrame 
	var configFrame = new Frame(dialog) {
		text: 'config',
		font: 'palette-bold',
		size: [190, 195],
		position: [5, 0]
	};
	//---------
	
	// *start helpFrame 
	var helpFrame = new Frame(dialog) {
		font: 'palette-bold',
		text: 'help',
		size: [190, 245],
		position: [5, 200]
	};
	//---------
	
	
	// finalize the dialog
	dialog.visible = true;
	//**********************************
}


var selobjs = null;
var allLayers = document.layers;
var mainLayer = document.activeLayer;
var minScale = 5.0;
var maxScale = 10.0;
var rotationValue = 0.2;
var strength = 0.2;
var minBranch = 2;
var maxBranch = 5;
var minSize = 0.5;
var maxSize = 1.5;
var black = new GrayColor(1);
var art, group, group2;

function onOptions()
{
	optionDialog()
}

function onMouseDown(event)
{
	selobjs = null;
	selobjs = document.selectedItems;
	
	topLevelObjects = [];
	getTopLevelObjects(selobjs);
	
	art = new Path();
	art.fillColor = null;
	if (art.strokeColor == null)
	{
		art.strokeColor = black;
		art.strokeWidth = 0.5;
	}

	group = new Group();	// branches
	group2 = new Group();	// endobjects
}

function onMouseUp(event)
{
	art.pointsToCurves();
	
	var branches = [];
	
	if (openDialog == true)
	{
		minScale = minScaleTextEdit.value;
		maxScale = maxScaleTextEdit.value;
		rotationValue = rotationValueTextEdit.value;
		strength = strengthTextEdit.value;
		minBranch = minBranchTextEdit.value;
		maxBranch = maxBranchTextEdit.value;
		minSize = minSizeTextEdit.value;
		maxSize = maxSizeTextEdit.value;	
	}
	
	
	// init branches
	for (var j = 0, l = art.curves.length; j < l; j++)
	{
		var newCount = Math.round(Math.random() * (maxBranch - minBranch) + minBranch);
		for (var c = 0; c < newCount; c++)
		{
			var rndPos = Math.random();
			var point = art.curves[j].getPoint(rndPos);
			var vector = new Point(art.curves[j].getTangent(rndPos));
            
			vector.normalize();
			vector = vector * strength;
			var rotate = rotationValue;
			if (Math.random() < 0.5) rotate *= -1.0;	// left or right branch
			var len = (Math.random() * (maxScale - minScale) + minScale);
			var obj = new Path();
			obj.fillColor = null;
			if (obj.strokeColor == null)
			{
				obj.strokeColor = black;
				obj.strokeWidth = 0.5;
			}
			
			group.appendChild(obj);
			branches.push({point: point, vector: vector, rotate: rotate, len: len, art: obj});
		}
	}
	
	// build branches
	for (var i in branches)
	{
		var branch = branches[i];
		for (n = 0; n < branch.len; n++)
		{
			branch.art.lineTo(branch.point);
			if (n < (branch.len - 1))
			{	// prepare next segmentpoint
				branch.point = branch.point + branch.vector;
				branch.vector = branch.vector.rotate(branch.rotate);
			}
		}
	}
   	

	
   	// build endobjects at each branchendpoint
	if (selobjs.length > 0)
	{
		
		for (var i in branches)
		{
			// select randomly one endobject out of all selected obj's in ai
			//var randomObject = selobjs.getArt(Math.round(Math.random() * (selobjs.length - 1)));
			var endobj = topLevelObjects[(Math.round(Math.random() * (topLevelObjects.length - 1)))];
			
			var eobj = endobj.clone();
			eobj.position = branches[i].point;			
			var scale = Math.random() * (maxSize - minSize) + minSize;
			eobj.scale(scale);

			
			if (branches[i].rotate < 0)
				eobj.rotate(branches[i].vector.angle);
			else
				eobj.rotate(branches[i].vector.angle + Math.PI);
			group2.appendTop(eobj);
		}
	}
	
		// smooth branches - does not work properly; see info at the top of the skript  
	    //for (var i in branches) {
		//branches[i].art.pointsToCurves(tolerance = 0, threshold = 5.0, cornerRadius = 5, scale = 5.0); 
	    //}
	
}

function getTopLevelObjects(selectedObjects)
{
	for (var t = 0; t < selectedObjects.length; t++)
	{
		if(selectedObjects[t].parent == mainLayer)
		{
			topLevelObjects.push(selectedObjects[t]);
		}
	}
}

function onMouseDrag(event)
{
    art.lineTo(event.point);
}

