/**
 * 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.0-rc1
 * @date August 24, 2008
 * @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.
 * @Modified by Martin Spain (martin.spain@lbi.com) for use with Syngenta website 
 */

// 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
    $.log = $.log || function(options) {	// Can we debug? - Do we have firebug
        var con = null;
        if (typeof console !== 'undefined' && typeof $.log !== 'undefined')
        { con = console; }
        else if (typeof window.console !== 'undefined' && typeof window.$.log !== 'undefined')
        { con = window.console; }

        // Do the log
        if (con) {	// Do we support arguments?
            if (typeof arguments !== 'undefined' && arguments.length > 1)
            { con.log(arguments); return arguments; }
            else
            { con.log(options); return options; }
        }
    };

    // 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(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: '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('background-color');
                        // 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);
            }

        },

        // -----------------
        // Options

        constructed: false,

        src: null, 	// the source location of our js file
        baseurl: null,

        files: {
            // If you are doing a repack with packer (http://dean.edwards.name/packer/) then append ".packed" onto the js and css files before you pack it.
            js: {
                lightbox: '/syn/assets/script/jquery.lightbox.js',
                colorBlend: '/syn/assets/script/jquery.colorblend.min.js'
            },
            css: {
                lightbox: '/syn/assets/style/lightbox.css'
            },
            images: {
                prev: '/syn/assets/img/gallery/prev.gif',
                next: '/syn/assets/img/gallery/next.gif',
                blank: '/syn/assets/img/gallery/blank.gif',
                loading: '/syn/assets/img/gallery/loading.gif'
            }
        },

        text: {
            // For translating
            image: '',
            of: 'of',
            close: 'Close window',
            closeInfo: 'You can also click anywhere outside the image to close',
            download: 'Direct link to download the image',
            help: {
                close: 'Click to close',
                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'
            }
        },
        show_linkback: false,

        keys: {
            close: 'c',
            prev: 'p',
            next: 'n'
        },

        handlers: {
            // For custom actions
            show: null
        },

        opacity: 0.9,
        padding: null, 	// if null - autodetect

        speed: 300, 	// Duration of effect, milliseconds

        rel: 'lightbox', // What to look for in the rels

        auto_relify: true, 	// should we automaticly do the rels?

        scroll: 'follow', // should the lightbox scroll with the page?

        ie6: null, 	// are we ie6?
        ie6_support: true, 	// have ie6 support
        ie6_upgrade: false, 	// show ie6 upgrade message

        colorBlend: false,     // null - auto-detect, true - force, false - no

        // names of the options that can be modified
        options: ['ie6_support', 'ie6_upgrade', 'colorBlend', 'baseurl', 'files', 'text', 'show_linkback', 'keys', 'opacity', 'padding', 'speed', 'rel', 'auto_relify', 'scroll_with'],

        // -----------------
        // 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;

                    // 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
                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.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"></div><div id="lightbox"><div id="lightbox-imageBox"><div id="lightbox-imageContainer"><div id="lightbox-infoHeader"><h4 id="lightbox-caption"></h4></div><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 id="lightbox-infoBox"><div id="lightbox-infoContainer" class="clearfix"><div id="lightbox-infoFooter"><div id="lightbox-currentNumber"></div><div id="lightbox-download">Download: <a id="lightbox-download-low" href="#" title="' + this.text.download + '"><a id="lightbox-download-high" href="#" title="' + this.text.download + '"></a></div></div></div></div><div id="lightbox-close"><a href="#" id="lightbox-close-button" title="' + this.text.closeInfo + '">' + this.text.close + '</a></span></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').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;
            });

            // Image link
            $('#lightbox-download-low').click(function() { window.open($(this).attr('href')); return false; });
            $('#lightbox-download-high').click(function() { window.open($(this).attr('href')); return false; });

            // Assign close clicks
            $('#lightbox-overlay, #lightbox, #lightbox-loading-link, #lightbox-close-button').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').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;
            }

            // We no longer care if we are general
            if (type === 'general') {	// Done
                return true;
            }

            // 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
            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').height(iHeight);
					$('#lightbox-imageBox').animate({height: nHeight}, this.speed, function(){$.Lightbox.showImage(null, 3);});
                    this.repositionBoxes({ 'nHeight': nHeight, 'speed': this.speed });
                }
            }
            else {	// We are a resize
                // Animate Lightbox
                $('#lightbox-image').animate({ height: iHeight }, this.speed);
                $('#lightbox-imageBox').animate({ height: nHeight }, this.speed);
                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;
			
			// vars
			/*var getVars = $.params_to_json(image.src);
			var mediaSrc = image.src.split("?")[0];*/

            // 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;
				//alert('skipped step ' + step + ' and skipped_step_1='+skipped_step_1+' and skipped_step_2='+skipped_step_2 + ' #lightbox-image src attr='+$('#lightbox-image').attr('src')+' and image.src='+image.src);
            }*/

            // 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-infoFooter,#lightbox-close').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
						if ($.params_to_json(image.src).type == "image") {
							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;
						}
						else {
							// Flash, so skip to step 2
							image.width = $.params_to_json(image.src).width;
							image.height = $.params_to_json(image.src).height;
							image.mediatype = "flash"; 
							this.showImage(null, 2);
						}
                    }

                    // Done
                    break;


                // --------------------------------- 
                // Resize the container 
                case 2:
                    // Apply image changes
					if ($.params_to_json(image.src).type == "flash") {
						
						var flashvars = {};
					
					    var params = {};
					    params.menu = "false";
					    params.allowScriptAccess = "sameDomain";
					
					    var attributes = {};
					    attributes.id = "lightbox-image";
					    attributes.name = "lightbox-image";
					
					    swfobject.embedSWF(image.src, 'lightbox-image', $.params_to_json(image.src).width, $.params_to_json(image.src).height, '9.0.0','', flashvars, params, attributes);	
					}
					else {
						$('#lightbox-image').before('<img src="'+image.src+'" id="lightbox-image" alt="" style="display:none;" />').remove();
						//$('#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
                        $('#lightbox-overlay').colorBlend([{
                            param: 'background-color',
                            fromColor: $('#lightbox-overlay').css('background-color'),
                            toColor: image.color,
                            cycles: 1,
                            isFade: false
}]);
                        }

                        // Resize boxes
                        this.resizeBoxes('transition');
                        // ^ contains callback to next step

                        // Done
                        break;


                    // --------------------------------- 
                    // Display the image 
                    case 3:
						
						
						
                        // Hide loading
                        $('#lightbox-loading').hide();

                        // Animate image
						if ($.params_to_json(image.src).type != "flash") {
							$('#lightbox-image').fadeIn(350, function(){
								$.Lightbox.showImage(null, 4);
							});
						}
						else {
							this.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
                        $('#lightbox-caption').html(image.title || 'Untitled'); //.attr('href', image.src);
                        
                        // Image download links
						if ($.params_to_json(image.src).lo) {
							$('#lightbox-download-low').html('Low resolution').attr('href', $.params_to_json(image.src).lo);
						}
                        if ($.params_to_json(image.src).hi) {
							$('#lightbox-download-high').html('High resolution').attr('href', $.params_to_json(image.src).hi);  
						}
						// If no GET vars for download, hide download text
						if (!$.params_to_json(image.src).lo && !$.params_to_json(image.src).hi) {
							$('#lightbox-download').hide();
						}
						else {
							$('#lightbox-download').show();
						}
                        
                        // 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

                        $('#lightbox-infoFooter').show();


                        // ---------------------------------
                        // 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();
						
						// Show close
						$('#lightbox-close').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
