/// <reference path="jquery-1.4.2.min.js"/> 
/// <reference path="jquery.timers.js"/> 
/* 
 @author Dan Gidman 
 released under GNU General Public License v3 
 http://www.gnu.org/licenses/gpl.html 
 version 1.01 
 requires jQuery.timers 
 http://plugins.jquery.com/project/timers 
 */ 
(function (jQuery) {
    jQuery.fn.autoscroll = function (settings) {
        /// <summary>Auto scroll scrollable elements.</summary>
        /// <param name="settings" type="object">
        ///     [optional]
        ///     1: action - [start]|stop|delay|fastfoward|rewind|update|pause|resume|reverse|toggle
        ///     2: step  -  unit [50] in pixels - higher units means faster scroll, lower units means slower scroll
        ///     3: direction - up|[down]|left|right|(up|down)(left|right)
        ///     4: scroll - [true]|false
        ///     5: delay -  unit [5000] in milliseconds
        ///     6: speed -  slow|[fast]|unit in milliseconds - used with fastforward and rewind
        ///</param>
        var config = {
            step: 50,
            scroll: true,
            event: false,
            container: "#container",
            stopFeedback: false,
            oldTop: 0,
            oldBottom: 0,
            finishcallback: false
        };
        jQuery.extend(config, settings);
        switch (config.action) {
            case "pause":
                this.each(function () {
                var c = this.$autoscroll;
                if (c && c.scroll) {
                    c.scroll = false;
                }
            });
            break;
            case "resume":
                this.each(function () {
                var c = this.$autoscroll;
                if (c) {
                    c.scroll = true;
                }
            });
            break;
            case "toggle":
                this.each(function () {
                var c = this.$autoscroll;
                if (c) {
                    c.scroll = !c.scroll;
                }
            });
            break;
            case "reverse":
                this.each(function () {
                var c = this.$autoscroll;
                if (c) {
                    switch (c.direction) {
                        case "up":
                            c.direction = "down";
                            break;
                        case "left":
                            c.direction = "right";
                            break;
                        case "right":
                            c.direction = "left";
                            break;
                        case "upleft":
                            c.direction = "downright";
                            break;
                        case "upright":
                            c.direction = "downleft";
                            break;
                        case "downleft":
                            c.direction = "upright";
                            break;
                        case "downright":
                            c.direction = "upleft";
                            break;
                        default:
                            c.direction = "up";
                            break;
                    }
                }
            });
            break;
            case "update":
                this.each(function () {
                if (this.$autoscroll) {
                    jQuery.extend(this.$autoscroll, settings);
                }
            });
            break;
        case "delay":
            this.each(function () {
            var c = this.$autoscroll;
            if (c && c.scroll) {
                c.scoll = false;
                jQuery(this).oneTime(config.delay || 5000, "autoscroll", function () {
                    this.$autoscroll.scroll = true;
                    if (config.finishcallback) {
                        config.finishcallback();
                    }
                });
            }
        });
        break;
        case "stop":
            this.each(function () {
            if (this.$autoscroll) {
                jQuery(this).stop(true);
                jQuery.timer.remove(this, "autoscroll");
                jQuery(this).removeAttr("$autoscroll");
            }
        });
        break;
        case "rewind": case "fastforward":
            this.each(function () {
            var c = this.$autoscroll;
            if (c) {
                var scroll = c.scroll;
                c.scroll = false;
                var speed = config.speed || "fast";
                switch (c.direction) {
                    case "up":
                        jQuery(this).stop(true).animate({
                        scrollTop: ((config.action == "rewind") ? "+=" : "-=") + config.step
                    }, speed, function () {
                        if (scroll) this.$autoscroll.scroll = true;
                    });
                    break;
                    case "left":
                        jQuery(this).stop(true).animate({
                        scrollLeft: ((config.action == "rewind") ? "+=" : "-=") + config.step
                    }, speed, function () {
                        if (scroll) this.$autoscroll.scroll = true;
                    });
                    break;
                    case "right":
                        jQuery(this).stop(true).animate({
                        scrollLeft: ((config.action == "rewind") ? "-=" : "+=") + config.step
                    }, speed, function () {
                        if (scroll) this.$autoscroll.scroll = true;
                    });
                    break;
                    case "upleft":
                        jQuery(this).stop(true).animate({
                        scrollTop: ((config.action == "rewind") ? "+=" : "-=") + config.step,
                        scrollLeft: ((config.action == "rewind") ? "+=" : "-=") + config.step
                    }, speed, function () {
                        if (scroll) this.$autoscroll.scroll = true;
                    });
                    break;
                    case "upright":
                        jQuery(this).stop(true).animate({
                        scrollTop: ((config.action == "rewind") ? "+=" : "-=") + config.step,
                        scrollLeft: ((config.action == "rewind") ? "-=" : "+=") + config.step
                    }, speed, function () {
                        if (scroll) this.$autoscroll.scroll = true;
                    });
                    break;
                    case "downleft":
                        jQuery(this).stop(true).animate({
                        scrollTop: ((config.action == "rewind") ? "-=" : "+=") + config.step,
                        scrollLeft: ((config.action == "rewind") ? "+=" : "-=") + config.step
                    }, speed, function () {
                        if (scroll) this.$autoscroll.scroll = true;
                    });
                    break;
                    case "downright":
                        jQuery(this).stop(true).animate({
                        scrollTop: ((config.action == "rewind") ? "-=" : "+=") + config.step,
                        scrollLeft: ((config.action == "rewind") ? "-=" : "+=") + config.step
                    }, speed, function () {
                        if (scroll) this.$autoscroll.scroll = true;
                    });
                    break;
                    default:
                        jQuery(this).stop(true).animate({
                        scrollTop: ((config.action == "rewind") ? "-=" : "+=") + config.step
                    }, speed, function () {
                        if (scroll) this.$autoscroll.scroll = true;
                    });
                    break;
                }
            }
        });
        break;
        default:
            this.each(function () {
            if (this.$autoscroll) return;
            else jQuery.extend(this, {
                $autoscroll: config
            });
            jQuery(this).hover(function () {
                var c = this.$autoscroll;
                if (c && c.scroll) {
                    jQuery(this).stop(true);
                    c.event = true;
                    c.scroll = false;
                }
            }, function () {
                var c = this.$autoscroll;
                if (c && c.event) {
                    c.event = false;
                    c.scroll = true;
                }
            });
            config.oldTop = jQuery(config.container).position().top;
            config.oldBottom = jQuery(config.container).position().top - jQuery(config.container).innerHeight() + jQuery(this).outerHeight() + (config.step / 2);
            jQuery(this).everyTime(110, "autoscroll", function () {
                var c = this.$autoscroll;
                if (c && c.scroll) {
                    switch (c.direction) {
                        case "up":
                            jQuery(this).stop(true).animate({
                            scrollTop: "-=" + c.step
                        }, 100, function () {
                            var c = this.$autoscroll;
                            if (config.oldTop <= jQuery(c.container).position().top) {
                                c.scroll = false;
                                c.direction = "down";
                                jQuery(this).oneTime(config.delay || 5000, "autoscroll", function () {
                                    this.$autoscroll.scroll = true;
                                });
                            }
                        });
                        break;
                        case "left":
                            jQuery(this).stop(true).animate({
                            scrollLeft: "-=" + c.step
                        }, 100);
                        break;
                        case "right":
                            jQuery(this).stop(true).animate({
                            scrollLeft: "+=" + c.step
                        }, 100);
                        break;
                        case "upleft":
                            jQuery(this).stop(true).animate({
                            scrollTop: "-=" + c.step,
                            scrollLeft: "-=" + c.step
                        }, 100);
                        break;
                        case "upright":
                            jQuery(this).stop(true).animate({
                            scrollTop: "-=" + c.step,
                            scrollLeft: "+=" + c.step
                        }, 100);
                        break;
                        case "downleft":
                            jQuery(this).stop(true).animate({
                            scrollTop: "+=" + c.step,
                            scrollLeft: "-=" + c.step
                        }, 100);
                        break;
                        case "downright":
                            jQuery(this).stop(true).animate({
                            scrollTop: "+=" + c.step,
                            scrollLeft: "+=" + c.step
                        }, 100);
                        break;
                        default:
                            jQuery(this).stop(true).animate({
                            scrollTop: "+=" + c.step
                        }, 100, function () {
                            var c = this.$autoscroll;
                            if (config.oldBottom >= jQuery(c.container).position().top) {
                                c.scroll = false;
                                c.direction = "up";
                                jQuery(this).oneTime(config.delay || 5000, "autoscroll", function () {
                                    this.$autoscroll.scroll = true;
                                });
                            }
                        });
                        break;
                    }
                }
            });
        });
        break;
    }
}; 
})(jQuery); 
 
