function $random(min, max){
	return Math.floor(Math.random() * (max - min + 1) + min);
};

Element.addMethods( {
	clear: function( element ) {
		element.descendants().each( function( el ) {
			el.remove();
		} )
	},
	
	clone: function( element, contents ) {
		return $(element.cloneNode(contents !== false));
	}
} );

Object.extend(Array.prototype, {
	random: function() {
		if( this.length == 0 ) {
			return null;
		}
		
		return this[ $random( 0, this.length-1 ) ];
	},
	
	remove: function( item ) {
		var i = 0;
		var len = this.length;
		while (i < len){
			if (this[i] === item){
				this.splice(i, 1);
				len--;
			} else {
				i++;
			}
		}
		return this;
	}
});

var switchImage;

document.observe( 'dom:loaded', function() {
	var imageList = [];

	var timingFade  = 1500;

	// preload images
	images.each( function( path ) {
		var img = new Image();
		img.src = path;
		
		imageList.push( new Element( "img", {
			src: path,
			alt: "",
			style: "display: none;"
		} ) );
	} );

	// make sure the array only contains extended elements and no element twice
	var tmp = [];
	imageContainers.each( function( el ) {
		el = $(el);
		if (el ) {
			tmp.push( $(el) );
		}
	} );
	imageContainers = tmp.uniq();
	
	var busyContainers = [];
	var busyImages = [];

	switchImage = function( pe ) {
		if( imageContainers.length === 0 || imageList.length === 0 ) {
			return;
		}
		
		var cell     = imageContainers.random();
		var newImage = imageList.random();
		var oldImage = busyImages.random();
		
		cell.insert( newImage );

		imageContainers.remove( cell );
		busyContainers.push( cell );

		imageList.remove( newImage );
		busyImages.push( newImage );

		newImage.appear( {duration: timingFade / 1000.0} );

		oldImage.fade( {duration: timingFade / 1000.0, afterFinish: function() {
			var cell = oldImage.up();
			oldImage.remove();
			oldImage.style.display = "none";
			imageList.push( oldImage );
			busyImages.remove( oldImage );

			imageContainers.push( cell );
			busyContainers.remove( cell );
		}});
	};

	var addImage = function( cell ) {
		if (!cell) {
			return;
		}
	
		if (cell.firstDescendant()) {
			cell.firstDescendant().remove();
		}
		var newImage = imageList.random();
		cell.insert( newImage );

		imageList.remove( newImage );
		busyImages.push( newImage );
		
		imageContainers.remove( cell );
		busyContainers.push( cell );
		
		newImage.appear( {duration: timingFade / 1000.0 } );
	};
	
	startCells.each( function( el ) {
		addImage( $(el) );
	} );
	
	new PeriodicalExecuter( switchImage, 3 );
} );
