function $ (id) {return document.getElementById(id)}
var oNode = {};
oNode.IsNode = function (el /* :HTMLElement */) {
    if (el && typeof el == 'object' && el.nodeType == 1)
        return true;
    return false;
};
oNode.CreateNode = function (tag /* :String */) {
    return document.createElement(tag);
};
oNode.AddNode = function (node /* :HTMLElement */, target /* :HTMLElement */) {
    target = target || document.body;
    if (this.IsNode(node) || this.IsTextNode(node)) {
        if (node.parentNode && this.IsNode(node.parentNode)) return false;
        target.appendChild(node);
    }
    else {
        //target.innerHTML += node;
        this.AddNode(this.CreateTextNode(node.toString()), target);
    }
    return true;
};
var Events = {};
Events.AttachEvent = function (obj, eventName, func, useCapture, _window) {
    obj = $(obj);if (!obj) return;
    useCapture = useCapture ? true : false;
    eventName = eventName.toLowerCase();
    if (obj.addEventListener) {
        obj.addEventListener(eventName, func, useCapture);
    }
    else {
        var E = this;
        this._AttachEvent(obj, eventName, func);
        obj['on' + eventName] = function (e) {E._FireEvent(obj, eventName, e, _window);};
    }
};
Events.RemoveEvent = function (obj, eventName, func, useCapture) {
    obj = $(obj);if (!obj) return;
    useCapture = useCapture ? true : false;
    eventName = eventName.toLowerCase();
    if (obj.removeEventListener) {
        obj.removeEventListener(eventName, func, useCapture);
    }
    else {
        if (obj.events && obj.events[eventName]) {
            var evts = obj.events[eventName];
            for (var i = 0, len = evts.length; i < len; i++) {
                if (evts[i] && func && evts[i] === func) {
                    evts.splice(i, 1);
                    break;
                }
            }
        }
    }
};
Events._AttachEvent = function (obj, eventName, func) {
    eventName = eventName.toLowerCase();
    if (! obj.events) obj.events = {};
    if (! obj.events[eventName]) obj.events[eventName] = [];
    var evts = obj.events[eventName];
    evts[evts.length] = func;
};
Events._FireEvent = function (obj, eventName, e, _window) {
    e = _window ? _window.event : $E(e);
    eventName = eventName.toLowerCase();
    if (!obj || !obj.events || !obj.events[eventName]) return;
    var evts = obj.events[eventName];
    for (var i = 0, len = evts.length; i < len; i++)
        evts[i] && evts[i].call(obj, e, obj);
};
var CSS = {LEFT:'left',RIGHT:'right',BOTH:'both'};
CSS.GetRe = function (c) {
    return new RegExp('^\\s*' + c + '\\s+|\\s+' + c + '\\s*$|\\s+' + c + '\\s+|^\\s*' + c + '\\s*$', '');
};
CSS.AddClass = function (el /* :HTMLElement */ /*, class1, class2, ..., classN */) {
    if (! oNode.IsNode(el)) return;
    var list = arguments;

    for (var i = 1, len = list.length; i < len; i++) {
        var c = list[i];
        if (typeof c != 'string' || c == '') continue;

        var re = this.GetRe(c);
        if (!re.test(el.className)) {
            el.className += ((el.className ? '\x20' : '') + c).replace(/\s{2,}/g, '\x20');
        }
    }
};
var Roll = {};
Roll.Top = function (el /* :HTMLElement */, content /* :String */, args /* :Object
        {
            scrollamount:(:Number), // 滚动量
            scrolldelaymin:(:Number), // 滚动延迟，滚动单一行的时间间隔
            scrolldelaymax:(:Number), // 滚动延迟，不同行间的时间间隔
        }
    */) {
    if (!el || !content) return;
    
    ///
    if (typeof args != 'object') args = {};
    if (typeof args.scrollamount != 'number')
        args.scrollamount = 1;
    if (typeof args.scrolldelaymin != 'number')
        args.scrolldelaymin = 1;
    if (typeof args.scrolldelaymax != 'number')
        args.scrolldelaymax = 1;

    //
    CSS.AddClass(el, 'roll');

    //
    var one;
    if (oNode.IsNode(content)) {
        one = content;
    }
    else {
        one = oNode.CreateNode('div');
        oNode.AddNode(one, el);
        one.innerHTML = content;
    }
    CSS.AddClass(one, 'top-one');
    one.style.top = 0;

    // 单条信息返回
    if (Math.floor(one.offsetHeight / args.scrollamount) < 2) return;
    
    var childs = one.getElementsByTagName('li');
    for (var i = 0, len = childs.length; i < len; i++) {
        childs[i].style.height = args.scrollamount + 'px';
    }

    var two = one.cloneNode(true);
    oNode.AddNode(two, el);
    CSS.AddClass(one, 'top-two');
    two.style.top = one.offsetHeight + 'px';

    //
    // 是否经过
    var mouseover = false;
    // 滚动状态
    var overState = 0;
    // 滚动延迟
    var delay1 = args.scrolldelaymin;
    var delay2 = args.scrolldelaymax;
    // 滚动一屏的像素量
    var amount1 = args.scrollamount || 20;
    var amount2 = 135;
    // 计时器
    var interval;
    function roll () {
        if (amount2 == 0) {
            overState = 1;
            if (mouseover) return;

            if (parseInt(one.style.top) < -one.offsetHeight) {
                one.style.top = parseInt(two.style.top) + two.offsetHeight + 'px';
            }
            if (parseInt(two.style.top) < -two.offsetHeight) {
                two.style.top = parseInt(one.style.top) + one.offsetHeight + 'px';
            }
            amount2 = amount1;

            interval = setTimeout(roll, delay2);
            return;
        }
        overState = 0;
        amount2--;
        one.style.top = parseInt(one.style.top) - 1 + 'px';
        two.style.top = parseInt(two.style.top) - 1 + 'px';

        interval = setTimeout(roll, delay1);
    }
    roll();

    Events.AttachEvent(el, 'mouseover', function () {
        mouseover = true;
        if (overState == 1)
            clearTimeout(interval);
    });
    Events.AttachEvent(el, 'mouseout', function () {
        mouseover = false;
        if (overState == 1) {
            clearTimeout(interval);
            interval = setTimeout(roll, delay2);
        }
    });
};
