(function($)
{
	if ( !$.browser.safari && typeof window.console !== 'undefined' && typeof window.console.log === 'function' )
	{
		$.log = window.console.log;
	}
	else
  {	// Don't use anything
  	$.log = function ( ) { };
  }
  $.LightboxClass = function ()
  {
    this.construct();
  }
  $.extend($.LightboxClass.prototype,
  {
  	constructed:		false,
  	
  	src:				null,		// the source location of our js file
  	baseurl:			null,
  	
  	files: {
  		js: {
  			lightbox:	'/script/jquery.lightbox.js',
  			colorBlend:	'/script/jquery.color.js'
  		},
  		css: {
  			lightbox:	'/style/jquery.lightbox.css'
  		},
  		images: {
  			prev:		'/images/lightbox/prev.gif',
  			next:		'/images/lightbox/next.gif',
  			blank:		'/images/lightbox/blank.gif',
  			loading:	'/images/lightbox/loading.gif'
  		}
  	},
  	
  	text: {
  		// For translating
  		image:		'Image',
  		of:			'of',
  		close:		'Sluiten X',
  		closeInfo:	'You can also click anywhere outside the image to close.',
  		download:	'Direct link to download the image.',
  		help: {
  			close:		'',
  			interact:	''
  		},
  		about: {
  			text: 	'jQuery Lightbox Plugin (balupton edition)',
  			title:	'Licenced under the GNU Affero General Public License.',
  			link:	'http://jquery.com/plugins/project/jquerylightbox_bal'
  		}
  	},
  	
  	keys: {
  		close:	'c',
  		prev:	'p',
  		next:	'n'
  	},
  	
  	handlers: {
  		// For custom actions
  		show:	null
  	},
  	
  	opacity:		0.5,
  	padding:		null,		// if null - autodetect
  	
  	speed:			200,		// Duration of effect, milliseconds
  	
  	rel:			'lightbox',	// What to look for in the rels
  	
  	auto_relify:	true,		// should we automaticly do the rels?
  	
  	auto_scroll:	'follow',	// should the lightbox scroll with the page? follow, disabled, ignore
  	auto_resize:	true,		// true or false
  	
  	ie6:			null,		// are we ie6?
  	ie6_support:	true,		// have ie6 support
  	
  	colorBlend:		null,		// null - auto-detect, true - force, false - no
  	
  	download_link:	true,		// Display the download link
  	
  	show_linkback:		true,	// true, false
  	show_info:			'auto',	// auto - automaticly handle, true - force
  	show_extended_info:	'auto',	// auto - automaticly handle, true - force	
  	
  	// names of the options that can be modified
  	options:	['auto_scroll', 'auto_resize', 'download_link', 'show_info', 'show_extended_info', 'ie6_support', 'colorBlend', 'baseurl', 'files', 'text', 'show_linkback', 'keys', 'opacity', 'padding', 'speed', 'rel', 'auto_relify'],
    
    images: {
      list: [],
      image: false,

      // functions
      prev: function (image)
      {
  			// Get previous from current?
  			if ( typeof image === 'undefined' )
  			{
          image = this.active();
  				if ( !image ) { return image; }
  			}
  			
  			// Is there a previous?
  			if ( this.first(image) )
  			{
          return false;
        }
  			
  			// Get the previous
  			return this.get(image.index-1);
  		},
  		
  		next: function ( image )
  		{
        // Get next image
  			
  			// Get next from current?
  			if ( typeof image === 'undefined' )
  			{
          image = this.active();
  				if ( !image )
          {
            return image;
          }
  			}
  			
  			// Is there a next?
  			if ( this.last(image) )
  			{
          //return false;
  			  return this.get(0);
        }
  			
  			// Get the next
  			return this.get(image.index+1);
  		},
  		
  		first: function ( image )
  		{
  			// Get the first image?
  			if ( typeof image === 'undefined' )
  			{
          return this.get(0);
        }
  			
  			// Are we the first?
  			return image.index === 0;
  		},
  		
  		last: function ( image )
  		{
  			// Get the last image?
  			if ( typeof image === 'undefined' )
  			{
          return this.get(this.size()-1);
        }
  			
  			// Are we the last?
  			return image.index === this.size()-1;
  		},
  	
  		single: function ( )
  		{
        // Are we only one
  			return this.size() === 1;
  		},
  		
  		size: function ( )
  		{
        // How many images do we have
  			return this.list.length;
  		},
  		
  		empty: function ( )
  		{
        // Are we empty
  			return this.size() === 0;
  		},
  		
  		clear: function ( )
  		{
        // Clear image arrray
  			this.list = [];
  			this.image = false;
  		},
  	
  		active: function ( image )
  		{
        // Set or get the active image
  			// Use false to reset
  			
  			// Get the active image?
  			if ( typeof image === 'undefined' )
  			{
          return this.image;
        }
  			
  			// Set the ative image
  			if ( image !== false )
  			{
          // Make sure image exists
  				image = this.get(image);
  				if ( !image )
  				{
            // Error
  					return image;
  				}
  			}
  			
  			// Set the active image
  			this.image = image;
  			return true;
  		},
  	
  		add: function ( obj )
  		{
  			// Do we need to recurse?
  			if ( obj[0] )
  			{	// We have a lot of images
  				for ( var i = 0; i < obj.length; i++ )
  				{
            this.add(obj[i]);
          }
  				return true;
  			}
  			
  			// Default image
  			
  			// Try and create a image
  			var image = this.create(obj);
  			if ( !image )
        {
          return image;
        }
  			
  			// Set image index
  			image.index = this.size();
  			
  			// Push image
  			this.list.push(image);
  			
  			// Success
  			return true;
  		},
  		
  		create: function ( obj )
  		{
        // Create image
  			
  			// Define
  			var image =
        { // default
  				src:	'',
  				title:	'Untitled',
  				description:	'',
  				name:	'',
  				index:	-1,
  				color:	null,
  				width:	null,
  				height:	null,
  				image:	true
  			};
  			
  			// Create
  			if ( obj.image )
  			{
          // Already a image, so copy over values
  				image.src = obj.src || image.src;
  				image.title = obj.title || image.title;
  				image.description = obj.description || image.description;
  				image.name = obj.name || image.name;
  				image.color = obj.color || image.color;
  				image.width = obj.width || image.width;
  				image.height = obj.height || image.height;
  				image.index = obj.index || image.index;
  			}
  			else if ( obj.tagName )
  			{
          // We are an element
  				obj = $(obj);
  				if ( obj.attr('src') || obj.attr('href') )
  				{
  					image.src = obj.attr('src') || obj.attr('href');
  					image.title = obj.attr('title') || obj.attr('alt') || image.title;
  					image.name = obj.attr('name') || '';
  					image.color = obj.css('backgroundColor');
  					// Extract description from title
  					var s = image.title.indexOf(': ');
  					if ( s > 0 )
  					{
              // Description exists
  						image.description = image.title.substring(s+2) || image.description;
  						image.title = image.title.substring(0,s) || image.title;
  					}
  				}
  				else
  				{
            // Unsupported element
  					image = false;
  				}
  			}
  			else
  			{
          // Unknown
  				image = false;
  			}
  			
  			if ( !image )
  			{
          // Error
  				$.log('ERROR', 'We dont know what we have:', obj);
  				return false;
  			}
  			
  			// Success
  			return image;
  		},
  		
  		get: function ( image )
  		{
        // Get the active, or specified image
  			
  			// Establish image
  			if ( typeof image === 'undefined' || image === null )
  			{
          // Get the active image
  				return this.active();
  			}
  			else if ( typeof image === 'number' )
  			{
          // We have a index
  				// Get image
  				image = this.list[image] || false;
  			}
  			else
  			{
          // Create
  				image = this.create(image);
  				if ( !image )
          {
            return false;
          }
  				
  				// Find
  				var f = false;
  				for ( var i = 0; i < this.size(); i++ )
  				{
  					var c = this.list[i];
  					if ( c.src === image.src && c.title === image.title && c.description === image.description )
  					{
              f = c;
            }
  				}
  				
  				// Found?
  				image = f;
  			}
  			
  			// Determine image
  			if ( !image )
  			{
          // Image doesn't exist
  				$.log('ERROR', 'The desired image doesn\'t exist: ', image, this.list);
  				return false;
  			}
  			
  			// Return image
  			return image;
  		},
  		
  		debug: function ( )
  		{
  			return $.Lightbox.debug(arguments);
  		}
  		
  	},
  	// -----------------
  	// Functions
  	
  	construct: function ( options )
  	{
      // Construct our Lightbox
  		
  		// -------------------
  		// Prepare
  		
  		// Initial construct
  		var initial = typeof this.constructed === 'undefined' || this.constructed === false;
  		this.constructed = true;
  		
  		// Perform domReady
  		var domReady = initial;
  		
  		// Prepare options
  		options = $.extend({}, options);
  		
  		// -------------------
  		// Handle files
  		
  		// Add baseurl
  		if ( initial && (typeof options.files === 'undefined') )
  		{
        // Load the files like default
  		
  			// Get the src of the first script tag that includes our js file (with or without an appendix)
  			this.src = $('script[src*='+this.files.js.lightbox+']:first').attr('src');
  			
  			// Make sure we found ourselves
  			if ( !this.src )
  			{
          // We didn't
  				// $.log('WARNING', 'Lightbox was not able to find it\'s javascript script tag necessary for auto-inclusion.');
  				// We don't work with files anymore, so don't care for domReady
  				domReady = false;
  			}
  			else
  			{
          // We found ourself
  			
  				// The baseurl is the src up until the start of our js file
  				this.baseurl = this.src.substring(0, this.src.indexOf(this.files.js.lightbox));
  				
  				// Apply baseurl to files
  				var me = this;
  				$.each(this.files, function(group, val){
  					$.each(this, function(file, val){
  						me.files[group][file] = me.baseurl+val;
  					});
  				});
  				delete me;
  				
  			}
  			
  		}
  		else if ( typeof options.files === 'object' )
  		{
        // We have custom files
  			var me = this;
  			$.each(options.files, function(group, val){
  				$.each(this, function(file, val){
  					this[file] = me.baseurl+val;
  				});
  			});
  			delete me;
  		}
  		else
  		{
        // Don't have any files, so no need to perform domReady
  			domReady = false;
  		}
  		
  		// -------------------
  		// Apply options
  		
  		for ( i in this.options )
  		{
        // Cycle through the options
  			var name = this.options[i];
  			if ( (typeof options[name] === 'object') && (typeof this[name] === 'object') )
  			{
          // We have a group like text or files
  				this[name] = $.extend(this[name], options[name]);
  			}
  			else if ( typeof options[name] !== 'undefined' )
  			{
          // We have that option, so apply it
  				this[name] = options[name];
  			}
  		}
  		
  		// -------------------
  		// Figure out what to do
  		
  		// Handle IE6
  		if ( initial && navigator.userAgent.indexOf('MSIE 6') >= 0 )
  		{
        // Is IE6
  			this.ie6 = true;
  		}
  		else
  		{
        // We are not IE6
  			this.ie6 = false;
  		}
  		
  		// -------------------
  		// Handle our DOM
  		
  		if (
        domReady
        || typeof options.download_link !== 'undefined'
        ||  typeof options.colorBlend !== 'undefined'
        || typeof options.files === 'object'
        || typeof options.text === 'object'
        || typeof options.show_linkback !== 'undefined'
        || typeof options.scroll_with !== 'undefined'
      )
  		{
        // We have reason to handle the dom
  			$(function()
        {
  				// DOM is ready, so fire our DOM handler
  				$.Lightbox.domReady();
  			});
  		}
  		
  		// -------------------
  		// Finish Up
  		
  		// All good
  		return true;
  	},
  	
  	domReady: function ( )
  	{
  		// -------------------
  		// Include resources
  		
  		// Grab resources
  		var bodyEl = document.getElementsByTagName($.browser.safari ? 'head' : 'body')[0];
  		var stylesheets = this.files.css;
  		var scripts = this.files.js;
  		
  		
  		// colorBlend
  		if ( this.colorBlend === true && typeof $.colorBlend === 'undefined' )
  		{
        // Force colorBlend
  			this.colorBlend = true;
  			// Leave file in place to be loaded
  		}
  		else
  		{
        // We either have colorBlend or we don't
  			this.colorBlend = typeof $.colorBlend !== 'undefined';
  			// Remove colorBlend file
  			delete scripts.colorBlend;
  		}
  		
  		// Include stylesheets
  		for ( stylesheet in stylesheets )
  		{
  			var linkEl = document.createElement('link');
  			linkEl.type = 'text/css';
  			linkEl.rel = 'stylesheet';
  			linkEl.media = 'screen';
  			linkEl.href = stylesheets[stylesheet];
  			linkEl.id = 'lightbox-stylesheet-'+stylesheet.replace(/[^a-zA-Z0-9]/g, '');
  			$('#'+linkEl.id).remove();
  			bodyEl.appendChild(linkEl);
  		}
  		
  		// Include javascripts
  		for ( script in scripts )
  		{
  			var scriptEl = document.createElement('script');
  			scriptEl.type = 'text/javascript';
  			scriptEl.src = scripts[script];
  			scriptEl.id = 'lightbox-script-'+script.replace(/[^a-zA-Z0-9]/g, '');
  			$('#'+scriptEl.id).remove();
  			bodyEl.appendChild(scriptEl);
  		}
  		
  		// Cleanup
  		delete scripts;
  		delete stylesheets;
  		delete bodyEl;
  		
  		// -------------------
  		// Append display
  		
  		// Append markup
  		$('#lightbox,#lightbox-overlay').remove();
  		$('body').append(
    ' <div id="lightbox-overlay"></div>'
  + ' <div id="lightbox">'
  + '   <div id="lightbox-imageBox">'
  + '     <div id="lightbox-imageContainer">'
  + '       <img id="lightbox-image" />'
  + '       <div id="lightbox-loading"><a href="#" id="lightbox-loading-link"><img src="' + this.files.images.loading + '" /></a></div>'
  + '     </div>'
  + '     <div id="lightbox-infoBox">'
  + '       <div id="lightbox-infoContainer">'
  + '         <div id="lightbox-infoHeader">'
  + '           <span id="lightbox-caption"'
  + '             ><span id="lightbox-caption-title"></span'
  + '             ><span id="lightbox-caption-seperator"></span'
  + '             ><span id="lightbox-caption-description"></span'
  + '           ></span>'
  + '         </div>'
  + '         <div id="lightbox-infoFooter">'
  + '           <span id="lightbox-currentNumber"></span'
  + '           ><span id="lightbox-close"'
  + '           ><a href="#" id="lightbox-close-button" title="' + this.text.closeInfo + '">' + this.text.close + '</a'
  + '           ></span'
  + '           <span id="lightbox-nav"'
  + '             ><a href="#" id="lightbox-nav-btnPrev"></a><a href="#" id="lightbox-nav-btnNext"></a'
  + '           ></span>'
  + '         </div>'
  + '         <div id="lightbox-infoContainer-clear"></div>'
  + '       </div>'
  + '     </div>'
  + '   </div>'
  + ' </div>'
      );
  		
  		// Update Boxes - for some crazy reason this has to be before the hide in safari and konqueror
  		this.resizeBoxes();
  		this.repositionBoxes();
  		
  		// Hide
  		$('#lightbox,#lightbox-overlay,#lightbox-overlay-text-interact').hide();
  		
  		// -------------------
  		// Browser specifics
  		
  		// Handle IE6
  		if ( this.ie6 && this.ie6_support )
  		{
        // Support IE6
  			// IE6 does not support fixed positioning so absolute it
  			// ^ This is okay as we disable scrolling
  			$('#lightbox-overlay').css({
  				position:	'absolute',
  				top:		'0px',
  				left:		'0px'
  			});
  		}
  		
  		// -------------------
  		// Preload Images
  		
  		// Cycle and preload
  		$.each(this.files.images, function()
  		{
        // Proload the image
  			var preloader = new Image();
  			preloader.onload = function() {
  				preloader.onload = null;
  				preloader = null;
  			};
        preloader.src = this;
  		});
  		
  		// -------------------
  		// Apply events
  		
  		// If the window resizes, act appropriatly
  		$(window).unbind().resize(function ()
  		{
        // The window has been resized
  			$.Lightbox.resizeBoxes('resized');
  		});
  		
  		// If the window scrolls, act appropriatly
  		if ( this.scroll === 'follow' )
  		{
        // We want to
  			$(window).scroll(function ()
  			{	// The window has scrolled
  				$.Lightbox.repositionBoxes();
  			});
  		}
  		
  		// Prev
  		$('#lightbox-nav-btnPrev').unbind().click(function() {
  			$.Lightbox.showImage($.Lightbox.images.prev());
  			return false;
  		});
  				
  		// Next
  		$('#lightbox-nav-btnNext').unbind().click(function() {
  			$.Lightbox.showImage($.Lightbox.images.next());
  			return false;
  		});
  		
  		// Assign close clicks
  		$('#lightbox-overlay, #lightbox, #lightbox-loading-link, #lightbox-btnClose').unbind().click(function() {
  			$.Lightbox.finish();
  			return false;	
  		});
  		
  		// -------------------
  		// Finish Up
  		
  		// Relify
  		if ( this.auto_relify )
  		{	// We want to relify, no the user
  			this.relify();
  		}
  		
  		// All good
  		return true;
  	},
  	
  	relify: function ( )
  	{	// Create event
  	
  		//
  		var groups = {};
  		var groups_n = 0;
  		var orig_rel = this.rel;
  		// Create the groups
  		$.each($('[@rel*='+orig_rel+']'), function(index, obj){
  			// Get the group
  			var rel = $(obj).attr('rel');
  			// Are we really a group
  			if ( rel === orig_rel )
  			{	// We aren't
  				rel = groups_n; // we are individual
  			}
  			// Does the group exist
  			if ( typeof groups[rel] === 'undefined' )
  			{	// Make the group
  				groups[rel] = [];
  				groups_n++;
  			}
  			// Append the image
  			groups[rel].push(obj);
  		});
  		// Lightbox groups
  		$.each(groups, function(index, group){
  			$(group).lightbox();
  		});
  		// Done
  		return true;
  	},
  	
  	init: function ( image, images )
  	{	// Init a batch of lightboxes
  		
  		// Establish images
  		if ( typeof images === 'undefined' )
  		{
  			images = image;
  			image = 0;
  		}
  		
  		// Clear
  		this.images.clear();
  		
  		// Add images
  		if ( !this.images.add(images) )
  		{	return false;	}
  		
  		// Do we need to bother
  		if ( this.images.empty() )
  		{	// No images
  			$.log('WARNING', 'Lightbox started, but no images: ', image, images);
  			return false;
  		}
  		
  		// Set active
  		if ( !this.images.active(image) )
  		{	return false;	}
  		
  		// Done
  		return true;
  	},
  	
  	start: function ( )
  	{	// Display the lightbox
  			
  		// We are alive
  		this.visible = true;
  		
  		// Adjust scrolling
  		if ( this.scroll === 'disable' )
  		{	// 
  			$(document.body).css('overflow', 'hidden');
  		}
  		
  		// Fix attention seekers
  		$('embed, object, select').css('visibility', 'hidden');//.hide(); - don't use this, give it a go, find out why!
  		
  		// Resize the boxes appropriatly
  		this.resizeBoxes('general');
  		
  		// Reposition the Boxes
  		this.repositionBoxes({'speed':0});
  		
  		// Hide things
  		$('#lightbox-infoFooter').hide(); // we hide this here because it makes the display smoother
  		$('#lightbox-image,#lightbox-nav,#lightbox-nav-btnPrev,#lightbox-nav-btnNext,#lightbox-infoBox').hide();
  				
  		// Display the boxes
  		$('#lightbox-overlay').css('opacity',this.opacity).fadeIn(150, function(){
  			// Show the lightbox
  			$('#lightbox').show();
  			
  			// Display first image
  			if ( !$.Lightbox.showImage($.Lightbox.images.active()) )
  			{	$.Lightbox.finish();	return false;	}
  		});
  		
  		// All done
  		return true;
  	},
  	
  	finish: function ( )
  	{	// Get rid of lightbox
  	
  		// Hide lightbox
  		$('#lightbox').hide();
  		$('#lightbox-overlay').hide();
  		
  		// Fix attention seekers
  		$('embed, object, select').css({ 'visibility' : 'visible' });//.show();
  		
  		// Kill active image
  		this.images.active(false);
  		
  		// Adjust scrolling
  		if ( this.scroll === 'disable' )
  		{	// 
  			$(document.body).css('overflow', 'visible');
  		}
  		
  		// We are dead
  		this.visible = false;
  		
  	},
  	
  	resizeBoxes: function ( type )
  	{	// Resize the boxes
  		// Used on transition or window resize
  		
  		// Resize Overlay
  		if ( type !== 'transition' )
  		{	// We don't care for transition
  			var $body = $(this.ie6 ? document.body : document);
  			$('#lightbox-overlay').css({
  				width:		$body.width(),
  				height:		$body.height()
  			});
  			delete $body;
  		}
  		// Handle cases
  		switch ( type )
  		{
  			case 'general': // general resize (start of lightbox)
  				return true;
  				break;
  			case 'resized': // window was resized
  				if ( this.auto_resize === false )
  				{	// Stop
  					// Reposition
  					this.repositionBoxes({'nHeight':nHeight, 'speed':this.speed});
  					return true;
  				}
  			case 'transition': // transition between images
  			default: // unknown
  				break;
  		}
  		
  		// Get image
  		var image = this.images.active();
  		if ( !image || !image.width || !this.visible )
  		{	// No image or no visible lightbox, so we don't care
  			$.log('WARNING', 'A resize occured while no image or no lightbox...');
  			return false;
  		}
  		
  		// Resize image box
  		// i:image, w:window, b:box, c:current, n:new, d:difference
  		
  		// Get image dimensions
  		var iWidth  = image.width;
  		var iHeight = image.height;
  		
  		// Get window dimensions
  		var wWidth  = $(window).width();
  		var wHeight = $(window).height();
  		
  		// Check if we are in size
  		// Lightbox can take up 4/5 of size
  		if ( this.auto_resize !== false )
  		{	// We want to auto resize
  			var maxWidth  = Math.floor(wWidth*(4/5));
  			var maxHeight = Math.floor(wHeight*(4/5));
  			var resizeRatio;
  			while ( iWidth > maxWidth || iHeight > maxHeight )
  			{	// We need to resize
  				if ( iWidth > maxWidth )
  				{	// Resize width, then height proportionally
  					resizeRatio = maxWidth/iWidth;
  					iWidth = maxWidth;
  					iHeight = Math.floor(iHeight*resizeRatio);
  				}
  				if ( iHeight > maxHeight )
  				{	// Resize height, then width proportionally
  					resizeRatio = maxHeight/iHeight;
  					iHeight = maxHeight;
  					iWidth = Math.floor(iWidth*resizeRatio);
  				}
  			}
  		}
  		
  		// Get current width and height
  		var cWidth  = $('#lightbox-imageBox').width();
  		var cHeight = $('#lightbox-imageBox').height();
  
  		// Get the width and height of the selected image plus the padding
  		// padding*2 for both sides (left+right || top+bottom)
  		var nWidth	= (iWidth  + (this.padding * 2));
  		var nHeight	= (iHeight + (this.padding * 2) + 20);
  		
  		// Diferences
  		var dWidth  = cWidth  - nWidth;
  		var dHeight = cHeight - nHeight;
      var resizeSpeed = Math.round(Math.max(Math.abs(dHeight), Math.abs(dWidth)) / 5);
  		
  		// Set the overlay buttons height and the infobox width
  		// Other dimensions specified by CSS
  		$('#lightbox-infoBox').css('width', nWidth);
  		
  		// Handle final action
  		if ( type === 'transition' )
  		{	// We are transition
  			// Do we need to wait? (just a nice effect to counter the other
  			if ( dWidth === 0 && dHeight === 0 )
  			{	// We are the same size
  				this.pause(this.speed/3);
  				this.showImage(null, 3);
  			}
  			else
  			{	// We are not the same size
  				// Animate

          //alert(Math.max(dWidth, dHeight));
  				$('#lightbox-image').width(iWidth).height(iHeight);
  				$('#lightbox-imageBox').animate({width: nWidth, height: nHeight}, resizeSpeed, function ( ) { $.Lightbox.showImage(null, 3); } );
  			}
  		}
  		else
  		{	// We are a resize
  			// Animate Lightbox
  			$('#lightbox-image').animate({width:iWidth, height:iHeight}, resizeSpeed);
  			$('#lightbox-imageBox').animate({width: nWidth, height: nHeight}, resizeSpeed);
  		}
  		
  		// Reposition
  		this.repositionBoxes({nHeight: nHeight + 30, speed: this.speed});
  		
  		// Done
  		return true;
  	},
  	
  	repositioning:			false,	// are we currently repositioning
  	reposition_failsafe:	false,	// failsafe
  	repositionBoxes: function ( options )
  	{
  		// Prepare
  		if ( this.repositioning )
  		{	// Already here
  			this.reposition_failsafe = true;
  			return null;
  		}
  		this.repositioning = true;
  		
  		// Options
  		options = $.extend({}, options);
  		options.callback = options.callback || null;
  		options.speed = options.speed || 200;
  		
  		// Get page scroll
  		var pageScroll = this.getPageScroll();
  		
  		// Figure it out
  		// alert($(window).height()+"\n"+$(document.body).height()+"\n"+$(document).height());
  		// var nHeight = options.nHeight || parseInt($('#lightbox').height(),10) || $(document).height()/3;
  		var nHeight = options.nHeight || parseInt($('#lightbox').height(),10);
  		
  		// Display lightbox in center
  		// var nTop = pageScroll.yScroll + ($(document.body).height() /*frame height*/ - nHeight) / 2.5;
  		var nTop = pageScroll.yScroll + ($(window).height() /*frame height*/ - nHeight) / 2.5;
  		var nLeft = pageScroll.xScroll;
  		
  		// Animate
  		var css = {
  			left: nLeft,
  			top: nTop
  		};
      var lbox = document.getElementById('lightbox');
      var repositionSpeed = Math.floor(Math.abs(lbox.offsetTop - nTop) / 2);
  		if ((repositionSpeed > 10) && (repositionSpeed < 300)) {
  			$('#lightbox').animate(css, repositionSpeed, function(){
  				if ( $.Lightbox.reposition_failsafe )
  				{	// Fire again
  					$.Lightbox.repositioning = $.Lightbox.reposition_failsafe = false;
  					$.Lightbox.repositionBoxes(options);
  				}
  				else
  				{	// Done
  					$.Lightbox.repositioning = false;
  					if ( options.callback )
  					{	// Call the user callback
  						options.callback();
  					}
  				}
  			});
  		}
  		else
  		{
  			$('#lightbox').css(css);
  			if ( this.reposition_failsafe )
  			{	// Fire again
  				this.repositioning = this.reposition_failsafe = false;
  				this.repositionBoxes(options);
  			}
  			else
  			{	// Done
  				this.repositioning = false;
  			}
  		}
  		
  		// Done
  		return true;
  	},
  	
  	visible: false,
  	showImage: function ( image, step )
  	{
  		// Establish image
  		image = this.images.get(image);
  		if ( !image ) { return image; }
  		
  		// Default step
  		step = step || 1;
  		
  		// Split up below for jsLint compliance
  		var skipped_step_1 = step > 1 && this.images.active().src !== image.src;
  		var skipped_step_2 = step > 2 && $('#lightbox-image').attr('src') !== image.src;
  		if ( skipped_step_1 || skipped_step_2 )
  		{	// Force step 1
  			$.log('We wanted to skip a few steps: ', image, step, skipped_step_1, skipped_step_2);
  			step = 1;
  		}
  		
  		// What do we need to do
  		switch ( step )
  		{
  			// ---------------------------------
  			// We need to preload
  			case 1:
  			
  				// Disable keyboard nav
  				this.KeyboardNav_Disable();
  				
  				// Show the loading image
  				$('#lightbox-loading').show();
  				
  				// Hide things
  				$('#lightbox-image').hide();
          $('#lightbox-infoFooter').css({visibility: 'hidden'});
  				
  				// Remove show info events
  				$('#lightbox-imageBox').unbind();
  				// ^ Why? Because otherwise when the image is changing, the info pops out, not good!
  				
  				// Make the image the active image
  				if ( !this.images.active(image) ) { return false; }
  				
  				// Check if we need to preload
  				if ( image.width && image.height )
  				{	// We don't
  					// Continue to next step
  					this.showImage(null, 2);
  				}
  				else
  				{	// We do
  					// Create preloader
  					var preloader = new Image();
  					// Set callback
  					preloader.onload = function()
  					{	// We have preloaded the image
  						// Update image with our new info
  						image.width  = preloader.width;
  						image.height = preloader.height;
  						// Continue to next step
  						$.Lightbox.showImage(null, 2);
  						// Kill preloader
  						preloader.onload = null;
  						preloader = null;
  					};
  					// Start preload
  					preloader.src = image.src;
  				}
  				
  				// Done
  				break;
  			
  			
  			// ---------------------------------
  			// Resize the container
  			case 2:
  				
  				// Apply image changes
  				$('#lightbox-image').attr('src', image.src);
  				
  				// Set container border (Moved here for Konqueror fix - Credits to Blueyed)
  				if ( typeof this.padding === 'undefined' || this.padding === null || isNaN(this.padding) )
  				{	// Autodetect
  					this.padding = parseInt($('#lightbox-imageContainer').css('padding-left'), 10) || parseInt($('#lightbox-imageContainer').css('padding'), 10) || 0;
  				}
  				
  				// Use colorBlend?
  				if ( this.colorBlend )
  				{	// We have colorBlend
  					// Background
  					$('#lightbox-overlay').animate({'backgroundColor':image.color}, this.speed*2);
  					// Border
  					$('#lightbox-imageBox').css('borderColor', image.color);
  				}
  				
  				// Resize boxes
  				this.resizeBoxes('transition');
  				// ^ contains callback to next step
  				
  				// Done
  				break;
  			
  			
  			// ---------------------------------
  			// Display the image
  			case 3:
  				
  				// Hide loading
  				$('#lightbox-loading').hide();
  				
  				// Animate image
  				$('#lightbox-image').fadeIn(this.speed, function() {$.Lightbox.showImage(null, 4); });
  				
  				// Start the proloading of other images
  				this.preloadNeighbours();
  				
  				// Fire custom handler show
  				if ( this.handlers.show !== null )
  				{	// Fire it
  					this.handlers.show(image);
  				}
  				$('#lightbox-infoBox').show();
  				$('#lightbox-infoFooter').show().css({visibility: 'visible'});

  				
  				// Done
  				break;
  			
  			
  			// ---------------------------------
  			// Set image info / Set navigation
  			case 4:
  				
  				// ---------------------------------
  				// Set image info
  				
  				// Hide and set image info
  				var $title = $('#lightbox-caption-title').html(image.title || 'Untitled');
  				if ( this.download_link )
  				{	$title.attr('href', this.download_link ? image.src : '');	}
  				delete $title;
  				$('#lightbox-caption-seperator').html(image.description ? ': ' : '');
  				$('#lightbox-caption-description').html(image.description || '&nbsp;');
  				
  				// If we have a set, display image position
  				if ( this.images.size() > 1 )
  				{	// Display
            if (!this.text.imageNumOfTotal)
            {
              this.text.imageNumOfTotal = this.text.image + ' {num} ' + this.text.of + ' {total}';
            }
            var imageNumOfTotal = this.text.imageNumOfTotal;
            imageNumOfTotal = imageNumOfTotal.replace('{num}', image.index + 1);
            imageNumOfTotal = imageNumOfTotal.replace('{total}', this.images.size());
            imageNumOfTotal = imageNumOfTotal.replace(' ', '&nbsp;');
            // Display
						$('#lightbox-currentNumber').html(imageNumOfTotal);
            $('#lightbox-image').unbind().click(function() {
              $.Lightbox.showImage($.Lightbox.images.next());
              return false;
            }).addClass('clickable');
  				} else
  				{	// Empty
  					$('#lightbox-currentNumber').html('&nbsp;');
            $('#lightbox-image').unbind().removeClass('clickable');
  				}
  				
  				// ---------------------------------
  				// Info events
  				
  				
  				// ---------------------------------
  				// Set navigation
  	
  				// If not first, show previous button
  				if ( !this.images.first(image) ) {
  					// Not first, show button
  					$('#lightbox-nav-btnPrev').show();
  				}
  				
  				// If not last, show next button
  				if ( !this.images.last(image) ) {
  					// Not first, show button
  					$('#lightbox-nav-btnNext').show();
  				}
  				
  				// Make navigation active / show it
  				$('#lightbox-nav').show();
  				
  				// Enable keyboard navigation
  				this.KeyboardNav_Enable();
  				
  				// Done
  				break;
  				
  				
  			// ---------------------------------
  			// Error handling
  			default:
  				$.log('ERROR', 'Don\'t know what to do: ', image, step);
  				return this.showImage(image, 1);
  				// break;
  			
  		}
  		
  		// All done
  		return true;
  	},
  	
  	preloadNeighbours: function ( )
  	{	// Preload all neighbour images
  		
  		// Do we need to do this?
  		if ( this.images.single() || this.images.empty() )
  		{	return true;	}
  		
  		// Get active image
  		var image = this.images.active();
  		if ( !image ) { return image; }
  		
  		// Load previous
  		var prev = this.images.prev(image);
  		var objNext;
  		if ( prev ) {
  			objNext = new Image();
  			objNext.src = prev.src;
  		}
  		
  		// Load next
  		var next = this.images.next(image);
  		if ( next ) {
  			objNext = new Image();
  			objNext.src = next.src;
  		}
  	},
  	
  	// --------------------------------------------------
  	// Things we don't really care about
  	
  	KeyboardNav_Enable: function ( ) {
  		$(document).keydown(function(objEvent) {
  			$.Lightbox.KeyboardNav_Action(objEvent);
  		});
  	},
  	
  	KeyboardNav_Disable: function ( ) {
  		$(document).unbind();
  	},
  	
  	KeyboardNav_Action: function ( objEvent ) {
  		// Prepare
  		objEvent = objEvent || window.event;
  		
  		// Get the keycode
  		var keycode = objEvent.keyCode;
  		var escapeKey = objEvent.DOM_VK_ESCAPE /* moz */ || 27;
  		
  		// Get key
  		var key = String.fromCharCode(keycode).toLowerCase();
  		
  		// Close?
  		if ( key === this.keys.close || keycode === escapeKey )
  		{	return $.Lightbox.finish();		}
  		
  		// Prev?
  		if ( key === this.keys.prev || keycode === 37 )
  		{	// We want previous
  			return $.Lightbox.showImage($.Lightbox.images.prev());
  		}
  		
  		// Next?
  		if ( key === this.keys.next || keycode === 39 )
  		{	// We want next
  			return $.Lightbox.showImage($.Lightbox.images.next());
  		}
  		
  		// Unknown
  		return true;
  	},
  	
  	getPageScroll: function ( ) {
  		var xScroll, yScroll;
  		if (self.pageYOffset)
  		{	// Some browser
  			yScroll = self.pageYOffset;
  			xScroll = self.pageXOffset;
  		} else if (document.documentElement && document.documentElement.scrollTop)
  		{	// Explorer 6 Strict
  			yScroll = document.documentElement.scrollTop;
  			xScroll = document.documentElement.scrollLeft;
  		} else if (document.body)
  		{	// All other browsers
  			yScroll = document.body.scrollTop;
  			xScroll = document.body.scrollLeft;	
  		}
  		var arrayPageScroll = {'xScroll':xScroll,'yScroll':yScroll};
  		return arrayPageScroll;
  	},
  	
  	pause: function ( ms ) {
  		var date = new Date();
  		var curDate = null;
  		do { curDate = new Date(); }
  		while ( curDate - date < ms);
  	}
  
  }); // We have finished extending/defining our LightboxClass


  // --------------------------------------------------
  // Finish up
  
  // Instantiate
  if ( typeof $.Lightbox === 'undefined' )
  {	// 
  	$.Lightbox = new $.LightboxClass();
  }
  // Extend jQuery elements for Lightbox
  $.fn.lightbox = function ( options )
  {	// Init a el for Lightbox
  	// Eg. $('#gallery a').lightbox();
  	
  	// If need be: Instantiate $.LightboxClass to $.Lightbox
  	$.Lightbox = $.Lightbox || new $.LightboxClass();
  	
  	// Handle IE6 appropriatly
  	if ( $.Lightbox.ie6 && !$.Lightbox.ie6_support )
  	{	// We are IE6 and we want to ignore
  		return this; // chain
  	}
  	
  	// Establish options
  	options = $.extend({start:false,events:true} /* default options */, options);
  	
  	// Get group
  	var group = $(this);
  	
  	// Events?
  	if ( options.events )
  	{	// Add events
  		$(group).unbind().click(function(){
  			// Get obj
  			var obj = $(this);
  			// Get rel
  			// var rel = $(obj).attr('rel');
  			// Init group
  			if ( !$.Lightbox.init($(obj)[0], group) )
  			{	return false;	}
  			// Display lightbox
  			if ( !$.Lightbox.start() )
  			{	return false;	}
  			// Cancel href
  			return false;
  		});
  		// Add style
  		$(group).addClass('lightbox-enabled');
  	}
  	
  	// Start?
  	if ( options.start )
  	{	// Start
  		// Get obj
  		var obj = $(this);
  		// Get rel
  		// var rel = $(obj).attr('rel');
  		// Init group
  		if ( !$.Lightbox.init($(obj)[0], group) )
  		{	return this;	}
  		// Display lightbox
  		if ( !$.Lightbox.start() )
  		{	return this;	}
  	}
  	
  	// And chain
  	return this;
  };

// Finished definition

})(jQuery); // We are done with our plugin, so lets call it with jQuery as the argument
