(function($) {
	$.fn.blackbox = function(settings) {
		settings = jQuery.extend({
			idleTime:               2500,
			overlayBgColor: 		'#000',
			overlayOpacity:			0.8,
			keycodeClose:			27,
			keycodePrevious:		37,
			keycodeNext:			39
		}, settings);
		
		var idleTimer;
		
		var jQueryMatchedIndex = 0;
		var jQueryMatchedObj = this;
		var jQueryMatchedObjSize = this.length;
		
		var keys = function(e) {
			switch(e.keyCode) {
				case settings.keycodePrevious:
					_refresh_preview_previous();
					break;
				case settings.keycodeNext:
					_refresh_preview_next();
					break;
				case settings.keycodeClose:
					_finish();
					break;
			}
		}	
		
		function _initialize(index) {
			jQueryMatchedIndex = index;
			_start(this, jQueryMatchedObj);
			_bind_keys();
			return false;
		}

		function _start(objClicked, jQueryMatchedObj) {
			$('embed, object, select').css({ 'visibility' : 'hidden' });
			_set_interface();
			_set_interface_controls();
			_set_idle_timer();			
			_refresh_preview();			
		}
		
		function _show_loader() {
			$('body').append('<div id="blackbox-loader"><em>Loading...</em></div>');
			$('#blackbox-loader:hidden').delay(1500).fadeIn(300);
		}
		
		function _hide_loader() {
			$('#blackbox-loader').stop(true, true).fadeOut(300, function() {
				$(this).remove();
			});
		}
		
		function _set_interface() {
			$('body').append('<div id="blackbox-overlay"></div><div id="blackbox-preview"><div class="blackbox-preview-container"><img src="#" title="" alt="" /><br class="offscreen" /><p id="blackbox-preview-label"><em>Name of photo here</em></p><div id="blackbox-controls"></div></div></div>');
			$('.blackbox-preview-container').mousemove(function() {
				_show_interface_controls();
				_set_idle_timer();
			});
			$('#blackbox-overlay').css({
				backgroundColor:	settings.overlayBgColor,
				opacity:			settings.overlayOpacity
			}).stop(true, true).fadeIn(300);
			$('#blackbox-preview').hide().css('position', 'fixed');
		}
		
		function _set_idle_timer() {
			clearTimeout(idleTimer);
			idleTimer = setTimeout(function() {
				_do_idle_action();
			}, settings.idleTime);
		}
		
		function _clear_idle_timer() {
			clearTimeout(idleTimer);
		}
		
		function _do_idle_action() {
			_hide_interface_controls();
		}
		
		function _show_interface_controls() {
			$('#blackbox-control-prev a:hidden').stop(true, true).show('slide', { direction: 'left' }, 300);
			$('#blackbox-control-next a:hidden').stop(true, true).show('slide', { direction: 'right' }, 300);
		}
		
		function _hide_interface_controls() {
			$('#blackbox-control-prev a').stop(true, true).hide('slide', { direction: 'left' }, 300);
			$('#blackbox-control-next a').stop(true, true).hide('slide', { direction: 'right' }, 300);
		}
		
		function _set_interface_controls() {
			if (jQueryMatchedObjSize > 1) {
				$('#blackbox-controls').append('<div class="blackbox-control" id="blackbox-control-prev"><a href="#" title="&laquo; Previous">&laquo; Previous</a></div>');
				$('#blackbox-controls').append('<div class="blackbox-control" id="blackbox-control-next"><a href="#" title="Next &raquo;">Next &raquo;</a></div>');
				$('#blackbox-control-prev a').click(function() {
					_set_idle_timer();
					_refresh_preview_previous();
					return false;
				});
				$('#blackbox-control-next a').click(function() {
					_set_idle_timer();
					_refresh_preview_next();
					return false;
				});
				$('#blackbox-controls').show();
			}
		}
		
		function _bind_keys() {
			$(document).unbind('keyup', keys).keyup(keys);
		}
		
		function _unbind_keys() {
			$(document).unbind('keyup', keys);
		}
		
		/*
		function _set_interface_buttons() {
			if (jQueryMatchedObjSize > 1) {
				$('#blackbox-nav-prev').show();
				$('#blackbox-nav-next').show();
			}
		}
		*/
		
		function _refresh_preview_previous() {
			if (jQueryMatchedObjSize > 1) {
				jQueryMatchedIndex = (jQueryMatchedObjSize + jQueryMatchedIndex - 1) % jQueryMatchedObjSize;
				$('#blackbox-preview').stop(true, true).fadeOut(500, function() {
					_refresh_preview();
				});
			}
		}
		
		function _refresh_preview_next() {
			if (jQueryMatchedObjSize > 1) {
				jQueryMatchedIndex = (jQueryMatchedObjSize + jQueryMatchedIndex + 1) % jQueryMatchedObjSize;
				$('#blackbox-preview').stop(true, true).fadeOut(500, function() {
					_refresh_preview();
				});
			}
		}
		
		function _refresh_preview() {
			_show_loader();
			var src = $(jQueryMatchedObj).eq(jQueryMatchedIndex).attr('href') + '?' + (new Date()).getTime();
			$('#blackbox-preview-label em').text($('img', $(jQueryMatchedObj).eq(jQueryMatchedIndex)).attr('title'));
			$('#blackbox-preview img').attr('alt', $('img', $(jQueryMatchedObj).eq(jQueryMatchedIndex)).attr('alt'));
			$('#blackbox-preview img').attr('title', $('img', $(jQueryMatchedObj).eq(jQueryMatchedIndex)).attr('title'));
			$('#blackbox-preview img').attr('src', src);
			$('#blackbox-preview img').load(function() {
				var arrPageSizes = ___getPageSize();
				var arrPageScroll = ___getPageScroll();
				var ix = ($('#blackbox-preview').width() / 2) - arrPageScroll[0];
				var iy = ($('#blackbox-preview').height() / 2);
				//var iy = ($('#blackbox-preview').height() / 2) - arrPageScroll[1];
				_hide_loader();
				$('#blackbox-preview-label').width(this.width);
				$('#blackbox-preview').hide().css({
					top: '50%',
					left: '50%',
					marginLeft: -ix,
					marginTop:  -iy
				}).delay(500).stop(true, true).fadeIn(500, function() {
					//$('#blackbox-nav:hidden').css('position', 'fixed').show('slide', { direction: 'up' }, 300);
				});
				
				$('#blackbox-overlay, #blackbox-preview').click(function() {
					_finish();
					return false;
				});
			});
		}

		function _refresh_overlay() {
			var arrPageSizes = ___getPageSize();
			var arrPageScroll = ___getPageScroll();
			var ix = ($('#blackbox-preview').width() / 2) - arrPageScroll[0];
			var iy = ($('#blackbox-preview').height() / 2) - arrPageScroll[1];
			//var iy = ($('#blackbox-preview').height() / 2) - arrPageScroll[1];
			$('#blackbox-overlay').css({
				width:		arrPageSizes[0],
				height:		arrPageSizes[1]
			});
			$('#blackbox-preview').css({
				marginLeft: -ix,
				marginTop:  -iy
			});
		}

		function _finish() {
			_hide_loader();
			_unbind_keys();
			$('#blackbox-preview').stop(true, false).fadeOut(300, function() {
				$('#blackbox-preview').remove();
			});
			$('#blackbox-overlay').delay(500).stop(true, false).fadeOut(300, function() {
				$('#blackbox-overlay').remove();
			});
		}

		function ___getPageSize() {
			pageWidth = $('body').width();
			pageHeight = $('body').height();
			windowWidth = $(window).width();
			windowHeight = $(window).height();
			arrayPageSize = new Array(pageWidth, pageHeight, windowWidth, windowHeight);
			return arrayPageSize;
		};
		
		function ___getPageScroll() {
			xScroll = $(window).scrollLeft();
			yScroll = $(window).scrollTop();
			arrayPageScroll = new Array(xScroll, yScroll);
			return arrayPageScroll;
		};
		
		return this.each(function(index) {
			if (enhanced) {
				$(this).unbind('click').click(function() {
					_initialize(index);
					return false;
				});
			}
		});
	};
})(jQuery);
