/***
*
*  TweenChain: makes chaining tweens easy !
*    *** smoothing = 0 --> there is no delay before calling this tween 
*    *** smoothing = 1 --> the tween starts when the previous tween ends
*    *** smoothing = x --> the tween starts at t = ([when the previous tween starts] + smoothing * [duration of previous tween])
*    
***/
var TweenChain = new Class({
        //
		//  initialize
		//
		Implements: [Options,Events],
		options: {
				duration: 750,
				smoothing: 1,
				transition: null,
				completeEvent: "TWEEN_COMPLETE",
				init_delay: 0
		},
		initialize: function(elm,options){
				this.setOptions(options)
				this.tweens = []
				this.chains = []
				this.element = document.id(elm)
				this.startTime = this.options.init_delay
				this.totalTime = 0
				this.duration = 0
				this.smoothing = 0
				this.length = 0
				this.isTweenChain = true
		},
		start: function(elm){
				if (elm) this.element = document.id(elm)
				this.tweens.each(function(obj,index){
						this.tweenObject(obj,index == this.length - 1)		
				}.bind(this))
				this.chains.each(function(obj){
						var start = function(obj){
								obj.tweenChain.start(obj.element)
						}
						start.delay(obj.startTime,this,obj)
				}.bind(this))
		},
		link: function(elm,typ,val,s,dur,evnt,trans){
				this.linkElement = elm
				this.type = typ
				this.value = val
				this.event = evnt
				this.trans = trans ? trans : this.options.transition
				this.smoothing = (s || s === 0) ? Math.max(s,0) : this.options.smoothing
				this.startTime += this.duration * this.smoothing
				this.duration = (dur || dur === 0) ? Math.max(dur,0) : this.options.duration
				this.totalTime = Math.max(this.startTime + this.duration,this.totalTime)
				var obj = new Object({
						linkElement:elm,
						type:typ,
						value:val,
						ovalue:null,
						event:evnt,
						startTime: this.startTime,
						duration: this.duration,
						transition: this.transition
				})
				this.tweens.push(obj)
				this.length++
				return this
		},
		add: function(typ,val,s,dur,evnt,trans){
				return this.link(this.linkElement,typ,val,s,dur,evnt,trans)
		},
		again: function(val){
				return this.link(this.linkElement,this.type,val,1,this.duration,this.transition)
		},
		bounce: function(){
				return this.link(this.linkElement,'bounce',null,1,this.duration,this.transition)
		},
		linkChain: function(tchain,elm,s) {
				s = (s || s === 0) ? Math.max(s,0) : this.options.smoothing
				this.startTime = s * this.totalTime
				this.totalTime = Math.max(this.startTime + tchain.totalTime,this.totalTime)
				var obj = new Object({
						tweenChain:tchain,
						element:elm,
						startTime:this.startTime
				})
				this.chains.push(obj)
				return this
		},
		setElement: function(elm){
				this.element = document.id(elm)
		},
		tweenObject: function(obj,last){
				var elm = this.element ? this.element : obj.linkElement
				if (obj.type != 'bounce') obj.ovalue = document.id(elm).getStyle(obj.type)
				else {
						obj.type = this.currentObj.type
						obj.value = this.currentObj.ovalue
						obj.ovalue = this.currentObj.value
				} 
				this.currentObj = obj
				var twn = new Fx.Tween(elm,{
						duration:obj.duration,
						transition:obj.transition,
						onComplete:	function(){
								if (obj.event) {
										this.eventTarget = elm
										this.fireEvent(obj.event)
								}		
								if (last && this.options.completeEvent) {
										this.eventTarget = elm
										this.fireEvent(this.options.completeEvent)
								}		
						}.bind(this)
				})
				var start = function(twn){
						twn.start(obj.type,obj.value)
				}
				start.delay(obj.startTime,this,twn)
				return this
		},
		toElement: function(){
				return this.element
		}
});
