﻿/*
* jQuery SmoothDivScroll 1.1
*
* Copyright (c) 2010 Thomas Kahn
* Licensed under the GPL license.
*
* http://www.maaki.com/thomas/SmoothDivScroll/
*
* Depends:
* jquery.ui.widget.js
*
*/
(function ($) {
    $.widget("thomaskahn.smoothDivScroll", {
        options: {
            scrollingHotSpotLeft: "div.scrollingHotSpotLeft",
            scrollingHotSpotRight: "div.scrollingHotSpotRight",
            scrollableArea: "div.scrollableArea",
            scrollWrapper: "div.scrollWrapper",
            hiddenOnStart: false,
            ajaxContentURL: "",
            countOnlyClass: "",
            scrollStep: 15,
            scrollInterval: 10,
            mouseDownSpeedBooster: 3,
            autoScroll: "",
            autoScrollDirection: "backandforth",
            autoScrollStep: 5,
            autoScrollInterval: 10,
            visibleHotSpots: "",
            hotSpotsVisibleTime: 5,
            startAtElementId: ""
        },
        _create: function () {
            var self = this,
            o = this.options,
            el = this.element;

            el.data("scrollWrapper", el.find(o.scrollWrapper));
            el.data("scrollingHotSpotRight", el.find(o.scrollingHotSpotRight));

            el.data("scrollingHotSpotLeft", el.find(o.scrollingHotSpotLeft));
            el.data("scrollableArea", el.find(o.scrollableArea));

            el.data("speedBooster", 1);
            el.data("motherElementOffset", el.offset().left);
            el.data("scrollXPos", 0);
            el.data("hotSpotWidth", el.find(o.scrollingHotSpotLeft).width());

            el.data("scrollableAreaWidth", 0);
            el.data("startingPosition", 0);

            el.data("rightScrollInterval", null);
            el.data("leftScrollInterval", null);

            el.data("autoScrollInterval", null);
            el.data("hideHotSpotBackgroundsInterval", null);

            el.data("previousScrollLeft", 0);
            el.data("pingPongDirection", "right");
            el.data("getNextElementWidth", true);
            el.data("swapAt", null);
            el.data("startAtElementHasNotPassed", true);
            el.data("swappedElement", null);
            el.data("originalElements", el.data("scrollableArea").children(o.countOnlyClass));

            el.data("visible", true);
            el.data("initialAjaxContentLoaded", false);
            el.data("enabled", true);

            if (o.autoScroll !== "always") {
                switch (o.visibleHotSpots) {
                    case "always": self.showHotSpotBackgrounds(); break;
                    case "onstart":
                        self.showHotSpotBackgrounds();
                        el.data("hideHotSpotBackgroundsInterval", setTimeout(function () {
                            self.hideHotSpotBackgrounds("slow")
                        },
                        (o.hotSpotsVisibleTime * 1000)));
                        break;
                    default: break
                }
            }

            // mousemove hotspot right
            el.data("scrollingHotSpotRight").bind("mousemove", function (e) {
                var x = e.pageX - (this.offsetLeft + el.data("motherElementOffset"));
                el.data("scrollXPos", Math.round((x / el.data("hotSpotWidth")) * o.scrollStep));

                if (el.data("scrollXPos") === Infinity) {
                    el.data("scrollXPos", 0)
                }
            });

            // mouseover >> mousedown
            el.data("scrollingHotSpotRight").bind("mouseover", function () {
                if ((o.autoScroll === "onstart" && el.data("autoScrollInterval") !== null)) {
                    clearInterval(el.data("autoScrollInterval"));
                    el.data("autoScrollInterval", null);
                    self._trigger("autoScrollIntervalStopped")
                }
                el.data("rightScrollInterval", setInterval(function () {
                    if (el.data("scrollXPos") > 0 && el.data("enabled")) {
                        el.data("scrollWrapper").scrollLeft(el.data("scrollWrapper").scrollLeft() + (el.data("scrollXPos") * el.data("speedBooster")));
                        self._showHideHotSpots()
                    }
                }, o.scrollInterval));
                self._trigger("mouseOverRightHotSpot")
            });

            // mouseout >> mouseup
            el.data("scrollingHotSpotRight").bind("mouseout", function (e) {
                clearInterval(el.data("rightScrollInterval"));
                el.data("scrollXPos", 0);

                var x = e.pageX - (this.offsetLeft + el.data("motherElementOffset"));
                el.data("scrollXPos", Math.round((x / el.data("hotSpotWidth")) * o.scrollStep));
            });

            /**/
            el.data("scrollingHotSpotRight").bind("mousedown", function () {
                el.data("speedBooster", o.mouseDownSpeedBooster)
            });

            $("body").bind("mouseup", function () {
                el.data("speedBooster", 1)
            });
            /**/

            el.data("scrollingHotSpotLeft").bind("mousemove", function (e) {
                var x = el.data("scrollingHotSpotLeft").innerWidth() - (e.pageX - el.data("motherElementOffset"));
                el.data("scrollXPos", Math.round((x / el.data("hotSpotWidth")) * o.scrollStep));

                if (el.data("scrollXPos") === Infinity) {
                    el.data("scrollXPos", 0)
                }
            });

            // mouseover >> mousedown
            el.data("scrollingHotSpotLeft").bind("mouseover", function () {
                if ((o.autoScroll === "onstart" && el.data("autoScrollInterval") !== null)) {
                    clearInterval(el.data("autoScrollInterval"));
                    el.data("autoScrollInterval", null);
                    self._trigger("autoScrollIntervalStopped")
                }
                el.data("leftScrollInterval", setInterval(
                    function () {
                        if (el.data("scrollXPos") > 0 && el.data("enabled")) {
                            el.data("scrollWrapper").scrollLeft(el.data("scrollWrapper").scrollLeft() - (el.data("scrollXPos") * el.data("speedBooster")));
                            self._showHideHotSpots()
                        }
                    }, o.scrollInterval
                ));
                self._trigger("mouseOverLeftHotSpot")
            });

            // mouseout >> mouseup
            el.data("scrollingHotSpotLeft").bind("mouseout", function (e) {
                clearInterval(el.data("leftScrollInterval"));
                el.data("scrollXPos", 0);

                var x = el.data("scrollingHotSpotLeft").innerWidth() - (e.pageX - el.data("motherElementOffset"));
                el.data("scrollXPos", Math.round((x / el.data("hotSpotWidth")) * o.scrollStep));
            });

            /**/
            el.data("scrollingHotSpotLeft").bind("mousedown", function () {
                el.data("speedBooster", o.mouseDownSpeedBooster)
            });
            /**/

            $(window).bind("resize", function () {
                if (!(o.hiddenOnStart)) { self._showHideHotSpots() } self._trigger("windowResized")
            });

            if (o.ajaxContentURL.length > 0) {
                self.replaceContent(o.ajaxContentURL)
            }
            else {
                self.recalculateScrollableArea()
            }

            if (o.hiddenOnStart) {
                self.hide()
            }

            if ((o.autoScroll.length > 0) && !(o.hiddenOnStart) && (o.ajaxContentURL.length <= 0)) {
                self.startAutoScroll()
            }

        },
        showHotSpotBackgrounds:
            function (fadeSpeed) {
                var self = this,
                el = this.element;

                if (fadeSpeed !== undefined) {
                    el.data("scrollingHotSpotLeft").css("opacity", "0.0");
                    el.data("scrollingHotSpotRight").css("opacity", "0.0");
                    el.data("scrollingHotSpotLeft").addClass("scrollingHotSpotLeftVisible");
                    el.data("scrollingHotSpotRight").addClass("scrollingHotSpotRightVisible");
                    el.data("scrollingHotSpotLeft").fadeTo(fadeSpeed, 0.35);
                    el.data("scrollingHotSpotRight").fadeTo(fadeSpeed, 0.35)
                }
                else {
                    el.data("scrollingHotSpotLeft").addClass("scrollingHotSpotLeftVisible");
                    el.data("scrollingHotSpotLeft").removeAttr("style");
                    el.data("scrollingHotSpotRight").addClass("scrollingHotSpotRightVisible");
                    el.data("scrollingHotSpotRight").removeAttr("style")
                }
                self._showHideHotSpots()
            },
        hideHotSpotBackgrounds:
                function (fadeSpeed) {
                    var el = this.element;
                    if (fadeSpeed !== undefined) {
                        el.data("scrollingHotSpotLeft").fadeTo(fadeSpeed, 0.0, function () {
                            el.data("scrollingHotSpotLeft").removeClass("scrollingHotSpotLeftVisible")
                        });
                        el.data("scrollingHotSpotRight").fadeTo(fadeSpeed, 0.0, function () {
                            el.data("scrollingHotSpotRight").removeClass("scrollingHotSpotRightVisible")
                        })
                    }
                    else {
                        el.data("scrollingHotSpotLeft").removeClass("scrollingHotSpotLeftVisible");
                        el.data("scrollingHotSpotLeft").removeAttr("style");
                        el.data("scrollingHotSpotRight").removeClass("scrollingHotSpotRightVisible");
                        el.data("scrollingHotSpotRight").removeAttr("style")
                    }
                },
        _showHideHotSpots:
            function () {
                var self = this,
                el = this.element,
                o = this.options;

                if (o.autoScroll !== "always") {
                    if (el.data("scrollableAreaWidth") <= (el.data("scrollWrapper").innerWidth())) {
                        el.data("scrollingHotSpotLeft").hide();
                        el.data("scrollingHotSpotRight").hide();
                    }
                    else if (el.data("scrollWrapper").scrollLeft() === 0) {
                        el.data("scrollingHotSpotLeft").hide();
                        el.data("scrollingHotSpotRight").show();
                        self._trigger("scrollLeftLimitReached");
                        clearInterval(el.data("leftScrollInterval"));
                        el.data("leftScrollInterval", null)
                    }
                    else if (el.data("scrollableAreaWidth") <= (el.data("scrollWrapper").innerWidth() + el.data("scrollWrapper").scrollLeft())) {
                        el.data("scrollingHotSpotLeft").show();
                        el.data("scrollingHotSpotRight").hide();
                        self._trigger("scrollRightLimitReached");
                        clearInterval(el.data("rightScrollInterval"));
                        el.data("rightScrollInterval", null)
                    }
                    else {
                        el.data("scrollingHotSpotLeft").show();
                        el.data("scrollingHotSpotRight").show()
                    }
                } else {
                    el.data("scrollingHotSpotLeft").hide();
                    el.data("scrollingHotSpotRight").hide()
                }
            },
        moveToElement:
            function (moveTo, elementNumber) {
                var self = this,
                el = this.element,
                o = this.options,
                tempScrollableAreaWidth = 0,
                foundStartAtElement = false;

                switch (moveTo) {
                    case "first":
                        el.data("scrollXPos", 0);
                        self._trigger("movedToFirstElement");
                        break;
                    case "start":
                        el.data("scrollableArea").children(o.countOnlyClass).each(function () {
                            if ((o.startAtElementId.length > 0) && (($(this).attr("id")) === o.startAtElementId)) {
                                el.data("startingPosition", tempScrollableAreaWidth); foundStartAtElement = true
                            }
                            tempScrollableAreaWidth = tempScrollableAreaWidth + $(this).outerWidth(true)
                        });

                        el.data("scrollXPos", el.data("startingPosition"));
                        self._trigger("movedToStartElement");
                        break;
                    case "last":
                        el.data("scrollXPos", el.data("scrollableAreaWidth"));
                        self._trigger("movedToLastElement");
                        break;
                    case "number":
                        if (!(isNaN(elementNumber))) {
                            el.data("scrollableArea").children(o.countOnlyClass).each(
                                function (index) {
                                    if (index === (elementNumber - 1)) {
                                        el.data("scrollXPos", tempScrollableAreaWidth)
                                    }
                                    tempScrollableAreaWidth = tempScrollableAreaWidth + $(this).outerWidth(true)
                                }
                            )
                        }
                        self._trigger("movedToElementNumber", null, { "elementNumber": elementNumber });
                        break;
                    default: break
                }

                el.data("scrollWrapper").scrollLeft(el.data("scrollXPos"));
                self._showHideHotSpots()
            },
        addContent:
            function (ajaxContentURL, addWhere) {
                var self = this, el = this.element;
                $.get(ajaxContentURL, function (data) {
                    if (addWhere === "first") {
                        el.data("scrollableArea").children(":first").before(data)
                    } else { el.data("scrollableArea").children(":last").after(data) } self.recalculateScrollableArea(); self._showHideHotSpots()
                })
            }, replaceContent: function (ajaxContentURL) { var self = this, el = this.element; el.data("scrollableArea").load(ajaxContentURL, function () { self.recalculateScrollableArea(); self.moveToElement("first"); self._showHideHotSpots(); el.data("startingPosition", 0) }) }, recalculateScrollableArea: function () { var tempScrollableAreaWidth = 0, foundStartAtElement = false, o = this.options, el = this.element, self = this; el.data("scrollableArea").children(o.countOnlyClass).each(function () { if ((o.startAtElementId.length > 0) && (($(this).attr("id")) === o.startAtElementId)) { el.data("startingPosition", tempScrollableAreaWidth); foundStartAtElement = true } tempScrollableAreaWidth = tempScrollableAreaWidth + $(this).outerWidth(true) }); if (!(foundStartAtElement)) { el.data("startAtElementId", "") } el.data("scrollableAreaWidth", tempScrollableAreaWidth); el.data("scrollableArea").width(el.data("scrollableAreaWidth")); el.data("scrollWrapper").scrollLeft(el.data("startingPosition")); el.data("scrollXPos", el.data("startingPosition")); if (!(el.data("initialAjaxContentLoaded"))) { if ((o.autoScroll.length > 0) && !(o.hiddenOnStart) && (o.ajaxContentURL.length > 0)) { self.startAutoScroll(); el.data("initialAjaxContentLoaded", true) } } }, stopAutoScroll: function () { var self = this, el = this.element; clearInterval(el.data("autoScrollInterval")); el.data("autoScrollInterval", null); self._showHideHotSpots(); self._trigger("autoScrollStopped") }, startAutoScroll: function () { var self = this, el = this.element, o = this.options; self._showHideHotSpots(); clearInterval(el.data("autoScrollInterval")); el.data("autoScrollInterval", null); self._trigger("autoScrollStarted"); el.data("autoScrollInterval", setInterval(function () { if (!(el.data("visible")) || (el.data("scrollableAreaWidth") <= (el.data("scrollWrapper").innerWidth()))) { clearInterval(el.data("autoScrollInterval")); el.data("autoScrollInterval", null) } else { el.data("previousScrollLeft", el.data("scrollWrapper").scrollLeft()); switch (o.autoScrollDirection) { case "right": el.data("scrollWrapper").scrollLeft(el.data("scrollWrapper").scrollLeft() + o.autoScrollStep); if (el.data("previousScrollLeft") === el.data("scrollWrapper").scrollLeft()) { self._trigger("autoScrollRightLimitReached"); clearInterval(el.data("autoScrollInterval")); el.data("autoScrollInterval", null); self._trigger("autoScrollIntervalStopped") } break; case "left": el.data("scrollWrapper").scrollLeft(el.data("scrollWrapper").scrollLeft() - o.autoScrollStep); if (el.data("previousScrollLeft") === el.data("scrollWrapper").scrollLeft()) { self._trigger("autoScrollLeftLimitReached"); clearInterval(el.data("autoScrollInterval")); el.data("autoScrollInterval", null); self._trigger("autoScrollIntervalStopped") } break; case "backandforth": if (el.data("pingPongDirection") === "right") { el.data("scrollWrapper").scrollLeft(el.data("scrollWrapper").scrollLeft() + (o.autoScrollStep)) } else { el.data("scrollWrapper").scrollLeft(el.data("scrollWrapper").scrollLeft() - (o.autoScrollStep)) } if (el.data("previousScrollLeft") === el.data("scrollWrapper").scrollLeft()) { if (el.data("pingPongDirection") === "right") { el.data("pingPongDirection", "left"); self._trigger("autoScrollRightLimitReached") } else { el.data("pingPongDirection", "right"); self._trigger("autoScrollLeftLimitReached") } } break; case "endlessloopright": if (el.data("getNextElementWidth")) { if ((o.startAtElementId.length > 0) && (el.data("startAtElementHasNotPassed"))) { el.data("swapAt", $("#" + o.startAtElementId).outerWidth(true)); el.data("startAtElementHasNotPassed", false) } else { el.data("swapAt", el.data("scrollableArea").children(":first").outerWidth(true)) } el.data("getNextElementWidth", false) } el.data("scrollWrapper").scrollLeft(el.data("scrollWrapper").scrollLeft() + o.autoScrollStep); if (el.data("swapAt") <= el.data("scrollWrapper").scrollLeft()) { el.data("swappedElement", el.data("scrollableArea").children(":first").detach()); el.data("scrollableArea").append(el.data("swappedElement")); el.data("scrollWrapper").scrollLeft(el.data("scrollWrapper").scrollLeft() - el.data("swappedElement").outerWidth(true)); el.data("getNextElementWidth", true) } break; case "endlessloopleft": if (el.data("getNextElementWidth")) { if ((o.startAtElementId.length > 0) && (el.data("startAtElementHasNotPassed"))) { el.data("swapAt", $("#" + o.startAtElementId).outerWidth(true)); el.data("startAtElementHasNotPassed", false) } else { el.data("swapAt", el.data("scrollableArea").children(":first").outerWidth(true)) } el.data("getNextElementWidth", false) } el.data("scrollWrapper").scrollLeft(el.data("scrollWrapper").scrollLeft() - o.autoScrollStep); if (el.data("scrollWrapper").scrollLeft() === 0) { el.data("swappedElement", el.data("scrollableArea").children(":last").detach()); el.data("scrollableArea").prepend(el.data("swappedElement")); el.data("scrollWrapper").scrollLeft(el.data("scrollWrapper").scrollLeft() + el.data("swappedElement").outerWidth(true)); el.data("getNextElementWidth", true) } break; default: break } } }, o.autoScrollInterval)) }, restoreOriginalElements: function () { var self = this, el = this.element; el.data("scrollableArea").html(el.data("originalElements")); self.recalculateScrollableArea(); self.moveToElement("first") }, show: function () { var el = this.element; el.data("visible", true); el.show() }, hide: function () { var el = this.element; el.data("visible", false); el.hide() }, enable: function () { var el = this.element; el.data("enabled", true) }, disable: function () { var el = this.element; clearInterval(el.data("autoScrollInterval")); clearInterval(el.data("rightScrollInterval")); clearInterval(el.data("leftScrollInterval")); clearInterval(el.data("hideHotSpotBackgroundsInterval")); el.data("enabled", false) }, destroy: function () { var el = this.element; clearInterval(el.data("autoScrollInterval")); clearInterval(el.data("rightScrollInterval")); clearInterval(el.data("leftScrollInterval")); clearInterval(el.data("hideHotSpotBackgroundsInterval")); el.data("scrollingHotSpotRight").unbind("mouseover"); el.data("scrollingHotSpotRight").unbind("mouseout"); el.data("scrollingHotSpotRight").unbind("mousedown"); el.data("scrollingHotSpotLeft").unbind("mouseover"); el.data("scrollingHotSpotLeft").unbind("mouseout"); el.data("scrollingHotSpotLeft").unbind("mousedown"); el.data("scrollableArea").html(el.data("originalElements")); el.data("scrollableArea").removeAttr("style"); el.data("scrollingHotSpotRight").removeAttr("style"); el.data("scrollingHotSpotLeft").removeAttr("style"); el.data("scrollWrapper").scrollLeft(0); el.data("scrollingHotSpotLeft").removeClass("scrollingHotSpotLeftVisible"); el.data("scrollingHotSpotRight").removeClass("scrollingHotSpotRightVisible"); el.data("scrollingHotSpotRight").hide(); el.data("scrollingHotSpotLeft").hide(); $.Widget.prototype.destroy.apply(this, arguments) }
    })
})(jQuery);
