/*	VERSION:	1.4
	1.4		More checks for "hasBeenAborted" to more aggressively avoid reacting after abort() or done()
	1.3		FIX:   Fixed a bug where tweens would not end when seconds is set to 0.3
	1.2		Added advanceFrame() to allow immediately advancing the animation frame / manually advance the animation
				Animation immediately starts before the next animation frame
	1.1		Tolerate redundant abort() calls,  by only resolving the promise if it's not already done.
	1.0

	DESCRIPTION:
		A simple tween system for times when Flash's native tween class is not available.
		Returns a promise instead of an interval;

	quikTween2( startAt, endAt, seconds, easeFunc )
	.then( animDone_func );

	USAGE:
		#include "functions/quikTween2.as"
		anim = quikTween2( 0, 300, 1, easeOut );
		anim.onProgress = function( value ){
			my_mc._x = value;
		}
		anim.then( done );
		
		// interrupting a tween during animation
		anim = quikTween2( 0, 300, 1, easeOut );
		anim.abort();
		
	EASING:
		easeLinear
		easeIn
		easeOut
		
	NOTE:
		This can also use Flash's native easing functions
*/
#include "functions/VOW.as"
function quikTween2( startAt, endAt, seconds, ease, fps ){
	var vow = VOW.make();
	
	if( !seconds ){
		trace("WARNING:  quickTween2 did not recieve 'seconds' parameter.  Using 0 seconds.");
		seconds = 0;
	}
	
	var fps = fps || 30;
	var frames = Math.floor( seconds * fps );
	var mag = endAt - startAt;
	var hasBeenAborted = false;
	var interval = null;
	
	function done(){
		if(vow.getStatus() === "pending")		vow.keep();
		vow.promise.advanceFrame = null;
		if(interval !== null)		clearInterval( interval );
		interval = null;
		hasBeenAborted = true;
	}// done()
	
	vow.promise.abort = function(){
		hasBeenAborted = true;
		done();
	}// abort()
	
	// if:  instant
	if( frames === 0 ){
		vow.promise.advanceFrame = function(){
			if( hasBeenAborted )		return;
			var value = endAt;
			vow.promise.onProgress( value );
			done();
		}// advanceFrame()
		setTimeout(function(){
			if(hasBeenAborted)		return;
			vow.promise.advanceFrame();
		}, 0);
	}// if:  instant
	
	// if:  animation has a length
	else{
		var frame = 0;
		vow.promise.advanceFrame = function(){
			if(hasBeenAborted)		return;
			frame++;
			var value = ease( frame, startAt, mag, frames );
			vow.promise.onProgress( value );
			if(frame >= frames){
				done();
			}
		}// advanceFrame()
		interval = setInterval( function(){
			if(hasBeenAborted)		return;
			vow.promise.advanceFrame();
		}, 33 );
		// "instantly" start animating  (move before the next frame)
		setTimeout(function(){
			if(hasBeenAborted)		return;
			vow.promise.advanceFrame();
		}, 0);
	}// if:  animation has a length
	
	return vow.promise;
}// quikTween()



function easeLinear( thisFrame, startAt, mag, totalFrames ){
	return mag * (thisFrame / totalFrames) + startAt;
}// easeLinear()

function easeIn( thisFrame, startAt, mag, totalFrames ){
	var pow = 3;
	var value = (thisFrame / totalFrames);
	var value = Math.pow(value, pow);
	var output = mag * value + startAt;
	return output;
}// easeIn()

function easeOut( thisFrame, startAt, mag, totalFrames ){
	var pow = 3;
	var value = (thisFrame / totalFrames);
	var value = 1 - Math.pow(1 - value, pow);
	var output = mag * value + startAt;
	return output;
}// easeOut()