(function($) {
    $.fn.viewer = function(method) {
        if ( methods[method] ) {
            return methods[ method ].apply( this, Array.prototype.slice.call( arguments, 1 ));
        } else if ( typeof method === 'object' || ! method ) {
            return methods.init.apply( this, arguments );
        } else {
            $.error( 'Method ' +  method + ' does not exist on jQuery.viewer' );
        }
    };
    
    var vars = {
        v : $(),
        i : $(),
        c : $(),
        firstRun : true,
        overlay  : $('<div id="viewer_overlay" />')
    };
    
    var methods = {
        init : function(options) {
            var o = $.extend({
                'slideshow' : '.parsel_slideshow',
                'images'    : '.parsel_slideshow_images',
            }, options);

            return this;
        },
        
        bind : function() {
            $(window).bind('keydown.viewer', methods.keydown);
            $(window).bind('keyup.viewer', methods.keyup);
            $(vars.v).bind('click.viewer', methods.destroy);
        },
        
        invoke : function(i, s, o) {        
            if (o === undefined) {
                var o = {
                    'slideshow' : '.parsel_slideshow',
                    'images'    : '.parsel_slideshow_images',
                }; 
            }
            
            if (s === undefined)
                s = this;

            if (i === undefined)
                i = 0;
        
            var orig = s.children(o.slideshow);
            vars.v = orig.clone();
            vars.c = orig.children(o.images);
            vars.i = vars.v.children(o.images);
            
            
            vars.v.addClass('viewer').children('nav').css('background', 'transparent');
            vars.i.addClass('viewer_images');
                        
            vars.v.find('img', o.images).each(function() {
                $(this).attr('style', '');
            });
            
            vars.v.find('.parsel_slideshow_pager').parent().remove();
            
            $('body').addClass('noscroll');            
            
            orig.after(vars.overlay);
            
            setTimeout(function() { methods.showOverlay() }, 1);
            setTimeout(function() { methods.show(i, o) }, 250);
        },
        
        showOverlay : function() {
            vars.overlay.addClass('visible');
        },
        
        show : function(i, o) {
            vars.overlay.before(vars.v);
            
            if (!$.browser.mozilla) {
                vars.i.css('top', '420px');
            } else {
                vars.i.css('top', '20px');
            }
            
            vars.v.addClass('fly_down');
            
            vars.i.children().wrap('<div class="inner_wrapper" />');
            setTimeout(function() { vars.i.children('.inner_wrapper:nth-child(' + (i+1) + ')').css('left', '50%') }, 1);
                        
            var before = function(c, n) {
                n = $(n);
                c = $(c);

                // Juggle the `current` class so we know which slide is being shown.
                c.removeClass('current');
                n.addClass('current');
                
                if (!vars.firstRun && c.index() < n.index()) {
                    $('nav .parsel_slideshow_next a', vars.v).addClass('selected');
                    
                    setTimeout(function() {
                        $('nav .parsel_slideshow_next a', vars.v).removeClass('selected') 
                    }, 200);
                }
                vars.v.animate({ scrollTop: 0 }, 'slow');
                vars.firstRun = false;
            }
            
            vars.i.children().each(function() {
                var w = $(this).children().attr('data-width');
                $(this).css('margin-left', (w/2)*-1 + 'px');
            });
            
            vars.i.cycleMod({
                fx      : "scrollHorz",
                before  : before,
                after   : function(c, n) {
                    n = $(n);
                    c = $(c);
                    
                    var nextImage = n.children();
                    var w = nextImage.attr('data-width');
                    var h = nextImage.attr('data-height');
                   
                    var setDimensions = function() {
                        n.height(h);
                        n.width(w);
                    }
                    
                    setTimeout(function() { setDimensions() }, 1);
                    
                    vars.i.height(h);
                },
                height: null,
                timeout: 0,
                next: vars.v.parent().find('.parsel_slideshow_next'),
                prev: vars.v.parent().find('.parsel_slideshow_prev'),
                startingSlide : i
            });
            
            methods.bind();
        },

        destroy : function() {
            $('body').removeClass('noscroll');
            vars.v.addClass('down_and_out');
            vars.overlay.removeClass('visible');
            
            $(window).unbind('.viewer');
            $(vars.v).unbind('.viewer');
            
            var index = $('.current', vars.i).index();
            vars.c.cycle(index);
            
            setTimeout(function() { vars.v.remove(); vars.overlay.remove() }, 1000);
        },
        
        keydown : function(e) {
            var hasViewer = (vars.v.length != 0) ? true : false;
        
            if (hasViewer) {                
                if (e.keyCode == 37) {
                    if (vars.v.scrollTop() > 0) {
                        vars.v.animate({ scrollTop: 0 }, 'slow', function() {
                            vars.i.cycleMod('prev');
                        });
                    } else {
                        vars.i.cycleMod('prev');
                    }
                    
                    $('nav .parsel_slideshow_prev a', vars.v).addClass('selected');
                    return false;
                }
                
                if (e.keyCode == 39) {                    
                    if (vars.v.scrollTop() > 0) {
                        vars.v.animate({ scrollTop: 0 }, 'slow', function() {
                            vars.i.cycleMod('next');
                        });
                    } else {
                        vars.i.cycleMod('next');
                    }
                    
                    $('nav .parsel_slideshow_next a', vars.v).addClass('selected');
                    return false;
                }
                
                if (e.keyCode == 27) {
                    methods.destroy();
                    return false;
                }
            }   
        },
        
        keyup : function() {
            var hasViewer = (vars.v.length != 0) ? true : false;
    
            if (hasViewer) {
                $('nav .parsel_slideshow_prev a', vars.v).removeClass('selected');
                $('nav .parsel_slideshow_next a', vars.v).removeClass('selected');
            }
        }
    }
})(jQuery);

