(function($) {
	$.extend({
		tablesorterPager: new function() {
		
			function updatePageDisplay(table) {
				var c = table.config;

				var pager = "";
				
				if(c.totalPages > 1) {
					var pagerBreak = '...&nbsp;';
					
					var currPage = c.page + 1;
					
					if(currPage == 1) {
						pager += '<span class="uwrTablePagingArrows">|&lt;</span>&nbsp;<span class="uwrTablePagingArrows">&lt;</span>&nbsp;';
					} else {
						pager += '<a class="uwrTablePagingArrows first" href="javascript:void(0)">|&lt;</a>&nbsp;' + 
							'<a class="uwrTablePagingArrows prev" href="javascript:void(0)">&lt;</a>&nbsp;';
					}
					
					var maxOfNumbers = 7;
					
					if(c.totalPages > maxOfNumbers) {
						var minLeftRight = 2;
						var start = 0;
						var end = 0;
						
						if(currPage > maxOfNumbers-minLeftRight || currPage > Math.ceil(c.totalPages/2)) {
							pager += pagerBreak;
							
							// Handling the right side of the paging number series
							if(currPage > c.totalPages-maxOfNumbers+minLeftRight) {
								end = c.totalPages;
								start = end-maxOfNumbers+1;
							} else if(currPage > Math.ceil(c.totalPages/2)){
								start=currPage-minLeftRight;
								end=start+maxOfNumbers-1;
							}
							
							if(currPage < Math.ceil(c.totalPages/2)) { // Handling the left floating part
								end = currPage+minLeftRight;
								start=end-maxOfNumbers+1;
							}
							
							if(currPage == Math.ceil(c.totalPages/2)){
								var halfMaxOfNumbers = Math.floor(maxOfNumbers / 2); // -> 3
								start = currPage -halfMaxOfNumbers;
								end=currPage +halfMaxOfNumbers;
							}
						} else if(currPage == Math.ceil(c.totalPages/2)){
								var halfMaxOfNumbers = Math.floor(maxOfNumbers / 2); // -> 3
								if(currPage>halfMaxOfNumbers+1){
									pager += pagerBreak;
								}
								start = currPage -halfMaxOfNumbers;
								end=currPage +halfMaxOfNumbers;
						} else { // Handling the left part
							start = 1;
							end = maxOfNumbers;
						}
	
						for (var page = start; page <= end; page++) {
							pager += '<a class="uwrTablePaging pageLink' + (page-1) + '" href="javascript:void(0)">' + page + '</a>' + '&nbsp;';
						}
						
						if(end < c.totalPages) {
							pager += pagerBreak;
						}
					} else {
						// Case in which no paging breaks are needed
						for (var page = 1; page <= c.totalPages; page++) {
							pager += '<a class="uwrTablePaging pageLink' + (page-1) + '" href="javascript:void(0)">' + page + '</a>&nbsp;';
						}
					}
					
					if(currPage == c.totalPages) {
						pager += '<span class="uwrTablePagingArrows">&gt;</span>&nbsp;<span class="uwrTablePagingArrows">&gt;|</span>';
					} else {
						pager += '<a class="uwrTablePagingArrows next" href="javascript:void(0)">&gt;</a>&nbsp;' + 
							'<a class="uwrTablePagingArrows last" href="javascript:void(0)">&gt;|</a>';
					}
				}
				
				var s = $(c.cssPageDisplay,$(table).parent()).html(pager);
				//var p = $(".pages",c.container).html((currPage) + c.seperator + c.totalPages); // Dev only

				$('.pageLink' + c.page,$(table).parent()).addClass('uwrTablePagingSelected');
				
				for (var page = 0; page < c.totalPages; page++) {
					$('.pageLink' + page,$(table).parent()).bind('click', {pageNumber: page}, function(event) {
						moveToPageNumber(table,event.data.pageNumber);
					});
				}
				
				$(config.cssFirst,c.container).click(function() {
					moveToFirstPage(table);
					return false;
				});
				$(config.cssNext,c.container).click(function() {
					moveToNextPage(table);
					return false;
				});
				$(config.cssPrev,c.container).click(function() {
					moveToPrevPage(table);
					return false;
				});
				$(config.cssLast,c.container).click(function() {
					moveToLastPage(table);
					return false;
				});
			}
			
			function setPageSize(table,size) {
				var c = table.config;
				c.size = size;
				c.totalPages = Math.ceil(c.totalRows / c.size);
				c.pagerPositionSet = false;
				moveToPage(table);
				fixPosition(table);
			}
			
			function fixPosition(table) {
				var c = table.config;
				if(!c.pagerPositionSet && c.positionFixed) {
					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;
				if(c.page!=0){
					c.page = 0;
					moveToPage(table);
				}
			}
			
			function moveToLastPage(table) {
				var c = table.config;
				if(c.page!=c.totalPages-1){
					c.page = (c.totalPages-1);
					moveToPage(table);
				}
			}
			
			function moveToNextPage(table) {
				var c = table.config;
				c.page++;
				if(c.page >= (c.totalPages-1)) {
					c.page = (c.totalPages-1);
				}
				moveToPage(table);
			}
			
			function moveToPrevPage(table) {
				var c = table.config;
				c.page--;
				if(c.page <= 0) {
					c.page = 0;
				}
				moveToPage(table);
			}
			
			function moveToPage(table) {
				var c = table.config;
				if(c.page < 0 || c.page > (c.totalPages-1)) {
					c.page = 0;
				}
				
				renderTable(table,c.rowsCopy);
			}
			
			function moveToPageNumber(table,number) {
				var c = table.config;
				c.page = number;
				moveToPage(table);
			}
			
			function renderTable(table,rows) {
			
				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);
				//alert("number of row pairs: "+e);
				for(var i = s; i < e; i++) {
					
					//tableBody.append(rows[i]);
					
					var o = rows[i];
					var l2 = o.length;
					
					//alert("number of records taht belong together: "+l2);
					
					for(var j=0; j < l2; j++) {
						tableBody[0].appendChild(o[j]);
					}
				}
				
				fixPosition(table,tableBody);
				
				$(table).trigger("applyWidgets");
				
				if( c.page >= c.totalPages ) {
					moveToLastPage(table);
				}
				
				// Passing the table instead of the config
				updatePageDisplay(table);
			}
			
			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);
			};
			
			this.defaults = {
				size: 20,
				offset: 0,
				page: 0,
				totalRows: 0,
				totalPages: 0,
				container: null,
				cssNext: '.next',
				cssPrev: '.prev',
				cssFirst: '.first',
				cssLast: '.last',
				cssPageDisplay: '.pagedisplay',
				cssPageSize: '.pagesize',
				seperator: "/",
				positionFixed: false,
				appender: this.appender
			};
			
			this.construct = function(settings) {
				
				return this.each(function() {	
					
					config = $.extend(this.config, $.tablesorterPager.defaults, settings);

					var table = this;

					if(config.container===null && $(this).attr('rows').length > config.size){
						$(this).parent().append('<div id="' + $(this).attr('id') + '-pager" class="pager textAlignRight" style="width:100%;direction:ltr"><div class="pagedisplay"><!--Leave this empty--></div></div>');
						config.container = $('#' + $(table).attr('id') + '-pager');
					}
					
					// To be triggered by the tablesorter endSort callback
					$(this).bind("moveToFirstPage", function(){
						moveToFirstPage(table);
						return false;
					});

					$(this).trigger("appendCache");
				});
			};
			
		}
	});
	// extend plugin scope
	$.fn.extend({
        tablesorterPager: $.tablesorterPager.construct
	});
	
})(jQuery);

