
function SortableTable(elem) {
	var sortableTable = this;
	this.elem = $(elem);
	
	this.sortColumn = null;
	this.sortAscending = true;
	this.sortImg = null;
	
	this.caseInsensitive = true;
	
	var headerRow = null;
	this.elem.find('tr').each(function() {
		if ($(this).find('th').length > 0) {
			headerRow = $(this);
			return false;
		}
	});
	
	if (!headerRow) {
		alert('Could not find header row (ie. the first <tr> that contains <th>)');
		return;
	}
	
	this.headerRow = headerRow;
	this.headerRow.addClass('sortable-table-header-row');
	this.headers = headerRow.find('th');
	
	this.headers.each(function() {
		$(this).click(function() {
			sortableTable.onClickHeader($(this));
		});
		$('<img class="sortable-table-arrow sortable-table-arrow-up" />').appendTo(this);
	});
}

SortableTable.prototype.onClickHeader = function(elem) {
	log('onClickHeader()');
	//log('elem:');
	//log(elem);
	log('elem.text(): ' + $.trim(elem.text()));
	
	var index;
	for (index=0; index<this.headers.length; index++) {
		if (this.headers[index] == elem[0]) {
			log('match');
			break;
		}
	}
	
	if (index >= this.headers.length) {
		alert('SortableTable.onClickHeader(): Error, could not find matching column header.');
		return;
	}
	
	this.sort(index);
}

SortableTable.prototype.sort = function(column) {
	log('sort()');
	log('  column: ' + column);
	var rows = this.elem.find('tr').not(this.headerRow);
	
	if (column == this.sortColumn) {
		this.sortAscending = !this.sortAscending;
	} else {
		this.sortColumn = column;
		this.sortAscending = true;
	}
	
	var caseInsensitive = this.caseInsensitive;
	function _sort(a, b) {
		var val1 = $($(a).find('td')[column]).text();
		var val2 = $($(b).find('td')[column]).text();
		
		if (caseInsensitive) {
			val1 = val1.toLowerCase();
			val2 = val2.toLowerCase();
		}
		
		if (val1 < val2) {
			return -1;
		} else if (val1 > val2) {
			return 1;
		} else {
			return 0;
		}
	}
	
	rows.sort(_sort);
	
	if (!this.sortAscending) {
		$.fn.reverse = [].reverse;
		rows.reverse();
	}
	
	for (var i=1; i<rows.length; i++) {
		$(rows[i-1]).after(rows[i]);
	}
	
	if (this.sortImage) {
		// Remove extra classes.
		this.sortImage.attr('class', 'sortable-table-arrow');
		this.sortImage.addClass('sortable-table-arrow-up');
	}
	
	var header = $(this.headers[this.sortColumn]);
	this.sortImage = header.find('.sortable-table-arrow');
	
	if (this.sortAscending) {
		this.sortImage.addClass('sortable-table-arrow-active-up');
	} else {
		this.sortImage.addClass('sortable-table-arrow-active-down');
	}
}

////////////////////////////////////////////////////////////////////////////////

$(function() {
	$('table.sortable-table').each(function() {
		new SortableTable(this);
	});
});
