/** FXs 1.0 - classe degli effetti grafici **/
/** requires: item.js **/

/**
	classe FXs
	 Questa classe è adibita all'innesco e alla gestione degli effetti grafici.
	 Per fare un effetto grafico è sufficiente agganciare il temporizzatore 
	 d'eventi dell'oggetto ad un timer generale, e passare l'Item del tag da
	 modificare ad un metodo effettistico. Da quel momento sarà la classe che
	 si preoccuperà di effettuare l'effettistica.
**/

if(typeof FX=="undefined")
{
	// include Item
	if(typeof Item=="undefined")
		document.write('<script type="text/javascript" src="item.js"></script>');
	
	function FXs()
	{
		var _hooked=false;
		
		this.hook=function(){ 
			_hooked=true;
		};
		
		this.isHooked=function(){
			return _hooked;
		};
		
		// temporizzatore: da agganciare ad un timer
		this.snapGear=function(){
			_fadeIn();
			_fadeOut();	
			_moveToCenter();
			_stretchToSize();
		};
		
		// recupera dimensione finestra [0]=width [1]=height
		function windowSize() {
			var myWidth = 0, myHeight = 0, IE;
			if( typeof( window.innerWidth ) == 'number' ) {
			 //Non-IE
			 myWidth = window.innerWidth;
			 myHeight = window.innerHeight;
			 IE=0;
			} else if( document.documentElement && ( document.documentElement.clientWidth || document.documentElement.clientHeight ) ) {
			 //IE 6+ in 'standards compliant mode'
			 myWidth = document.documentElement.clientWidth;
			 myHeight = document.documentElement.clientHeight;
			 IE=1;
			} else if( document.body && ( document.body.clientWidth || document.body.clientHeight ) ) {
			 //IE 4 compatible
			 myWidth = document.body.clientWidth;
			 myHeight = document.body.clientHeight;
			 IE=1;
			}
			
			var res=new Array(myWidth,myHeight,IE);
			return res;
		};
		
		function clearQueue(method){
			for(var i=0;i<method.items.length;i++)
				method.items.pop();
		};
		
	
		
		/** Metodi pubblici degli effetti **/
		
		// Questo metodo mantiene un array di item che devono essere opacizzati, ad ogni chiamata
		// lo fa secondo i parametri passati nell'item (usa gli oggetti item, prelevati dinamicamente,
		// anche piu' di uno alla volta)
		this.fadeIn=function(){ 	// wrapper pubblico
			_fadeIn.apply(this,arguments);
		};
		function _fadeIn()
		{
			var this_f=_fadeIn;
			if(typeof this_f.items=="undefined")						// crea array degli item
				this_f.items=new Array();
			
			if(arguments.length)									// preleva items dai parametri e li inserisce nell'array (se non presenti)
			{
				for(var i=0;i<arguments.length;i++)				// ci sono uno o piu parametri
				{
					var arg=arguments[i];
					
					if(typeof _fadeOut.items!="undefined")
						_fadeOut.items.removeItem(arg);	// evita flickering
					
					if(!this_f.items.contains(arg))	//se non e' gia' presente
					{
						arg.init();						// inizializza per uso
						if(!arg.beginValue)
							arg.beginValue=0;
						if(!arg.targetValue)
							arg.targetValue=1;
						this_f.items.push(arg);		// inserisce
					}
				}
			}
			
			for(i=0;i<this_f.items.length;i++)							// per ogni item
			{
				var item=this_f.items[i];
				if(item.firstLoop)										// primo giro
				{
					item.firstLoop=false;
					item.setOpacity(item.beginValue);
					item.current=item.beginValue;						// current staccato per portabilita'
					item.show();
				}
				else															// giri successivi
				{
					item.setOpacity(item.current+item.speed);
					if(item.current>=item.targetValue)				// se raggiunge l'opacita' finale
					{
						item.setOpacity(item.targetValue);			// assegna il valore finale
						this_f.items.removeItem(item);						// rimuove dagli item
					}
					else
						item.current+=item.speed;						// ottimizzazione
				}
			}
		};
	
		// Questo metodo mantiene un array di item che devono essere deopacizzati, ad ogni chiamata
		// lo fa secondo i parametri passati nell'item (usa gli oggetti item, prelevati dinamicamente,
		// anche piu' di uno alla volta)
		this.fadeOut=function(){
			_fadeOut.apply(this,arguments);
		};
		function _fadeOut(){
			var this_f=_fadeOut;
			
			if(typeof this_f.items=="undefined")						// crea array degli item
				this_f.items=new Array();
			
			if(arguments.length)									// preleva items dai parametri e li inserisce nell'array (se non presenti)
			{
				for(var i=0;i<arguments.length;i++)				// ci sono uno o piu parametri
				{
					var arg=arguments[i];
					
					if(typeof _fadeIn.items!="undefined")
						_fadeIn.items.removeItem(arg);	// evita flick
					
					if(!this_f.items.contains(arg))			//se non e' gia' presente
					{
						arg.init();									// inizializza per uso
						if(!arg.beginValue)
							arg.beginValue=1;
						if(!arg.targetValue)
							arg.targetValue=0;
						this_f.items.push(arg);					// inserisce
					}
				}
			}
			
			for(i=0;i<this_f.items.length;i++)							// per ogni item
			{
				var item=this_f.items[i];
				if(item.firstLoop)										// primo giro
				{
					item.firstLoop=false;
					item.setOpacity(item.beginValue);
					item.current=item.beginValue;						// current staccato per portabilita'
					item.show();
				}
				else															// giri successivi
				{
					item.setOpacity(item.current-item.speed);
					if(item.current<=item.targetValue)				// se raggiunge l'opacita' finale
					{
						item.setOpacity(item.targetValue);			// assegna il valore finale
						this_f.items.removeItem(item);				// rimuove dagli item
						item.hide();
					}
					else
						item.current-=item.speed;						// ottimizzazione
				}
			}
		};
		
		// Sposta il tag al centro dello schermo (richiede position: absolute)
		this.moveToCenter=function(){
			_moveToCenter.apply(this,arguments);
		};
		function _moveToCenter()
		{
			var this_f=_moveToCenter;
			
			if(typeof this_f.items=="undefined")						// crea array degli item
				this_f.items=new Array();
			
			if(arguments.length)									// preleva items dai parametri e li inserisce nell'array (se non presenti)
			{
				for(i=0;i<arguments.length;i++)				// ci sono uno o piu parametri
				{
					var arg=arguments[i];

					if(!this_f.items.contains(arg))			//se non e' gia' presente
					{
						arg.init();									// inizializza per uso
						this_f.items.push(arg);					// inserisce
					}
				}
			}
			
			for(i=0;i<this_f.items.length;i++)
			{
				var item=this_f.items[i];
				if(!item.visible())
					continue;

				var size=windowSize();
				
				if(parseInt(item.speed)!=0)
				{
					var wpivot=item.wMidPivot();
					var hpivot=item.hMidPivot();
				
					// speed valorizzato spostamento interpolato
					if(wpivot<(size[0]/2)-item.speed)
						item.moveAtX(item.left()+item.speed);
					else
					{
						if(wpivot>(size[0]/2)+item.speed)
							item.moveAtX(item.left()-item.speed);
					}

					if(hpivot<(size[1]/2)-item.speed)
						item.moveAtY(item.top()+item.speed);
					else
					{
						if(hpivot>(size[1]/2)+item.speed)
							item.moveAtY(item.top()-item.speed);
					}
				}
				else
				{
					// speed 0 spostamento immediato
					item.moveAt((size[0]/2)-item.midWidth(),(size[1]/2)-item.midHeight());
				}
				
				if(!i)
					item.placeShadow();
			}
		};
		
		// Sposta il tag al centro del tag padre (richiede position: absolute)
		this.moveToParentCenter=function(){
			_moveToParentCenter.apply(this,arguments);
		};
		function _moveToParentCenter()
		{
			var this_f=_moveToParentCenter;
			
			if(typeof this_f.items=="undefined")						// crea array degli item
				this_f.items=new Array();
			
			if(arguments.length)									// preleva items dai parametri e li inserisce nell'array (se non presenti)
			{
				for(i=0;i<arguments.length;i++)				// ci sono uno o piu parametri
				{
					var arg=arguments[i];

					if(!this_f.items.contains(arg))			//se non e' gia' presente
					{
						arg.init();									// inizializza per uso
						this_f.items.push(arg);					// inserisce
					}
				}
			}
			
			for(i=0;i<this_f.items.length;i++)
			{
				var item=this_f.items[i];
				if(!item.visible())
					continue;

				var size=new Array();
				size[0]=item.beginValue;	// width
				size[1]=item.targetValue;	// height
				
				if(parseInt(item.speed)!=0)
				{
					var wpivot=item.wMidPivot();
					var hpivot=item.hMidPivot();
				
					// speed valorizzato spostamento interpolato
					if(wpivot<(size[0]/2)-item.speed)
						item.moveAtX(item.left()+item.speed);
					else
					{
						if(wpivot>(size[0]/2)+item.speed)
							item.moveAtX(item.left()-item.speed);
					}

					if(hpivot<(size[1]/2)-item.speed)
						item.moveAtY(item.top()+item.speed);
					else
					{
						if(hpivot>(size[1]/2)+item.speed)
							item.moveAtY(item.top()-item.speed);
					}
				}
				else
				{
					// speed 0 spostamento immediato
					item.moveAt((size[0]/2)-item.midWidth(),(size[1]/2)-item.midHeight());
				}
				
				if(!i)
					item.placeShadow();
			}
		};
		
		// item.beginValue=>w item.targetValue=>h
		// consigliata una velocita' pari per il ridimensionamento centrato
		this.stretchToSize=function(){
			_stretchToSize.apply(this,arguments);
		};
		function _stretchToSize()
		{
			var this_f=_stretchToSize;
			
			if(typeof this_f.items=="undefined")			// crea array degli item
				this_f.items=new Array();

			if(arguments.length)									// preleva items dai parametri e li inserisce nell'array (se non presenti)
			{
				for(i=0;i<arguments.length;i++)				// ci sono uno o piu parametri
				{
					var arg=arguments[i];

					if(!this_f.items.contains(arg))			// se non e' gia' presente
					{
						arg.init();									// inizializza per uso
						this_f.items.push(arg);					// inserisce
					}
				}
			}

			for(i=0;i<this_f.items.length;i++)
			{
				var ready=true;
				var item=this_f.items[i];
				var item_width=item.width();
				var item_height=item.height();
				
				var dest_w=parseInt(item.beginValue);
				var dest_h=parseInt(item.targetValue);
				var par_speed=item.speed-1;

				if(item_width>dest_w+par_speed)
				{
					//diminuisco di un terzo la width
					item.resize(-item.speed,0);
					item.move(item.speed/2,0);
					ready=false;
				}
				else
				{
					if(item_width<dest_w-par_speed)
					{
						//aumento di un terzo la width
						item.resize(item.speed,0);
						item.move(-(item.speed/2),0);
						ready=false;
					}
				}

				if(item_height>dest_h+par_speed)
				{
					//diminuisco di un terzo la height
					item.resize(0,-item.speed);
					item.move(0,item.speed/2);
					ready=false;
				}
				else
				{
					if(item_height<dest_h-par_speed)
					{
						//aumento di un terzo la height
						item.resize(0,item.speed);
						item.move(0,-(item.speed/2));
						ready=false;
					}
				}

				if(ready)
				{
					this_f.items.removeItem(item);	//rimuove l'item dalla lista
					if(typeof item.special=="function")
						item.special();				//chiama il suo metodo finale
				}

				if(!i)
					item.placeShadow();
			}
		};
	
	};	// fine "classe"
	
	var FX=new FXs();
}

