(function($){
	
	/**
	 * A new easing
	 * @param {int} x
	 * @param {int} t
	 * @param {int} b
	 * @param {int} c
	 * @param {int} d
	 */
	$.extend($.easing, {
		easePelicanBay: function(x, t, b, c, d){
			return c * ((t = t / d - 1) * t * t + 1) + b;
		}
	});
	
	/**
	 * extend jauqry
	 * @param {int} i
	 * @param {Object} attr
	 */
	$.each(['backgroundColor', 'borderBottomColor', 'borderLeftColor', 'borderRightColor', 'borderTopColor', 'color', 'outlineColor'], function(i, attr){
		$.fx.step[attr] = function(fx){
			if (fx.state == 0) {
				fx.start = getColor(fx.elem, attr);
				fx.end = getRGB(fx.end);
			}
			
			fx.elem.style[attr] = "rgb(" +
			[Math.max(Math.min(parseInt((fx.pos * (fx.end[0] - fx.start[0])) + fx.start[0]), 255), 0), Math.max(Math.min(parseInt((fx.pos * (fx.end[1] - fx.start[1])) + fx.start[1]), 255), 0), Math.max(Math.min(parseInt((fx.pos * (fx.end[2] - fx.start[2])) + fx.start[2]), 255), 0)].join(",") +
			")";
		}
	});
	
	/**
	 * Get RGB of object
	 * @param {Object} color
	 */
	function getRGB(color){
		var result;
		
		if (color && color.constructor == Array && color.length == 3) 
			return color;
		
		if (result = /rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(color)) 
			return [parseInt(result[1]), parseInt(result[2]), parseInt(result[3])];
		
		if (result = /rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(color)) 
			return [parseFloat(result[1]) * 2.55, parseFloat(result[2]) * 2.55, parseFloat(result[3]) * 2.55];
		
		if (result = /#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(color)) 
			return [parseInt(result[1], 16), parseInt(result[2], 16), parseInt(result[3], 16)];
		
		if (result = /#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(color)) 
			return [parseInt(result[1] + result[1], 16), parseInt(result[2] + result[2], 16), parseInt(result[3] + result[3], 16)];
		
		return;
	}
	
	/**
	 * Get color of object
	 * @param {Object} elem
	 * @param {Object} attr
	 */
	function getColor(elem, attr){
		var color;
		
		do {
			color = $.curCSS(elem, attr);
			
			if (color != '' && color != 'transparent' || $.nodeName(elem, "body")) 
				break;
			
			attr = "backgroundColor";
		}
		while (elem = elem.parentNode);
		
		return getRGB(color);
	};
	
	/**
	 * Add a glow effect
	 * @param {Object} settings
	 */
	$.fn.glow = function(settings){
		var config = {
			'colorHover': '#fdfdfd',
			'colorDefault': '#f2f2f2',
			'durationIn': 100,
			'durationOut': 250
		};
		
		if (settings) 
			$.extend(config, settings);
		
		this.each(function(){
			$(this).find('li').hover(function(){
				$(this).children('a').stop(true, true).animate({
					'backgroundColor': config.colorHover
				}, {
					'duration': config.durationIn
				})
			}, function(){
				$(this).children('a').stop(true, true).animate({
					'backgroundColor': config.colorDefault
				}, {
					'duration': config.durationOut
				})
			});
		});
		return this;
	}
	
	/**
	 * Implement a pic fader
	 * @param {Array} Array of pictures to fade
	 * @param {Object} Settings
	 */
	$.fn.picFade = function(pictures, settings){
		var config = {
			'delay': 8000
		};
		
		if (settings) 
			$.extend(config, settings);
		
		var buffer = new Image();
		var myPictures = pictures;
		var mySelectors = new Array();
		var myCurrentPicture = -1;
		var myImgA;
		var myImgB;
		var myTimeOut = null;
		var myRunning = true;
		
		$(buffer).load(function(){
			myImgB.style.display = 'none';
			myImgB.style.zIndex = 20;
			myImgB.style.left = '-80px';
			myImgB.style.top = '-12px';
			myImgB.style.width = '1120px';
			myImgB.style.height = '385px';
			myImgB.src = buffer.src;
			myImgA.style.zIndex = 10;
			$(myImgB).fadeTo(0).animate({
				'left': '0px',
				'top': '0px',
				'width': '960px',
				'height': '330px',
				'opacity': 1
			}, {
				duration: 1200,
				easing: 'easePelicanBay'
			});
						
			var swap = myImgA;
			myImgA = myImgB;
			myImgB = swap;
			
			if (myRunning & pictures.length>1) 
				runShow();
		});
		
		/**
		 * Start the show
		 */
		function runShow(){
			stopShow();
			myTimeOut = window.setTimeout(nextPicture, config.delay);
			myRunning = true;
		}
		
		/**
		 * Stop the show
		 */
		function stopShow(){
			if (myTimeOut != null) {
				window.clearTimeout(myTimeOut);
				myTimeOut = null;
			}
			myRunning = false;
		}
		
		/**
		 * Next in queue
		 */
		function nextPicture(){
			if (myCurrentPicture == myPictures.length - 1) {
				loadPicture(0);
			}
			else {
				loadPicture(myCurrentPicture + 1);
			}
		}
		
		/**
		 * Start loading
		 * @param {int} Index of picture to load
		 */
		function loadPicture(index){
			if (myCurrentPicture != index) {
				myCurrentPicture = index;
				for (i = 0; i < mySelectors.length; i++) {
					mySelectors[i].className = ((i == myCurrentPicture) ? 'selector sel' : 'selector');
				}
 				buffer.src = myPictures[index];
			}
		}
		
		/**
		 * Extend
		 */
		this.each(function(){
			if (pictures.length > 1) {
				for (var i = 0; i < pictures.length; i++) {
					var picSelector = document.createElement('div');
					picSelector.style.left = (8 + i * 32) + 'px';
					picSelector.pictureIndex = i;
					picSelector.onclick = function(){
						stopShow();
						loadPicture(this.pictureIndex);
					}
					picSelector.onmouseover = stopShow;
					picSelector.onmouseout = runShow;
					$(this).append(picSelector);
					
					mySelectors.push(picSelector);
				}
			}
			
			myImgA = document.createElement('img');
			$(this).append(myImgA);
			myImgB = document.createElement('img');
			$(this).append(myImgB);
			
			loadPicture(0);
			
			return this;
		})
	};
	
	/**
	 * Implement a drop menu
	 * @param {Object} settings
	 */
	$.fn.dropMenu = function(settings){
		var config = {
			'colorHover': '#F8FAFC',
			'colorDefault': '#EDF3F8'
		};
		
		if (settings) 
			$.extend(config, settings);
		
		
		this.each(function(){
			$(this).find('li').each(function(){
				if ($(this).position().left > 550) {
					$(this).addClass('right');
				}
			});
			
			$(this).find('li').hover(function(){
				$(this).children('ul').hide();
				$(this).addClass('hover');
				$(this).children('ul').fadeIn(500);
				$(this).children('a').stop(true, true).animate({
					'backgroundColor': config.colorHover
				}, {
					'duration': 100
				})
			}, function(){
				$(this).removeClass('hover').children('a').stop(true, true).animate({
					'backgroundColor': config.colorDefault
				}, {
					'duration': 250
				})
			});
		});
		return this;
	};
})(jQuery);
