/*
Justified Gallery
Version: 1.0.3
Author: Miro Mannino
Author URI: http://miromannino.it

Copyright 2012 Miro Mannino (miro.mannino@gmail.com)

This file is part of Justified Gallery.

This work is licensed under the Creative Commons Attribution 3.0 Unported License.

To view a copy of this license, visit http://creativecommons.org/licenses/by/3.0/
or send a letter to Creative Commons, 444 Castro Street, Suite 900, Mountain View, California, 94041, USA.
*/

__justifiedGallery_galleryID = 0;

(function($){

   $.fn.justifiedGallery = function(options){

		var settings = $.extend( {
			'justifyLastRow' : false,
			'rowHeight' : 120,
			'fixedHeight' : false,
			'captions' : true,
			'margins' : 1,
			'minWidth' : 120,
			'refreshTime' : 500,
			'label' : true
		}, options);

		function getErrorHtml(message, classOfError){
			return "<div class=\"alert alert-danger " + classOfError + "\">" + message + "</div>";
		}

		return this.each(function(index, cont){
			$(cont).addClass("justifiedGallery");
			var imgLength = $(cont).find("img").length,
				loaded = 0,
				images = [imgLength];

			__justifiedGallery_galleryID++;

			if(imgLength === 0) return;

			$(cont).append("<div class=\"jg-loading\"><div class=\"jg-loading-img\"></div></div>");

			$(cont).find(".thumb").each(function(index, entry){
				var $entry = $(entry),
					img = $entry.find("img"),
					link = $entry.find('a'),
					label = $entry.find('.photo_label').html(),
					content = $entry.find('.photo_details').html();

				images[index] = new Array(5);
				images[index].src = $(img).attr("src");
				images[index].alt = $(img).attr("alt");
				images[index].href = link.attr("href");
				images[index].content = content;
				images[index].label = label;
				images[index].checked = $(label).find('.check_image').is(':checked');

				$(entry).remove(); //remove de image, we have its data

				var img = new Image();

				$(img).load(function() {
					if(images[index].height != settings.rowHeight) {
						images[index].width = Math.ceil(this.width / (this.height / settings.rowHeight));
						if (images[index].width < settings.minWidth) images[index].width = settings.minWidth;
					} else {
						images[index].width = this.width;

					}
					images[index].height = settings.rowHeight;
					if(++loaded == images.length) startProcess(cont, images, settings);
				});

				$(img).error(function() {
					$(cont).prepend(getErrorHtml("The image can't be loaded: \"" + images[index].src +"\"", "jg-usedPrefixImageNotFound"));
					images[index] = null;
					if(++loaded == images.length) startProcess(cont, images, settings);
				});

				$(img).attr('src', images[index].src);
			});
		});

		function startProcess(cont, images, settings){
			//FadeOut the loading image and FadeIn the images after their loading
			$(cont).find(".jg-loading").fadeOut(500, function(){
				$(this).remove(); //remove the loading image
				processesImages($, cont, images, 0, settings);
			});
		}

		function buildImage(image, nw, nh, l, minRowHeight, settings){
			var ris,
				activeClass = '';
			if(image.checked) {
				activeClass = ' jg-image-active';
				$('.justifiedGallery').addClass('justifiedGallery-active');
			}

			ris =  "<div class='jg-image" + activeClass + "' style='left:" + l + "px'>";
			ris += "<div class='jg-image-selected glyphicons-ok glyphicons'></div>";
			if(settings.label&&image.label!==null) {
				ris += image.label;
			}
			ris += "	<a style='height: " + minRowHeight + "px; width: " + nw + "px' href='" + image.href + "' >";
			ris += "		<img alt='" + image.alt + "'' src='" + image.src + "'' style='width: " + nw + "px''>";
			ris += "	</a>";

			if(settings.captions&&image.content!==null) {
				ris += "  <div class=\"jg-image-content\">" + image.content + "</div>";
			}

			ris += "</div>";
			return ris;
		}

		function buildContRow(row, images, extraW, settings){
			var l = 0,
				minRowHeight;

			for(var j = 0; j < row.length; j++){
				row[j].nh = Math.ceil(images[row[j].indx].height *
							((images[row[j].indx].width + extraW) /
							images[row[j].indx].width));

				row[j].nw = images[row[j].indx].width + extraW;

				row[j].l = l;

				if(!settings.fixedHeight){
					if(j === 0) {
						minRowHeight = row[j].nh;
					} else {
						if(minRowHeight > row[j].nh) minRowHeight = row[j].nh;
					}
				}

				l += row[j].nw + settings.margins;
			}

			if(settings.fixedHeight) minRowHeight = settings.rowHeight;

			var rowCont = "";
			for(var j = 0; j < row.length; j++){
				rowCont += buildImage(images[row[j].indx], row[j].nw, row[j].nh, row[j].l, minRowHeight, settings);
			}

			return "<div class=\"jg-row\" style=\"height: " + minRowHeight + "px; margin-bottom:" + settings.margins + "px;\">" + rowCont + "</div>";
		}

		function processesImages($, cont, images, lastRowWidth, settings){
			var row = [];
			var row_i, i;
			var partialRowWidth = 0;
			var extraW;
			var rowWidth = $(cont).width();

			for(i = 0, row_i = 0; i < images.length; i++){
				if(images[i] == null) continue;
				if(partialRowWidth + images[i].width + settings.margins <= rowWidth){
					//we can add the image
					partialRowWidth += images[i].width + settings.margins;
					row[row_i] = new Array(5);
					row[row_i].indx = i;
					row_i++;
				} else {
					//the row is full
					extraW = Math.ceil((rowWidth - partialRowWidth + 1) / row.length);
					$(cont).append(buildContRow(row, images, extraW, settings));

					row = [];
					row[0] = new Array(5);
					row[0].indx = i;
					row_i = 1;
					partialRowWidth = images[i].width + settings.margins;
				}
			}

			//last row----------------------
			//now we have all the images index loaded in the row array

			if(settings.justifyLastRow && row.length >= 4){
				extraW = Math.ceil((rowWidth - partialRowWidth + 1) / row.length);
			}else{
				extraW = 0;
			}
			$(cont).append(buildContRow(row, images, extraW, settings));
			//---------------------------


			//Captions---------------------
			if(settings.captions){
				var jgImage = $(cont).find(".jg-image");
				jgImage.mouseenter(function(sender){
					$(sender.currentTarget).addClass('jg-hover');
				}).mouseleave(function(sender){
					$(sender.currentTarget).removeClass('jg-hover');
				});
			}

			$(cont).find(".jg-resizedImageNotFound").remove();

			//fade in the images that we have changed and need to be reloaded
			$(cont).find(".jg-image img").load(function(){
					$(this).fadeTo(500, 1);
			}).error(function(){
				$(cont).prepend(getErrorHtml("The image can't be loaded: \"" +  $(this).attr("src") +"\"", "jg-resizedImageNotFound"));
			}).each(function(){
					if(this.complete) $(this).load();
			});

			checkWidth($, cont, images, rowWidth, settings);

		}

		function checkWidth($, cont, images, lastRowWidth, settings){
			var id = setInterval(function(){

				if(lastRowWidth != $(cont).width()){
					$(cont).find(".jg-row").remove();
					clearInterval(id);
					processesImages($, cont, images, lastRowWidth, settings);
					return;
				}
			}, settings.refreshTime);
		}

   }

})(jQuery);
