/**************************************************************************************************/
// Code Cavalier JavaScript Library 2 - Objects & Prototypes
// Copyright 2009. Brodie Sebresos. Please redistribute freely.
// Refer to website for periodic updates.
// http://codecavalier.com/dhtml/cc_lib/cc2.js
// Version: 2.0.10 (2009-10-27)
//
// The cc2.js library is a collection of various free scripts that have been gleaned from across
// the Internet, and modified to work within a global cc object. This approach encapsulates most
// of the library within its own name space, thus increasing portability. It is also composed of
// several JavaScript native object prototypes which are considered ubiquitous enough to avoid
// causing compatibility problems when used in conjunction with other libraries. cc2.js provides
// much of the best and most commonly used JavaScript functionality in an integrated, concise,
// unobtrusive, and cross-platform compatible package.
//
// A large portion of the code is original work by Brodie Sebresos, being influenced by many other
// of the great minds in web browser innovation. In instances where code has been taken directly
// from other programmers, credit and reference links have been provided. If any portion of this
// code is improperly copied or credited, please report cases to: webmaster@codecavalier.com
/**************************************************************************************************/
//WISH LIST:
//  FEATURE: Automatic box element drop shadows from class="dropShadow" attribute
//   SOURCE: http://www.tastypopsicle.com/dropshadow/
//   SOURCE: http://www.erik-rasmussen.com/blog/2006/12/04/the-shadower-realistic-drop-shadows-in-javascript/
//  FEATURE: Automatic tool tips from toolTip="" attribute
//  FEATURE: Port ajax support from cc_lib
/**************************************************************************************************/




/**************************************************************************************************/
// Extensions to the basic JavaScript language by prototyping native objects. These are considered
// so ubiquitous that even if they are already defined in other libraries, they should have the
// same functionality, so redefining them here is safe.
/**************************************************************************************************/
//FUNCTION: window.$() - courtesy of Dustin Diaz, The Prototype Dollar Function, http://www.dustindiaz.com/top-ten-javascript/
if (typeof window.$ !== 'function') window.$ = function $ () {
	var elements = new Array();
	for (var i = 0; i < arguments.length; i++) {
		var element = arguments[i];
		if (typeof element == 'string')
			element = document.getElementById(element);
		if (arguments.length == 1)
			return element;
		elements.push(element);
	}
	return elements;
}
//PROTOTYPE: Object.beget() - makes a cloned object that inherits the properties of the parent object (aka: prototypal inheritance) - Crockford, Douglas (2008). JavaScript: The Good Parts, 1st Edition. O'Reilly Media, Inc. p. ??. ISBN-13 978-0-596-51774-8. Safari Books Online. Retrieved on Feb 6, 2009. http://my.safaribooksonline.com/9780596517748/prototype
if (typeof Object.beget !== 'function') Object.beget = function (o) {
	var F = function () {};
	F.prototype = o;
	return new F();
}
//PROTOTYPE: Math.integer() - returns the integer portion of positive or negative real numbers - Crockford, Douglas (2008). JavaScript: The Good Parts, 1st Edition. O'Reilly Media, Inc. p. ??. ISBN-13 978-0-596-51774-8. Safari Books Online. Retrieved on Feb 6, 2009. http://my.safaribooksonline.com/9780596517748/augmenting_types
if (typeof Number.prototype.integer !== 'function') Number.prototype.integer = function () {
	return Math[(this < 0 ? 'ceil' : 'floor')](this);
}
//PROTOTYPES: 3 Javascript functions that trim whitespace from the ends of strings using simple, elegant regular expressions. The functions are granted to the public domain. © Shailesh N. Humbad - http://www.somacon.com/p355.php
if (typeof String.prototype.trim !== 'function') String.prototype.trim = function() {
	return this.replace(/^\s+|\s+$/g,"");
}
if (typeof String.prototype.ltrim !== 'function') String.prototype.ltrim = function() {
	return this.replace(/^\s+/,"");
}
if (typeof String.prototype.rtrim !== 'function') String.prototype.rtrim = function() {
	return this.replace(/\s+$/,"");
}
//==== Various prototypes inspired by Sven Tofte: www.svendtofte.com/code/usefull_prototypes/prototypes.js
//PROTOTYPES: Number.max(), Number.min() - returns the greater/lesser of the two inputs
if (typeof Number.prototype.max !== 'function') Number.prototype.max = function (a,b) {
	return a<b?b:a;
}
if (typeof Number.prototype.min !== 'function') Number.prototype.min = function (a,b) {
	return a>b?b:a;
}
//PROTOTYPE: Math.mod() - standard mathematical mod function
if (typeof Math.mod !== 'function') Math.mod = function(val,mod) {
	if (val < 0) {
		while(val<0) val += mod;
		return val;
	} else {
		return val%mod;
	}
}
//METHODS: window.getInnerWidth(), window.getInnerHeight() - cross-platform, return dimensions of the browser window in pixels
if (typeof window.getInnerWidth !== 'function') window.getInnerWidth = function() {
	if (window.innerWidth) {
		return window.innerWidth;
	} else if (document.body.clientWidth) {
		return document.body.clientWidth;
	} else if (document.documentElement.clientWidth) {
		return document.documentElement.clientWidth;
	}
}
if (typeof window.getInnerHeight !== 'function') window.getInnerHeight = function() {
	if (window.innerHeight) {
		return window.innerHeight;
	} else if (document.body.clientHeight) {
		return document.body.clientHeight;
	} else if (document.documentElement.clientHeight) {
		return document.documentElement.clientHeight;
	}
}

String.prototype.endsWith = function(str) {
	return (this.length-str.length)==this.lastIndexOf(str);
}

String.prototype.reverse = function() {
	var s = "";
	var i = this.length;
	while (i>0) {
		s += this.substring(i-1,i);
		i--;
	}
	return s;
}

String.prototype.toInt = function() {
	var a = new Array();
	for (var i = 0; i < this.length; i++) {
		a[i] = this.charCodeAt(i);
	}
	return a;
}

Array.prototype.intArrayToString = function() {
	var a = new String();
	for (var i = 0; i < this.length; i++) {
		if(typeof this[i] != "number") {
			throw new Error("Array must be all numbers");
		} else if (this[i] < 0) {
			throw new Error("Numbers must be 0 and up");
		}
		a += String.fromCharCode(this[i]);
	}
	return a;
}

Array.prototype.compareArrays = function(arr) {
	if (this.length != arr.length) return false;
	for (var i = 0; i < arr.length; i++) {
		if (this[i].compareArrays) { //likely nested array
			if (!this[i].compareArrays(arr[i])) return false;
			else continue;
		}
		if (this[i] != arr[i]) return false;
	}
	return true;
}

Array.prototype.map = function(fnc) {
	var a = new Array(this.length);
	for (var i = 0; i < this.length; i++) {
		a[i] = fnc(this[i]);
	}
	return a;
}

Array.prototype.foldr = function(fnc,start) {
	var a = start;
	for (var i = this.length-1; i > -1; i--) {
		a = fnc(this[i],a);
	}
	return a;
}

Array.prototype.foldl = function(fnc,start) {
	var a = start;
	for (var i = 0; i < this.length; i++) {
		a = fnc(this[i],a);
	}
	return a;
}

Array.prototype.exists = function (x) {
	for (var i = 0; i < this.length; i++) {
		if (this[i] == x) return true;
	}
	return false;
}

Array.prototype.filter = function(fnc) {
	var a = new Array();
	for (var i = 0; i < this.length; i++) {
		if (fnc(this[i])) {
			a.push(this[i]);
		}
	}
	return a;
}

Array.prototype.random = function() {
	return this[Math.floor((Math.random()*this.length))];
}
//==== End. Sven Tofte prototypes ====================================================
/** End. Extensions by prototype ********************************************************/






/****************************************************************************************/
// CodeCavalier library:  The cc library is contained within the global cc object in
// order to provide a distinct naming space, and allow for library extensions.
/****************************************************************************************/
//OBJECT: cc - CodeCavalier library container object
if(window.cc === undefined) window.cc = {};
//PROPERTIES:
if(cc.name === undefined) cc.name        = 'CodeCavalier JavaScript Library 2 - Version: 2.0.10 (2009-10-27)';
if(cc.name === undefined) cc.version     = '2.0.10';
if(cc.name === undefined) cc.cssIncluded = false; //note: this flag specifies if a CSS has been loaded via cc.includeCSS, it gives no further detail when including multiple CSS files
if(cc.name === undefined) cc.jsIncluded  = false; //note: this flag specifies if a JS has been loaded via cc.includeJS, it gives no further detail when including multiple JS files

/****************************************************************************************/
// Header methods: file inclusion, page load events, style sheet manipulation, etc.

//METHOD: cc.includeCSS - dynamically includes the specified CSS file (URL) - courtesy of Stoyan Stefanov, http://www.phpied.com/javascript-include-ready-onload/
cc.includeCSS = function (css_file) {
	var html_doc = document.getElementsByTagName('head')[0];
	css = document.createElement('link');
	css.setAttribute('rel', 'stylesheet');
	css.setAttribute('type', 'text/css');
	css.setAttribute('href', css_file);
	html_doc.appendChild(css);
	css.onreadystatechange = function () {
		if(css.readyState == 'complete') cc.cssIncluded = true;
	}
	css.onload = function () {
		cc.cssIncluded = true;
	}
}
//METHOD: cc.includeJS - dynamically includes the specified JS file (URL) - courtesy of Stoyan Stefanov
cc.includeJS = function (file) {
	var html_doc = document.getElementsByTagName('head')[0];
	js = document.createElement('script');
	js.setAttribute('type', 'text/javascript');
	js.setAttribute('src', file);
	html_doc.appendChild(js);
	js.onreadystatechange = function () {
		if (js.readyState == 'complete') cc.jsIncluded = true;
	}
	js.onload = function () {
		cc.jsIncluded = true;
	}
}
//METHOD: cc.addLoadEvent - appends the specified function (via reference) to the window.onload event - courtesy of Simon Willison, http://simonwillison.net/2004/May/26/addLoadEvent/
cc.addLoadEvent = function (func) {
	var oldonload = window.onload;
	if (typeof window.onload !== 'function') {
		window.onload = func;
	}
	else {
		window.onload = function() {
			if (oldonload) {
				oldonload();
			}
			func();
		}
	}
}
//METHOD: cc.fixPngs - Fixes PNGs with alpha transparency in IE 5 & 6, in IMG tags and block backgrounds
//        This function provides similar functionality to Drew McLellan's SuperSleight - http://24ways.org/2007/supersleight-transparent-png-in-ie6
//  Note: for block elements with background images, the background-position property is overridden by the old-fashioned AlphaImageLoader() function in IE, which only supports scaling the image to the size of the element, or resizing the element to the size of the image - http://msdn.microsoft.com/en-us/library/ms532920(VS.85).aspx
cc.fixPngs = function () {
	var ver = navigator.appVersion.split('MSIE');
	ver = parseFloat(ver[1]);
	if (ver >= 5.5 && ver < 7 && document.body.filters)
	{//IE version is 5.5-6.x and filters object exists in DOM
		var pattern = new RegExp("([a-zA-Z0-9])+.png",'i');
		//Scan all block element backgrounds
		var scanElm = document.getElementsByTagName('*');
		for (var i = 0; i < scanElm.length; i++) {
			if(scanElm[i].style && scanElm[i].style.backgroundImage && pattern.test(scanElm[i].style.backgroundImage) )
			{//this element has an explicit .png background
				//alert('BACKGROUND-'+i+':'+scanElm[i].nodeName+':'+scanElm[i].className+':'+scanElm[i].style.backgroundImage+'\n'+(pattern.test(scanElm[i].style.backgroundImage) ? "IS a PNG" : "Nope")+'\n'+scanElm[i].style.filter+'\n'+scanElm[i].style.backgroundImage.replace("url(",'').replace(")",''));
				scanElm[i].style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"+scanElm[i].style.backgroundImage.replace("url(",'').replace(")",'')+"',sizingMethod='crop')";
				scanElm[i].style.backgroundImage = 'none';
			}
		}
		//Scan backgrounds in all style sheets
		//var o = '';
		for(var i = 0; i < document.styleSheets.length; i++) {
			//o = o+'STYLE-'+i+'\n';
			for(var r = 0; r < document.styleSheets[i].rules.length; r++) {
				if(document.styleSheets[i].rules[r].style.backgroundImage && pattern.test(document.styleSheets[i].rules[r].style.backgroundImage) ) {
					//o = o+'  Rule-'+r+':'+document.styleSheets[i].rules[r].selectorText+'\n'+'    backgroundImage:'+document.styleSheets[i].rules[r].style.backgroundImage+'\n';
					document.styleSheets[i].rules[r].style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"+document.styleSheets[i].rules[r].style.backgroundImage.replace("url(",'').replace(")",'')+"',sizingMethod='crop')";
					document.styleSheets[i].rules[r].style.backgroundImage = 'none';
				}
			}
		}
		//alert(o);
		//Scan all IMG tags
		for(var i = 0; i < document.images.length; i++)
		{//Loop through all images
			var img = document.images[i];
			var iSrc = img.src;
			if (iSrc.substring(iSrc.length-3, iSrc.length).toUpperCase() == 'PNG')
			{//this is a .png image
				var newOuterHTML = '<span '
				                 + (img.id ? "id='"+img.id+"' " : '')
				                 + (img.name ? "name='"+img.name+"' " : '')
				                 + (img.className ? "class='"+img.className+"' " : '')
				                 + (img.title ? "title='"+img.title+"' " : (img.alt ? "title='"+img.alt+"' " : ''))
				                 + ' style="display:inline-block;'
				                 + 'width:'+img.width+'px;'
				                 + 'height:'+img.height+'px;'
				                 + (img.align.toUpperCase()=='LEFT' ? 'float:left;' : '')
				                 + (img.align.toUpperCase()=='RIGHT' ? 'float:right;' : '')
				                 + (img.parentElement.href ? 'cursor:hand;' : '')
				                 + "filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"+img.src+"',sizingMethod='scale');"
				                 + '"></span>';
				img.outerHTML = newOuterHTML;
				i = i-1;//decrement the image count because we've removed one img element from the DOM
			}
		}
	}
}

/****************************************************************************************/
//MEMBER OBJECT: BrowserDetect by Peter-Paul Koch - http://www.quirksmode.org/js/detect.html
//               last update: 2009-07-08 (This code needs to be updated periodically)
//  Browser name: cc.BrowserDetect.browser
//  Browser version: cc.BrowserDetect.version
//  OS name: cc.BrowserDetect.OS
cc.BrowserDetect = {
	init: function () {
		this.browser = this.searchString(this.dataBrowser) || "An unknown browser";
		this.version = this.searchVersion(navigator.userAgent)
			|| this.searchVersion(navigator.appVersion)
			|| "an unknown version";
		this.OS = this.searchString(this.dataOS) || "an unknown OS";
	},
	searchString: function (data) {
		for (var i=0;i<data.length;i++)	{
			var dataString = data[i].string;
			var dataProp = data[i].prop;
			this.versionSearchString = data[i].versionSearch || data[i].identity;
			if (dataString) {
				if (dataString.indexOf(data[i].subString) != -1)
					return data[i].identity;
			}
			else if (dataProp)
				return data[i].identity;
		}
	},
	searchVersion: function (dataString) {
		var index = dataString.indexOf(this.versionSearchString);
		if (index == -1) return;
		return parseFloat(dataString.substring(index+this.versionSearchString.length+1));
	},
	dataBrowser: [
		{
			string: navigator.userAgent,
			subString: "Chrome",
			identity: "Chrome"
		},
		{ 	string: navigator.userAgent,
			subString: "OmniWeb",
			versionSearch: "OmniWeb/",
			identity: "OmniWeb"
		},
		{
			string: navigator.vendor,
			subString: "Apple",
			identity: "Safari",
			versionSearch: "Version"
		},
		{
			prop: window.opera,
			identity: "Opera"
		},
		{
			string: navigator.vendor,
			subString: "iCab",
			identity: "iCab"
		},
		{
			string: navigator.vendor,
			subString: "KDE",
			identity: "Konqueror"
		},
		{
			string: navigator.userAgent,
			subString: "Firefox",
			identity: "Firefox"
		},
		{
			string: navigator.vendor,
			subString: "Camino",
			identity: "Camino"
		},
		{		// for newer Netscapes (6+)
			string: navigator.userAgent,
			subString: "Netscape",
			identity: "Netscape"
		},
		{
			string: navigator.userAgent,
			subString: "MSIE",
			identity: "Explorer",
			versionSearch: "MSIE"
		},
		{
			string: navigator.userAgent,
			subString: "Gecko",
			identity: "Mozilla",
			versionSearch: "rv"
		},
		{ 		// for older Netscapes (4-)
			string: navigator.userAgent,
			subString: "Mozilla",
			identity: "Netscape",
			versionSearch: "Mozilla"
		}
	],
	dataOS : [
		{
			string: navigator.platform,
			subString: "Win",
			identity: "Windows"
		},
		{
			string: navigator.platform,
			subString: "Mac",
			identity: "Mac"
		},
		{
			   string: navigator.userAgent,
			   subString: "iPhone",
			   identity: "iPhone/iPod"
	    },
		{
			string: navigator.platform,
			subString: "Linux",
			identity: "Linux"
		}
	]
};

/****************************************************************************************/
// DOM methods: for easier DOM manipulation

//METHOD: cc.clear - empties the specified DOM element by removing all its child nodes
cc.clear = function (elm) {
	while(elm.childNodes.length)
		elm.removeChild(elm.childNodes[0]);
	return elm;
}
//METHOD: cc.getParentWithId - returns a reference to the parent element with passed id
cc.getParentWithId = function (elm,id_in) {
	return (elm.id==id_in ? elm : (elm.nodeName=='HTML' ? null : (getParentWithId(elm.parentNode,id_in))));
}
//METHOD: cc.getParentWithClass - returns a reference to the parent element with passed className
cc.getParentWithClass = function (elm,class_name) {
	return (elm.className==class_name ? elm : (elm.nodeName=='HTML' ? false : (getParentWithClass(elm.parentNode,class_name))));
}
//METHOD: cc.getParentNode - returns a reference to the parent element matching a particular node
cc.getParentNode = function (elm,node_name) {
	return (elm.nodeName==node_name ? elm : (elm.nodeName=='HTML' ? false : (getParentNode(elm.parentNode,node_name))));
}
//METHOD: cc.getChildWithClass - returns a reference to the child element with passed class_name
cc.getChildWithClass = function (elm,class_name) {
	for(var i=0;i<elm.childNodes.length;i++) {
		var classArr = (elm.childNodes[i].className ? elm.childNodes[i].className.split(' ') : Array());
		for(var j=0;j<classArr.length;j++)
			if(classArr[j] == class_name)
				return elm.childNodes[i];
	}
	var childResult = false;
	for(i=0;i<elm.childNodes.length;i++) {
		childResult = getChildWithClass(elm.childNodes[i],class_name);
		if(childResult) return childResult;
	}
	return false;
}
//METHOD: cc.getChildNode - returns a reference to the child element with passed node_name
cc.getChildNode = function (elm,node_name) {
	for(var i=0;i<elm.childNodes.length;i++)
		if(elm.childNodes[i].nodeName == node_name)
			return elm.childNodes[i];
	var childResult = false;
	for(i=0;i<elm.childNodes.length;i++)
		if(childResult = getChildNode(elm.childNodes[i],node_name)) return childResult;
	return false;
}

/****************************************************************************************/
// Window methods: for manipulation of browser windows

//METHOD: cc.absPos - returns the absolute {x,y} coordinates (px) of an element
cc.absPos = function (elm) {
	return ( elm.offsetParent == null
		? {
				x:elm.offsetLeft,
				y:elm.offsetTop
			}
		: this.absPos(elm.offsetParent)
	);
}
//METHOD: cc.absPosX - returns the absolute x coordinate (px) of an element - inspired by Mike Hall, getPageOffsetLeft, http://www.brainjar.com/dhtml/menubar/default3.asp
cc.absPosX = function (elm) {
	return (elm.offsetParent == null ? elm.offsetLeft : elm.offsetLeft + this.absPosX(elm.offsetParent));
}
//METHOD: cc.absPosY - returns the absolute y coordinate (px) of an element - inspired by Mike Hall, getPageOffsetTop, http://www.brainjar.com/dhtml/menubar/default3.asp
cc.absPosY = function (elm) {
	return (elm.offsetParent == null ? elm.offsetTop : elm.offsetTop + this.absPosY(elm.offsetParent));
}
//METHOD: cc.windowSize - returns the dimensions of the browser window (works better when document body width/height are set to 100%)
cc.windowSize = function () {
	return {
		x:document.body.clientWidth,
		y:document.body.clientHeight
	};
}
//METHOD: cc.pageSize - returns the dimensions of the whole web page (including scrolled portions)
cc.pageSize = function () {
	var html = document.getElementsByTagName('HTML');
	return {
		x:(html[0] ? html[0].clientWidth : null),
		y:(html[0] ? html[0].clientHeight : null)
	};
}

/****************************************************************************************/
// SFX methods: for creating cross-browser special effects

//MEMBER OBJECT: cc.ds - Drop shadow object
cc.ds = {};
//PROPERTIES:
cc.ds.simpleShadowClass = 'dropShadow';
cc.ds.fadingShadowClass = 'fadingDropShadow';
cc.ds.simpleColor = 'black';
cc.ds.fadingColor = '44'; //Hex number between 00 and FF
// Warning: This drop shadow effect does not work well when text is wrapped, or when pages are zoomed.

//METHOD: cc.ds.scanForElementsToDropShadow - Scans DOM for elements that want drop shadows on text
//  Inspired by: Stan Slaughter - http://stansight.com/WordPress/2007/10/28/text-drop-shadows/
//               with significant mods
cc.ds.scanForElementsToDropShadow = function () {
	// Use these class names to specify elements to drop shadow, and which effect to use
	var node = document;
	var tag = '*';

	// Build regular expressions that will search for drop shadow classes
	var patternSimple = new RegExp("(^|\\s)"+cc.ds.simpleShadowClass+"(\\s|$)");
	var patternFading = new RegExp("(^|\\s)"+cc.ds.fadingShadowClass+"(\\s|$)");

	// Scan through all tag elements in the document
	var scanElm = node.getElementsByTagName(tag);
	for (i = 0; i < scanElm.length; i++) {

		if (patternSimple.test(scanElm[i].className) )
		{//element wants a fading shadow
			//alert(scanElm[i].nodeName);
			// Create Simple Shadow Child for this element
			cc.ds.createSimpleShadow(scanElm[i]);
		}
		else if (patternFading.test(scanElm[i].className) )
		{//element wants a simple drop shadow
			// Get the value from the element
			var text_value = scanElm[i].innerHTML;

			// Create Fading Shadow Children for this element
			cc.ds.createFadingShadow(scanElm[i],text_value);
		}
	} // End for loop
}
//METHOD: ds.createFadingShadow - Creates child DOM elements for the fading drop shadow effect
//  By: Stan Slaughter - http://stansight.com/WordPress/2007/10/28/text-drop-shadows/
//      with slight mod (TODO:fix the half-pixel problem)
cc.ds.createFadingShadow = function (shadow_element,shadow_value) {
	// Starting relative offset for child DIVs
	var top_pos = .5;
	var left_pos = .5;

	// Assign starting color (in Hex notation) for the Red, Green, and Blue
	// Components (when they all have the same value you will alwys get a gray color).
	// For lighter shadows start with a "lighter" color of 66, 77, 88 99, aa, bb, etc..
	var cRed = parseInt(this.fadingColor,'16');
	var cGreen = parseInt(this.fadingColor,'16');
	var cBlue = parseInt(this.fadingColor,'16');

	// Set the max number of shadow elements to create.
	// This should never be set larger than the Z-Index value of dropshadow class
	var max_shadows = 10;

	// Calculate color increament based on range of gray colors (from this.fadingColor to
	// the lighest gray color of #fefefe) and max number of shadows you want
	var color_inc =  parseInt(( parseInt('fe','16') - parseInt(this.fadingColor,'16') ) / max_shadows,'10');

	for (j = 1; j <= max_shadows; j++) {

		// Build full color Hex string from it's individual RGB values
		var full_color_value = cRed.toString(16) + cGreen.toString(16) + cBlue.toString(16);

		// Create a Shadow DIV
		var shadow_div = document.createElement('div');

		//  Add the shadow_value to Shadow DIV
		shadow_div.innerHTML = shadow_value;

		// Style Shadow DIV
		shadow_div.style.width=shadow_element.offsetWidth + "px";
		shadow_div.style.color = '#' + full_color_value;
		shadow_div.style.borderColor = '#' + full_color_value;
		shadow_div.style.display = "block";
		shadow_div.style.position = "absolute";
		shadow_div.style.top = top_pos + "px";
		shadow_div.style.left = left_pos + "px";
		shadow_div.style.zIndex = (-1) * j;

		// Apppend Shadow DIV to shadow element
		shadow_element.appendChild(shadow_div);

		// Increment positons and shadows individual RGB color values
		top_pos += .5;
		left_pos += .5;
		cRed += color_inc;
		cGreen += color_inc;
		cBlue += color_inc;
	}
}
//METHOD: cc.ds.createSimpleShadow - creates drop-shadow text
//    Set attribute class="dropShadow" in the desired element
//  optional:
//    Set attribute dsWidth="{number}" to specify a custom pixel width (and by default, height)
//    Set attribute dsHeight="{number}" to specify a custom pixel height
//    Set attribute dsColor="{CSS color value}" to specify a custom color
//    Set attribute dsOpacity="{CSS3 opacity value}" to specify a custom opacity (auto-converts to IE compatible value)
//    Set attribute dsFirefoxCorrect="{number}" to specify the number of pixels to correct the height (Firefox-only)
//    Set attribute dsSafariCorrect="{number}" to specify the number of pixels to correct the height (Safari-only)
//    Set attribute dsBrowserAllow="{comma-separated list of browser names with optional space and version number}" drop shadow effect will only appear on listed browsers
//    Set attribute dsBrowserDisable="{comma-separated list of browser names with optional space and version number}" drop shadow effect will not appear on listed browsers
//  notes:
//    I researched having the optional values configurable as custom style properties, but it proved to be too difficult to read custom properties from style sheets because each browser's DOM has its own pre-defined list of properties in the style obect. (see: http://www.quirksmode.org/dom/w3c_css.html)
//    For some reason, Firefox pushes the text in the child element vertically, sometimes resulting in incorrect drop shadow height.  I haven't figured out why this happens, so it currently requires a manual fix.  See the dsFirefoxCorrect attribute above.
cc.ds.createSimpleShadow = function (sourceElm,textVal)
{
	if(sourceElm && sourceElm.style)
	{//sourceElm is a valid element
		var browserEnabled = true;
		//Look for dsBrowserAllow
		var dsBrowserAllow = sourceElm.getAttribute('dsBrowserAllow');
		if(dsBrowserAllow)
		{//Need to verify if this browser is disabled
			browserEnabled = false;
			var thisBrowser = cc.BrowserDetect.browser+' '+cc.BrowserDetect.version;
			var browsers = dsBrowserAllow.split(',');
			for(var i=0; i < browsers.length; i++) {
				var searchBrowser = browsers[i].trim();
				var pattern = new RegExp(searchBrowser);
				//alert("dsBrowserAllow:"+dsBrowserAllow+'\n'+"thisBrowser:"+thisBrowser+'\n'+"searchBrowser:"+searchBrowser+'\n'+"Pattern match:"+(pattern.test(thisBrowser) ? 'TRUE' : 'FALSE'));
				if(pattern.test(thisBrowser))
				{//the browser listed in dsBrowserAllow matches this browser's name
					browserEnabled = true;
					break;
				}
			}
		}
		//Look for dsBrowserDisable
		var dsBrowserDisable = sourceElm.getAttribute('dsBrowserDisable');
		if(dsBrowserDisable)
		{//Need to verify if this browser is disabled
			var thisBrowser = cc.BrowserDetect.browser+' '+cc.BrowserDetect.version;
			var browsers = dsBrowserDisable.split(',');
			for(var i=0; i < browsers.length; i++) {
				var searchBrowser = browsers[i].trim();
				var pattern = new RegExp(searchBrowser);
				//alert("dsBrowserDisable:"+dsBrowserDisable+'\n'+"thisBrowser:"+thisBrowser+'\n'+"searchBrowser:"+searchBrowser+'\n'+"Pattern match:"+(pattern.test(thisBrowser) ? 'TRUE' : 'FALSE'));
				if(pattern.test(thisBrowser))
				{//the browser listed in dsBrowserDisable matches this browser's name
					browserEnabled = false;
					break;
				}
			}
		}
		//If this browser hasn't been explicitly disabled, do the drop shadow
		if( browserEnabled )
		{
			//Verify style properties of the source element
			sourceElm.style.position = 'relative';
			sourceElm.style.zIndex = 1;

			//Create the shadow element in the DOM as a child of the source element
			var shadowElm = document.createElement('DIV');
			shadowElm.innerHTML = sourceElm.innerHTML;
			shadowElm.className = this.simpleShadowClass + '_Shadow';
			shadowElm.style.width = sourceElm.offsetWidth + 'px';
			shadowElm.style.display = 'block';
			shadowElm.style.position = 'absolute';
			shadowElm.style.zIndex = -100;

			//Check custom attributes of the source element, or use defaults
			var dsColor = sourceElm.getAttribute('dsColor');
			shadowElm.style.color = (dsColor === null ? this.simpleColor : dsColor);
			var dsWidth = sourceElm.getAttribute('dsWidth');
			shadowElm.style.left = (dsWidth === null ? 1 : dsWidth) + 'px';
			var dsHeight = sourceElm.getAttribute('dsHeight');
			var dsBrowserCorrect = 0;
			if(cc.BrowserDetect.browser == 'Firefox' && sourceElm.getAttribute('dsFirefoxCorrect'))
				dsBrowserCorrect = parseInt(sourceElm.getAttribute('dsFirefoxCorrect'));
			if(cc.BrowserDetect.browser == 'Safari' && sourceElm.getAttribute('dsSafariCorrect'))
				dsBrowserCorrect = parseInt(sourceElm.getAttribute('dsSafariCorrect'));
			shadowElm.style.top = ((dsHeight === null ? (dsWidth === null ? 1 : dsWidth) : dsHeight) + dsBrowserCorrect) + 'px';
			//TODO:custom opacity

			sourceElm.appendChild(shadowElm);
		}
	}
}

// End of cc library object.
/****************************************************************************************/




/****************************************************************************************/
// CodeCavalier library auto-loaders:  Some of these commands are run immediately, and
// others are automatically run upon page load.  They are considered default features of
// the library.
/****************************************************************************************/
//Initialize the browser detection object
cc.BrowserDetect.init();
//Fix the transparent PNGs on window.onload
if(window.attachEvent) //this function is native only to IE 5 & 6
	window.attachEvent("onload", cc.fixPngs);
//Scan for drop shadow text
cc.addLoadEvent( cc.ds.scanForElementsToDropShadow );
//Alert the browser version (if this works, then none of the other auto-loaders crashed)
//cc.addLoadEvent( function () {alert(cc.BrowserDetect.browser+' '+cc.BrowserDetect.version);} );
/****************************************************************************************/
