(function($) {
    $.fn.fadeNav = function(opt) {
        var container = $(this),  // container holds the images
        
            defaults = {
                caption: null, 
                navigation: null,           // element to hold the navigation controls
                speed: 600,                 // speed of the cross-fade between images
                easing: 'swing',            // animation easing for cross-fade
                slideshow: false,           // slideshow mode
                slideshow_timeout: 8000,     // time between slides in slideshow mode
                protect: true
            },
            o = $.extend({}, defaults, opt),
            
            cur = 0;        // references the index of the visible image
        
        
        // Set up required styles
        var images = container.find('img').css({opacity: 0}).parent().css({
            position: 'absolute', top: 0, left: 0
        }).addClass('fadenav').hide().end();
        
        if (o.protect) {
            images.parent().each(function() {
                $('<img/>', {
                    src: webroot + 'img/blank.gif'
                }).css({
                    position: 'absolute', display: 'block',
                    top: 0, left: 0, zIndex: 100,
                    width: '100%', height: '100%'
                }).appendTo(this);
            });
        }

        container.css({
            position: 'relative'
        });

        var img_sources = $.map(images, function(img) {
            var p = $(img).parent();
            var src = p.attr('href');
            p.attr('href', '#');
            return src || $(img).attr('src');
        });

        // Set up navigation controls
        var nav = o.navigation || $('<div class="image-nav"></div>').appendTo(container),
            nav_container = $('<div class="wrapper"></div>').appendTo(nav),
            title = $('<h2></h2>').hide().appendTo(nav),
            prev = $('<a class="image-prev prev">prev</a>').appendTo(nav_container),
            next = $('<a class="image-next next">next</a>').appendTo(nav_container),
            caption = o.caption || $('<div class="image-caption"></div>').hide().appendTo(nav);

        if (images.length < 2) nav_container.hide();
    
        // Image getter
        var index = function(n) {
            return (n + images.length ) % images.length
        }
        
        // Image loading
        var preload = function(n) {
            n = index(n);
            var img = images.eq(n).attr('src', img_sources[n]);
        }
        
        // Switching images
        var show = function(n, speed) {
            var last = cur; cur = index(n);
            var img = images.eq(cur);
            speed = speed == null ? o.speed : speed;

            if (!img.attr('src')) preload(cur);

            container.trigger('fadeNav-startshow', [cur, last]);
                        
            // Show the new current image.
            var title_text = img.attr('title');
            if (title_text) title.text(title_text).show();
            else title.hide();
            var caption_text = img.attr('alt');
            if (caption_text) caption.empty().html(caption_text).show();
            else caption.empty().hide()
            images.eq(last).stop().animate({
                opacity: 0
            }, speed, o.easing, function() {
                $(this).parent().hide();
            });
            images.eq(cur).stop().parent().show().end().animate({
                opacity: 1
            }, speed, o.easing, function() {
                container.trigger('fadeNav-endshow', [cur, last]);
                
                // Preload images on either side of current.
                for (i=cur; i < cur + 2; i++ ) {
                    preload(i);
                }
                i = cur - 1;
                for (i = cur-1; i > cur-2; i--) {
                    preload(i);
                }
            });
        }

        
        // Load event positions images and shows the first image.
        preload(cur);
        $(window).load(function() {
            show(cur);
        });
        container.bind('fadeNav-show', function(e, n) {
            show(n);
        });

        // Navigation Events
        prev.click(function() { show(cur-1); return false; });
        next.click(function() { show(cur+1); return false; });
        if (images.length > 1) {
            images.parent().click(function() { 
               show(cur+1); return false; 
            });
        } else {
            images.parent().css({
                cursor: 'default'
            }).click(function() {return false; });
        }
        
        
        // If in slideshow mode, start the show...
        if (o.slideshow) {
            var t = setInterval(function() {
                show(cur+1);
            }, o.slideshow_timeout);
        }

        // Videos
        var video_players = [];

        $('.video').click(function(e) {
            e.stopPropagation();
            return false;
        });

        container.bind('fadeNav-startshow', function(e, cur, last) {
            if (video_players[last]) {
                try {
                    video_players[last].pause();
                } catch(e) {}
            }
            $('a.play').hide();
            $('.video').hide();
            
        });

        container.bind('fadeNav-endshow', function(e, cur, last) {
            var img = $(images[cur]);
            var video_div = img.parent().find('.video');

            if (!video_div.length) return;

            var video = video_div.find('video');
            var video_src = video.attr('loadsrc');

            // Set up play button
            var play_button = img.parent().find('a.play');
            if (!play_button.length) {
                play_button = $('<a class="play">&nbsp;</a>').appendTo(img.parent()).css({
                    position: 'absolute', 
                    top: (img.attr('height') - 116) / 2,
                    left: '50%', marginLeft: 0 - 116 / 2
                })
            }

            play_button.show().click(function(e) {
                var img_width = img.attr('width'),
                    img_height = img.attr('height');
                
                // Show the current video container and play button
                video_div.show();
                play_button.hide();

                if (!video_players[cur]) {
                    video_div.css({
                        left: (img.parent().width() - img_width) / 2
                    }); 

                    // Set src
                    video.attr('src', video_src);
                    video_players[cur] = new MediaElementPlayer(video, {
                        enableAutosize: false,
                        success: function(mediaElement, dom) {
                            mediaElement.addEventListener('loadedmetadata', function(e) {
                                // Set size, but not smaller than video area.
                                var w = mediaElement.videoWidth,
                                    h = mediaElement.videoHeight;

                                if (!(w && h)) return;

                                if (w > img.parent().width()) {
                                    w = img.parent().width();
                                    h = (w / mediaElement.videoWidth) * h;
                                } else if (w < img_width) {
                                    w = img_width;
                                    h = (w / mediaElement.videoWidth) * h;
                                }
                                video_div.css({
                                    width: w,
                                    height: h
                                }).css({
                                    left: (img.parent().width() - w) / 2
                                });

                                video_players[cur].setPlayerSize(w, h);
                                video_players[cur].setControlsSize();
                                mediaElement.setVideoSize(w, h);
                            }, false);

                            // Start playing the video
                            mediaElement.load();
                            mediaElement.play();
                        }
                    });
                } else {
                    setTimeout(function() {
                        try {
                            video_players[cur].play();
                        } catch(e) {}
                    }, 300);
                }

                e.stopPropagation();
                return false;
            });
        });

        return this;
    }
})(jQuery);

