var Preloader = Class.create({
		
	initialize: function() {
		this.preloadImages = [];
		this.loadedImagePaths =[];
		//console.info("Preloader::initialize");
		this.bObj = this.onImageLoad.bind(this);
	},
	
	
	/**
	 *	Add a single image path, or array of image paths, to the Preloader.
	 */
	addToQueue: function(imgs) {
		//console.info("Preloader::addToQueue", imgs);
		if(typeof imgs == 'string') {
			this.preloadImages.push(imgs);
		} else if (typeof imgs == 'array'|| typeof imgs == 'object') {
			for (var i=0;i<imgs.length;i++) {
				this.preloadImages.push(imgs[i]);
			}
		}
	},
	
	/**
	 *	Start loading images from the preloadImages array.
	 */
	startLoading: function() {
		//console.info("Preloader::startLoading");
     this.loadNext();
	},
	
	/**
	 *	Loads the next image in the preloadImages array.
	 */
	loadNext: function() {
		//console.info("Preloader::loadNext");
		
		if(this.preloadImages.length == 0)
			return;
			
		var nextImgPath = this.preloadImages.shift();
		
    // Create an extended image element.
		var imgToLoad = Element.extend(document.createElement('img'));
    // Insert the img as a hidden element on the page.
    var bodyTag = $$('body')[0];
    imgToLoad.setStyle({display:'none'});
    bodyTag.insert({bottom:imgToLoad});
		// Set up the load event for imageLoader.	
		Event.observe(imgToLoad,'load', this.bObj);
		Event.observe(imgToLoad,'error', this.bObj);
		// set new src url
		// setTimeout works around 'stack overflow at line 0' in IE.
		setTimeout(function(){
		  imgToLoad.setAttribute('src',nextImgPath);
		}, 0);

	},
	
	
	/**
	 * Determines whether the passed path has been loaded by the preloader.
	 */
	hasPathLoaded: function(path) {
	  for (var i=0;i<this.loadedImagePaths.length;i++) {
      var parsedUrl = parseUri(this.loadedImagePaths[i]);
	    if(parsedUrl.relative == path)
	      return true;	    
	  }
	  return false;	
	},
		
	/**
	 *	Handler for each image load event.
	 */
	onImageLoad: function(ev) {
    // console.info("Preloader::onImageLoad","type:"+ev.type, "image:"+ev.element().src);
	  // Store the image path in the loadedImagePaths array.
    this.loadedImagePaths.push(ev.element().src);
    // Stop observing this event.
    Event.stopObserving(ev.element(),'load', this.bObj);
    Event.stopObserving(ev.element(),'error', this.bObj);
    // Remove the element from the DOM
    ev.element().remove();
		// If there's more images to load, load the next image.
		if(this.preloadImages.length != 0)
			this.loadNext();
	}
	
});


/*
	parseUri 1.2.1
	(c) 2007 Steven Levithan <stevenlevithan.com>
	MIT License
*/

function parseUri (str) {
  	var	o   = parseUri.options,
    		m   = o.parser[o.strictMode ? "strict" : "loose"].exec(str),
    		uri = {},
    		i   = 14;

  	while (i--) uri[o.key[i]] = m[i] || "";

  	uri[o.q.name] = {};
  	uri[o.key[12]].replace(o.q.parser, function ($0, $1, $2) {
  		  if ($1) uri[o.q.name][$1] = $2;
  	});

  	return uri;
};

parseUri.options = {
  	strictMode: false,
  	key: ["source","protocol","authority","userInfo","user","password","host","port","relative","path","directory","file","query","anchor"],
  	q:   {
    		name:   "queryKey",
    		parser: /(?:^|&)([^&=]*)=?([^&]*)/g
  	},
  	parser: {
    		strict: /^(?:([^:\/?#]+):)?(?:\/\/((?:(([^:@]*):?([^:@]*))?@)?([^:\/?#]*)(?::(\d*))?))?((((?:[^?#\/]*\/)*)([^?#]*))(?:\?([^#]*))?(?:#(.*))?)/,
    		loose:  /^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*):?([^:@]*))?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/
  	}
};



