// create closure
( function( $ ) {

    // plugin definition
    $.fn.grabCss = function( options ) {
		for( var eachProperty in options ) {
			if( typeof $.fn.grabCss.defaults[ eachProperty ] != 'undefined' ) {
				$.fn.grabCss.defaults[ eachProperty ] = options[ eachProperty ];
			}
		}

		if( this.length < 1 ) {
			$.fn.grabCss.defaults.withText( '' );
			return '';
		}

		$this = $( this[0] );

		var parsedCss = parseCss( $this, '' );

		for( var eachSel = 1; eachSel < this.length; eachSel++ ) {
			if( this[ eachSel ].nodeType == 3 ) {
				continue;
			}
			var horCss = parseCss( $( this[ eachSel ] ), '', parsedCss );
			if( horCss.trim() != '' ) {
				parsedCss += '\n' + horCss;
			}
		}

		$.fn.grabCss.defaults.withText( parsedCss );
		
		return parsedCss;
    };

    // plugin defaults
    $.fn.grabCss.defaults = {
		withText : function( txt ) {
			alert( txt );
		},
		toLevel : 3,
		getStyle : false
    };

    // private helper functions
	function getSelector( $jqueryObject ) {
		if( $jqueryObject.attr( 'id' ) ) {
			return ' ' + $jqueryObject[0].nodeName.toLowerCase() + '#' + $jqueryObject.attr( 'id' );
		} else if( $jqueryObject.attr( 'class' ) ) {
			var firstClass = $jqueryObject.attr( 'class' ).split( ' ' );
			return ' ' + $jqueryObject[0].nodeName.toLowerCase() + '.' + firstClass[0];
		}
		return ' ' + $jqueryObject[0].nodeName.toLowerCase();
	}

	String.prototype.camelToDash = function( optionalString ) {
		optionalString = optionalString ? optionalString : this;
		var retStr = '';
		for( var indx = 0; indx < optionalString.length; indx++ ) {
			if( optionalString.charAt( indx ) !== optionalString.charAt( indx ).toLowerCase() ) {
				retStr += '-';
			}
			retStr += optionalString.charAt( indx ).toLowerCase();
		}
		return retStr;
	}

	function getStyle( $jqueryObject ) {
		var htmlControl = $jqueryObject[0];
		var styleText = '';
		for( var eachProp in htmlControl.style ) {
			if( typeof htmlControl.style[ eachProp ] != 'function' ) {
				if( $jqueryObject.css( eachProp.camelToDash() ) ) {
					styleText += eachProp.camelToDash() + ': ' + $jqueryObject.css( eachProp.camelToDash() ) + '; ';
				}
			}
		}
		return styleText;
	}

	String.prototype.trim = function( optionalString ) {
		optionalString = optionalString ? optionalString : this;
		while( optionalString.charAt(0) == ' ' || optionalString.charAt(0) == '\n' || optionalString.charAt(0) == '\t' ||optionalString.charAt(0) == '\r' ) {
			optionalString = optionalString.substr( 1 );
		}
		while( optionalString.charAt( optionalString.length - 1 ) == ' ' || optionalString.charAt( optionalString.length - 1 ) == '\n' || optionalString.charAt( optionalString.length - 1 ) == '\t' ||optionalString.charAt( optionalString.length - 1 ) == '\r' ) {
			optionalString = optionalString.substr( 0, optionalString.length - 1 );
		}
		return optionalString;
	}

	String.prototype.replaceAll = function( theseChars, withThese, optionalString ) {
		optionalString = optionalString ? optionalString : this;
		var stringToReturn = '';
		while( optionalString.search( theseChars ) > -1 ) {
			if( optionalString.substr( optionalString.search( theseChars ), theseChars.length ) == theseChars ) {
				stringToReturn += optionalString.substr( 0, optionalString.search( theseChars ) ) + withThese;
				optionalString = optionalString.substr( optionalString.substr( 0, optionalString.search( theseChars ) ).length + theseChars.length );
			} else {
				stringToReturn += optionalString.substr(0,1);
				if( optionalString.length == 1 ) {
					optionalString = '';
					break;
				}
				optionalString = optionalString.substr(1);
			}
		}
		stringToReturn += optionalString;
		return stringToReturn;
	}

	function parseCss( $selector, currentLevel, oldCss ) {
		if( $selector.length < 1 ) {
			return '';
		}
		currentLevel = currentLevel ? currentLevel : '';
		oldCss = oldCss ? oldCss : '';
		if( currentLevel == '' ) {
			window.cssText = '';
		}
		currentLevel += getSelector( $selector );
		var levelSelector = '';
		var allLevels = currentLevel.trim().split( ' ' );
		if( $.fn.grabCss.defaults.toLevel > 0 ) {
			for( var indx = allLevels.length - 1; indx >= 0 && indx >= allLevels.length - $.fn.grabCss.defaults.toLevel; indx-- ) {
				levelSelector = (allLevels[ indx ]).trim() + ' ' + levelSelector.trim();
			}
		} else {
			levelSelector = currentLevel.trim();
		}
		if( window.cssText.search( levelSelector + ' {' ) < 0 && oldCss.search( levelSelector + ' {' ) ) {
			window.cssText += levelSelector + ' { ';
			if( $.fn.grabCss.defaults.getStyle ) {
				window.cssText += getStyle( $selector );
			}
			window.cssText += '}\n';
		}
		//alert( window.cssText );
		var $children = $selector.children();
		for( var indx = 0; indx < $children.size(); indx++ ) {
			parseCss( $children.eq( indx ), currentLevel );
		}
		return window.cssText.replaceAll( '\n ', '\n' ).trim();
	}

    // end of closure
})( jQuery );
