/*! Copyright (c) 2008 Brandon Aaron (http://brandonaaron.net)
* Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php)
* and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses.
*
* Color functions from Steve's Cross Browser Gradient Backgrounds v1.0 (steve@slayeroffice.com && http://slayeroffice.com/code/gradient/)
*
* Version 1.0.1-pre
*/
(function($) {
 
/**
* Adds a gradient to the background of an element.
*
* @example $('div').gradient({ from: '000000', to: 'CCCCCC' });
*
* @param Map options Settings/options to configure the gradient.
* @option String from The hex color code to start the gradient with.
* By default the value is "000000".
* @option String to The hex color code to end the gradient with.
* By default the value is "FFFFFF".
* @option String direction This tells the gradient to be horizontal
* or vertical. By default the value is "horizontal".
* @option Number length This is used to constrain the gradient to a
* particular width or height (depending on the direction). By default
* the length is set to null, which will use the width or height
* (depending on the direction) of the element.
* @option String position This tells the gradient to be positioned
* at the top, bottom, left and/or right within the element. The
* value is just a string that specifices top or bottom and left or right.
* By default the value is 'top left'.
*
* @name gradient
* @type jQuery
* @cat Plugins/gradient
* @author Brandon Aaron (brandon.aaron@gmail.com || http://brandonaaron.net)
*/
$.fn.gradient = function(options) {
	var options = $.extend({ from: '000000', to: 'ffffff', direction: 'horizontal', position: 'top', length: null }, options || {});

	var createColorPath = function(startColor, endColor, distance) {
		var colorPath = [],
		colorPercent = 1.0,
		distance = (distance < 100) ? distance : 100;
		
		do {
			colorPath[colorPath.length] = setColorHue(longHexToDec(startColor), colorPercent, longHexToDec(endColor));
			colorPercent -= ((100/distance)*0.01);
		} while (colorPercent>0);
		
		return colorPath;
	},

	setColorHue = function(originColor, opacityPercent, maskRGB) {
		var returnColor = [];
		for (var i=0; i<originColor.length; i++)
		returnColor[i] = Math.round(originColor[i]*opacityPercent) + Math.round(maskRGB[i]*(1.0-opacityPercent));
		return returnColor;
	},
	
	longHexToDec = function(longHex) {
		return new Array(toDec(longHex.substring(0,2)),toDec(longHex.substring(2,4)),toDec(longHex.substring(4,6)));
	},

	toDec = function(hex) {
		return parseInt(hex,16);
	};

	return this.each(function() {
		var $this = $(this),
			width = $this.innerWidth(), 
			height = $this.innerHeight(), 
			x = 0, 
			y = 0, 
			w = 1, 
			h = 1, 
			html = [],
			length = options.length || (options.direction == 'vertical' ? width : height),
			position = (options.position == 'bottom' ? 'bottom:0;' : 'top:0;') + (options.position == 'right' ? 'right:0;' : 'left:0;'),
			colorArray = createColorPath(options.from, options.to, length);
		if (options.direction == 'horizontal') {
			h = Math.round(length/colorArray.length) || 1;
			w = width;
		} else {
			w = Math.round(length/colorArray.length) || 1;
			h = height;
		}

		html.push('<div class="gradient" style="position: absolute; ' + position + ' width: ' + (options.direction == 'vertical' ? length+"px" : "100%") +'; height: ' + (options.direction == 'vertical' ? "100%" : length+"px") + '; overflow: hidden; z-index: 0; background-color: #' + (options.position.indexOf('bottom') != -1 ? options.from : options.to) + '">');

		for(var i=0; i<colorArray.length; i++) {
			html.push('<div style="position:absolute;z-index:1;top:' + y + 'px;left:' + x + 'px;height:' + (options.direction == 'vertical' ? "100%" : h+"px") + ';width:' + (options.direction == 'vertical' ? w+"px" : "100%") + ';background-color:rgb(' + colorArray[i][0] + ',' + colorArray[i][1] + ',' + colorArray[i][2] + ');"></div>');
			options.direction == 'vertical' ? x+=w : y+=h;
			 
			if ( y >= height || x >= width) 
				break;
		}

		html.push('</div>');

		if ( $this.css('position') == 'static' )
			$this.css('position', 'relative');
		 
		$this
			.html('<div style="display:' + $this.css("display") + '; position: relative; z-index: 2;">' + this.innerHTML + '</div>')
			.prepend(html.join(''));
	});
};

})(jQuery);

