// standardista_table_sorting :: v?.?.?
// v1.3 :: updated 200703 by jeffrey barke <http://themechanism.com/code/>
	// essential code by Neil Crosby and Stuart Langridge
	// updated to work with and depend on the prototype javascript framework
// originally by Neil Crosby <http://www.workingwith.me.uk/articles/scripting/standardista_table_sorting>
// based on Stuart Langridge's "sorttable" code.  Specifically, 
	// the determineSortFunction, sortCaseInsensitive, sortDate, sortNumeric, and
	// sortCurrency functions are heavily based on his code.  This module would not
	// have been possible without Stuart's earlier outstanding work.
var standardistaTableSorting = {

	that: false,
	isOdd: false,
	sortColumnIndex: -1,
	lastAssignedId: 0,
	newRows: -1,
	lastSortedTable: -1,
	blnFilter: false,

	init: function() {
		if (!document.getElementsByTagName) { return false; }
this.that=this;var tables=document.getElementsByTagName('table');for(var i=0;i<tables.length;i++){var thisTable=tables[i];if(Element.hasClassName(thisTable,'sortable')){this.makeSortable(thisTable);}else if(Element.hasClassName(thisTable,'autostripe')){this.makeStripe(thisTable);}}
return true;},makeStripe:function(table){if(!table.id){table.id='sortableTable'+this.lastAssignedId++;}
if(!table.tHead||!table.tHead.rows||0==table.tHead.rows.length){return false;}
this.isOdd=false;var rows=table.tBodies[0].rows;for(var i=0;i<rows.length;i++){this.doStripe(rows[i]);}},filter:function(objFilter){var objFilters=document.getElementsByClassName('filterselect');var td=objFilters[0].parentNode;var tr=td.parentNode;var thead=tr.parentNode;var table=thead.parentNode;if(!table.tBodies||table.tBodies[0].rows.length<=1){return false;}
var intCol=objFilter.id.substring(4);var strFilter=objFilter.options[objFilter.selectedIndex].value;var blnShow=false;var arrShow=new Array(table.tBodies[0].rows[0].cells.length);var arrFilter=new Array(table.tBodies[0].rows[0].cells.length);for(var i=0;i<objFilters.length;i++){if(objFilters[i].options[objFilters[i].selectedIndex]){arrFilter[i]=objFilters[i].options[objFilters[i].selectedIndex].value;}else{arrFilter[i]=null;}}
var itm="";var rowNum=0;while(rowNum<table.tBodies[0].rows.length){blnShow=true;arrItems=new Array();for(var i=0;i<table.tBodies[0].rows[rowNum].cells.length;i++){arrItems.push(this.getInnerText(table.tBodies[0].rows[rowNum].cells[i]));}
for(var i=0;i<arrShow.length;i++){arrShow[i]=false;}
for(var i=0;i<arrItems.length;i++){if(arrItems[i].strip()==arrFilter[i]||arrFilter[i]==''||arrFilter[i]==null){arrShow[i]=true;}}
for(var i=0;i<arrShow.length;i++){if(arrShow[i]==false){blnShow=false;}}
if(blnShow){table.tBodies[0].rows[rowNum].style.display='table-row';this.doStripe(table.tBodies[0].rows[rowNum]);}else{table.tBodies[0].rows[rowNum].style.display='none';}
rowNum++;}},addFilters:function(rows,cell){var arrUnique=new Array();var strVal='';for(var i=0;i<rows.length;i++){strVal=this.getInnerText(rows[i].cells[cell]);if(arrUnique.indexOf(strVal)==-1){arrUnique.push(strVal);}}
arrUnique.sort();return(arrUnique);},makeSortable:function(table){if(!table.id){table.id='sortableTable'+this.lastAssignedId++;}
if(!table.tHead||!table.tHead.rows||0==table.tHead.rows.length){return false;}
var objNewRow=Builder.node('tr');var arrCells=new Array;var filtTd='';var row=table.tHead.rows[table.tHead.rows.length-1];for(var i=0;i<row.cells.length;i++){if(Element.hasClassName(row.cells[i],'nosort')){continue;}
if(Element.hasClassName(row.cells[i],'filter')){this.blnFilter=true;var arrValues=this.addFilters(table.tBodies[0].rows,i);var strSelect='<select id="filt'+i+'" class="filterselect" onchange="javascript:standardistaTableSorting.filter(this)"><option value="">All Values</option>';for(var m=0;m<arrValues.length;m++){strSelect=strSelect+'<option value="'+arrValues[m]+'">'+arrValues[m]+'</option>';}
strSelect=strSelect+'</select>';filtTd=Builder.node('td');filtTd.innerHTML=strSelect;arrCells.push(filtTd);}else{arrCells.push(Builder.node('td'));}
var linkEl=Builder.node('a',{href:'/',title:'Click to sort',onclick:"javascript:return false;"});linkEl.setAttribute('columnId',i);if(Element.hasClassName(row.cells[i],'defaultSort')){Element.addClassName(linkEl,'selectsort');}
var innerEls=row.cells[i].childNodes;for(var j=0;j<innerEls.length;j++){linkEl.appendChild(innerEls[j]);}
row.cells[i].appendChild(linkEl);Event.observe(linkEl,'click',this.headingClicked);var spanEl=Builder.node('span',{className:'tableSortArrow'});if(Element.hasClassName(row.cells[i],'defaultSort')){spanEl.innerHTML=' \u2191';spanEl.setAttribute('sortorder','DESC');}else{spanEl.innerHTML='\u00A0\u00A0';}
row.cells[i].appendChild(spanEl);if(Element.hasClassName(row.cells[i],'defaultSort')){Element.addClassName(row.cells[i],'selectsort');}}
if(this.blnFilter==true){for(var m=0;m<arrCells.length;m++){objNewRow.appendChild(arrCells[m]);}
table.tHead.appendChild(objNewRow);}
if(table.hasClassName('autostripe')){this.isOdd=false;if(table.tBodies[0]){var rows=table.tBodies[0].rows;for(var i=0;i<rows.length;i++){this.doStripe(rows[i]);}}}
return true;},headingClicked:function(e){var that=standardistaTableSorting.that;var linkEl=Event.element(e);var td=linkEl.parentNode;var tr=td.parentNode;var thead=tr.parentNode;var table=thead.parentNode;if(!table.tBodies||table.tBodies[0].rows.length<=1){return false;}
var column=linkEl.getAttribute('columnId')||td.cellIndex;var arrows=document.getElementsByClassName('tableSortArrow',td);var previousSortOrder='';if(arrows.length>0){previousSortOrder=arrows[0].getAttribute('sortOrder');}
var itm="";var rowNum=0;while(""==itm&&rowNum<table.tBodies[0].rows.length){itm=that.getInnerText(table.tBodies[0].rows[rowNum].cells[column]);rowNum++;}
var sortfn=that.determineSortFunction(itm);if(table.id==that.lastSortedTable&&column==that.sortColumnIndex){newRows=that.newRows;newRows.reverse();}else{that.sortColumnIndex=column;var newRows=new Array();for(var j=0;j<table.tBodies[0].rows.length;j++){newRows[j]=table.tBodies[0].rows[j];}
newRows.sort(sortfn);}
that.moveRows(table,newRows);that.newRows=newRows;that.lastSortedTable=table.id;var arrows=document.getElementsByClassName('tableSortArrow',tr);for(var j=0;j<arrows.length;j++){var arrowParent=arrows[j].parentNode;arrowParent.removeChild(arrows[j]);Element.removeClassName(arrowParent.firstChild,'selectsort');if(arrowParent!=td){spanEl=Builder.node('span',{className:'tableSortArrow'},'\u00A0\u00A0');arrowParent.appendChild(spanEl);}}
spanEl=Builder.node('span',{className:'tableSortArrow'});if(null==previousSortOrder||''==previousSortOrder||'DESC'==previousSortOrder){spanEl.innerHTML=' \u2191';spanEl.setAttribute('sortOrder','ASC');}else{spanEl.innerHTML=' \u2193';spanEl.setAttribute('sortOrder','DESC');}
td.appendChild(spanEl);Element.addClassName(spanEl.parentNode.firstChild,'selectsort');Element.addClassName(spanEl.parentNode,'selectsort');return false;},getInnerText:function(el){if('string'==typeof el||'undefined'==typeof el){return el;}
var str=el.getAttribute('standardistaTableSortingInnerText');if(null!=str&&''!=str){return str;}
str="";var cs=el.childNodes;var l=cs.length;for(var i=0;i<l;i++){if(1==cs[i].nodeType){str+=this.getInnerText(cs[i]);break;}else if(3==cs[i].nodeType){str+=cs[i].nodeValue;break;}}
return str;},moveRows:function(table,newRows){this.isOdd=false;for(var i=0;i<newRows.length;i++){var rowItem=newRows[i];this.doStripe(rowItem);table.tBodies[0].appendChild(rowItem);}},doStripe:function(rowItem){if(rowItem.style.display!='none'){if(this.isOdd){Element.addClassName(rowItem,'odd');}else{Element.removeClassName(rowItem,'odd');}
this.isOdd=!this.isOdd;}},

	determineSortFunction: function(itm) {
		var sortfn = this.sortCaseInsensitive;
		itm.strip();
		itm = itm.replace(/,/g,'');
		if (itm.match(/^\d\d[\/-]\d\d[\/-]\d\d\d\d$/)) {
			sortfn = this.sortDate;
		}
		if(itm.match(/^\d\d[\/-]\d\d[\/-]\d\d$/)){sortfn=this.sortDate;}
		if(itm.match(/^[$]/)){sortfn=this.sortCurrency;}
		if (itm.match(/^\d?\.?\d+%?$/)) {
			sortfn = this.sortNumeric;
		}
		if(itm.match(/^[+-]?\d*\.?\d+([eE]-?\d+)?$/)){sortfn=this.sortNumeric;}
		if(itm.match(/^([01]?\d\d?|2[0-4]\d|25[0-5])\.([01]?\d\d?|2[0-4]\d|25[0-5])\.([01]?\d\d?|2[0-4]\d|25[0-5])\.([01]?\d\d?|2[0-4]\d|25[0-5])$/)){sortfn=this.sortIP;}
		return sortfn;
	},

	sortCaseInsensitive:function(a,b){var that=standardistaTableSorting.that;var aa=that.getInnerText(a.cells[that.sortColumnIndex]).toLowerCase();var bb=that.getInnerText(b.cells[that.sortColumnIndex]).toLowerCase();if(aa==bb){return 0;}else if(aa<bb){return-1;}else{return 1;}},sortDate:function(a,b){var that=standardistaTableSorting.that;var aa=that.getInnerText(a.cells[that.sortColumnIndex]);var bb=that.getInnerText(b.cells[that.sortColumnIndex]);var dt1,dt2,yr=-1;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;}else if(dt1<dt2){return-1;}
return 1;},sortCurrency:function(a,b){var that=standardistaTableSorting.that;var aa=that.getInnerText(a.cells[that.sortColumnIndex]).replace(/[^0-9.]/g,'');var bb=that.getInnerText(b.cells[that.sortColumnIndex]).replace(/[^0-9.]/g,'');if(aa.strip()==''){aa=0.00;}
if(bb.strip()==''){bb=0.00;}
return parseFloat(aa)-parseFloat(bb);},sortNumeric:function(a,b){var that=standardistaTableSorting.that;var aa=that.getInnerText(a.cells[that.sortColumnIndex]);aa=aa.replace(/,/g,'');aa=parseFloat(aa);if(isNaN(aa)){aa=0;}
var bb=that.getInnerText(b.cells[that.sortColumnIndex]);bb=bb.replace(/,/g,'');bb=parseFloat(bb);if(isNaN(bb)){bb=0;}
return aa-bb;},makeStandardIPAddress:function(val){var vals=val.split('.');for(x in vals){val=vals[x];while(3>val.length){val='0'+val;}
vals[x]=val;}
val=vals.join('.');return val;},sortIP:function(a,b){var that=standardistaTableSorting.that;var aa=that.makeStandardIPAddress(that.getInnerText(a.cells[that.sortColumnIndex]).toLowerCase());var bb=that.makeStandardIPAddress(that.getInnerText(b.cells[that.sortColumnIndex]).toLowerCase());if(aa==bb){return 0;}else if(aa<bb){return-1;}else{return 1;}}

}

Event.observe(window, 'load', standardistaTableSorting.init.bindAsEventListener(standardistaTableSorting), false);