/**
* jQuery Lightbox Plugin (balupton edition) - Lightboxes for jQuery
* Copyright (C) 2008 Benjamin Arthur Lupton
* http://jquery.com/plugins/project/jquerylightbox_bal
*/

// Start of our jQuery Plugin
(function($)
{
if ( !$.browser.safari && typeof window.console !== 'undefined' && typeof window.console.log === 'function' )
{
$.log = window.console.log;
}
else
{
$.log = function ( ) { };
}

$.params_to_json = $.params_to_json || function ( params )
{
params = String(params);
params = params.substring(params.indexOf('?')+1);
params = params.replace(/\+/g, '%20');
if ( params.substring(0,1) === '{' && params.substring(params.length-1) === '}' )
{
return eval(decodeURIComponent(params));
}
params = params.split(/\&|\&amp\;/);
var json = {};
for ( var i = 0, n = params.length; i < n; ++i )
{
var param = params[i] || null;
if ( param === null ) { continue; }
param = param.split('=');
if ( param === null ) { continue; }
var key = param[0] || null;
if ( key === null ) { continue; }
if ( typeof param[1] === 'undefined' ) { continue; }
var value = param[1];
key = decodeURIComponent(key);
value = decodeURIComponent(value);
try {
value = eval(value);
} catch ( e ) {
}

var keys = key.split('.');
if ( keys.length === 1 )
{
json[key] = value;
}
else
{
var path = '';
for ( ii in keys )
{
key = keys[ii];
path += '.'+key;
eval('json'+path+' = json'+path+' || {}');
}
eval('json'+path+' = value');
}
}
return json;
};

$.LightboxClass = function ( ){this.construct();};

$.fn.lightbox = function ( options )
{
$.Lightbox = $.Lightbox || new $.LightboxClass();

if ( $.Lightbox.ie6 && !$.Lightbox.ie6_support )
{
return this;
}
options = $.extend({start:false,events:true} , options);

var group = $(this);
if ( options.events )
{
$(group).unbind().click(function(){
var obj = $(this);
if ( !$.Lightbox.init($(obj)[0], group) )
{	return false;	}
if ( !$.Lightbox.start() )
{	return false;	}
return false;
});
$(group).addClass('lightbox-enabled');
}
if ( options.start )
{
var obj = $(this);
if ( !$.Lightbox.init($(obj)[0], group) )
{	return this;	}
if ( !$.Lightbox.start() )
{	return this;	}
}

return this;
};

$.extend($.LightboxClass.prototype,
{
images: {
list:[], 
image: false,

prev: function ( image )
{
if ( typeof image === 'undefined' )
{	image = this.active();
if ( !image ) { return image; }
}
if ( this.first(image) )
{	return false;	}
return this.get(image.index-1);
},
next: function ( image )
{
if ( typeof image === 'undefined' )
{	image = this.active();
if ( !image ) { return image; }
}
if ( this.last(image) )
{	return false;	}
return this.get(image.index+1);
},
first: function ( image )
{
if ( typeof image === 'undefined' )
{	return this.get(0);	}
return image.index === 0;
},
last: function ( image )
{
if ( typeof image === 'undefined' )
{	return this.get(this.size()-1);	}
return image.index === this.size()-1;
},
single: function ( )
{
return this.size() === 1;
},
size: function ( )
{
return this.list.length;
},
empty: function ( )
{
return this.size() === 0;
},

clear: function ( )
{
this.list = [];
this.image = false;
},

active: function ( image )
{
if ( typeof image === 'undefined' )
{	return this.image;	}

if ( image !== false )
{
image = this.get(image);
if ( !image )
{	return image;}
}

this.image = image;
return true;
},
add: function ( obj )
{
if ( obj[0] )
{
for ( var i = 0; i < obj.length; i++ )
{	this.add(obj[i]);	}
return true;
}
var image = this.create(obj);
if ( !image ) { return image; }
image.index = this.size();
this.list.push(image);
return true;
},

create: function ( obj )
{
var image = { 
src:	'',
title:	'Untitled',
description:	'',
name:	'',
index:	-1,
color:	null,
width:	null,
height:	null,
image:	true
};

if ( obj.image )
{
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 )
{
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');
var s = image.title.indexOf(': ');
if ( s > 0 )
{
	image.description = image.title.substring(s+2) || image.description;
	image.title = image.title.substring(0,s) || image.title;
}
}
else {
	image = false;
}
}
else {
image = false;
}

if ( !image )
{
$.log('ERROR', 'We dont know what we have:', obj);
return false;
}
return image;
},

get: function ( image )
{
if ( typeof image === 'undefined' || image === null )
{
return this.active();
}
else
if ( typeof image === 'number' )
{
image = this.list[image] || false;
}
else
{
image = this.create(image);
if ( !image ) { return false; }

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;	}
}

image = f;
}

if ( !image )
{
$.log('ERROR', 'The desired image doesn\'t exist: ', image, this.list);
return false;
}
return image;
},
debug: function ( )
{
return $.Lightbox.debug(arguments);
}
},

constructed:		false,

src:				null,		
baseurl:			null,

files: {
js: {
lightbox:	'js/jquery.lightbox.js',
colorBlend:	'js/jquery.color.js'
},
css: {
lightbox:	'css/jquery.lightbox.css'
},
images: {
prev:		'images/prev.gif',
next:		'images/next.gif',
blank:		'images/blank.gif',
loading:	'images/loading.gif'
}
},
text: {
image:		'Image',
of:			'of',
close:		'Close X',
closeInfo:	'You can also click anywhere outside the image to close.',
download:	'',
help: {
close:		'',
interact:	''
},
about: {
text: 	'',
title:	'',
link:	''
}
},
keys: {
close:	'c',
prev:	'p',
next:	'n'
},
handlers: {
show:	null
},

opacity:		0.9,
padding:		null,		// if null - autodetect

speed:			400,		// 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
ie6_upgrade:	true,		// show ie6 upgrade message

colorBlend:		null,		// null - auto-detect, true - force, false - no

download_link:	false,		// Display the download link

show_linkback:		false,	// 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', 'ie6_upgrade', 'colorBlend', 'baseurl', 'files', 'text', 'show_linkback', 'keys', 'opacity', 'padding', 'speed', 'rel', 'auto_relify'],

construct: function ( options )
{
var initial = typeof this.constructed === 'undefined' || this.constructed === false;
this.constructed = true;

// Perform domReady
var domReady = initial;

// Prepare options
options = $.extend({}, options);

if ( initial && (typeof options.files === 'undefined') )
{	
this.src = $('script[src*='+this.files.js.lightbox+']:first').attr('src');

if ( !this.src )
{
domReady = false;
}
else
{
this.baseurl = this.src.substring(0, this.src.indexOf(this.files.js.lightbox));
var me = this;
$.each(this.files, function(group, val){
	$.each(this, function(file, val){
		me.files[group][file] = me.baseurl+val;
	});
});
delete me;
options = $.extend(options, $.params_to_json(this.src));
}

}
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
{	
domReady = false;
}
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' )
{	
$(function() {

$.Lightbox.domReady();
});
}

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;

// Handle IE6 appropriatly
if ( this.ie6 && this.ie6_upgrade )
{	// Add the upgrade message
scripts.ie6 = 'http://www.savethedevelopers.org/say.no.to.ie.6.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 id="lightbox-overlay-text">'+(this.show_linkback?'<p><span id="lightbox-overlay-text-about"><a href="#" title="'+this.text.about.title+'">'+this.text.about.text+'</a></span></p><p>&nbsp;</p>':'')+'<p><span id="lightbox-overlay-text-close">'+this.text.help.close+'</span><br/>&nbsp;<span id="lightbox-overlay-text-interact">'+this.text.help.interact+'</span></p></div></div><div id="lightbox"><div id="lightbox-imageBox"><div id="lightbox-imageContainer"><img id="lightbox-image" /><div id="lightbox-nav"><a href="#" id="lightbox-nav-btnPrev"></a><a href="#" id="lightbox-nav-btnNext"></a></div><div id="lightbox-loading"><a href="#" id="lightbox-loading-link"><img src="' + this.files.images.loading + '" /></a></div></div></div><div id="lightbox-infoBox"><div id="lightbox-infoContainer"><div id="lightbox-infoHeader"><span id="lightbox-caption">'+(this.download_link ? '<a href="#" title="' + this.text.download + '" id="lightbox-caption-title"></a>' : '<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></div><div id="lightbox-infoContainer-clear"></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().hover(function() { // over
$(this).css({ 'background' : 'url(' + $.Lightbox.files.images.prev + ') left 45% no-repeat' });
},function() { // out
$(this).css({ 'background' : 'transparent url(' + $.Lightbox.files.images.blank + ') no-repeat' });
}).click(function() {
$.Lightbox.showImage($.Lightbox.images.prev());
return false;
});

// Next
$('#lightbox-nav-btnNext').unbind().hover(function() { // over
$(this).css({ 'background' : 'url(' + $.Lightbox.files.images.next + ') right 45% no-repeat' });
},function() { // out
$(this).css({ 'background' : 'transparent url(' + $.Lightbox.files.images.blank + ') no-repeat' });
}).click(function() {
$.Lightbox.showImage($.Lightbox.images.next());
return false;
});

// Help
if ( this.show_linkback )
{	// Linkback exists so add handler
$('#lightbox-overlay-text-about a').click(function(){window.open($.Lightbox.text.about.link); return false;});
}
$('#lightbox-overlay-text-close').unbind().hover(
function(){
$('#lightbox-overlay-text-interact').fadeIn();
},
function(){
$('#lightbox-overlay-text-interact').fadeOut();
}
);

// Image link
$('#lightbox-caption-title').click(function(){window.open($(this).attr('href')); 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(400, function(){
// Show the lightbox
$('#lightbox').fadeIn(300);

// 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').fadeOut(function() { $('#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));

// Diferences
var dWidth  = cWidth  - nWidth;
var dHeight = cHeight - nHeight;

// Set the overlay buttons height and the infobox width
// Other dimensions specified by CSS
$('#lightbox-nav-btnPrev,#lightbox-nav-btnNext').css('height', nHeight); 
$('#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
$('#lightbox-image').width(iWidth).height(iHeight);
$('#lightbox-imageBox').animate({width: nWidth, height: nHeight}, this.speed, function ( ) { $.Lightbox.showImage(null, 3); } );
}
}
else
{	// We are a resize
// Animate Lightbox
$('#lightbox-image').animate({width:iWidth, height:iHeight}, this.speed);
$('#lightbox-imageBox').animate({width: nWidth, height: nHeight}, this.speed);
}

// Reposition
this.repositionBoxes({'nHeight':nHeight, '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 || 'slow';

// 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
};
if (options.speed) {
$('#lightbox').animate(css, 'slow', 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,#lightbox-nav,#lightbox-nav-btnPrev,#lightbox-nav-btnNext,#lightbox-infoBox').hide();

// 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*1.5, 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);
}

// 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
	$('#lightbox-currentNumber').html(this.text.image + '&nbsp;' + ( image.index + 1 ) + '&nbsp;' + this.text.of + '&nbsp;' + this.images.size());
} else
{	// Empty
	$('#lightbox-currentNumber').html('&nbsp;');
}

// ---------------------------------
// Info events

// Apply event
$('#lightbox-imageBox').unbind('mouseover').mouseover(function(){
	$('#lightbox-infoBox').slideDown('fast');
});

// Apply event
$('#lightbox-infoBox').unbind('mouseover').mouseover(function(){
	$('#lightbox-infoFooter').slideDown('fast');
});

// Forced show?
if ( this.show_extended_info === true )
{	// Force show
	$('#lightbox-imageBox').trigger('mouseover');
	$('#lightbox-infoBox').trigger('mouseover');
}
else if ( this.show_info === true )
{	// Force show
	$('#lightbox-imageBox').trigger('mouseover');
}

// ---------------------------------
// Set navigation

// Instead to define this configuration in CSS file, we define here. And it's need to IE. Just.
$('#lightbox-nav-btnPrev, #lightbox-nav-btnNext').css({ 'background' : 'transparent url(' + this.files.images.blank + ') no-repeat' });

// 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();
}

// Finished definition

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