/*
	jQuery.Clip
	
	Simplifies the getting, setting and animating of the clip property.
	
	.clip( [values, duration, callback] );
	
	arguments:
		- values:Array - The clip values to set in the order, top, right, bottom, left
		- duration:Integer - duration of the animation
		- callback:Function - the function to execute onComplete
		
	
	USAGE:
	
	Allows the clip property to be used in animate function:
		$('#myelement').animate({'clip':'rect(300px, 400px, 200px, 0px)'});
		
	Shortcut Methods:
	
	Getting clip - 
		$('#myelement').clip():Array
			returns clip values as array
			
	Setting clip - 
		$('#myelement').clip( [0, 200, 500, 0] ):Element;
		
	Animating clip - 
		$('#myelement').clip( [0, 200, 500, 0], 2000 ):Element;
		
	Animating clip (with callback ) - 
		function afterAnim(){
			alert('finished');
		}
		$('#myelement').clip( [0, 200, 500, 0], 2000, afterAnim):Element;
*/

(function(jQuery){
	jQuery.fx.step.clip = function(fx){
		if( fx.state == 0 ){
			fx.start = $(fx.elem).clip();
			fx.end = jQuery.Clip.convertFromString(fx.end);
		}
		var currentRect = [];
		for (var i = 0; i < 4; ++i) {
			currentRect.push((fx.pos * (fx.end[i] - fx.start[i])) + fx.start[i]);
		}
		try{fx.elem.style.clip = 'rect(' + currentRect.join('px ') + 'px)'; }catch(e){}
	}
})(jQuery);



jQuery.Clip = {
	
	convertToString: function(arr){
		return arr.length < 4 ? 'rect(0px 0px 0px 0px)' : 'rect('+arr[0]+'px '+arr[1]+'px '+arr[2]+'px '+arr[3]+'px)';
	},
	
	convertFromString: function(str){
		var arr = [];
		vals = str.replace(/rect\(([^)]*)\)/, '$1').split(/,?\s/);
		for( var i=0; i < vals.length; i++){
			arr.push( parseInt(vals[i]) );
		}
		return arr;
	},
	
	get: function(){
		var str;
		var arr = [];
		if( this.currentStyle ){
			if( this.currentStyle.clip ){
				var arr = jQuery.Clip.convertFromString( this.currentStyle.clip );
				if( arr[0] == 0 && arr[1] == 0 && arr[2] == 0 && arr[3] == 0){
					arr[1] = $(this).outerWidth();
					arr[2] = $(this).outerHeight();
				}
			}else{
				arr[0] = this.currentStyle.clipTop == 'auto' ? 0 : parseInt(this.currentStyle.clipTop);
				arr[1] = this.currentStyle.clipRight == 'auto' ? $(this).width() : parseInt(this.currentStyle.clipRight);
				arr[2] = this.currentStyle.clipBottom == 'auto' ? $(this).height() : parseInt(this.currentStyle.clipBottom);
				arr[3] = this.currentStyle.clipLeft == 'auto' ? 0 : parseInt(this.currentStyle.clipLeft);
			}
		}else if(window.getComputedStyle){
			c = document.defaultView.getComputedStyle(this,null).getPropertyValue('clip');
			if( c == 'auto' ){
				arr = [
					0,
					$(this).width(),
					$(this).height(),
					0   
					   ];
			}else{
				arr = jQuery.Clip.convertFromString(c);
			}
		}
		return arr;
	},
	
	set: function(arr){
		this.style.clip = jQuery.Clip.convertToString(arr);
	},
	
	test: function(arr){
		return this.style.clip == jQuery.Clip.convertToString(arr) ? true : false;
	}
}

jQuery.fn.clip = function(){
	if( arguments.length == 0){
		return jQuery.Clip.get.call(this[0]);	
	}else if(arguments.length == 1){
		var arr = arguments[0];
		this.each( function(){ jQuery.Clip.set.call(this, arr); });
	}else if(arguments.length == 2){
		return this.animate({'clip' : jQuery.Clip.convertToString(	arguments[0] )}, {duration: arguments[1]} );
	}else if(arguments.length == 3){
		return this.animate({'clip' : jQuery.Clip.convertToString(	arguments[0] )}, {duration: arguments[1], complete: arguments[2]} );
	}
}
