
/////////////////////////////////////////////////////////////////
//                      HappyAccidents
/////////////////////////////////////////////////////////////////
//
// Written by: Thomas Fors
//
// 10/31/2003 11:28PM
// Version Beta 2.2
// Added some contrast adjustments and re-wrote main randomizer code to
// work by category of "accident"
//
// 10/26/2003 9:19PM
// Version Beta 2.1
// Modifications made to library code.  This version now operates
// interactively only.
//
// 10/26/2003 0:28AM
// Version Beta 2
//
// 10/25/2003 11:34PM
// New build system to better manage code.
// Now applies PhotoKit effects in random order
// Combined PhotoKit and Tone betas into a single script.
//
// Version Beta 1, 10/25/03
// First beta release


/////////////////////////////////////////////////////////////////
//                   Module Functions
/////////////////////////////////////////////////////////////////
//
// 10/31/2003 11:03PM
// New file

// Had to create a random insert function fot the Array class because I get
// unhandled exception errors (even through I tried handling them!) when
// I try to use array.sort() with a random compare function and I don't
// know why.
function arr_RandomInsert(el) {
    var i;

    // Pick a random location
    var insertPos = rand(this.length);

    // Move the rest of the array down
    for ( i=this.length; i>insertPos; i-- ) {
        this[i] = this[i-1];
    }

    // Add it
    this[insertPos] = el;
}
Array.prototype.RandomInsert = arr_RandomInsert;


// Global list of "accidents" grouped by category
//
var gAccidentGroups = Array("Contrast", "BW", "Color", "SharpBlur", "Effects");
var gAccidents = new Array();
for ( i=0; i<gAccidentGroups.length; i++ ) {
    gAccidents[gAccidentGroups[i]] = new Array();
}

// Perform initialization of the modules
InitColoringModule();
InitToningModule();
InitContrastModule();
InitPhotoKitModule();



/////////////////////////////////////////////////////////////////
//                Random Number Generator
/////////////////////////////////////////////////////////////////
//
// 10/30/2003 0:08AM
// Fixed bug in rand() that could cause it to return an unexpected
// negative value
//
// 10/26/2003 7:06PM
// Added random function with gaussian distribution
//
// 10/25/2003 9:35PM
// Switched to new build system

// 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;
}



/////////////////////////////////////////////////////////////////
//                   Coloring Functions
/////////////////////////////////////////////////////////////////
//
// 10/31/2003 11:26PM
// Added init function.
//
// 10/26/2003 9:14PM
// Now use random function with gaussian distribution to choose
// hue.
//
// 10/25/2003 10:34PM
// Switched to new build system
// Added reporting for text file output in HappyAccident

// Register "accidents"
//
function InitColoringModule() {
    gAccidents["Color"].RandomInsert(Function("return RandomColorShift()"));
}

// Creates Hue/Saturation adjustment layer.  Hue and blending
// mode (Darken or Lighten) are set randomly
//
function RandomColorShift()
{
    var ret = "";
    var hue = rand_gaussian(1.5, -180, 180);
    var sat = -rand(100);
		var light = 0;
		var m = rand(1);
		var mode;
		if ( m > 0 )
				mode = "Drkn";
		else
				mode = "Lghn";

    ret = "Hue/Sat Adjustment Layer: Hue=" + hue + ", Sat=" + sat + ", Lightness=" + light + ", Blending Mode=";
    if ( m > 0 )
        ret += "Darken\r";
    else
        ret += "Lighten\r";

    // Ensure that there is a hue/sat adjustment layer named
    // Random ColorShift selected.
    try
    {
        docRef.activeLayer = docRef.layers["Random Color Shift"];
    }
    catch (err)
    {
        NewHueSatLayer("Random Color Shift");
    }

		//ScriptListener code
    var id8112 = charIDToTypeID( "setd" );
        var desc1787 = new ActionDescriptor();
        var id8113 = charIDToTypeID( "null" );
            var ref1166 = new ActionReference();
            var id8114 = charIDToTypeID( "AdjL" );
            var id8115 = charIDToTypeID( "Ordn" );
            var id8116 = charIDToTypeID( "Trgt" );
            ref1166.putEnumerated( id8114, id8115, id8116 );
        desc1787.putReference( id8113, ref1166 );
        var id8117 = charIDToTypeID( "T   " );
            var desc1788 = new ActionDescriptor();
            var id8118 = charIDToTypeID( "Adjs" );
                var list226 = new ActionList();
                    var desc1789 = new ActionDescriptor();
                    var id8119 = charIDToTypeID( "H   " );
                    desc1789.putInteger( id8119, hue );
                    var id8120 = charIDToTypeID( "Strt" );
                    desc1789.putInteger( id8120, sat );
                    var id8121 = charIDToTypeID( "Lght" );
                    desc1789.putInteger( id8121, light );
                var id8122 = charIDToTypeID( "Hst2" );
                list226.putObject( id8122, desc1789 );
            desc1788.putList( id8118, list226 );
        var id8123 = charIDToTypeID( "HStr" );
        desc1787.putObject( id8117, id8123, desc1788 );
    executeAction( id8112, desc1787, DialogModes.NO );

    var id8124 = charIDToTypeID( "setd" );
        var desc1790 = new ActionDescriptor();
        var id8125 = charIDToTypeID( "null" );
            var ref1167 = new ActionReference();
            var id8126 = charIDToTypeID( "Lyr " );
            var id8127 = charIDToTypeID( "Ordn" );
            var id8128 = charIDToTypeID( "Trgt" );
            ref1167.putEnumerated( id8126, id8127, id8128 );
        desc1790.putReference( id8125, ref1167 );
        var id8129 = charIDToTypeID( "T   " );
            var desc1791 = new ActionDescriptor();
            var id8130 = charIDToTypeID( "Md  " );
            var id8131 = charIDToTypeID( "BlnM" );
            var id8132 = charIDToTypeID( mode );
            desc1791.putEnumerated( id8130, id8131, id8132 );
        var id8133 = charIDToTypeID( "Lyr " );
        desc1790.putObject( id8129, id8133, desc1791 );
    executeAction( id8124, desc1790, DialogModes.NO );

    return ret;
}

// Creates a Hue/Sat adjustment layer with default settings.
//
function NewHueSatLayer(name)
{
    var id8096 = charIDToTypeID( "Mk  " );
        var desc1782 = new ActionDescriptor();
        var id8097 = charIDToTypeID( "null" );
            var ref1164 = new ActionReference();
            var id8098 = charIDToTypeID( "AdjL" );
            ref1164.putClass( id8098 );
        desc1782.putReference( id8097, ref1164 );
        var id8099 = charIDToTypeID( "Usng" );
            var desc1783 = new ActionDescriptor();
            var id8100 = charIDToTypeID( "Type" );
                var desc1784 = new ActionDescriptor();
                var id8101 = charIDToTypeID( "Clrz" );
                desc1784.putBoolean( id8101, false );
            var id8102 = charIDToTypeID( "HStr" );
            desc1783.putObject( id8100, id8102, desc1784 );
        var id8103 = charIDToTypeID( "AdjL" );
        desc1782.putObject( id8099, id8103, desc1783 );
    executeAction( id8096, desc1782, DialogModes.NO );

    var id8104 = charIDToTypeID( "setd" );
        var desc1785 = new ActionDescriptor();
        var id8105 = charIDToTypeID( "null" );
            var ref1165 = new ActionReference();
            var id8106 = charIDToTypeID( "Lyr " );
            var id8107 = charIDToTypeID( "Ordn" );
            var id8108 = charIDToTypeID( "Trgt" );
            ref1165.putEnumerated( id8106, id8107, id8108 );
        desc1785.putReference( id8105, ref1165 );
        var id8109 = charIDToTypeID( "T   " );
            var desc1786 = new ActionDescriptor();
            var id8110 = charIDToTypeID( "Nm  " );
            desc1786.putString( id8110, name );
        var id8111 = charIDToTypeID( "Lyr " );
        desc1785.putObject( id8109, id8111, desc1786 );
    executeAction( id8104, desc1785, DialogModes.NO );
}


/////////////////////////////////////////////////////////////////
//                   Toning Functions
/////////////////////////////////////////////////////////////////
//
// 10/31/2003 11:23PM
// Added init function
//
// 10/26/2003 8:14PM
// A and B channels of Lab color are now chosen based on a gaussian
// distribution to make the changes more subtle.  Also, wiggles quarter
// and 3/4 toning points around a little.
//
// 10/25/2003 10:21PM
// Switched to new build system

// Register "accidents"
//
function InitToningModule() {
    gAccidents["BW"].RandomInsert(Function("return RandomSplitTone()"));
}

// Applies random quarter and 3/4 tone colors to a gradient adjustment level
//
function RandomSplitTone()
{
    var ret = "";
		var r1, g1, b1, r2, g2, b2;
    var sigma = 0.30;
		var lab = new LabColor();
		var sc = new SolidColor();

    var l1, l2;
    l1 = rand_gaussian(1, 13, 38);
    l2 = rand_gaussian(1, 63, 88);

		// Ensure that there is a gradient adjustment layer named
		// Random Tone selected.
		try
		{
				docRef.activeLayer = docRef.layers["Random Tone"];
		}
		catch (err)
		{
				NewGradientMapLayer("Random Tone");
		}

		// Random quarter-tone color maintaining L of 25%
    lab.l = l1;
    lab.a = Math.abs(rand_gaussian(sigma, -127, 127));
    lab.b = Math.abs(rand_gaussian(sigma, -127, 127));
		sc.lab = lab;
		r1 = sc.rgb.red;
		g1 = sc.rgb.green;
		b1 = sc.rgb.blue;
    ret += "Gradient Map Adjustment Layer 0%=#000000, " + l1 + "%=#" + sc.rgb.hexValue;

		// Random 3/4 tone color maintaining L 0f 75%
    lab.l = l2;
    lab.a = Math.abs(rand_gaussian(sigma, -127, 127));
    lab.b = Math.abs(rand_gaussian(sigma, -127, 127));
		sc.lab = lab;
		r2 = sc.rgb.red;
		g2 = sc.rgb.green;
		b2 = sc.rgb.blue;
    ret += ", " + l2 + "%=#" + sc.rgb.hexValue + ", 100%=#FFFFFF\r";

		// ScriptListener code to change gradient
		var id139 = charIDToTypeID( "setd" );
		    var desc37 = new ActionDescriptor();
		    var id140 = charIDToTypeID( "null" );
		        var ref35 = new ActionReference();
		        var id141 = charIDToTypeID( "AdjL" );
		        var id142 = charIDToTypeID( "Ordn" );
		        var id143 = charIDToTypeID( "Trgt" );
		        ref35.putEnumerated( id141, id142, id143 );
		    desc37.putReference( id140, ref35 );
		    var id144 = charIDToTypeID( "T   " );
		        var desc38 = new ActionDescriptor();
		        var id145 = charIDToTypeID( "Grad" );
		            var desc39 = new ActionDescriptor();
		            var id146 = charIDToTypeID( "Nm  " );
		            desc39.putString( id146, "Custom" );
		            var id147 = charIDToTypeID( "GrdF" );
		            var id148 = charIDToTypeID( "GrdF" );
		            var id149 = charIDToTypeID( "CstS" );
		            desc39.putEnumerated( id147, id148, id149 );
		            var id150 = charIDToTypeID( "Intr" );
		            desc39.putDouble( id150, 4096.000000 );
		            var id151 = charIDToTypeID( "Clrs" );
		                var list13 = new ActionList();
		                    var desc40 = new ActionDescriptor();
		                    var id152 = charIDToTypeID( "Clr " );
		                        var desc41 = new ActionDescriptor();
		                        var id153 = charIDToTypeID( "Rd  " );
		                        desc41.putDouble( id153, 0.000000 );
		                        var id154 = charIDToTypeID( "Grn " );
		                        desc41.putDouble( id154, 0.000000 );
		                        var id155 = charIDToTypeID( "Bl  " );
		                        desc41.putDouble( id155, 0.000000 );
		                    var id156 = charIDToTypeID( "RGBC" );
		                    desc40.putObject( id152, id156, desc41 );
		                    var id157 = charIDToTypeID( "Type" );
		                    var id158 = charIDToTypeID( "Clry" );
		                    var id159 = charIDToTypeID( "UsrS" );
		                    desc40.putEnumerated( id157, id158, id159 );
		                    var id160 = charIDToTypeID( "Lctn" );
		                    desc40.putInteger( id160, 0 );
		                    var id161 = charIDToTypeID( "Mdpn" );
		                    desc40.putInteger( id161, 50 );
		                var id162 = charIDToTypeID( "Clrt" );
		                list13.putObject( id162, desc40 );
		                    var desc42 = new ActionDescriptor();
		                    var id163 = charIDToTypeID( "Clr " );
		                        var desc43 = new ActionDescriptor();
		                        var id164 = charIDToTypeID( "Rd  " );
		                        desc43.putDouble( id164, r1 );
		                        var id165 = charIDToTypeID( "Grn " );
		                        desc43.putDouble( id165, g1 );
		                        var id166 = charIDToTypeID( "Bl  " );
		                        desc43.putDouble( id166, b1 );
		                    var id167 = charIDToTypeID( "RGBC" );
		                    desc42.putObject( id163, id167, desc43 );
		                    var id168 = charIDToTypeID( "Type" );
		                    var id169 = charIDToTypeID( "Clry" );
		                    var id170 = charIDToTypeID( "UsrS" );
		                    desc42.putEnumerated( id168, id169, id170 );
		                    var id171 = charIDToTypeID( "Lctn" );
                        desc42.putInteger( id171, Math.round(l1*40.96) );
		                    var id172 = charIDToTypeID( "Mdpn" );
		                    desc42.putInteger( id172, 50 );
		                var id173 = charIDToTypeID( "Clrt" );
		                list13.putObject( id173, desc42 );
		                    var desc44 = new ActionDescriptor();
		                    var id174 = charIDToTypeID( "Clr " );
		                        var desc45 = new ActionDescriptor();
		                        var id175 = charIDToTypeID( "Rd  " );
		                        desc45.putDouble( id175, r2 );
		                        var id176 = charIDToTypeID( "Grn " );
		                        desc45.putDouble( id176, b2 );
		                        var id177 = charIDToTypeID( "Bl  " );
		                        desc45.putDouble( id177, b2 );
		                    var id178 = charIDToTypeID( "RGBC" );
		                    desc44.putObject( id174, id178, desc45 );
		                    var id179 = charIDToTypeID( "Type" );
		                    var id180 = charIDToTypeID( "Clry" );
		                    var id181 = charIDToTypeID( "UsrS" );
		                    desc44.putEnumerated( id179, id180, id181 );
		                    var id182 = charIDToTypeID( "Lctn" );
                        desc44.putInteger( id182, Math.round(l2*40.96) );
		                    var id183 = charIDToTypeID( "Mdpn" );
		                    desc44.putInteger( id183, 50 );
		                var id184 = charIDToTypeID( "Clrt" );
		                list13.putObject( id184, desc44 );
		                    var desc46 = new ActionDescriptor();
		                    var id185 = charIDToTypeID( "Clr " );
		                        var desc47 = new ActionDescriptor();
		                        var id186 = charIDToTypeID( "Rd  " );
		                        desc47.putDouble( id186, 255.000000 );
		                        var id187 = charIDToTypeID( "Grn " );
		                        desc47.putDouble( id187, 255.000000 );
		                        var id188 = charIDToTypeID( "Bl  " );
		                        desc47.putDouble( id188, 255.000000 );
		                    var id189 = charIDToTypeID( "RGBC" );
		                    desc46.putObject( id185, id189, desc47 );
		                    var id190 = charIDToTypeID( "Type" );
		                    var id191 = charIDToTypeID( "Clry" );
		                    var id192 = charIDToTypeID( "UsrS" );
		                    desc46.putEnumerated( id190, id191, id192 );
		                    var id193 = charIDToTypeID( "Lctn" );
		                    desc46.putInteger( id193, 4096 );
		                    var id194 = charIDToTypeID( "Mdpn" );
		                    desc46.putInteger( id194, 50 );
		                var id195 = charIDToTypeID( "Clrt" );
		                list13.putObject( id195, desc46 );
		            desc39.putList( id151, list13 );
		            var id196 = charIDToTypeID( "Trns" );
		                var list14 = new ActionList();
		                    var desc48 = new ActionDescriptor();
		                    var id197 = charIDToTypeID( "Opct" );
		                    var id198 = charIDToTypeID( "#Prc" );
		                    desc48.putUnitDouble( id197, id198, 100.000000 );
		                    var id199 = charIDToTypeID( "Lctn" );
		                    desc48.putInteger( id199, 0 );
		                    var id200 = charIDToTypeID( "Mdpn" );
		                    desc48.putInteger( id200, 50 );
		                var id201 = charIDToTypeID( "TrnS" );
		                list14.putObject( id201, desc48 );
		                    var desc49 = new ActionDescriptor();
		                    var id202 = charIDToTypeID( "Opct" );
		                    var id203 = charIDToTypeID( "#Prc" );
		                    desc49.putUnitDouble( id202, id203, 100.000000 );
		                    var id204 = charIDToTypeID( "Lctn" );
		                    desc49.putInteger( id204, 4096 );
		                    var id205 = charIDToTypeID( "Mdpn" );
		                    desc49.putInteger( id205, 50 );
		                var id206 = charIDToTypeID( "TrnS" );
		                list14.putObject( id206, desc49 );
		            desc39.putList( id196, list14 );
		        var id207 = charIDToTypeID( "Grdn" );
		        desc38.putObject( id145, id207, desc39 );
		    var id208 = charIDToTypeID( "GdMp" );
		    desc37.putObject( id144, id208, desc38 );
		executeAction( id139, desc37, DialogModes.NO );

    return ret;
}


// Creates a new Gradient Map Adjustment Layer set to a grayscale ramp
//
function NewGradientMapLayer(name)
{
		//  ScriptListener code to add new gradient layer
		var id3 = charIDToTypeID( "Mk  " );
		    var desc2 = new ActionDescriptor();
		    var id4 = charIDToTypeID( "null" );
		        var ref1 = new ActionReference();
		        var id5 = charIDToTypeID( "AdjL" );
		        ref1.putClass( id5 );
		    desc2.putReference( id4, ref1 );
		    var id6 = charIDToTypeID( "Usng" );
		        var desc3 = new ActionDescriptor();
        		var id1296 = charIDToTypeID( "Nm  " );
        		desc3.putString( id1296, name );
		        var id7 = charIDToTypeID( "Type" );
		            var desc4 = new ActionDescriptor();
		            var id8 = charIDToTypeID( "Grad" );
		                var desc5 = new ActionDescriptor();
		                var id9 = charIDToTypeID( "Nm  " );
		                desc5.putString( id9, "Custom" );
		                var id10 = charIDToTypeID( "GrdF" );
		                var id11 = charIDToTypeID( "GrdF" );
		                var id12 = charIDToTypeID( "CstS" );
		                desc5.putEnumerated( id10, id11, id12 );
		                var id13 = charIDToTypeID( "Intr" );
		                desc5.putDouble( id13, 4096.000000 );
		                var id14 = charIDToTypeID( "Clrs" );
		                    var list1 = new ActionList();
		                        var desc6 = new ActionDescriptor();
		                        var id15 = charIDToTypeID( "Clr " );
		                            var desc7 = new ActionDescriptor();
		                            var id16 = charIDToTypeID( "Rd  " );
		                            desc7.putDouble( id16, 0.000000 );
		                            var id17 = charIDToTypeID( "Grn " );
		                            desc7.putDouble( id17, 0.000000 );
		                            var id18 = charIDToTypeID( "Bl  " );
		                            desc7.putDouble( id18, 0.000000 );
		                        var id19 = charIDToTypeID( "RGBC" );
		                        desc6.putObject( id15, id19, desc7 );
		                        var id20 = charIDToTypeID( "Type" );
		                        var id21 = charIDToTypeID( "Clry" );
		                        var id22 = charIDToTypeID( "UsrS" );
		                        desc6.putEnumerated( id20, id21, id22 );
		                        var id23 = charIDToTypeID( "Lctn" );
		                        desc6.putInteger( id23, 0 );
		                        var id24 = charIDToTypeID( "Mdpn" );
		                        desc6.putInteger( id24, 50 );
		                    var id25 = charIDToTypeID( "Clrt" );
		                    list1.putObject( id25, desc6 );
		                        var desc8 = new ActionDescriptor();
		                        var id26 = charIDToTypeID( "Clr " );
		                            var desc9 = new ActionDescriptor();
		                            var id27 = charIDToTypeID( "Rd  " );
		                            desc9.putDouble( id27, 64 );
		                            var id28 = charIDToTypeID( "Grn " );
		                            desc9.putDouble( id28, 64 );
		                            var id29 = charIDToTypeID( "Bl  " );
		                            desc9.putDouble( id29, 64 );
		                        var id30 = charIDToTypeID( "RGBC" );
		                        desc8.putObject( id26, id30, desc9 );
		                        var id31 = charIDToTypeID( "Type" );
		                        var id32 = charIDToTypeID( "Clry" );
		                        var id33 = charIDToTypeID( "UsrS" );
		                        desc8.putEnumerated( id31, id32, id33 );
		                        var id34 = charIDToTypeID( "Lctn" );
		                        desc8.putInteger( id34, 1024 );
		                        var id35 = charIDToTypeID( "Mdpn" );
		                        desc8.putInteger( id35, 50 );
		                    var id36 = charIDToTypeID( "Clrt" );
		                    list1.putObject( id36, desc8 );
		                        var desc10 = new ActionDescriptor();
		                        var id37 = charIDToTypeID( "Clr " );
		                            var desc11 = new ActionDescriptor();
		                            var id38 = charIDToTypeID( "Rd  " );
		                            desc11.putDouble( id38, 191 );
		                            var id39 = charIDToTypeID( "Grn " );
		                            desc11.putDouble( id39, 191 );
		                            var id40 = charIDToTypeID( "Bl  " );
		                            desc11.putDouble( id40, 191 );
		                        var id41 = charIDToTypeID( "RGBC" );
		                        desc10.putObject( id37, id41, desc11 );
		                        var id42 = charIDToTypeID( "Type" );
		                        var id43 = charIDToTypeID( "Clry" );
		                        var id44 = charIDToTypeID( "UsrS" );
		                        desc10.putEnumerated( id42, id43, id44 );
		                        var id45 = charIDToTypeID( "Lctn" );
		                        desc10.putInteger( id45, 3072 );
		                        var id46 = charIDToTypeID( "Mdpn" );
		                        desc10.putInteger( id46, 50 );
		                    var id47 = charIDToTypeID( "Clrt" );
		                    list1.putObject( id47, desc10 );
		                        var desc12 = new ActionDescriptor();
		                        var id48 = charIDToTypeID( "Clr " );
		                            var desc13 = new ActionDescriptor();
		                            var id49 = charIDToTypeID( "Rd  " );
		                            desc13.putDouble( id49, 255.000000 );
		                            var id50 = charIDToTypeID( "Grn " );
		                            desc13.putDouble( id50, 255.000000 );
		                            var id51 = charIDToTypeID( "Bl  " );
		                            desc13.putDouble( id51, 255.000000 );
		                        var id52 = charIDToTypeID( "RGBC" );
		                        desc12.putObject( id48, id52, desc13 );
		                        var id53 = charIDToTypeID( "Type" );
		                        var id54 = charIDToTypeID( "Clry" );
		                        var id55 = charIDToTypeID( "UsrS" );
		                        desc12.putEnumerated( id53, id54, id55 );
		                        var id56 = charIDToTypeID( "Lctn" );
		                        desc12.putInteger( id56, 4096 );
		                        var id57 = charIDToTypeID( "Mdpn" );
		                        desc12.putInteger( id57, 50 );
		                    var id58 = charIDToTypeID( "Clrt" );
		                    list1.putObject( id58, desc12 );
		                desc5.putList( id14, list1 );
		                var id59 = charIDToTypeID( "Trns" );
		                    var list2 = new ActionList();
		                        var desc14 = new ActionDescriptor();
		                        var id60 = charIDToTypeID( "Opct" );
		                        var id61 = charIDToTypeID( "#Prc" );
		                        desc14.putUnitDouble( id60, id61, 100.000000 );
		                        var id62 = charIDToTypeID( "Lctn" );
		                        desc14.putInteger( id62, 0 );
		                        var id63 = charIDToTypeID( "Mdpn" );
		                        desc14.putInteger( id63, 50 );
		                    var id64 = charIDToTypeID( "TrnS" );
		                    list2.putObject( id64, desc14 );
		                        var desc15 = new ActionDescriptor();
		                        var id65 = charIDToTypeID( "Opct" );
		                        var id66 = charIDToTypeID( "#Prc" );
		                        desc15.putUnitDouble( id65, id66, 100.000000 );
		                        var id67 = charIDToTypeID( "Lctn" );
		                        desc15.putInteger( id67, 4096 );
		                        var id68 = charIDToTypeID( "Mdpn" );
		                        desc15.putInteger( id68, 50 );
		                    var id69 = charIDToTypeID( "TrnS" );
		                    list2.putObject( id69, desc15 );
		                desc5.putList( id59, list2 );
		            var id70 = charIDToTypeID( "Grdn" );
		            desc4.putObject( id8, id70, desc5 );
		        var id71 = charIDToTypeID( "GdMp" );
		        desc3.putObject( id7, id71, desc4 );
		    var id72 = charIDToTypeID( "AdjL" );
		    desc2.putObject( id6, id72, desc3 );
		executeAction( id3, desc2, DialogModes.NO );
}



/////////////////////////////////////////////////////////////////
//                   PhotoKit Functions
/////////////////////////////////////////////////////////////////
//
// 10/31/2003 11:23PM
// Added Init function
//
// 10/25/2003 9:37PM
// Switched to new build system

// 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 Burn 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() {
    if (activeDocument.bitsPerChannel == BitsPerChannelType.EIGHT) {
        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 );
}


/////////////////////////////////////////////////////////////////
//                   Contrast Functions
/////////////////////////////////////////////////////////////////
//
// 10/29/2003 11:38PM
// New file

// Register "accidents"
//
function InitContrastModule() {
    gAccidents["Contrast"].RandomInsert(Function("return RandomCurve()"));
    gAccidents["Contrast"].RandomInsert(Function("return RandomLocalContrastLayer()"));
}

// Apply a random slight curve adjustment layer
//
function RandomCurve()
{
    var ret = "";

    var x1 = rand_gaussian(1, 64-32, 64+32);
    var y1 = rand_gaussian(1, 64-32, 64+32);

    var x2 = rand_gaussian(1, 191-32, 191+32);
    var y2 = rand_gaussian(1, 191-32, 191+32);

    NewCurveLayer(0, 0, x1, y1, x2, y2, 255, 255);

    ret = "Curve Adjustment Layer: (0,0), (" + x1 + "," + y1 + "), (" + x2 + "," + y2 + "), (255,255)\r";

    return ret;
}

// Add curve adjustment layer.  Pass a list of in,out pairs.
//
function NewCurveLayer()
{
    var num = arguments.length/2;

    var id3 = charIDToTypeID( "Mk  " );
        var desc2 = new ActionDescriptor();
        var id4 = charIDToTypeID( "null" );
            var ref1 = new ActionReference();
            var id5 = charIDToTypeID( "AdjL" );
            ref1.putClass( id5 );
        desc2.putReference( id4, ref1 );
        var id6 = charIDToTypeID( "Usng" );
            var desc3 = new ActionDescriptor();
            var id7 = charIDToTypeID( "Type" );
                var desc4 = new ActionDescriptor();
                var id8 = charIDToTypeID( "Adjs" );
                    var list1 = new ActionList();
                        var desc5 = new ActionDescriptor();
                        var id9 = charIDToTypeID( "Chnl" );
                            var ref2 = new ActionReference();
                            var id10 = charIDToTypeID( "Chnl" );
                            var id11 = charIDToTypeID( "Chnl" );
                            var id12 = charIDToTypeID( "Cmps" );
                            ref2.putEnumerated( id10, id11, id12 );
                        desc5.putReference( id9, ref2 );
                        var id13 = charIDToTypeID( "Crv " );
                            var list2 = new ActionList();

                            var desc, ida, idb, idc;
                            for ( i=0; i<num; i++ )
                            {
                                desc = new ActionDescriptor();
                                ida = charIDToTypeID( "Hrzn" );
                                desc.putDouble( ida, arguments[2*i] );
                                idb = charIDToTypeID( "Vrtc" );
                                desc.putDouble( idb, arguments[2*i+1] );
                                idc = charIDToTypeID( "Pnt " );
                                list2.putObject(idc, desc);
                            }

                        desc5.putList( id13, list2 );
                    var id26 = charIDToTypeID( "CrvA" );
                    list1.putObject( id26, desc5 );
                desc4.putList( id8, list1 );
            var id27 = charIDToTypeID( "Crvs" );
            desc3.putObject( id7, id27, desc4 );
        var id28 = charIDToTypeID( "AdjL" );
        desc2.putObject( id6, id28, desc3 );
    executeAction( id3, desc2, DialogModes.NO );
}

// Creates a snapshot layer and applies a "Local Contrast Enhancement"
// as described on Luminous-Landscape.com
//
function RandomLocalContrastLayer()
{
    SnapshotLayer("Local Contrast Enhancement");

    var amount = rand_gaussian(3, 0, 24);
    var radius = rand_gaussian(3, 25, 75);
    UnsharpMask(amount, radius, 0);

    return "Unsharp Mask on flattened image: amount=" + amount + ", radius=" + radius + ", threshold=0\r";
}

// Applies unsharp mask filter
//
function UnsharpMask(amount, radius, threshold)
{
    var id1043 = charIDToTypeID( "UnsM" );
        var desc255 = new ActionDescriptor();
        var id1044 = charIDToTypeID( "Amnt" );
        var id1045 = charIDToTypeID( "#Prc" );
        desc255.putUnitDouble( id1044, id1045, amount );
        var id1046 = charIDToTypeID( "Rds " );
        var id1047 = charIDToTypeID( "#Pxl" );
        desc255.putUnitDouble( id1046, id1047, radius );
        var id1048 = charIDToTypeID( "Thsh" );
        desc255.putInteger( id1048, threshold );
    executeAction( id1043, desc255, DialogModes.NO );
}

// Temporarily flattens the image in order to make a snapshot layer
//
function SnapshotLayer(name)
{
    var nLayers = activeDocument.layers.length;
    if ( nLayers > 1 )
        nHist = -2;
    else
        nHist = -1;

    // Flatten Image
    var id859 = charIDToTypeID( "FltI" );
    executeAction( id859, undefined, DialogModes.NO );

    // Select All
    var id860 = charIDToTypeID( "setd" );
        var desc208 = new ActionDescriptor();
        var id861 = charIDToTypeID( "null" );
            var ref202 = new ActionReference();
            var id862 = charIDToTypeID( "Chnl" );
            var id863 = charIDToTypeID( "fsel" );
            ref202.putProperty( id862, id863 );
        desc208.putReference( id861, ref202 );
        var id864 = charIDToTypeID( "T   " );
        var id865 = charIDToTypeID( "Ordn" );
        var id866 = charIDToTypeID( "Al  " );
        desc208.putEnumerated( id864, id865, id866 );
    executeAction( id860, desc208, DialogModes.NO );

    // Copy
    var id867 = charIDToTypeID( "copy" );
    executeAction( id867, undefined, DialogModes.NO );

    // Back 2 History States
    var id868 = charIDToTypeID( "slct" );
        var desc209 = new ActionDescriptor();
        var id869 = charIDToTypeID( "null" );
            var ref203 = new ActionReference();
            var id870 = charIDToTypeID( "HstS" );
            ref203.putOffset( id870, nHist );
        desc209.putReference( id869, ref203 );
    executeAction( id868, desc209, DialogModes.NO );

    // New Layer
    var id871 = charIDToTypeID( "Mk  " );
        var desc210 = new ActionDescriptor();
        var id872 = charIDToTypeID( "null" );
            var ref204 = new ActionReference();
            var id873 = charIDToTypeID( "Lyr " );
            ref204.putClass( id873 );
        desc210.putReference( id872, ref204 );
        var id874 = stringIDToTypeID( "below" );
        desc210.putBoolean( id874, false );
        var id875 = charIDToTypeID( "Usng" );
            var desc211 = new ActionDescriptor();
            var id876 = charIDToTypeID( "Nm  " );
            desc211.putString( id876, name );
        var id877 = charIDToTypeID( "Lyr " );
        desc210.putObject( id875, id877, desc211 );
    executeAction( id871, desc210, DialogModes.NO );

    // Paste
    var id878 = charIDToTypeID( "past" );
        var desc212 = new ActionDescriptor();
        var id879 = charIDToTypeID( "AntA" );
        var id880 = charIDToTypeID( "Annt" );
        var id881 = charIDToTypeID( "Anno" );
        desc212.putEnumerated( id879, id880, id881 );
    executeAction( id878, desc212, DialogModes.NO );
}


/////////////////////////////////////////////////////////////////
// Main Code
/////////////////////////////////////////////////////////////////

if ( documents.length > 0 )
{
    try
    {
        // Get reference to active document
        var docRef = activeDocument;

        // Check version
        var ver = version.split(".");
        if ( ver[0] < 8 ) {
            // Not using Photoshop CS
            if (docRef.bitsPerChannel != BitsPerChannelType.EIGHT) {
                throw("This function only operates on 8 bit images.");
            }
        }

        // Check document type
        if ( docRef.mode != DocumentMode.RGB )
        {
            throw("This function only operates on RGB images.");
        }

      // 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;

      // Apply random effects
      var a = "";
      var accidents = new Array();
      while ( a == "" ) {
          for ( i=0; i<gAccidentGroups.length; i++ ) {
              if ( rand(1) && gAccidents[gAccidentGroups[i]].length ) {
                  numFromGroup = Math.abs(rand_gaussian(1, -2, 2)) + 1;
                  for (j=0; j<numFromGroup; j++)
                      accidents.RandomInsert(gAccidents[gAccidentGroups[i]][gAccidents[gAccidentGroups[i]].length - 1]);
              }
          }

          for ( i=0; i<accidents.length; i++ )
              a += accidents[i]();
      }

      // Move newly created Photokit layers to a layer set.
      var newLayerSet = docRef.layerSets.add();
      newLayerSet.name = "Random Adjustments";
      while (docRef.artLayers.length > numOriginalLayers)
          docRef.artLayers[0].moveToEnd(newLayerSet);
    }

    catch(e)
    {
        alert(e);
    }

}
