(function($){
	
	var selected_mosaic = null;
	var selected_picture = null;
	var selected_type = null;
	var changed_images = null;
	var loaded_images = null;
	var container = null;
	var settings = null;
	var images = new Array();
	
	$.fn.zipMosaic = function(options) {
        return this.each(function() {   
            $.zipMosaic(this, options);
        });
    };
	
	$.zipMosaic = function(parent, options){
		settings = {
			cols: 7,
			rows: 2,
			mosaic_folders: ['images/mosaic/1', 'images/mosaic/2'],
			picture_folders: ['images/picture/1','images/picture/2','images/picture/3','images/picture/4','images/picture/5','images/picture/6'],
			change_speed: 'fast',
			part_changeTimeout: 100,
			full_changeTimeout: 5000
		};
		if (options) settings = $.extend(settings, options);
		container = parent;
		$(parent).empty();
				
		if (settings.mosaic_folders.length > 0) {
			selected_mosaic = 0;
			selected_picture = 0;
			selected_type = 'mosaic';
			changed_images = new Array(); 
			loaded_images = new Array();
		}
		
		for(var j=0; j<settings.rows; j++) {
			var wrapper = $('<div></div>').addClass('wrapper').appendTo(parent);
			for(var i=1; i<=settings.cols; i++) 
				$('<img/>').attr('src',settings.mosaic_folders[selected_mosaic]+'/'+(j*7+i)+'.jpg').appendTo(wrapper);
		}
		
		$.zipMosaic.preloadImages();
		setTimeout($.zipMosaic.change,settings.full_changeTimeout);		
	};
	
	$.zipMosaic.change = function() {
		// swaps all images of picture
		if (loaded_images.length == settings.cols*settings.rows) {
			
			var swapOrder = new Array();
			for (var i=0; i<settings.cols*settings.rows; i++) {
				var index = 0;
				var unique = true;
				do {
					unique = true;
					index = parseInt(Math.random()*settings.rows*settings.cols);
					for(var j=0; j<settings.cols*settings.rows && unique; j++)
						if (swapOrder[j] == index) unique = false;
				}
				while(!unique);
				swapOrder[swapOrder.length] = index;
			}
			for(var i=0; i<settings.cols*settings.rows; i++) {
				setTimeout('$.zipMosaic.swapImage('+swapOrder[i]+')',i*settings.part_changeTimeout);
			}
		}
		else setTimeout($.zipMosaic.change,1000);
	};
	
	$.zipMosaic.swapImage = function(index) {
		// finds image with specified index and swap it to preloaded image
		$('img',container).eq(index).fadeOut(settings.change_speed,function(){
			var img = null;
			for(var i=0; i<loaded_images.length && img == null; i++) 
				if ($(loaded_images[i]).attr('index') == index) img = loaded_images[i];
			$(img).insertAfter(this).fadeIn(settings.change_speed);
			$(this).remove();
			changed_images[changed_images.length] = index;
			
			if (changed_images.length == settings.rows*settings.cols) {
				changed_images = new Array();
				$.zipMosaic.swapPicture();
			}
		});		
	}
	
	$.zipMosaic.swapPicture = function() {
		if (selected_type == 'mosaic') {
			selected_type = 'picture';
			var index = 0;
			var unique = true;
			do {
				unique = true;
				index = Math.round(Math.random()*(settings.mosaic_folders.length-1));
				if (selected_mosaic == index) unique = false;
			}
			while (!unique);
			selected_mosaic = index;
		}	
		else {
			selected_type = 'mosaic';
			var index = 0;
			var unique = true;
			do {
				unique = true;
				index = Math.round(Math.random()*(settings.picture_folders.length-1));
				if (selected_picture == index) unique = false;
			}
			while (!unique);
			selected_picture = index;
		}
		$.zipMosaic.preloadImages();
		setTimeout($.zipMosaic.change,settings.full_changeTimeout);
	}
	
	$.zipMosaic.preloadImages = function() {
		// preload images of next picture 
		var path = settings.mosaic_folders[selected_mosaic];
		if (selected_type == 'mosaic') path = settings.picture_folders[selected_picture];
		loaded_images = new Array();
		for(var i=0; i<settings.cols*settings.rows; i++) {
			var img = new Image();
			var index = i;
			$(img).hide().load(function() {
				loaded_images[loaded_images.length] = $(this);
			}).attr('index',i).attr('src',path+'/'+(index+1)+'.jpg');
		} 
	};
		
})(jQuery);
