// Image roller script by Daniel Cohen Gindi (danielgindi@gmail.com) 054-5655765
var ImageRoller = function(opts) {
    return this._init(opts);
};

ImageRoller.prototype = {
    defs: {
        id: null,
        btnPrev: null,
        btnNext: null,
        btnGo: null,
        mouseWheel: false,
        auto: null,
        speed: 200,
        fps: 40,
        vertical: false,
        circular: true,
        reverse: false,
        visible: 1,
        start: 0,
        scroll: 1,
        hoverPause: null,
        horzDir: 'auto'
    },

    running: false,
    animCss: '',
    sizeCss: '',
    o: null,
    autoInterval: null,

    _init: function(o) {
        if (!o) return null;
        var o = this.o = dgTools.extend({}, 'id btnPrev btnNext btnGo mouseWheel auto speed fps vertical circular reverse visible start scroll hoverPause horzDir', o, this.defs);
        var self = this;

        this.animCss = o.vertical ? 'top' : 'left';
        this.sizeCss = o.vertical ? 'height' : 'width';

        var ul = dgTools.$(o.id);
        if (!ul) return null;
        o.btnPrev = dgTools.$(o.btnPrev);
        o.btnNext = dgTools.$(o.btnNext);
        if (o.btnGo) {
            for (var j = 0; j < o.btnGo.length; j++) {
                o.btnGo[j] = dgTools.$(o.btnGo[j]);
            }
        }

        var tmp = ul.getElementsByTagName('LI');
        var tLi = [];
        for (var j = 0; j < tmp.length; j++) tLi.push(tmp[j]);
        var realItemLength = tLi.length;

        if (o.scroll < 0) {
            o.reverse = true;
            o.scroll = -o.scroll;
        }

        o.offset = 0;
        var v = o.visible;
        if (o.circular && realItemLength > 0) {
            var vv = v + Math.max(o.scroll * 2, realItemLength);
            vv -= realItemLength;
            var idx = 0;
            var parent = tLi[0].parentNode;
            while (vv > 0) {
                parent.appendChild(tLi[idx].cloneNode(true));
                idx++;
                if (idx >= realItemLength) idx = 0;
                vv--;
            }
            vv = realItemLength % o.scroll;
            if (vv > 0) {
                vv = Math.max(vv, v);
                o.offset = vv;
                var f = parent.firstChild;
                var el = null;
                idx = realItemLength - 1;
                for (var j = 0; j < vv; j++) {
                    el = tLi[idx].cloneNode(true);
                    parent.insertBefore(el, f);
                    f = el;
                    idx--;
                    if (idx < 0) idx = realItemLength - 1;
                }
                f = el = null;
            }
        }

        tmp = ul.getElementsByTagName('LI');
        var li = [];
        for (var j = 0; j < tmp.length; j++) li[j] = tmp[j];

        if (o.horzDir == 'auto' && !o.vertical) {
            if (li[0] && dgTools.Elm.getRenderedStyle(li[0], 'float') == 'right') o.horzDir = 'right';
            else o.horzDir = 'left';
        }
        for (var j = 0; j < li.length; j++) {
            li[j].style.overflow = 'hidden';
            li[j].style.float = o.vertical ? "none" : o.horzDir;
        }

        var itemLength = li.length;
        var curr = o.start;
        o.offset2 = itemLength - o.offset - realItemLength;
        if (o.horzDir == 'right') {
            var vv = o.offset2 - parseInt(o.offset2 / realItemLength, 10) * realItemLength;
            if (vv > 0) curr += vv;
            curr += realItemLength - o.visible;
            while (curr < 0) curr += realItemLength;
        }
        else {
            curr += o.offset;
        }

        var liSize = 0;
        if (realItemLength > 0) {
            liSize = o.vertical ? (li[0].offsetHeight || li[0].clientHeight) : (li[0].offsetWidth || li[0].clientWidth);
            if (o.vertical) {
                var t = parseInt(dgTools.Elm.getRenderedStyle(li[0], 'margin-top'), 10);
                var b = parseInt(dgTools.Elm.getRenderedStyle(li[0], 'margin-bottom'), 10);
                liSize += (t > b) ? t : b;
            }
            else {
                liSize += parseInt(dgTools.Elm.getRenderedStyle(li[0], 'margin-right'), 10);
                liSize += parseInt(dgTools.Elm.getRenderedStyle(li[0], 'margin-left'), 10);
            }
        }

        var ulSize = liSize * itemLength;
        ul.style[this.sizeCss] = ulSize + 'px';
        ul.style[this.animCss] = -(curr * liSize) + 'px';

        if (o.btnPrev) {
            dgTools.observe(o.btnPrev, 'click', function() { return go(o.reverse ? curr + o.scroll : curr - o.scroll); })
        }
        if (o.btnNext) {
            dgTools.observe(o.btnNext, 'click', function() { return go(o.reverse ? curr - o.scroll : curr + o.scroll); })
        }
        if (o.btnGo) {
            for (var j = 0; j < o.btnGo.length; j++) {
                var btnGo = o.btnGo[j];
                if (btnGo) btnGo.idx = j;
                dgTools.observe(btnGo, 'click', function() { self.stopAuto(); return go(o.circular ? o.visible + btnGo.idx : btnGo.idx); })
            }
        }
        if (o.mouseWheel) {
            dgTools.observe(ul, 'mousewheel', function(e) {
                var evt = e || event;
                aaa = evt;
                if (evt.wheelDelta > 0 && !o.reverse) go(curr - o.scroll);
                else go(curr + o.scroll);
                if (evt.stopPropagation) evt.stopPropagation();
                else evt.cancelBubble = true;
                if (evt.preventDefault) evt.preventDefault();
                else evt.returnValue = false;
                return true;
            })
        }
        if (o.auto) {
            if (o.hoverPause) {
                dgTools.hover(ul, function() { stopAuto(); }, function() { startAuto(); });
                if (o.btnPrev) dgTools.hover(o.btnPrev, function() { stopAuto(); }, function() { startAuto(); });
                if (o.btnNext) dgTools.hover(o.btnNext, function() { stopAuto(); }, function() { startAuto(); });
            }
            startAuto();
        };

        function go(to) {
            if (!self.running && realItemLength > 0) {
                var reverse = to < curr;
                if (o.circular) {
                    if (to < o.start) {
                        do {
                            to += realItemLength;
                        } while (to < o.start);
                        if (reverse) ul.style[self.animCss] = (-((to + o.scroll) * liSize)) + 'px';
                        else ul.style[self.animCss] = (-((to - o.scroll) * liSize)) + 'px';
                        curr = to;
                    }
                    else if (to > o.start + v + o.scroll + 1) {
                        do {
                            to -= realItemLength;
                        } while (to > o.start + v + o.scroll + 1);
                        if (to < o.start) to += realItemLength;
                        if (reverse) ul.style[self.animCss] = (-((to + o.scroll) * liSize)) + 'px';
                        else ul.style[self.animCss] = (-((to - o.scroll) * liSize)) + 'px';
                        curr = to;
                    } else {
                        curr = to;
                    }
                } else {
                    if (to < 0 || to > itemLength - v) return; else curr = to;
                }
                self.running = true;
                dgTools.easyAnimate(
                    ul,
                    null,
                    self.animCss == "left" ? { left: -(curr * liSize)} : { top: -(curr * liSize) },
                    o.speed,
                    o.fps,
                    function() { self.running = false },
                    dgTools.Transitions.swing
                );
                if (!o.circular) {
                    if (o.btnPrev) dgTools.Elm.removeClassName(o.btnPrev, 'disabled');
                    if (o.btnNext) dgTools.Elm.removeClassName(o.btnNext, 'disabled');
                    if (o.btnPrev &&
                    (((curr - o.scroll < 0) && !o.reverse) ||
                    ((curr + o.scroll > itemLength - v) && o.reverse))) o.btnPrev.className += ' disabled';
                    if (o.btnNext &&
                    (((curr - o.scroll < 0) && o.reverse) ||
                    ((curr + o.scroll > itemLength - v) && !o.reverse))) o.btnNext.className += ' disabled';
                }
            }
            return false;
        };
        function startAuto() {
            self.autoInterval = setInterval(function() {
                if (o.reverse) go(curr - o.scroll);
                else go(curr + o.scroll);
            }, o.auto + o.speed);
        };
        function stopAuto() {
            clearInterval(self.autoInterval);
            self.autoInterval = null;
        };

        return this;
    }
};

