(function($) {
	$.extend({
		tablesorterPager: new function() {
			
			function updatePageDisplay(c, paging) {
			    var s = '';
				//s = $(c.cssPageDisplay,c.container).val((c.page+1) + c.seperator + c.totalPages);	
				s = $(c.cssPageDisplay,c.container).html(c.totalRows);
				s = $(c.cssPageDisplay,c.containerAdditional).html(c.totalRows);
				
				var displayString = '';
				
				if((paging == true) && ( (c.page == 0) || (c.page + 1 == c.totalPages) || (c.page + 1 == c.pageCounterLowerBound) || (c.page == c.pageCounterUpperBound))){
				    if(c.totalPages > c.displayedPages){
				        c.pageCounterUpperBound = c.displayedPages;
				    } else {
				        c.pageCounterUpperBound = c.totalPages;
				    }
    				
				    if(c.page + 1 > c.displayedPages){
				        c.pageCounterLowerBound = c.page + 1 - c.displayedPages;
				        c.pageCounterUpperBound = c.pageCounterLowerBound + c.displayedPages;
				    } else {
				        c.pageCounterLowerBound = 0;
				    }	
				}	
				
				for(i=c.pageCounterLowerBound;i<c.pageCounterUpperBound;i++){
				    if (i != c.page){
				        displayString += '<a href="javascript:$.tablesorterPager.moveToParticularPage(' + parseInt(i) + ')">' + parseInt(i+1) + '</a>&nbsp;&nbsp;'
				    } else {
				        displayString += parseInt(i+1) + '&nbsp;&nbsp;'
				    }    
				}
				
				if(c.pageCounterUpperBound < c.totalPages){
				    displayString += '...'
				}
				
				s = $(c.cssPageLinksDisplay,c.container).html(displayString);
				s = $(c.cssPageLinksDisplay,c.containerAdditional).html(displayString);	
				
				document.getElementById('selectedPage').value = c.page;
				
				if(c.page == 0){
				    $("a[class*='first']").removeClass("pagingFirst");
                    $("a[class*='first']").addClass("pagingFirstInactive");
                    $("a[class*='prev']").removeClass("pagingBackward");
                    $("a[class*='prev']").addClass("pagingBackwardInactive");
				} else {
				    $("a[class*='first']").removeClass("pagingFirstInactive");
                    $("a[class*='first']").addClass("pagingFirst");
                    $("a[class*='prev']").removeClass("pagingBackwardInactive");
                    $("a[class*='prev']").addClass("pagingBackward");
				}
				
				if(c.page == c.totalPages-1){
				    $("a[class*='last']").removeClass("pagingLast");
                    $("a[class*='last']").addClass("pagingLastInactive");
                    $("a[class*='next']").removeClass("pagingForward");
                    $("a[class*='next']").addClass("pagingForwardInactive");
				} else {
				    $("a[class*='last']").removeClass("pagingLastInactive");
                    $("a[class*='last']").addClass("pagingLast");
                    $("a[class*='next']").removeClass("pagingForwardInactive");
                    $("a[class*='next']").addClass("pagingForward");
				}
				
				if(c.totalRows == 0){
				    $("a[class*='first']").css("display","none");
				    $("a[class*='prev']").css("display","none");
				    $("a[class*='next']").css("display","none");
				    $("a[class*='last']").css("display","none");				   
				} else {
				    $("a[class*='first']").css("display","inline-block");
				     $("a[class*='prev']").css("display","inline-block");
				    $("a[class*='next']").css("display","inline-block");
				    $("a[class*='last']").css("display","inline-block");				   
				}
			}
			
			function setPageSize(table,size) {
				var c = table.config;
				c.size = size;
				c.totalPages = Math.ceil(c.totalRows / c.size);
				c.pagerPositionSet = false;
				moveToPage(table, true);
				fixPosition(table);
			}
			
			function fixPosition(table) {
				var c = table.config;
				if(!c.pagerPositionSet && c.positionFixed) {
					var c = table.config, o = $(table);
					if(o.offset) {
						c.container.css({
							top: o.offset().top + o.height() + 'px',
							position: 'absolute'
						});
					}
					c.pagerPositionSet = true;
				}
			}
			
			function moveToFirstPage(table) {
				var c = table.config;
				c.page = 0;
				moveToPage(table, true);
			}
			
			function moveToLastPage(table) {
				var c = table.config;
				c.page = (c.totalPages-1);
				moveToPage(table, true);
			}
			
			function moveToNextPage(table) {
				var c = table.config;
				c.page++;
				if(c.page >= (c.totalPages-1)) {
					c.page = (c.totalPages-1);
				}
				moveToPage(table, true);
			}
			
			function moveToPrevPage(table) {
				var c = table.config;
				c.page--;
				if(c.page <= 0) {
					c.page = 0;
				}
				moveToPage(table, true);
			}
						
			
			function moveToPage(table, paging) {
				var c = table.config;
				if(c.page < 0 || c.page > (c.totalPages-1)) {
					c.page = 0;
				}
				
				renderTable(table,c.rowsCopy,paging);
			}
			
			function renderTable(table,rows,paging) {
				
				var c = table.config;
				var l = rows.length;
				var s = (c.page * c.size);
				var e = (s + c.size);
				if(e > rows.length ) {
					e = rows.length;
				}
				
				
				var tableBody = $(table.tBodies[0]);
				
				// clear the table body
				
				$.tablesorter.clearTableBody(table);
				
				for(var i = s; i < e; i++) {
					
					//tableBody.append(rows[i]);
					
					var o = rows[i];
					var l = o.length;
					for(var j=0; j < l; j++) {
						
						tableBody[0].appendChild(o[j]);

					}
				}
				
				fixPosition(table,tableBody);
				
				$(table).trigger("applyWidgets");
				
				if( (c.page >= c.totalPages) && (l > 0) ) {
        			moveToLastPage(table);
				}
				
				updatePageDisplay(c,paging);
			}
			
			this.moveToParticularPage = function(index) {
			    var c = config;
			    
			    c.page = index;
			    moveToPage(table, false);
			}
			
			this.appender = function(table,rows) {
				
				var c = table.config;
				
				c.rowsCopy = rows;
				c.totalRows = rows.length;
				c.totalPages = Math.ceil(c.totalRows / c.size);
				
				renderTable(table,rows,true);
			};
			
			this.defaults = {
				size: 10,
				offset: 0,
				page: 0,
				totalRows: 0,
				totalPages: 0,
				displayedPages: 4,
				pageCounterLowerBound: 0,
				pageCounterUpperBound: 0,
				container: null,
				containerAdditional: null,
				cssNext: '.next',
				cssPrev: '.prev',
				cssFirst: '.first',
				cssLast: '.last',
				cssPageDisplay: '.pagedisplay',
				cssPageLinksDisplay: '.pagelinksdisplay',
				cssPageSize: '.pagesize',
				seperator: "/",
				positionFixed: true,
				appender: this.appender
			};
			
			this.construct = function(settings) {
				
				return this.each(function() {	
					
					config = $.extend(this.config, $.tablesorterPager.defaults, settings);
					
					table = this, pager = config.container, pagerAdditional = config.containerAdditional;
				
					$(this).trigger("appendCache");
					
					config.size = parseInt($(".pagesize",pager).val());
					
					$(config.cssFirst,pager).click(function() {
						moveToFirstPage(table);
						$("html, body").animate({scrollTop: 0 },0);
						return false;
					});
					$(config.cssNext,pager).click(function() {
						moveToNextPage(table);
						$("html, body").animate({scrollTop: 0 },0);
						return false;
					});
					$(config.cssPrev,pager).click(function() {
						moveToPrevPage(table);
						$("html, body").animate({scrollTop: 0 },0);
						return false;
					});
					$(config.cssLast,pager).click(function() {
						moveToLastPage(table);
						$("html, body").animate({scrollTop: 0 },0);
						return false;
					});
					$(config.cssPageSize,pager).change(function() {
						setPageSize(table,parseInt($(this).val()));
						return false;
					});
					
					$(config.cssFirst,pagerAdditional).click(function() {
						moveToFirstPage(table);
						$("html, body").animate({scrollTop: 0 },0);
						return false;
					});
					$(config.cssNext,pagerAdditional).click(function() {
						moveToNextPage(table);
						$("html, body").animate({scrollTop: 0 },0);
						return false;
					});
					$(config.cssPrev,pagerAdditional).click(function() {
						moveToPrevPage(table);
						$("html, body").animate({scrollTop: 0 },0);
						return false;
					});
					$(config.cssLast,pagerAdditional).click(function() {
						moveToLastPage(table);
						$("html, body").animate({scrollTop: 0 },0);
						return false;
					});
					$(config.cssPageSize,pagerAdditional).change(function() {
						setPageSize(table,parseInt($(this).val()));
						return false;
					});
				});
			};
			
		}
	});
	// extend plugin scope
	$.fn.extend({
        tablesorterPager: $.tablesorterPager.construct
	});
	
})(jQuery);				
