/**
 * jQuery based Media Carousel
 * Copyright (c) 2010 Creuna Norge
 * 
 * Customized for Rottefella
 * 
 * Based on AD Gallery (v. 1.2.2):
 * Copyright (c) 2009 Anders Ekdahl (http://coffeescripter.com/)
 * Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php)
 * and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses.
 */

(function($) {

    $.fn.mcGallery = function(options) {
        var defaults = {
            loader_image: '/web/images/media-carousel/mc_loader.gif',
            start_at_index: 0,
            thumb_opacity: 0.5,
            animate_first_image: false,
            animation_speed: 500,
            width: false,
            height: false,
            display_next_and_prev: true,
            display_back_and_forward: true,
            display_info: true,
            scroll_jump: 0, // If 0, it jumps the width of the container
            slideshow: {
                enable: true,
                autostart: false,
                speed: 7000,
                start_label: 'START',
                stop_label: 'PAUSE',
                stop_on_scroll: true,
                display_number: true,
                countdown_prefix: '(',
                countdown_sufix: 's)',
                onStart: false,
                onStop: false
            },
            effect: 'slide-hori', // slide-hori / slide-vert / fade / resize / none
            enable_keyboard_move: true,
            cycle: true,
            callbacks: {
                init: false,
                afterImageVisible: false,
                beforeImageVisible: false
            },
            flash_autoplay: false
        };

        var settings = $.extend(false, defaults, options);

        if (options && options.slideshow) {
            settings.slideshow = $.extend(false, defaults.slideshow, options.slideshow);
        }

        if (!settings.slideshow.enable) {
            settings.slideshow.autostart = false;
        }

        var galleries = [];
        $(this).each(function() {
            var gallery = new McGallery(this, settings);
            galleries[galleries.length] = gallery;
        });

        // Sorry, breaking the jQuery chain because the gallery instances
        // are returned so you can fiddle with them
        return galleries;
    }

    // Slide vertical to next/previous media
    function VerticalSlideAnimation(img_container, direction, info) {
        var current_top = parseInt(img_container.css('top'), 10);

        if (direction == 'left') {
            var old_image_top = '-' + this.image_wrapper_height + 'px';
            img_container.css('top', this.image_wrapper_height + 'px');
        } else {
            var old_image_top = this.image_wrapper_height + 'px';
            img_container.css('top', '-' + this.image_wrapper_height + 'px');
        }

        return {
            old_image: {
                top: old_image_top
            },
            new_image: {
                top: current_top
            }
        }
    }

    // Slide horisontal to next/previous media
    function HorizontalSlideAnimation(img_container, direction, info) {
        var current_left = parseInt(img_container.css('left'), 10);

        if (direction == 'left') {
            var old_image_left = '-' + this.image_wrapper_width + 'px';
            img_container.css('left', this.image_wrapper_width + 'px');
        } else {
            var old_image_left = this.image_wrapper_width + 'px';
            img_container.css('left', '-' + this.image_wrapper_width + 'px');
        }

        return {
            old_image: {
                left: old_image_left
            },
            new_image: {
                left: current_left
            }
        }
    }

    // Resize in center to next/previous media
    function ResizeAnimation(img_container, direction, info) {
        var image_width = img_container.width();
        var image_height = img_container.height();
        var current_left = parseInt(img_container.css('left'), 10);
        var current_top = parseInt(img_container.css('top'), 10);
        img_container.css({
            width: 0,
            height: 0,
            top: this.image_wrapper_height / 2,
            left: this.image_wrapper_width / 2
        });
        return {
            old_image: {
                width: 0,
                height: 0,
                top: this.image_wrapper_height / 2,
                left: this.image_wrapper_width / 2
            },
            new_image: {
                width: image_width,
                height: image_height,
                top: current_top,
                left: current_left
            }
        }
    }

    // Fade to next/previous media
    function FadeAnimation(img_container, direction, info) {
        img_container.css('opacity', 0);
        return {
            old_image: {
                opacity: 0
            },
            new_image: {
                opacity: 1
            }
        }
    }

    // Jump to next/previous media without any transition
    function NoneAnimation(img_container, direction, info) {
        img_container.css('opacity', 0);
        return {
            old_image: {
                opacity: 0
            },
            new_image: {
                opacity: 1
            },
            speed: 0
        }
    }

    function McGallery(wrapper, settings) {
        this.init(wrapper, settings);
    }

    McGallery.prototype = {
        // Elements
        wrapper: false,
        image_wrapper: false,
        gallery_info: false,
        nav: false,
        loader: false,
        preloads: false,
        thumbs_wrapper: false,
        scroll_back: false,
        scroll_forward: false,
        next_link: false,
        prev_link: false,
        slideshow: false,
        image_wrapper_width: 0,
        image_wrapper_height: 0,
        current_index: 0,
        current_image: false,
        nav_display_width: 0,
        settings: false,
        images: false,
        in_transition: false,
        animations: false,
        init: function(wrapper, settings) {
            var context = this;
            this.wrapper = $(wrapper);
            this.settings = settings;
            this.setupElements();
            this.setupAnimations();
            if (this.settings.width) {
                this.image_wrapper_width = this.settings.width;
                this.image_wrapper.width(this.settings.width);
                this.wrapper.width(this.settings.width);
            } else {
                this.image_wrapper_width = this.image_wrapper.width();
            }
            if (this.settings.height) {
                this.image_wrapper_height = this.settings.height;
                this.image_wrapper.height(this.settings.height);
            } else {
                this.image_wrapper_height = this.image_wrapper.height();
            }
            this.nav_display_width = this.nav.width();
            this.current_index = 0;
            this.current_image = false;
            this.in_transition = false;
            this.findImages();
            if (this.settings.display_next_and_prev) {
                this.initNextAndPrev();
            }
            // The slideshow needs a callback to trigger the next image to be shown
            // but we don't want to give it access to the whole gallery instance
            var nextimage_callback = function(callback) {
                return context.nextImage(callback);
            }
            this.slideshow = new McGallerySlideshow(nextimage_callback, this.settings.slideshow);
            this.controls.append(this.slideshow.create());
            if (this.settings.slideshow.enable) {
                this.slideshow.enable();
            } else {
                this.slideshow.disable();
            }
            if (this.settings.display_back_and_forward) {
                this.initBackAndForward();
            }
            if (this.settings.enable_keyboard_move) {
                this.initKeyEvents();
            }
            var start_at = this.settings.start_at_index;
            if (window.location.hash && window.location.hash.indexOf('#mc-image') === 0) {
                start_at = window.location.hash.replace(/[^0-9]+/g, '');
                // Check if it's a number
                if ((start_at * 1) != start_at) {
                    start_at = this.settings.start_at_index;
                }
            }

            this.loading(true);
            this.showImage(start_at, function() {
                // We don't want to start the slideshow before the image has been
                // displayed
                if (context.settings.slideshow.autostart) {
                    context.preloadImage(start_at + 1);
                    context.slideshow.start();
                }
            });
            this.fireCallback(this.settings.callbacks.init);
        },
        setupAnimations: function() {
            this.animations = {
                'slide-vert': VerticalSlideAnimation,
                'slide-hori': HorizontalSlideAnimation,
                'resize': ResizeAnimation,
                'fade': FadeAnimation,
                'none': NoneAnimation
            }
        },
        setupElements: function() {
            this.controls = this.wrapper.find('.mc-controls');
            this.gallery_info = $('<p class="mc-info"></p>');
            this.controls.append(this.gallery_info);
            this.image_wrapper = this.wrapper.find('.mc-wrapper');
            this.image_wrapper.empty();
            this.nav = this.wrapper.find('.mc-nav');

            if (this.settings.carousel == false) {
                $('.mc-nav').css('height', '0');
                $('.mc-thumbs').css('height', '0');
            }

            this.thumbs_wrapper = this.nav.find('.mc-thumbs');
            this.preloads = $('<div class="mc-preloads"></div>');
            this.loader = $('<img class="mc-loader" src="' + this.settings.loader_image + '">');
            this.image_wrapper.append(this.loader);
            this.loader.hide();
            $(document.body).append(this.preloads);
        },
        loading: function(bool) {
            if (bool) {
                this.loader.show();
            } else {
                this.loader.hide();
            }
        },
        addAnimation: function(name, fn) {
            if ($.isFunction(fn)) {
                this.animations[name] = fn;
            }
        },
        findImages: function() {
            var context = this;
            this.images = [];
            var thumb_wrapper_width = 0;
            var thumbs_loaded = 0;
            var thumbs = this.thumbs_wrapper.find('a.mediaLink');
            var thumb_count = thumbs.length;
            if (this.settings.thumb_opacity < 1) {
                thumbs.find('img').css('opacity', this.settings.thumb_opacity);
            }

            // Get info from thumbnails
            thumbs.each(
				function(i) {
				    var link = $(this);
				    var thumb = link.find('img');
				    var media_type = thumb.attr('class');
				    var media_src = '/web/images/media-carousel/mc_dummy.gif';
				    var page_link = $(this).parent().find('a.pageLink').attr('href');

				    if (media_type == 'image') {
				        var media_src = link.attr('href');
				    }

				    // Check if the thumb has already loaded
				    if (!context.isImageLoaded(thumb[0])) {
				        thumb.load(function() {
				            thumb_wrapper_width += this.parentNode.parentNode.offsetWidth;
				            thumbs_loaded++;
				        });
				    } else {
				        thumb_wrapper_width += thumb[0].parentNode.parentNode.offsetWidth;
				        thumbs_loaded++;
				    }

				    link.addClass('mc-thumb' + i);
				    link.click(function() {
				        context.showImage(i);
				        context.slideshow.stop();
				        return false;
				    }).hover(function() {
				        if (!$(this).is('.mc-active') && context.settings.thumb_opacity < 1) {
				            $(this).find('img').fadeTo(300, 1);
				        }
				        context.preloadImage(i);
				    },
					function() {
					    if (!$(this).is('.mc-active') && context.settings.thumb_opacity < 1) {
					        $(this).find('img').fadeTo(300, context.settings.thumb_opacity);
					    }
					});

				    var title = false;
				    if (thumb.data('mc-title')) {
				        title = thumb.data('mc-title');
				    } else if (thumb.attr('title') && thumb.attr('title').length) {
				        title = thumb.attr('title');
				    }

				    var longdesc = false;
				    if (thumb.data('mc-longdesc')) {
				        longdesc = thumb.data('mc-longdesc');
				    } else if (thumb.attr('longdescription') && thumb.attr('longdescription').length) {
				        longdesc = thumb.attr('longdescription');
				    }

				    var number = false;
				    number = i + 1;
				    // 					if(i < 9) {
				    // 						number = '0'+ number;
				    // 					}

				    thumb.attr('id', ('img' + number));

				    if (context.settings.slideshow.display_number) {
				        link.each(function() {
				            $(this).append('<span>' + number + '<\/span>');
				        });
				    }

				    var media = false;
				    if (thumb.data('mc-media')) {
				        media = thumb.data('mc-media');
				    } else {
				        media = false;
				    }

				    var pagelink = false;
				    if (page_link && page_link.length) {
				        pagelink = page_link;
				    } else {
				        pagelink = false;
				    }

				    context.images[i] = {
				        thumb: thumb.attr('src'),
				        image: media_src,
				        type: media_type,
				        link: link.attr('href'),
				        error: false,
				        preloaded: false,
				        title: title,
				        longdesc: longdesc,
				        media: media,
				        number: number,
				        size: false,
				        pagelink: pagelink
				    };
				}
			);

            // Wait until all thumbs are loaded, and then set the width of the ul
            var inter = setInterval(function() {
                if (thumb_count == thumbs_loaded) {
                    context.nav.find('.mc-thumb-list').css('width', thumb_wrapper_width + 'px');
                    if (thumb_count < 2) {
                        context.nav.find('.mc-thumb-list').css('height', '0');
                        $('.mc-slideshow-controls').css('visibility', 'hidden');
                    }
                    clearInterval(inter);
                }
            }, 100);
        },
        initKeyEvents: function() {
            var context = this;
            $(document).keydown(
				function(e) {
				    if (e.keyCode == 39) {
				        // right arrow
				        context.nextImage();
				        context.slideshow.stop();
				    } else if (e.keyCode == 37) {
				        // left arrow
				        context.prevImage();
				        context.slideshow.stop();
				    }
				}
			);
        },
        initNextAndPrev: function() {
            this.next_link = $('<div class="mc-next"><div class="mc-next-frame"><div class="mc-next-image"><img src="' + $('#img' + (this.nextIndex() + 1)).attr('src') + '"  alt="" /></div></div></div>');
            this.prev_link = $('<div class="mc-prev"><div class="mc-prev-frame"><div class="mc-prev-image"><img src="' + $('#img' + this.images.length).attr('src') + '"  alt="" /></div></div></div>');
            this.image_wrapper.append(this.next_link);
            this.image_wrapper.append(this.prev_link);
            var context = this;
            this.prev_link.add(this.next_link).mouseenter(function(e) { 	// mouseover
                $(this).find('div').css('opacity', '1')
            }).mouseleave(function(e) { 									//mouseout
                $(this).find('div').css('opacity', '0')
            }).click(function() {
                if ($(this).is('.mc-next')) {
                    context.nextImage();
                    context.slideshow.stop();

                    if ((context.nextIndex() + 2) > context.images.length) {
                        $('.mc-next-image img').attr('src', $('#img1').attr('src')); 						// $('.mc-next-image').html(1);
                    } else {
                        $('.mc-next-image img').attr('src', $('#img' + (context.nextIndex() + 2)).attr('src')); // $('.mc-next-image').html(context.nextIndex() + 2);
                    }
                    if ((context.prevIndex() + 1) < context.images.length) {
                        $('.mc-prev-image img').attr('src', $('#img' + (context.prevIndex() + 2)).attr('src')); // $('.mc-prev-image').html(context.prevIndex() + 2);
                    } else {
                        $('.mc-prev-image img').attr('src', $('#img1').attr('src')); 						// $('.mc-prev-image').html(1);
                    }

                } else {
                    context.prevImage();
                    context.slideshow.stop();

                    if (context.nextIndex() < 1) {
                        $('.mc-next-image img').attr('src', $('#img' + context.images.length).attr('src')); 	// $('.mc-next-image').html(context.images.length);
                    } else {
                        $('.mc-next-image img').attr('src', $('#img' + context.nextIndex()).attr('src')); 	// $('.mc-next-image').html(context.nextIndex());
                    }
                    if (context.prevIndex() > 0) {
                        $('.mc-prev-image img').attr('src', $('#img' + context.prevIndex()).attr('src')); 	// $('.mc-prev-image').html(context.prevIndex());
                    } else {
                        $('.mc-prev-image img').attr('src', $('#img' + context.images.length).attr('src')); 	// $('.mc-prev-image').html(context.images.length);
                    }

                }
            }).find('div').css('opacity', '0');
        },
        initBackAndForward: function() {
            var context = this;
            this.scroll_forward = $('<div class="mc-forward"></div>');
            this.scroll_back = $('<div class="mc-back"></div>');
            this.nav.append(this.scroll_forward);
            this.nav.prepend(this.scroll_back);
            var has_scrolled = 0;
            var thumbs_scroll_interval = false;
            $(this.scroll_back).add(this.scroll_forward).click(function() {

                // Don't jump the whole width, since an image might be cut at the edge
                var width = context.nav_display_width - 50;

                if (context.settings.scroll_jump > 0) {
                    var width = context.settings.scroll_jump;
                }
                if ($(this).is('.mc-forward')) {
                    var left = context.thumbs_wrapper.scrollLeft() + width;
                } else {
                    var left = context.thumbs_wrapper.scrollLeft() - width;
                }
                if (context.settings.slideshow.stop_on_scroll) {
                    context.slideshow.stop();
                }
                context.thumbs_wrapper.animate({ scrollLeft: left + 'px' });
                return false;
            }).css('opacity', 0.6).hover(function() {
                var direction = 'left';
                if ($(this).is('.mc-forward')) {
                    direction = 'right';
                }
                thumbs_scroll_interval = setInterval(function() {
                    has_scrolled++;

                    // Don't stop the slideshow just because we scrolled a pixel or two
                    if (has_scrolled > 30 && context.settings.slideshow.stop_on_scroll) {
                        context.slideshow.stop();
                    }
                    var left = context.thumbs_wrapper.scrollLeft() + 1;
                    if (direction == 'left') {
                        left = context.thumbs_wrapper.scrollLeft() - 1;
                    }
                    context.thumbs_wrapper.scrollLeft(left);
                }, 10);
                $(this).css('opacity', 1);
            },
			function() {
			    has_scrolled = 0;
			    clearInterval(thumbs_scroll_interval);
			    $(this).css('opacity', 0.6);
			});
        },
        _afterShow: function() {
            this.gallery_info.html((this.current_index + 1) + ' / ' + this.images.length);
            if (!this.settings.cycle) {
                // Needed for IE
                this.prev_link.show().css('height', this.image_wrapper_height);
                this.next_link.show().css('height', this.image_wrapper_height);
                if (this.current_index == (this.images.length - 1)) {
                    this.next_link.hide();
                }
                if (this.current_index == 0) {
                    this.prev_link.hide();
                }
            }
            this.fireCallback(this.settings.callbacks.afterImageVisible);
        },
        // Shrink image proportionally if its bigger than its container
        _getContainedImageSize: function(image_width, image_height) {
            if (image_height > this.image_wrapper_height) {
                var ratio = image_width / image_height;
                image_height = this.image_wrapper_height;
                image_width = this.image_wrapper_height * ratio;
            }
            if (image_width > this.image_wrapper_width) {
                var ratio = image_height / image_width;
                image_width = this.image_wrapper_width;
                image_height = this.image_wrapper_width * ratio;
            }
            return {
                width: image_width,
                height: image_height
            }
        },
        // Center image if its smaller than its container
        _centerImage: function(img_container, image_width, image_height) {
            img_container.css('top', '0px');
            if (image_height < this.image_wrapper_height) {
                var dif = this.image_wrapper_height - image_height;
                img_container.css('top', (dif / 2) + 'px');
            }
            img_container.css('left', '0px');
            if (image_width < this.image_wrapper_width) {
                var dif = this.image_wrapper_width - image_width;
                img_container.css('left', (dif / 2) + 'px');
            }
        },
        // Create info box
        _getDescription: function(image) {
            var info = false;
            var img_number = '<div class="mc-info-number">' + image.number + '/' + this.images.length + '</div>';
            if (image.title.length || image.longdesc.length) {		//  || image.pagelink.length
                var title = '';
                if (image.title.length) {
                    title = '<h3 class="mc-info-title">' + image.title + '</h3>';
                }
                var longdesc = '';
                if (image.longdesc.length) {
                    longdesc = '<p>' + image.longdesc + '</p>';
                }
                var pagelink = '';
                if (image.pagelink && image.pagelink.length) {
                    pagelink = '<a href="' + image.pagelink + '"></a>';
                }
                info = $('<div class="mc-media-info">' + img_number + '<div class="mc-info-text">' + title + longdesc + '</div><div class="mc-page-link">' + pagelink + '</div></div>');
            }
            return info;
        },
        /**
        * @param function callback Gets fired when the image has loaded,
        * is displaying and it's animation has finished
        */
        showImage: function(index, callback) {
            if (this.images[index] && !this.in_transition) {
                var context = this;
                var image = this.images[index];
                this.in_transition = true;
                if (!image.preloaded) {
                    this.loading(true);
                    this.preloadImage(index, function() {
                        context.loading(false);
                        context._showWhenLoaded(index, callback);
                    });
                } else {
                    this._showWhenLoaded(index, callback);
                }
            }
        },
        /**
        * @param function callback Gets fired when the image has loaded,
        * is displaying and it's animation has finished
        */
        _showWhenLoaded: function(index, callback) {
            if (this.images[index]) {
                var context = this;
                var image = this.images[index];
                var img_container = $(document.createElement('div')).addClass('mc-image');

                // Link on images
                // 				if(image.type == 'image' && image.pagelink && image.pagelink.length) {
                // 					img_container.prepend('<a href="'+ image.pagelink +'" class="pageLink"></a>');
                // 				}

                // Index-number of media
                // 				if(image.number && this.settings.slideshow.display_number) {
                // 					img_container.append('<span class="mc-number">'+ image.number +'</span>');
                // 				}

                // Check if media is other than plain images (=else)
                if (image.type != 'image') {
                    var img = image.media;

                    // Case: YouTube video
                    if (image.type == 'youtube') {
                        var img = '<object width="' + this.settings.width + '" height="' + this.settings.height + '"><param name="wmode" value="transparent" /><param name="movie" value="' + image.link + '"><\/param><param name="allowFullScreen" value="true"><\/param><param name="allowscriptaccess" value="always"><\/param><embed src="' + image.link + '" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="' + this.settings.width + '" height="' + this.settings.height + '" wmode="transparent"><\/embed><\/object>';
                        img_container.append(img);
                        this.image_wrapper.prepend(img_container);
                    }

                    // Case: Vimeo
                    if (image.type == 'vimeo') {
                        var img = '<object width="' + this.settings.width + '" height="' + this.settings.height + '"><param name="wmode" value="transparent" /><param name="allowfullscreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="movie" value="' + image.link + '&amp;show_title=0&amp;show_byline=0&amp;show_portrait=0&amp;color=&amp;fullscreen=1" /><embed src="' + image.link + '&amp;show_title=0&amp;show_byline=0&amp;show_portrait=0&amp;color=&amp;fullscreen=1" type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" width="' + this.settings.width + '" height="' + this.settings.height + '" wmode="transparent"><\/embed><\/object>';
                        img_container.append(img);
                        this.image_wrapper.prepend(img_container);
                    }

                    // Case: Flash
                    if (image.type == 'flash') {
                        var flash_container = $(document.createElement('div')).attr('id', 'flash-player').html('<p style="z-index: 1000; display: inline-block; margin-left: ' + ((this.settings.width / 2) - 55) + 'px; margin-top: ' + ((this.settings.height / 2) - 15) + 'px;"><a href="http://www.adobe.com/go/getflashplayer"><img src="/web/images/get_flash_player.png" alt="Get Adobe Flash player" /></a></p></div>');
                        this.image_wrapper.prepend(img_container);
                        $(".mc-image").append(flash_container);

                        var fW = this.settings.width;
                        var fH = this.settings.height;
                        var fA = this.settings.flash_autoplay;

                        // Specific for Rottefella flash player
                        function doFlashElem() {
                            var flashvars = {};
                            flashvars.video = image.link;
                            flashvars.autoplay = fA;

                            var params = {};
                            params.wmode = "transparent";
                            params.allowscriptaccess = "sameDomain";

                            var attributes = {};
                            swfobject.embedSWF("/web/flash/videoplayer.swf", "flash-player", fW, fH, "10.0.0", "/web/flash/expressInstall.swf", flashvars, params, attributes);
                        }
                        doFlashElem();
                    }
                }
                else {
                    var img = $(new Image()).attr('src', image.image);
                    img_container.append(img);
                    this.image_wrapper.prepend(img_container);
                    var size = this._getContainedImageSize(image.size.width, image.size.height);
                    img.attr('width', size.width);
                    img.attr('height', size.height);
                    img_container.css({
                        width: size.width + 'px',
                        height: size.height + 'px'
                    });
                    this._centerImage(img_container, size.width, size.height);
                }
                 var info = this._getDescription(image, img_container);
                if (info && this.settings.display_info && !(image.type == 'flash')) {

                    // Append info container
                    img_container.append(info);

                    /* Fade in/out method */
                    // Append info icon
                    // 					img_container.append('<span class="mc-media-info-retriever">i</span>');
                    $('.mc-media-info-retriever').fadeIn('fast');

                    // Animate info container
                    info.css("display", "none")
						.delay(500)
						.fadeIn('fast')
						.delay((this.settings.slideshow.speed / 3) * 2)
						.fadeOut('fast');
                    $('.mc-wrapper').mouseenter(function() { // mouseover
                        info.remove();
                        img_container.append(info);
                        info.stop(true, true).fadeIn('fast')
                    }).mouseleave(function() {
                        info.stop(true, true).fadeOut('fast')
                    });

                    /* Slide up/down method 
                    var info_start_position = '-'+ info[0].offsetHeight;
                    info.css('top', info_start_position +'px');
                    var anim_speed = this.settings.animation_speed * 1.5;

					// Append info icon
                    // 					img_container.append('<span class="mc-media-info-retriever">i</span>');
                    $('.mc-media-info-retriever').animate({top: 0}, anim_speed);

					// Animate info container
                    info.animate({top: 0}, anim_speed)
                    .delay((this.settings.slideshow.speed / 3) * 2)
                    .animate({top: '-'+ info[0].offsetHeight +'px'}, anim_speed);
                    $('.mc-wrapper').mouseenter(function() { // mouseover
                    info.remove();
                    img_container.append(info);
                    info.animate({top: 0}, anim_speed)
                    }).mouseleave(function() {
                    info.animate({top: '-'+ info[0].offsetHeight +'px'}, anim_speed)
                    });
                    */

                }
                this.highLightThumb(this.nav.find('.mc-thumb' + index));

                var direction = 'right';
                if (this.current_index < index) {
                    direction = 'left';
                }
                this.fireCallback(this.settings.callbacks.beforeImageVisible);
                if (this.current_image || this.settings.animate_first_image) {
                    var animation_speed = this.settings.animation_speed;
                    var easing = 'swing';
                    var animation = this.animations[this.settings.effect].call(this, img_container, direction, info);
                    if (typeof animation.speed != 'undefined') {
                        animation_speed = animation.speed;
                    }
                    if (typeof animation.easing != 'undefined') {
                        easing = animation.easing;
                    }
                    if (this.current_image) {
                        var old_image = this.current_image;
                        old_image.animate(animation.old_image, animation_speed, easing, function() {
                            old_image.remove();
                        });
                    }
                    img_container.animate(animation.new_image, animation_speed, easing, function() {
                        context.current_index = index;
                        context.current_image = img_container;
                        context.in_transition = false;
                        context._afterShow();
                        context.fireCallback(callback);
                    });
                } else {
                    this.current_index = index;
                    this.current_image = img_container;
                    this.in_transition = false;
                    context._afterShow();
                    this.fireCallback(callback);
                }
            }
        },
        nextIndex: function() {
            if (this.current_index == (this.images.length - 1)) {
                if (!this.settings.cycle) {
                    return false;
                }
                var next = 0;
            } else {
                var next = this.current_index + 1;
            }
            return next;
        },
        nextImage: function(callback) {
            var next = this.nextIndex();
            if (next === false) return false;
            this.preloadImage(next + 1);
            this.showImage(next, callback);
            return true;
        },
        prevIndex: function() {
            if (this.current_index == 0) {
                if (!this.settings.cycle) {
                    return false;
                }
                var prev = this.images.length - 1;
            } else {
                var prev = this.current_index - 1;
            }
            return prev;
        },
        prevImage: function(callback) {
            var prev = this.prevIndex();
            if (prev === false) return false;
            this.preloadImage(prev - 1);
            this.showImage(prev, callback);
            return true;
        },
        preloadAll: function() {
            var context = this;
            var i = 0;
            function preloadNext() {
                if (i < context.images.length) {
                    i++;
                    context.preloadImage(i, preloadNext);
                }
            }
            context.preloadImage(i, preloadNext);
        },
        preloadImage: function(index, callback) {
            if (this.images[index]) {
                var image = this.images[index];
                if (!this.images[index].preloaded) {
                    var img = $(new Image());
                    img.attr('src', image.image);
                    if (!this.isImageLoaded(img[0])) {
                        this.preloads.append(img);
                        var context = this;
                        img.load(function() {
                            image.preloaded = true;
                            image.size = {
                                width: this.width,
                                height: this.height
                            }
                            context.fireCallback(callback);
                        }).error(function() {
                            image.error = true;
                            image.preloaded = false;
                            image.size = false;
                        });
                    } else {
                        image.preloaded = true;
                        image.size = {
                            width: img[0].width,
                            height: img[0].height
                        }
                        this.fireCallback(callback);
                    }
                } else {
                    this.fireCallback(callback);
                }
            }
        },
        isImageLoaded: function(img) {
            if (typeof img.complete != 'undefined' && !img.complete) {
                return false;
            }
            if (typeof img.naturalWidth != 'undefined' && img.naturalWidth == 0) {
                return false;
            }
            return true;
        },
        highLightThumb: function(thumb) {
            this.thumbs_wrapper.find('.mc-active').removeClass('mc-active');
            thumb.addClass('mc-active');
            if (this.settings.thumb_opacity < 1) {
                this.thumbs_wrapper.find('a:not(.mc-active) img').fadeTo(300, this.settings.thumb_opacity);
                thumb.find('img').fadeTo(300, 1);
            }
            var left = thumb[0].parentNode.offsetLeft;
            left -= (this.nav_display_width / 2) - (thumb[0].offsetWidth / 2);
            this.thumbs_wrapper.animate({ scrollLeft: left + 'px' });
        },
        fireCallback: function(fn) {
            if ($.isFunction(fn)) {
                fn.call(this);
            }
        }
    }

    function McGallerySlideshow(nextimage_callback, settings) {
        this.init(nextimage_callback, settings);
    }

    McGallerySlideshow.prototype = {
        start_link: false,
        stop_link: false,
        countdown: false,
        controls: false,
        settings: false,
        nextimage_callback: false,
        enabled: false,
        running: false,
        countdown_interval: false,
        init: function(nextimage_callback, settings) {
            var context = this;
            this.nextimage_callback = nextimage_callback;
            this.settings = settings;
        },
        create: function() {
            this.start_link = $('<span class="mc-slideshow-start">' + this.settings.start_label + '</span>');
            this.stop_link = $('<span class="mc-slideshow-stop">' + this.settings.stop_label + '</span>');
            this.countdown = $('<span class="mc-slideshow-countdown"></span>');
            this.controls = $('<div class="mc-slideshow-controls"></div>');
            this.controls.append(this.start_link).append(this.countdown).append(this.stop_link);
            this.countdown.hide();
            var context = this;

            this.start_link.click(function() {
                context.start();
            });

            this.stop_link.click(function() {
                context.stop();
            });
            $('.mc-wrapper').mousedown(function() {
                context.stop();
            });

            $(document).keydown(function(e) {
                if ((e.keyCode == 80) || (e.keyCode == 83)) {
                    // 's' for start/stop of 'p' for play/pause
                    if (context.running) {
                        context.stop();
                    } else {
                        context.start();
                    }
                }
            });
            return this.controls;
        },
        disable: function() {
            this.enabled = false;
            this.stop();
            this.controls.hide();
        },
        enable: function() {
            this.enabled = true;
            this.controls.show();
        },
        toggle: function() {
            if (this.enabled) {
                this.disable();
            } else {
                this.enable();
            }
        },
        start: function() {
            if (this.running || !this.enabled) return false;
            var context = this;
            this.running = true;
            this.controls.addClass('mc-slideshow-running');
            this.start_link.hide();
            this.stop_link.show();
            this._next();
            this.fireCallback(this.settings.onStart);
            return true;
        },
        stop: function() {
            if (!this.running) return false;
            this.running = false;
            this.stop_link.hide();
            this.countdown.hide();
            this.start_link.show();
            this.controls.removeClass('mc-slideshow-running');
            clearInterval(this.countdown_interval);
            this.fireCallback(this.settings.onStop);
            return true;
        },
        _next: function() {
            var context = this;
            var pre = this.settings.countdown_prefix;
            var su = this.settings.countdown_sufix;
            clearInterval(context.countdown_interval);
            this.countdown.show().html(pre + (this.settings.speed / 1000) + su);
            var slide_timer = 0;
            this.countdown_interval = setInterval(function() {
                slide_timer += 1000;
                if (slide_timer >= context.settings.speed) {
                    var whenNextIsShown = function() {

                        // Continue to next media if user has stopped the slideshow during the animation
                        if (context.running) {
                            context._next();
                        }
                        slide_timer = 0;
                    }
                    if (!context.nextimage_callback(whenNextIsShown)) {
                        context.stop();
                    }
                    slide_timer = 0;
                }
                var sec = parseInt(context.countdown.text().replace(/[^0-9]/g, ''), 10);
                sec--;
                if (sec > 0) {
                    context.countdown.html(pre + sec + su);
                }
            }, 1000);
        },
        fireCallback: function(fn) {
            if ($.isFunction(fn)) {
                fn.call(this);
            }
        }
    }
})(jQuery);
