/**
 * Represents a page flipper tool.
 * To use this, create an instance, set the amountPerPage, currentPage and totalItems variables and call setup().
 */
function Paginator() {
}

/** Amount of items displayed per page */
Paginator.prototype.amountPerPage = 8;
/** Current page */
Paginator.prototype.currentPage = 1;
/** Total amount of items */
Paginator.prototype.totalItems = 0;
/** Page numbers to show around the current page */
Paginator.prototype.aroundPages = 3;
/** Callback; set using setCallback(). */
Paginator.prototype.callback = false;

/**
 * Returns the amount of pages.
 * @return number Amount of pages
 */
Paginator.prototype.getNumberOfPages = function() {
	return Math.ceil(this.totalItems / this.amountPerPage);
}

/**
 * Sets the callback. This callback will be called with a page number when the page number changes.
 * It should re-run Paginator.setup(); after being called.
 */
Paginator.prototype.setCallback = function(callback) {
	this.callback = callback;
}

/**
 * Creates a pagination button.
 * @param string Text to display
 * @param number Page number to go to
 * @return HTMLListElement
 */
Paginator.prototype.makeButton = function(text, pageNum) {
	var element, href, self;
	element = document.createElement('li');
	if(pageNum == this.currentPage) {
		element.appendChild(document.createTextNode(text));
	}
	else {
		href = document.createElement('a');
		href.setAttribute('href', '#');
		href.appendChild(document.createTextNode(text));
		element.appendChild(href);
	}
	
	self = this;
	
	if(this.currentPage == pageNum) {
		element.setAttribute('class', 'current');
		element.setAttribute('className', 'current');
	}
	
	// DOM way
	if(element.addEventListener) {
		element.addEventListener('click', function() {
			self.goPage(pageNum);
		}, false);
	}
	// IE way
	else if(element.attachEvent) {
		element.attachEvent('onclick', function() {
			self.goPage(pageNum);
		});
	}
	
	return element;
}

/**
 * Goes to a given page.
 * @param number Page number to go to
 * @return void
 */
Paginator.prototype.goPage = function(page) {
	this.currentPage = page;
	if(this.callback) {
		this.callback(page);
	}
}

/**
 * Sets up the pagination.
 * @return void
 */
Paginator.prototype.setup = function(element) {
	// Empty the element
	while(element.childNodes[0]) {
		element.removeChild(element.childNodes[0]);
	}

	var pages;
	
	//      <<           <              1              7               >           >>
	var dispFirst, dispBack, dispStartPage, dispEndPage, dispForward, dispLast;
	pages = this.getNumberOfPages();
	
	// Don't show pagination for zero to one page(s)
	if(pages <= 1)
		return;
	
	// Display the first page button if we are at page 3 or above.
	if(this.currentPage >= 3)
		dispFirst = true;
	
	// Display the previous page button if we are at page 2 or above.
	if(this.currentPage >= 2)
		dispBack = true;
	
	// Display up to $aroundPages pages around or less if we would go negative.
	dispStartPage = this.currentPage - this.aroundPages;
	if(dispStartPage < 1)
		dispStartPage = 1;
	
	dispEndPage = this.currentPage + this.aroundPages;
	if(dispEndPage > pages)
		dispEndPage = pages;
	
	// Display the forward button if we can go forward and aren't on the last or next-to-last page.
	if(this.currentPage < pages)
		dispForward = true;

	// Display the last button if we aren't on the last page.
	if(this.currentPage < (pages - 1))
		dispLast = true;
	
	if(dispFirst)
		element.appendChild(this.makeButton('<<', 1));

	if(dispBack)
		element.appendChild(this.makeButton('<', this.currentPage - 1));
	
	for(var i = dispStartPage; i <= dispEndPage; ++i) {
		element.appendChild(this.makeButton(i, i));
	}
	
	if(dispForward)
		element.appendChild(this.makeButton('>', this.currentPage + 1));

	if(dispLast)
		element.appendChild(this.makeButton('>>', pages));
}

