(function($){
    $.anythingSlider = function(el, options){
        var base = this;
        base.$el = $(el).addClass('anythingBase').wrap('<div class="anythingSlider"><div class="anythingWindow" /></div>');
        base.$el.data("AnythingSlider", base);
        base.init = function(){
            base.options = $.extend({}, $.anythingSlider.defaults, options);
            base.initialized = false;
            if ($.isFunction(base.options.onBeforeInitialize)) {
                base.$el.bind('before_initialize', base.options.onBeforeInitialize);
            }
            base.$el.trigger('before_initialize', base);
            base.$wrapper = base.$el.parent().closest('div.anythingSlider').addClass('anythingSlider-' + base.options.theme);
            base.$window = base.$el.closest('div.anythingWindow');
            base.$controls = $('<div class="anythingControls"></div>').appendTo((base.options.appendControlsTo !== null && $(base.options.appendControlsTo).length) ? $(base.options.appendControlsTo) : base.$wrapper);
            base.win = window;
            base.$win = $(base.win);
            base.$nav = $('<ul class="thumbNav" />').appendTo(base.$controls);
            base.flag = false;
            base.playing = false;
            base.slideshow = false;
            base.hovered = false;
            base.panelSize = [];
            base.currentPage = base.options.startPanel = parseInt(base.options.startPanel, 10) || 1;
            base.adjustLimit = (base.options.infiniteSlides) ? 0 : 1;
            base.outerPad = [base.$wrapper.innerWidth() - base.$wrapper.width(), base.$wrapper.innerHeight() - base.$wrapper.height()];
            if (base.options.playRtl) {
                base.$wrapper.addClass('rtl');
            }
            base.original = [base.options.autoPlay, base.options.buildNavigation, base.options.buildArrows];
            if (base.options.expand) {
                base.$outer = base.$wrapper.parent();
                base.$window.css({
                    width: '100%',
                    height: '100%'
                });
                base.outerDim = [base.$outer.width(), base.$outer.height()];
                base.checkResize();
            }
            base.updateSlider();
            base.$lastPage = base.$currentPage;
            base.runTimes = $('div.anythingSlider').index(base.$wrapper) + 1;
            base.regex = new RegExp('panel' + base.runTimes + '-(\\d+)', 'i');
            if (!$.isFunction($.easing[base.options.easing])) {
                base.options.easing = "swing";
            }
            if (base.options.theme !== 'default' && !$('link[href*=' + base.options.theme + ']').length) {
                $('head').append('<link rel="stylesheet" href="' + base.options.themeDirectory.replace(/\{themeName\}/g, base.options.theme) + '" type="text/css" />');
            }
            if (base.options.pauseOnHover) {
                base.$wrapper.hover(function(){
                    if (base.playing) {
                        base.$el.trigger('slideshow_paused', base);
                        base.clearTimer(true);
                    }
                }, function(){
                    if (base.playing) {
                        base.$el.trigger('slideshow_unpaused', base);
                        base.startStop(base.playing, true);
                    }
                });
            }
            var triggers, startPanel = (base.options.hashTags) ? base.gotoHash() || base.options.startPanel : base.options.startPanel;
            base.setCurrentPage(startPanel, false);
            base.slideControls(false);
            base.$wrapper.bind('mouseenter mouseleave', function(e){
                base.hovered = (e.type === "mouseenter") ? true : false;
                base.slideControls(base.hovered, false);
            });
            if (base.options.enableKeyboard) {
                $(document).keyup(function(e){
                    if (base.$wrapper.is('.activeSlider') && !e.target.tagName.match('TEXTAREA|INPUT|SELECT')) {
                        switch (e.which) {
                            case 39:
                                base.goForward();
                                break;
                            case 37:
                                base.goBack();
                                break;
                        }
                    }
                });
            }
            triggers = "slideshow_paused slideshow_unpaused slide_init slide_begin slideshow_stop slideshow_start initialized swf_completed".split(" ");
            $.each("onShowPause onShowUnpause onSlideInit onSlideBegin onShowStop onShowStart onInitialized onSWFComplete".split(" "), function(i, o){
                if ($.isFunction(base.options[o])) {
                    base.$el.bind(triggers[i], base.options[o]);
                }
            });
            if ($.isFunction(base.options.onSlideComplete)) {
                base.$el.bind('slide_complete', function(){
                    setTimeout(function(){
                        base.options.onSlideComplete(base);
                    }, 0);
                });
            }
            base.initialized = true;
            base.$el.trigger('initialized', base);
        };
        base.updateSlider = function(){
            base.$el.find('li.cloned').remove();
            base.$nav.empty();
            base.$items = base.$el.find('> li');
            base.pages = base.$items.length;
            base.options.showMultiple = parseInt(base.options.showMultiple, 10) || 1;
            if (base.options.showMultiple > 1) {
                if (base.options.showMultiple > base.pages) {
                    base.options.showMultiple = base.pages;
                }
                base.adjustMultiple = (base.options.infiniteSlides) ? 0 : parseInt(base.options.showMultiple, 10) - 1;
                base.pages = base.$items.length - base.adjustMultiple;
            }
            if (base.pages <= 1) {
                base.options.autoPlay = false;
                base.options.buildNavigation = false;
                base.options.buildArrows = false;
                base.$controls.hide();
                base.$nav.hide();
                if (base.$forward) {
                    base.$forward.add(base.$back).hide();
                }
            }
            else {
                base.options.autoPlay = base.original[0];
                base.options.buildNavigation = base.original[1];
                base.options.buildArrows = base.original[2];
                base.$controls.show();
                base.$nav.show();
                if (base.$forward) {
                    base.$forward.add(base.$back).show();
                }
                base.buildNavigation();
                if (base.options.autoPlay) {
                    base.playing = !base.options.startStopped;
                    base.buildAutoPlay();
                }
                if (base.options.buildArrows) {
                    base.buildNextBackButtons();
                }
            }
            if (base.options.infiniteSlides && base.pages > 1) {
                base.$el.prepend(base.$items.filter(':last').clone().addClass('cloned').removeAttr('id'));
                if (base.options.showMultiple > 1) {
                    base.$el.append(base.$items.filter(':lt(' + base.options.showMultiple + ')').clone().addClass('cloned').addClass('multiple').removeAttr('id'));
                }
                else {
                    base.$el.append(base.$items.filter(':first').clone().addClass('cloned').removeAttr('id'));
                }
                base.$el.find('li.cloned').each(function(){
                    $(this).find('a,input,textarea,select').attr('disabled', 'disabled');
                    $(this).find('[id]').removeAttr('id');
                });
            }
            base.$items = base.$el.find('> li').addClass('panel');
            base.setDimensions();
            if (!base.options.resizeContents) {
                base.$win.load(function(){
                    base.setDimensions();
                });
            }
            if (base.options.resizeContents) {
                if (base.options.width) {
                    base.$items.css('width', base.options.width);
                    base.$wrapper.css('width', base.getDim(base.currentPage)[0]);
                }
                if (base.options.height) {
                    base.$wrapper.add(base.$items).css('height', base.options.height);
                }
            }
            if (base.currentPage > base.pages) {
                base.currentPage = base.pages;
                base.setCurrentPage(base.pages, false);
            }
            base.$nav.find('a').eq(base.currentPage - 1).addClass('cur');
            base.hasEmb = base.$items.find('embed[src*=youtube]').length;
            base.hasSwfo = (typeof(swfobject) !== 'undefined' && swfobject.hasOwnProperty('embedSWF') && $.isFunction(swfobject.embedSWF)) ? true : false;
            if (base.hasEmb && base.hasSwfo) {
                base.$items.find('embed[src*=youtube]').each(function(i){
                    var $tar = ($(this).parent()[0].tagName === "OBJECT") ? $(this).parent() : $(this);
                    $tar.wrap('<div id="ytvideo' + i + '"></div>');
                    swfobject.embedSWF($(this).attr('src') + '&enablejsapi=1&version=3&playerapiid=ytvideo' + i, 'ytvideo' + i, $tar.attr('width'), $tar.attr('height'), '10', null, null, {
                        allowScriptAccess: "always",
                        wmode: base.options.addWmodeToObject,
                        allowfullscreen: true
                    }, {
                        'class': $tar.attr('class'),
                        'style': $tar.attr('style')
                    }, function(){
                        if (i >= base.hasEmb - 1) {
                            base.$el.trigger('swf_completed', base);
                        }
                    });
                });
            }
            base.$items.find('a').unbind('focus').bind('focus', function(e){
                base.$items.find('.focusedLink').removeClass('focusedLink');
                $(this).addClass('focusedLink');
                var panel = $(this).closest('.panel');
                if (!panel.is('.activePage')) {
                    base.gotoPage(base.$items.index(panel));
                    e.preventDefault();
                }
            });
        };
        base.buildNavigation = function(){
            var tmp, klass, $a;
            if (base.options.buildNavigation && (base.pages > 1)) {
                base.$items.filter(':not(.cloned)').each(function(i){
                    var index = i + 1;
                    klass = ((index === 1) ? 'first' : '') + ((index === base.pages) ? 'last' : '');
                    $a = $('<a href="#"></a>').addClass('panel' + index).wrap('<li class="' + klass + '" />');
                    base.$nav.append($a.parent());
                    if ($.isFunction(base.options.navigationFormatter)) {
                        tmp = base.options.navigationFormatter(index, $(this));
                        $a.html('<span>' + tmp + '</span>');
                        if (parseInt($a.find('span').css('text-indent'), 10) < 0) {
                            $a.addClass(base.options.tooltipClass).attr('title', tmp);
                        }
                    }
                    else {
                        $a.html('<span>' + index + '</span>');
                    }
                    $a.bind(base.options.clickControls, function(e){
                        if (!base.flag && base.options.enableNavigation) {
                            base.flag = true;
                            setTimeout(function(){
                                base.flag = false;
                            }, 100);
                            base.gotoPage(index);
                            if (base.options.hashTags) {
                                base.setHash(index);
                            }
                        }
                        e.preventDefault();
                    });
                });
            }
        };
        base.buildNextBackButtons = function(){
            if (base.$forward) {
                return;
            }
            base.$forward = $('<span class="arrow forward"><a href="#"><span>' + base.options.forwardText + '</span></a></span>');
            base.$back = $('<span class="arrow back"><a href="#"><span>' + base.options.backText + '</span></a></span>');
            base.$back.bind(base.options.clickArrows, function(e){
                base.goBack();
                e.preventDefault();
            });
            base.$forward.bind(base.options.clickArrows, function(e){
                base.goForward();
                e.preventDefault();
            });
            base.$back.add(base.$forward).find('a').bind('focusin focusout', function(){
                $(this).toggleClass('hover');
            });
            base.$wrapper.prepend(base.$forward).prepend(base.$back);
            base.$arrowWidth = base.$forward.width();
        };
        base.buildAutoPlay = function(){
            if (base.$startStop || base.pages < 2) {
                return;
            }
            base.$startStop = $("<a href='#' class='start-stop'></a>").html('<span>' + (base.playing ? base.options.stopText : base.options.startText) + '</span>');
            base.$controls.prepend(base.$startStop);
            base.$startStop.bind(base.options.clickSlideshow, function(e){
                if (base.options.enablePlay) {
                    base.startStop(!base.playing);
                    if (base.playing) {
                        if (base.options.playRtl) {
                            base.goBack(true);
                        }
                        else {
                            base.goForward(true);
                        }
                    }
                }
                e.preventDefault();
            }).bind('focusin focusout', function(){
                $(this).toggleClass('hover');
            });
            base.startStop(base.playing);
        };
        base.checkResize = function(stopTimer){
            clearTimeout(base.resizeTimer);
            base.resizeTimer = setTimeout(function(){
                var w = base.$outer.width(), h = (base.$outer[0].tagName === "BODY") ? base.$win.height() : base.$outer.height(), dim = base.outerDim;
                if (dim[0] !== w || dim[1] !== h) {
                    base.outerDim = [w, h];
                    base.setDimensions();
                    base.gotoPage(base.currentPage, base.playing, null, 1);
                }
                if (typeof(stopTimer) === 'undefined') {
                    base.checkResize();
                }
            }, 500);
        };
        base.setDimensions = function(){
            var w, h, c, cw, dw, leftEdge = 0, bww = (base.options.showMultiple > 1) ? base.options.width || base.$window.width() / base.options.showMultiple : base.$window.width(), winw = base.$win.width();
            if (base.options.expand) {
                w = base.$outer.width() - base.outerPad[0];
                h = base.$outer.height() - base.outerPad[1];
                base.$wrapper.add(base.$window).add(base.$items).css({
                    width: w,
                    height: h
                });
                bww = (base.options.showMultiple > 1) ? w / base.options.showMultiple : w;
            }
            base.$items.each(function(i){
                c = $(this).children('*');
                if (base.options.resizeContents) {
                    w = parseInt(base.options.width, 10) || bww;
                    h = parseInt(base.options.height, 10) || base.$window.height();
                    $(this).css({
                        width: w,
                        height: h
                    });
                    if (!base.initialized && c.length === 1) {
                        c.css({
                            width: '100%',
                            height: '100%'
                        });
                        if (c[0].tagName === "OBJECT") {
                            c.find('embed').andSelf().attr({
                                width: '100%',
                                height: '100%'
                            });
                        }
                    }
                }
                else {
                    w = $(this).width();
                    dw = (w >= winw) ? true : false;
                    if (c.length === 1 && dw) {
                        cw = (c.width() >= winw) ? bww : c.width();
                        $(this).css('width', cw);
                        c.css('max-width', cw);
                        w = cw;
                    }
                    w = (dw) ? base.options.width || bww : w;
                    $(this).css('width', w);
                    h = $(this).outerHeight();
                    $(this).css('height', h);
                }
                base.panelSize[i] = [w, h, leftEdge];
                leftEdge += w;
            });
            base.$el.css('width', (leftEdge < base.options.maxOverallWidth) ? leftEdge : base.options.maxOverallWidth);
        };
        base.getDim = function(page){
            page = (base.options.infiniteSlides) ? page : page - 1;
            var i, w = base.panelSize[page][0], h = base.panelSize[page][1];
            if (base.options.showMultiple > 1) {
                for (i = 1; i < base.options.showMultiple; i++) {
                    w += base.panelSize[(page + i) % base.options.showMultiple][0];
                    h = Math.max(h, base.panelSize[page + i][1]);
                }
            }
            return [w, h];
        };
        base.gotoPage = function(page, autoplay, callback, time){
            if (base.pages <= 1) {
                return;
            }
            base.$lastPage = base.$currentPage;
            if (typeof(page) !== "number") {
                page = base.options.startPanel;
                base.setCurrentPage(page);
            }
            if (base.hasEmb && base.checkVideo(base.playing)) {
                return;
            }
            if (page > base.pages + 1 - base.adjustLimit) {
                page = (!base.options.infiniteSlides && !base.options.stopAtEnd) ? 1 : base.pages;
            }
            if (page < base.adjustLimit) {
                page = (!base.options.infiniteSlides && !base.options.stopAtEnd) ? base.pages : 1;
            }
            base.currentPage = (page > base.pages) ? base.pages : (page < 1) ? 1 : base.currentPage;
            base.$currentPage = base.$items.eq(base.currentPage - 1);
            base.exactPage = page;
            base.$el.trigger('slide_init', base);
            base.slideControls(true, false);
            if (autoplay !== true) {
                autoplay = false;
            }
            if (!autoplay || (base.options.stopAtEnd && page === base.pages)) {
                base.startStop(false);
            }
            base.$el.trigger('slide_begin', base);
            if (!base.options.resizeContents) {
                var d = base.getDim(page);
                base.$wrapper.filter(':not(:animated)').animate({
                    width: d[0],
                    height: d[1]
                }, {
                    queue: false,
                    duration: time || base.options.animationTime,
                    easing: base.options.easing
                });
            }
            base.$el.filter(':not(:animated)').animate({
                left: -base.panelSize[(base.options.infiniteSlides) ? page : page - 1][2]
            }, {
                queue: false,
                duration: time || base.options.animationTime,
                easing: base.options.easing,
                complete: function(){
                    base.endAnimation(page, callback);
                }
            });
        };
        base.endAnimation = function(page, callback){
            if (page === 0) {
                base.$el.css('left', -base.panelSize[base.pages][2]);
                page = base.pages;
            }
            else 
                if (page > base.pages) {
                    base.$el.css('left', -base.panelSize[1][2]);
                    page = 1;
                }
            base.exactPage = page;
            base.setCurrentPage(page, false);
            base.$items.removeClass('activePage').eq(page - base.adjustLimit).addClass('activePage');
            if (!base.hovered) {
                base.slideControls(false);
            }
            if (base.hasEmb) {
                var emb = base.$currentPage.find('object[id*=ytvideo], embed[id*=ytvideo]');
                if (emb.length && $.isFunction(emb[0].getPlayerState) && emb[0].getPlayerState() > 0 && emb[0].getPlayerState() !== 5) {
                    emb[0].playVideo();
                }
            }
            base.$el.trigger('slide_complete', base);
            if (typeof callback === 'function') {
                callback(base);
            }
            if (base.options.autoPlayLocked && !base.playing) {
                setTimeout(function(){
                    base.startStop(true);
                }, base.options.resumeDelay - base.options.delay);
            }
        };
        base.setCurrentPage = function(page, move){
            if (base.pages <= 1) {
                return;
            }
            page = parseInt(page, 10);
            if (page > base.pages + 1 - base.adjustLimit) {
                page = base.pages - base.adjustLimit;
            }
            if (page < base.adjustLimit) {
                page = 1;
            }
            if (base.options.buildNavigation) {
                base.$nav.find('.cur').removeClass('cur');
                base.$nav.find('a').eq(page - 1).addClass('cur');
            }
            if (!base.options.infiniteSlides && base.options.stopAtEnd) {
                base.$wrapper.find('span.forward')[page === base.pages ? 'addClass' : 'removeClass']('disabled');
                base.$wrapper.find('span.back')[page === 1 ? 'addClass' : 'removeClass']('disabled');
                if (page === base.pages && base.playing) {
                    base.startStop();
                }
            }
            if (!move) {
                var d = base.getDim(page);
                base.$wrapper.css({
                    width: d[0],
                    height: d[1]
                });
                base.$wrapper.scrollLeft(0);
                base.$el.css('left', -base.panelSize[(base.options.infiniteSlides) ? page : page - 1][2]);
            }
            base.currentPage = page;
            base.$currentPage = base.$items.eq(page).addClass('activePage');
            if (!base.$wrapper.is('.activeSlider')) {
                $('.activeSlider').removeClass('activeSlider');
                base.$wrapper.addClass('activeSlider');
            }
        };
        base.goForward = function(autoplay){
            if (autoplay !== true) {
                autoplay = false;
                base.startStop(false);
            }
            base.gotoPage(base.currentPage + 1, autoplay);
        };
        base.goBack = function(autoplay){
            if (autoplay !== true) {
                autoplay = false;
                base.startStop(false);
            }
            base.gotoPage(base.currentPage - 1, autoplay);
        };
        base.gotoHash = function(){
            var n = base.win.location.hash.match(base.regex);
            return (n === null) ? '' : parseInt(n[1], 10);
        };
        base.setHash = function(n){
            var s = 'panel' + base.runTimes + '-', h = base.win.location.hash;
            if (typeof h !== 'undefined') {
                base.win.location.hash = (h.indexOf(s) > 0) ? h.replace(base.regex, s + n) : h + "&" + s + n;
            }
        };
        base.slideControls = function(toggle){
            var dir = (toggle) ? 'slideDown' : 'slideUp', t1 = (toggle) ? 0 : base.options.animationTime, t2 = (toggle) ? base.options.animationTime : 0, op = (toggle) ? 1 : 0, sign = (toggle) ? 0 : 1;
            if (base.options.toggleControls) {
                base.$controls.stop(true, true).delay(t1)[dir](base.options.animationTime / 2).delay(t2);
            }
            if (base.options.buildArrows && base.options.toggleArrows) {
                if (!base.hovered && base.playing) {
                    sign = 1;
                    op = 0;
                }
                base.$forward.stop(true, true).delay(t1).animate({
                    right: sign * base.$arrowWidth,
                    opacity: op
                }, base.options.animationTime / 2);
                base.$back.stop(true, true).delay(t1).animate({
                    left: sign * base.$arrowWidth,
                    opacity: op
                }, base.options.animationTime / 2);
            }
        };
        base.clearTimer = function(paused){
            if (base.timer) {
                base.win.clearInterval(base.timer);
                if (!paused && base.slideshow) {
                    base.$el.trigger('slideshow_stop', base);
                    base.slideshow = false;
                }
            }
        };
        base.startStop = function(playing, paused){
            if (playing !== true) {
                playing = false;
            }
            if (playing && !paused) {
                base.$el.trigger('slideshow_start', base);
                base.slideshow = true;
            }
            base.playing = playing;
            if (base.options.autoPlay) {
                base.$startStop.toggleClass('playing', playing).html('<span>' + (playing ? base.options.stopText : base.options.startText) + '</span>');
                if (parseInt(base.$startStop.find('span').css('text-indent'), 10) < 0) {
                    base.$startStop.addClass(base.options.tooltipClass).attr('title', playing ? 'Stop' : 'Start');
                }
            }
            if (playing) {
                base.clearTimer(true);
                base.timer = base.win.setInterval(function(){
                    if (!(base.hasEmb && base.checkVideo(playing))) {
                        if (base.options.playRtl) {
                            base.goBack(true);
                        }
                        else {
                            base.goForward(true);
                        }
                    }
                }, base.options.delay);
            }
            else {
                base.clearTimer();
            }
        };
        base.checkVideo = function(playing){
            var emb, ps, stopAdvance = false;
            base.$items.find('object[id*=ytvideo], embed[id*=ytvideo]').each(function(){
                emb = $(this);
                if (emb.length && $.isFunction(emb[0].getPlayerState)) {
                    ps = emb[0].getPlayerState();
                    if (playing && (ps === 1 || ps > 2) && base.$items.index(emb.closest('li.panel')) === base.currentPage && base.options.resumeOnVideoEnd) {
                        stopAdvance = true;
                    }
                    else {
                        if (ps > 0) {
                            emb[0].pauseVideo();
                        }
                    }
                }
            });
            return stopAdvance;
        };
        base.init();
    };
    $.anythingSlider.defaults = {
        width: null,
        height: null,
        expand: false,
        resizeContents: true,
        showMultiple: false,
        tooltipClass: 'tooltip',
        theme: 'default',
        themeDirectory: 'css/theme-{themeName}.css',
        startPanel: 1,
        hashTags: true,
        infiniteSlides: true,
        enableKeyboard: true,
        buildArrows: true,
        toggleArrows: false,
        buildNavigation: true,
        enableNavigation: true,
        toggleControls: false,
        appendControlsTo: null,
        navigationFormatter: null,
        forwardText: "&raquo;",
        backText: "&laquo;",
        enablePlay: true,
        autoPlay: true,
        autoPlayLocked: false,
        startStopped: false,
        pauseOnHover: true,
        resumeOnVideoEnd: true,
        stopAtEnd: false,
        playRtl: false,
        startText: "Start",
        stopText: "Stop",
        delay: 3000,
        resumeDelay: 15000,
        animationTime: 600,
        easing: "swing",
        clickArrows: "click",
        clickControls: "click focusin",
        clickSlideshow: "click",
        addWmodeToObject: "opaque",
        maxOverallWidth: 32766
    };
    $.fn.anythingSlider = function(options, callback){
        return this.each(function(){
            var page, anySlide = $(this).data('AnythingSlider');
            if ((typeof(options)).match('object|undefined')) {
                if (!anySlide) {
                    (new $.anythingSlider(this, options));
                }
                else {
                    anySlide.updateSlider();
                }
            }
            else 
                if (/\d/.test(options) && !isNaN(options) && anySlide) {
                    page = (typeof(options) === "number") ? options : parseInt($.trim(options), 10);
                    if (page >= 1 && page <= anySlide.pages) {
                        anySlide.gotoPage(page, false, callback);
                    }
                }
        });
    };
})(jQuery);

