(function($) {
    $.fn.nextSlide = function() {
        // get slide index and count
        var ss = $(this);
        var slideIndex = parseInt(ss.data("SlideIndex"));
        var slideCount = parseInt(ss.data("SlideCount"));
        var slidePlaylist = ss.data("SlidePlaylist");
        var slideState = ss.data("ShowState");

        var newSlideIndex = (slideIndex + 1) % slideCount;
        return ss.goToSlide(newSlideIndex);
    };

    $.fn.prevSlide = function() {
        // get slide index and count
        var ss = $(this);
        var slideIndex = parseInt(ss.data("SlideIndex"));
        var slideCount = parseInt(ss.data("SlideCount"));
        var slidePlaylist = ss.data("SlidePlaylist");
        var slideState = ss.data("ShowState");

        var newSlideIndex = (slideIndex - 1);
        if (newSlideIndex < 0) newSlideIndex += slideCount;

        return ss.goToSlide(newSlideIndex);
    };

    $.fn.dimPageButton = function() { $(this).css({ border: "1px solid #CCC" }); }
    $.fn.highlightPageButton = function() { $(this).css({ border: "1px solid #888" }); }

    $.fn.goToSlide = function(newSlideIndex) {
        return this.each(function() {
            // get slide index and count
            var ss = $(this);
            var slideIndex = parseInt(ss.data("SlideIndex"));
            var slideCount = parseInt(ss.data("SlideCount"));
            var slidePlaylist = ss.data("SlidePlaylist");
            var slideState = ss.data("ShowState");
            var options = ss.data("Options");

            ss.stopTime("slideanims");
            if ((slideState == "playing" || slideState == "paused") && slideIndex != newSlideIndex) {
                // pick our new slide
                var slides = ss.children();

                if (newSlideIndex >= 0 && newSlideIndex < slideCount) {
                    // get the elements for old and new slides
                    var oldSlide = slides.eq(slidePlaylist[slideIndex]);
                    var newSlide = slides.eq(slidePlaylist[newSlideIndex]);

                    // swap z-indexes around so new slide is always on top
                    oldSlide.css("z-index", options.zIndexBottom);
                    newSlide.css("z-index", options.zIndexTop);

                    // do the fade
                    oldSlide.stop(true, true).fadeOut(options.fadeLength);
                    newSlide.stop(true, true).fadeIn(options.fadeLength);

                    if (options.showPageSelect) {
                        ss.find(".SlidePage").dimPageButton();
                        ss.find(".SlidePage:eq(" + newSlideIndex + ")").highlightPageButton();
                    }

                    // save our current slide index
                    ss.data("SlideIndex", newSlideIndex);
                }

                if (slideState == "playing") {
                    ss.oneTime(options.slideLength, "slideanims", function() {
                        $(this).nextSlide();
                    });
                }
            }
        });
    };

    $.fn.slidey = function(options) {
        var defaults = {
            // how long a slide will display for
            slideLength: 10000,
            // length of the fade transition
            fadeLength: 500,
            // z-index of the "top" slide during the fade transition
            zIndexTop: 10,
            // z-index of the "bottom" slide during the fade transition
            zIndexBottom: 9,
            // ordering: "Sequential" / "Random" / "FirstThenRandom"
            ordering: "Sequential",
            // whether or not to show the play controls
            showPlayControls: true,
            // whether or not to show next/previous buttons
            showNextBack: true,
            // whether or not to show page number buttons
            showPageSelect: true
        };
        var options = $.extend(defaults, options);

        return this.each(function() {
            var obj = $(this);
            var slides = obj.children();

            // stack all slides on top of each other
            obj.css("position", "relative");
            slides.css("position", "absolute").css("top", "0px").css("left", "0px");

            // set our initial slide index and slide count for future reference
            obj.data("SlideIndex", 0).data("SlideCount", slides.length);

            // start out sorted
            var SlidePlaylist = new Array();
            for (var i = 0; i < slides.length; i++)
                SlidePlaylist[i] = i;

            // shuffle the playlist if random
            if (options.ordering.toLowerCase() == "random" || options.ordering.toLowerCase() == "firstthenrandom") {
                SlidePlaylist.sort(function(a, b) {
                    if (options.ordering.toLowerCase() == "firstthenrandom") {
                        if (a == 0) return -1;
                        else if (b == 0) return 1;
                    }
                    if (Math.random() > 0.5)
                        return -1;
                    else
                        return 1;
                });
            }
            obj.data("SlidePlaylist", SlidePlaylist);
            obj.data("ShowState", "playing");
            obj.data("Options", options);

            // hide all slides
            slides.css("display", "none").css("z-index", options.zIndexBottom);
            // show first slide
            slides.eq(SlidePlaylist[0]).css("display", "");

            // get the widest and tallest our slideshow should be
            var topWidth = 0;
            var topHeight = 0;
            slides.each(function() {
                if ($(this).width() > topWidth) topWidth = $(this).width();
                if ($(this).height() > topHeight) topHeight = $(this).height();
            });

            // set slide w/h
            obj.width(topWidth).height(topHeight);

            // only do the slideshow if we have more than one slide
            if (slides.length > 1) {
                if (options.showPlayControls) {
                    // show play controls
                    var playControls = $(document.createElement("div"));
                    playControls.css({
                        position: "absolute",
                        bottom: "4px",
                        right: "4px",
                        fontFamily: "verdana, arial sans-serif",
                        fontSize: "9px",
                        color: "black",
                        padding: "2px",
                        opacity: 0.2,
                        backgroundColor: "#CCC",
                        border: "1px solid #666",
                        zIndex: options.zIndexTop
                    });

                    playControls
                        .bind("mouseenter", function() { $(this).stop(true,true).animate({ opacity: 0.7 }, 200); })
                        .bind("mouseleave", function() { $(this).stop(true,true).animate({ opacity: 0.2 }, 200); });

                    var createPageButton = function(slideText, nextSlide) {
                        var page = $(document.createElement("div"));
                        page.appendTo(playControls);
                        page.css({
                            cursor: "pointer",
                            cssFloat: "left",
                            padding: "2px",
                            textAlign: "center"
                        });

                        page.text(slideText);
                        page.data("SlideIndex", nextSlide);

                        page
                            .bind("mouseenter", function() { $(this).css({ backgroundColor: "#FFF" }); })
                            .bind("mouseleave", function() { $(this).css({ background: "none" }); });

                        // highlight initial slide
                        if (nextSlide == "0")
                            page.highlightPageButton();
                        else
                            page.dimPageButton();
                            
                        if (nextSlide == "n")
                            page.click(function() { obj.nextSlide(); });
                        else if (nextSlide == "p")
                            page.click(function() { obj.prevSlide(); });
                        else {
                            page.addClass("SlidePage");
                            page.click(function() {
                                var index = parseInt($(this).data("SlideIndex"));
                                obj.goToSlide(index);
                            });
                        }
                    }

                    if (options.showNextBack) createPageButton("<", "p");
                    if (options.showPageSelect) {
                        for (var i = 0; i < slides.length; i++) {
                            createPageButton(i + 1, i);
                        }
                    }
                    if (options.showNextBack) createPageButton(">", "n");

                    playControls.append("<br style='clear:both;'/>");
                    playControls.appendTo(obj);
                }

                // every [slideLength] seconds, fade in a new slide
                obj.oneTime(options.slideLength, "slideanims", function() {
                    $(this).nextSlide();
                });
            }
        });
    };
})(jQuery); 