var Paginator = {
    PREVIOUS_STUB:   "<span class=\"previous nav disabled\"><img src=\"http://static.operator11.com/img/buttons/pagination/previous-disabled.gif\" alt=\"&lt; Previous\" \/><\/span>",
    PREVIOUS_BUTTON: "<a href=\"#\" class=\"previous nav enabled\"><img src=\"http://static.operator11.com/img/buttons/pagination/previous.gif\" alt=\"&lt; Previous\" \/><\/a>",
    NEXT_STUB:   "<span class=\"next nav disabled\"><img src=\"http://static.operator11.com/img/buttons/pagination/next-disabled.gif\" alt=\"Next &gt;\" \/><\/span>",
    NEXT_BUTTON: "<a href=\"#\" class=\"next nav enabled\"><img src=\"http://static.operator11.com/img/buttons/pagination/next.gif\" alt=\"Next &gt;\" \/><\/a>"
};

Paginator.Base = Class.create();
Paginator.Base.prototype = {
    initialize: function() {},
    updateCurrentPage: function() {},

    moveForward: function() {
        if (this.onLastPage()) return;
        this.currentPage += 1;
        this.updateCurrentPage();
        return false;
    },
    moveBack: function() {
        if (this.onFirstPage()) return;
        this.currentPage -= 1;
        this.updateCurrentPage();
        return false;
    },
    setupNavigationHandles: function() {
        if (this.element.previous() && this.element.previous().hasClassName("nav"))
            this.element.previous().remove();
        if (this.element.next() && this.element.next().hasClassName("nav"))
            this.element.next().remove();

        new Insertion.Before(this.element, this.onFirstPage() ? Paginator.PREVIOUS_STUB : Paginator.PREVIOUS_BUTTON);
        new Insertion.After(this.element, this.onLastPage() ? Paginator.NEXT_STUB : Paginator.NEXT_BUTTON);

        this.element.previous().observe("click", this.moveBack.bind(this));
        this.element.next().observe("click", this.moveForward.bind(this));
    },
    getCurrentPage: function() {
        return this.pages[this.currentPage - 1];
    },
    onFirstPage: function() {
        return this.currentPage == 1;
    },
    onLastPage: function() {
        return this.currentPage == this.pages.size();
    },
    wrap: function() {
        this.element.wrap().up().id = "pagination-for-" + this.element.id;
    }
}

Paginator.Local = Class.create();
Paginator.Local.prototype = Object.extend(new Paginator.Base(), {
    initialize: function(element) {
        this.element = $(element);
        this.options = Object.extend({
            pageSize: 4,
            startingPage: 1
        }, arguments[1] || {});

        this.wrap();

        this.pages = this.element.immediateDescendants().inGroupsOf(this.options.pageSize).map(function(page) {
            return page.reject(function(item) {
                return item == null;
            });
        });

        this.currentPage = this.options.startingPage;
        this.updateCurrentPage();

        this.setupNavigationHandles();
    },
    updateCurrentPage: function() {
        this.pages.reject(function(page) { 
            return page == this.getCurrentPage();
        }.bind(this)).invoke("invoke", "hide");
        this.getCurrentPage().invoke("show");
        this.setupNavigationHandles();
    }
});

window.paginatorInstances = [];

Paginator.Ajax = Class.create();
Paginator.Ajax.prototype = Object.extend(new Paginator.Base(), {
    initialize: function(element, elementTotal, updateUrl) {
        window.paginatorInstances.push(this);
        this.element = $(element);
        this.url = updateUrl;
        this.options = Object.extend({
            pageSize: 4,
            startingPage: 1,
            pageParameter: "page",
            sizeParameter: "per_page",
            callOnComplete: function(){}
        }, arguments[3] || {});
        this.pages = new Array((elementTotal / this.options.pageSize).ceil());
        this.wrap();

        this.currentPage = this.options.startingPage;
        this.callOnComplete = this.options.callOnComplete;
        this.setupNavigationHandles();

        this.pages[this.currentPage - 1] = this.element.innerHTML; //this.element.immediateDescendants();
    },
    updateCurrentPage: function() {
        this.setupNavigationHandles();
        if (this.pages[this.currentPage - 1] && this.pages[this.currentPage - 1].length > 0) {
            this.element.update(this.getCurrentPage());
            this.callOnComplete();
            if (this.options.afterMove)
              this.options.afterMove(this.currentPage);
            return;
        }

        var parameters = { t: new Date().getTime() };
        parameters[this.options.pageParameter] = this.currentPage;
        parameters[this.options.sizeParameter] = this.options.pageSize;
        
        new Ajax.Updater(this.element, this.url, {
            method: "get",
            parameters: parameters,
            onComplete: function(request) {
                this.pages[this.currentPage - 1] = this.element.innerHTML;
                this.callOnComplete();
                if (this.options.afterMove)
                  this.options.afterMove(this.currentPage);
            }.bind(this)
        });
    }
});
