/** A pluggable paging/navigation object
 * 
 * @author EricS <esatire@gmail.com>
 * @version 1.0rc1 07/08/2007
 */

/** The semi-abstract class constructor
 * 
 * The DOM should contain 2 objects for this:
 * 1) A container for content with some id with id + _container
 * 2) A container for the pages navigator with id + _pagenavigator
 * For example a DIV with id "shmulik_container" and another DIV with id "shmulik_pagenavigator"
 * 
 * @param elementIdPrefix{string} As explained above
 * @param numPerPage{int} how many items are in each page
 * @param pageSpan{int} optional - how many page links will be created
 */
function PageNavigator(elementIdPrefix, numPerPage, pageSpan)
{
	// since it's meant to be used as a parent a lot,
	// It will only be inited if containerId was entered
	if (elementIdPrefix)
	{
		this.container = document.getElementById(elementIdPrefix + "_container");
		this.pageNavigator = document.getElementById(elementIdPrefix + "_pagenavigator");
		var myself = this;
		this.curPage = -1;
		this.totalPages = 0;
		if (numPerPage) this.numPerPage = numPerPage;
		this.pageSpan = (pageSpan) ? 3 : pageSpan;
		this.request = null; // for ajax. Init through function
		this.serverScript = null;

		// pluggable methods
		this.onPageRequest = function(){};
		this.onLink = function(){ myself.requestPage(parseInt(this.id)); }
	}
}
/** Called on page set - feel free to overrid when needed */
PageNavigator.prototype.boundCheck = function(pageNum)
{
	if (pageNum < 0 || pageNum > this.totalPages) return false;
	return true;
}
PageNavigator.prototype.setPage = function(pageNum)
{
	this.curPage = pageNum;
	this.createPagingLinks();
}
/** When sending the ajax request */
PageNavigator.prototype.requestPage = function(pageNum)
{
	if (this.boundCheck(pageNum))
	{
		this.onPageRequest(pageNum);
	}
}
PageNavigator.prototype.nextPage = function()
{
	this.requestPage(this.curPage+1);
}
PageNavigator.prototype.nextPage = function()
{
	this.requestPage(this.curPage+1);
}
PageNavigator.prototype.setNumItems = function(numItems)
{
	this.totalPages = Math.ceil(numItems/this.numPerPage);
}
/** Creates the actual links in the pagenavigator DOM element */
PageNavigator.prototype.createPagingLinks = function()
{
	if (this.totalPages <= 1)
	{
		this.pageNavigator.innerHTML = '';
		return;
	}

	var navigatorHTML = new Array();
	var iStart,iEnd;
	if (this.curPage <= this.pageSpan)
	{
		iStart = 0;
		iEnd   = this.pageSpan*2;
	}
	else if (this.curPage > (this.totalPages-1)-this.pageSpan)
	{
		iStart = this.totalPages - 1 - this.pageSpan*2;
		iEnd   = this.totalPages;
	}
	else
	{
		iStart = this.curPage-this.pageSpan;
		iEnd   = this.curPage+this.pageSpan;
	}
	// out of bounds fix
	if (iEnd > (this.totalPages-1)) iEnd = (this.totalPages-1);
	if (iStart < 0) iStart = 0;
	
	if (iStart > 0) navigatorHTML.push("<span class='link' id='0'>1&lt;&lt;</span>");

	for (var i=iStart; i<=iEnd;i++)
	{
		if (i != this.curPage)
		{
			navigatorHTML.push("&nbsp;<span class='link' id='"+i+"'> " + (i+1) + " </span>");
		}
		else
		{ // it has a span so we can give it a different style than the '...' parts 
			navigatorHTML.push("&nbsp;<span class='active'> "+(i+1)+" </span>");
		}
	}

	if (iEnd < (this.totalPages-1))
	{
		navigatorHTML.push ("&nbsp;<span class='link' id='"+(this.totalPages-1)+"'>&gt;&gt;"+this.totalPages+"</span>");
	}

	this.pageNavigator.innerHTML = navigatorHTML.join('');

	// work on the links
	var links = this.pageNavigator.getElementsByTagName('span');
	for (var i=0;i<links.length;i++)
	{
		if (links[i].id)
		{
			links[i].onclick = this.onLink;
			links[i].style.cursor = 'pointer';
		}
	}
}
/** Basic functionality for request results - when the responseText is the block's HTML */
PageNavigator.prototype.onRequestResult = function(responseText,pageNum,count_id)
{
	this.container.innerHTML = responseText;
	var count;
	try
	{
		count = parseInt(document.getElementById(count_id).innerHTML);
		if (isNaN(count)) count = 0;
	}
	catch (ex)
	{
		count = 0;
	}
	this.setNumItems(count);
	this.setPage(pageNum);
}

/** Used as a namespace for common navigator functions - for older code
 * @deprecated 07/08/2007 
 */
function DynamicNavigator(){}

DynamicNavigator.PageNavigatorCalc = function(currentPage,totalPages,pageSpan,varName)
{
	if (totalPages <= 1) return '';

	var navigatorHTML = '',iStart,iEnd;
	if (currentPage <= pageSpan)
	{
		iStart = 0;
		iEnd   = pageSpan*2;
	}
	else if (currentPage > (totalPages-1)-pageSpan)
	{
		iStart = totalPages - pageSpan*2;
		iEnd   = totalPages;
	}
	else
	{
		iStart = currentPage-pageSpan;
		iEnd   = currentPage+pageSpan;
	}
	// out of bounds fix
	if (iEnd > (totalPages-1)) iEnd = (totalPages-1);
	if (iStart < 0) iStart = 0;
	
	if (iStart > 0)
		navigatorHTML += "<a class='member' href='javascript:"+varName+".SetPage(0)'>-1-</a> ... ";

	for (var i=iStart; i<=iEnd;i++)
	{
		if (i != currentPage)
		{
			navigatorHTML +=  " <a class='member' href='javascript:" + varName + '.SetPage('
								+ i + ")'>-" + (i+1) + "-</a> ";
		}
		else navigatorHTML += " <span class='memberPink'>-"+(i+1)+"-</span> ";
	}

	if (iEnd < (totalPages-1))
	{
		navigatorHTML += " ... <a class='member' href='javascript:"+varName+
		".SetPage("+(totalPages-1)+")'>-"+totalPages+"-</a>";
	}
	return navigatorHTML;
}