addEvent(window, "load", initializeActiveTables);

function initializeActiveTables() {
    if (!document.getElementsByTagName) return;
    tbls = document.getElementsByTagName("table");
    for (ti=0;ti<tbls.length;ti++) {
        thisTbl = tbls[ti];
        if (hasClass(thisTbl, 'activetable')) {
            var sortTable = new ActiveTable(thisTbl);
        }
    }
}

function ActiveTable (table) {

    me = this;
    this.getInnerText = function(el) {
	if (typeof el == "string") return el;
    	if (typeof el == "undefined") { return el };
	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++) {
		switch (cs[i].nodeType) {
			case 1: //ELEMENT_NODE
				str += me.getInnerText(cs[i]);
				break;
			case 3:	//TEXT_NODE
				str += cs[i].nodeValue;
				break;
		}
	}
	return str;
    }
    this.sortTable = function(e) {
        
	if (!e) var e = window.event;
    	e.cancelBubble = true;
	if (e.stopPropagation) {
            e.stopPropagation();
	}
	var cell = whichElement(e);
	if (cell.nodeName != 'TH') {
            cell = me.getParent(cell,'TH');
	}
	// Get the span identifying the sort direction
        var spans = cell.getElementsByTagName('span');
	var span = spans[spans.length -1];
        var column = cell.cellIndex;
        var table = me.getParent(cell,'TABLE');
        // Determine the type of sort
        if (table.rows.length <= 1) return;
        var itm = me.getInnerText(table.rows[1].cells[column]);
        if (hasClass(cell,'date')) sortfn = me.sortDate;
        else if (hasClass(cell,'currency')) sortfn = me.sortCurrency;
        else if (hasClass(cell,'numeric')) sortfn = me.sortNumeric;
        else if (hasClass(cell,'decimal')) sortfn = me.sortNumeric;
        else sortfn = me.sortCaseInsensitive;
        SORT_COLUMN_INDEX = column;
        var firstRow = new Array();
        var rows = new Array();

        addToArray(rows,table.rows);
	rows.splice(0,1);

        rows.sort(sortfn);

        if (hasClass(span,'sortDesc')) {
            ARROW = '&nbsp;&nabla;';
            rows.reverse();
            removeClass(span, 'sortDesc');
            addClass(span, 'sortAsc');
        } else {
            ARROW = '&nbsp;&Delta;';
            removeClass(span, 'sortAsc');
            addClass(span, 'sortDesc');
        }
        span.innerHTML = ARROW;
    
        for (i=0;i<rows.length;i++) {table.tBodies[0].appendChild(rows[i]);}
    
        // Delete any other arrows there may be showing
        var allspans = me.getParent(cell,'TR').getElementsByTagName("span");
        for (var ci=0;ci<allspans.length;ci++) {
            if (hasClass(allspans[ci], 'sortAsc') || hasClass(allspans[ci], 'sortDesc')) {
                if (allspans[ci] != span) {
                    allspans[ci].innerHTML = '&nbsp;';
                    allspans[ci].className = '';
                }
            }
        }
    }

    this.getParent = function (el, pTagName) {
	if (el == null) return null;
	else if (el.nodeType == 1 && el.tagName.toLowerCase() == pTagName.toLowerCase()) {	
            return el;
	} else {
            return me.getParent(el.parentNode, pTagName);
        }
    }

    this.sortDate = function(a,b) {
        dt1 = Date.parse(me.getInnerText(a.cells[SORT_COLUMN_INDEX]));
	dt2 = Date.parse(me.getInnerText(b.cells[SORT_COLUMN_INDEX]));
	if (isNaN(dt2)) dt2 = 0;
	if (isNaN(dt1)) dt1 = 0;
        return dt1-dt2;
    }

    this.sortCurrency = function(a,b) { 
        aa = me.getInnerText(a.cells[SORT_COLUMN_INDEX]).replace(/[^0-9.]/g,'');
        bb = me.getInnerText(b.cells[SORT_COLUMN_INDEX]).replace(/[^0-9.]/g,'');
        if (isNaN(aa)) aa = 0;
        if (isNaN(bb)) bb = 0;
        return parseFloat(aa) - parseFloat(bb);
    }

    this.sortNumeric = function(a,b) { 
        aa = parseFloat(me.getInnerText(a.cells[SORT_COLUMN_INDEX]));
        if (isNaN(aa)) aa = 0;
        bb = parseFloat(me.getInnerText(b.cells[SORT_COLUMN_INDEX])); 
        if (isNaN(bb)) bb = 0;
        return aa-bb;
    }

    this.sortCaseInsensitive = function(a,b) {
        aa = me.getInnerText(a.cells[SORT_COLUMN_INDEX]).toLowerCase();
        bb = me.getInnerText(b.cells[SORT_COLUMN_INDEX]).toLowerCase();
        if (aa==bb) return 0;
        if (aa<bb) return -1;
        return 1;
    }

    this.sortDefault = function(a,b) {
        aa = me.getInnerText(a.cells[SORT_COLUMN_INDEX]);
        bb = me.getInnerText(b.cells[SORT_COLUMN_INDEX]);
        if (aa==bb) return 0;
        if (aa<bb) return -1;
        return 1;
    }

    //*******************************************************************************
    // Ititialization
    //*******************************************************************************
    this.SORT_COLUMN_INDEX;
    if (table.rows && table.rows.length > 0) {
        var firstRow = table.rows[0];
    }
    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];
        var txt = this.getInnerText(cell);
        cell.innerHTML = cell.innerHTML + '<span>&nbsp;</span>';
        addEvent(cell,'click', me.sortTable);
        addClass(cell,'sortHeader');
    }
}
