/*
 * PfeLoader v1.0.3
 * 
 * Copyright (c) 2009 Arkadiusz Dzięgiel
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 * 
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
 
jQuery.PfeLoader={
	'findImages':function(){
		var rexp=/^url(\(['"]?(.*?)['"]?\))/i;
		var images=new Array();
		var b=$("*")
		var s=b.size()
		b.each(function(){
			if(this.tagName.toUpperCase()=="IMG"){
				images.push(this.src);
			}
			var i=this.style.backgroundImage;
			if(i!=""){
				images.push(i.match(rexp)[2])
			}
		})
		var l=document.styleSheets.length
		for(var i=0;i<l;i++){
			var sheet=document.styleSheets[i];
			var sheet_dir='';
			if(sheet.href!=null){
				sheet_dir=sheet.href.substring(0,sheet.href.lastIndexOf('/')+1);
			}
			var rules=sheet[sheet.cssRules?'cssRules':'rules'];
			ll=rules.length
		
			for(var j=0;j<ll;j++){
				var rule=rules[j];
				var bg=rule.style.backgroundImage;
				if(bg!="" && bg!='none'){
					images.push(sheet_dir+bg.match(rexp)[2]);
				}
			}
		}
		return images;
	},
	'preload':function(imgs,onStart,onChange,onDone,timeout){
		//hidden div for images
		var the_div=$(document.createElement('div')).css({
			display:'block',position:'absolute',height:1,width:1,left:-1,top:-1,overflow:'hidden'
		}).appendTo('body');
		
		the_div.images_loaded=0;
		the_div.images_timeout=0;
		the_div.images_count=-1;
		
		function getObj(){
			return {'loaded':the_div.images_loaded,'count':the_div.images_count,'timeout':the_div.images_timeout};
		}
		
		the_div.check_images=function(){
			if(this.images_loaded+this.images_timeout==this.images_count){
				if(onDone)
					onDone.apply(getObj());
				this.remove();
			}
		};

		function createImage(src){
			var img=$(new Image());

			if(timeout!=0){
				var t=setTimeout(function(){
					the_div.images_timeout++;
					triggerChange();
				},timeout);
			}

			function triggerChange(){
				if(timeout!=0)
					clearTimeout(t);
				img.remove();
				if(the_div.images_count>0 && onChange)
					onChange.apply(getObj());
				the_div.check_images();
			}
					
			img.appendTo(the_div).load(function(){
				the_div.images_loaded+=1;
				triggerChange();
			}).attr('src',src);
			
		}
	
		var images_count=0;
		for(var i=0;i<imgs.length;i++){
			if(imgs[i]!=null){
				createImage(imgs[i]);
				images_count++;
			}
		}
		the_div.images_count=images_count;
		if(onStart) onStart.apply(getObj());
		the_div.check_images();
	},
	'getImages':function(b){
		var a=jQuery.PfeLoader.findImages();
		return jQuery.merge(a,b);
	},
	'getOptions':function(o){
		return jQuery.extend({
			timeout:	0,
			imgs:		[],
			onStart:	null,
			onChange:	null,
			onDone:		null,
			findImages:	true
		},o);
	},
	'start':function(o){
		var opts=jQuery.PfeLoader.getOptions(o);
		var imgs;
		if(opts.findImages){
			imgs=jQuery.PfeLoader.getImages(opts.imgs);
		} else {
			imgs=opts.imgs;
		}
		jQuery.PfeLoader.preload(imgs,opts.onStart,opts.onChange,opts.onDone,opts.timeout);
	},
	'demo':function(opts){
		var o=jQuery.PfeLoader.getOptions(opts);
		var images_count=o.imgs.length;
		if(o.findImages){
			images_count=jQuery.PfeLoader.getImages(o.imgs).length;
		}
		var max_loaded=Math.floor(Math.random()*images_count/3*2)+images_count/3;
		var images_loaded=0;
		var images_timeout=0;
		
		var i;
		
		function getObj(){
			return {'loaded':images_loaded,'count':images_count,'timeout':images_timeout};
		}
		
		function increment(){
			var rnd=Math.random();
			if(rnd<0.5){
				if(images_loaded==max_loaded){
					images_timeout++;
				} else {
					images_loaded++;
				}
			} else
			if(rnd<0.8){
				if(images_count-max_loaded==images_timeout){
					images_loaded++;
				} else {
					images_timeout++;
				}
			} else {
				//nothing
			}
			
			if(rnd<0.8){
				o.onChange.apply(getObj());
			}
			if(images_loaded+images_timeout==images_count){
				clearInterval(i);
				o.onDone.apply(getObj());
			}
			
		}
		
		o.onStart.apply(getObj());
		i=setInterval(increment,300);
	}
}
