/*

 * jQuery SuperBox! 0.9.0

 * Copyright (c) 2009 Pierre Bertet (pierrebertet.net)

 * Licensed under the MIT (MIT-LICENSE.txt)

 *

 * TODO :

 * - Ajax

 * - Document.load if init is before </body> against IE crash.

 * - Animations

 * - Image / Gallery mode : display a legend

*/

;(function($){

	

	// Local variables

	var $overlay, $wrapper, $container, $superbox, $closeBtn, $loading, $nextprev, $nextBtn, $prevBtn, settings,

	

	// Default settings

	defaultSettings = {

		boxId: "superbox",

		boxClasses: "",

		overlayOpacity: .8,

		boxWidth: "*",

		boxHeight: "*",

		loadTxt: "Loading...",

		closeTxt: "CLOSE",

		prevTxt: "Previous",

		nextTxt: "Next"

	},

	

	galleryGroups = {},

	galleryMode = false,

	hideElts = $([]);

	

	// Init dispatcher

	$.superbox = function(){

		

		// Settings

		settings = $.extend({}, defaultSettings, $.superbox.settings);

		

		// If IE6, select elements to hide

		if ($.browser.msie && $.browser.version < 7){

			hideElts = hideElts.add("select");

		}

		

		// Create base elements

		createElements();

		

		// Dispatch types

		dispatch();

	};

	

	// Dispatch types

	function dispatch(){

		

		// Match all a[rel^=superbox]

		$("a[rel^=superbox]").each(function(){

			

			// Optimisation

			var $this = $(this),

			relAttr = $this.attr("rel"),

			

			// Match type (ex : superbox[gallery#my_id.my_class][my_gallery] > gallery

			type = relAttr.match(/^superbox\[([^#\.\]]+)/)[1],

			

			// Match additionnal classes or IDs (#xxx.yyy.zzz)

			boxCurrentAttrs = relAttr.replace("superbox", "").match(/([#\.][^#\.\]]+)/g) || [],

			

			// Box ID and classes

			newBoxId = settings.boxId,

			newBoxClasses = settings.boxClasses;

			

			// Additionnal rel settings

			this._relSettings = relAttr.replace("superbox["+ type + boxCurrentAttrs.join("") +"]", "");

            

			// Redefine settings

			$.each(boxCurrentAttrs, function(i, val){ // each class or id

				if (val.substr(0,1) == "#"){

					newBoxId = val.substr(1);

				}

				else if (val.substr(0,1) == "."){

					newBoxClasses += " " + val.substr(1);

				}

			});

			

			// Call type method

			if (type.search(/^image|gallery|iframe|content|ajax$/) != -1) {

				$this.superbox(type, {boxId: newBoxId, boxClasses: newBoxClasses});

			}

		});

	};

	

	/*-- Superbox Method --*/

	$.fn.superbox = function(type, curSettings){

		curSettings = $.extend({}, settings, curSettings);

		$.superbox[type](this, curSettings);

	};

	

	/*-- Types --*/

	$.extend($.superbox, {

		

		// Image

		image: function($elt, curSettings, type){

			

			var relSettings = getRelSettings($elt.get(0)),

			dimensions = false;

			

			// Extra settings

			if (relSettings && type == "gallery")

				dimensions = relSettings[1];

			else if (relSettings)

				dimensions = relSettings[0];

			

			// On click event

			$elt.click(function(e){

				e.preventDefault();

				

				prepareBox();

				

				// "Prev / Next" buttons

				if (type == "gallery")

					nextPrev($elt, relSettings[0]);

				

				// Loading anim

				initLoading(function(){

					

					// Dimensions

					var dims = false,

					

					// Image

					$curImg;

					

					if (dimensions) {

						dims = dimensions.split("x");

					}

					

					// Image

					$curImg = $('<img src="'+ $elt.attr("href") +'" title="'+ ($elt.attr("title") || $elt.text()) +'" />');

					

					// On image load

					$curImg.load(function(){

						

						// Resize

						resizeImageBox($curImg, dims);

						

						// Id and Classes

						setBoxAttrs({boxClasses: "image " + curSettings.boxClasses, boxId: curSettings.boxId});

						

						// Show box

						showBox();

						

					}).appendTo($innerbox);

					

				});

				

			});

		},

		

		// Gallery

		gallery: function($elt, curSettings){

			

			// Extra settings

			var extraSettings = getRelSettings($elt.get(0));

			

			// Create group

			if(!galleryGroups[extraSettings[0]]) {

			    galleryGroups[extraSettings[0]] = [];

			}

			

			// Add element to current group

			galleryGroups[extraSettings[0]].push($elt);

			

			$elt.get(0)._superboxGroupKey = (galleryGroups[extraSettings[0]].length - 1);

			

			// Image Box

			$.superbox["image"]($elt, curSettings, "gallery");

		},

		

		// iFrame

		iframe: function($elt, curSettings){

			

			// Extra settings

			var extraSettings = getRelSettings($elt.get(0));

			

			// On click event

			$elt.click(function(e){

				e.preventDefault();

				

				prepareBox();

				

				// Loading anim

				initLoading(function(){

					

					// Dimensions

					var dims = false,

					

					// iFrame

					$iframe;

					

					if (extraSettings) {

						dims = extraSettings[0].split("x");

					}

					

					curSettings = $.extend({}, curSettings, {

						boxWidth: dims[0] || curSettings.boxWidth,

						boxHeight: dims[1] || curSettings.boxHeight

					});

					

					// iFrame

					$iframe = $('<iframe src="'+ $elt.attr("href") +'" name="'+ $elt.attr("href") +'" frameborder="0" scrolling="auto" hspace="0" width="'+ curSettings.boxWidth +'" height="'+ curSettings.boxHeight +'"></iframe>');

					

					// On iFrame load

					$iframe.load(function(){

						

						// Specified dimensions

						$superbox.width( curSettings.boxWidth+"px" );

						$innerbox.height( curSettings.boxHeight+"px" );

						

						// Id and Classes

						setBoxAttrs({boxClasses: "iframe " + curSettings.boxClasses, boxId: curSettings.boxId});

						

						// Show box

						showBox();

						

					}).appendTo($innerbox);

				});

				

			});

		},

		

		// Content

		content: function($elt, curSettings){

			// Extra settings

			var extraSettings = getRelSettings($elt.get(0));

			

			// On click event

			$elt.click(function(e){

				e.preventDefault();

				

				prepareBox();

				

				// Loading anim

				initLoading(function(){

					

					// Dimensions

					var dims = false;

					if (extraSettings)

						dims = extraSettings[0].split("x");

					

					curSettings = $.extend({}, curSettings, {

						boxWidth: dims[0] || curSettings.boxWidth,

						boxHeight: dims[1] || curSettings.boxHeight

					});

					

					if (curSettings.boxWidth  == '*') curSettings.boxWidth  = $($elt.attr('href')).outerWidth();

					if (curSettings.boxHeight == '*') curSettings.boxHeight = $($elt.attr('href')).outerHeight();

					

					// Specified dimensions

					$superbox.width( curSettings.boxWidth+"px" );

					$innerbox.height( curSettings.boxHeight+"px" );

					

					$($elt.attr('href')).clone().appendTo($innerbox);

					

					// Id and Classes

					setBoxAttrs({boxClasses: "content " + curSettings.boxClasses, boxId: curSettings.boxId});

					

					// Show box

					showBox();

				});

				

			});

		},

		

		// Ajax

		ajax: function($elt, curSettings){

			

			// Extra settings

			var extraSettings = getRelSettings($elt.get(0));

			

			// On click event

			$elt.click(function(e){

				e.preventDefault();

				

				prepareBox();

				

				// Loading anim

				initLoading(function(){

					

					// Dimensions

					var dims = false;

					if (extraSettings && extraSettings[3]) {

						dims = extraSettings[3].split("x");

					}

					

					// Extend default dimension settings

					curSettings = $.extend({}, curSettings, {

						boxWidth: dims[0] || curSettings.boxWidth,

						boxHeight: dims[1] || curSettings.boxHeight

					});

					

					// Specified dimensions

					$superbox.width( curSettings.boxWidth+"px" );

					$innerbox.height( curSettings.boxHeight+"px" );

					

					$.get( extraSettings[2], function(data){

						$(data).appendTo($innerbox);

					});

					

					// Id and Classes

					setBoxAttrs({boxClasses: "ajax " + curSettings.boxClasses, boxId: curSettings.boxId});

					

					// Show box

					showBox();

				});

			});

		}

	});

	

	

	// Get extra settings in rel attribute

	function getRelSettings(elt){

		return elt._relSettings.match(/([^\[\]]+)/g);

	};

	

	// Set image box dimensions

	function resizeImageBox($curImg, dims){

		

		// Auto

		$superbox.width($curImg.width() + ($innerbox.css("paddingLeft").slice(0,-2)-0) + ($innerbox.css("paddingRight").slice(0,-2)-0)); // Padding ajouté, pour corriger le problème de définition padding sur $innerbox

		$innerbox.height($curImg.height());

		

		// Specified

		if (dims && dims[0] != "") {

			$superbox.width(dims[0] + "px");

		}

		if (dims && dims[1] != "" && dims[1] > $curImg.height()) {

			$innerbox.height(dims[1] + "px");

		}

	};

	

	// Next / Previous

	function nextPrev($elt, group){

		$nextprev.show();

		

		galleryMode = true;

		

		var nextKey = $elt.get(0)._superboxGroupKey + 1,

		    prevKey = nextKey - 2;

		

		// Next

		if (galleryGroups[group][nextKey]){

			$nextBtn.removeClass("disabled").unbind("click").bind("click", function(){

				galleryGroups[group][nextKey].click();

			});

		}

		else

			$nextBtn.addClass("disabled").unbind("click");

		

		// Prev

		if (galleryGroups[group][prevKey]){

			$prevBtn.removeClass("disabled").unbind("click").bind("click", function(){

				galleryGroups[group][prevKey].click();

			});

		}

		else

			$prevBtn.addClass("disabled").unbind("click");

	};

	

	// Set ID and Class

	function setBoxAttrs(attrs){

		$superbox.attr("id", attrs.boxId).attr("class", attrs.boxClasses);

	};

	

	// Hide Box

	function hideBox(){

		$(document).unbind("keydown");

		$loading.hide();

		$nextprev.hide();

		$wrapper.hide().css({position: "fixed", top: 0});

		$innerbox.empty();

	};

	

	// Hide Box + Overlay

	function hideAll(callback){

		hideBox();

		$overlay.fadeOut(300, function(){

			// Show hidden elements for IE6

			hideElts.show();

		});

		galleryMode = false;

	};

	

	// "Loading..."

	function initLoading(callback){

		

		var loading = function(){

			

			// IE6

			if($.browser.msie && $.browser.version < 7){

				$wrapper.css({position: "absolute", top:"50%"});

			}

			

			// Hide elements for IE6

			hideElts.hide();

			

			$loading.show();

			callback();

		};

		

		if (galleryMode){

			$overlay.css("opacity", settings.overlayOpacity).show();

			loading();

		}

		else {

			$overlay.css("opacity", 0).show().fadeTo(300, settings.overlayOpacity, loading);

		}

	};

	

	// "Prepare" box : Show $superbox with top:-99999px;

	function prepareBox(){

		$wrapper.show();

		$innerbox.empty();

		$superbox.css({position: "absolute", top: "-99999px"});

	};

	

	// Display box

	function showBox(){

		// Stop "Loading..."

		$loading.hide();

		

		// Keys shortcuts

		$(document).unbind("keydown").bind("keydown",function(e){

			// Escape

			if (e.keyCode == 27)

				hideAll();

			// Left/right arrows

			if (e.keyCode == 39 && $nextBtn.is(":visible"))

				$nextBtn.click();

			if (e.keyCode == 37 && $prevBtn.is(":visible"))

				$prevBtn.click();

		});

		

		// Show $superbox

		$superbox.css({position: "relative", top: 0, opacity: 0});

		

		// IE6 and IE7

		if ($.browser.msie && $.browser.version < 8){

			$superbox.css({position: "relative", top:"-50%"});

		// IE6

		if ($.browser.msie && $.browser.version < 7)

			$wrapper.css({position: "absolute", top:"50%"});

		}

		

		// Position absolute if image height > window height

		if ( $(window).height() < $wrapper.height() ){

			$wrapper.css({position: "absolute", top: ($wrapper.offset().top + 10) + "px"});

		}

		

		$superbox.fadeTo(300,1);

		

	};

	

	// Create base elements (overlay, wrapper, box, loading)

	function createElements(){

		if (!$.superbox.elementsReady){

		

			// Overlay (background)

			$overlay = $('<div id="superbox-overlay"></div>').appendTo("body").hide();

			

			// Wrapper

			$wrapper = $('<div id="superbox-wrapper"></div>').appendTo("body").hide();

			

			// Box container

			$container = $('<div id="superbox-container"></div>').appendTo($wrapper);

			

			// Box

			$superbox = $('<div id="superbox"></div>').appendTo($container);

			

			// Inner box

			$innerbox = $('<div id="superbox-innerbox"></div>').appendTo($superbox);

			

			// "Next / Previous"

			$nextprev = $('<p class="nextprev"></p>').appendTo($superbox).hide();

			$prevBtn = $('<a class="prev"><strong><span>'+ settings.prevTxt +'</span></strong></a>').appendTo($nextprev);

			$nextBtn = $('<a class="next"><strong><span>'+ settings.nextTxt +'</span></strong></a>').appendTo($nextprev);

			

			// Add close button

			$closeBtn = $('<p class="close"><a><strong><span>'+ settings.closeTxt +'</span></strong></a></p>').prependTo($superbox).find("a");

			

			// "Loading..."

			$loading = $('<p class="loading">'+ settings.loadTxt +'</p>').appendTo($container).hide();

			

			// Hide on click

			$overlay.add($wrapper).add($closeBtn).click(function(){

				hideAll();

			});

			

			// Remove "hide on click" on superbox

			$superbox.click(function(e){

				e.stopPropagation();

			});

			

			// Dont call this function twice

			$.superbox.elementsReady = true;

		}

	};

	

})(jQuery);