function Tween(elem, valeurs){
	
	/*////////////////////////////////////////////////////////////////////////////////////////////////////////////
	
									V A R I B L E S
	
	////////////////////////////////////////////////////////////////////////////////////////////////////////////*/
	this.ips 	= 30;
	this.onComplete = new Function;
	this.transition = new Function;
	this.pos = 0; //entre 0 et 1 -> position du mouvement
	
	this._elem = elem;
	this._cur_vals;
	this._fin_vals;
	this._deb_vals;	
	this._temps;
	this._iter; // nombre d'iterations du mvt
	this._step;
	
	this.intervaux = new Array();
	

	
	/*////////////////////////////////////////////////////////////////////////////////////////////////////////////
	
									Mouvements
	
	////////////////////////////////////////////////////////////////////////////////////////////////////////////*/
	
	this._delay = function(temps, styl, arr,pos, step){
		
		var laclass = this;
		this.intervaux.push( setTimeout(function(){ laclass._pre_mouv(styl, step, arr); },temps) );
		
		this.pos = pos;
	}
	this._delayFin = function(temps, styl){
		var laclass = this;
		this.intervaux.push( setTimeout(function(){laclass._move(styl); laclass._finMvt()},temps) );
		this.pos = 1;
	}
	
	this._pre_mouv = function(styl, step,arr){	
		if(step === 0 || (step-1) == this._step ){
			this._move(styl);			
		}else{
		
		}
		this._cur_vals = this._copy_object(arr);
		this._step = step;
	}
	
	this.moveTo = function(to, temps){
		
		
		if(this._is_same_obj(to, this._fin_vals))return;
		
		this._stopMvt();
	
		this._iter = Math.ceil(temps / 1000 * this.ips);
		this._deb_vals = this._copy_object(this._cur_vals);
		this._fin_vals = this._copy_object(to);
		
		var pos = 0;
		var inter = 1/this._iter;
		var nms	= 1000/this.ips;
		for(var i=0; i<this._iter-1; i++){
			
			pos += inter;
			var inc = this.transition(pos);
			var ret = {};
			
			for(var e in this._fin_vals){				
				if(typeof(this._fin_vals[e]) == 'array' || typeof(this._fin_vals[e]) == 'object'){					
					ret[e] = new Array();
					for(var c=0; c<this._fin_vals[e].length;c++){						
						ret[e][c] = Math.round(this._deb_vals[e][c] + ((this._fin_vals[e][c] - this._deb_vals[e][c]) *inc));						
					}
				}else{
					ret[e] = this._deb_vals[e] + ((this._fin_vals[e] - this._deb_vals[e]) *inc);
				}	
			}
			
			var styl =this._to_style(ret);
			this._delay(nms*i,styl,ret, inc,i);
		}
		
		var styl =this._to_style(this._fin_vals);
		this._delayFin(nms*(this._iter-1), styl);
		
	}

	this._move = function(vals){
		for(var tt in vals){			
			this._elem.style[tt] = vals[tt];			
		}
	}
	
	this._finMvt = function(){
		this._deb_vals = this._copy_object(this._fin_vals);
		this._cur_vals =this._copy_object(this._fin_vals);
		this._fin();
	}
	
	this._fin = function(){
		this._deb_vals = this._copy_object(this._cur_vals);
		this.onComplete();
	}
	
	this._stopMvt = function(){
		for(var i =0; i<this.intervaux.length; i++){
			clearInterval(this.intervaux[i]);	
		}
	}
		
	/*////////////////////////////////////////////////////////////////////////////////////////////////////////////
	
									F O N C T T I O N S
	
	////////////////////////////////////////////////////////////////////////////////////////////////////////////*/
	
	this._copy_array = function(var_array){
		var ret = new Array();
		for(var i=0;i<var_array.length;i++){
			ret[i] = var_array[i];
		}
		return ret;
	}
	
	this._copy_object = function(var_obj){
		var ret = new Object;
		for(var ii in var_obj){
			if(typeof(var_obj[ii]) == 'array' || typeof(var_obj[ii]) == 'object'){
				ret[ii] = this._copy_array(var_obj[ii]);
			}else{
				ret[ii] = var_obj[ii];
			}
		}
		return ret;
	}
	
	this._is_same_obj = function(obj1, obj2){
			if(!obj2)return false;
			for(var ii in obj1){
				if(typeof(obj1[ii]) == 'array' || typeof(obj1[ii]) == 'object'){
					if(this._is_same_array(obj1[ii], obj2[ii]))return false;
				}else{
					if(obj1[ii] !== obj2[ii] )return false;
				}
			}
			return true;
	}
	
	this._is_same_array = function(ar1, ar2){
			for(var i=0;i<var_array.length;i++){
				if(obj1[i] !== obj2[i] )return false;
			}
			return true;
	}
	
	/*////////////////////////////////////////////////////////////////////////////////////////////////////////////
	
									P A R A M E T R E S
	
	////////////////////////////////////////////////////////////////////////////////////////////////////////////*/
	
	this._to_style = function(vals){
		var ret = {};
		for(var ii in vals){
			  if(ii != 'opacity'){
				  ret[ii] = this._getCssVal(ii, vals[ii]);
			  }else{
				var al = this._modAlpha(vals[ii]);
			  	ret[al.type] = al.val;				
			  }
		}	
		return ret;
	}
	
	this._getCssVal = function(param, val){
			
			
			if(!isNaN(val)){
				val = Math.floor(val);
			}
			switch(param){
				
				case 'height' :
				case 'width' :
				case 'minWidth' :
				case 'top' :
				case 'left' :
				case 'bottom' :
				case 'right' :
				case 'margin' :
				case 'marginTop' :
				case 'marginBottom' :
				case 'marginLeft' :
				case 'marginRight' :
				case 'padding' :
				case 'fontSize' :
					if(isNaN(val))return;	
					return val+'px';
				case 'opacity' :
					return val;
					
				case 'color' :
				case 'backgroundColor' :
					return this._mod_color(val);
			}
	}
	
	this._mod_color = function(vals){
		if(vals.length !=3)return;
		var color = vals.join(',');
		return 'rgb('+color+')';
	}
	
	
	this._modAlpha = function(opa){	
	
		if(document.all && !window.opera){ 
			if(opa<=99){
				return{'type':'filter', 'val':'progid:DXImageTransform.Microsoft.Alpha(Opacity=' + (opa) + ')'};
			}else{			
				return{'type':'filter', 'val':''};
			}
		}else{
			var val = opa/100;
			return{'type':'opacity', 'val':val};
		}
	}
	/*////////////////////////////////////////////////////////////////////////////////////////////////////////////
	
									T R A N S I T I O N S
	
	////////////////////////////////////////////////////////////////////////////////////////////////////////////*/
	
	this.linear = function(pos){
		return pos;
	}
	
	this.ease = function(pos){
			if(pos >= 1) return 1
			pos =  -(Math.cos(pos*(Math.PI)));
			pos +=1;
			return pos/2;
	}
	this.easeOut = function(pos){
			if(pos >= 1) return 1
			pos =  Math.sin(pos*(Math.PI/2));			
			return pos;
	}
	
	this.easeIn = function(pos){
			if(pos >= 1) return 1
			return pos*pos;
	}
	
	this.transition = this.easeIn;
	/*////////////////////////////////////////////////////////////////////////////////////////////////////////////
	
								I N I T I A L I S A T I O N
	
	////////////////////////////////////////////////////////////////////////////////////////////////////////////*/
	this._cur_vals	= this._copy_object(valeurs);
	var styl = this._to_style(this._cur_vals); 
	this._move(styl); // --- bouger le 1er truc
}
