function SortableTable( htmlTableID, sortedColumnIndex )
{
	var i;
	var thisCopy = this;


	this.SORTED = 'st_Sorted';
	this.SORTABLE = 'st_Sortable';
	this.SORTED_ASC = 'st_Asc';
	this.SORTED_DESC = 'st_Desc';

	this.TYPE_NUMBER = 'st_TypeNumber';
	this.TYPE_MONEY = 'st_TypeMoney';

	this.SortedColumnIndex = ( sortedColumnIndex == null ) ? -1 : sortedColumnIndex;

	this.table = document.getElementById( htmlTableID );
	this.head = this.table.getElementsByTagName('thead')[0];
	this.headCells = this.head.getElementsByTagName('td');


	if( this.head )
	{
		for( i=0; i<this.headCells.length; i++ )
		{
			if( this.getSelector( this.headCells[i], this.SORTABLE ) )
			{
				this.headCells[i].st_Index = i

				if( this.getSelector( this.headCells[i], this.TYPE_NUMBER ) )
				{
					this.headCells[i].st_SortkeyType = this.TYPE_NUMBER
				}

				if( this.headCells[i].attachEvent )
				{
					this.headCells[i].attachEvent( 'onclick', function(){thisCopy.sort()} )
					this.headCells[i].unselectable = true
				}
				if( this.headCells[i].addEventListener )
				{
					this.headCells[i].addEventListener( 'click', function(e){thisCopy.sort(e)}, false )
					this.headCells[i].onmousedown = function() {return false}
				}
			}
		}
	}

	this.body = this.table.getElementsByTagName('tbody')[0];
	this.rows = this.body.getElementsByTagName('tr');
	this.rowsCount = this.rows.length;
	this.cache = new Array();


	var cells = this.body.getElementsByTagName('td');
	var cellsCount = cells.length;

	var abbr;

	for( i=0; i<cellsCount; i++ )
	{
		abbr = cells[i].getAttribute('abbr');
		var cell_value = (cells[i].firstChild) ? cells[i].firstChild.nodeValue : '';
		this.setCellSortkey(cells[i], ( abbr != null && abbr != '' ) ? abbr : cell_value)
	}

	for( i=0; i<this.rowsCount; i++ )
	{
		this.cache[i] = this.rows[i].cloneNode(true)
	}

	return this
}



SortableTable.prototype.sort = function(e)
{
	var thisCopy = this
	var headCell =  window.event ? window.event.srcElement : e.currentTarget

	if (headCell.tagName != 'TD' && headCell.tagName != 'td')
	{
		var c = 0
		while (headCell.tagName != 'TD' && headCell.tagName != 'td' && c < 10)
		{
			headCell = headCell.parentNode
			c++
		}
	}

	if( this.OnSortBegin )
	{

		this.OnSortBegin( window.event ? window.event : e )
	}


	this.applySelectors(headCell)


	if( headCell.st_Index == this.SortedColumnIndex )
	{
		this.cache.reverse(headCell)
	}
	else
	{
		this.SortedColumnIndex = headCell.st_Index;

		switch( headCell.st_SortkeyType )
		{

			case this.TYPE_NUMBER :
			this.cache.sort(
				function( a, b )
				{
					var aVal = parseInt( thisCopy.getCellSortkey( a.getElementsByTagName('td')[thisCopy.SortedColumnIndex] ).replace (',', '.') )
					var bVal = parseInt( thisCopy.getCellSortkey( b.getElementsByTagName('td')[thisCopy.SortedColumnIndex] ).replace (',', '.') )

					var aValSort = a.getElementsByTagName('td')[thisCopy.SortedColumnIndex].getAttribute ("sort_order");
					var bValSort = b.getElementsByTagName('td')[thisCopy.SortedColumnIndex].getAttribute ("sort_order");

					if (aValSort && bValSort) return aValSort - bValSort

					return  ( aVal - bVal )
				}
			)
			break


			case this.TYPE_MONEY :
			this.cache.sort(
				function( a, b )
				{
					var aVal = parseFloat( thisCopy.getCellSortkey( a.getElementsByTagName('td')[thisCopy.SortedColumnIndex].firstChild.nodeValue).substr(1) )
					var bVal = parseFloat( thisCopy.getCellSortkey( b.getElementsByTagName('td')[thisCopy.SortedColumnIndex].firstChild.nodeValue).substr(1) )
					return ( aVal - bVal )
				}
			)
			break


			default:
			this.cache.sort(
				function( a, b )
				{
					var aVal = thisCopy.getCellSortkey( a.getElementsByTagName('td')[thisCopy.SortedColumnIndex] )
					var bVal = thisCopy.getCellSortkey( b.getElementsByTagName('td')[thisCopy.SortedColumnIndex] )
					return ( aVal == bVal ? 0 : ( aVal > bVal ? 1 : -1 ) )
				}
			)
		}
	}

	var body = document.createElement('tbody')
	for( var i=0; i<this.rowsCount; i++ )
	{
		body.appendChild( this.cache[i] )
	}
	this.table.replaceChild(body, this.body)
	this.body = body

	if( this.OnSortEnd )
	{

		this.OnSortEnd( window.event ? window.event : e )
	}
}



SortableTable.prototype.getCellSortkey = function( cell )
{
	return cell.getAttribute('Sortkey')
}


SortableTable.prototype.setCellSortkey = function( cell, val )
{
	cell.setAttribute('Sortkey', val)
}


SortableTable.prototype.getSelector = function( elem, selector )
{
	return ( elem && elem.className.indexOf(selector) != -1 )
}


SortableTable.prototype.setSelector = function( elem, selector )
{
	for( var i=1; i<arguments.length; i++ )
	{
		elem.className += ' ' + arguments[i]
	}
}


SortableTable.prototype.deleteSelector = function( elem, selector )
{
	for( var i=1; i<arguments.length; i++ )
	{
		elem.className = elem.className.replace( new RegExp(arguments[i], 'g'), '' )
	}

}



SortableTable.prototype.applySelectors = function( headCell )
{
	for( var i=0; i<this.headCells.length; i++ )
	{
		if( headCell.st_Index == this.headCells[i].st_Index )
		{
			this.setSelector(this.headCells[i], this.SORTED)

			if( this.getSelector(this.headCells[i], this.SORTED_ASC) )
			{
				this.deleteSelector(this.headCells[i], this.SORTED_ASC)
				this.setSelector(this.headCells[i], this.SORTED_DESC)
			}
			else
			{
				this.deleteSelector(this.headCells[i], this.SORTED_DESC)
				this.setSelector(this.headCells[i], this.SORTED_ASC)
			}
		}
		else
		{
			this.deleteSelector(this.headCells[i], this.SORTED, this.SORTED_ASC, this.SORTED_DESC)
		}
	}
}

