/**
 * Static functions for creating pagination
 */
(function(context, $) {

    "use strict";

    context.JK = context.JK || {};

    context.JK.Paginator = {

        $templatePaginator: null,

        /** returns a jquery object that encapsulates pagination markup.
         * It's left to the caller to append it to the page as they like.
         * @param pages the number of pages
         * @param currentPage the current page
         * @param onPageSelected when a new page is selected.  receives one argument; the page number.
         * the function should return a deferred object (whats returned by $.ajax), and that response has to have a 'total-entries' header set
         */
        create:function(totalEntries, perPage, currentPage, onPageSelected, maxPages) {

            if(this.$templatePaginator === null) {
              this.$templatePaginator = $('#template-paginator')
              if(this.$templatePaginator.length == 0) {
                throw "no #template-paginator"
              }
            }

            var $templatePaginator = this.$templatePaginator;


            function calculatePages(total, perPageValue) {
                return Math.ceil(total / perPageValue);
            }


            function attemptToMoveToTargetPage(targetPage) {

                // 'working' == click guard
                var working = paginator.data('working');
                if(!working) {
                    paginator.data('working', true);

                    onPageSelected(targetPage)
                        .done(function(data, textStatus, jqXHR) {
                            totalEntries = data.total_entries || parseInt(jqXHR.getResponseHeader('total-entries'));
                            pages = calculatePages(totalEntries, perPage);
                            options = { pages: pages,
                                currentPage: targetPage };

                            // recreate the pagination, and
                            var newPaginator = $(context._.template($templatePaginator.html(), options, { variable: 'data' }));
                            registerEvents(newPaginator);
                            paginator.replaceWith(newPaginator);
                            paginator = newPaginator;
                        })
                        .always(function() {
                            paginator.data('working', false);
                        });
                }
                else {

                }
            }

            function registerEvents(paginator) {
                $('a.page-less', paginator).click(function(e) {
                    var currentPage = parseInt(paginator.attr('data-current-page'));
                    if (currentPage > 0) {
                        var targetPage = currentPage - 1;
                        attemptToMoveToTargetPage(targetPage);
                    }
                    else {
                        // do nothing
                    }
                    return false;
                });

                $('a.page-more', paginator).click(function(e) {

                    var currentPage = parseInt(paginator.attr('data-current-page'));
                    if (currentPage <  pages - 1) {
                        var targetPage = currentPage + 1;
                        attemptToMoveToTargetPage(targetPage);
                    }
                    else {
                        // do nothing
                    }
                    return false;
                });

                $('a.page-link', paginator).click(function(e) {
                    var targetPage = parseInt($(this).attr('data-page'));
                    attemptToMoveToTargetPage(targetPage);
                    return false;
                });
            }


            var pages = calculatePages(totalEntries, perPage);


            if(maxPages) {
                if((totalEntries / perPage) > maxPages) {
                    pages = calculatePages(maxPages * perPage, perPage);
                }
            }

            var options = { pages: pages,
                            currentPage: currentPage };

            var paginator = $(context._.template($templatePaginator.html(), options, { variable: 'data' }));

            registerEvents(paginator);

            return paginator;
        }
    }
})(window, jQuery);