/**
 * @namespace window.transition
 * @author patcla   
 * @version 1.0
 * @sdoc transition.sdoc
 */

/**
 * Object control for CSS transitions, don't extend this object. This object should be tailored to 
 * each sites needs and not be a 'do it all'. if you need loades of different types of transition use Moo.    
 * @id Transition
 * @alias transition
 * @constructor
 * @version	16.a 
 */
/** @id Transition */
function Transition(){

	this.fade			= Fade;
	this.fadeIn 		= FadeIn;
	this.fadeOut 		= FadeOut;
	this.drop			= Drop;
	this.dropIn			= DropIn;
	this.wipe			= Wipe;
	this.wipeOut		= WipeOut;
	this.pull			= Pull;
	this.pullOut		= PullOut;
	this.dropFirstChild = DropFirstChild;
	this.dropFirstChildClose = DropFirstChildClose;

	this.setHeight 		= SetHeight;
	this.setOpacity 	= SetOpacity;
	this.getElement		= GetElement;
	this.setStyle		= SetStyle;
	
	this.i				= 0;
	this.tempId			= 0;
	this.enablefilter	= false;
	
	
/**
 * Method, sets up the element and starts the pull interval.
 * @id Transition.Pull
 * @alias Pull
 * @memberOf Transition
 * @param {string} id
 * @param {int} increment
 * @return {Void} 
 */	
	/** @id Transition.Pull */
	function Pull(id,increment,speed,onfinish){
		speed = (speed)? speed : 10;
		var el = transition.getElement(id);
		if (!el){return};
		if (el.setInterval){
			clearInterval(el.setInterval);
			el.setInterval = null;			
		}
		el.increment 		= (increment) ? increment : 10;
		el.fixedEnd			= true;
		el.onfinish 		= onfinish;
		el.currentHeight 	= el.offsetHeight;
		el.style.height 	= el.currentHeight + 'px';
		el.setInterval = window.setInterval("transition.pullOut('"+el.id+"')",speed);

	}
/**
 * Method, reduces an elements height or clears the interval.
 * @id Transition.PullOut
 * @alias PullOut
 * @memberOf Transition
 * @param {string} id
 * @param {int} increment
 * @return {Void} 
 */	
	/** @id Transition.PullOut */
	function PullOut(id){
		var el = transition.getElement(id);
		el.increment = (el.increment*2);
		el.currentHeight-= el.increment;
		if (el.currentHeight <= 0){
			clearInterval(el.setInterval);
			el.setInterval = null; 
			el.currentHeight = el.style.height = 0;
			if (el.onfinish){
				if (typeof el.onfinish == 'string'){ eval(el.onfinish);}
				if (typeof el.onfinish == 'function'){ el.onfinish() ;}
			}
			loader.logger.log('pullout finished '+el.id+' height set ' + el.currentHeight)
		} else {
			transition.setStyle(el,'height',el.currentHeight+'px');
		}		
	}
		
/**
 * Method, sets up the element and starts the wipe interval.
 * @id Transition.Wipe
 * @alias Wipe
 * @memberOf Transition
 * @param {string} id
 * @param {int} increment
 * @return {Void} 
 */	
	/** @id Transition.Wipe */
	function Wipe(id,direction,increment,speed,onfinish){
		speed = (speed || 10);
		var el = transition.getElement(id);
		if (!el.container)
			el.container = transition.getElement(el.getElementsByTagName('div')[0]);
		if (!el){return};
		if (el.setInterval){
			clearInterval(el.setInterval);
			el.setInterval = null;			
		}
		el.increment 		= (increment || 10);
		el.fixedEnd			= true;
		el.onfinish 		= onfinish;
		el.targetOffset 	= (direction) ? parseInt( el.container.getStyle('left') ) + el.offsetWidth : parseInt( el.container.getStyle('left') ) - el.offsetWidth ;
		el.currentOffset	= parseInt( el.container.getStyle('left') );
		el.setInterval = window.setInterval("transition.wipeOut('"+el.id+"',"+direction+")",speed);

	}
/**
 * Method, reduces an elements width or clears the interval.
 * @id Transition.WipeOut
 * @alias WipeOut
 * @memberOf Transition
 * @param {string} id
 * @param {int} increment
 * @return {Void} 
 */	
	/** @id Transition.WipeOut */
	function WipeOut(id,direction){
		var el = transition.getElement(id);
		el.increment = (el.increment);
		if (direction){
			el.currentOffset+= el.increment;
		} else {
			el.currentOffset-= el.increment;
		}
		if (el.currentOffset <= el.targetOffset && !direction){
			clearInterval(el.setInterval);
			el.setInterval = null; 
			el.getElementsByTagName('div')[0].style.left = el.targetOffset + 'px';
			if (el.onfinish){
				if (typeof el.onfinish == 'string'){ eval(el.onfinish);}
				if (typeof el.onfinish == 'function'){ el.onfinish() ;}
			}
			loader.logger.log('wipeOut finished '+el.id );
		} else if (el.currentOffset >= el.targetOffset && direction){
			clearInterval(el.setInterval);
			el.setInterval = null; 
			el.getElementsByTagName('div')[0].style.left = el.targetOffset + 'px';
			if (el.onfinish){
				if (typeof el.onfinish == 'string'){ eval(el.onfinish);}
				if (typeof el.onfinish == 'function'){ el.onfinish() ;}
			}
			loader.logger.log('wipeOut finished '+el.id );
		} else {
			transition.setStyle(el.getElementsByTagName('div')[0],'left',el.currentOffset +'px');
		}		
	}
		
/**
 * Method, increments an elements height or clears the interval.
 * @id Transition.DropIn
 * @alias DropIn
 * @memberOf Transition
 * @param {string} id
 * @param {int} increment
 * @return {Void} 
 */	
	/** @id Transition.DropIn */
	function DropIn(id){
		var el = transition.getElement(id);
		el.increment = (el.increment*2);
		el.currentHeight+= el.increment;
		if (el.currentHeight >= el.targetHeight){
			clearInterval(el.setInterval);
			el.setInterval = null; 
			if(el.fixedEnd){
				transition.setStyle(el,'height',el.fixedEnd);
			} else {
				transition.setStyle(el,'height','auto');
			}
			if (el.onfinish){
				eval(el.onfinish);
			}
		} else {
			transition.setStyle(el,'height',el.currentHeight+'px')
		}
	}
	
	function DropFirstChild(el,tag,targetHeight,increment,speed,onfinish){
		if (el.getElementsByTagName(tag) && el.getElementsByTagName(tag)[0]){
			el = el.getElementsByTagName(tag)[0];
			el.id = (el.id=='') ? 'transition_'+ (this.i++) : el.id ;
			this.drop(el.id,targetHeight,increment,speed,onfinish)
		}
	}
	function DropFirstChildClose(el,tag){
		if (el.getElementsByTagName(tag) && el.getElementsByTagName(tag)[0]){
			el.getElementsByTagName(tag)[0].style.height = 0;
		}
	}
/**
 * Method, sets up the element and starts the drop interval
 * @id Transition.Drop
 * @alias Drop
 * @memberOf Transition
 * @param {string} id
 * @param {int} targetHeight
 * @param {int} increment
 * @param {int} speed
 * @param {string} onfinish
 * @return {Void} 
 */		
	/** @id Transition.Drop */
	function Drop(id,targetHeight,increment,speed,onfinish){
		speed = (speed)? speed : 10;
		var el = transition.getElement(id);
		if (!el){return};
		if (el.setInterval){
			clearInterval(el.setInterval);
			el.setInterval = null;			
		}
		el.increment 		= (increment || 10);
		if (targetHeight == 'auto'){
			el.targetHeight 	= GetTargetHeight(el);
			el.fixedEnd			= false;
		} else {
			el.targetHeight 	= targetHeight ;
			el.fixedEnd			= true;
		}
		el.onfinish 		= onfinish;
		el.currentHeight 	= el.style.height 	= 0;
		el.setInterval = window.setInterval("transition.dropIn('"+el.id+"')",speed);
	
		function GetTargetHeight(el){
			el.originalHeight 		= el.getStyle('height');
			el.originalPosition		= el.getStyle('position');
			el.originalVisibility	= el.getStyle('visibility');
			el.style.visibility		= 'hidden';
			el.style.position 		= 'absolute';
			el.style.height 		= 'auto';
			el.h 					= el.offsetHeight;
			el.style.height 		= el.originalHeight;
			el.style.position 		= el.originalPosition;
			el.style.visibility		= el.originalVisibility;
			return el.h;			
		}
	}
/**
 * Method, return the target height of an element
 * @id Transition.GetElement
 * @alias GetElement
 * @memberOf Transition
 * @param {String} obj
 * @param {Object} obj
 * @return {Object}  
 */		
	/** @id Transition.GetElement */
	function GetElement(obj){
		var el;
		if (typeof(obj) == 'string' && document.getElementById(obj)){
			el = document.getElementById(obj);
		} else if (typeof(obj) == 'object'){
			el = obj;
			if (!el.id){
				el.id = 'transitionId'+ (++this.tempId);
				if (window.logger){logger.log('transition.GetElement: found object asigning id : '+ el.id)}
			}
		}
		if (!el){return null;}
		if (!el.getStyle){
			el.getStyle = GetStyle;
		}
		return el; 
		
		
		function GetStyle(style){
			if(this.currentStyle){
			    return this.currentStyle[style];
			} else if (document.defaultView.getComputedStyle){
			    return document.defaultView.getComputedStyle(this,'')[style];
			} else {return null;}
		}
	}
	
/**
 * Method, sets the height on an element
 * @id Transition.SetHeight
 * @alias SetHeight
 * @memberOf Transition
 * @param {string} id
 * @param {int} height
 * @return {Void} 
 */	
	/** @id Transition.SetHeight */
	function SetHeight(el,height){
		height = (height == 'auto') ? height : height+'px' ;
		el.style.height = height ;			
	}	
/**
 * Method, sets up the element and starts the fade interval
 * @id Transition.Fade
 * @alias Fade
 * @memberOf Transition
 * @param {string} id
 * @param {int} targetOpacity
 * @param {int} startOpacity
 * @param {int} increment
 * @param {int} speed
 * @param {string} onfinish
 * @return {Void} 
 */			
	/** @id Transition.Fade */
	function Fade(el,targetOpacity,startOpacity,increment,speed,onfinish){
		el = transition.getElement(el);
		if (!el){
			if (window.logger){logger.log('**ERROR** transition.fade() no element found')}
			return; 
		}
		if (el.setInterval){
			clearInterval(el.setInterval);
			el.setInterval = null;			
		}
		el.increment 		= (increment || 4);
		speed 				= (speed || 10);
		el.currentOpacity  	= startOpacity || 100;
		el.targetOpacity 	= targetOpacity;
		if (onfinish) el.onfinish = onfinish;
		el.style.visibility = 'visible';
		if (el.filters && !el.onfinish && transition.enablefilter){
			el.style.filter = "progid:DXImageTransform.Microsoft.Alpha(opacity="+el.currentOpacity+") progid:DXImageTransform.Microsoft.Fade(duration=0.5);";
			el.filters.item("DXImageTransform.Microsoft.Fade").Apply();
			el.filters.item("DXImageTransform.Microsoft.Alpha").opacity = el.targetOpacity; 
			el.filters.item("DXImageTransform.Microsoft.Fade").Play();
		} else {
			transition.setOpacity(el,el.currentOpacity);
			var type = (targetOpacity>startOpacity) ? 'In' : 'Out';
			el.setInterval = window.setInterval("transition.fade"+type+"('"+el.id+"')",speed);
		}
	}
/**
 * Method, increments an elements opacity or clears the interval.
 * @id Transition.FadeIn
 * @alias FadeIn
 * @memberOf Transition
 * @param {string} id
 * @param {int} increment
 * @return {Void} 
 */		
	/** @id Transition.FadeIn */
	function FadeIn(id){
		var el = document.getElementById(id);
		el.currentOpacity+= el.increment;
		if (el.currentOpacity >= el.targetOpacity){
			clearInterval(el.setInterval);
			el.setInterval = null; 
			transition.setOpacity(el,el.targetOpacity);
			if (el.onfinish){
				if (typeof el.onfinish == 'string') eval(el.onfinish);
				if (typeof el.onfinish == 'function') el.onfinish();
			}
		} else {
			transition.setOpacity(el,el.currentOpacity);
		}
	}
	
/**
 * Method, increments an elements opacity or clears the interval.
 * @id Transition.FadeOut
 * @alias FadeOut
 * @memberOf Transition
 * @param {string} id
 * @param {int} increment
 * @return {Void} 
 */		
	/** @id Transition.FadeOut */
	function FadeOut(id){
		var el = document.getElementById(id);
		el.currentOpacity-= el.increment;
		if (el.currentOpacity <= el.targetOpacity){
			clearInterval(el.setInterval);
			el.setInterval = null; 
			transition.setOpacity(el,el.targetOpacity);
			if (el.onfinish){
				if (typeof el.onfinish == 'string') eval(el.onfinish);
				if (typeof el.onfinish == 'function') el.onfinish();
			}
		} else {
			transition.setOpacity(el,el.currentOpacity);
		}
	}	
/**
 * Method, sets the opacity of an element
 * @id Transition.SetOpacity
 * @alias SetOpacity
 * @memberOf Transition
 * @param {Object} el
 * @param {int} opacity
 * @return {Void} 
 */		
	
	/** @id Transition.SetOpacity */
	function SetOpacity(el,opacity){
	    el.style.opacity 		= (opacity / 100); 
	    el.style.MozOpacity 	= (opacity / 100); 
	    el.style.KhtmlOpacity 	= (opacity / 100); 
	    el.style.filter 		= 'alpha(opacity='+ opacity + ')';				
	}
/**
 * Method, sets the style value of an element
 * @id Transition.SetStyle
 * @alias SetStyle
 * @memberOf Transition
 * @param {Object} el
 * @param {string} style 
 * @param {string} value
 * @return {Void} 
 */		
	
	/** @id Transition.SetStyle */
	function SetStyle(el,style,value){
		el = transition.getElement(el);
		switch (style){
			case 'opacity' :
			    this.setOpacity(el,value);				
			break;
			default : 
			try {
				el.style[style] = value;
			} catch (e){if (window.logger){logger.log('cant set '+style)}}
			; 
		}
	}
	
}
window.transition = new Transition;


