/**
 * jQuery Lightbox Plugin (balupton edition) - Lightboxes for jQuery
 * Copyright (C) 2008 Benjamin Arthur Lupton
 * http://jquery.com/plugins/project/jquerylightbox_bal
 *
 * This file is part of jQuery Lightbox (balupton edition).
 * 
 * jQuery Lightbox (balupton edition) is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 * 
 * jQuery Lightbox (balupton edition) is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 * 
 * You should have received a copy of the GNU Affero General Public License
 * along with jQuery Lightbox (balupton edition).  If not, see <http://www.gnu.org/licenses/>.
 *
 * @name jquery_lightbox: jquery.lightbox.js
 * @package jQuery Lightbox Plugin (balupton edition)
 * @version 1.3.7-final
 * @date April 25, 2009
 * @category jQuery plugin
 * @author Benjamin "balupton" Lupton {@link http://www.balupton.com}
 * @copyright (c) 2008 Benjamin Arthur Lupton {@link http://www.balupton.com}
 * @license GNU Affero General Public License - {@link http://www.gnu.org/licenses/agpl.html}
 * @example Visit {@link http://jquery.com/plugins/project/jquerylightbox_bal} for more information.
 */

// Start of our jQuery Plugin
(function($)
{	// Create our Plugin function, with $ as the argument (we pass the jQuery object over later)
    // More info: http://docs.jquery.com/Plugins/Authoring#Custom_Alias
	
    // Debug
    if ( typeof $.log === 'undefined' ) {
        if ( !$.browser.safari && typeof window.console !== 'undefined' && typeof window.console.log === 'function' )
        {	// Use window.console
            $.log = function(){
                var args = [];
                for(var i = 0; i < arguments.length; i++) {
                    args.push(arguments[i]);
                }
                window.console.log.apply(window.console, args);
            }
            $.console = {
                log:	$.log,
                debug:	window.console.debug	|| $.log,
                warn:	window.console.warn		|| $.log,
                error:	window.console.error	|| $.log,
                trace:	window.console.trace	|| $.log
            }
        }
        else
        {	// Don't use anything
            $.log = function ( ) { };
            $.console = {
                log:	$.log,
                debug:	$.log,
                warn:	$.log,
                error:	alert,
                trace:	$.log
            };
        }
    }
	
    // Pre-Req
    $.params_to_json = $.params_to_json || function ( params )
    {	// Turns a params string or url into an array of params
        // Adjust
        params = String(params);
        // Remove url if need be
        params = params.substring(params.indexOf('?')+1);
        // params = params.substring(params.indexOf('#')+1);
        // Change + to %20, the %20 is fixed up later with the decode
        params = params.replace(/\+/g, '%20');
        // Do we have JSON string
        if ( params.substring(0,1) === '{' && params.substring(params.length-1) === '}' )
        {	// We have a JSON string
            return eval(decodeURIComponent(params));
        }
        // We have a params string
        params = params.split(/\&|\&amp\;/);
        var json = {};
        // We have params
        for ( var i = 0, n = params.length; i < n; ++i )
        {
            // Adjust
            var param = params[i] || null;
            if ( param === null ) {
                continue;
            }
            param = param.split('=');
            if ( param === null ) {
                continue;
            }
            // ^ We now have "var=blah" into ["var","blah"]
			
            // Get
            var key = param[0] || null;
            if ( key === null ) {
                continue;
            }
            if ( typeof param[1] === 'undefined' ) {
                continue;
            }
            var value = param[1];
            // ^ We now have the parts
			
            // Fix
            key = decodeURIComponent(key);
            value = decodeURIComponent(value);
            try {
                // value can be converted
                value = eval(value);
            } catch ( e ) {
            // value is a normal string
            }
			
            // Set
            // console.log({'key':key,'value':value}, split);
            var keys = key.split('.');
            if ( keys.length === 1 )
            {	// Simple
                json[key] = value;
            }
            else
            {	// Advanced
                var path = '';
                for ( ii in keys )
                {	//
                    key = keys[ii];
                    path += '.'+key;
                    eval('json'+path+' = json'+path+' || {}');
                }
                eval('json'+path+' = value');
            }
        // ^ We now have the parts added to your JSON object
        }
        return json;
    };
	
    // Declare our class
    $.LightboxClass = function ( )
    {	// This is the handler for our constructor
        this.construct();
    };

    // 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').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;
    };
	
    // Define our class
    $.extend($.LightboxClass.prototype,
    {	// Our LightboxClass definition
		
        // -----------------
        // Everyting to do with images
		
        images: {
			
            // -----------------
            // Variables
			
            // Our array of images
            list:[], /* [ {
				src: 'url to image',
				link: 'a link to a page',
				title: 'title of the image',
				name: 'name of the image',
				description: 'description of the image'
			} ], */
			
            // The current active image
            image: false,
			
            // -----------------
            // Functions
			
            prev: function ( image )
            {	// Get previous 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;
                }
				
                // 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:	'',
                    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
                    $.console.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
                    $.console.error('The desired image does not exist: ', image, this.list);
                    return false;
                }
				
                // Return image
                return image;
            },
			
            debug: function ( )
            {
                return $.Lightbox.debug(arguments);
            }
			
        },
		
        // -----------------
        // Variables
		
        constructed:		false,
        compressed:			null,
		
        // -----------------
        // Options
		
        src:				null,		// the source location of our js file
        baseurl:			null,
		
        files: {
            compressed: {
                js: {
                    lightbox:	'includes/javascript/jquery/jquery.lightbox.min.js',
                    colorBlend:	'includes/javascript/jquery/jquery.color.min.js'
                },
                css: {
                    lightbox:	'templates/new/jquery.lightbox.css'
                }
            },
            uncompressed: {
                js: {
                    lightbox:	'includes/javascript/jquery/jquery.lightbox.js',
                    colorBlend:	'includes/javascript/jquery/jquery.color.js'
                },
                css: {
                    lightbox:	'templates/new/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:			'sur',
            close:		'Fermer X',
            closeInfo:	'Fermer',
            download:	'Télécharger.',
            help: {
                close:		'Cliquer pour fermer',
                interact:	'Hover to 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:	's'
        },
		
        handlers: {
            // For custom actions
            show:	null
        },
		
        opacity:		0.9,
        padding:		null,		// if null - autodetect
		
        speed:			100,		// Duration of effect, milliseconds
		
        rel:			'lightbox',	// What to look for in the rels
		
        auto_relify:	true,		// should we automaticly do the rels?
		
        auto_scroll:	'disabled',	// should the lightbox scroll with the page? follow, disabled, ignore
        auto_resize:	false,		// true or false
		
        ie6:			null,		// are we ie6?
        ie6_support:	true,		// have ie6 support
        ie6_upgrade:	false,		// show ie6 upgrade message
		
        colorBlend:		null,		// null - auto-detect, true - force, false - no
		
        download_link:		false,	// Display the download link
		
        show_helper_text:	false,	// Display the helper text up the top right
        show_linkback:		false,	// true, false
        show_info:			false,	// auto - automaticly handle, true - force
        show_extended_info:	false,	// auto - automaticly handle, true - force
		
        // names of the options that can be modified
        options:	['show_helper_text', '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'],
		
        // -----------------
        // 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 = options || {};
			
            // -------------------
            // Handle files
			
            // Prepend function to use later
            var prepend = function(item, value) {
                if ( typeof item === 'object' ) {
                    for (var i in item) {
                        item[i] = prepend(item[i], value);
                    }
                } else if ( typeof value === 'array' ) {
                    for (var i=0,n=item.length; i<n; ++i) {
                        item[i] = prepend(item[i], value);
                    }
                } else {
                    item = value+item;
                }
                return item;
            }
			
            // Add baseurl
            if ( initial && (typeof options.files === 'undefined') )
            {	// Load the files like default
				
                // Reset compressed
                this.compressed = null;
				
                // Get the src of the first script tag that includes our js file (with or without an appendix)
                var $script = $('script[src*='+this.files.compressed.js.lightbox+']:first');
                if ( $script.length !== 0 ) {
                    // Compressed
                    $.extend(true, this.files, this.files.compressed);
                    this.compressed = true;
                } else {
                    // Uncompressed
                    $script = $('script[src*='+this.files.uncompressed.js.lightbox+']:first');
                    if ( $script.length !== 0 ) {
                        // Uncompressed
                        $.extend(true, this.files, this.files.uncompressed);
                        this.compressed = false;
                    } else {
                // Nothing
                }
                }
				
                // Make sure we found ourselves
                if ( this.compressed === null )
                {	// We didn't
                    $.console.error('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
					
                    // Grab the script src
                    this.src = $script.attr('src');
					
                    // 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));
					
                    // Prepend baseurl to files
                    this.files = prepend(this.files, this.baseurl);
					
                    // Now as we have source, we may have more params
                    options = $.extend(options, $.params_to_json(this.src));
                }
				
            }
            else
            if ( typeof options.files === 'object' )
            {	// We have custom files
                // Prepend baseurl to files
                options.files = prepend(options.files, this.baseurl);
            }
            else
            {	// Don't have any files, so no need to perform domReady
                domReady = false;
            }
			
            // -------------------
            // Apply options
			
            for ( var 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(true, this[name], options[name]);
                }
                else if ( typeof options[name] !== 'undefined' )
                {	// We have that option, so apply it
                    this[name] = options[name];
                }
            }
            delete i;
			
            // -------------------
            // 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;
			
            // 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">\n\
        <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>':'')+
                (this.show_helper_text?'<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>\n\
    </div>\n\
    <div id="lightbox">\n\
        <div id="lightbox-imageBox">\n\
            <div id="lightbox-imageContainer">\n\
                <a id="lbCloseLink" href="#" ></a>\n\
                <img id="lightbox-image" />\n\
                <div id="lightbox-loading"><a href="#" id="lightbox-loading-link"><img src="' + this.files.images.loading + '" /></a></div>\n\
            </div>\n\
        </div>\n\
        <div id="lightbox-infoBox">\n\
            <div id="lightbox-infoContainer">\n\
                <div id="lightbox-nav"><a href="#" id="lightbox-nav-btnPrev"></a><a href="#" id="lightbox-nav-btnNext"></a></div>\n\
                <div id="lightbox-infoHeader">\n\
                    <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>\n\
                </div>\n\
                <div id="lightbox-infoFooter"><span id="lightbox-currentNumber"></span></div>\n\
                <div id="lightbox-infoContainer-clear"></div>\n\
            </div>\n\
        </div>\n\
    </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').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
                $.console.warn('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').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
                //$.console.warn('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-nav-btnPrev,#lightbox-nav-btnNext').css('height', 10);

            $('#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 +22
                    }, 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
                $.console.info('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();
					
                    // 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 || '');
                    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:not(:visible)').stop().slideDown('fast');
                    });
					
                    // Apply event
                    $('#lightbox-infoBox').unbind('mouseover').mouseover(function(){
                        $('#lightbox-infoFooter:not(:visible)').stop().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({
//                        'transparent background' : ' url(' + this.files.images.blank + ') no-repeat'
//                    });
                    
                    $('#lightbox-nav-btnPrev').css({'background' : 'url(' + $.Lightbox.files.images.prev + ') left 45% no-repeat'});
                    $('#lightbox-nav-btnNext').css({'background' : 'url(' + $.Lightbox.files.images.next + ') right 45% no-repeat'});
					
                    // If not first, show previous button
                    if ( !this.images.first(image) ) {
                        // Not first, show button
                        $('#lightbox-nav-btnPrev').show();
                    }else{
                        $('#lightbox-nav-btnPrev').hide();
                    }
					
                    // If not last, show next button
                    if ( !this.images.last(image) ) {
                        // Not first, show button
                        $('#lightbox-nav-btnNext').show();
                    }else{
                        $('#lightbox-nav-btnNext').hide();
                    }
					
                    // Make navigation active / show it
                    $('#lightbox-nav').show();
					
                    // Enable keyboard navigation
                    this.KeyboardNav_Enable();
					
                    // Done
                    break;
					
					
                // ---------------------------------
                // Error handling
                default:
                    $.console.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('keydown');
        },
		
        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

