window.$e = function( id, s, e ) {
	var eo = new $e.prototype.init( id, s, e );
	eo.setSP(s);
	eo.setEP(e);
	eo.$( id );
	eo.element.method = eo;
	return eo;
}

window.$e.method = $e.prototype = {
	version: '1.0',
	element: '',
	eas: 0,
	frames: 50,
	unit: new Array(),
	
	init: function( id, s, e ) {
		var _curFrame =  0 ; // 現在のフレーム
		
		this.$( id );
		if( !this.element.easingMethod ) this.element.easingMethod = new Object();
		
		this.START = function( id ){
			if( !id ) return false;
			this.element.easingMethod[id] = {
				fn: this.LOOP( id, this ),
				cb: this.CALLBACK
			}
			this.element.easingMethod[id].fn( id, this );
		}
		
		this.LOOP = function( id, self, t ) {
			var _sp = this.sp;
			var _ep = this.ep;
			var _unit = this.unit;
			var _easing = this.eas;
			var _frames = this.frames;
			
			return function ( id, self ) {
				if( _curFrame++ < _frames ){
					var c = _curFrame / _frames ;
					var e = new Array();
					for( var i=0; i<_sp.length; i++ ) {
						e.push( ( parseInt( _ep[i] ) - parseInt( _sp[i] ) ) * ( c + _easing / ( 100 * Math.PI ) * Math.sin( Math.PI * c ) ) + parseInt( _sp[i] ) + _unit[i] );
					}
					if( typeof( self.MAIN ) == 'function' ) self.MAIN( e );
					var _self = self;
					setTimeout( function() {
						_self.element.easingMethod[id].fn( id, _self );
					}, 20 );
				} else {
					if( typeof( self.element.easingMethod[id].cb ) == 'function' ) {
						self.element.easingMethod[id].cb();
						self.element.easingMethod[id].cb = new Function();
					}
				}
			}
		}
	},
	
	setMethod: function( funcName, func ) {
		if( typeof( func ) == 'function' ) this.MAIN = func;
	},
	
	setCallBack: function( func ) {
		if ( typeof( func ) == 'function' ) this.CALLBACK = func;
	},
	
	$: function( obj ) {
		if( !obj ) {
			this.element = window;
		} else {
			var d = ( typeof( obj ) == 'string' ) ? document.getElementById( obj ) : obj;
			var date = new Date();
			date = 'easing' + date.getTime();
			if( !d.easingID ) d.easingID = date;
			this.element = d;
		}
	},
	
	setSP: function( s ) {
		if( typeof( s ) == 'undefined' ) return this;
		if( !( s instanceof Array ) ) this.sp = [ s ];
		else this.sp = s;		// 始点
		this.unit = new Array();
		for( var i=0; i<this.sp.length; i++ ) {
			String(this.sp[i]).match( /([0-9]+)(.*)/ );
			this.unit.push( RegExp.$2 );	//単位の取得
			this.sp[i] = parseInt( this.sp[i] );
		}
		
		return this;
	},
	
	setEP: function( e ) {
		if( typeof( e ) == 'undefined' ) return this;
		if( !( e instanceof Array ) ) this.ep = [ e ];
		else this.ep = e;	// 終点
		
		for( var i=0; i<this.ep.length; i++ ) {
			this.ep[i] = parseInt( this.ep[i] );
		}
		
		return this;
	},
	
	time: function( t ) {
		if( t == 'slow' ) this.frames = 80;
		else if( t == 'normal' ) this.frames = 50;
		else if( t == 'fast' ) this.frames = 20;
		else if( !!t && typeof( parseInt( t ) ) == 'number' ) this.frames = parseInt( t ) / 20;
		return this;
	},
	
	easing: function( e ) {
		if( parseInt( e ) > 100 ) {
			this.eas = 100;
		} else if( parseInt( e ) < -100 ) {
			this.eas = 100;
		} else {
			this.eas = parseInt( e );
		}
		
		return this;
	},
	
	defaultEasing: function( e ) {
		if( parseInt( e ) <= 100 && parseInt( e ) >= -100 ) {
			window.$e.prototype.eas = parseInt( e );
		}
		return this;
	},
	
	STOP: function( id ) {
		if( id && this.element.easingMethod[id] ) this.element.easingMethod[id].fn = function(){}
	},
	
	allSTOP: function() {
		if( this.element.easingMethod ) {
			for( var i in this.element.easingMethod ) {
				this.element.easingMethod[i].fn = new Function();
			}
		}
	}
}

window.$e.prototype.init.prototype = $e.prototype;