/*
 * KFBox 
 * jQuery plugin for displaying images or AJAX content in lightbox style popup. 
 * Supports smart paging with page numbers. Inspired by Thickbox 2.0 by Cody Lindley.   
 *  
 * Copyright (c) 2008 Karel Fučík  
 * Licensed under the MIT License (http://www.opensource.org/licenses/mit-license.php)  
 */

(function($){

$.fn.kfBox = function(options)
{  
	new kfBox(this, options);
	return this;
};

var kfBox = function($elements, options)
{
	this.$elements = $elements;
	this.options = $.extend({
		hashPrefix: 'kfbox-',
		minWidth: 540,
		maxWidth: 600,
		topOffset: 40,
		pageSpan: 3,
		pageLeaders: ' … ',
		historyLoadCallback: null,
		afterShowCallback: null,
		langCode: null,
		langs: {
			cs: { close: "Zavřít", prev: "předchozí", next: "další" },
			en: { close: "Close", prev: "previous", next: "next" },
			de: { close: "Zumachen", prev: "vorige", next: "folgend" },
			es: { close: "Vaer", prev: "previo", next: "siguiente" },
			fr: { close: "Fermer", prev: "précédant", next: "suivant" },
			it: { close: "Chiudere", prev: "previo", next: " veniente" },
			ru: { close: "???????", prev: "??????????????", next: "???????????" }
		},
		htmlTemplate: "<div id='kfb-window'><div id='kfb-paging'><div id='prevnext'><a href='#' id='kfb-prev' rel=''></a><a href='#' id='kfb-next' rel=''></a></div><div id='kfb-page-list'></div></div><div id='kfb-close'><a href='#' id='kfb-close-btn' title=''></a></div><div class='break'></div><h2 id='kfb-caption'></h2> <p id='kfb-desc'></p> <a href='' id='kfb-image-anchor' title=''></a><div id='kfb-content'></div></div>"
	}, options);
	
	this.langCode = this.options.langCode || $('html').attr('xml:lang') || 'cs';
	this.isOpen = false;
	this.oldHash = '';
	
	var that = this;
	this.$elements.bind('click', function(event)
	{
		that.oldHash = window.location.hash.replace('#', '');
		if(typeof that.options.historyLoadCallback == 'function') that.options.historyLoadCallback(that.getHash(this));		
		else that.showByHash(that.getHash(this));
		return false;
	});
};

kfBox.prototype = new function()
{	
	this.getHash = function(element)
	{
		return this.options.hashPrefix + (this.$elements.index(element) + 1);
	};
	
	this.showByHash = function(hash)
	{
		if(hash.indexOf(this.options.hashPrefix) !== 0){
			this.hideBox();
			return false;
		}
		this.activeIndex = parseInt(hash.replace(this.options.hashPrefix, '')) - 1;
		this.$activeLink = $(this.$elements[this.activeIndex]);
		this.renderBox();
		this.initGroup(this.$activeLink);
		return true;
	};
	
	this.renderBox = function()
	{
		if(!this.isOpen)
		{
			this.showOverlay();
			var $htmlTemplate = $(this.options.htmlTemplate);
			$("body").append($htmlTemplate);
			$("#kfb-prev").html(this.options.langs[this.langCode]["prev"]);
			$("#kfb-next").html(this.options.langs[this.langCode]["next"]);
			$("#kfb-close-btn").html(this.options.langs[this.langCode]["close"]);
			$("#kfb-image-anchor").attr('title', this.options.langs[this.langCode]["close"]);			
			$("#kfb-close-btn").bind('click', {kfBox: this} ,this.closeBox);
			this.positionBox(this.options.minWidth);
			this.isOpen = true;			
		}
	};
	
	this.closeBox = function(event)
	{
		that = event.data.kfBox;
		if(that.isOpen)
		{
			if(typeof that.options.historyLoadCallback == 'function') that.options.historyLoadCallback(that.oldHash);		
			return that.hideBox();
		}
	};
	
	this.hideBox = function()
	{
		$('#kfb-window, #kfb-overlay, #kfb-iframe').remove();		
		$(document).unbind('keyup');
		this.isOpen = false;
		return false;
	};
		
	this.initGroup = function()
	{
		var that = this;
		var title = this.$activeLink.attr('title');
			 
		/* Generate paging... */		
		var pagesCount = this.$elements.size();
		var htmlPages = '';
		var pageSpan = this.options.pageSpan;

		var startSpan = this.activeIndex - pageSpan;
		var endSpan = this.activeIndex + pageSpan + 1;		
		
		if(startSpan <= 0)
		{
			startSpan = 0; 
			endSpan = 2 * pageSpan + 2;
			if(endSpan > pagesCount) endSpan = pagesCount - 1;
		}
		if(endSpan >= pagesCount - 1)
		{
			startSpan = pagesCount - 2 - 2 * pageSpan;
			if(startSpan < 0) startSpan = 0;
			endSpan = pagesCount - 1;		
		}
		
		var factoryPageLink = function(i)
		{
			var active = (i == that.activeIndex) ? ' class="active" ' : '';			
			return ' <a href="' + this.href + '"'+ active +'>' + (i + 1) + '</a> ';
		};
		this.$elements.slice(startSpan, endSpan).each(function(i)
		{
			htmlPages += factoryPageLink.call(this, i + startSpan);
		}).end();
		
		if(startSpan > 1) htmlPages = this.options.pageLeaders + htmlPages;
		if(startSpan > 0) this.$elements.eq(0).each(function(i){ htmlPages = factoryPageLink.call(this, 0) + htmlPages; }).end();
		if(endSpan <= pagesCount - 2) htmlPages += this.options.pageLeaders;
		if(endSpan <= pagesCount - 1) this.$elements.eq(pagesCount - 1).each(function(i){ htmlPages += factoryPageLink.call(this, pagesCount - 1); }).end();
		
		$("#kfb-page-list").empty().append(htmlPages); 		
		$("#kfb-prev").unbind('click').bind('click', function(){ that.$elements.eq(that.activeIndex - 1).trigger('click').end(); return false; });
		$("#kfb-next").unbind('click').bind('click', function(){ that.$elements.eq(that.activeIndex + 1).trigger('click').end(); return false; });
		$("#kfb-prev, #kfb-next, #kfb-page-list").removeClass('hidden');	
		if(this.activeIndex == 0) $("#kfb-prev").addClass('hidden');
		if(this.activeIndex == pagesCount - 1) $("#kfb-next").addClass('hidden');
		if(pagesCount <= 1) $("#kfb-prev, #kfb-next, #kfb-page-list").addClass('hidden');		
		$("#kfb-page-list a")
			.bind('click', function()
				{
					var hash = that.options.hashPrefix + $(this).text();	
					if(typeof that.options.historyLoadCallback == 'function') that.options.historyLoadCallback(hash);		
					else that.showByHash(hash);
					return false;
				});
				
		$(document).unbind('keyup').bind('keyup', function(e)
		{ 
			switch(e.keyCode)
			{
				case 27:
					$("#kfb-close-btn").trigger('click'); 
					break;
				case 37:
					$("#kfb-prev:visible").trigger('click'); 
					break;
				case 39:
					$("#kfb-next:visible").trigger('click');
					break;
			}
		});
		
		this.preloadContent(this.$activeLink.attr('href'));
	};
	
	this.preloadContent = function(href)
	{	
		var regexp = /\.jpg|\.png|\.gif$/;
		if(href.toLowerCase().search(regexp) !== -1) this.preloadImage(href);
		else this.preloadHtml(href);
	};
			
	this.preloadImage = function(href)
	{
		var that = this;
		$('#kfb-caption, #kfb-desc, #kfb-image-anchor').removeClass('hidden');
		$("#kfb-content").addClass('hidden');
		
		var $imageAnchor = $('#kfb-image-anchor');
		$imageAnchor
			.height($imageAnchor[0].offsetHeight + "px")
			.find('img').remove().end();

		$('#kfb-content').empty();
		var imgPreloader = $(document.createElement('img'))
			.bind('load', function(e)
				{		
					this.onload = null;
					
					var imageWidth = this.width;
					var imageHeight = this.height;
					
					var $img = $('img', that.$activeLink);		
					
					var caption = $img.attr('alt') || that.$activeLink.attr('title'); 
					var desc = $img.attr('title');
					var longdesc = $img.attr('longdesc');
					
					var enhdesc = [];					
					if(desc) enhdesc.push(desc);
					if(longdesc) enhdesc.push('<a href="' + longdesc + '">' + longdesc + '</a>');
					enhdesc = enhdesc.join(', ');  
					
					if(caption)	$("#kfb-caption").removeClass("hidden").html(caption);
					else $("#kfb-caption").addClass("hidden").empty();
					
					if(enhdesc) $("#kfb-desc").removeClass("hidden").html(enhdesc);
					else $("#kfb-desc").addClass("hidden").empty();				
					
					$('#kfb-image-anchor').removeClass('hidden');
					
					var boxWidth = imageWidth;
					if(boxWidth < that.options.minWidth) boxWidth = that.options.minWidth;
			
					that.positionBox(boxWidth);
					
					this.alt = caption;
					if(desc) this.title = desc;
					$('#kfb-image-anchor').height("auto").empty().append(this).bind('click', function() { that.hideBox(); return false; } );
			
					$("#kfb-window").css({display:"block"});
					
					if(typeof that.options.afterShowCallback == 'function') that.options.afterShowCallback(that.$activeLink[0]);
				})
			.attr('src', href);
	};

	this.preloadHtml = function(href)
	{
		var that = this;
		$("#kfb-content").removeClass('hidden').addClass('loader');
		$('#kfb-caption, #kfb-desc, #kfb-image-anchor').addClass('hidden');			
		
		var $imageAnchor = $('#kfb-image-anchor').find('img').remove();
		boxWidth = that.options.maxWidth; 
		$("#kfb-content").load(href, null, function()
		{			
			$("#kfb-content").removeClass('loader');
			if(typeof that.options.afterShowCallback == 'function') that.options.afterShowCallback(that.$activeLink[0]);			
		});
	};

	this.positionBox = function(boxWidth)
	{
		var scrollTop = $(window).scrollTop();
		var windowWidth = boxWidth + parseInt($('#kfb-image-anchor').css('padding-left')) * 2;
		$("#kfb-window").css({marginLeft: '-' + parseInt(windowWidth / 2) + 'px', width: windowWidth + 'px', top: (scrollTop + this.options.topOffset) + 'px'});			
	};
		
	this.showOverlay = function()
	{
		if($("#kfb-iframe").size() == 0)
		{
			$("body").append("<iframe id='kfb-iframe'></iframe><div id='kfb-overlay'></div>");
			$("#kfb-overlay").bind('click', {kfBox: this}, this.closeBox);
		  	var documentHeight = $(document).height();
		  	var windowHeight = $(window).height();
		  	var maxHeight = documentHeight > windowHeight ? documentHeight : windowHeight;
			$("#kfb-overlay, #kfb-iframe").css("height", maxHeight);
		}
	};
};

$.kfBox = kfBox;

})(jQuery)
