jQuery.fn.ajaxtablesort = function(ajaxurl, options) {
	table = this;
	table.settings = jQuery.extend({
		index: 0,
		order: 0,
		offset: 0,
		rows: 20,
		total: 0,
		recordName: 'Records',
		cssHeader: 'header',
		cssAsc: 'headerSortUp',
		cssDesc: 'headerSortDown',
		cssOdd: 'odd',
		headers: {},
		first: '.first',
		previous: '.previous',
		next: '.next',
		last: '.last',
		cssFirst: 'firstButton',
		cssFirstDisabled: 'firstButtonDisabled',
		cssPrevious: 'previousButton',
		cssPreviousDisabled: 'previousButtonDisabled',
		cssNext: 'nextButton',
		cssNextDisabled: 'nextButtonDisabled',
		cssLast: 'lastButton',
		cssLastDisabled: 'lastButtonDisabled',
		pagerinfo: '#pageinfo',
		pagerpages: '#pagepages',
		filter: '',
		afterAjax: function() {}
	}, options);
	
	jQuery(table.settings.first).click(function() {
		if(jQuery(table.settings.first).hasClass(table.settings.cssFirst) == true) {
			table.settings.offset = 0;
			setPager(table);
			loadAjaxBoady(table, ajaxurl);
			return false;
		}		
	});
	
	jQuery(table.settings.previous).click(function() {		
		if(jQuery(table.settings.previous).hasClass(table.settings.cssPrevious) == true) {			
			table.settings.offset -= table.settings.rows;
			setPager(table);
			loadAjaxBoady(table, ajaxurl);
			return false;
		}		
	});
	
	jQuery(table.settings.next).click(function() {
		if(jQuery(table.settings.next).hasClass(table.settings.cssNext) == true) {
			table.settings.offset += table.settings.rows;
			setPager(table);
			loadAjaxBoady(table, ajaxurl);
			return false;
		}		
	});
	
	jQuery(table.settings.last).click(function() {
		if(jQuery(table.settings.last).hasClass(table.settings.cssLast) == true) {			
			table.settings.offset = (Math.floor((table.settings.total - 1) / table.settings.rows) * table.settings.rows);
			setPager(table);
			loadAjaxBoady(table, ajaxurl);
			return false;
		}
	});
	
	tableHeaders = jQuery('thead th',table);
	tableHeaders.each(function(index) {
		this.column = index;
		this.property = jQuery(this).attr('id');
		this.order = index == table.settings.index ? table.settings.order : 0;
		if(checkHeaderOptions(table,index)) {
			this.sortDisabled = true;
		}
		if(!this.sortDisabled) {
			jQuery(this).addClass(table.settings.cssHeader);
			jQuery(this).click(function() {
				setHeadersCss(table,tableHeaders,index);
				loadAjaxBoady(table, ajaxurl);
			});
		}
	});
	
	setPager(table);
	setHeadersCss(table,tableHeaders,table.settings.index);	

	loadAjaxBoady(table, ajaxurl);
	
	jQuery(this).bind('filter', function(e,filter) {
		table.settings.filter = filter;
		table.settings.offset = 0;
		setPager(table);
		loadAjaxBoady(table, ajaxurl);
	});
	
	function checkHeaderOptions(table,i) {	
		if((table.settings.headers[i]) && (table.settings.headers[i].sorter === false)) { 
			return true; 
		};
		return false;
	}
	
	function setHeadersCss(table,headers,i) {
		headers.removeClass(table.settings.cssAsc).removeClass(table.settings.cssDesc);
		tableHeaders.each(function(index) {
			if((index == i) && !this.sortDisabled) {
				if(this.order == 2) {
					this.order = 1;
					jQuery(this).addClass(table.settings.cssAsc);
				} else {
					this.order = 2;
					jQuery(this).addClass(table.settings.cssDesc);
				}
				table.settings.order = this.order;
				table.settings.property = this.property;
			} else {
				this.order = 0;
			}
		});
	}
	
	function setPager(table) {
		if((table.settings.offset <= 0) && (table.settings.offset >= (table.settings.total - table.settings.rows))) {
			jQuery(table.settings.first).removeClass(table.settings.cssFirst).addClass(table.settings.cssFirstDisabled);
			jQuery(table.settings.previous).removeClass(table.settings.cssPrevious).addClass(table.settings.cssPreviousDisabled);
			jQuery(table.settings.next).removeClass(table.settings.cssNext).addClass(table.settings.cssNextDisabled);
			jQuery(table.settings.last).removeClass(table.settings.cssLast).addClass(table.settings.cssLastDisabled);
		}
		else if((table.settings.offset > 0) && (table.settings.offset < (table.settings.total - table.settings.rows))) {
			jQuery(table.settings.first).removeClass(table.settings.cssFirstDisabled).addClass(table.settings.cssFirst);
			jQuery(table.settings.previous).removeClass(table.settings.cssPreviousDisabled).addClass(table.settings.cssPrevious);
			jQuery(table.settings.next).removeClass(table.settings.cssNextDisabled).addClass(table.settings.cssNext);
			jQuery(table.settings.last).removeClass(table.settings.cssLastDisabled).addClass(table.settings.cssLast);
		}
		else if(table.settings.offset <= 0) {
			jQuery(table.settings.first).removeClass(table.settings.cssFirst).addClass(table.settings.cssFirstDisabled);
			jQuery(table.settings.previous).removeClass(table.settings.cssPrevious).addClass(table.settings.cssPreviousDisabled);
			jQuery(table.settings.next).removeClass(table.settings.cssNextDisabled).addClass(table.settings.cssNext);
			jQuery(table.settings.last).removeClass(table.settings.cssLastDisabled).addClass(table.settings.cssLast);
		}
		else if(table.settings.offset >= (table.settings.total - table.settings.rows)) {
			jQuery(table.settings.first).removeClass(table.settings.cssFirstDisabled).addClass(table.settings.cssFirst);
			jQuery(table.settings.previous).removeClass(table.settings.cssPreviousDisabled).addClass(table.settings.cssPrevious);
			jQuery(table.settings.next).removeClass(table.settings.cssNext).addClass(table.settings.cssNextDisabled);
			jQuery(table.settings.last).removeClass(table.settings.cssLast).addClass(table.settings.cssLastDisabled);
		}
		
		to = (table.settings.offset + table.settings.rows);
		if(to > table.settings.total) {
			to = table.settings.total;
		}
		jQuery(table.settings.pagerinfo).html((table.settings.offset + 1) + ' - ' + to + ' of ' + table.settings.total + ' ' + table.settings.recordName);
		
		var totalPages = Math.floor(table.settings.total / table.settings.rows);
		var curPage = (table.settings.offset / table.settings.rows);
		var minPage = curPage - 4;		
		var maxPage = curPage + 5;
		if(minPage < 0) {
			minPage = 0;
		}
		else if(maxPage - minPage < 9) {
			minPage = totalPages - 9;
		}
		if((curPage + 5) > totalPages) {
			maxPage = totalPages;
		}
		else if(maxPage + minPage < 10) {
			maxPage = 9;
		}
		jQuery(table.settings.pagerpages).html('');
		for(i = minPage; i <= maxPage; i++) {
			if(i == curPage) {
				jQuery(table.settings.pagerpages).append("<b>" + (i + 1) + "</b>");
			}
			else {
				jQuery(table.settings.pagerpages).append("<span id=\"pp" + i + "\" class=\"pp\">" + (i + 1) + "</span>");
				jQuery("#pp" + i).click(function () {
					table.settings.offset = (jQuery(this).text() - 1) * table.settings.rows;
					setPager(table);
					loadAjaxBoady(table, ajaxurl);
				});
			}
			if(i < maxPage) {
				jQuery(table.settings.pagerpages).append(", ");
			}
		}
	}

	function loadAjaxBoady(table, ajaxurl) {
		jQuery.blockUI({ 
			message: '<h1>Loading Data...</h1>', 
			css: {             
			border: 'none', 
            padding: '15px', 
            backgroundColor: '#000', 
            opacity: '.5', 
            color: '#fff' 
        } });
		
		params = {property: table.settings.property, order: table.settings.order, offset: table.settings.offset, rows: table.settings.rows, filter: table.settings.filter};
		jQuery.post(ajaxurl, params, function(html) {
			var result = html.split("|");
			table.settings.total = result[0];
			setPager(table);
			jQuery(jQuery(table).selector + ' tbody').replaceWith(result[1]);	
			jQuery("tbody tr",table).filter(':odd').addClass(table.settings.cssOdd);
			jQuery(jQuery(table).selector + " tbody tr").click(function(event) {
				var tr = this;
				if(event.target.tagName !== 'IMG') {
					window.location = jQuery(this).attr('id');
				}
			});
			if (typeof table.settings.afterAjax == 'function') {
				table.settings.afterAjax();
			}
			jQuery.unblockUI();
		});
	}
	
	return this;
}
