function AjaxPagination(countPerPage, shownPages, totalResults, callbackFunction, paginationDivs, className, anchor) {
	this.setCountPerPage(countPerPage);
	this.setShownPages(shownPages);
	this.setTotalResults(totalResults);
	this.setCallbackFunction(callbackFunction);

	this.currentClassName = 'current';
	this.disabledClassName = 'disabled';

	this.currentPage = 0;

	if (typeof className == 'object') {
	    this.className = className.className;
	    if (className.currentPage) {
	        this.currentClassName = className.currentPage;
	    }
	    if (className.disabledPage) {
	        this.disabledClassName = className.disabledPage;
	    }
	} else {
	   this.className = className;
	}
	this.anchor = anchor;

	if (typeof paginationDivs == 'object') {
		this.paginationDivs = paginationDivs;
	}

	this.showButtonsIfInactive = true;

	this.buttons = {
	    firstPage: '<<<',
	    prevSection: '<<',
	    prevPage: '<',
	    nextPage: '>',
	    nextSection: '>>',
	    lastPage: '>>>'
	};
	this.currentClassName = 'current';
	this.startPage = 1;
}

AjaxPagination.prototype.setShowButtonsIfInactive = function(f)
    {
        if (f) this.showButtonsIfInactive = true;
        else this.showButtonsIfInactive = false;
    };

AjaxPagination.prototype.setCountPerPage = function(countPerPage)
	{
		switch (typeof countPerPage) {
			case 'string':
				this.countPerPage = countPerPage.parseInt();
				break;
			case 'number':
				this.countPerPage = Math.floor(countPerPage);
				break;
			default:
				throw "Invalid countPerPage type";
		}
	};

AjaxPagination.prototype.setShownPages = function(shownPages)
	{
		switch (typeof shownPages) {
			case 'string':
				this.shownPages = shownPages.parseInt();
				break;
			case 'number':
				this.shownPages = Math.floor(shownPages);
				break;
			default:
				throw "Invalid countPerPage type";
		}
	};


AjaxPagination.prototype.setTotalResults = function(totalResults)
	{
		switch (typeof totalResults) {
			case 'string':
				this.totalResults = totalResults.parseInt();
				break;
			case 'number':
				this.totalResults = Math.floor(totalResults);
				break;
			default:
				throw "Invalid countPerPage type";
		}
	};

AjaxPagination.prototype.setCallbackFunction = function(callbackFunction)
	{
		this.callbackFunction = callbackFunction;
	};


AjaxPagination.prototype.show = function(flag) {
	var div;
	var i;
	for (var i = 0, len = this.paginationDivs.length; i < len; ++i) {
		div = $(this.paginationDivs[i]);
		if (div) {
		    if (flag) {
		        div.show();
		    } else {
		        div.hide();
		    }
		}
	}
}
AjaxPagination.prototype.paginate = function(userData) {
	var pag = this.startPage;
	var totalPages;
	var firstShownPage = 0;
	var lastShownPage = 0;
	var delta = 0;
	var pagString = '';
	var element;

	this.delDivContents();

	totalPages = Math.ceil(this.totalResults / this.countPerPage);

    this.show(false);

	if (totalPages <= 1) {
		return;
	}


	if (totalPages <= this.shownPages) {
		firstShownPage = 1;
		lastShownPage = totalPages;
	} else {
		firstShownPage = Math.round(pag - (this.shownPages / 2));
		lastShownPage = Math.round(pag + (this.shownPages / 2)) - 1;

		if (firstShownPage < 1) {
			delta = 1 - firstShownPage;
		}

		if (lastShownPage > totalPages) {
			delta = totalPages - lastShownPage;
		}

		firstShownPage += delta;
		lastShownPage += delta;

		if (lastShownPage > totalPages) {
			lastShownPage = totalPages;
		}

		if (firstShownPage < 1) {
			firstShownPage = 1;
		}
	}

	if (this.buttons.firstPage) {
    	if (pag > 1) {
    		this.addPageButton(this.buttons.firstPage, true, 1);
    	} else if (this.showButtonsIfInactive) {
    		this.addPageButton(this.buttons.firstPage, false);
    	}
	}

	if (this.buttons.prevSection) {
    	if (pag - this.shownPages <= firstShownPage && pag - this.shownPages >= 1) {
    		this.addPageButton(this.buttons.prevSection, true, pag - this.shownPages);
    	} else if (this.showButtonsIfInactive) {
    		this.addPageButton(this.buttons.prevSection, false);
    	}
	}

    if (this.buttons.prevPage) {
    	if (pag > 1) {
    		this.addPageButton(this.buttons.prevPage, true, pag - 1);
    	} else if (this.showButtonsIfInactive) {
    		this.addPageButton(this.buttons.prevPage, false);
    	}
    }

	for (i = firstShownPage; i <= lastShownPage; ++i) {
		if (i != pag) {
			this.addPageButton(i.toString(), true, i);
		} else {
			this.addPageButton(i.toString(), false, null, true);
		}
	}

	if (this.buttons.nextPage) {
    	if (pag < totalPages) {
    		this.addPageButton(this.buttons.nextPage, true, pag + 1);
    	} else if (this.showButtonsIfInactive) {
    		this.addPageButton(this.buttons.nextPage, false);
    	}
	}


	if (this.buttons.nextSection) {
    	if (pag + this.shownPages >= lastShownPage && pag + this.shownPages <= totalPages) {
    		this.addPageButton(this.buttons.nextSection, true, pag + this.shownPages);
    	} else if (this.showButtonsIfInactive) {
    		this.addPageButton(this.buttons.nextSection, false);
    	}
	}

    if (this.buttons.lastPage) {
    	if (pag < totalPages) {
    		this.addPageButton(this.buttons.lastPage, true, totalPages);
    	} else if (this.showButtonsIfInactive) {
    		this.addPageButton(this.buttons.lastPage, false);
    	}
    }

    this.show(true);
};

AjaxPagination.prototype.start = function(userData) {
	this.gotoPage(1, userData);
	this.userData = userData;
};

AjaxPagination.prototype.returnCall = function(totalResults, userData) {
	var numTotalResults;
	switch (typeof totalResults) {
		case 'string':
			numTotalResults = parseInt(totalResults);
			break;
		case 'number':
			numTotalResults = Math.floor(totalResults);
			break;
		default:
			numTotalResults = 0;
	}
	if (numTotalResults >= 0) {
		this.totalResults = numTotalResults;
	}

	this.paginate();
}

AjaxPagination.prototype.gotoPage = function(pageNum, userData) {
	var limit;
	var offset;
	var numResults;

	offset = (pageNum - 1) * this.countPerPage;
	this.startPage = pageNum;
	eval(this.callbackFunction + '(' + this.countPerPage + ', ' + offset + ', userData)');
};

AjaxPagination.prototype.delDivContents = function() {
	var div;
	var i;
	for (var i = 0, len = this.paginationDivs.length; i < len; ++i) {
		div = $(this.paginationDivs[i]);
		if (div) {
			while(div.childNodes.length > 0) {
				div.removeChild(div.childNodes[0]);
			}
		}
	}
};

AjaxPagination.prototype.addDivElement = function(element) {
	var div;
	var divName;
	var i;
	for (var i = 0, len = this.paginationDivs.length; i < len; ++i) {
		divName = this.paginationDivs[i];
		div = $(divName);
		if (div) {
			div.appendChild(element);
		}
	}
};


AjaxPagination.prototype.onClick = function(event) {
	var element;
	element = Event.findElement(event, 'a');
	if (element) {
		element.ajaxPagination.gotoPage(element.page, element.ajaxPagination.userData);
		if (element.ajaxPagination.anchor) {
		    a = $(element.ajaxPagination.anchor);
		    a.scrollTo();
//			window.location.hash = '#' + element.ajaxPagination.anchor;
		}
	}
}

AjaxPagination.prototype.getNewElement = function(displayText, enabled, pageNum, current) {
	var element, className, text;

    if (typeof displayText == 'object') {
        className = this.className + ' ' + displayText.className;
        text = (displayText.text?displayText.text:'');
    } else {
        className = this.className;
        text = displayText;
    }
	element = Builder.node('a', {href: 'javascript: void(0);', className: className}, text);

	if (enabled) {
		element.page = pageNum;
		element.ajaxPagination = this;
		Event.observe(element, 'click', this.onClick);
	} else {
	    if (current) {
	        element.addClassName(this.currentClassName);
	    } else {
	        element.addClassName(this.disabledClassName);
		}
	}

	return element;
}

AjaxPagination.prototype.addPageButton = function(displayText, enabled, pageNum, current) {
    var element, div, divName, i, len, image;
	for (i = 0, len = this.paginationDivs.length; i < len; ++i) {
		divName = this.paginationDivs[i];
		div = $(divName);
		if (div) {
		    element = this.getNewElement(displayText, enabled, pageNum, current);
			div.appendChild(element);
		}
	}
}

AjaxPagination.prototype.startPage = 0;
