/*
 * Written by: Thomas Fors
 *
 * $History: RandomPhotoKit.js $
 * 
 * *****************  Version 2  *****************
 * User: Tfors        Date: 11/13/03   Time: 11:29p
 * Updated in $/Web/fors.net/www/scripts/RandomPhotoKit
 * LABEL: Version 1.0
 * Updated to be compatible with Photokit 1.2.
 * Now supports 16-bit RGB images.
 * Changed 'Dodge Burn 2/3' to 'Dodge Right 2/3'.
 */


/////////////////////////////////////////////////////////////////
//                    RandomPhotoKit
/////////////////////////////////////////////////////////////////



/////////////////////////////////////////////////////////////////
//                Random Number Generator
/////////////////////////////////////////////////////////////////


// Generates a pseudo-random number from zero to max inclusive.
//
function rand(max) {
    return Math.round(Math.random()*max);
}

// Generates a random number with gaussian distribution over the
// range min to max.
//
function rand_gaussian(sigma, min, max) {
    var x, y, r2, z;

    do {
        // choose x,y in uniform square (-1,-1) to (1,1)
        x = -1.0 + 2.0 * Math.random();
        y = -1.0 + 2.0 * Math.random();

        // see if it is in the unit circle
        r2 = x*x + y*y;
    }
    while (r2 > 1.0 || r2 == 0);

    // Box-Muller transform
    z = (sigma * y * Math.sqrt( (-2.0 * Math.log(r2)) / r2 ));

    // Offset and clip to within min and max
    z /= 6.0;  // consider 6 sigma as full range
    z *= (max - min)/2.0;
    z += (max + min)/2.0;
    z = Math.round(z);
    z = Math.min(z, max);
    z = Math.max(z, min);
    return z;
}



/////////////////////////////////////////////////////////////////
//                   PhotoKit Functions
/////////////////////////////////////////////////////////////////


// This section defines the names of all the PhotoKit actions that
// can be called by the script.  If you would like to exclude any actions
// from being applied, simply comment out the line with a double slash.
//
var PhotoKitActions = new Array();
PhotoKitActions["SETS"] = new Array();
var set = 0;
var action=0;
PhotoKitActions["SETS"][set] = "B&W Toning Set";
PhotoKitActions[PhotoKitActions["SETS"][set]] = new Array();
PhotoKitActions[PhotoKitActions["SETS"][set]][action++] = "Sepia Tone #1";
PhotoKitActions[PhotoKitActions["SETS"][set]][action++] = "Sepia Tone #2";
PhotoKitActions[PhotoKitActions["SETS"][set]][action++] = "Sepia Tone #3";
PhotoKitActions[PhotoKitActions["SETS"][set]][action++] = "Cold Tone #1";
PhotoKitActions[PhotoKitActions["SETS"][set]][action++] = "Cold Tone #2";
PhotoKitActions[PhotoKitActions["SETS"][set]][action++] = "Cold Tone #3";
PhotoKitActions[PhotoKitActions["SETS"][set]][action++] = "Selenium Tone";
PhotoKitActions[PhotoKitActions["SETS"][set]][action++] = "Platinum Tone";
PhotoKitActions[PhotoKitActions["SETS"][set]][action++] = "Brown Tone";
set++; action=0;
PhotoKitActions["SETS"][set] = "Burn Tone Set";
PhotoKitActions[PhotoKitActions["SETS"][set]] = new Array();
PhotoKitActions[PhotoKitActions["SETS"][set]][action++] = "Burn Center Oval";
PhotoKitActions[PhotoKitActions["SETS"][set]][action++] = "Burn 4 Corners";
PhotoKitActions[PhotoKitActions["SETS"][set]][action++] = "Burn Top Corners";
PhotoKitActions[PhotoKitActions["SETS"][set]][action++] = "Burn Bottom Corners";
PhotoKitActions[PhotoKitActions["SETS"][set]][action++] = "Burn Top 1/4";
PhotoKitActions[PhotoKitActions["SETS"][set]][action++] = "Burn Top 1/3";
PhotoKitActions[PhotoKitActions["SETS"][set]][action++] = "Burn Top 1/2";
PhotoKitActions[PhotoKitActions["SETS"][set]][action++] = "Burn Top 2/3";
PhotoKitActions[PhotoKitActions["SETS"][set]][action++] = "Burn Bottom 1/4";
PhotoKitActions[PhotoKitActions["SETS"][set]][action++] = "Burn Bottom 1/3";
PhotoKitActions[PhotoKitActions["SETS"][set]][action++] = "Burn Bottom 1/2";
PhotoKitActions[PhotoKitActions["SETS"][set]][action++] = "Burn Bottom 2/3";
PhotoKitActions[PhotoKitActions["SETS"][set]][action++] = "Burn Left 1/4";
PhotoKitActions[PhotoKitActions["SETS"][set]][action++] = "Burn Left 1/3";
PhotoKitActions[PhotoKitActions["SETS"][set]][action++] = "Burn Left 1/2";
PhotoKitActions[PhotoKitActions["SETS"][set]][action++] = "Burn Left 2/3";
PhotoKitActions[PhotoKitActions["SETS"][set]][action++] = "Burn Right 1/4";
PhotoKitActions[PhotoKitActions["SETS"][set]][action++] = "Burn Right 1/3";
PhotoKitActions[PhotoKitActions["SETS"][set]][action++] = "Burn Right 1/2";
PhotoKitActions[PhotoKitActions["SETS"][set]][action++] = "Burn Right 2/3";
set++; action=0;
PhotoKitActions["SETS"][set] = "Color Balance Set";
PhotoKitActions[PhotoKitActions["SETS"][set]] = new Array();
PhotoKitActions[PhotoKitActions["SETS"][set]][action++] = "Warming 1";
PhotoKitActions[PhotoKitActions["SETS"][set]][action++] = "Warming 2";
PhotoKitActions[PhotoKitActions["SETS"][set]][action++] = "Warming 3";
PhotoKitActions[PhotoKitActions["SETS"][set]][action++] = "Warming 4";
PhotoKitActions[PhotoKitActions["SETS"][set]][action++] = "Cooling 1";
PhotoKitActions[PhotoKitActions["SETS"][set]][action++] = "Cooling 2";
PhotoKitActions[PhotoKitActions["SETS"][set]][action++] = "Cooling 3";
PhotoKitActions[PhotoKitActions["SETS"][set]][action++] = "Cooling 4";
PhotoKitActions[PhotoKitActions["SETS"][set]][action++] = "+Magenta";
PhotoKitActions[PhotoKitActions["SETS"][set]][action++] = "+Red";
PhotoKitActions[PhotoKitActions["SETS"][set]][action++] = "+Yellow";
PhotoKitActions[PhotoKitActions["SETS"][set]][action++] = "+Green";
PhotoKitActions[PhotoKitActions["SETS"][set]][action++] = "+Cyan";
PhotoKitActions[PhotoKitActions["SETS"][set]][action++] = "+Blue";
set++; action=0;
PhotoKitActions["SETS"][set] = "Color to B&W Set";
PhotoKitActions[PhotoKitActions["SETS"][set]] = new Array();
PhotoKitActions[PhotoKitActions["SETS"][set]][action++] = "Deep Red Contrast";
PhotoKitActions[PhotoKitActions["SETS"][set]][action++] = "1/2 Deep Red Contrast";
PhotoKitActions[PhotoKitActions["SETS"][set]][action++] = "Red Contrast";
PhotoKitActions[PhotoKitActions["SETS"][set]][action++] = "1/2 Red Contrast";
PhotoKitActions[PhotoKitActions["SETS"][set]][action++] = "Yellow Contrast";
PhotoKitActions[PhotoKitActions["SETS"][set]][action++] = "1/2 Yellow Contrast";
PhotoKitActions[PhotoKitActions["SETS"][set]][action++] = "Orange Contrast";
PhotoKitActions[PhotoKitActions["SETS"][set]][action++] = "1/2 Orange Contrast";
PhotoKitActions[PhotoKitActions["SETS"][set]][action++] = "Green Contrast";
PhotoKitActions[PhotoKitActions["SETS"][set]][action++] = "1/2 Green Contrast";
PhotoKitActions[PhotoKitActions["SETS"][set]][action++] = "Blue Contrast";
PhotoKitActions[PhotoKitActions["SETS"][set]][action++] = "1/2 Blue Contrast";
set++; action=0;
PhotoKitActions["SETS"][set] = "Dodge Tone Set";
PhotoKitActions[PhotoKitActions["SETS"][set]] = new Array();
PhotoKitActions[PhotoKitActions["SETS"][set]][action++] = "Dodge Center Oval";
PhotoKitActions[PhotoKitActions["SETS"][set]][action++] = "Dodge 4 Corners";
PhotoKitActions[PhotoKitActions["SETS"][set]][action++] = "Dodge Top Corners";
PhotoKitActions[PhotoKitActions["SETS"][set]][action++] = "Dodge Bottom Corners";
PhotoKitActions[PhotoKitActions["SETS"][set]][action++] = "Dodge Top 1/4";
PhotoKitActions[PhotoKitActions["SETS"][set]][action++] = "Dodge Top 1/3";
PhotoKitActions[PhotoKitActions["SETS"][set]][action++] = "Dodge Top 1/2";
PhotoKitActions[PhotoKitActions["SETS"][set]][action++] = "Dodge Top 2/3";
PhotoKitActions[PhotoKitActions["SETS"][set]][action++] = "Dodge Bottom 1/4";
PhotoKitActions[PhotoKitActions["SETS"][set]][action++] = "Dodge Bottom 1/3";
PhotoKitActions[PhotoKitActions["SETS"][set]][action++] = "Dodge Bottom 1/2";
PhotoKitActions[PhotoKitActions["SETS"][set]][action++] = "Dodge Bottom 2/3";
PhotoKitActions[PhotoKitActions["SETS"][set]][action++] = "Dodge Left 1/4";
PhotoKitActions[PhotoKitActions["SETS"][set]][action++] = "Dodge Left 1/3";
PhotoKitActions[PhotoKitActions["SETS"][set]][action++] = "Dodge Left 1/2";
PhotoKitActions[PhotoKitActions["SETS"][set]][action++] = "Dodge Left 2/3";
PhotoKitActions[PhotoKitActions["SETS"][set]][action++] = "Dodge Right 1/4";
PhotoKitActions[PhotoKitActions["SETS"][set]][action++] = "Dodge Right 1/3";
PhotoKitActions[PhotoKitActions["SETS"][set]][action++] = "Dodge Right 1/2";
PhotoKitActions[PhotoKitActions["SETS"][set]][action++] = "Dodge Right 2/3";
set++; action=0;
PhotoKitActions["SETS"][set] = "Image Enhancement Set";
PhotoKitActions[PhotoKitActions["SETS"][set]] = new Array();
PhotoKitActions[PhotoKitActions["SETS"][set]][action++] = "Edge Sharpen 1";
PhotoKitActions[PhotoKitActions["SETS"][set]][action++] = "Edge Sharpen 2";
PhotoKitActions[PhotoKitActions["SETS"][set]][action++] = "Edge Sharpen 3";
PhotoKitActions[PhotoKitActions["SETS"][set]][action++] = "Luminance Sharpen 1";
PhotoKitActions[PhotoKitActions["SETS"][set]][action++] = "Luminance Sharpen 2";
PhotoKitActions[PhotoKitActions["SETS"][set]][action++] = "Luminance Sharpen 3";
PhotoKitActions[PhotoKitActions["SETS"][set]][action++] = "Luminance Sharpen 4";
PhotoKitActions[PhotoKitActions["SETS"][set]][action++] = "High Pass Sharpen 1";
PhotoKitActions[PhotoKitActions["SETS"][set]][action++] = "High Pass Sharpen 2";
PhotoKitActions[PhotoKitActions["SETS"][set]][action++] = "High Pass Sharpen 3";
PhotoKitActions[PhotoKitActions["SETS"][set]][action++] = "Noise Reduction 1";
PhotoKitActions[PhotoKitActions["SETS"][set]][action++] = "Noise Reduction 2";
PhotoKitActions[PhotoKitActions["SETS"][set]][action++] = "Noise Reduction 3";
set++; action=0;
PhotoKitActions["SETS"][set] = "Photo Effects Set";
PhotoKitActions[PhotoKitActions["SETS"][set]] = new Array();
PhotoKitActions[PhotoKitActions["SETS"][set]][action++] = "Grain 50";
PhotoKitActions[PhotoKitActions["SETS"][set]][action++] = "Grain 100";
PhotoKitActions[PhotoKitActions["SETS"][set]][action++] = "Grain 200";
PhotoKitActions[PhotoKitActions["SETS"][set]][action++] = "Grain 400";
PhotoKitActions[PhotoKitActions["SETS"][set]][action++] = "Grain 800";
PhotoKitActions[PhotoKitActions["SETS"][set]][action++] = "Fog Effect #1";
PhotoKitActions[PhotoKitActions["SETS"][set]][action++] = "Fog Effect #2";
PhotoKitActions[PhotoKitActions["SETS"][set]][action++] = "Fog Effect #3";
PhotoKitActions[PhotoKitActions["SETS"][set]][action++] = "Fog Effect #4";
PhotoKitActions[PhotoKitActions["SETS"][set]][action++] = "Diffusion #1";
PhotoKitActions[PhotoKitActions["SETS"][set]][action++] = "Diffusion #2";
PhotoKitActions[PhotoKitActions["SETS"][set]][action++] = "Diffusion #3";
PhotoKitActions[PhotoKitActions["SETS"][set]][action++] = "Diffusion #4";
PhotoKitActions[PhotoKitActions["SETS"][set]][action++] = "Center Clear Blur #1";
PhotoKitActions[PhotoKitActions["SETS"][set]][action++] = "Center Clear Blur #2";
PhotoKitActions[PhotoKitActions["SETS"][set]][action++] = "Center Clear Blur #3";
PhotoKitActions[PhotoKitActions["SETS"][set]][action++] = "Black Rule 2px";
PhotoKitActions[PhotoKitActions["SETS"][set]][action++] = "Black Rule 3px";
PhotoKitActions[PhotoKitActions["SETS"][set]][action++] = "Black Rule 4px";
PhotoKitActions[PhotoKitActions["SETS"][set]][action++] = "Black Rule 6px";
PhotoKitActions[PhotoKitActions["SETS"][set]][action++] = "Black Rule 8px";
PhotoKitActions[PhotoKitActions["SETS"][set]][action++] = "Soft Black Rule Thin";
PhotoKitActions[PhotoKitActions["SETS"][set]][action++] = "Soft Black Rule Medium";
PhotoKitActions[PhotoKitActions["SETS"][set]][action++] = "Soft Black Rule Fat";
PhotoKitActions[PhotoKitActions["SETS"][set]][action++] = "Soft Edge Vignette 4px";
PhotoKitActions[PhotoKitActions["SETS"][set]][action++] = "Soft Edge Vignette 6px";
PhotoKitActions[PhotoKitActions["SETS"][set]][action++] = "Soft Edge Vignette 8px";
PhotoKitActions[PhotoKitActions["SETS"][set]][action++] = "Soft Edge Vignette 12px";
set++; action=0;
PhotoKitActions["SETS"][set] = "Tone Correction Set";
PhotoKitActions[PhotoKitActions["SETS"][set]] = new Array();
PhotoKitActions[PhotoKitActions["SETS"][set]][action++] = "Punch Blacks";
PhotoKitActions[PhotoKitActions["SETS"][set]][action++] = "Burn Shadows 1";
PhotoKitActions[PhotoKitActions["SETS"][set]][action++] = "Burn Shadows 2";
PhotoKitActions[PhotoKitActions["SETS"][set]][action++] = "Burn Shadows 3";
PhotoKitActions[PhotoKitActions["SETS"][set]][action++] = "Dodge Shadows 1";
PhotoKitActions[PhotoKitActions["SETS"][set]][action++] = "Dodge Shadows 2";
PhotoKitActions[PhotoKitActions["SETS"][set]][action++] = "Dodge Shadows 3";
PhotoKitActions[PhotoKitActions["SETS"][set]][action++] = "Punch Whites";
PhotoKitActions[PhotoKitActions["SETS"][set]][action++] = "Dodge Hilights 1";
PhotoKitActions[PhotoKitActions["SETS"][set]][action++] = "Dodge Hilights 2";
PhotoKitActions[PhotoKitActions["SETS"][set]][action++] = "Dodge Hilights 3";
PhotoKitActions[PhotoKitActions["SETS"][set]][action++] = "Burn Hilights 1";
PhotoKitActions[PhotoKitActions["SETS"][set]][action++] = "Burn Hilights 2";
PhotoKitActions[PhotoKitActions["SETS"][set]][action++] = "Burn Hilights 3";
PhotoKitActions[PhotoKitActions["SETS"][set]][action++] = "Contrast Mask 1";
PhotoKitActions[PhotoKitActions["SETS"][set]][action++] = "Contrast Mask 2";
PhotoKitActions[PhotoKitActions["SETS"][set]][action++] = "Contrast Mask 3";
PhotoKitActions[PhotoKitActions["SETS"][set]][action++] = "Boost Contrast 1";
PhotoKitActions[PhotoKitActions["SETS"][set]][action++] = "Boost Contrast 2";
PhotoKitActions[PhotoKitActions["SETS"][set]][action++] = "Boost Contrast 3";
PhotoKitActions[PhotoKitActions["SETS"][set]][action++] = "Plus 1/4";
PhotoKitActions[PhotoKitActions["SETS"][set]][action++] = "Plus 1/2";
PhotoKitActions[PhotoKitActions["SETS"][set]][action++] = "Plus 3/4";
PhotoKitActions[PhotoKitActions["SETS"][set]][action++] = "Plus 1";
PhotoKitActions[PhotoKitActions["SETS"][set]][action++] = "Minus 1/4";
PhotoKitActions[PhotoKitActions["SETS"][set]][action++] = "Minus 1/2";
PhotoKitActions[PhotoKitActions["SETS"][set]][action++] = "Minus 3/4";
PhotoKitActions[PhotoKitActions["SETS"][set]][action++] = "Minus 1";

// Comparison function for sorting array of set ranks
//
var setRank = new Array();
var setOrder = new Array();
function sortNumbers(a,b) {
		return setRank[a] - setRank[b];
}

// Register "accidents"
//
function InitPhotoKitModule() {
    gAccidents["Contrast"].RandomInsert(Function("return RandomPhotoKitFromSet(\"Burn Tone Set\")"));
    gAccidents["Contrast"].RandomInsert(Function("return RandomPhotoKitFromSet(\"Dodge Tone Set\")"));
    gAccidents["Contrast"].RandomInsert(Function("return RandomPhotoKitFromSet(\"Tone Correction Set\")"));

    gAccidents["BW"].RandomInsert(Function("return RandomPhotoKitFromSet(\"B&W Toning Set\")"));
    gAccidents["BW"].RandomInsert(Function("return RandomPhotoKitFromSet(\"Color to B&W Set\")"));

    gAccidents["Color"].RandomInsert(Function("return RandomPhotoKitFromSet(\"Color Balance Set\")"));

    gAccidents["SharpBlur"].RandomInsert(Function("return RandomPhotoKitFromSet(\"Image Enhancement Set\")"));

    gAccidents["Effects"].RandomInsert(Function("return RandomPhotoKitFromSet(\"Photo Effects Set\")"));
}

// Randomly selects PhotoKit actions to run from a set
//
function RandomPhotoKitFromSet(set) {
    var ret = "";
    docRef = activeDocument;

    action = PhotoKitActions[set][rand(PhotoKitActions[set].length - 1)];
    try {
        PhotoKit(set, action);
        action = "PhotoKit: " + set + " --> " + action + "\r";
    } catch (err) {
        // Ignore errors such as actions that don't exist
        action = "";
    }
    ret += action;

    return ret;
}


// Randomly selects PhotoKit actions to run
//
function RandomPhotoKit() {
		var ret = "";
		docRef = activeDocument;

		// Randomly run photokit actions
		var numSets = PhotoKitActions["SETS"].length;
    for (var i=0; i<numSets; i++ ) {
        setRank[i] = rand(100);
        setOrder[i] = i;
    }
    setOrder = setOrder.sort(sortNumbers);
    for (i=0; i<numSets; i++ ) {
        if ( setRank[setOrder[i]] > 50 ) {
            set = PhotoKitActions["SETS"][setOrder[i]];
            action = PhotoKitActions[set][rand(PhotoKitActions[set].length - 1)];
            try {
                PhotoKit(set, action);
                action = "PhotoKit: " + set + " --> " + action + "\r";
            } catch (err) {
                // Ignore errors such as actions that don't exist
                action = "";
            }
            ret += action;
        }
    }

		return ret;
}

// Applies a PixelGenius PhotoKit effect
//
function PhotoKit(set, effect)
{
		//Based on ScriptListener generated code
    var id3 = stringIDToTypeID( "Pixel Genius PhotoKit" );
		    var desc2 = new ActionDescriptor();
		    var id4 = charIDToTypeID( "PKSt" );
		    desc2.putString( id4, set );
		    var id5 = charIDToTypeID( "PKAc" );
		    desc2.putString( id5, effect );
		executeAction( id3, desc2, DialogModes.NO );
}


/////////////////////////////////////////////////////////////////
//                        Main Code
/////////////////////////////////////////////////////////////////

if ( documents.length > 0 )
{
	// Get reference to active document
	var docRef = activeDocument;

	// Only works on 8-bit RGB, CMYK, or LAB images
  if (  docRef.mode == DocumentMode.RGB )
	{
      // Remove the layer set from a previous run if it exists.
      var numLayerSets = docRef.layerSets.length;
      for ( i=0; i<numLayerSets; i++  ) {
          if (docRef.layerSets[i].name == "Random Adjustments")
              docRef.layerSets[i].remove();
      }

      //Save number of layers in original document
      var numOriginalLayers = docRef.artLayers.length;

			RandomPhotoKit();

      // Move newly created layers to a layer set.
      var newLayerSet = docRef.layerSets.add();
      newLayerSet.name = "Random Adjustments";
      while (docRef.artLayers.length > numOriginalLayers)
          docRef.artLayers[0].moveToEnd(newLayerSet);
	}
	else
	{
    alert( "This function only operates on 8 or 16-bit RGB documents" );
	}
}
else
{
	alert( "You must have a document open!" );
}
