
/**
* NOTE:
* For _alpha to render text correctly in IE6 and below 
* you must add a background color/image to the target 
* object/class that is not transparent.
*/

function Tween (target, prop, func, begin, finish, duration, useSeconds) {
	
	this._listeners = new Array();
	this.addListener(this);
	
	this.obj = (typeof target == "object") ? target : document.getElementById(target);
	this.setProp(prop);
	this.begin = begin;
	this.setPosition(begin);
	this.useSeconds = useSeconds;
	this.duration(duration);
	if (func) this.func = func;
	this.setFinish(finish);
	
	this.start();
	
}

Class(Tween);

Broadcaster.initialize(Tween.prototype, true);

Tween.prototype.onMotionFinished = new Function;
Tween.prototype.onMotionLooped = new Function;
Tween.prototype.onMotionChanged = new Function;
Tween.prototype.onMotionStarted = new Function;
Tween.prototype.started = false;
Tween.prototype.onMotionStopped = new Function;
Tween.prototype.onMotionResumed = new Function;

Tween.prototype.isPlaying = false;
Tween.prototype.obj = new Object();
Tween.prototype.prop = "";
Tween.prototype.func = function (t, b, c, d) { return c*t/d + b; };
Tween.prototype.begin = 0;
Tween.prototype.change = 0;
Tween.prototype.useSeconds = false;
Tween.prototype.prevTime = 0;
Tween.prototype.prevPos = 0;
Tween.prototype.looping = false;
Tween.prototype.fps = 30;
Tween.prototype._listeners = new Array();
Tween.prototype._duration = 0;
Tween.prototype._time = 0;
Tween.prototype._pos = 0;
Tween.prototype._fps = 0;
Tween.prototype._position = 0;
Tween.prototype._startTime = 0;
Tween.prototype._intervalID = 0;
Tween.prototype._finish = 0;

Tween.prototype.continueTo = function (finish, duration) {
	this.begin = this.getPosition(this._time);
	this.setFinish(finish);
	if (duration != undefined) {
		this.duration(duration);
	}
	this.started = false;
	this.start();
}

Tween.prototype.yoyo = function () {
	this.continueTo(this.begin, this._time);
}

Tween.prototype.start = function () {
	this.rewind();
	this.startEnterFrame();
	var classPointer = this;
	//var onMotionStartedTimeout = setTimeout(function() { classPointer.broadcastMessage.apply(classPointer, ["onMotionStarted", this]); }, 0);
	//this.broadcastMessage("onMotionStarted", this);
}

Tween.prototype.stop = function () {
	this.stopEnterFrame();
	this.broadcastMessage("onMotionStopped", this);
}

Tween.prototype.resume = function () {
	this.fixTime();
	this.startEnterFrame();
	this.broadcastMessage("onMotionResumed", this);
}

Tween.prototype.rewind = function (t) {
		this._time = (t == undefined) ? 0 : t;
		this.fixTime();
		this.update();
}

Tween.prototype.fforward = function () {
	this.time(this._duration);
	this.fixTime();
}

Tween.prototype.startEnterFrame = function () {
	var classPointer = this;
	this._intervalID = setInterval(function() { classPointer.onEnterFrame.apply(classPointer); }, 1000 / this.fps);
	this.isPlaying = true;
}

Tween.prototype.stopEnterFrame = function () {
	clearInterval (this._intervalID);
	this.isPlaying = false;
}

Tween.prototype.onEnterFrame = function () {
	if (!this.started) {
		this.broadcastMessage("onMotionStarted", this);
		this.started = true;
	}
	
	this.nextFrame();
}

Tween.prototype.nextFrame = function () {
	this.time(this._time + 1);
}

Tween.prototype.time = function (t) {
	this.prevTime = this._time;
	if (t > this._duration) {
		if (this.looping) {
			this.rewind (t - this._duration);
			this.update();
			this.broadcastMessage("onMotionLooped", this);
		} else {
			if (this.useSeconds) {
				this._time = this._duration;
				this.update();
			}
			this.stop();
			this.broadcastMessage("onMotionFinished", this);
		}
	} else if (t < 0) {
		this.rewind();
		this.update();
	} else {
		this._time = t;
		this.update();
	}
}

Tween.prototype.setProp = function (value) {
	switch (value) {
		case "_x" :
			this.prop = "left";
			break;
			
		case "_y" :
			this.prop = "top";
			break;
			
		case "_width" :
			this.prop = "height";
			break;
			
		case "_height" :
			this.prop = "height";
			break;
				
		case "_alpha" :
			this.prop = "opacity";
			break;
			
	}
}

Tween.prototype.setPosition = function (p) {
	this.prevPos = this._pos;
	this._pos = p;
	if (this.prop == "opacity") {
		
		if (this.obj.style[this.prop] != undefined) {
			this.obj.style[this.prop] = (p * .01);
		} else {
			/**
			* Forces IE html object to have "layout"
			* which allows filters to take affect.
			*/
			if (!this.obj.currentStyle.hasLayout) {
				this.obj.style.display = "inline-block";
			}
			
			this.obj.style.filter = "progid:DXImageTransform.Microsoft.Alpha(opacity = " + p + ")";
			/*
			if (this.obj.filters.length == 0) {
				this.obj.style.filter = "progid:DXImageTransform.Microsoft.Alpha(opacity = " + p + ")";
			} else {
				this.obj.filters.item("DXImageTransform.Microsoft.Alpha").opacity = p;
			}
			*/
		}
	} else {
		this.obj.style[this.prop] = p + "px";
	}
	
	this.broadcastMessage("onMotionChanged", this, this._pos);
}

Tween.prototype.getPosition = function (t) {
	if (t == undefined) t = this._time;
	return this.func(t, this.begin, this.change, this._duration);
}

Tween.prototype.duration = function (d) {
	if (this.useSeconds) d = (d == null || d <= 0) ? 0 : d * this.fps;
	this._duration = (d == null || d <= 0) ?  0 : d;
}

Tween.prototype.setFinish = function (f) {
	this.change = f - this.begin;
}

Tween.prototype.getFinish = function () {
	return this.begin + this.change;
}

Tween.prototype.prevFrame = function () {
	if (!this.useSeconds) this.time(this._time - 1);
}

Tween.prototype.fixTime = function () {
	if (this.useSeconds) this._startTime = this._time * 1000;
}

Tween.prototype.update = function () {
	this.setPosition(this.getPosition(this._time));
}
