/*************************


Nathan Broslawsky
Cross Browser Gradient Backgrounds


...inspired by...


Cross Browser Gradient Backgrounds
v1.0
Last Revision: 11.03.2005
steve@slayeroffice.com

please leave this notice in tact.

should you improve upon this code, please
let me know so that I may update the version
hosted on slayeroffice

--- to use --
reference this file (on your own server) as a javascript src
in the head of your document. give the elements
you want a gradient background applied to a class as such:

class="gradient 000000 ffffff horizontal"

See http://slayeroffice.com/code/gradient/ for more examples.


*************************/


GradientGenerator = (function() {

	/************ private helper functions ****************/

	function getGradientObjects() {
		var a = document.getElementsByTagName("*");
		var objs = [], c;
		for(var i=0;i<a.length;i++) {
			c = a[i].className;
			if(c != "" && (c.indexOf("gradient") == 0)) {
				objs[objs.length] = a[i];
			} 
		} 
		return objs;
	}
	
	function createColorPath(color1,color2, gradLength) {
		var colorPath = [];
		var colorPercent = 1.0;
		var stepSize = .01;
		
		if(gradLength < (colorPercent/stepSize)) {
			stepSize = colorPercent/gradLength;
		}
		
		do {
			colorPath[colorPath.length]=setColorHue(longHexToDec(color1),colorPercent,longHexToDec(color2));
			colorPercent-=stepSize;
		} while(colorPercent>0);
		
		return colorPath;
	}
			
	function setColorHue(originColor,opacityPercent,maskRGB) {
		
		var returnColor = [];
		for (var w = 0; w < originColor.length; w++) {
			returnColor[w] = Math.round(originColor[w] * opacityPercent) + Math.round(maskRGB[w] * (1.0 - opacityPercent));
		}
		return returnColor;
	}
	
	function longHexToDec(longHex) {
		return [toDec(longHex.substring(0,2)),toDec(longHex.substring(2,4)),toDec(longHex.substring(4,6))];	
	}
	
	function toDec(hex) { return parseInt(hex,16); }
		
	function makeGrandParent(obj) {
		var disp = document.defaultView.getComputedStyle(obj,'').display;
			disp == "block"
				? nSpan = document.createElement("div")
				: nSpan = document.createElement("span");
		var mHTML = obj.innerHTML;
		obj.innerHTML = "";
		nSpan.innerHTML = mHTML;
		nSpan.setAttribute("style","position:relative;z-index:10;");
		obj.appendChild(nSpan);
	}

	/****************** Main() ************************/
	
	function GradientGenerator() {
		
		this.addOverlayToElement = function(thisElement) {
			
			var params = thisElement.className.split(" ");
			var i=0;
			while(params[i] != "gradient") {
				params.shift();
			}
			
			
			if(document.all && !window.opera) {
				
				thisElement.style.width = thisElement.offsetWidth + "px";
				params[3] == "horizontal"?gType = 1:gType = 0;
				thisElement.style.filter = "progid:DXImageTransform.Microsoft.Gradient(GradientType="+gType+",StartColorStr=\"#" + params[1] + "\",EndColorStr=\"#" + params[2] + "\")";
				
			} else {
				
				var gradLength = (params[4] && params[4].match(/length_(\d+)/));
					gradLength = gradLength && gradLength[1];
				
				var colorArray = createColorPath(params[1],params[2], gradLength);
				var x=0, y=0;
				if(params[3] == "horizontal") {
					
					var w=Math.round((gradLength || thisElement.offsetWidth)/colorArray.length);
					if (!w) { w = 1; }
					var h = thisElement.offsetHeight;
					
				} else {
					
					var h = Math.round((gradLength || thisElement.offsetHeight)/colorArray.length);
					if (!h) { h = 1; } 
					var w = thisElement.offsetWidth;
				}
				
				makeGrandParent(thisElement);
				
				var tmpDOM = document.createDocumentFragment();
				var g;
				for(p=0;p<colorArray.length;p++) {
					g = document.createElement("div");
					g.setAttribute("style","position:absolute;z-index:0;top:" + y + "px;left:" + x + "px;height:" + h + "px;width:" + w + "px;background-color:rgb(" + colorArray[p][0] + "," + colorArray[p][1] + "," + colorArray[p][2] + ");");
					(params[3] == "horizontal")
						? x+=w
						: y+=h;
					tmpDOM.appendChild(g);
					
					if(y>=thisElement.offsetHeight || x >= thisElement.offsetWidth) {
						break;
					} 
				}
				
				thisElement.appendChild(tmpDOM);
				tmpDOM = null;
			}
			
		}
		
		this.addOverlays = function() {
			
			var elements = getGradientObjects();
			for(var i=0; i<elements.length; i++) {
				this.addOverlayToElement(elements[i]);
			}
			
		}
		
	}
	
	return GradientGenerator;

})();


(function($) {
	
	var gg = new GradientGenerator();
	
	$.fn.gradientify = function(oParams) {
		
		this.each(function() {
		
			var component = $(this);
			if(component.hasClass("gradient")) { return; } //can only do it once
			
			var params = $.extend({
				startColor : "000000",
				endColor : "FFFFFF",
				orientation : "vertical",
				length : null
			}, oParams);
			
			component
				.addClass("gradient")
				.addClass(params.startColor)
				.addClass(params.endColor)
				.addClass(params.orientation)
			
			if(params.length) {
				component.addClass("length_" + params.length);
			}
			
			gg.addOverlayToElement(component.get(0));
		
		});
	}
	
})(jQuery);



//window.addEventListener
//	? window.addEventListener("load",createGradient,false)
//	: window.attachEvent("onload",createGradient);

