function hoverTr ( row, action ) {
	var ta = new Array();
	if ( ! ta.push ) return; // to kick ie5mac
	if ( ! document.createAttribute ) return; // to kick ???
	var cn = row.className;
	if ( ( action == 'out' && ( cn == 'tr0hov' || cn == 'tr1hov' ) ) || ( action == 'click' && ( cn == 'tr0act' || cn == 'tr1act' ) ) )
		row.className = cn.substr ( 0, 3 );
	else if ( action == 'over' && ( cn == 'tr0' || cn == 'tr1' ) )
		row.className = cn + 'hov';
	else if ( action == 'click' && ( cn == 'tr0' || cn == 'tr1' || cn == 'tr0hov' || cn == 'tr1hov' ) )
		row.className = cn.substr ( 0, 3 ) + 'act';
}


var isFirstCall = true;
var lastSortCol = false;
var lastSortDir = false;

function sort ( nLink ) {
	// kick non-capable browsers like netscape 4.x and ie5mac
	var ta = new Array();
	if ( typeof nLink.tagName === 'undefined' || ! ta.push ) {
		alert ( 'Ihr Browser unterstützt nicht alle benötigten Funktionen, um die Tabelle client-seitig zu sortieren'+"\n"+'Um dieses Feature nutzen zu können ist ein aktueller Browser notwendig' );
		return false;
	}
	var dStart = new Date();
	
	// ascertain table-node
	var iSortCol = 0;
	var nTable = nLink;
	var nColHead = false;
	var nColHeads = false;
	while ( nTable.tagName !== 'TABLE' ) {
		var nParent = nTable.parentNode;
		if ( ! nParent ) { alert ( 'error 01' ); return false; }
		// ascertain column-number
		if ( nParent.tagName === 'TR' ) {
			var iParentChilds = nParent.childNodes.length;
			for ( var i = 0; i < iParentChilds; i++ ) {
				var nChild = nParent.childNodes[i];
				if ( nChild.tagName === 'TH' ) {
					iSortCol++;
					nColHeads = nParent;
				}
				if ( nChild === nTable ) {
					nColHead = nChild;
					break;
				}
			}
		}
		nTable = nParent;
	}
	//alert ( 'Table-Tag: ' + nTable.tagName + "\n" + 'Col-Nr: ' + iSortCol );
	
	// ascertain table-body
	var nTBody = nTable;
	for ( var i = 0; i < nTable.childNodes.length; i++ ) {
		if ( nTable.childNodes[i].tagName === 'TBODY' ) nTBody = nTable.childNodes[i];
	}
	//alert ( nTBody.tagName );
	
	// get current sort criteria based on link-classes
	if ( isFirstCall ) {
		//alert ('first');
		isFirstCall = false;
	}
	
	// ascertain body-rows
	var aRows = new Array();
	var aColumn = new Array();
	for ( var i = 0; i < nTBody.childNodes.length; i++ ) {
		var nRow = nTBody.childNodes[i];
		if ( nRow.tagName === 'TR' ) {
			var iCol = 0;
			// ascertain content of body-cells
			for ( var j = 0; j < nRow.childNodes.length; j++ ) {
				var nCell = nRow.childNodes[j];
				if ( nCell.tagName === 'TD' ) {
					iCol++;
					if ( iCol === iSortCol ) {
						var inHtml = nCell.innerHTML;
						var inHtmlStripe = inHtml.replace ( /<[^>]+>/g, '' );
						if ( inHtmlStripe == '' ) inText = inHtml;
						else inText = inHtmlStripe;
						inText = inText.toLowerCase();
						
						var patNumber = /^(\d+)$/;
						var patDateGerman = /^(\d\d)\.(\d\d)\.(\d\d\d\d)\s(\d\d):(\d\d)$/;
						var patDateEnglish = /^(\d\d):(\d\d)\s(\w\w)\s(\d\d)\/(\d\d)\/(\d\d\d\d)$/;
						if ( patNumber.test && patNumber.test ( inText ) ) { // test for number as sort criteria
							patNumber.exec ( inText );
							inText = parseInt ( RegExp.$1, 10 ); // prevent detection of octal-number
						} else if ( patDateGerman.test && patDateGerman.test ( inText ) ) { // test for german date as sort criteria
							patDateGerman.exec ( inText );
							inText = RegExp.$3 + '-' + RegExp.$2 + '-' + RegExp.$1 + ' ' + RegExp.$4 + ':' + RegExp.$5;
						} else if ( patDateEnglish.test && patDateEnglish.test ( inText ) ) { // test for english date as sort criteria
							patDateEnglish.exec ( inText );
							var hour = ( RegExp.$3 == 'am' ? parseInt(RegExp.$1) : parseInt(RegExp.$1) + 12 );
							inText = RegExp.$6 + '-' + RegExp.$4 + '-' + RegExp.$5 + ' ' + hour.toString() + ':' + RegExp.$2;
						}
						aColumn[aColumn.length] = inText;
					}
				}
			}
			if ( iCol > 0 ) aRows[aRows.length] = nRow;
		}
	}
	//if ( aRows.length !== aColumn.length ) { alert ( 'error 02' ); return false; }
	//alert ( 'Werte: ' + aColumn.join ( ' ' ) );
	
	// do sorting of cell-content (optimized bubble-sort)
	var bubbles = 0;
	for ( var i = aRows.length - 2; i >= 0; i-- ) {
		for ( var j = 0; j <= i; j++ ) {
			if ( aColumn[j] > aColumn[j + 1] ) {
				bubbles++;
				var tmp = aRows[j];
				aRows[j] = aRows[j+1];
				aRows[j+1] = tmp;
				tmp = aColumn[j];
				aColumn[j] = aColumn[j+1];
				aColumn[j+1] = tmp;
			}
		}
	}
	//alert ( bubbles );
	
	// store column and direction and reverse if sorted descending
	if ( lastSortCol === iSortCol ) {
		if ( lastSortDir === false ) aRows.reverse();
		lastSortDir = ! lastSortDir;
	} else {
		lastSortCol = iSortCol;
		lastSortDir = false;
	}
	
	// reset class of all col-head
	for ( var i = 0; i < nColHeads.childNodes.length; i++ ) {
		var nHead = nColHeads.childNodes[i];
		if ( nHead.tagName === 'TH' ) {
			var nHeadSpan = nHead.childNodes[0];
			if ( nHeadSpan.tagName === 'SPAN' ) {
				var nHeadLink = nHeadSpan.childNodes[0];
				if ( typeof nHeadLink.tagName == 'undefined' && nHeadSpan.childNodes.length > 1 ) nHeadLink = nHeadSpan.childNodes[1];
				if ( nHeadLink.tagName === 'A' && nHeadLink.className.substr ( 0, 3 ) === 'ord' ) {
					nHeadLink.className = 'ordnone';
				}
			}
		}
	}
	// set new class of sort col-head
	if ( nColHead && nColHead.tagName === 'TH' ) {
		var nHeadSpan = nColHead.childNodes[0];
		if ( nHeadSpan.tagName === 'SPAN' ) {
			var nHeadLink = nHeadSpan.childNodes[0];
			if ( typeof nHeadLink.tagName == 'undefined' && nHeadSpan.childNodes.length > 1 ) nHeadLink = nHeadSpan.childNodes[1];
			if ( nHeadLink.tagName === 'A' && nHeadLink.className.substr ( 0, 3 ) === 'ord' ) {
				nHeadLink.className = 'ord' + ( lastSortDir ? 'desc' : 'asc' );
			}
		}
	}
	
	// regenerate class tr[0|1](act)
	var clsName = new Array ( 'tr0', 'tr1' );
	for ( var i = 0; i < aRows.length; i++ ) {
		if ( aRows[i].className == clsName[( i + 1 ) % 2] ) aRows[i].className = clsName[i % 2];
		else if ( aRows[i].className == clsName[( i + 1 ) % 2] + 'act' ) aRows[i].className = clsName[i % 2] + 'act';
	}
	
	// inserting "sorted" rows
	for ( var i = 0; i < aRows.length; i++ ) {
		nTBody.appendChild ( aRows[i] );
	}
	
	var dEnd = new Date();
	//alert ( 'sorting of ' + aRows.length + ' rows takes ' + Math.floor ( dEnd.getTime() - dStart.getTime() ) + 'ms' );
	// template-admin - 128 rows - sort by id
	// ie 6 (pc)		125ms-141ms
	// firebird (pc)	280ms
	// firebird (mac)	2350ms
	// safari (mac)		1210ms-2400ms
	
	return false;
}