/*
* lightbox
* inspired-by: Buck Wilson's lightbox_me
*/

(function($) {

	var methods = 
	{
		"reposition": function()
		{
			var 
				$self = $(this),
				data	= $self.data('lightbox');

			if(data && data.options)
			{
				$self.css({zIndex: (data.options.zIndex + 3) });

				if(data.options.centered.left)
					// reset CSS so width is re-calculated for margin-left CSS
					$self.css({position: 'fixed', left: '50%', marginLeft: ($self.outerWidth() / 2) * -1});
				
				if (data.options.centered.top)
					$self.css({ position: 'fixed', top: '50%', marginTop: ($self.outerHeight() / 2) * -1});

				$self.show();
			}
		},

		"close": function()
		{
			var 
				$self = $(this),
				data	= $self.data('lightbox');

			if(data && data.options)
			{
				var finish = function()
				{
					if(data.options.close.destroy)
						$self.remove();
					else
						$self.hide().appendTo(data.parent);

					data.overlay.hide();
				};

				if(data.options.animate.close)
					$self.animate(data.options.animate.close, {complete:finish});
				else
					finish();

				// clean up events.
				$self.undelegate(data.options.close.selector, "click");
				$(window).unbind('scroll.lightbox').unbind("keypress.lightbox").unbind("resize.lightbox");
				
				$self.trigger("close.lightbox");
			}
		},

		"remove": function()
		{
			var 
				$self = $(this),
				data	= $self.data('lightbox');

			if(data && data.options)
			{
				$self.unbind("close.lightbox").unbind("open.lightbox");
			}
		}
	};

	var create = function(settings) 
	{
		var 
			options	= $.extend(true, {}, $.fn.lightbox.defaults, settings),
	      $overlay = $(),
	      $self 	= $(this);

		// close out any previous lightbox created on this object
		if($self.data("lightbox"))
			$self.lightbox("remove");

		if(options.overlay.show) 
		{
			//check if there's an existing overlay, if so, make subequent ones clear
			$overlay = $("div." + options["class"].overlay + ":visible");

			if($overlay.length <= 0)
				$overlay = $('<div>').addClass(options["class"].overlay);
		}

		$self.data("lightbox", {options:options, overlay:$overlay, parent:$self.parent()});
		$('body').append($self.hide()).append($overlay);
	
		if(options.overlay.show) 
		{
			setOverlayHeight(); // pulled this into a function because it is called on window resize.
			$overlay.css({ position: 'absolute', width: '100%', top: 0, left: 0, right: 0, bottom: 0, zIndex: (options.zIndex + 2), display: 'none' });
		}
	
		if(options.overlay.show) 
		{
			$overlay.fadeTo(options.overlay.speed, $overlay.css("opacity"), function() 
			{
				if(options.animate.open)
				{
					setOverlayHeight(); 
				 	setSelfPosition();

					$self.show().animate(options.animate.open, {complete: function()
				   {
						load();
				   }});
				}
				else
				{
					setOverlayHeight(); 
				 	setSelfPosition();
					load();
				}
			});
		}
		else
		{
			setSelfPosition();
	
			if(options.animate.open)
	 			$self.show().animate(options.animate.open, {complete: load});
	 		else
				load();
		}
	
		$(window).bind('resize.lightbox', setOverlayHeight).bind('resize.lightbox', setSelfPosition);
		$(window).bind('scroll.lightbox', setSelfPosition).bind('keyup.lightbox', observeKeyPress);

	 	if(options.close.click)
		{
	   	$overlay.click(function(e) { close(); e.preventDefault; });
		}
	 	
		if(options.close.selector)
			$self.delegate(options.close.selector, "click", function(e) { close(); e.preventDefault(); });
	
		function observeKeyPress(e) 
		{
			if((e.keyCode == 27 || (e.DOM_VK_ESCAPE == 27 && e.which===0)) && options.close.esc)
				close();
		}

		function setSelfPosition()
		{
			$self.lightbox("reposition");
		}

		function close()
		{
			$self.lightbox("close");
		}

		function load()
		{
			$self.trigger("open.lightbox");
		}
	
		function setOverlayHeight() 
		{
			if($(window).height() < $(document).height())
	      	$overlay.css({height: $(document).height() + 'px'});
			else
				$overlay.css({height: '100%'});
		}
	};

	$.fn.lightbox = function(method)
	{
		if(methods[method])
		{
			return this.each(function() { methods[method].apply(this, Array.prototype.slice.call(arguments, 1)); });
		}
		else if(typeof method === 'object' || !method)
		{
			var options = arguments;
			return this.each(function() { create.apply(this, options); });
		}
	};

	$.fn.lightbox.defaults = 
	{
		// animation
		animate:		{open:null, close:null},
		overlay: 	{speed:250, show:true},
		
		// close
		close: {selector: false, click:true, esc:true, destroy:false},
		
		// style
		"class": {overlay:"lightbox", modal:"lightbox"},
		zIndex: 9999,
		centered: {top:false, left:false}
	};
})(jQuery);

