

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 
//		var: Preloader
//		This class enables serial preloads, ordered by priority. 
//
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////




var Preloader = new Class(
{
	Implements: [Options, Events],
	
	options: {},
	
	initialize: function(options) 
	{
		// Managing Data /////////////////////////////////////////////////////////////////////////////////////////////////////
		// and setting up the HTML structure /////////////////////////////////////////////////////////////////////////////////
		
		this.setOptions(options);
		var wrapper = new Element( 'div', { id:'Preloader' }).fade(0.5);
		
		
		// var: extensions ///////////////////////////////////////////////////////////////////////////////////////////////////
		// This in fact is the *real* class. All important functionality will be implemented into the HTML wrapper DIV for easy access by $(ID).
		
		var extensions = 
		{
			options: this.options,
			complete: [],
			queue: [],
			status: [],
			
			
			// func: preload
			// This function is being called from outside. It will queue the given file and start the load-Loop. 
			preload: function(file,priority)
			{
				// console.log( 'Preloader.preload() file='+file);
				if( this.complete.contains( file )) 
				{
					this.fireEvent( 'complete', [ file ]);
				}
				else
				{
					this.queue.push({file:file, priority:priority});
					if( this.status!='running') this.loadNext();
				}
			},
			
			
			// func: loadNext
			// This resorts the queue and starts the preload. It's being called by <preload> or just by the previous load. 
			loadNext: function()
			{
				if( this.queue.length <1) 
				{
					this.status = 'ready';
				}
				else
				{
					this.status = 'running';
					function sortHelper(a,b) { return a.priority - b.priority; }
					this.queue.sort( sortHelper );
					var nextFile = this.queue.shift().file;
					
					// By now, only image formats can be preloaded, other file types will be skipped. 
					if( !this.complete.contains(nextFile) && ( nextFile.test(/\.jpg/) || nextFile.test(/\.gif/) || nextFile.test(/\.png/)))
					{
						// console.log( 'Preloader.loadNext() starting file='+nextFile);
						var img = new Element('img', { src:nextFile }).inject( this, 'top' );
						img.addEvent( 'load', function()
						{
							this.complete.push( nextFile );
							this.fireEvent( 'complete', [ nextFile ]);
							// console.log( 'Preloader.loadNext() complete file='+nextFile);
							img.destroy();
							this.loadNext();
						}.bind(this));
					}
					else 
					{
						this.fireEvent( 'complete', [ nextFile ]);
						this.loadNext();
					}
				}
			}
						
			
		};
		$extend( wrapper, extensions );
		
		
		

		// return: wrapper ///////////////////////////////////////////////////////////////////////////////////////////////////
		// The whole HTML structure will be returned, with all the important attributes and functions implemented into it. ///
		// So the class can easyly be accessed by $(ID) and the rest of it won't be needed from now on. //////////////////////
		// By default, the wrapper will be injected into the body. ///////////////////////////////////////////////////////////
		return wrapper.inject( $$('body')[0] ); 
		
	}
});
