addEvent(window, "load", sortables_init);

var SORT_COLUMN_INDEX;
var headerRowCount=0;
var tmpcnt=0;

function sortables_init() {
    // Find all tables with class sortable and make them sortable
    if (!document.getElementsByTagName) return;
    tbls = document.getElementsByTagName("table");
    for (ti=0;ti<tbls.length;ti++) {
        thisTbl = tbls[ti];        
        if (((' '+thisTbl.className+' ').indexOf("sortable") != -1) && (thisTbl.id)) {
            //initTable(thisTbl.id);
            ts_makeSortable(thisTbl);                                    
        }
    }
}

function ts_makeSortable(table) {
    if (table.rows && table.rows.length > 0) {
        var row;
        var cellTag;
        var rowHTML;
        var firstRow
        var index=0;
        
        headerRowCount=0;
        for (var i=0; i<table.rows.length; i++){
            row = table.rows[i];            
            rowHTML = row.innerHTML.toLowerCase();
            index = rowHTML.indexOf("<th");
            
            if (index != -1) {                
                ts_makeHeaderRow(row);
                headerRowCount++;
            }
            else break;            
        }        
    }
    //if (!firstRow) return;
    
    
    
    // We have a first row: assume it's the header, and make its contents clickable links
    /*for (var i=0;i<firstRow.cells.length;i++) {
        var cell = firstRow.cells[i];
        if ((' '+cell.className+' ').indexOf("nosort") == -1) {
			var txt = ts_getInnerText(cell);
			//cell.innerHTML = '<a href="#" class="sortheader" onclick="ts_resortTable(this);return false;">'+txt+'<span class="sortarrow"></span></a>';
			cell.innerHTML = '<a href="#" class="sortheader" onclick="ts_resortTable(this,' + i + ');return false;">'+txt+'<span class="sortarrow"></span></a>';

		}
    }*/
}

function ts_makeHeaderRow(row) {
    for (var i=0;i<row.cells.length;i++) {
        var cell = row.cells[i];
        if ((' '+cell.className+' ').indexOf("nosort") == -1) {
			var txt = cell.innerHTML; //ts_getInnerText(cell);
			cell.innerHTML = '<a href="#" class="sortheader" onclick="ts_resortTable(this,' + i + ');return false;">'+txt+'<span class="sortarrow"></span></a>';
		}
    }
}

function ts_getInnerText(el) {
	//alert(typeof el);
	if (typeof el == "string") return el;
	if (typeof el == "undefined") {return '';}
	if (el.innerText) return el.innerText;	//Not needed but it is faster
	var str = "";
	var done = false;
	
	var cs = el.childNodes;
	var l = cs.length;
	
	for (var i = 0; i < l; i++) {
	    if (done==true) break;
	    
	    //if (tmpcnt==0) alert(cs[i].nodeType);
	    switch (cs[i].nodeType) {
			case 1: //ELEMENT_NODE				
				if (cs[i].nodeName=="SELECT") {
				    str +=cs[i].options[cs[i].selectedIndex].value;
				    done=true;				    
				}
				else {
				    str += ts_getInnerText(cs[i]);				
				}
				break;
			case 3:	//TEXT_NODE
				str += cs[i].nodeValue;				
				break;
		}
		
		//if (tmpcnt==1) alert(i + ": $" + str + "$");
		
		//if (tmpcnt==1) alert(i + ": $" + str + "$");		
	}
	str=str.replace(/\n/g, ""); // remove newlines
	str=str.replace(/\t/g, ""); // remove tabs
	str=str.replace(/\s /g, "");   // remove spaces
	return str;
}

function ts_resortTable(lnk, cellIndex) {
    // get the span
    var span;
    var cellClass;
    var highlightIndex;
    
    for (var ci=0;ci<lnk.childNodes.length;ci++) {		
        if (lnk.childNodes[ci].tagName && lnk.childNodes[ci].tagName.toLowerCase() == 'span') span = lnk.childNodes[ci];
    }
    
    var spantext = ts_getInnerText(span);
    var td = lnk.parentNode;
    //var column = td.cellIndex;
    var column = cellIndex || td.cellIndex;
    var table = getParent(td,'TABLE');
    
    // Set default sort direction
    if (span.getAttribute("sortdir")==null) {
		if ((' '+td.className+' ').indexOf("sortasc") != -1) {
			span.setAttribute('sortdir','up');
		}
		else
			span.setAttribute('sortdir','down');
    }
    
    // Work out a type for the column
    if (table.rows.length <= 1) return;
    
    if ((' '+td.className+' ').indexOf("sortpos") != -1) {
		sortfn = ts_sort_position;
	}
	else if ((' '+td.className+' ').indexOf("sortgrade") != -1) {
		sortfn = ts_sort_grade;
	}
	else if ((' '+td.className+' ').indexOf("sortheight") != -1) 
    {
		sortfn = ts_sort_height;
	}
	else if ((' '+td.className+' ').indexOf("sortrecord") != -1) 
    {
		sortfn = ts_sort_record;
	}
	else if ((' '+td.className+' ').indexOf("sortclass") != -1) 
    {
		sortfn = ts_sort_class;
	}
	else if ((' '+td.className+' ').indexOf("sortsmalldate") != -1) 
    {
		sortfn = ts_sort_smalldate;
	}
	else if ((' '+td.className+' ').indexOf("sortdatetime") != -1) 
    {
		sortfn = ts_sort_datetime;
	}	
    else {
		var iIdx=headerRowCount;
		
		var itm = ts_getInnerText(table.rows[iIdx].cells[column]);
		tmpcnt=1;
		
		while ((escape(itm)=='%A0' || escape(itm)=='%20') && iIdx<table.rows.length){
			iIdx++;
			var itm = ts_getInnerText(table.rows[iIdx].cells[column]);								 			
		}
		
		sortfn = ts_sort_caseinsensitive;
		if (itm.match(/^\d\d[\/-]\d\d[\/-]\d\d\d\d$/)) sortfn = ts_sort_date;
		if (itm.match(/^\d\d[\/-]\d\d[\/-]\d\d$/)) sortfn = ts_sort_date;
		if (itm.match(/^[£$]/)) sortfn = ts_sort_currency;
		if (itm.match(/^[\d\.]+$/)) sortfn = ts_sort_numeric;
    }
    
    //alert(sortfn);
    
    SORT_COLUMN_INDEX = column;
    var bottomRows = new Array();
    var newRows = new Array();
    
    //for (i=0;i<table.rows[0].length;i++) {firstRow[i] = table.rows[0][i];}
    
    // create content rows
    for (j=1;j<table.rows.length-(headerRowCount-1);j++) {		
		if (table.rows[j+(headerRowCount-1)].className && (table.rows[j+(headerRowCount-1)].className.indexOf('sortbottom') == -1)) {
		    newRows[j-1] = table.rows[j+(headerRowCount-1)]; 		
		}
		else bottomRows[bottomRows.length] = table.rows[j+(headerRowCount-1)]; 		
	}
	
	newRows.sort(sortfn);
    var sortDirection;
    
    if (span.getAttribute("sortdir") == 'down') {
        ARROW = '&nbsp;&nbsp;&uarr;';
        newRows.reverse();
        //span.setAttribute('sortdir','up');
        sortDirection = 'up';
    } else {
        ARROW = '&nbsp;&nbsp;&darr;';
        //span.setAttribute('sortdir','down');
        sortDirection = 'down';
    }
    
    // set sort direction for all header row links
    var headerSpan;
    var headerLink;
    for (i=0; i<headerRowCount; i++) {
        headerLink = table.rows[i].cells[SORT_COLUMN_INDEX].childNodes[0];
        for (var i=0; i<headerLink.childNodes.length; i++) {		
            if (headerLink.childNodes[i].tagName && headerLink.childNodes[i].tagName.toLowerCase() == 'span') headerSpan = headerLink.childNodes[i];
        }        
        headerSpan.setAttribute('sortdir', sortDirection);
        
    }
        
    // Set correct row class
    var rowCount=0;
    for (j=0;j<newRows.length;j++) { 		
		newRows[j].className=newRows[j].className.replace("even","");
		newRows[j].className=newRows[j].className.replace("odd","");
		
		if (rowCount % 2){newRows[j].className+=' even';}
		else {newRows[j].className+=' odd';}
		
		// Set highlight on column
		for (k=0;k<newRows[j].cells.length;k++) { 		
			newRows[j].cells[k].className = newRows[j].cells[k].className.replace("highlight","");
		
			//cellClass=newRows[j].cells[k].className;
			//highlightIndex=(' '+cellClass+' ').indexOf("highlight");			
			if (k==SORT_COLUMN_INDEX) {
				//if (highlightIndex == -1) {newRows[j].cells[k].className=cellClass + ' highlight';}
				newRows[j].cells[k].className += ' highlight';
			}
			//else if (highlightIndex != -1) newRows[j].cells[k].className=cellClass.slice(0,highlightIndex-1);				
		}
		
		rowCount++;
	}
	
    // We appendChild rows that already exist to the tbody, so it moves them rather than creating new ones
    for (i=0;i<newRows.length;i++) { 
		table.tBodies[0].appendChild(newRows[i]);
		
	}
	// do sortbottom rows     
    for (i=0;i<bottomRows.length;i++) { 
		table.tBodies[0].appendChild(bottomRows[i]);		
	}	
	tmpcnt=0;
}

function getParent(el, pTagName) {
	if (el == null) return null;
	else if (el.nodeType == 1 && el.tagName.toLowerCase() == pTagName.toLowerCase())	// Gecko bug, supposed to be uppercase
		return el;
	else
		return getParent(el.parentNode, pTagName);
}
function ts_sort_date(a,b) {
    // y2k notes: two digit years less than 50 are treated as 20XX, greater than 50 are treated as 19XX
    aa = ts_getInnerText(a.cells[SORT_COLUMN_INDEX]);
    bb = ts_getInnerText(b.cells[SORT_COLUMN_INDEX]);
    if (aa.length == 10) {
        dt1 = aa.substr(6,4)+aa.substr(3,2)+aa.substr(0,2);
    } else {
        yr = aa.substr(6,2);
        if (parseInt(yr) < 50) { yr = '20'+yr; } else { yr = '19'+yr; }
        dt1 = yr+aa.substr(3,2)+aa.substr(0,2);
    }
    if (bb.length == 10) {
        dt2 = bb.substr(6,4)+bb.substr(3,2)+bb.substr(0,2);
    } else {
        yr = bb.substr(6,2);
        if (parseInt(yr) < 50) { yr = '20'+yr; } else { yr = '19'+yr; }
        dt2 = yr+bb.substr(3,2)+bb.substr(0,2);
    }
    if (dt1==dt2) return 0;
    if (dt1<dt2) return -1;
    return 1;
}

function ts_sort_datetime(a,b) {
    // format mm/dd/yyyy hh:mm [am/pm]
    aa = ts_getInnerText(a.cells[SORT_COLUMN_INDEX]);
    bb = ts_getInnerText(b.cells[SORT_COLUMN_INDEX]);
    
    dt1 = new Date(aa);
    dt2 = new Date(bb);
    
    if (!dt1.getMonth()) return -1;
    if (!dt2.getMonth()) return 1;
    if (dt1==dt2) return 0;
    if (dt1<dt2) return -1;
    return 1;
}

function ts_sort_smalldate(a,b) {
    // small dates are just mon/day (i.e. 2/15)
    aa = ts_getInnerText(a.cells[SORT_COLUMN_INDEX]);
    bb = ts_getInnerText(b.cells[SORT_COLUMN_INDEX]);
    
    aa = aa + '/2000';
    bb = bb + '/2000';
    dt1 = new Date(aa);
    dt2 = new Date(bb);

    if (dt1==dt2) return 0;
    if (dt1<dt2) return -1;
    return 1;
}

function ts_sort_currency(a,b) { 
    aa = parseFloat(ts_getInnerText(a.cells[SORT_COLUMN_INDEX]).replace(/[^0-9.]/g,''));
    if (isNaN(aa)) aa = 0;
    bb = parseFloat(ts_getInnerText(b.cells[SORT_COLUMN_INDEX]).replace(/[^0-9.]/g,''));
	if (isNaN(bb)) bb = 0;
	return aa-bb;
}

function ts_sort_numeric(a,b) { 
    aa = parseFloat(ts_getInnerText(a.cells[SORT_COLUMN_INDEX]));
    if (isNaN(aa)) aa = -1;
    bb = parseFloat(ts_getInnerText(b.cells[SORT_COLUMN_INDEX])); 
    if (isNaN(bb)) bb = -1;
    return aa-bb;
}

function ts_sort_caseinsensitive(a,b) {
    aa = ts_getInnerText(a.cells[SORT_COLUMN_INDEX]).toLowerCase();
    bb = ts_getInnerText(b.cells[SORT_COLUMN_INDEX]).toLowerCase();
    
    if (aa==bb) return 0;
    if (aa==" " || aa<bb) return -1;
    return 1;
}

function ts_sort_position(a,b) {
    var a_adj, b_adj;
    
    aa = ts_getInnerText(a.cells[SORT_COLUMN_INDEX]).toLowerCase();
    bb = ts_getInnerText(b.cells[SORT_COLUMN_INDEX]).toLowerCase();
    
    switch (aa){
		case 'pg': a_adj=1; break;
		case 'sg': a_adj=2; break;
		case 'sf': a_adj=3; break;
		case 'pf': a_adj=4; break;
		case 'c': a_adj=5; break;
		default: a_adj=6;
	}
	switch (bb){
		case 'pg': b_adj=1; break;
		case 'sg': b_adj=2; break;
		case 'sf': b_adj=3; break;
		case 'pf': b_adj=4; break;
		case 'c': b_adj=5; break;
		default: b_adj=6;
	}
    if (a_adj==b_adj) return 0;
    if (a_adj<b_adj) return -1;
    return 1;
}

function ts_sort_class(a,b) {
    var a_adj, b_adj;
    
    aa = ts_getInnerText(a.cells[SORT_COLUMN_INDEX]).toLowerCase();
    bb = ts_getInnerText(b.cells[SORT_COLUMN_INDEX]).toLowerCase();
    
    aa = aa.slice(0,2);
    bb = bb.slice(0,2);
    
    switch (aa){
		case 'fr': a_adj=1; break;
		case 'so': a_adj=2; break;
		case 'jr': a_adj=3; break;
		case 'sr': a_adj=4; break;		
		default: a_adj=5;
	}
	switch (bb){
		case 'fr': b_adj=1; break;
		case 'so': b_adj=2; break;
		case 'jr': b_adj=3; break;
		case 'sr': b_adj=4; break;		
		default: b_adj=5;
	}
    if (a_adj==b_adj) return 0;
    if (a_adj<b_adj) return -1;
    return 1;
}

function ts_sort_grade(a,b) {
    var a_adj, b_adj;
    
    aa = ts_getInnerText(a.cells[SORT_COLUMN_INDEX]).toLowerCase();
    bb = ts_getInnerText(b.cells[SORT_COLUMN_INDEX]).toLowerCase();
    
    switch (aa){
		case 'a+': a_adj=1; break;
		case 'a':  a_adj=2; break;
		case 'a-': a_adj=3; break;
		case 'b+': a_adj=4; break;
		case 'b':  a_adj=5; break;
		case 'b-': a_adj=6; break;
		case 'c+': a_adj=7; break;
		case 'c':  a_adj=8; break;
		case 'c-': a_adj=9; break;
		case 'd+': a_adj=10; break;
		case 'd':  a_adj=11; break;
		case 'd-': a_adj=12; break;		
		default: a_adj=13;
	}
	switch (bb){
		case 'a+': b_adj=1; break;
		case 'a':  b_adj=2; break;
		case 'a-': b_adj=3; break;
		case 'b+': b_adj=4; break;
		case 'b':  b_adj=5; break;
		case 'b-': b_adj=6; break;
		case 'c+': b_adj=7; break;
		case 'c':  b_adj=8; break;
		case 'c-': b_adj=9; break;
		case 'd+': b_adj=10; break;
		case 'd':  b_adj=11; break;
		case 'd-': b_adj=12; break;		
		default: b_adj=13;
	}
    if (a_adj==b_adj) return 0;
    if (a_adj<b_adj) return -1;
    return 1;
}

function ts_sort_height(a,b) {
    var a_adj, b_adj, i;
    
    aa = ts_getInnerText(a.cells[SORT_COLUMN_INDEX], false).toLowerCase();
    bb = ts_getInnerText(b.cells[SORT_COLUMN_INDEX], false).toLowerCase();
    
    a_adj = Number(aa.charAt(0) * 12) + Number(aa.substring(2, aa.length-1));
        
    b_adj = Number(bb.charAt(0) * 12) + Number(bb.substring(2, bb.length-1));
    
    if (a_adj==b_adj) return 0;
    if (a_adj<b_adj) return -1;
    return 1;
}

function ts_sort_record(a,b) {
    var a_adj, b_adj, i;
    var a_wins, a_losses, b_wins, b_losses;
    
    aa = ts_getInnerText(a.cells[SORT_COLUMN_INDEX], false).toLowerCase();
    bb = ts_getInnerText(b.cells[SORT_COLUMN_INDEX], false).toLowerCase();
   
    i = aa.indexOf('-');
    if (i == -1)
		a_adj = Number(-1);		
	else {
		a_wins = Number(aa.substring(0,i));
		a_losses = Number(aa.substring(i+1));
		//a_adj = wins; //wins / (wins+losses);
	}
		
    i = bb.indexOf('-');
    if (i == -1)
		b_adj = Number(-1);
	else {
		b_wins = Number(bb.substring(0,i));
		b_losses = Number(bb.substring(i+1));
		//b_adj = wins; //wins / (wins+losses);
	}
	
	if (a_wins==b_wins) {
		a_adj = -a_losses;
		b_adj = -b_losses;    
    }
    else {
        a_adj = a_wins;
        b_adj = b_wins;
    }
    	    
    if (a_adj==b_adj) return 0;
    if (a_adj<b_adj) return -1;
    return 1;
}

function ts_sort_default(a,b) {
    aa = ts_getInnerText(a.cells[SORT_COLUMN_INDEX]);
    bb = ts_getInnerText(b.cells[SORT_COLUMN_INDEX]);
    if (aa==bb) return 0;
    if (aa<bb) return -1;
    return 1;
}

function addEvent(elm, evType, fn, useCapture)
// addEvent and removeEvent
// cross-browser event handling for IE5+,  NS6 and Mozilla
// By Scott Andrew
{
  if (elm.addEventListener){
    elm.addEventListener(evType, fn, useCapture);
    return true;
  } else if (elm.attachEvent){
    var r = elm.attachEvent("on"+evType, fn);
    return r;
  } else {
    alert("Handler could not be removed");
  }
} 
