/**
 * Ajax Paginator
 */

(function($) {
    $.fn.paginator = function(options) {
        var container = this;
        var options = $.extend({
            paginator    : '.pagination',
            urlPageParam : 'p',
            startCallback: null,
            endCallback  : null
        }, options);
        var serverRequest = null;
        
        /**
         * Init class
         */
        function init() {
            // event delegation for paginator
            container.click(function (e) {
                var link = $(e.target);
                if ((link.is('a') || link.is('span')) && link.parents(options.paginator).length) {
                    if (link.is('span')) {
                        link = link.parent();
                    }
                    requestPage(link.attr('href'));
                    return false;
                }
            });
        }
        
        /**
         * Show a loading message using the
         * provided message engine
         */
        function showLoading() {
            container.fadeOut('fast');
            options.startCallback && options.startCallback(container);
        }
        
        /**
         * Hide the loading message by hooking
         * the message engine persistent alert and
         * hiding it smoothly
         */
        function hideLoading() {
            container.fadeIn('fast');
            options.endCallback && options.endCallback(container);
        }
        
        /**
         * Hide all objects and push new one in page
         * Data already come in HTML, so rebind event
         * to the paginator.
         * It also call the callback if any
         * 
         * param {object} data Server object returned
         */
        function insertPage(data) {
            container.html(data.join('\n'));
            serverRequest = null;
            hideLoading();
        }
        
        /**
         * call the server-side service to get pagnied object
         * 
         * param {int} href Url arguments
         */
        function requestPage(url) {
            // Prevent multiple concurent calls
            if (serverRequest !== null) {
                serverRequest.abort();
            } else {
                showLoading();
            }
            // Generic AJAX call
            serverRequest = $.post(url, { js: true }, insertPage, 'json');
        }
        
        init();
    };
})(jQuery);

