/*\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
                   __   __ ___     __                              
  __  _  _______  |  | |  |\_ |__ |  | _____  ________ ___________ 
  \ \/ \/ /\__  \ |  | |  | | __ \|  | \__  \ \___   // __ \_  __ \ 2.0
   \     /  / __ \|  |_|  |_| \_\ \  |__/ __ \_/  __/\  ___/|  | \/
    \/\_/  (____  /____/____/___  /____(____  /_____ \\___  >__|   
                \/              \/          \/      \/    \/    
				

   wallblazer2.0.js is a script for scriptographer 2.0. 
   it draws paths from the mousepoint to a location which is relative 
   to the documents zeropoint, using the distance from that zeropoint
   to the current mousepoint. the script can be used either as a 
   drawing tool or it can be applied to an existing object. 
   read the scripthelp for further information on the settings.
   
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ coded by the mighty graf salamander \\\
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ from an old script by pedro \\\
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ used best with www.scriptographer.com \\\
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/

// standard values
var pointDist = 2; // distance between points
var targetblazer = false; // use wallbalzer or targetblazer (false --> use wallblazer)
var randomize = true; // randomize length of the wallblazer-wall-paths (true --> do randomize)
var randomMultiplier = 100; // random length multipier for randomized wallblazer-wall-paths
var killbase = false; // if used on objects, keep the object/base (false --> kill the base)

var openDialog = false; // status of dialog (false --> dialog is not open)

optionDialog(); // start the dialog

var randomMultiplierSpin;
//****function which creates the option dialog****
function optionDialog() 
{
	if(!openDialog) {
		//////////////////////CONFIG//////////////////////////
		// dialog config stuff
		var dialogSize = new Size(200, 227);
		var dialogHelpSize = new Size(200, 720);
		var dialogTitle = "wallblazer configuration";
		
			
		openDialog = true; // set dialog status to true/open
		
		// create dialog
		dialog = new FloatingDialog('tabbed') {
			title: dialogTitle,
			size: dialogSize
		};
		
		// ***** start wallblaze radiobuttons *****
			// button one
		var wallblazeRadio = new RadioButton(dialog) {
			checked: true,
			position: [170, 20],
			size: [20, 15],
			onClick: function () {
				targetblazer = targetblazeRadio.checked; // set option on click
				randomMultiplierSpin.enabled = (randomize == true && targetblazer == false); // gray out the randomMultiplierSpin if targetblazer-mode is set
			}
		};
		
			// button two
		var targetblazeRadio = new RadioButton(dialog) {
				checked: true,
				position: [170, 40],
				size: [20, 15],
				onClick: function () {
					targetblazer = targetblazeRadio.checked; // set option on click
					randomMultiplierSpin.enabled = (randomize == true && targetblazer == false);
				}
			};
			
			//text for radiobutton 1
		var wallRadioText1 = new TextPane(dialog) {
			text: 'wallblaze',
			position: [20, 20]
		};
		
			//text for radiobutton 2
		var wallRadioText2 = new TextPane(dialog)	 {
				text: 'targetblaze',
				position: [20, 40]
		};
		
		// ----- end radiobuttons -----
		
		
		// ***** start random checkbox *****
		var randomCheck = new CheckBox(dialog) {
			position: [170, 60],
			size: [20, 15],
			checked: true,
			onClick: function () {
				randomize = randomCheck.checked;

				if (randomize == true && targetblazer == false) // gray out the randomMultiplierSpin if random-mode is unchecked
				{
					randomMultiplierSpin.enabled = true;
				}
				else
				{
					randomMultiplierSpin.enabled = false;
				}
			}
		};

		var randomText = new TextPane(dialog) {
			text: 'random length',
			position: [20, 60]
		};
		// ----- end random checkbox -----
		
		
		// ***** start baseline checkbox *****
		var baselineCheck = new CheckBox(dialog) {
			position: [170, 80],
			size: [20, 15],
			onClick: function() {
			killbase = baselineCheck.checked;
			}
		};
		
		var baselineText = new TextPane(dialog) {
			text: 'keep baseline',
			position: [20, 80]
		};

		// ----- end baseline checkbox -----
		
		// *start density value
		var densitySpin = new SpinEdit(dialog) {
			position: [135, 170],
			size: [50, 20],
			value: 2
		};
		
		var densityText = new TextPane(dialog) {
			text: 'point distance:',
			position: [20, 175]
		};
		//------
		
		// *start randomMultiplier spin
		randomMultiplierSpin = new SpinEdit(dialog) {
			position: [135, 110],
			size: [50, 20],
			value: 100
		};
		
		var randomMultiplierText = new TextPane(dialog) {
			text: 'random length multiplier:',
			position: [20, 115]
		};
		//------
		
		// *start goButton
		var submitButton = new Button(dialog) {
			text: 'blaze selected objects',
			position: [17, 195],
			onClick: function () { // set all option on click
				pointDist = densitySpin.text;
				targetblazer = targetblazeRadio.checked;
				randomize = randomCheck.checked;
				randomMultiplier =  randomMultiplierSpin.text;
				killbase = baselineCheck.checked;
				startObjectBlaze();
			}
		};
		//-------
		
		// *start dropOut	
		var dropOut = dialog.popupMenu;
		var listHelp = new ListEntry(dropOut) {
			text : 'help',
			onClick : function () {
				dialog.size = dialogHelpSize;
			}
		};

		var listCloseHelp = new ListEntry(dropOut) {
			text : 'close help',
			onClick : function () {
				dialog = dialogSize;
			}
		};
		
		var helpText = new TextPane(dialog) {
			text : 'wallblazer uses the documents zeropoint (default is bottom left of your document) as the main value for the generated paths. it can be either applied to an existing shape or it can be used as a drawing tool.\n___\nwallblaze: the main function of the program. it draws paths from the mousepoint to a location which is relative to the documents zeropoint, using the distance from that zeropoint to the current mousepoint.\n___\ntargetblaze: is an alternate function of the script. it draws paths from the mousepoint to the documents zeropoint.\n___\nrandom length:  enables a random output of the pathlengths, using the random length multiplier.\n___\nrandom length mulitplier: modifies the length of the generated paths when \'random length\' is activated\n___\nkeep baseline: lets you keep (or kill if deactivated) the drawn line or selected shape for further processing.\n___\npoint distance: sets the distance between the generated paths. this is only accessible when the script is applied to a shape. the pointdistance in drawing-mode is modified by the speed of your mousemovement.\n\n',
			size : [165, 460],
			position : [20, 240]
		};
		
		// *start configFrame 
		var configFrame = new Frame(dialog) {
			text: 'draw/on object',
			font: 'palette-bold',
			size: [190, 150],
			position: [5, 0]
		};
		//---------
		
		// *start onObjectFrame 
		var onObjectFrame = new Frame(dialog) {
			font: 'palette-bold',
			text: 'on object only',
			size: [190, 73],
			position: [5, 150]
		};

		//---------
		
		// *start helpFrame 
		var helpFrame = new Frame(dialog) {
			font: 'palette-bold',
			text: 'help',
			size: [190, 490],
			position: [5, 225]
		};
		//---------
		
		// finalize the dialog
		dialog.visible = true;
		dialog.onClose = function() {
		        this.destroy();
				openDialog = false;
		}
		//**********************************
	}
}

// ******************
// 
//  wallblazer on objects
//
//

var gPaths, groupObjs, allObjects, countOfObjects;

//****function which handles the selected objects and passes them over to the wallblaze function****
function startObjectBlaze()
{
	gPaths = []; // new array for paths which belong to a group, array will be used in the ungroup function
	groupObjs = []; // new array for all group objects, array will be used in the ungroup function
	allObjects = document.selectedItems;
	countOfObjects = allObjects.length;
	
	for (var j = 0; j < countOfObjects; j++) // go through all selected objects
	{
		for (var m = 0; m < gPaths.length; m++) // remove all paths which belong to a group from selected objects (see the ungroup function)
		{
				allObjects.remove(gPaths[m]); // remove already processed paths to avoid conflicts
				allObjects.add(null); // to keep the size of the array correct we add a null-value for every removes object
		}
		
		for (var m = 0; m < groupObjs.length; m++) // remove all paths which belong to a group from selected objects (see the ungroup function)
		{
				allObjects.remove(groupObjs[m]); // remove already processed groups to avoid conflicts
				allObjects.add(null); // to keep the size of the array correct we add a null-value for every removes object
		}
		
		gPaths = []; // reinitialize the gPath array (empty it)
		
		groupObjs = []; // reinitialize the groupObjs array (empty it)
		
		var obj = allObjects[j]; // the current object is now called "obj"
		
			if (obj != null) // ignore null-objects
			{
				
				if(obj.hasChildren()) // if the object has child elements, it's most likely a group
				{
					ungroupRecoursiveAndBlaze(obj); // pass the group over to the ungroup function
				}
				else // if it is a normal path ...
				{
					wallblaze(obj); // ... blaze it!
				}
			}
	}
	
}

//****function which ungroups objects and passes them over to the blaze function****
function ungroupRecoursiveAndBlaze(groupObj) 
{
	var countOfGroupObjects = null; 
	var obj = groupObj.children; // get all the grouped objects
	countOfGroupObjects = obj.length; // get the count of the grouped objects
	var reGroup = new Group(); // new group to regroup the blazed objects later
	
	for (var n = 0; n < countOfGroupObjects; n++)
	{
		if(obj[n].hasChildren()) // if the object has children again, it's most likely a group... a group in a group... like vectorized fonts...
		{
				groupObjs.push(obj[n]); // add the group object to the groupObjs array to delete it from the allObjects array
				ungroupRecoursiveAndBlaze(obj[n]); // do it all again
		}
		else // the object seems to be a path
		{
			gPaths.push(obj[n]); // add the path to the gpaths array to delete it from the allObjects array
			reGroup.appendTop(wallblaze(obj[n]));	// add the path to a group and pass it over to the blaze function		
		}
	}
}

//****function which does the wallblazing itself (aka the mighty blaze function)****
function wallblaze(blazeObj) // blazeObj is the object which soon will be blazed!
{
		base = blazeObj.clone(); // create a clone of the blazeObj in case you would keep the base object
		
		//print(typeof blazeObj + ' : ' + blazeObj + ' is hasChildren: ' + blazeObj.hasChildren() );
		
		blazeObj.curvesToPoints(pointDist, 10000); // creates anchorpoints on the blazeObj, the distance between the points is set in the options dialog
		
		var group = new Group();  // a new empty group for the wallblazer-wall-paths
		
		var count = blazeObj.curves.length; // get the count of anchorpoints --> count of wallblazer-wall-paths to draw
		
		for (var i = 0; i < count; i++) // for every wallblazer-wall-path do
		{
			path = new Path(); // create a new path element
			path.moveTo(blazeObj.curves[i].point1); // set the start point of the path (the anchotpoint on the blazeObj)
			
			if (targetblazer == false) // test if targetblaze option is set
			{
				if (randomize == true) // test if randomlength option is set
				{
					// for random mode
					randomNumber = Math.round(Math.random() * randomMultiplier)/100; // get a random number based on the randomMultipler, set in the options dialog
					randomTarget = blazeObj.curves[i].point1 * randomNumber;// create a new point which is the start point x and y value multiplied with the randomNumber
					endPoint = blazeObj.curves[i].point1 + randomTarget; // create the endpoint of the path, which is the randomPoint added to the startpoint
				}
				else
				{
					// for normal mode
					endPoint = blazeObj.curves[i].point1 + blazeObj.curves[i].point1; // create the endpoint, which is the distance to the zeropoint added to the startpoint (the distance to zero is equivalent to the startpoint)
				}
			}
			else
			{
				// for targetblazer mode
				endPoint = new Point(0,0) // create the endpoint, which is the zeropoint itself
			}
			
			path.lineTo(endPoint); // draw the path to the endpoint, depending on the mode...
			group.appendChild(path); // add the path to a group
		}
		
		if (killbase == false) // test if the base object should be killed or not
		{
			blazeObj.remove();
			base.remove();
		}
		else
		{
			blazeObj.remove();
		}
		
		return group; // return the group of the wallblazer-wall-paths (the blazed object)
}


// ******************
// 
//  the draw tool
//
//


function onInit()
{
	// set some standard values, in case no dialog is open
	targetblazer = false;
	randomize = true;
	randomMultiplier = 100;
}

function onOptions()
{
	optionDialog(); // onOptions open the option dialog
}

function onMouseDown(event)
{
	group = new Group(); // create a new empty group for the wallblazer-wall-paths
	
	if(killbase == true) // if the user want to keep the baseline ... 
	{
		baseLine = new Path(); // ... create a new path for the baseline
		baseLine.fillColor = null; // set the fillcolor to null, so it is a line for sure
	}
		
}

function onMouseDrag(event)
{

	path = new Path(); // create a new wallblazer-wall-path ...
	path.moveTo(event.point); // ... which starts at the point where the mouse is at the moment
	
	if(killbase == true) // if the user wants to keep the baseline ...
		baseLine.segments.add(event.point); // ... draw the path from the last point to the point where the mouse is at the moment
	
	if(targetblazer == false) // test if targetblaze option is set
	{
		if (randomize == true) // test if randomLength option is set
		{
			//for randomLength mode
			if(openDialog == true) // test if the dialog is open... 
			{
				randomMultiplier = randomMultiplierSpin.text; //... if open, use the randomMultiplier value from the dialog
			}
			 
			randomNumber = Math.round(Math.random() * randomMultiplier)/100; // get a random number based on the randomMultipler, set in the options dialog
			randomTarget = new Point(event.point.x * randomNumber, event.point.y * randomNumber); // create a new point which is the start point x and y value multiplied with the randomNumber
			target = event.point + randomTarget; // create the endpoint of the path, which is the randomPoint added to the startpoint
		}
		else
		{
			// for normal mode
			target = event.point + event.point; // create the endpoint, which is the distance to the zeropoint added to the startpoint (the distance to zero is equivalent to the startpoint)
		}
	}
	else
	{
		// for targetblazer mode
		target = new Point(0, 0); // create the endpoint, which is the zeropoint itself
	}
	
	path.lineTo(target);   // draw the path, to the endpoint, depending on the mode...
	group.appendTop(path);  // and add the path to a group
}

function onMouseUp(event)
{
	
}

// done!



