/* Picture Animation */

// Extend the array prototype to add the function "shuffle" to randomise it's contents
// http://www.hunlock.com/blogs/Mastering_Javascript_Arrays
Array.prototype.shuffle = function() {
	for(var rnd, tmp, i=this.length; i; rnd=parseInt(Math.random()*i), tmp=this[--i], this[i]=this[rnd], this[rnd]=tmp);
}


// When the document is loaded, start the show with it's parameters
jQuery(document).ready(function() {
	
	var randomShow = new SHOW({
		fps : 7, // Frames per second in which the pictures change
		picNumber : 49, // Total number of pictures in the sprite sheet
		picSheet : null, // Pass the sprite sheet image instead and we will calculate picNumber nous-même
		picWidth : 39, // The width of one sprite
		selector : ["#PhotoLeft", "#PhotoRight"], // Selector of the rows
		style : ["faced-div-left", "faced-div-right"], // Style of the rows
	});
	
	randomShow.runShow();
	
	// On resize we need to re-calculate the number of shows
	// Uses a jQuery plugin ( http://benalman.com/projects/jquery-resize-plugin/ ) for consitent cross-browser behaviour
	jQuery(window).resize(function() {
		randomShow.recalculate(randomShow);
	});
})



var SHOW = function(param) {
	
	/** Vars **/
	
	if(param.picNumber) {
		this.picNumber = param.picNumber; // Total number of pictures in the sprite sheet
	} else {
		var img = new Image();
		img.src = param.picSheet;
		this.picNumber = img.width / param.picWidth; // Sprite sheet width / sprite width
	}
	
	this.fps = param.fps, // Frames per second in which the pictures change
	this.selector = param.selector, // Selector of the rows
	this.style = param.style, // Style of the rows
	this.picWidth = param.picWidth;
	
	this.numberOfShows = 0;
	this.shows = [];
	this.picturePool = [];
	
	/** Methods **/
	
	/* Public */
	
	this.runShow = function() {
		
		this.numberOfShows = this._calcNumberOfShows();

		/* Initialisation */
		
		// Create two arrays: one for all the show div ids and one for all the pictures that are currently not shown
		this.shows = Array(this.numberOfShows * this.selector.length);
		this.picturePool = Array(this.picNumber); // Start with all the pictures in the pool
		
		// To start with all picture id's are numbered 0 to totalNumberOfPictures - 1
		for(var i=0; i < this.picturePool.length; i++) {
			this.picturePool[i] = i;
		}
		this.picturePool.shuffle(); // Now shuffle the array so we have a random sequence of picture id's
		
		// Create the show's elements and add a unique id to each of them
		// We need to take care of the different selectors as well
		for(var j=0; j < this.selector.length; j++) {
			var target = jQuery(this.selector[j]);
			for(var i=0; i < this.numberOfShows; i++) {
				 /* var id = "show-id-" + (j * this.numberOfShows + i); */ // Unique ID of this div
				var id = "show-id-" + ((i * this.selector.length) + j); // Unique ID of this div, spread the divs over the selectors
				this.shows[id] = this.picturePool.pop(); // Take pictures from the pool one by one
				
				target.append("<div class='" + this.style[j] + "' id='" + id + "'></div>"); // Here we create the div's and add it's style and a unique ID
			}
		}
		
		// Now loop through all the created divs and load the images (could probably be done in the same loop above, but this seems clearerfr now)
		for(var j=0; j < this.selector.length; j++) {
			var target = jQuery(this.selector[j]);
			var my = this;
			jQuery.each(target.children(), function () {
				var id = jQuery(this).attr('id'); // Get the id of this element
				var position = my._calcPosition(my.shows[id]); // Calculate te position by the picID of current show
				jQuery(this).css("backgroundPosition", position, 0); // Set the background position
			});
		}
		
		/* Set the timer for the animation */
		
		var my = this;
		var timer = setInterval(function() {
			var newPicture = my._getNewPicture(my.shows, my.picturePool); // Get the picture to replace and the replacement picture
			
			// Change the background-position of the div
			var position = my._calcPosition(newPicture.picId);
			
			jQuery('#' + newPicture.showId).css("backgroundPosition", position, 0);
		}, 1000 / this.fps);
	}
	
	// Recalculate the divs on .resize()
	this.recalculate = function(my) {
		var numberOfShows = my.numberOfShows; // Number of current shows
		var newNumberOfShows = my._calcNumberOfShows(); // Number of shows we made (less) room for
		
		/* SHOULD STOP WHEN AT A CERTAIN MINIMUM OF PICURES (= NUMBER OF PICTURES IN LAYOUT WIDTH) */
		if(numberOfShows == newNumberOfShows || newNumberOfShows < 5) { // Nothing changed
			return;
		} else if(numberOfShows < newNumberOfShows) { // Shows were added
			var addShows = newNumberOfShows - numberOfShows;
			for(var j=0; j < my.selector.length; j++) {
				var target = jQuery(my.selector[j]);
				for(i=0; i < addShows ; i++) { // Spread over the selectors
					// Take a picture from the pool
					var random = my._generateRandom(my.picturePool.length - 1);
					var picture = my.picturePool.splice(random, 1);
					
					// Generate a new div
					var id = "show-id-" + (my.shows.length); // Unique ID of this div
					target.append("<div class='" + my.style[j] + "' id='" + id + "'></div>"); // Here we create the div's and add it's style and a unique ID
					
					// Add to shows
					my.shows[id] = picture;
					my.shows.length++; // Update he length, it's not an array but an object!
					
					// Set he background position
					var position = my._calcPosition(my.shows[id]); // Calculate te position by the picID of current show
					jQuery("#" + id).css("backgroundPosition", position, 0); // Set the background position
				}
			}
		} else { // Shows were removed
			var delShows = numberOfShows - newNumberOfShows;
			for(var j=0; j < my.selector.length; j++) {
				var target = jQuery(my.selector[j]);
				for(i=0; i < delShows; i++) {
					// Add to the picture pool, then remove the show
					var id = "show-id-" + (my.shows.length - 1);
					my.picturePool.push(my.shows[id]);
					delete my.shows[id];
					my.shows.length--; // Update he length, it's not an array but an object!
					
					// Delete the div
					jQuery("#" + id).remove();
					console.log(id);
				}
			}
		}
		
		my.numberOfShows = newNumberOfShows;
	}
	
	/* Private */
	
	// Get innformation to replace a show with a new picture
	this._getNewPicture = function() {
		var showToChange = "show-id-" + this._generateRandom(this.shows.length - 1); // Pick a random show id from the number of shows
		var newPicture = this._generateRandom(this.picturePool.length - 1); // Pick a random spot in the list if unused pictures
		var newPictureId = this.picturePool[newPicture]; // Get the value (= pictureId) of the random spot
		
		this.picturePool[newPicture] = this.shows[showToChange]; // Replace the picture in the pool with the picture from the show
		this.shows[showToChange] = newPictureId; // The show must now show the new picture
		
		return { 'showId' : showToChange, 'picId' : newPictureId}; // Return the show and picture so we can change css with this information
	}
	
	
	// Generates a random number between 0 and max
	this._generateRandom = function(max) {
		var random = Math.floor(Math.random() * (max + 1));
		return random;
	}

	// Formula to calculate the background position when the picture number is given
	this._calcPosition = function(picId) {
		return this.picWidth * (picId - 1);
	}

	// Calculates the number of pictures to show in one gallery
	this._calcNumberOfShows = function() {
		var pixels = (jQuery(window).width() - 500) / 2; // (screen width - logo width) / 2
		var numberOfShows = Math.floor(pixels / this.picWidth);
		return numberOfShows;
	}
}

