var vow_version = 3.9;
/*
VERSION:	3.9
3.9		Change: merged the any() everyTried() and allResolved() because they all do exactly the same thing.  (well almost. allResolved() used null instead of undefined. Now they all use undefined as the output for failed promises)
3.8		Change:	repeated calls to keep() or doBreak() are ignored instead of throwing errors
3.7		Fixed:  VOW.everyTried() wasn't correctly keeping count of promises as they resolved.  The count was only being updated when promises succeeded,  but was not updated each time one failed.
3.6		Added:  VOW.everyTried() function to wait for all promises to finish being attempted.  It's similar to VOW.every() except that it doesn't matter whether the promises succeed or fail, as long as they resolve.
3.5		Added:  VOW.failThru() function to automatically send the first failure output to the end of the promise-sequence.
3.4		Fixed:  "version" is no longer undefined
3.3		Added:  "version" property to:  VOW  VOW.make()  vow.promise
			Change:  "vow" objects and "promise" objects are now the exact same object.  (they already had most of the same functions anyway)
3.2		Change:  preApply()  can now store and use any number of parameters
3.1		Added  promise.then = function  can be used to create non-nested reactions.  promise.then( func )  still works.
			Fixed:  VOW.wait() was resolving instantly
			Warning: 		Attempting to use  .then=  with older versions of VOW will BREAK those versions!!  (A thorough re-compile is required EVERYWHERE that VOW has ever been used before .then= will ever be safe to use)
3.0		When a promise is broken,  all dependent promises are also broken  (regardless of how the fail function resolves)
2.9		Fixed VOW.runSequence() to always return a promise.
2.8		Added VOW.preApply()
2.7		Added promise.getValue()
2.6		Added VOW.wrap() which accepts an async function that resolves using a callback, and allows that function to be used within a promise-chain
2.5		Added VOW.runSequence() which calls an array of asynchronous functions in sequence, and returns a promise for the completion of the sequence.
2.4		Fixed VOW.firstWait() to not default to 1 second upon invalid input.
2.3		Fixed VOW.wait() so that received promise-chain values pass through it to the next function in the chain.

2.2		Fixed VOW.wait() so that it actually works within promise-chains.

2.1		Added getValue() to promise objects so that their resolved values can be read.

2.0		Added VOW.start() so a promise-chain can be started using any functions, like so:
				VOW.start()
				.then( normalFunc1 )
				.then( asyncFunc2 )
				.then( lastFunc, failFunc )

1.9		Fixed VOW.every() to handle empty arrays.  Now if there's nothing to wait for, then resume successfully instead of failing.

1.8		Fixed a memory leak:  where using my_prom.then() on completed promises used to re-call all of its previous listeners

1.7		Added vow.getStatus() so external code can determine the state of an un-sent promise		// "pending"  "kept"  "broken"

1.5		Revised forEach() to be a strictly local function instead of polluting the global Array object
			(It was conflicting with ZigoEngine)

1.4		Add:  VOW.firstWait() & VOW.wait()
	VOW.firstWait(500)
		.then( func )
		.then( VOW.wait(1000) )
		.then( func )
	
	func()
		.then( VOW.wait(1000) )
		.then( func )
		
1.3		VOW.wait has a default wait of 1 frame AKA 34 milliseconds
1.2		VOW.wait() added to allow setTimeout-style delays, like so:
				VOW.wait( 1000 ).then( doSomething );
1.1		keep() and doBreak() return their promise obj, to allow returning pre-kept promises like so:
				return VOW.make().keep()
				This allows async functions to be optionally be synchronous
	
	
FUNCTIONS
	VOW				Used to create vows & check promises
		everyTried		same as:  any, allResolved, everyTried		(failed promises output:  undefined)
		any						same as:  any, allResolved, everyTried		(failed promises output:  undefined)
		allResolved		same as:  any, allResolved, everyTried		(failed promises output:  undefined)		(was null in previous versions)
		make
		every
		first
		kept
		broken
		wait
		firstWait
		start
		runSequence
		wrap
		preApply
		failThru
		
	vow				Used by async functions that make promises
		promise
		keep
		doBreak
		getStatus
		getValue
	
	promise		Used to call reactions later when some async thing finishes
		is_promise
		then
		getStatus
		
				
USAGE:
	#include "functions/VOW.as"
	function doAsync( input ){
		var promise = VOW.make();
		onSucceed = function(){
			promise.keep( results );
		}
		onFail = function(){
			promise.doBreak( reason );
		}
		return promise;
	}// doAsync()
	
	doAsync("param A").then( useResults )
	
	
	
	var promiseState = promise.getStatus();		// "pending"  "kept"  "broken"
	
	
	
	promiseA = doAsync("param A");
	promiseB = doSomethingElse("param B");
	promiseC = doAsync("param C");
	VOW.every([
	 promiseA,
	 promiseB,
	 promiseC
	]).then( laterFunc );
	
	
	
	promiseB.then = function( result ){
		
	}
	
	
	
	VOW.start()
	.then( firstStep, VOW.failThru )
	.then( secondStep, VOW.failThru )
	.then( thirdStep, fail )
	
	
	
EXPLANATION:
	function doAsync()
		returns a promise and calls promise.keep() later on
	
	promise1.then( onSucceess, onFail );
		When this promise is kept, it calls the 1st function
		If this promise is broken, it calls the 2nd function
	
	VOW.every([ promise1, promise2 ]).then( handleResults );
	
	promiseB.then = function( result ){
		When this promise is kept,  run this function defined on the right.
		(WARNING:  Do not use this with older versions of VOW because it will break them!  Be certain that you are using a newer version of VOW before using this)
	
	promise1
		.then( handleResult1, onFail )	// use the result of promise1, then make promise2
		.then( handleResult2, onFail )	// use the result of promise2, then make promise3
		.then( handleResult3, onFail )	// use the result of promise3
		

CRED:
	This promise library is a derivative work.
	It was adapted from Douglas Crockford's JavaScript implementation, located here:
	https://github.com/douglascrockford/monad/blob/master/vow.js
	... and then tweaked, extended  (improved?)  by me.
	Major kudos to him for introducing me to this brilliant concept!
	I'll try not to be evil ;-)
*/



var vow_scope = function(){
	var version = vow_version;
	
	function forEach( array, callback){
		for(var i=0; i<array.length; i++){
			callback( array[i], i );
		}// for:  each item within this array
	}// forEach()
	
	
	
// enlighten is a helper function of herald and .then. It schedules the
// processing of all of the resolution functions in either the keepers queue
// or the breakers queue in later turns with the promise's fate.

	function enlighten(queue, fate){
		forEach(queue, function (func) {
			setTimeout(function(){
				func(fate);
			}, 0);// setTimeout()
		});// forEach()
	}// enlighten()
	
	
// The VOW object contains a .make function that is used to make vows.
// It may also contain other useful functions.
// In some mythologies, 'VOW' is called 'deferrer'.

	var vow_output = {
		version: version, 
		
// The make function makes new vows. A vow is a promise object and the
// two resolution functions (doBreak and keep) that determine the fate of the
// promise.  ("break" cannot be used as a function name because it is a protected keyword in Flash)

		make: function (){
			var breakers = [],					// .when's broken queue
					fate = undefined,				// The promise's ultimate value
					keepers = [], 					// .when's kept queue
					status = 'pending';			// 'broken'; 'kept'; or 'pending'
			
			
// enqueue is a helper function used by .then. It will append a function to
// either the keepers queue or the breakers queue.

			function enqueue (
												resolution, 	// 'keep' or 'break'
												func, 				// A function that was registered with .when
												vow){					// A vow that provides the resolution functions
				var queue = resolution === 'kept' 
					? keepers 
					: breakers;
				var isBroken = Boolean(queue === breakers);
				queue[queue.length] = typeof func !== 'function'
				
// If func is not a function, push the resolver so that the value passes to
// the next cascaded .then.

					? vow[resolution]
					
// If the func is a function, push a function that calls func with a value.
// The result can be a promise, or not a promise, or an exception.

					: function (value) {
						try {
							var result = func(value);
							
// If the result is a promise, then register our resolver with that promise.

							if(result && result.is_promise === true){
								if( isBroken ){
									// if:  promises are being broken,  then:  all dependent promises are also broken
									result.then( vow.doBreak, vow.doBreak );
								} else {
									result.then( vow.keep, vow.doBreak );
								} 
							}// if:  result is a promise
							
// But if it is not a promise, then use the result to resolve our promise.

							else
							{// if:  result is NOT a promise
								if( isBroken )		vow.doBreak( result );
								if( !isBroken )		vow.keep( result );
							}// if:  result is NOT a promise
						}// try
						
// But if func throws an exception, then break our promise.

						catch(e){
							vow.doBreak(e);
						}// catch
					}// queue[length] = func
			}// enqueue()
			
			
// The herald function is a helper function of break and keep.
// It seals the promise's fate, updates its status, enlightens
// one of the queues, and empties both queues.

			function herald (state, value, queue){
				/*	
				if(status !== 'pending'){
					 throw 'overpromise';		// do not resolve twice
				}// if:  this promise is already resolved
				*/
				if(status !== 'pending')		return;		// already resolved  =>  stop here and ignore this call
				fate = value;
				status = state;
				enlighten(queue, fate);
				//keepers.length = 0;
				//breakers.length = 0;
				keepers = [];
				breakers = [];
			}// herald()
			
			
// Construct and return the vow/promise object.

			// make() output is a promise object
			var promise = {
				version: vow_output.version, 
				
// The promise is an object with a .then method.

				is_promise: true,
				getStatus: function(){
					return status;
				},// getStatus()
				getValue: function(){
					return fate;
				},// getValue()
				
// The break method breaks the promise.

				doBreak: function (value){
					herald('broken', value, breakers);
					return this.promise;
				},// doBreak()
				
// The keep method keeps the promise.

				keep: function (value){
					herald('kept', value, keepers);
					return this.promise;
				}// keep()
			}// {promise}   {break, keep, promise}
			
			
// The .then method is the promise monad's bind. The .then method can take two
// optional functions. One of those functions may be called, depending on the
// promise's resolution. Both could be called if the the kept function throws.

			var set_then = function(kept, broken){
				
// Make a new vow/promise. Return the new promise.

				var promise = VOW.make();
				switch (status){
					
// If this promise is still pending, then enqueue both kept and broken.

					case 'pending':
						enqueue('kept', kept, promise);
						enqueue('break', broken, promise);
					break;
					
// If the promise has already been kept, then enqueue only the kept function,
// and enlighten it.

					case 'kept':
						enqueue('kept', kept, promise);
						enlighten(keepers, fate);
						keepers = [];
					break;
					
// If the promise has already been broken, then enqueue only the broken
// function, and enlighten it.

					case 'broken':
						enqueue('break', broken, promise);
						enlighten(breakers, fate);
						breakers = [];
					break;
				}// case: status
				return promise;
			}// then()
			// this allows the traditional promise.then() chaining  (a monad)
			function get_then(){
				return set_then;
			}
			
			// promise.then = set_then;
			// this allows  promise.then =  reaction
			promise.addProperty("then", get_then, set_then );
			
			// Legacy support for external code that assumes that vow's and promises are different objects
			promise.promise = promise;
			
			return promise;
		},// make()
		
		
// The every function takes an array of promises and returns a promise that
// will deliver an array of results only if every promise is kept.
// 
// The "every" function returns a promise whose then() gives an array containing
// the result of each promise ONLY if all promises succeeded.

		every: function (array){
			var remaining = array.length,
					results = [],
					vow = VOW.make();
			if(!remaining){
				vow.keep([]);
			}// if:  array is empty
			else
			{// if:  array has values
				forEach( array, function (promise, i){
					promise.then(
						function (value) {
							results[i] = value;
							remaining--;
							if(remaining === 0){
								vow.keep(results);
							}// if:  array counter is Zero
						},// success()
						function (reason) {
							remaining = null;
							vow.doBreak(reason);
						}// fail()
					);// then()
				});// array.forEach()
				
			}// if:  array has values
			return vow.promise;
		},// every()
		
		
// The everyTried() function takes an array of promises and returns a promise that
// will deliver an array of results only if every promise is resolved, succeed or fail.
// The result will contain an undefined element for each broken promise.
// 
// The "everyTried" function returns a promise whose then() gives an array containing
// the results of each promise. Promises that failed have an undefined value as
// their result.

		everyTried: function (array){
			var remaining = array.length,
					results = [],
					vow = VOW.make();
			if(!remaining){
				vow.keep([]);
			}// if:  array is empty
			else
			{// if:  array has values
				forEach( array, function (promise, i){
					promise.then(
						function (value) {
							results[i] = value;
							remaining--;
							if(remaining === 0){
								vow.keep( results );
							}// if:  array counter is Zero
						},// success()
						function ( failReason ) {
							results[i] = undefined;
							remaining--;
							if(remaining === 0){
								vow.keep( results );
							}// if:  array counter is Zero
						}// fail()
					);// then()
				});// array.forEach()
				
			}// if:  array has values
			return vow.promise;
		},// everyTried()
		

// The first function takes an array of promises and returns a promise to
// deliver the first observed kept promise, or a broken promise if all of
// the promises are broken.
// 
// The "first" function returns a promise whose then() gives the result 
// of the promise that completes first, ignoring all others.

		first: function (array){
			var found = false,
					remaining = array.length,
					vow = VOW.make();
			function check(){
				remaining--;
				if(remaining === 0  &&  !found){
					vow.doBreak();
				}// if:  no more items to check
			}// check()
			if(remaining === 0){
				vow.doBreak(array);
			}// if:  array was empty to begin with
			else
			{// if:  array has values
				forEach( array, function (promise){
					promise.then(
						function (value){
							if(!found){
								found = true;
								vow.keep(value);
							}//if:  found not updated yet
							check();
						},// success()
						check		// fail()
					);// then()
				});// array.forEach()
			}// if:  array has values
			return vow.promise;
		},// first()
		
		
// The VOW.kept() function immediately returns a successfully kept promise.
// This can be useful for testing purposes.
// This is also useful for beginning a promise chain, like so:
// 
// VOW.kept()
// .then( step1 )
// .then( step2 )
// .then( step3 )

		kept: function (value){
			var vow = VOW.make();
			vow.keep(value);
			return vow.promise;
		},// kept()
		
		
// The VOW.broken() function immediately returns a broken promise.
// This can be useful for testing purposes.

		broken: function (reason){
			var vow = VOW.make();
			vow.doBreak(reason);
			return vow.promise;
		},// broken()
		
		
// The VOW.wait() function is used to cause a pause in a promise chain.
// wait() accepts a number representing how long to wait.
// This function can be used like so:
// 
// step1()
// .then( step2 )
// .then( VOW.wait(1000) )
// .then( step3 )

		wait: function ( milliseconds ){
			var doWait = function( input ){
				milliseconds;		// this reference is needed or else this will resolve instantly
				var vow = VOW.make();
				var milliseconds = (milliseconds===undefined) ? 0 : milliseconds;
				setTimeout(function(){
					vow.keep(input);
				},
				milliseconds);
				return vow.promise;
			}// doWait()
			return doWait;
		},// wait()
		
		
// The VOW.firstWait() function is used to cause a delay, before starting a promise chain.
// firstWait() accepts a number representing how long to wait.
// This function can be used like so:
// 
// VOW.firstWait( 1000 )
// .then( step1 )
// .then( step2 )
// .then( step3 )

		firstWait: function (milliseconds){
			var vow = VOW.make();
			var milliseconds = (milliseconds===undefined) ? 0 : milliseconds;
			setTimeout(function() {
				vow.keep({});
				},
				milliseconds);
			return vow.promise;
		},// firstWait()
		
		
// The VOW.start() function immediately returns a successfully kept promise.
// This function is identical to VOW.kept()...
// ... and exists for the purpose of clearly expressing intent when starting a promise chain, like so:
// 
// VOW.start()
// .then( step1 )
// .then( step2 )
// .then( step3 )

		start: function (value){
			var vow = VOW.make();
			vow.keep(value);
			return vow.promise;
		},// start()
		
		
// The VOW.runSequence() function takes an array of async functions (which return promises) and returns a promise that
// represents the successful completion of the entire sequence.
// The sequence runs one function at a time,  with the next one starting only after the previous one finishes.
// 
// When runSequence() is called, it immediately begins running the first function in the sequence.

		runSequence: function ( sequence ){
			var prevPromise = VOW.make().keep();
			// var prevPromise = null;
			for(var s=0; s<sequence.length; s++){
				var thisStep = sequence[s];
				var newProm = prevPromise.then( thisStep );
				if( newProm.is_promise !== true )		newProm = VOW.kept();
				prevPromise = newProm;
			}// for:  each step in the sequence
			var finalPromise = prevPromise;
			return finalPromise;
		},// runSequence()
		
		
// The VOW.wrap() function takes a function reference, and an index number
// and outputs a function that gives a promise when called.
// The promise will deliver the first parameter passed to the callback function.

		wrap: function ( func, callbackIndex ){
			if( callbackIndex === undefined )		var callbackIndex = 0;
			return function(){
				var vow = VOW.make();
				
				if( callbackIndex === undefined )		var callbackIndex = arguments.length-1;
				
				arguments[callbackIndex] = function( output ){
					vow.keep( output );
				}
				func.apply( this, arguments );
				return vow.promise;
			}// return func ()
		},// wrap()
		
		
// The VOW.preApply() function takes a function reference, and any number of parameters and outputs a function.
// The parameters are stored at the time of definition.
// When this new function is run, it'll call the specified function and pass the stored parameters.

		preApply: function( func, param ){
			var args = arguments.slice( 1 );
			return function(){
				return func.apply( null, args );
				// return func( param );
			}// return func()
		},// preApply()
		
		
// The VOW.failThru() function is used as a default fail-function in a promise sequence,  allowing failures to pass their output down the chain to the final failure function...
// ... this means that if any promise in the sequence is broken, its output will be sent to the very last failure function
// The last failure function should be created specifically for that sequence.
		
		failThru: function( failReason ){
			return failReason
		},// failThru()
		
		
		
		null:null
	}// vow_output {}
	vow_output.any = vow_output.allResolved = vow_output.everyTried;
	
	return vow_output;
};// vow_scope()
var VOW = vow_scope();
delete vow_scope;
delete vow_version;