// javascript animation action start
// 2005. 6. 26. by guoo.net
// 2005. 7. 2. modified by guoo.net

var Animation = {
	itemList : [],
	fps : 30,
	add : function(data) {
		if(!data.object) return;
		if(!data.effect) return;
		var item = null;
		item = new AnimationItem(data);
		item.fps = this.fps;
		this.itemList.push(item);
		return item;
	},
	remove : function(item) {
		item = null;
		this.itemList = this.itemList.without(item);
	}
}

var AnimationItem = Class.create();
AnimationItem.prototype = {
	isFinish : false, 
	timeout : '', 
	effect : '', 
	object : null, 
	spendTime : 0, 
	delayTime : 0, 
	currentTime : 0, 
	currentA : 0, 
	currentB : 0, 
	initA : 0, 
	initB : 0, 
	markA : 0, 
	markB : 0, 
	method : '', 
	ease : '', 
	fps : 30, 
	initialize : function(data) {
		if(!data.spendTime) data.spendTime = 1000;
		if(!data.ease) data.ease = 'normalTween';

		this.object = $(data.object);
		this.effect = data.effect;
		this.spendTime = $parseInt(data.spendTime);
		this.delayTime = $parseInt(data.delayTime);
		this.initA = data.initA;
		this.initB = data.initB;
		this.markA = data.markA;
		this.markB = data.markB;
		this.ease = data.ease;
		if(data.callback) this.callback = data.callback;
		if(data.raise) this.raise = data.raise;
	}, 
	start : function() {
		this.isFinish = false;
		if(this['action_'+this.effect]) {
			this.action = this['action_'+this.effect];
		}
		if(this.effect=='fade') {
			if(this.initA=='undefined') this.initA = 100;
			this.currentA = this.initA;
		}
		else if(this.effect=='move') {
			if(this.initA=='undefined') this.initA = this.object.offsetLeft;
			if(this.initB=='undefined') this.initB = this.object.offsetTop;
			this.currentA = this.initA;
			this.currentB = this.initB;
		}
		else if(this.effect == 'movex') {
			if(this.initA=='undefined') this.initA = this.object.offsetLeft;
			this.currentA = this.initA;
		}
		else if(this.effect == 'movey') {
			if(this.initA=='undefined') this.initA = this.object.offsetTop;
			this.currentA = this.initA;
		}
		else if(this.effect == 'size') {
			if(this.initA=='undefined') this.initA = Element.getWidth(this.object);
			if(this.initB=='undefined') this.initB = Element.getHeight(this.object);
			this.currentA = this.initA;
			this.currentB = this.initB;
		}
		else if(this.effect == 'width') {
			if(this.initA=='undefined') this.initA = Element.getWidth(this.object);
			this.currentA = this.initA;
		}
		else if(this.effect == 'height') {
			if(this.initA=='undefined') this.initA = Element.getHeight(this.object);
			this.currentA = this.initA;
		}

		this.timeout = setTimeout(this.tos.bind(this), this.delayTime);
	}, 
	tos : function() {
		this.raise(this);
		this.active(this);
	},
	pause : function() {
		clearTimeout(this.timeout);
	},
	stop : function() {
		clearTimeout(this.timeout);
		this.isFinish = true;
	},
	finish : function() {
		if(this.effect=='fade') {
			this.object.setStyle({
				opacity : this.markA/100
			});
		}
		else if(this.effect=='move') {
			this.object.style.left = this.markA + 'px';
			this.object.style.top = this.markB + 'px';
		}
		else if(this.effect == 'movex') {
			this.object.style.left = this.markA + 'px';
		}
		else if(this.effect == 'movey') {
			this.object.style.top = this.markA + 'px';
		}
		else if(this.effect == 'size') {
			this.object.style.width = this.markA + 'px';
			this.object.style.height = this.markB + 'px';
		}
		else if(this.effect == 'width') {
			if(this.markA < 0) {
				this.object.style.width = -this.markA + 'px';
				this.object.style.left = this.object.offsetLeft - this.markA + 'px';
			}else {
				this.object.style.width = this.markA + 'px';
			}
		}
		else if(this.effect == 'height') {
			if(this.markA < 0) {
				this.object.style.height = -this.markA + 'px';
				this.object.style.top = this.object.offsetTop - this.markA + 'px';
			}else {
				this.object.style.height = this.markA + 'px';
			}
		}
		this.callback(this);
		Animation.remove(this);
	}, 
	raise : function(item) {}, 
	callback : function(item) {}, 
	
	normalTween : function(t, d, b, c) {
		return c*t/d + b;
	},
	//QUADRATIC EASING: x^2
	easeInQuad : function(t, d, b, c) {
		return c*(t/=d)*t + b;
	},
	easeOutQuad : function(t, d, b, c) {
		return -c*(t/=d)*(t-2) + b;
	},
	easeInOutQuad : function(t, d, b, c) {
		if ((t/=d/2) < 1) return c/2*t*t + b;
		return -c/2 * ((--t)*(t-2) - 1) + b;
	},
	// CUBIC EASING: x^3
	easeInCubic : function(t, d, b, c) {
		return c*(t/=d)*t*t + b;
	},
	easeOutCubic : function(t, d, b, c) {
		return c*((t=t/d-1)*t*t + 1) + b;
	},
	easeInOutCubic : function(t, d, b, c) {
		if ((t/=d/2) < 1) return c/2*t*t*t + b;
		return c/2*((t-=2)*t*t + 2) + b;
	},
	// QUARTIC EASING: x^4
	easeInQuart : function(t, d, b, c) {
		return c*(t/=d)*t*t*t + b;
	},
	easeOutQuart : function(t, d, b, c) {
		return -c * ((t=t/d-1)*t*t*t - 1) + b;
	},
	easeInOutQuart : function(t, d, b, c) {
		if ((t/=d/2) < 1) return c/2*t*t*t*t + b;
		return -c/2 * ((t-=2)*t*t*t - 2) + b;
	},
	// QUINTIC EASING: x^5
	easeInQuint : function(t, d, b, c) {
		return c*(t/=d)*t*t*t*t + b;
	},
	easeOutQuint : function(t, d, b, c) {
		return c*((t=t/d-1)*t*t*t*t + 1) + b;
	},
	easeInOutQuint : function(t, d, b, c) {
		if ((t/=d/2) < 1) return c/2*t*t*t*t*t + b;
		return c/2*((t-=2)*t*t*t*t + 2) + b;
	},
	// SINUSOIDAL EASING: sin(x)
	easeInSine : function(t, d, b, c) {
		return c * (1 - Math.cos(t/d * (Math.PI/2))) + b;
	},
	easeOutSine : function(t, d, b, c) {
		return c * Math.sin(t/d * (Math.PI/2)) + b;
	},
	easeInOutSine : function(t, d, b, c) {
		return c/2 * (1 - Math.cos(t/d * Math.PI)) + b;
	},
	// EXPONENTIAL EASING: e^x
	easeInExpo : function(t, d, b, c) {
		return c * Math.pow(2, 10 * (t/d - 1)) + b;
	},
	easeOutExpo : function(t, d, b, c) {
		return c * (-Math.pow(2, -10 * t/d) + 1) + b;
	},
	easeInOutExpo : function(t, d, b, c) {
		if ((t/=d/2) < 1) return c/2 * Math.pow(2, 10 * (t - 1)) + b;
		return c/2 * (-Math.pow(2, -10 * --t) + 2) + b;
	},
	// CIRCULAR EASING: sqrt(1-x^2)
	easeInCirc : function(t, d, b, c) {
		return c * (1 - Math.sqrt(1 - (t/=d)*t)) + b;
	},
	easeOutCirc : function(t, d, b, c) {
		return c * Math.sqrt(1 - (t=t/d-1)*t) + b;
	},
	easeInOutCirc : function(t, d, b, c) {
		if ((t/=d/2) < 1) return c/2 * (1 - Math.sqrt(1 - t*t)) + b;
		return c/2 * (Math.sqrt(1 - (t-=2)*t) + 1) + b;
	},
	easeSine : function(t, d, b, c) {
		var g=c*0.7*Math.sin(t*Math.PI/d);
		return Math.easeInQuad(t, d, b, c)+ g;
	},
	elastic : function(t, d, b, c, eb, ec) {
		var g=c*Math.exp(-eb*t/d)*Math.cos((ec*2-1)/2*t*Math.PI/d);
		return c+b-g;
	},
	getCurrentValue : function(id, t, d, b, c) {
		if(id=='elastic') {
			return this.elastic(t, d, b, c, 5, 7);
		}else if(this[id]) {
			return this[id](t, d, b, c);
		}else {
			return this.normalTween(t, d, b, c);
		}
	}, 
	action_fade : function() {
		this.currentA = this.getCurrentValue(this.ease, this.currentTime, this.spendTime, this.initA, (this.markA - this.initA));

		$(this.object).setStyle({
			opacity : this.currentA / 100
		});
	}, 
	action_move : function() {
		this.currentA = this.getCurrentValue(this.ease, this.currentTime, this.spendTime, this.initA, (this.markA - this.initA));
		this.currentB = this.getCurrentValue(this.ease, this.currentTime, this.spendTime, this.initB, (this.markB - this.initB));
		this.object.style.left = this.currentA + 'px';
		this.object.style.top = this.currentB + 'px';
	}, 
	action_size : function() {
		this.currentA = this.getCurrentValue(this.ease, this.currentTime, this.spendTime, this.initA, (this.markA - this.initA));
		this.currentB = this.getCurrentValue(this.ease, this.currentTime, this.spendTime, this.initB, (this.markB - this.initB));
		this.object.style.width = this.currentA + 'px';
		this.object.style.height = this.currentB + 'px';
	}, 
	action_movex : function() {
		this.currentA = this.getCurrentValue(this.ease, this.currentTime, this.spendTime, this.initA, (this.markA - this.initA));
		this.object.style.left = this.currentA + 'px';
	}, 
	action_movey : function() {
		this.currentA = this.getCurrentValue(this.ease, this.currentTime, this.spendTime, this.initA, (this.markA - this.initA));
		this.object.style.top = this.currentA + 'px';
	}, 
	action_height : function() {
		if(this.markA < 0) {
			this.currentA = this.getCurrentValue(this.ease, this.currentTime, this.spendTime, this.initA, (-this.markA - this.initA));
			this.object.style.height = this.currentA;
			this.object.style.left = this.object.offsetLeft - this.currentA + 'px';
		}else {
			this.currentA = this.getCurrentValue(this.ease, this.currentTime, this.spendTime, this.initA, (this.markA - this.initA));
			this.object.style.height = this.currentA + 'px';
		}
	}, 
	action_width : function() {
		if(this.markA < 0) {
			this.currentA = this.getCurrentValue(this.ease, this.currentTime, this.spendTime, this.initA, (-this.markA - this.initA));
			this.object.style.width = this.currentA + 'px';
			this.object.style.left = this.object.offsetLeft - this.currentA + 'px';
		}else {
			this.currentA = this.getCurrentValue(this.ease, this.currentTime, this.spendTime, this.initA, (this.markA - this.initA));
			this.object.style.width = this.currentA + 'px';
		}
	}, 
	action_set : function() {
		if(!this.isFinish) {
			this.object.style[initA] = markA;
		}
	}, 
	action : function() {}, 	
	active : function() {
		if(this.currentTime > this.spendTime) this.currentTime = this.spendTime;

		if(!this.isFinish) {
			this.action();
			this.timeout = setTimeout(this.active.bind(this), this.fps);
		}
		if(this.currentTime>=this.spendTime || this.isFinish) {
			this.isFinish = true;
			this.finish();
		}
		this.currentTime = this.currentTime + this.fps;
	}
}

// javascript animation action finish