var SlidingPagingControls = new Class({
    initialize: function(pagingControls) {
        this._pagingControls = pagingControls;
        this._pagingBox = pagingControls.getElement('#sliding-paging-box');
        this._pageList = pagingControls.getElement('ul');
        this._scrollWidth = 0;
        this._startingPage = 0;
        this._slider = pagingControls.getElement('.slider');
        this._sliderHandle = this._slider.getElement('.slider-handle');
        this._calcAndSetScrollWidth();
    },

    activate: function() {
        if (this._scrollWidth > 0) {
            var startingPercentage = this._calcStartingPercentage(this._startingPage);
            this._slideList(startingPercentage);
            new Slider(
                this._slider,
                this._sliderHandle,
                {
                    wheel: true,
                    steps: 100,
                    initialStep: Math.round(startingPercentage * 100),
                    onChange: function(percentage) {
                        this._slideList(percentage / 100);
                    }.bind(this)
                }
            );
        } else {
            this._slider.dispose();
        }
    },

    _calcAndSetScrollWidth: function() {
        var firstItem = $(this._pageList.firstChild);
        var lastItem = $(this._pageList.lastChild);
        var listWidth = lastItem.getPosition(firstItem).x + lastItem.getSize().x
                        + 1; // compensate for any rounding errors
        this._pageList.setStyle('width', listWidth + 'px');

        var sliderSize = $(this._pageList.parentNode).getSize().x;
        $(this._slider.parentNode).setStyle('width', sliderSize + 'px');

        this._scrollWidth = listWidth - sliderSize;

        // find the starting page
        var i;
        var len;
        for (i = 0, len = this._pageList.childNodes.length; i < len; ++i) {
            if ($(this._pageList.childNodes[i]).hasClass('current')) {
                this._startingPage = i;
                break;
            }
        }
    },

    _slideList: function(percent) {
        this._pageList.parentNode.scrollLeft = Math.round(percent * this._scrollWidth);
    },

    _getItemSize: function(itemIndex) {
        return $(this._pageList.childNodes[itemIndex]).getSize().x;
    },

    /**
     * Calculate the starting slider percentage so that the current page is
     * roughly centered.
     *
     * We add the first item to the right of the starting page, then the first
     * item to the left, then the second item to the right, then the second to
     * the left, ... until they no longer fit. Then we calculate the slider
     * percentage required to scroll to the rightmost page.
     */
    _calcStartingPercentage: function(startingPageIdx) {
        var sizeOfPagesThatFit = this._getItemSize(startingPageIdx);
        var maxSize = $(this._pageList.parentNode).getSize().x;
        var pageCount = this._pageList.childNodes.length;
        var distance = 0;
        var rightPageIdx;
        var sizeRight;
        var anyRightPagesRemaining = true;
        var leftPageIdx;
        var sizeLeft;
        var anyLeftPagesRemaining = true;
        var indexOfRightMostPageThatFits = startingPageIdx;
        while (anyRightPagesRemaining && anyLeftPagesRemaining) {
            distance++;

            rightPageIdx = startingPageIdx + distance;
            if (rightPageIdx < pageCount) {
                sizeRight = this._getItemSize(rightPageIdx);
                if (sizeRight + sizeOfPagesThatFit <= maxSize) {
                    sizeOfPagesThatFit += sizeRight;
                    indexOfRightMostPageThatFits = rightPageIdx;
                } else {
                    break;
                }
            } else {
                anyRightPagesRemaining = false;
            }

            leftPageIdx = startingPageIdx - distance;
            if (leftPageIdx > 0) {
                sizeLeft = this._getItemSize(leftPageIdx);
                if (sizeLeft + sizeOfPagesThatFit <= maxSize) {
                    sizeOfPagesThatFit += sizeLeft;
                } else {
                    break;
                }
            } else {
                anyLeftPagesRemaining = false;
            }
        }
        var rmpCoordinates = $(this._pageList.childNodes[indexOfRightMostPageThatFits]).getCoordinates();
        var requiredScrolling =
            rmpCoordinates.right -
            this._pageList.firstChild.getCoordinates().left -
            maxSize;
        requiredScrolling = Math.max(requiredScrolling, 0);
        return (requiredScrolling / this._scrollWidth);
    }
});

window.addEvent('domready', function() {
    var pagingControls = $('sliding-paging-controls');
    if (pagingControls) {
        new SlidingPagingControls(pagingControls).activate();
    }
});

