/**
 * jQuery-Plugin "preloadCssImages"
 * by Scott Jehl, scott@filamentgroup.com
 * http://www.filamentgroup.com
 * reference article: http://www.filamentgroup.com/lab/update_automatically_preload_images_from_css_with_jquery/
 * demo page: http://www.filamentgroup.com/examples/preloadImages/index_v2.php
 * 
 * Copyright (c) 2008 Filament Group, Inc
 * Dual licensed under the MIT (filamentgroup.com/examples/mit-license.txt) and GPL (filamentgroup.com/examples/gpl-license.txt) licenses.
 *
 * Version: 5.0, 10.31.2008
 * Changelog:
 * 		 02.20.2008 initial Version 1.0
 *    06.04.2008 Version 2.0 : removed need for any passed arguments. Images load from any and all directories.
 *    06.21.2008 Version 3.0 : Added options for loading status. Fixed IE abs image path bug (thanks Sam Pohlenz).
 *    07.24.2008 Version 4.0 : Added support for @imported CSS (credit: http://marcarea.com/). Fixed support in Opera as well. 
 *    10.31.2008 Version: 5.0 : Many feature and performance enhancements from trixta
 * --------------------------------------------------------------------
 */

;jQuery.preloadCssImages = function(settings){
		 settings = jQuery.extend({
		 		 statusTextEl: null,
		 		 statusBarEl: null,
		 		 errorDelay: 999, // handles 404-Errors in IE
		 		 simultaneousCacheLoading: 2
		 }, settings);
		 var allImgs = [],
		 		 loaded = 0,
		 		 imgUrls = [],
		 		 thisSheetRules,		 
		 		 errorTimer;
		 
		 function onImgComplete(){
		 		 clearTimeout(errorTimer);
		 		 if (imgUrls && imgUrls.length && imgUrls[loaded]) {
		 		 		 loaded++;
		 		 		 if (settings.statusTextEl) {
		 		 		 		 var nowloading = (imgUrls[loaded]) ? 
		 		 		 		 		 'Now Loading: <span>' + imgUrls[loaded].split('/')[imgUrls[loaded].split('/').length - 1] : 
		 		 		 		 		 'Loading complete'; // wrong status-text bug fixed
		 		 		 		 jQuery(settings.statusTextEl).html('<span class="numLoaded">' + loaded + '</span> of <span class="numTotal">' + imgUrls.length + '</span> loaded (<span class="percentLoaded">' + (loaded / imgUrls.length * 100).toFixed(0) + '%</span>) <span class="currentImg">' + nowloading + '</span></span>');
		 		 		 }
		 		 		 if (settings.statusBarEl) {
		 		 		 		 var barWidth = jQuery(settings.statusBarEl).width();
		 		 		 		 jQuery(settings.statusBarEl).css('background-position', -(barWidth - (barWidth * loaded / imgUrls.length).toFixed(0)) + 'px 50%');
		 		 		 }
		 		 		 loadImgs();
		 		 }
		 }
		 
		 function loadImgs(){
		 		 //only load 1 image at the same time / most browsers can only handle 2 http requests, 1 should remain for user-interaction (Ajax, other images, normal page requests...)
		 		 // otherwise set simultaneousCacheLoading to a higher number for simultaneous downloads
		 		 if(imgUrls && imgUrls.length && imgUrls[loaded]){
		 		 		 var img = new Image(); //new img obj
		 		 		 img.src = imgUrls[loaded];		 //set src either absolute or rel to css dir
		 		 		 if(!img.complete){
		 		 		 		 jQuery(img).bind('error load onreadystatechange', onImgComplete);
		 		 		 } else {
		 		 		 		 onImgComplete();
		 		 		 }
		 		 		 errorTimer = setTimeout(onImgComplete, settings.errorDelay); // handles 404-Errors in IE
		 		 }
		 }
		 
		 function parseCSS(sheets, urls) {
		 		 var w3cImport = false,
		 		 		 imported = [],
		 		 		 importedSrc = [],
		 		 		 baseURL;
		 		 var sheetIndex = sheets.length;
		 		 while(sheetIndex--){//loop through each stylesheet
		 		 		 
		 		 		 var cssPile = '';//create large string of all css rules in sheet
		 		 		 
		 		 		 if(urls && urls[sheetIndex]){
		 		 		 		 baseURL = urls[sheetIndex];
		 		 		 } else {
		 		 		 		 var csshref = (sheets[sheetIndex].href) ? sheets[sheetIndex].href : 'window.location.href';
		 		 		 		 var baseURLarr = csshref.split('/');//split href at / to make array
		 		 		 		 baseURLarr.pop();//remove file path from baseURL array
		 		 		 		 baseURL = baseURLarr.join('/');//create base url for the images in this sheet (css file's dir)
		 		 		 		 if (baseURL) {
		 		 		 		 		 baseURL += '/'; //tack on a / if needed
		 		 		 		 }
		 		 		 }
		 		 		 if(sheets[sheetIndex].cssRules || sheets[sheetIndex].rules){
		 		 		 		 thisSheetRules = (sheets[sheetIndex].cssRules) ? //->>> http://www.quirksmode.org/dom/w3c_css.html
		 		 		 		 		 sheets[sheetIndex].cssRules : //w3
		 		 		 		 		 sheets[sheetIndex].rules; //ie 
		 		 		 		 var ruleIndex = thisSheetRules.length;
		 		 		 		 while(ruleIndex--){
		 		 		 		 		 if(thisSheetRules[ruleIndex].style && thisSheetRules[ruleIndex].style.cssText){
		 		 		 		 		 		 var text = thisSheetRules[ruleIndex].style.cssText;
		 		 		 		 		 		 if(text.toLowerCase().indexOf('url') != -1){ // only add rules to the string if you can assume, to find an image, speed improvement
		 		 		 		 		 		 		 cssPile += text; // thisSheetRules[ruleIndex].style.cssText instead of thisSheetRules[ruleIndex].cssText is a huge speed improvement
		 		 		 		 		 		 }
		 		 		 		 		 } else if(thisSheetRules[ruleIndex].styleSheet) {
		 		 		 		 		 		 imported.push(thisSheetRules[ruleIndex].styleSheet);
		 		 		 		 		 		 w3cImport = true;
		 		 		 		 		 }
		 		 		 		 		 
		 		 		 		 }
		 		 		 }
		 		 		 //parse cssPile for image urls
		 		 		 var tmpImage = cssPile.match(/[^\("]+\.(gif|jpg|jpeg|png)/g);//reg ex to get a string of between a "(" and a ".filename" / '"' for opera-bugfix
		 		 		 if(tmpImage){
		 		 		 		 var i = tmpImage.length;
		 		 		 		 while(i--){ // handle baseUrl here for multiple stylesheets in different folders bug
		 		 		 		 		 var imgSrc = (tmpImage[i].charAt(0) == '/' || tmpImage[i].match('://')) ? // protocol-bug fixed
		 		 		 		 		 		 tmpImage[i] : 
		 		 		 		 		 		 baseURL + tmpImage[i];
		 		 		 		 		 
		 		 		 		 		 if(jQuery.inArray(imgSrc, imgUrls) == -1){
		 		 		 		 		 		 imgUrls.push(imgSrc);
		 		 		 		 		 }
		 		 		 		 }
		 		 		 }
		 		 		 
		 		 		 if(!w3cImport && sheets[sheetIndex].imports && sheets[sheetIndex].imports.length) {
		 		 		 		 for(var iImport = 0, importLen = sheets[sheetIndex].imports.length; iImport < importLen; iImport++){
		 		 		 		 		 var iHref = sheets[sheetIndex].imports[iImport].href;
		 		 		 		 		 iHref = iHref.split('/');
		 		 		 		 		 iHref.pop();
		 		 		 		 		 iHref = iHref.join('/');
		 		 		 		 		 if (iHref) {
		 		 		 		 		 		 iHref += '/'; //tack on a / if needed
		 		 		 		 		 }
		 		 		 		 		 var iSrc = (iHref.charAt(0) == '/' || iHref.match('://')) ? // protocol-bug fixed
		 		 		 		 		 		 iHref : 
		 		 		 		 		 		 baseURL + iHref;
		 		 		 		 		 
		 		 		 		 		 importedSrc.push(iSrc);
		 		 		 		 		 imported.push(sheets[sheetIndex].imports[iImport]);
		 		 		 		 }
		 		 		 		 
		 		 		 		 
		 		 		 }
		 		 }//loop
		 		 if(imported.length){
		 		 		 parseCSS(imported, importedSrc);
		 		 		 return false;
		 		 }
		 		 var downloads = settings.simultaneousCacheLoading;
		 		 while( downloads--){
		 		 		 setTimeout(loadImgs, downloads);
		 		 }
		 }
		 parseCSS(document.styleSheets);
		 return imgUrls;
};

