﻿var Animate;

Animate = function(elm){
	var _$ = this ;
	
	if(!Listener) throw new Error(_$.module.name+" Class : Listener Module Required")
	if(typeof elm == "string") elm = document.getElementById(elm);
	if(elm.style.position != "absolute") elm.style.position = "absolute";
	_$.element = elm;
	_$.defaultX = elm.offsetLeft;
	_$.defaultY = elm.offsetTop;
	_$.animating = false;
	_$.stopframe = null;
	
	Listener.add(window,"unload",function(){_$ = null});
};
Animate.easing = {
	def : function (of/* offset */,mf/* maxframe */,f/* frame */){
		//offset = α*maxframe*maxframe*maxframe;
		//α = offset/(maxframe*maxframe*maxframe)
		return (of/(mf*mf*mf))*f*f*f ;
	}
};
Animate.fx = {
	browser : {
		isIE : navigator.userAgent.indexOf("MSIE")!= -1,
		isSafari : navigator.userAgent.indexOf("Safari")!= -1,
		isFirefox : navigator.userAgent.indexOf("Firefox")!= -1,
		isMac : navigator.userAgent.indexOf("Macintosh")!= -1
	}
};

Animate.prototype = {
	constructor : Animate ,
	toString : function(){
		return this.module.name+" Class(instance) : Class Version "+this.module.ver;
	},
	module : {
		name : "Animate",
		ver : "1.0"
	},
	action : function(propvalue , easing , time , callback){
	
/*
propvalue : [Object CSS prop and value]
easing    : [String easing name]
time      : [Number animation time (1000 = 1sec)]
callback  : [function]
*/

		var _$ = this , _$fx = _$.constructor.fx , frame = 0 , maxframe = time/1000*40 , elm = _$.element ;
		act(elm);

		function act(elm){
			clearTimeout(_$.stopframe);
			_$.animating = true;
			
			if(frame > maxframe){
				_$.animating = false;
				if(callback) callback();
				return ;
			}
			
			var curStyle = elm.currentStyle || document.defaultView.getComputedStyle(elm,"");
			
			for(var prop in propvalue){
				
				var start ;
				switch(prop){
					case "opacity":
						if(_$fx.browser.isIE){
							(curStyle["filter"]).match(/opacity\s?=\s?(\d+)/);
							start = parseFloat((RegExp.$1 || 100)/100);
						}
						else start = parseFloat(curStyle[prop]);
						break;
					case "top":
					case "left":
						start = parseInt((curStyle[prop] == "auto") ? elm["offset"+(prop.charAt(0)).toUpperCase()+prop.substring(1)] : curStyle[prop]);
						break;
					default:
						start = parseInt(curStyle[prop]);
						break;
				}
				
				var end = propvalue[prop];
				var offset = end - start;
				//alert(prop + "  offset01 : " +  offset + "(" + end + " - " + start + ")");
				//offset = offset/maxframe;
				offset = Animate.easing[easing](offset,maxframe,frame);
				//alert(prop + "  offset02 : " +  offset);
				
				var n = (start + offset).toFixed(3);
				
				switch(prop){
					case "opacity":
						if(_$fx.browser.isIE) elm.style.filter = "alpha(opacity=" + n*100 + ")";
						else elm.style[prop] = n ;
						break;
					default:
						elm.style[prop] = n + "px";
						break;
				}
			}
			
			frame++;
			_$.stopframe = setTimeout(function(){act(elm);},time/maxframe);
		}
	},
	stop : function(){
		clearTimeout(this.stopframe);
	},
	fadeOut : function(time , callback){
		this.action({opacity:0},"def",time, callback);
	},
	fadeIn : function(time , callback){
		this.action({opacity:1},"def",time, callback);
	},
	fadeTo : function(time , num , callback){
		this.action({opacity:num},"def",time, callback);
	},
	flash : function(time , callback){
		var acttime = time/6;
		var _this = this ;
		
		this.action({opacity:0},"def",acttime, function(){
			_this.action({opacity:1},"def",acttime, function(){
				_this.action({opacity:0},"def",acttime, function(){
					_this.action({opacity:1},"def",acttime, function(){
						_this.action({opacity:0},"def",acttime, function(){
							_this.action({opacity:1},"def",acttime, callback);
						});
					});
				});
			});
		});
	}
};