;(function($) {
    /* version 2.0
    changes from 1.1:
        - more intuitively, it's now the banner elements themselves that this
          method gets called on, so instead of menu_elements.bannerise([options]),
          it's called as banner_elements.bannerise([options]) where optional menu
          elements are set in the options
        - completely decoupled from tooltipping, the menu_tooltips option no longer
          exists
    */
    $.fn.bannerise = function(settings) {

        /*---------------------------------------------------------------------------

        options:
            delay:         how long each banner should be shown for before moving to the next
                           (if auto_rotate is true)

            fade_speed:    the time it takes for one banner to fade to the next in ms

            auto_rotate:   whether or not the banners should automatically rotate

            links:         a set of elements that form corresponding links to each banner
                           so that when each one is clicked it shows the corresponding banner

            init:          the number (0-indexed) of the initial banner to show
                           (counted from the bottom of the list of banner elements if cycle="reversed"
                           and counted from the top if not)

            pause:         whether or not automatic banner rotation should be paused on hover

            cycle:         the direction in which to cycle through the banners (any value but
                           "reversed" means it cycles top to bottom through the banner elements)


            -- these last two options are the remnants of a sort of broken tooltipping
               solution. could maybe decouple this by globally advertising the current
               banner, or by using some sort of callback function to fire an event which
               can be picked upon outside the plugin

            descriptions:  a list of elements that contain a corresponding description
                           for each banner

            tipelement:    an element in which the description for each banner is placed
                           as the banner is displayed

            $(".rc-banners").bannerise({ auto_rotate: false,
                                         fade_speed: 100,
                                         links: "rc-tabs",
                                         init: 0 });

        ----------------------------------------------------------------------------*/
        var that = this;
        options = jQuery.extend(
            {
                delay: 5000,
                fade_speed: 600,
                auto_rotate: true,
                links: null,
                init: 1,
                pause: true,
                cycle: "forward",

                // these are for tooltipping purposes -- should ultimately be separated
                descriptions: null,
                tipelement: null

            }, settings);

        $banners = $(this);
        num_banners = $banners.size();
        options.init = (options.cycle!="reverse") ? (options.init) : (num_banners-1-options.init);
        $links = $(options.links);
        $descriptions = $(options.descriptions);
        $tooltip = $(options.tipelement);
        var rotate_tout;

        current = -1;
        if(options.descriptions && options.tipelement) {
            init_desc = $descriptions.eq(current).html();
            $tooltip.html(init_desc);
        }
        // initialise stuff

        function do_timers(rotate) {

            if(rotate && !that.stopped) rotate_tout = setTimeout(function() {
                if(options.cycle=="reverse") {
                    prev_banner();
                } else {
                    next_banner();
                }}, options.delay);

        }

        function mouseover_handler() {
            if (!that.stopped) clearTimeout(rotate_tout);
        }
        function mouseout_handler() {
            do_timers(true);
        }

        function change_banner(which, rotate) {
            if (that.stopped) return;
            if(options.auto_rotate && rotate_tout !== undefined) clearTimeout(rotate_tout);
            if (rotate_tout === undefined) {
                do_timers(rotate);
            }
            $bc = $banners.eq(current);
            $bn = $banners.eq(which);
            $lc = $links.eq(current);
            $ln = $links.eq(which);
            if(which!=current) {
                $lc.removeClass("current")
                $ln.addClass("current");
                $bc.removeClass("current");
                $bc.addClass("current");

                $bc.css("position", "absolute").css("z-index", current+1).fadeOut(options.fade_speed);
                $bn.css("position", "absolute").css("z-index", num_banners+1).fadeIn(options.fade_speed);

                do_timers(rotate);

                current = which;
                if(options.tipelement && options.descriptions){
                    next_desc = $descriptions.eq(which).html();
                    $tooltip.html(next_desc);
                }
            }
        }

        function next_banner() {
            if (that.stopped) return;
            if(current<num_banners-1) {
                change_banner(current+1, options.auto_rotate);
            } else {
                change_banner(0, options.auto_rotate);
            }
        }
        function prev_banner() {
            if (that.stopped) return;
            if(current>0) {
                change_banner(current-1, options.auto_rotate);
            } else {
                change_banner(num_banners-1, options.auto_rotate);
            }
        }


        $([]).add($banners).add($links).mouseover(function() {
            if(options.auto_rotate && options.pause) mouseover_handler();
            return false;
        }).mouseout(function() {
            if(options.auto_rotate && options.pause) mouseout_handler();
            return false;
        });

        $banners.each(function(i) {
            $(this).css("position", "relative").css("z-index", String(num_banners-i)).hide();
        }).mouseover(function() {
            if(options.tipelement && options.descriptions) {
                next_desc = $descriptions.eq(current).html();
                $tooltip.html(next_desc);
            }
        });

        $links.each(function(i) {
            $(this).click(function(e) {
                e.preventDefault();
                change_banner(i, false);
            }).mouseover(function() {
                if(options.tipelement && options.descriptions) {
                    next_desc = $descriptions.eq(i).html();
                    $tooltip.html(next_desc);
                }
            });
        });

        this.stopped = false;
        change_banner(options.init, options.auto_rotate);

        $(window).blur(function() {
            that.stopped = true;
        });
        $(window).focus(function() {
            that.stopped = false;
            change_banner(options.init, options.auto_rotate);
        });


        return this;
    };

})(jQuery);

