/**
 * Emv ajax paginator.
 */
if ('undefined' === typeof(Emv.Paginator)) {

    Emv.Paginator = {};
}

/**
 * Constructor.
 * 
 * @param string url
 * @param string replaceElement
 * @param string httpMethod ('GET', 'POST', default: 'GET')
 * @param string contentType
 * @param string urlGetParams
 * @param string scrollTo
 */
Emv_Paginator_Ajax = function(url, replaceElement, httpMethod, contentType, urlGetParams, scrollTo) {

    this.url                      = url;
    this.urlGetParams             = urlGetParams;
    this.urlPostParams            = null;
    this.replaceElement           = replaceElement;
    this.httpMethod               = httpMethod;
    this.contentType              = contentType;
    this.linkedPaginatorSlider    = null;
    this.linkedPaginatorCarrousel = null;
    this.requestedPage            = 1;
    this.currentPage              = 1;
    this.pageCount                = 1;
    this.pageRange                = 10;
    this.id                       = null;
    this.scrollTo			      = scrollTo;

    if (!this.httpMethod) {

        this.httpMethod = 'GET';
    }
};

/**
 * Set target url.
 * 
 * @param string url
 */
Emv_Paginator_Ajax.prototype.setUrl = function(url) {

    this.url = url;
};

/**
 * Set target url GET-parameters.
 * 
 * @param string params
 */
Emv_Paginator_Ajax.prototype.setUrlGetParams = function(params) {

    this.urlGetParams = params;
};

/**
 * Set target url POST-parameters.
 * 
 * @param string params
 */
Emv_Paginator_Ajax.prototype.setUrlPostParams = function(params) {

    this.urlPostParams = params;
};

/**
 * Set 'scrollTo'-Position.
 * 
 * @param string scrollTo
 */
Emv_Paginator_Ajax.prototype.setScrollTo = function(scrollTo) {

    this.scrollTo = scrollTo;
};

/**
 * Set link to a 'Emv.Paginator.Slider'-instance.
 * 
 * @param object slider
 */
Emv_Paginator_Ajax.prototype.linkPaginatorSlider = function(slider) {

    this.linkedPaginatorSlider = slider;
};

/**
 * Set link to a 'Emv.Carrousel'-instance.
 * 
 * @param object carrousel
 */
Emv_Paginator_Ajax.prototype.linkPaginatorCarrousel = function(carrousel) {

    this.linkedPaginatorCarrousel = carrousel;
};

/**
 * Set current page.
 * 
 * @param integer page
 */
Emv_Paginator_Ajax.prototype.setCurrentPage = function(page) {

    this.currentPage = parseInt(page, 10);
};

/**
 * Set page count.
 * 
 * @param integer count
 */
Emv_Paginator_Ajax.prototype.setPageCount = function(count) {

    this.pageCount = parseInt(count, 10);
};

/**
 * Set page range.
 * 
 * @param integer pageRange
 */
Emv_Paginator_Ajax.prototype.setPageRange = function(pageRange) {

    this.pageRange = parseInt(pageRange, 10);
};

/**
 * Set paginator element id.
 * 
 * @param string id
 */
Emv_Paginator_Ajax.prototype.setId = function(id) {

    this.id = id;
};

/**
 * Redirect to next page.
 */
Emv_Paginator_Ajax.prototype.pageNext = function() {

    if (this.pageCount <= this.currentPage) {

        return;
    }

    this.pageTo(parseInt(this.currentPage, 10) + 1);
};

/**
 * Redirect to previous page.
 */
Emv_Paginator_Ajax.prototype.pagePrevious = function() {

    if (this.currentPage <= 1) {

        return;
    }

    this.pageTo(parseInt(this.currentPage, 10) - 1);
};

/**
 * Set params for alpabet navigation.
 * 
 * @param string urlGetParams
 * @param integer pageCount
 */
Emv_Paginator_Ajax.prototype.reuseInAlphabet = function(urlGetParams, pageCount) {

    pageCount = parseInt(pageCount, 10);

    this.setUrlGetParams(urlGetParams);
    this.linkedPaginatorSlider.setPageCount(pageCount, false);
    this.setPageCount(pageCount);
    this.pageTo(1);
};

/**
 * Paging function.
 * 
 * @param integer page
 * @uses jQuery.ajax (http://api.jquery.com/jQuery.ajax/)
 * @uses jQuery.browser (http://api.jquery.com/jQuery.browser/)
 */
Emv_Paginator_Ajax.prototype.pageTo = function(page) {

    page = parseInt(page, 10);

    this.requestedPage = page;
    this.currentPage   = page;
    paginator          = this;

    if (this.url !== '' && this.url != '/') {

        $('#ajax_wrap' + this.replaceElement).find('.ajax-loading-overlay').show();

        var target    = ($.browser.opera) ? 'html' : 'html,body';
        var scrollPos = 0;

        if ('undefined' !== typeof(paginator.scrollTo) && null !== paginator.scrollTo && '' !== paginator.scrollTo) {

            scrollPos = $('#' + paginator.scrollTo).position().top;
        } else {

            if (null !== $('#ajax_wrap' + paginator.replaceElement).position()) {

                scrollPos = $('#ajax_wrap' + paginator.replaceElement).position().top;
            }
        }

        if (scrollPos > 0) {

            $(target).animate({ scrollTop: scrollPos }, 'fast');
        }

        var getParams = '';
        if (undefined !== this.urlGetParams && '' !== this.urlGetParams) {

            getParams = '?' + this.urlGetParams;
        }

        $.ajax({
            url: this.url + 'seite-' + page + getParams,
            success: function(data, status, xhr) {

                Emv_Paginator_Ajax.prototype.handleSuccess(data, xhr, paginator);
            },
            error: function(xhr, textStatus, errorThrown) {

                Emv_Paginator_Ajax.prototype.handleError(xhr, paginator);
            }
        });
    } else {

        paginator.linkedPaginatorSlider.reinit(parseInt(paginator.requestedPage, 10));
    }

    if (paginator.linkedPaginatorCarrousel !== 'undefined' && paginator.linkedPaginatorCarrousel !== null) {

        paginator.linkedPaginatorCarrousel.scroll(page);
    }

    this.checkButtons();
};

/**
 * Set custom css-styles to buttons after paging.
 */
Emv_Paginator_Ajax.prototype.checkButtons = function() {

    // Enable/Disable buttons (also needed for statistics)!
    if (this.currentPage == 1) {

        $('#paginator-' + this.id).find('a.arrow-backward').addClass('disabled');
    } else {

        $('#paginator-' + this.id).find('a.arrow-backward').removeClass('disabled');
    }

    if (this.currentPage == this.pageCount) {

        $('#paginator-' + this.id).find('a.arrow-forward').addClass('disabled');
    } else {

        $('#paginator-' + this.id).find('a.arrow-forward').removeClass('disabled');
    }
};

/**
 * Handle ajax-success of Emv_Paginator_Ajax.pageTo().
 * 
 * @param string data
 * @param string response
 * @param object paginator
 */
Emv_Paginator_Ajax.prototype.handleSuccess = function(data, xhr, paginator) {

    if (paginator.contentType == 'html') {

        $('#' + paginator.replaceElement).html(data);

        // Try to execute embedded js code from ajax response.
        scriptCodes = $('#' + paginator.replaceElement + ' > script');

        for (i = 0; i < scriptCodes.length; i++) {

            try {

                eval(scriptCodes[i].innerHTML);
            } catch (e) {}
        }
    }

    if (paginator.contentType == 'json') {

        var json = xhr.responseText.substring(xhr.responseText.indexOf('{'), xhr.responseText.lastIndexOf('}') + 1);
        var data = eval('(' + json + ')');

        // If controller returns no data - do not overwrite playlist(?) with nothing...
        // So error == true is returned to skip this
        if ('undefined' !== typeof(data.error) && data.error === true) {

            return;
        }

        container.innerHTML = data.html;
        eval(data.js);
    }

    if (paginator.linkedPaginatorSlider) {

        paginator.linkedPaginatorSlider.reinit(parseInt(paginator.requestedPage, 10));
    }

    $('#ajax_wrap' + paginator.replaceElement).find('.ajax-loading-overlay').hide();
};

/**
 * Handle ajax-errors of Emv_Paginator_Ajax.pageTo().
 * 
 * @todo implement something useful.
 * @param object xhr
 * @param object paginator
 */
Emv_Paginator_Ajax.prototype.handleError = function(xhr, paginator) {};

/**
 * Constructor for the Paginator Slider.
 *
 * @param string elementId
 * @param integer pageCount
 * @param integer pageRange
 * @param integer currentPage
 * @param string basePrefix
 * @param string baseSuffix
 * @param boolean isAjax
 */
Emv.Paginator.Slider = function(elementId, pageCount, pageRange, currentPage, basePrefix, baseSuffix, isAjax) {
    
    element = document.getElementById(elementId);

    //Variables
    this.baseElement = element;
    this.elementId   = elementId;
    this.pageCount   = pageCount;
    this.currentPage = currentPage;
    this.pageRange   = pageRange;
    this.basePrefix  = basePrefix;
    this.baseSuffix  = baseSuffix;
    this.isAjax      = isAjax;

    this.init();
};

/**
 * re inits the slider with a new element and new currentPage
 * mainly used if you reload content by ajax
 */
Emv.Paginator.Slider.prototype.reinit = function(currentPage) {

    element = document.getElementById(this.elementId);
    this.baseElement = element;
    this.currentPage = currentPage;
    this.init();
};

/**
 * Update the PageCount
 *
 * @param {Object} pageCount
 */
Emv.Paginator.Slider.prototype.setPageCount = function(pageCount, init)
{
    this.pageCount = pageCount;
    if ('undefined' != init && false !== init) {

        this.init();
    }
};

/**
 * Update the PageRange
 *
 * @param {Object} pageRange
 */
Emv.Paginator.Slider.prototype.setPageRange = function(pageRange)
{
    this.pageRange = pageRange;
    this.init();
};

/**
 * Inits the slider
 */
Emv.Paginator.Slider.prototype.init = function() {

    element = this.baseElement;

    //html elements
    this.scrollbar 			= $(element).find('div.scrollbar')[0];
    this.sliderBackground  	= $(element).find('div.sliderBackground')[0];
    this.positionIndicator 	= $(element).find('div.positionIndicator')[0];


    //Load other stuff
    this.buildSlider();
    this.drawPaginator();
    this.setupEvents();

    this.scrollToCurrentPage();
    this.setPositionIndicator();
};

/**
 * sets the width of the sliderBackground
 */
Emv.Paginator.Slider.prototype.buildSlider = function() {

    this.sliderBackground.xPos = 0;
    this.sliderBackground.style.display = 'inline';

    if (this.pageRange > this.pageCount) {

        this.sliderBackground.style.width = '100%';
    }
    else
    {

        this.sliderBackground.style.width = this.pageRange / this.pageCount * 100 + '%';
    }
};

/**
 * Sets the slider to the correct position on the bar
 */
Emv.Paginator.Slider.prototype.setSlider = function()
{
    this.sliderBackground.style.left = this.sliderBackground.xPos + 'px';
};

/**
 * Redraws the Pager and sets the slider to the correct position
 */
Emv.Paginator.Slider.prototype.drawPaginator = function()
{
    percentFromLeft = this.sliderBackground.xPos/(this.scrollbar.offsetWidth);

    //happens if pager is on a not visible tab so we init it with 0
    if (isNaN(percentFromLeft))
    {
        percentFromLeft = 0;
    }

    baseValue = Math.round(percentFromLeft * this.pageCount);

    if (baseValue < 1)
    {
        baseValue = 1;
        this.sliderBackground.xPos = 0;
        this.setSlider();
    }
    else if (baseValue >= (this.pageCount - this.pageRange))
    {
            baseValue = this.pageCount - this.pageRange + 1;
            this.sliderBackground.xPos = this.scrollbar.offsetWidth - this.sliderBackground.offsetWidth;
            this.setSlider();
    }

    if (baseValue < 1)
    {
        baseValue                  = 1;
        this.sliderBackground.xPos = 0;
        this.setSlider();
    }

    subElements = this.baseElement.getElementsByTagName('A');

    for(var i=0; i< subElements.length; i++)
    {
        curValue = baseValue + i;
        $(subElements[i]).removeClass('active');

        if (curValue == this.currentPage)
        {
            $(subElements[i]).addClass('active');
        }
        else
        {
            $(subElements[i]).addClass('paginatorLink');
        }

        if (this.isAjax)
        {
            subElements[i].href = this.basePrefix + curValue + this.baseSuffix;
        }
        else
        {
            if (curValue > 1 )
            {
                subElements[i].href = this.basePrefix + '/seite-' + curValue + this.baseSuffix;
            }
            else
            {
                subElements[i].href = this.basePrefix + this.baseSuffix;
            }
        }

        subElements[i].innerHTML   = curValue;
        subElements[i].style.width = (String(this.pageCount).length * 8.1) + 'px';
    }
};

/**
 * Setups the on Click eg. events to the slider
 */
Emv.Paginator.Slider.prototype.setupEvents = function() {
    var _this = this;

    this.sliderBackground.onmousedown = function(e)
    {
        if (!e)
        {
            var e = $.event.fix(window.event);
        }

        e.cancelBubble = true;

        if (e.stopPropagation)
        {
            e.stopPropagation();
        }

        this.dx = e.pageX - this.xPos;

        document.onmousemove = function(e)
        {
            if (!e)
            {
                var e = $.event.fix(window.event);
            }

            _this.sliderBackground.xPos = e.pageX - _this.sliderBackground.dx;
            _this.setSlider();
            _this.drawPaginator();
        };

        document.onmouseup = function()
        {
            document.onmousemove = null;
            _this.enableSelection();
        };

        _this.disableSelection();
    };

    this.scrollbar.onmousedown = function(e)
    {
        if (!e)
        {
            var e = $.event.fix(window.event);
        }

        _this.sliderBackground.xPos =
            e.pageX - $(_this.scrollbar).pageX - _this.sliderBackground.offsetWidth/2;
        _this.setSlider();
        _this.drawPaginator();
    };
};

/**
 * Scrolls to current Page
 */
Emv.Paginator.Slider.prototype.scrollToCurrentPage = function()
{
    this.sliderBackground.xPos = (this.currentPage - Math.round(this.pageRange/2))/this.pageCount * this.scrollbar.offsetWidth;
    this.setSlider();
    this.drawPaginator();
};

/**
 * Sets the positionIndicator to the correct Position
 */
Emv.Paginator.Slider.prototype.setPositionIndicator = function()
{

    if(this.currentPage == 1)
    {
        this.positionIndicator.style.left = 0;
    }
    else
    {
        this.positionIndicator.style.left = this.currentPage/this.pageCount * this.scrollbar.offsetWidth + 'px';
    }
};

/**
 * Disables that a mouse selection selects anythifg on the page
 */
Emv.Paginator.Slider.prototype.disableSelection = function()
{

    document.onselectstart = function()
    {
        return false;
    };

    this.sliderBackground.focus();
};

/**
 * Enables that selecting with the mouse works.
 */
Emv.Paginator.Slider.prototype.enableSelection = function()
{
    document.onselectstart = function()
    {
        return true;
    };

    this.sliderBackground.blur();
};
