var TABLE_HEIGHT = 200;
var BUFFER_MAX_SIZE = 200;
var PAGE_SIZE = 150; /* SHUOLD MATCH BACK-END CONFIGURATION: See PageConstants.java */
var DEFAULT_WIDTH = 940;
function AjaxScrollbar(tableID, dwrFuncName, dwrParams, populateFunc, pageNumParamName, tableWidth) {
	PAGE_SIZE = 150;
	this.init(tableID, dwrFuncName, dwrParams, populateFunc, pageNumParamName, tableWidth);
}
function AjaxScrollbar(tableID, dwrFuncName, dwrParams, populateFunc, pageNumParamName, tableWidth, overridingPage_SIZE) {
	if(overridingPage_SIZE == undefined){	
		PAGE_SIZE = 150;
	}else{
		PAGE_SIZE =  overridingPage_SIZE;
	}
	this.init(tableID, dwrFuncName, dwrParams, populateFunc, pageNumParamName, tableWidth);
}
AjaxScrollbar.prototype.init = function(tableID, dwrFuncName, dwrParams, populateFunc, pageNumParamName, tableWidth) {
	this.tableID = tableID;
	this.dwrFuncName = dwrFuncName;
	this.pageNumParamName = (pageNumParamName != null) ? pageNumParamName : "pageNum";
	this.dwrParams = dwrParams;
	this.tableWidth = tableWidth != null ? tableWidth : DEFAULT_WIDTH;
	this.lastScrollTop = -10;
	this.waitingForResponse = false;
	this.firstPage = 1;
	this.lastPage = 2;
	this.bottom = false;
	this.bufferSize = 0;
	this.lastBuferSize = 0;
	this.populateFunc = populateFunc;	
	this.scrolledByJS = false;
	this.lastResponseSize = 1000;
	this.lastDirection = "bottom";
	this.lastPageRequest = 1;
};
AjaxScrollbar.prototype.initScrollbar = function(ajaxObj, initialBufferSize,tableHeight) {
	// Cleaning up the mess of scrollable table before initializing new one
	var temp = $("#scrollableDiv" + ajaxObj.tableID+"0").contents();
	$("#scrollableDiv" + ajaxObj.tableID+"0").replaceWith(temp);
	//Sometimes there might be another scrollableDiv if ScrollableTabl object was initialized from JS file other than AjaxScrollbar
	var temp = $("#scrollableDiv" + ajaxObj.tableID+"0").contents();
	$("#scrollableDiv" + ajaxObj.tableID+"0").replaceWith(temp);
	$("#"+ajaxObj.tableID + " tbody").css("height","auto");
	if (tableHeight == null)
		tableHeight = TABLE_HEIGHT; 
	ajaxObj.st = new ScrollableTable(document.getElementById(ajaxObj.tableID), tableHeight, ajaxObj.tableWidth,ajaxObj.scrollListener,ajaxObj);
	this.bufferSize = (initialBufferSize!=null) ? initialBufferSize : 0;
};
/* Retrieve */
AjaxScrollbar.prototype.scrollListener = function(scrollTop, height,scrollableDiv,ajaxScrollObj) {
	if (ajaxScrollObj.scrolledByJS) { ajaxScrollObj.scrolledByJS=false; }
	else {
		if (!ajaxScrollObj.waitingForResponse ) {
			/* User has scrolled down */
			if ( (((ajaxScrollObj.bufferSize <= 20) && scrollTop / height >= 0.25)
					||
					((ajaxScrollObj.bufferSize >= 20) && scrollTop / height >= 0.65))
					&&  scrollTop > ajaxScrollObj.lastScrollTop) {
				if (!(ajaxScrollObj.lastDirection == "bottom" && ajaxScrollObj.lastResponseSize == 0)) {
					eval("ajaxScrollObj.dwrParams." + ajaxScrollObj.pageNumParamName + " = ajaxScrollObj.lastPage;");
					ajaxScrollObj.bottom = true;
					ajaxScrollObj.lastScrollTop = scrollTop;
					ajaxScrollObj.invokeDWR(ajaxScrollObj, scrollTop);
				}
			}
			/* User has scrolled up */
			else if (scrollTop / height <= 0.40 &&  scrollTop <= ajaxScrollObj.lastScrollTop) {
				if (!(ajaxScrollObj.lastDirection == "top" && ajaxScrollObj.lastPageRequest == 1)) {
					ajaxScrollObj.bottom = false;
					eval("ajaxScrollObj.dwrParams." + ajaxScrollObj.pageNumParamName + " = " + (ajaxScrollObj.firstPage-1) + ";");
					ajaxScrollObj.lastScrollTop = scrollTop;
					ajaxScrollObj.invokeDWR(ajaxScrollObj, scrollTop);
				}
			} else {
				ajaxScrollObj.lastScrollTop = scrollTop;
			}
		}
	}
};
AjaxScrollbar.prototype.invokeDWR = function(ajaxScrollObj,scrollTop) {
	if (
		( (!ajaxScrollObj.bottom) && !(ajaxScrollObj.lastDirection == "top" && ajaxScrollObj.lastPageRequest == 1) && ajaxScrollObj.firstPage != 1)
		||
		( (ajaxScrollObj.bottom) && !(ajaxScrollObj.lastDirection == "bottom" && ajaxScrollObj.lastResponseSize == 0))
		) {
		ajaxScrollObj.waitingForResponse = true;
		disablePage();
		eval("ajaxScrollObj.lastPageRequest = ajaxScrollObj.dwrParams." + ajaxScrollObj.pageNumParamName + ";");
		eval(ajaxScrollObj.dwrFuncName + "(ajaxScrollObj.dwrParams, " +
				"{ " +
					"callback: function(responseObj) {" +
					" ajaxScrollObj.prePopulate(); " +
					"ajaxScrollObj.populateFunc(" + ajaxScrollObj.bottom + ", responseObj); " +
					"ajaxScrollObj.postPopulate(" + scrollTop + ", responseObj.bufferableResponseSize); }" +
					" } );");
	}
}
AjaxScrollbar.prototype.prePopulate = function() {
	if (this.bufferSize >= BUFFER_MAX_SIZE) {
		// Remove from top
		if (this.bottom)
		{
			//alert("Removing from 0 to " + PAGE_SIZE);
			$("#" + this.tableID + " tbody tr:lt(" + PAGE_SIZE + ")").remove();
			
		}
		else
		{
			//alert("Removing from " + (BUFFER_MAX_SIZE-PAGE_SIZE) + "To " + $("#" + this.tableID + " tbody tr").size());
			$("#" + this.tableID + " tbody tr:gt(" + (BUFFER_MAX_SIZE-this.lastResponseSize) + ")").remove();
			
		}
	}
	
};

AjaxScrollbar.prototype.postPopulate = function(newScrollTop,responseSize)
{
	
	if (this.bufferSize >= BUFFER_MAX_SIZE)
	{
		if (this.bottom)
		{
			this.firstPage++;
			this.lastPage++;
		}
		else
		{
			this.firstPage--;
			this.lastPage--;
		}
	}
	else
	{
		this.lastPage++;

		this.bufferSize +=  responseSize;
		
	}
	
	// Go back to same position

	this.lastResponseSize =  responseSize;
	if (this.bottom)
		this.lastDirection = "bottom";
	else
		this.lastDirection = "top";

	
	//if (this.lastScrollTop <
	//this.st = new ScrollableTable(document.getElementById(this.tableID), TABLE_HEIGHT , this.tableWidth,this.scrollListener,this);
	$("#" + this.tableID).scrollTop(newScrollTop);
	this.st.containerEl.scrollTop =newScrollTop; 
	this.st.tableEl.scrollTop = newScrollTop;
	$(this.st.containerEl).scrollTop(newScrollTop);
	$(this.st.tableEl).scrollTop(newScrollTop);
	$(this.st.tbody).scrollTop(newScrollTop);
	this.waitingForResponse = false;
	this.scrolledByJS = true;
	//alert("First Page is " + this.firstPage + " and last page is " + (this.lastPage-1) );
	enablePage();
	
};



