/**
 * Overlay Gallery plugin, version: 1.0.0
 * 
 * Copyright (c) 2009 Tero Piirainen
 * http://flowplayer.org/tools/overlay.html#gallery
 *
 * Dual licensed under MIT and GPL 2+ licenses
 * http://www.opensource.org/licenses
 *
 * Since  : July 2009
 * Date: ${date}
 * Revision: ${revision} 
 */
(function ($)
{

	// TODO: next(), prev(), getIndex(), onChange event

	// version number
	var t = $.tools.overlay;
	t.plugins = t.plugins || {};

	t.plugins.gallery = {
		version: '1.0.0',
		conf: {
			imgId: 'img',
			next: '.next',
			prev: '.prev',
			info: '.info',
			progress: '.progress',
			disabledClass: 'disabled',
			activeClass: 'active',
			opacity: 0.8,
			speed: 'slow',
			template: '<strong>${title}</strong> <span>Image ${index} of ${total}</span>',
			autohide: true,
			preload: true,
			playerId: "player",
			html5PlayerId: "html5player",
			videoAttrName: "video",
			playerWidth: null,
			playerHeight: null,
			api: false
		}
	};

	$.fn.gallery = function (opts)
	{
		var conf = $.extend({}, t.plugins.gallery.conf), api;
		$.extend(conf, opts);

		// common variables for all gallery images
		api = this.overlay();

		var links = this,
			 overlay = api.getOverlay(),
			 next = overlay.find(conf.next),
			 prev = overlay.find(conf.prev),
			 info = overlay.find(conf.info),
			 progress = overlay.find(conf.progress),
			 els = prev.add(next).add(info).css({ opacity: conf.opacity }),
			 close = api.getClosers(),
			 index;

		//{{{ load 

		function load(el)
		{
			conf.playerWidth = conf.playerWidth ? conf.playerWidth : 720;
			conf.playerHeight = conf.playerHeight ? conf.playerHeight : 400;

			overlay
			.css("left", (($(window).width() - overlay.width()) / 2) + "px")
			.css("top", (($(window).height() - overlay.height()) / 2 + $(window).scrollTop()) + "px");

			progress.fadeIn();
			els.hide(); close.hide();

			var url = "/_Library/JavaScript/jquery_tools/image/blank.gif";

			var video = el.attr(conf.videoAttrName);

			var player = overlay.find("#" + conf.playerId);
			var html5player = overlay.find("#" + conf.html5PlayerId);

			if (video && player.length)
			{
				player.empty().show();
			}
			else
			{
				player.empty().hide();
				html5player.attr("src", "/").hide();

				url = el.attr("href");
			}

			// download the image 
			var image = new Image();

			image.onload = function ()
			{
				links = $(links.selector);

				progress.fadeOut();

				// find image inside overlay
				var img = $("#" + conf.imgId, overlay);

				// or append it to the overlay 
				if (!img.length)
				{
					img = $("<img/>").attr("id", conf.imgId).css("visibility", "hidden");
					overlay.prepend(img);
				}

				// make initially invisible to get it's dimensions
				img.attr("src", url).css("visibility", "hidden").width(0).height(0);

				// animate overlay to fit the image dimensions
				var width = image.width;
				var height = image.height;
				var maxWidth = $(document.body).width() - 40;
				var maxHeight = $(document.body).height() - 40;
				if (width > maxWidth || height > maxHeight)
				{
					var dy = maxWidth * image.height / image.width;
					if (dy <= maxHeight)
					{
						width = maxWidth;
						height = dy;
					}
					else
					{
						width = maxHeight * image.width / image.height;
						height = maxHeight;
					}
				}

				if (video && conf.playerId && player.length)
				{
					player.css({ width: "0px", height: "0px" }).parent().css({ display: "block" });

					width = player.outerWidth(true) + conf.playerWidth;
					height = player.outerHeight(true) + conf.playerHeight;
				}

				var left = ($(window).width() - width) / 2;
				var top = ($(window).height() - height) / 2 + $(window).scrollTop();

				// calculate index number
				if (video && conf.playerId && player.length)
					index = links.index(links.filter("[" + conf.videoAttrName + "='" + video + "']"));
				else
					index = links.index(links.filter("[href='" + url + "']"));

				// activate trigger
				links.removeClass(conf.activeClass).eq(index).addClass(conf.activeClass);

				// enable/disable next/prev links
				var cls = conf.disabledClass;
				els.removeClass(cls);

				if (index === 0) { prev.addClass(cls); }
				if (index == links.length - 1) { next.addClass(cls); }


				// set info text & width
				var text = conf.template
					.replace("${title}", el.attr("title") || el.data("title"))
					.replace("${index}", index + 1)
					.replace("${total}", links.length);

				var padd = parseInt(info.css("paddingLeft"), 10) + parseInt(info.css("paddingRight"), 10);
				info.html(text).css({ width: width - padd });
				if (video && conf.playerId && player.length)
				{
					info.css("visibility", "hidden");
				}
				else
				{
					info.css("visibility", "visible");
				}

				overlay.animate({
					width: width, height: height, left: left, top: top
				}, conf.speed, function ()
				{
					if (video && conf.playerId && player.length)
					{
						if (!conf.autohide)
						{
							els.fadeIn(); close.show();
						}

						$("#" + conf.playerId).show().css({ width: conf.playerWidth + "px", height: conf.playerHeight + "px" });
						if (video.charAt(0) == '<')
						{
							var tempVideo = video;
							tempVideo = $(video).find("param[name='movie']").attr("value") + "";
							flowplayer(conf.playerId, { src: tempVideo, wmode: 'opaque' }, { clip: { url: "", scaling: "fit"} });
							$("#" + conf.playerId).find("object").attr("data", tempVideo);
						}
						else
						{
							$("#" + conf.html5PlayerId).attr("src", "/").hide();
							flowplayer(conf.playerId, { src: "/_Library/JavaScript/flowplayer/flowplayer.swf", wmode: 'opaque', onFail: function ()
							{
								$("#" + conf.playerId).hide();
								$("#" + conf.html5PlayerId).show().css({ width: conf.playerWidth + "px", height: conf.playerHeight + "px" }).attr('src', video);
							}
							}, { clip: { url: video, scaling: "fit"} });
						}

					}
					else
					{
						img.width(width);
						img.height(height);

						// gradually show the image
						img.hide().css("visibility", "visible").fadeIn(function ()
						{
							if (!conf.autohide)
							{
								els.fadeIn(); close.show();
							}
						});
					}
				});
			};

			image.onerror = function ()
			{
				overlay.fadeIn().html("Cannot find image " + url);
			};

			image.src = url;

			if (conf.preload)
			{
				if ((video && conf.playerId && player.length) == false)
				{
					links.filter(":eq(" + (index - 1) + "), :eq(" + (index + 1) + ")").each(function ()
					{
						var img = new Image();
						img.src = $(this).attr("href");
					});
				}
			}

		}

		//}}}


		// function to add click handlers to next/prev links	 
		function addClick(el, isNext)
		{

			el.unbind("click").click(function ()
			{
				if (el.hasClass(conf.disabledClass)) { return; }

				// find the triggering link
				var trigger = links.eq(i = index + (isNext ? 1 : -1));

				// if found load it's href
				if (trigger.length) { load(trigger); }

			});
		}

		// assign next/prev click handlers
		addClick(next, true);
		addClick(prev);


		// arrow keys
		var KeydownEvent = function (evt)
		{
			if (!overlay.is(":visible") || evt.altKey || evt.ctrlKey) { return; }

			if (evt.keyCode == 37 || evt.keyCode == 39)
			{
				var btn = evt.keyCode == 37 ? prev : next;
				btn.click();
				return evt.preventDefault();
			}
			return true;
		}
		$(document).unbind("keydown.KeydownEvent").bind("keydown.KeydownEvent", KeydownEvent);

		function showEls()
		{
			if (!overlay.is(":animated"))
			{
				els.show(); close.show();
			}
		}

		// autohide functionality
		if (conf.autohide)
		{
			overlay.hover(showEls, function () { els.fadeOut(); close.hide(); }).mousemove(showEls);
		}

		// load a proper gallery image when overlay trigger is clicked
		var ret;

		this.each(function ()
		{
			var el = $(this), api = $(this).overlay(), ret = api;

			api.onBeforeLoad(function ()
			{
				load(el);
			});

			api.onClose(function ()
			{
				overlay.find("#" + conf.playerId).empty();
				overlay.find("#" + conf.html5PlayerId).attr("src", "/");
				links.removeClass(conf.activeClass);
			});
		});

		return conf.api ? ret : this;

	};

})(jQuery);	
		

