
	String.prototype.capitalize = function() {
		return this.length == 0 ? '' : this.charAt(0).toUpperCase() + this.slice(1);
	}

	// take from comments here: http://www.codestore.net/store.nsf/unid/BLOG-20060313/
	String.prototype.fulltrim = function() {
		return this.replace(/(?:(?:^|\n)\s+|\s+(?:$|\n))/g,"").replace(/\s+/g," ");
	}

	
	CSSDocument = Class.create();
	CSSDocument.prototype = {
		
		initialize: function(url, css) {

			this.selectors = [];
			this.styles = [];
			this.url = url;

			// get rid of comments using some non-greedy matching
			css = css.replace((/\/\*(.|[\r\n])*?\*\//g), '');
			
			cssTokens = css.split(/{|}/);
			
			// in case of space after last bracket
			if (cssTokens.length % 2 == 1)
				cssTokens.pop();
			
			while (cssTokens.length) {
			
				selectors = cssTokens.shift().fulltrim().split(',');

				styles = {};
				styleTokens = cssTokens.shift().fulltrim().split(';');
				
				for (var i = 0; i < styleTokens.length; i++) {
					 styleTokenParts = styleTokens[i].split(':');
					 if (styleTokenParts.length != 2)
					 	continue;
					 styles[this._cssToJSStyleNames(styleTokenParts[0].fulltrim())] = styleTokenParts[1].fulltrim();
				}
				
				for (var i = 0; i < selectors.length; i++) {
					this.selectors.push(selectors[i]);
					this.styles.push(styles);
				}
				
			}

			/*
			out = '';
			for (i in this.styles) {
			
				if (isNaN(parseInt(i)))
					continue;
			
				out += '[' + i + '] ';
				for (j in this.styles[i])
					out += '|' + j + '| ' + this.styles[i][j] + ' ';
				out += "\n";
			}
				
			alert(out);
			*/
			
		},
		
		matchSelectors: function (regexp) {
		
			indexes = [];
			
			for (var i = 0; i < this.selectors.length; i++)
				if (this.selectors[i].match(regexp))
					indexes.push(i);

			return indexes;
		
		},
		
		_cssToJSStyleNames: function(cssStyleName) {

			if (cssStyleName == 'float')
				return 'cssFloat';
			
			nameParts = cssStyleName.split('-');
			
			cssStyleName = nameParts.shift();
			while (nameParts.length)
				cssStyleName += nameParts.shift().capitalize();
			
			return cssStyleName;
		},
		
		toString: function() {
			return 'CSSDocument';
		}
		
	};

	CSSDocument.load = function(url, onLoad) {
		new Ajax.Request(
				url, 
				{
					method: 'get', 
					onComplete: function(response) { onLoad(new CSSDocument(url, response.responseText)) }
				}
			);	
	}


	/*
	 *	Basic browser detection
	 *	(blatantly stolen from: http://www.mozilla.org/docs/web-developer/sniffer/browser_type.html)
	 */
	var agt = navigator.userAgent.toLowerCase();
	var is_major = parseInt(navigator.appVersion);
	
	var is_ie = ((agt.indexOf("msie") != -1) && (agt.indexOf("opera") == -1));
	var is_ie5_5 = (is_ie && (is_major == 4) && (agt.indexOf("msie 5.5") !=-1));
	var is_ie6 = (is_ie && (is_major == 4) && (agt.indexOf("msie 6.")!=-1));

	// LOAD CSSDocuments if it's the right IE
	if (is_ie5_5 || is_ie6)
		$A(document.getElementsByTagName('link')).each(function(link) {
			new CSSDocument.load(link.href, fixCSS);
		});
	




	function fixCSS(cssDocument) {	
	
		/*
		 *	Fix :hover
		 *	
		 */

		cssDocument.matchSelectors(/\S+:hover/).each(function(index) {
			
			selectorParts = cssDocument.selectors[index].fulltrim().split(':hover');

			$$(selectorParts[0]).each(function(parent) {

				
				if (parent.tagName == 'A')
					return;
				
				// find the elements affacted
				elements = selectorParts[1].length ? 
					Selector.findChildElements(parent, [selectorParts[1]]) : [parent]

				// only continue if any elements actually match
				if (elements.length) {

					if (!parent.fixCSS) 
						parent.fixCSS = [];

					if (!parent.fixCSS['hover'])
						parent.fixCSS['hover'] = {elements: [], stylesOnMouseOver: [], stylesOnMouseOut: [], observing: false};

					elements.each(function(element) {
					
						// save the elements that match the CSS selector
						parent.fixCSS['hover'].elements.push(element)
					
						// save the styles to apply on mouseover
						parent.fixCSS['hover'].stylesOnMouseOver.push(cssDocument.styles[index]);
					
						// save the current styles for each element to apply new styles to
						oldStyles = {};
						for (property in cssDocument.styles[index])
							oldStyles[property] = Element.getStyle(element, property);
						parent.fixCSS['hover'].stylesOnMouseOut.push(oldStyles);
					});

					if (!parent.fixCSS['hover'].observing) {
						Event.observe(parent, 'mouseover', (function() {
								for (var i = 0; i < this.fixCSS['hover'].elements.length; i++)
									for (property in this.fixCSS['hover'].stylesOnMouseOver[i])
										this.fixCSS['hover'].elements[i].style[property] = this.fixCSS['hover'].stylesOnMouseOver[i][property];														
							}).bind(parent), false);
						Event.observe(parent, 'mouseout', (function() {
								for (var i = 0; i < this.fixCSS['hover'].elements.length; i++)
									for (property in this.fixCSS['hover'].stylesOnMouseOut[i])
										this.fixCSS['hover'].elements[i].style[property] = this.fixCSS['hover'].stylesOnMouseOut[i][property];														
							}).bind(parent), false);
						parent.fixCSS['hover'].observing = true;
					}
				}
				
			});
			
		});
		
		/*
		*	Fix +
		*
		*/

		//cssDocument.matchSelectors('+').each(function(index) {
			//alert(cssDocument.selectors[index]);
		//}

		//var end = (new Date()).getTime();
		//alert((end-start)/1000);
		
	}
	
