﻿/*
container:滚动的容器ID
btnPrevious：上一步按钮的ID
btnNext：下一步按钮的ID
eventType：上一个和下一个按钮事件的触发方式:click为点击触发滚动 否则就是 鼠标按住按钮触发滚动
*/
function Scroller(container, btnPrevious, btnNext, eventType) {
    this.Speed = 10; //滚动速度 1--10
    this.IsSmoothScroll = false; //是否平滑连续滚动 平滑滚动:true 间隔滚动:false
    this.PauseTime = 3500; //间隔滚动时每次滚动间隔的时间。单位：毫秒。建议值：100--3000 适用于间隔滚动。
    this.Direction = "N"; //滚动方向.向东：E，向北：N
    this.EventType = "click" || eventType; //上一个和下一个按钮事件的触发方式:click为点击触发滚动 否则就是 鼠标按住按钮触发滚动。支持click 和mousedown两种模式
    this.BackCall = null; //回调函数 滚动到末尾时执行
    this.Loop = false; //是否为循环滚动;
    this.ScrollStep = 5; //滚动的步长
    this.StopScroll = false; //是否停止滚动的标志位
    this.NextButton = this.$(btnNext);
    this.PreviousButton = this.$(btnPrevious); //按钮标签
    this.ScrollElement = this.$(container); //滚动内容区域
    this.ScrollSize = 0;//滚动区域显示大小
    this.ContainerTag = 'ul'; //滚动容器标签
    this.ListTag = 'li'; //滚动列表标签
    this.ContainerSize; //滚动容器实际宽/高度
    this.ListSize = 0;  //滚动容器中对象实际宽/高度
    this.LastPos = 0; //最后偏移位置
    this.ScrollFlag = false; //滚动标记
    this.Offset = 0; //修正偏移
    this.ScrollObj = null;//滚动方向对象
}
Scroller.prototype = {
    $: function(element) {
        return document.getElementById(element);
    },
    Init: function() {
        var ContainerElement = this.ScrollElement.getElementsByTagName(this.ContainerTag)[0];
        ContainerElement.innerHTML += ContainerElement.innerHTML;
        var lists = ContainerElement.getElementsByTagName(this.ListTag);
        var scrollSize = 0;

        if (this.Direction == "E") {
            this.ScrollObj = { s0: 'scrollLeft', s1: 'scrollWidth', o0: 'offsetWidth' };
        } else {
            this.ScrollObj = { s0: 'scrollTop', s1: 'scrollHeight', o0: 'offsetHeight' };
        }

        for (var i = 0; i < lists.length; i++) {
            scrollSize += lists[i][this.ScrollObj.o0];
            scrollSize += this.Offset;
        }
        if (this.Direction == "E") {
            this.ListSize = lists[0][this.ScrollObj.o0] + this.Offset;
            this.ScrollSize = parseInt(this.ScrollElement.style.width);
            ContainerElement.style.width = scrollSize + 'px';
        } else {
            this.ListSize = lists[0][this.ScrollObj.o0] + this.Offset;
            this.ScrollSize = parseInt(this.ScrollElement.style.height);
            ContainerElement.style.height = scrollSize + 'px';
        }
        this.Bind(this.PreviousButton, this.EventType, "Previous");
        this.Bind(this.NextButton, this.EventType, "Next");
    },
    Bind: function(el, type, param) {
        if (el) {
            if (type == "click") {
                el.onclick = this.GetFunction(this, param);
            } else {
                el.onmousedown = this.GetFunction(this, "MouseDown");
                el.onmouseup = this.GetFunction(this, "MouseUp");
                el.onmouseover = this.GetFunction(this, "MouseOver");
                el.onmouseout = this.GetFunction(this, "MouseOut");
            }
        }
    },
    Previous: function() {
        if (this.ScrollFlag) return;
        this.LastPos = parseInt(this.ScrollElement[this.ScrollObj.s0]);
        clearTimeout(this.ScrollTimer);
        this.Scroll("pre");
    },
    Next: function() {
        if (this.ScrollFlag) return;
        this.LastPos = parseInt(this.ScrollElement[this.ScrollObj.s0]);
        clearTimeout(this.ScrollTimer);
        this.Scroll("next");
    },
    Start: function() {
        if (this.IsSmoothScroll) {
            this.AutoScrollInterval = setInterval(this.GetFunction(this, "SmoothScroll"), this.Speed);
        } else {
            this.AutoScrollInterval = setInterval(this.GetFunction(this, "IntervalScroll"), this.PauseTime);
        }
        this.ScrollElement.getElementsByTagName(this.ContainerTag)[0].onmouseover = this.GetFunction(this, "MouseOver");
        this.ScrollElement.getElementsByTagName(this.ContainerTag)[0].onmouseout = this.GetFunction(this, "MouseOut");
    },
    Stop: function() {
        clearInterval(this.AutoScrollInterval);
    },
    MouseOver: function() {
        clearTimeout(this.ScrollTimer);
        this.StopScroll = true;
    },
    MouseOut: function() {
        this.MouseUp();
        this.StopScroll = false;
    },
    MouseDown: function(direction) {
        this.MouseDownInterval = setInterval(this.GetFunction(this, "QuickScroll", direction), this.PauseTime);
    },
    MouseUp: function() {
        clearInterval(this.MouseDownInterval);
    },
    IntervalScroll: function() {
        if (this.ScrollFlag) return;
        this.ScrollElement[this.ScrollObj.s0] += this.ScrollStep;
        if (parseInt(this.ScrollElement[this.ScrollObj.s0] % this.ListSize) != 0) {
            this.AutoScrollTimer = setTimeout(this.GetFunction(this, "IntervalScroll"), this.Speed);
        } else {
            if (parseInt(this.ScrollElement[this.ScrollObj.s0]) >= parseInt(this.ScrollElement[this.ScrollObj.s1]) / 2) {
                this.ScrollElement[this.ScrollObj.s0] = 0;
            }
            clearTimeout(this.AutoScrollTimer);
            if (this.BackCall) this.BackCall();
        }
    },
    SmoothScroll: function() {
        if (this.ScrollFlag) return;
        this.ScrollElement[this.ScrollObj.s0] += this.ScrollStep;
        if (parseInt(this.ScrollElement[this.ScrollObj.s0]) >= parseInt(this.ScrollElement[this.ScrollObj.s1]) / 2) {
            this.ScrollElement[this.ScrollObj.s0] = 0;
        }
    },
    Scroll: function(direction) {
        if (this.Loop) {
            if (direction == "pre") {
                this.ScrollElement[this.ScrollObj.s0] -= this.ScrollStep;
            } else {
                this.ScrollElement[this.ScrollObj.s0] += this.ScrollStep;
            }
            if (this.ScrollElement[this.ScrollObj.s0] >= parseInt(this.ScrollElement[this.ScrollObj.s1] / 2)) {
                this.ScrollElement[this.ScrollObj.s0] = 0;
                this.ScrollFlag = false;
            } else if (this.ScrollElement[this.ScrollObj.s0] <= 0) {
                this.ScrollElement[this.ScrollObj.s0] = parseInt(this.ScrollElement[this.ScrollObj.s1] / 2);
                this.ScrollFlag = false;
            } else {
                if (Math.abs(this.LastPos - this.ScrollElement[this.ScrollObj.s0]) < this.ListSize) {
                    this.ScrollFlag = true;
                    this.ScrollTimer = setTimeout(this.GetFunction(this, "Scroll", direction), this.Speed);
                } else {
                    this.LastPos = this.ScrollElement[this.ScrollObj.s0];
                    this.ScrollFlag = false;
                }
            }
        } else {
            if (direction == "pre") {
                if (this.ScrollElement[this.ScrollObj.s0] > 0) {
                    this.ScrollElement[this.ScrollObj.s0] -= this.ScrollStep;
                }
            } else {
                if (this.ScrollElement[this.ScrollObj.s0] < parseInt(this.ScrollElement[this.ScrollObj.s1] / 2) - this.ScrollSize) {
                    this.ScrollElement[this.ScrollObj.s0] += this.ScrollStep;
                }
            }
            if (this.ScrollElement[this.ScrollObj.s0] <= 0) {
                this.ScrollElement[this.ScrollObj.s0] = 0;
                this.ScrollFlag = false;
            } else if (this.ScrollElement[this.ScrollObj.s0] + this.ScrollSize >= parseInt(this.ScrollElement[this.ScrollObj.s1] / 2)) {
                this.ScrollElement[this.ScrollObj.s0] = parseInt(this.ScrollElement[this.ScrollObj.s1] / 2) - this.ScrollSize;
                this.ScrollFlag = false;
            } else {
                if (Math.abs(this.LastPos - this.ScrollElement[this.ScrollObj.s0]) < this.ListSize) {
                    this.ScrollFlag = true;
                    this.ScrollTimer = setTimeout(this.GetFunction(this, "Scroll", direction), this.Speed);
                } else {
                    this.LastPos = this.ScrollElement[this.ScrollObj.s0];
                    this.ScrollFlag = false;
                }
            }
        }
        if (this.BackCall) this.BackCall();
    },
    QuickScroll: function(direction) {
        if (direction == "pre") {
            this.ScrollElement[this.ScrollObj.s0] -= this.ScrollStep;
        } else {
            this.ScrollElement[this.ScrollObj.s0] += this.ScrollStep;
        }
        if (parseInt(this.ScrollElement[this.ScrollObj.s0]) >= parseInt(this.ScrollElement[this.ScrollObj.s1]) / 2) {
            this.ScrollElement[this.ScrollObj.s0] = 0;
        } else if (parseInt(this.ScrollElement[this.ScrollObj.s0]) <= 0) {
            this.ScrollElement[this.ScrollObj.s0] = parseInt(this.ScrollElement[this.ScrollObj.s1]) / 2;
        }
    },
    GetFunction: function(variable, method, param) {
        return function() {
            variable[method](param);
        }
    }
};