/**
 * @author Simon Hanukaev
 * 
 * To add a lightBox to a link on the page, the anchor tags should look
 * like this:
 * <a class="lightBoxLink" href="{imageUrl}" title="{imageCaption}">...</a>
 * {imageUrl} is the url of the image that will be shown in the lightBox.
 * {imageCaption} is the text that will be shown for each image.
 * 
 * Configurable constants:
 * LIGHT_BOX_LINK_CLASS - the class name of links that should open lightBox
 * AJAX_LOADER_IMAGE - url of AJAX loader, animation gif.
 * 
 * Dependencies
 * jQuery 1.2.6
 */
(function () {
/*global $, console */
/*jslint browser: true */

// Constants
var LIGHT_BOX_LINK_CLASS = "lightBoxLink";
var AJAX_LOADER_IMAGE = "http://bubbleshq.com/images/lightbox/progressBar.gif";

// Private variables
var lightBoxHorizontalPadding;
var lightBoxVerticalPadding;
var progressBarImg = new Image();
progressBarImg.src = AJAX_LOADER_IMAGE;
var userAgent = navigator.userAgent;
var $lightBoxLinks;
var center;
var numOfImages;
var currentLightBoxIndex;

var $progressBar, $lightBoxContent;
var $lightBox, $lightBoxShadow, $img, $lightBoxControls;
var $lightBoxImageCounter, $lightBoxImageDescription;

// ========== Build LightBox jQuery, and append it to body ==========
$(function(){
	// ==================================================
	//	<div id='lightBox'>
	//		<img id='lightBoxProgressBar' src='{progressBarUrl}'/>
	//		<div id='lightBoxContent' class='clearfix'>
	//			<img id='lightBoxImage' alt=''/>
	//			<div id='lightBoxControls'>
	//				<a id='lightBoxPrev' href='#'></a>
	//				<a id='lightBoxNext' href='#'></a>
	//			</div>
	//			<a id='lightBoxClose' href='#'></a>
	//			<span id='lightBoxImageCounter'></span><br/>
	//			<span id='lightBoxImageDescription'></span>
	//		</div>
	//	</div>
	// ==================================================
	$lightBox = $("" +
			"<div id='lightBox'>" +
				"<img id='lightBoxProgressBar' src='"+progressBarImg.src+"'/>" +
				"<div id='lightBoxContent' class='clearfix'>" +
					"<img id='lightBoxImage' alt=''/>" +
					"<div id='lightBoxControls'>" +
						"<a id='lightBoxPrev' href='#'></a>" +
						"<a id='lightBoxNext' href='#'></a>" +
					"</div>" +
					"<a id='lightBoxClose' href='#'></a>" +
					"<span id='lightBoxImageCounter'></span><br/>" +
					"<span id='lightBoxImageDescription'></span>" +
				"</div>" +
			"</div>");
	$progressBar = $("#lightBoxProgressBar",$lightBox);
	$lightBoxContent = $ ("#lightBoxContent",$lightBox);
	$img = $("img",$lightBoxContent);
	$lightBoxControls = $("#lightBoxControls",$lightBoxContent);
	
	// Bind event handlers for next/prev buttons
	$("#lightBoxPrev",$lightBoxControls).bind("click", function() {
		var $prevLightBoxLink = $lightBoxLinks.eq(currentLightBoxIndex > 0 ? currentLightBoxIndex - 1 : numOfImages - 1);
		$lightBoxContent.fadeOut("normal",function() {
			loadImage($prevLightBoxLink.get(0));
		});
		return false;
	});
	$("#lightBoxNext",$lightBoxControls).bind("click", function() {
		var $nextLightBoxLink = $lightBoxLinks.eq(currentLightBoxIndex < numOfImages - 1 ? currentLightBoxIndex + 1 : 0);
		$lightBoxContent.fadeOut("normal",function() {
			loadImage($nextLightBoxLink.get(0));
		});
		return false;
	});
	
	// Bind event handler for close button
	$("#lightBoxClose",$lightBoxContent).bind("click",closeLightBox);

	$lightBoxImageCounter = $("#lightBoxImageCounter",$lightBoxContent);
	$lightBoxImageDescription = $("#lightBoxImageDescription",$lightBoxContent);

	$lightBoxShadow = $("<div id='lightBoxShadow'></div>");
	
	$lightBoxShadow.bind("click",closeLightBox);
	
	// Set styles	
	$lightBox.css({
		display:			"none",
		zIndex:				100
	});
	$lightBoxContent.css("display","none");
	$lightBoxShadow.css({
		position:			"absolute",
		top:				"0px",
		left:				"0px",	
		backgroundColor:	"#000000",
		opacity:			0,
		display:			"none",
		zIndex:				99
	});

	// Append to body
	$("body").append($lightBoxShadow);
	$("body").append($lightBox);
	
	lightBoxHorizontalPadding = parseInt($lightBox.css("padding-left"),10) +
			parseInt($lightBox.css("padding-right"),10);
	lightBoxVerticalPadding = parseInt($lightBox.css("padding-top"),10) +
			parseInt($lightBox.css("padding-bottom"),10);		
	
	// Initizalize lightbox links when DOM loads.
	initLightBox();
});

/**
 * Ligh Box links initialization.
 * This method need to be invoked when all light box links are loaded.
 * <a href="{imgUrl}" title="{imgCaption}">...</a>
 */
window.initLightBox = function() {
	$lightBoxLinks = $("."+LIGHT_BOX_LINK_CLASS);
	numOfImages = $lightBoxLinks.length;
	
	if (numOfImages === 1) {
		$lightBoxControls.css("display","none");
		$lightBoxImageCounter.css("display","none");
	} else {
		$lightBoxControls.css("display","block");
		$lightBoxImageCounter.css("display","inline");
	}
	
	// Bind click event to the lightBoxLink
	$lightBoxLinks.bind("click", function() {
		viewLightBox(this);
		return false;
	});
};

function viewLightBox(lightBoxLink) {
	
	var pageScrollDim = getPageScrollDimensions();
	var pageClientDim = getViewPortDimensions();
	var pageScrollPos = getPageScrollPosition();

	center = {
		left:	pageScrollPos.left + parseInt(pageClientDim.width/2,10),
		top:	pageScrollPos.top + parseInt(pageClientDim.height/2,10)
	};

	var shadowWidth = pageScrollDim.width > pageClientDim.width ? pageScrollDim.width : pageClientDim.width;
	var shadowHeight = pageScrollDim.height > pageClientDim.height ? pageScrollDim.height : pageClientDim.height; 

	var cssObj = {
		width:		shadowWidth+"px",
		height:		shadowHeight+"px",
		display:	"block"
	};
	
	$lightBoxShadow.css(cssObj);
	$lightBoxShadow.animate({opacity:"0.5"},function(){
		$lightBox.css({
			top: 		(center.top - parseInt($lightBox.outerHeight()/2,10)) + "px",
			display:	"block"
		});
		loadImage(lightBoxLink);
	});
}

function loadImage(lightBoxLink) {
	currentLightBoxIndex = $lightBoxLinks.index(lightBoxLink);
	
	$lightBoxImageCounter.text("Image "+(currentLightBoxIndex+1)+" of "+numOfImages);
	$lightBoxImageDescription.text($(lightBoxLink).attr("title"));
	
	// Show ajax loader.
	$progressBar.css("display","block");

	var imgSrc = $(lightBoxLink).attr("href");
	var img = new Image();
	img.onload = function() {
		if ($lightBox.css("display") == "none") {
			return;
		}
		$img.attr("src",img.src);
		$img.css({
			width:			img.width+"px",
			height:			img.height+"px"
		});
		
		$progressBar.css("display","none");
		
		var newWidth = img.width;
		var newHeight = $lightBoxContent.height();
		
		var newMarginLeft = - Math.round((newWidth+lightBoxHorizontalPadding)/2);
		var newTop = center.top - Math.round((newHeight+lightBoxVerticalPadding)/2);
		$lightBox.animate({
			marginLeft:		newMarginLeft+"px",
			top:			newTop+"px",
			width:			newWidth+"px",
			height:			newHeight+"px"
		},500,function() {
			$lightBoxContent.fadeIn("normal");
		});
	};
	img.src = imgSrc;
}

function closeLightBox() {
	$lightBoxContent.css("display","none");
	$lightBox.css("display","none");
	$lightBoxShadow.animate({opacity:0},"normal",function(){
		$lightBoxShadow.css("display","none");
	});
	return false;
}

function getPageScrollDimensions() {
	var offsetWidth = document.body.offsetWidth;
	var offsetHeight = document.body.offsetHeight;
	return {width:offsetWidth, height:offsetHeight};
}

function getViewPortDimensions() {
	isOpera = /Opera/.test(userAgent);
	var viewPortWidth, viewPortHeight;
	if (!isOpera) {
		viewPortWidth = document.documentElement.clientWidth;
		viewPortHeight = document.documentElement.clientHeight;
	}
	else {
		viewPortWidth = document.body.clientWidth;
		viewPortHeight = document.body.clientHeight;
	}
	return {width:viewPortWidth, height:viewPortHeight};
}

function getPageScrollPosition() {
	var scrollLeft = window.pageXOffset || document.documentElement.scrollLeft;
	var scrollTop = window.pageYOffset || document.documentElement.scrollTop;
	return {left:scrollLeft, top:scrollTop};
}

})();