// TODO: alter variable/property naming so that less string manipulation is required.
// TODO: make prototype "safe". low priority.


		////////////////////////////////////////////////////////////////////////////////////////////////
		////////////////////////////////////////////////////////////////////////////////////////////////
		////                                                                                        ////
		////    TITLE: quadCorners jquery plugin v 1.0 - initial release                            ////
		////                                                                                        ////
		////    AUTHOR: Jose Cao-Garcia                                                             ////
		////                                                                                        ////
		////    DESCRIPTION: quadCorners is a jQuery plugin. It provides a dead-simple way to       ////
		////    specify rounded-corner/dropShadowed/stroked/etc corner styles to an element,        ////
		////    via css, or javascript. QuadCorners permits you to use a single background          ////
		////    image to specify your container background, without restricting the width and       ////
		////    height of your container to the size of your image. Quadcorners inserts your        ////
		////    image four times within your container--clipped at 50% width/height and             ////
		////    positioned absolutely at top-left, top-right, bottom-right, and bottom-left.        ////
		////    This clipped, four-corner positioning permits the container to resize despite       ////
		////    the fact that only a single image is being used as a background. As long as         ////
		////    the container is not larger the 2X image length - 1X corner radius, it will         ////
		////    not repeat. The quadCorner markup will expand and contract naturally with the       ////
		////    width/height of the markup container, without the assistance of javascript.         ////
		////                                                                                        ////
		////////////////////////////////////////////////////////////////////////////////////////////////
		////                                                                                        ////
		////    Copyright 2009 Jose Cao-Garcia                                                      ////
		////                                                                                        ////
		////    This work is licensed under the Creative Commons Attribution-Share Alike 3.0        ////
		////    United States License. To view a copy of this license, visit                        ////
		////    http://creativecommons.org/licenses/by-sa/3.0/us/ or send a letter to Creative      ////
		////    Commons, 171 Second Street, Suite 300, San Francisco, California, 94105, USA.       ////
		////                                                                                        ////
		////////////////////////////////////////////////////////////////////////////////////////////////
		////                                                                                        ////
		////    LIMITATIONS: background image applied must be at least ~1/2 the size of the         ////
		////    comtainers maximum dimensions. This limitation will be eliminated in a future       ////
		////    release. Contaioner must be positioned relatively ... this limitation will          ////
		////    also be eliminated in the future.                                                   ////
		////                                                                                        ////
		////    FEATURES: Use a single image to specify resizable corner/edge styling for           ////
		////    containers. apply this styling via CSS background properties, or via                ////
		////    javascript. Supports png transparency in standards-challenged browsers.             ////
		////                                                                                        ////
		////    DEPENDENCIES: jQuery.                                                               ////
		////                                                                                        ////
		////    USAGE: see documentation at http://jcao.com/scripts/quadCorners/                    ////
		////                                                                                        ////
		////////////////////////////////////////////////////////////////////////////////////////////////
		////////////////////////////////////////////////////////////////////////////////////////////////

		// For legibility - set tabs to four spaces.
		// all MSIE 6.0 code is denoted with an /*MSIE*/ comment at the beginning of the line.

		// wrap in anonymous function to keep the window napespace clean, and protect plugin scripts.
			(function() {
			////////////////////////////////////////////////////////////////////////////////////////////
			//// object contains important properties, and support for the jquery plugin functions
			////////////////////////////////////////////////////////////////////////////////////////////
				var quadBg = {
				// styles used by quadcorners, edit at your own risk. percentage values are converted to
				// expressions for ie6, but otherwise, it is what it is.
					STRinlineStyling  : '\n\
						<style type="text/css">\n\
							/* THE FOLLOWING STYLES ARE THE BASE/DEFAULT STYLES, AND ASSUME NO BIAS */\n\
							/* BIAS STYING IS APPLIED INLINE, AS IT MUST BE CALCULATED IN JS.       */\n\
								/* only styles imposed upon original container */\n\
									.railCornerParentContainer                 { overflow: hidden; position: relative; }\n\
									div.rndCornersContentWrapper               { position: relative;  margin: 0px; padding: 0px; }\n\
								/* baseline container properties */\n\
									div.rndCornersTopLeft,\n\
									div.rndCornersTopRight,\n\
									div.rndCornersBottomLeft,\n\
									div.rndCornersBottomRight                  { overflow: hidden; position: absolute; width: 50%; height: 50%; margin: 0px; padding: 0px; border: none; font-size: 0px; }\n\
								/* baseline image properties */\n\
									div.rndCornersTopLeft .rndCornersImg,\n\
									div.rndCornersTopRight .rndCornersImg,\n\
									div.rndCornersBottomLeft .rndCornersImg,\n\
									div.rndCornersBottomRight .rndCornersImg   { position: absolute; margin: 0px; padding: 0px; border: none; font-size: 0px; }\n\
								/* ZERO BIAS corner container properties */\n\
									div.rndCornersTopLeft                      { top: 0%;    left: 0%;  }\n\
									div.rndCornersTopRight                     { top: 0%;    left: 50%; }\n\
									div.rndCornersBottomLeft                   { top: 50%;   left: 0%;  }\n\
									div.rndCornersBottomRight                  { top: 50%;   left: 50%; }\n\
								/* ZERO BIAS corner image properties */\n\
									div.rndCornersTopLeft      .rndCornersImg  { top: 0%;    left: 0%;  }\n\
									div.rndCornersTopRight     .rndCornersImg  { top: 0%;    right: 0%; }\n\
									div.rndCornersBottomLeft   .rndCornersImg  { bottom: 0%; left: 0%;  }\n\
									div.rndCornersBottomRight  .rndCornersImg  { bottom: 0%; right: 0%; }\n\
						</style>\n\
					',
/*MSIE*/		////////////////////////////////////////////////////////////////////////////////////////
/*MSIE*/		//// function converts css percentage values to ie-proprietary css "expressions" it is
/*MSIE*/		//// necessary because standards-challenged browsers (ie6) don't support height by
/*MSIE*/		//// percentage, but do by "expression". pass it a css string and it then converts it,
/*MSIE*/		//// if the rendering engine is ie6. For standards-capable browsers, it just passes
/*MSIE*/		//// the unedited css on. Yet another example of MSIE littering the web with crap code.
/*MSIE*/		////////////////////////////////////////////////////////////////////////////////////////
/*MSIE*/			procStyles   : function(STRstyle) {
/*MSIE*/			// if MSIE6, then process
/*MSIE*/				if (jQuery.browser.msie && jQuery.browser.version == '6.0') {
/*MSIE*/				// regex to id percentage values in the styling strings
/*MSIE*/					var RGXcentVal         = /\d{1,3}\%{1}/g;
/*MSIE*/				// split stying into arrays split by percentage values
/*MSIE*/					var ARRcentVals        = STRstyle.match(RGXcentVal);
/*MSIE*/					var ARRcutCents        = STRstyle.split(RGXcentVal);
/*MSIE*/					if(ARRcentVals) {
/*MSIE*/					// create an empty string to build new styling into
/*MSIE*/						var STRnewStyle    = '';
/*MSIE*/					// loop through percent values, convert to expressions and reassemble arrays into new styling string
/*MSIE*/						for (var i=0; i<ARRcentVals.length; i++) {
/*MSIE*/							var STRthisVal = ARRcentVals[i];
/*MSIE*/							var NUMthisVal = STRthisVal.split('%')[0];
/*MSIE*/							var offsetProp = (ARRcutCents[i].match(/width:\s*$|left:\s*$/)) ? 'offsetWidth' : 'offsetHeight';
/*MSIE*/							ARRcentVals[i] =  (NUMthisVal>0) ? 'expression(this.parentNode.'+offsetProp+'*0.' + NUMthisVal + ' + \'px\')' : '0px';
/*MSIE*/							STRnewStyle    += ARRcutCents[i] + ARRcentVals[i];
/*MSIE*/						}
/*MSIE*/					// add remaining string length to new styling string?
/*MSIE*/						if (ARRcutCents.length > ARRcentVals.length) { STRnewStyle += ARRcutCents[ARRcutCents.length-1]; }
/*MSIE*/					// substitute new styling string for old styling
/*MSIE*/						STRstyle           = STRnewStyle;
/*MSIE*/					}
/*MSIE*/				}
/*MSIE*/			// return the appropriate stying string.
/*MSIE*/				return STRstyle;
/*MSIE*/			}
				};
			////////////////////////////////////////////////////////////////////////////////////////////
			//// plugin for adding/removing quadcorner markup/styling and settings
			////////////////////////////////////////////////////////////////////////////////////////////
				jQuery.fn.setQuadBg = function(OBJsettings) {
					DOMparentObj               = this;
					var ARRcornerClasses       = ['rndCornersTopLeft', 'rndCornersTopRight', 'rndCornersBottomLeft', 'rndCornersBottomRight'];
					var STRcornerMarkup        = '<div class="<!--CLASS-->" style="<!--DIVSTYLE-->"><img src="<!--IMG-->" class="rndCornersImg" style="<!--IMGSTYLE-->" /></div>';
					var STRcontWrapMarkup      = '<div class="rndCornersContentWrapper">';
					if (OBJsettings == 'remove') {
						var wrapperDom         = DOMparentObj.find('div.rndCornersContentWrapper');
						if (wrapperDom.length) {
						// move actual content elements to original parent (unwrap)
							wrapperDom.children().each(function(){
								jQuery(this).remove().appendTo(DOMparentObj);
							});
						// remove all IMMEDIATE injected markup (don't screw up nested elements, alter only the target).
							DOMparentObj.children().each(function() { 
								var thisChild  = jQuery(this);
								if (
									thisChild.hasClass('rndCornersContentWrapper') ||
									thisChild.hasClass('rndCornersTopLeft') ||
									thisChild.hasClass('rndCornersTopRight') ||
									thisChild.hasClass('rndCornersBottomLeft') ||
									thisChild.hasClass('rndCornersBottomRight')
								) {
									thisChild.remove();
								}
							});
						}
					}
					if (typeof(OBJsettings) == 'object') {
					// classify the parent container
						DOMparentObj.addClass('railCornerParentContainer');
					// unless otherwise indicated, remove the backup background image.
						if (!OBJsettings.keepBg) { DOMparentObj.css('backgroundImage', 'none'); }
					// wrap the original content in its own div
						DOMparentObj.contents().wrapAll(STRcontWrapMarkup);
/*MSIE*/			// do we neeed special handholding for ie6 png support
/*MSIE*/				var helpIeNotSuck = (jQuery.browser.msie && jQuery.browser.version == '6.0');
						for (var i=0; i<ARRcornerClasses.length; i++) {
						// get the current class
							var STRthisClass          = ARRcornerClasses[i];
						// get the correct image, use the override if it is provided, or the regular image otherwise.
							var thisImg               = OBJsettings['img'+STRthisClass.match(/(Top|Bottom)/)[0].charAt(0) + STRthisClass.match(/(Left|Right)/)[0].charAt(0)] || OBJsettings.img;
/*MSIE*/					var thisImgIsPng          = (/\w\.png/.test(thisImg));
						// perform string construction operations
							var STRthisCornerMarkup   = STRcornerMarkup;
								STRthisCornerMarkup   = STRthisCornerMarkup.replace('<!--CLASS-->', STRthisClass);
/*MSIE*/					if (helpIeNotSuck && thisImgIsPng) {
/*MSIE*/						STRthisCornerMarkup   = STRthisCornerMarkup.replace('<img src="<!--IMG-->" class="rndCornersImg" style="<!--IMGSTYLE-->" />','<div class="rndCornersImg" style="<!--IMGSTYLE-->">&nbsp;</div>');
/*MSIE*/						STRthisCornerMarkup   = STRthisCornerMarkup.replace('<!--IMGSTYLE-->', 'filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src=\'' + OBJsettings.img + '\', sizingMethod=\'image\');');
/*MSIE*/					} else {
								STRthisCornerMarkup   = STRthisCornerMarkup.replace('<!--IMGSTYLE-->', '');
								STRthisCornerMarkup   = STRthisCornerMarkup.replace('<!--IMG-->', thisImg);
/*MSIE*/					}
						// perform offfset enforcement if specified
							var STRthisStyle = '';
							if (OBJsettings.biasL || OBJsettings.biasT) {
							// assert horizontal bias
								if(OBJsettings.biasL) {
									if (/Left$/.test(STRthisClass)) {
										STRthisStyle  += 'width:'+OBJsettings.biasL+'%;left:'+0+'%;';
									} else {
										STRthisStyle  += 'width:'+(100-parseInt(OBJsettings.biasL))+'%;left:'+OBJsettings.biasL+'%;';
									}
								}
							// assert horizontal bias
								if(OBJsettings.biasT) {
									if (/^rndCornersTop/.test(STRthisClass)) {
										STRthisStyle  += 'height:'+OBJsettings.biasT+'%;top:'+0+'%;';
									} else {
										STRthisStyle  += 'height:'+(100-parseInt(OBJsettings.biasT))+'%;top:'+OBJsettings.biasT+'%;';
									}
								}
							}
							STRthisCornerMarkup       = STRthisCornerMarkup.replace('<!--DIVSTYLE-->', quadBg.procStyles(STRthisStyle));
							STRthisCornerMarkup       = STRthisCornerMarkup.replace(' style=""', '');
						// prepend element
							DOMparentObj.prepend(STRthisCornerMarkup);
						}
/*MSIE*/			// post process png images for IE
/*MSIE*/				if (helpIeNotSuck) {
/*MSIE*/					var setImgSize = function(imgSrc) {
/*MSIE*/						var imgFile                = imgSrc.match(/[^\/]+\.\w+$/);
/*MSIE*/						var loaderImg              = document.createElement('img');
/*MSIE*/						loaderImg.onload           = function() {
/*MSIE*/							jQuery('img.rndCornersImg[srcjQuery='+imgFile+']').each(function(){
/*MSIE*/								jQuery(this).css({width: this.offsetWidth + 'px', height: this.offsetHeight + 'px', visibility: 'visible'});
/*MSIE*/								jQuery(this).attr('src', quadBg.STRblankGifSrc);
/*MSIE*/							});                    
/*MSIE*/							this.parentNode.removeChild(this);
/*MSIE*/						};
/*MSIE*/						loaderImg                  = document.getElementsByTagName('body')[0].appendChild(loaderImg);
/*MSIE*/						loaderImg.style.visibility = 'hidden';
/*MSIE*/						loaderImg.src              = imgSrc;
/*MSIE*/					};
/*MSIE*/					setImgSize(OBJsettings.img);
/*MSIE*/				}
					}
				// return jquery
					return DOMparentObj;
				};
			////////////////////////////////////////////////////////////////////////////////////////////
			//// plugin applies quadcorner markup/styling via CSS (within "this" context).
			////////////////////////////////////////////////////////////////////////////////////////////
				jQuery.fn.applyCssQuadBg = function() {
					this.find('*').each(function(){
					// decorate iterated element
						var element = $(this);
					// determine if element has CSS background, containing the querystring keyword
						var hasQuadBg = (
							(
								element.css('background') &&
								/[\?\&]qcImg\=/.test(element.css('background'))
							) || (
								element.css('background-image') &&
								/[\?\&]qcImg\=/.test(element.css('background-image'))
							)
						);
					// if the element styling indicates a corner image, apply it appropriately
						if (hasQuadBg) {
						// get the complete css propery string applicable. longhand trunmps shorthand
							var cssStr           = element.css('background-image') || element.css('background');
						// strip the css string down to the url property alone
							var imgStr           = cssStr.split('url(')[1].split(')')[0].replace('"','').replace('\'','');
						// get the base image location
							var baseImg          = imgStr.split('#')[0].split('?')[0];
						// construct object to pass constructor info on to the processing function.
							var cnrSpecs         = {};
							// get the default image
								cnrSpecs.img     = imgStr.split(/[\?\&]qcImg\=/)[1].split('&')[0];
							// get the top left image override, if there is one.
								cnrSpecs.imgTL   = (/[\?\&]qcImgTL\=[^\&]+/.test(imgStr)) ? imgStr.match(/[\?\&]qcImgTL\=[^\&]+/)[0].split('=')[1] : null;
							// get the top right image override, if there is one.
								cnrSpecs.imgTR   = (/[\?\&]qcImgTR\=[^\&]+/.test(imgStr)) ? imgStr.match(/[\?\&]qcImgTR\=[^\&]+/)[0].split('=')[1] : null;
							// get the bottom right image override, if there is one.
								cnrSpecs.imgBR   = (/[\?\&]qcImgBR\=[^\&]+/.test(imgStr)) ? imgStr.match(/[\?\&]qcImgBR\=[^\&]+/)[0].split('=')[1] : null;
							// get the bottom left image override, if there is one.
								cnrSpecs.imgBL   = (/[\?\&]qcImgTL\=[^\&]+/.test(imgStr)) ? imgStr.match(/[\?\&]qcImgTL\=[^\&]+/)[0].split('=')[1] : null;
							// get left biasing
								cnrSpecs.biasL   = (/[\?\&](qcBiasL|qcBiasR)\=\d+/.test(imgStr)) ? ((/[\?\&]qcBiasL\=\d+/.test(imgStr)) ? imgStr.match(/[\?\&]qcBiasL\=\d+/)[0].split('=')[1] : 100 - imgStr.match(/[\?\&]qcBiasR\=\d+/)[0].split('=')[1]) : null;
							// get top biasing
								cnrSpecs.biasT   = (/[\?\&](qcBiasT|qcBiasB)\=\d+/.test(imgStr)) ? ((/[\?\&]qcBiasT\=\d+/.test(imgStr)) ? imgStr.match(/[\?\&]qcBiasT\=\d+/)[0].split('=')[1] : 100 - imgStr.match(/[\?\&]qcBiasB\=\d+/)[0].split('=')[1]) : null;
							// detemerine whether or not to keep the original background styling
								cnrSpecs.keepBg  = !!(/[\?\&]qcKeepBg\=true/.test(imgStr));
						// process all image properties for correct pathing
							for (var i in cnrSpecs) { if (i.indexOf('img') != -1 && cnrSpecs[i]) { cnrSpecs[i] = (/^\.\/|^\./.test(cnrSpecs[i])) ? cnrSpecs[i] : (baseImg.substring(0, baseImg.lastIndexOf('/'))+'/'+cnrSpecs[i]); } }
						}
						element.setQuadBg(cnrSpecs);
					});
				};
			////////////////////////////////////////////////////////////////////////////////////////////
			//// plugin provides quadcorners-safe (nondestructive) HTML method, like $().html().
			////////////////////////////////////////////////////////////////////////////////////////////
				jQuery.fn.HTML = function(arg) {
				// if element contains a quadcorners content wrapper as an immediate child, shift target element, to it.
					var target = (this.children('div.rndCornersContentWrapper').length) ? $(this.children('div.rndCornersContentWrapper')[0]) : this;
				// if new HTML has been specified, make sure it gets processed for any quadCorner styling automatically.
					if (arg) {
					// first - insert the innerhtml.
						target.html(arg);
					// second, apply quadCorners throughout element contents (on a delay or styling is ignored).
						setTimeout(
							function() {
								target.applyCssQuadBg();
							},
							10
						);
					}
				// finally, return the completed markup.
					return target.html(arg);
				};
				jQuery(document).ready(function() { jQuery('body').applyCssQuadBg(); });
			////////////////////////////////////////////////////////////////////////////////////////////
			//// write in supporting inline styles.
			////////////////////////////////////////////////////////////////////////////////////////////
/*MSIE*/		document.write(quadBg.procStyles(quadBg.STRinlineStyling));
			})();



