// originally found here,
// http://kryogenix.org/code/browser/sorttable/
// and rebuilt by me, Andrew Hughes 08/2006
// cleaned up name spaces and uasge,
// utilized some dom tools from our other library (.addNode and $() )


var tableSort = {};

// prepare a table for sorting, by supplying the rows of fields 
// that control the sort and the tble to be sorted
// sortRowObjOrID - string or object for the control row
// tblObjOrID - string or object of the table with the rows to sort
// 	^-- can be different than sortRowObjOrID
tableSort.prepTable = function(sortRowObjOrID,tblObjOrID,postSortFunc) {
		if ($(sortRowObjOrID) && $(sortRowObjOrID).cells){
			var sortRow = $(sortRowObjOrID);
		}else{
			return;
		}
		if (!$(tblObjOrID) || !$(tblObjOrID).rows){ alert("Cannot Sort '" + tblObjOrID + "' - not a table object."); return;}
		
		var tblID = $(tblObjOrID).id?$(tblObjOrID).id:"tblSort_" & xhr.rnd();
		if (!$(tblObjOrID).id){ $(tblObjOrID).id = tblID; }
		
    for (var i=0;i<sortRow.cells.length;i++) {
        var cell = sortRow.cells[i];
        var txt = tableSort.getInnerText(cell);
        cell.innerHTML = "";
        dom.addNode(txt + "<span class=\"sortarrow\"></span>",cell,"a",{postsortfunc:postSortFunc,tblid:tblID,cellid:i,href:"#",onclick:function(){tableSort.doSort(this);return false;}});
    }
}

// perform the actual table sort - called by 
// the click of a link from the sort header above
tableSort.doSort = function(lnk) {
    // get the span
   
    var span;
    var sortRow = lnk.parentNode.parentNode;
    var appendParent = $(lnk.tblid);
    sortRow.id = sortRow.id?sortRow.id:"tblSortRow_" & xhr.rnd();
		tbl = $(lnk.tblid);
		
    for (var ci=0;ci<lnk.childNodes.length;ci++) {
        if (lnk.childNodes[ci].tagName && lnk.childNodes[ci].tagName.toLowerCase() == 'span'){
        	span = lnk.childNodes[ci];
        }
    }

		tableSort.SORT_COLUMN_INDEX = lnk.cellid || lnk.parentNode.cellIndex;

    if (tbl.rows.length <= 1){ return; }
  
    //populate the arrays
    var firstRow = new Array();
    var newRows = new Array();
    for (i=0;i<sortRow.cells.length;i++) { firstRow[i] = sortRow[i]; }
    
    for (j=0;j<tbl.rows.length;j++) { 
    	var r = tbl.rows[j];
    	if (r && (r.cells.length == sortRow.cells.length) && ((r.id && r.id != sortRow.id) || !r.id)){
    		newRows.push(r); 
    	}
    }
    
    // grab the first value out of the newRows and determine its type
    var itm = tableSort.getInnerText(newRows[0].cells[tableSort.SORT_COLUMN_INDEX]);
    
    var sortfn = tableSort.charSort;
    if (isDate(itm)){ sortfn = tableSort.dateSort;
    }else if (itm.match(/^[£$]/)){ sortfn = tableSort.currencySort ;
    }else if (itm.match(/^[\d\.]+$/)){ sortfn = tableSort.numericSort;}
    
		//perform the appropriate sort
		newRows.sort(sortfn);
		
    if (span.getAttribute("sortdir") == 'down') {
        ARROW = '&nbsp;&uarr;';
        newRows.reverse();        
        span.setAttribute('sortdir','up');
    } else {
        ARROW = '&nbsp;&darr;';
        span.setAttribute('sortdir','down');
    }
    
    // Using appendChild for each row moves them and
    // avoids remove and replacement - very slick.
   for (i=0;i<newRows.length;i++) { 
   		if (newRows[i]){
   			appendParent.appendChild(newRows[i]);
   		}
    }

    // Delete any other arrows there may be showing
    var allspans = sortRow.getElementsByTagName("span");
    for (var ci=0;ci<allspans.length;ci++) {
        if (allspans[ci].className == 'sortarrow'){ allspans[ci].innerHTML = ''; }       
    }
    span.innerHTML = ARROW;
    if (lnk.postsortfunc){ lnk.postsortfunc(lnk,sortRow,appendParent); }
}


tableSort.getInnerText = function(el) {
	if (typeof el == "string" || typeof el == "undefined"){ 
		return el;
	}else if (el.innerText){ return el.innerText;	} //Not needed but it is faster
	var str = "";	
	var cs = el.childNodes;
	var l = cs.length;
	for (var i = 0; i < l; i++) {
		str += (cs[i].nodeType == 1)?tableSort.getInnerText(cs[i]):"";
		str += (cs[i].nodeType == 3)?cs[i].nodeValue:"";
	}
	return str;
}

//create the different type of sorts
tableSort.dateSort = function(a,b) {
    // y2k notes: two digit years less than 50 are treated as 20XX, greater than 50 are treated as 19XX
    var aa = tableSort.getInnerText(a.cells[tableSort.SORT_COLUMN_INDEX]);
    var bb = tableSort.getInnerText(b.cells[tableSort.SORT_COLUMN_INDEX]);
    var dt1 = new Date(aa);
    var dt2 = new Date(bb);
    //console.info(dt1 + " == " + dt2 + " : " + (dt1 == dt2));
    /*
    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;
}

tableSort.currencySort = function(a,b) { 
    var aa = tableSort.getInnerText(a.cells[tableSort.SORT_COLUMN_INDEX]).replace(/[^0-9.]/g,'');
    var bb = tableSort.getInnerText(b.cells[tableSort.SORT_COLUMN_INDEX]).replace(/[^0-9.]/g,'');
    return parseFloat(aa) - parseFloat(bb);
}

tableSort.numericSort = function(a,b) { 
    var aa = parseFloat(tableSort.getInnerText(a.cells[tableSort.SORT_COLUMN_INDEX]));
    if (isNaN(aa)) aa = 0;
    var bb = parseFloat(tableSort.getInnerText(b.cells[tableSort.SORT_COLUMN_INDEX])); 
    if (isNaN(bb)) bb = 0;
    return aa-bb;
}

tableSort.charSort = function(a,b) {
    var aa = tableSort.getInnerText(a.cells[tableSort.SORT_COLUMN_INDEX]).toLowerCase();
    var bb = tableSort.getInnerText(b.cells[tableSort.SORT_COLUMN_INDEX]).toLowerCase();
    if (aa==bb) return 0;
    if (aa<bb) return -1;
    return 1;
}

tableSort.defaultSort = function(a,b) {
    var aa = tableSort.getInnerText(a.cells[tableSort.SORT_COLUMN_INDEX]);
    var bb = tableSort.getInnerText(b.cells[tableSort.SORT_COLUMN_INDEX]);
    if (aa==bb) return 0;
    if (aa<bb) return -1;
    return 1;
}
