﻿jQuery.fn.adidoPager = function(options) {
    var currentPage = 1; // Current page of the pager
    var pageHeight = 0; // Height of the items on the current page
    var oldPageHeight = 0; // Height of the page before the next page is clicked
    var listTop = 0; // Top coordinate of the list (used to animate)
    var newsList = $(this);
    var pager, animate, newPager, totalPages, totalItems, pageStart, pageEnd, pageStartOffset, pageEndOffset, moving;
    
    /***********************************
    **          Settings              **
    ***********************************/
    jQuery.fn.adidoPager.settings = jQuery.extend ({
        pageSize : 5,
        pagerTop : null,
        pagerBottom : null,
        pagerClass : 'pager',
        summaryClass : 'summary',
        scrollTime : 800,
        nextText : "Next",
        prevText : "Prev",
        summaryText : "Displaying XXX to YYY of ZZZ pages",
        easing : "swing",
        queueEffects : false,
		listItem : 'li'
    }, options);
    
    var settings = $.fn.adidoPager.settings;
    
    /***********************************
    **             Init               **
    ***********************************/
    function init(){
        moving = false;
        if (settings.scrollTime == 0) {animate = false;}
        newsList.wrap($("<div id='pagedItemsWrap'></div>").css({
		    overflow : 'hidden',
		    position : 'relative'
	    }));
        newsList.css({
            position : 'relative',
            top : 0
        });
        newsList.css({
            'margin-top' : 0,
            'padding-top' : 0,
            'border-top' : 0,
            'margin-bottom' : 0,
            'padding-bottom' : 0,
            'border-bottom' : 0
        });
    }
        
    /***********************************
    **     Create pager and links     **
    ***********************************/
    function createPager() {
        totalPages = Math.ceil(newsList.children(settings.listItem).size() / settings.pageSize);
        if (currentPage > totalPages) currentPage = totalPages;
        /***********************
        ** "Page x of y" text **
        ***********************/
        var summaryText = settings.summaryText;
        summaryText = summaryText.replace(/XXX/gi, "<span class='pagerCurrentStart'>X</span>");
        summaryText = summaryText.replace(/YYY/gi, "<span class='pagerCurrentEnd'>Y</span>");
        summaryText = summaryText.replace(/ZZZ/gi, "<span class='pagerTotalItems'>Z</span>");
        
        var summary = $('<span class="pagerSummary"></span>');
        summary.html(summaryText);
        
        /***************************
        **     Numbered Pager     **
        ***************************/
        newPager = $('<ul class="' + settings.pagerClass + '"></ul>');
        
        // Previous page link
        addListItem(settings.prevText, "prev");
        for(i=1; i <= totalPages; i++){
            addListItem(i, "page" + i);
        }
        addListItem(settings.nextText, "next");
    
        /***********************************
        **        Add Pager to page       **
        ***********************************/
        if(settings.pagerTop != null){ 
            newPager.clone(true).appendTo(settings.pagerTop); 
            summary.clone(true).appendTo(settings.pagerTop); 
        }
        if(settings.pagerBottom != null){ 
            newPager.clone(true).appendTo(settings.pagerBottom); 
            summary.clone(true).appendTo(settings.pagerBottom); 
        }
        
        /***********************************
        **       Pager Link Listener      **
        ***********************************/
        pager = $('ul.pager');
        pager.find('li.page1 a').addClass('active');
        
        pager.find('li a').not('li.next a')
                          .not('li.prev a')
                          .click (function(e){
            e.preventDefault();
            pager.find('li a').removeClass('active');
            currentPage = parseInt($(this).html());
            pager.find('li.page' + currentPage + ' a').addClass('active');
            updatePages();
        });
        
        /*******************************
        ** Next / Previous Page links **
        *******************************/
        pager.find('li.next a').click (function(e){
            e.preventDefault();
            if (currentPage < totalPages && moving == false){
                currentPage += 1;
                updatePages();
            }
        });
        
        pager.find('li.prev a').click (function(e){
            e.preventDefault();
            if (currentPage > 1 && moving == false){
                currentPage -= 1;
                updatePages();
            }    
        });
    };
    
    function addListItem(label, class){
        var listItem = $('<li></li>');
        listItem.addClass(class);
        var link = $('<a href="#"></a>');
        
        link.html(label);
        link.appendTo(listItem);
        listItem.appendTo(newPager);
    };
    
    /***********************************
    **      Page Update Function      **
    ***********************************/
    function updatePages(animate){
        if (moving == false || settings.queueEffects == true){
            // Flag as moving to stop clicks queueing
            moving = true;
            
            if (animate != false) {animate = true;}
            var oldPageStart = pageStart;
            var oldPageEnd = pageEnd;
            
            /**********************************************************
            ** Get the index of the first and last items on the page **
            **********************************************************/
            if (currentPage * settings.pageSize >= totalItems){
                // If this is the last page
                pageEnd = totalItems;
                pageEndOffset = newsList.children(settings.listItem).eq(pageEnd - 1).position().top + newsList.children(settings.listItem).eq(pageEnd - 1).outerHeight(true);
                pageStart = currentPage * settings.pageSize - settings.pageSize;
            }
            else {
                // All but the last page
                pageEnd = settings.pageSize * currentPage;
                pageEndOffset = newsList.children(settings.listItem).eq(pageEnd).position().top;
                pageStart = currentPage * settings.pageSize - settings.pageSize;
            }
            /*****************************************
            ** Calculate the height of the new page **
            *****************************************/
            oldPageHeight = pageHeight;
            pageStartOffset = newsList.children(settings.listItem).eq(pageStart).position().top;
            pageHeight = pageEndOffset - pageStartOffset;
            
            /********************************************************************
            ** Change the wrapper's height to match the height of the new page **
            ********************************************************************/
            listTop = newsList.children(settings.listItem).eq(pageStart).position().top;
            
            if (animate){
                $('#pagedItemsWrap').animate({height : pageHeight + 'px'}, settings.scrollTime, settings.easing);
                newsList.animate({top : -listTop + 'px'}, settings.scrollTime, settings.easing,
                                    function() {
                                        moving = false;
                                    });
            } else {
                $('#pagedItemsWrap').css ({height : pageHeight + 'px'}, settings.scrollTime);
                newsList.css({top : -listTop + 'px'}, settings.scrollTime);
                moving = false;
            }
            
            /******************************************
            ** Update Pager to indicate current page **
            ******************************************/
            if (currentPage == totalPages){
                pager.find('li.next a').addClass('disabled');
            } else {
                pager.find('li.next a').removeClass('disabled');
            }
            
            if (currentPage == 1){
                pager.find('li.prev a').addClass('disabled');
            } else {
                pager.find('li.prev a').removeClass('disabled');
            }
            pager.find('li a').removeClass('active');
            pager.find('li.page' + currentPage + ' a').addClass('active');
            
            $('span.pagerCurrentStart').html(pageStart + 1);
            $('span.pagerCurrentEnd').html(pageEnd);
            $('span.pagerTotalItems').html(totalItems);
        }
    };
    
    jQuery.fn.adidoPager.regen = function (){
        settings.pagerTop.html("");
        settings.pagerBottom.html("");
        newsList.unwrap($('#pagedItemsWrap'));
        start();
    }
    
    function start(){
        init();
        createPager();
        totalItems = newsList.children(settings.listItem).size();
        updatePages(false);
    }
    
    start();
};

