/*----------------------------------------------------------------------------\
|                                Table Sort                                   |
|-----------------------------------------------------------------------------|
|                         Created by Erik Arvidsson                           |
|                  (http://webfx.eae.net/contact.html#erik)                   |
|                      For WebFX (http://webfx.eae.net/)                      |
|-----------------------------------------------------------------------------|
| A DOM 1 based script that allows an ordinary HTML table to be sortable.     |
|-----------------------------------------------------------------------------|
|                  Copyright (c) 1998 - 2002 Erik Arvidsson                   |
|-----------------------------------------------------------------------------|
| This software is provided "as is", without warranty of any kind, express or |
| implied, including  but not limited  to the warranties of  merchantability, |
| fitness for a particular purpose and noninfringement. In no event shall the |
| authors or  copyright  holders be  liable for any claim,  damages or  other |
| liability, whether  in an  action of  contract, tort  or otherwise, arising |
| from,  out of  or in  connection with  the software or  the  use  or  other |
| dealings in the software.                                                   |
| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
| This  software is  available under the  three different licenses  mentioned |
| below.  To use this software you must chose, and qualify, for one of those. |
| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
| The WebFX Non-Commercial License          http://webfx.eae.net/license.html |
| Permits  anyone the right to use the  software in a  non-commercial context |
| free of charge.                                                             |
| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
| The WebFX Commercial license           http://webfx.eae.net/commercial.html |
| Permits the  license holder the right to use  the software in a  commercial |
| context. Such license must be specifically obtained, however it's valid for |
| any number of  implementations of the licensed software.                    |
| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
| GPL - The GNU General Public License    http://www.gnu.org/licenses/gpl.txt |
| Permits anyone the right to use and modify the software without limitations |
| as long as proper  credits are given  and the original  and modified source |
| code are included. Requires  that the final product, software derivate from |
| the original  source or any  software  utilizing a GPL  component, such  as |
| this, is also licensed under the GPL license.                               |
|-----------------------------------------------------------------------------|
| 1998-??-?? | First version                                                  |
|-----------------------------------------------------------------------------|
| Created 1998-??-?? | All changes are in the log above. | Updated 2001-??-?? |
\----------------------------------------------------------------------------*/


var dom = (document.getElementsByTagName) ? true : false;
var ie5 = (document.getElementsByTagName && document.all) ? true : false;
var arrowUp, arrowDown;
var sAu = '\u25b2';
var sAd = '\u25bc';

if (ie5 || dom)
    initSortTable();

function initSortTable() {
    arrowUp = document.createElement("span");
    var tn = document.createTextNode(sAu);
    arrowUp.appendChild(tn);
    arrowUp.className = "arrow";

    arrowDown = document.createElement("span");
    var tn = document.createTextNode(sAd);
    arrowDown.appendChild(tn);
    arrowDown.className = "arrow";
}

function sortTable(tableNode, nCol, bDesc, mCol) {
    var start = new Date;
    var tBody = tableNode.tBodies[0];
    var trs = tBody.rows;
    var trl= trs.length;
    var a = new Array();
    
    for (var i = 0; i < trl; i++) {
        a[i] = trs[i];
    }
    
    a.sort(compareByColumn(nCol,bDesc,mCol));
    
    for (var i = 0; i < trl; i++) {
        tBody.appendChild(a[i]);
    }
    
    // check for onsort
    if (typeof tableNode.onsort == "string")
        tableNode.onsort = new Function("", tableNode.onsort);
    if (typeof tableNode.onsort == "function") 
        tableNode.onsort(tBody, nCol);
//    window.status = "Sorting (" + nCol + ", " + bDesc + ") complete in " + (new Date - start) + "ms)";
}

function fIgnore(s) {
    return 0;
}

function fBlank(s) {
    if (Number(s) == 0)
        return 1;
    return 0;
}

function fNegNbr(s) {
    return -Number(s);
}

function fGone(s) {
    if (s == "RETD" || s == "DQ" || s == "WDRW" || s == "STRT")
        return 1;
    return 0;
}

function fStatus(s) {
    if (s.indexOf('(') != -1)
        return 18;
    if (s.indexOf(':') != -1)
        return Number(s.substr(s.indexOf(':')-2,2) + s.substr(s.indexOf(':')+1,2));
    if (s.indexOf('*') != -1)
        return Number(s.substr(1));
    return Number(s);
}

function CaseInsensitiveString(s) {
    return String(s).toUpperCase();
}

function parseDate(s) {
    return Date.parse(s.replace(/\-/g, '/'));
}

/* alternative to number function
 * This one is slower but can handle non numerical characters in
 * the string allow strings like the follow (as well as a lot more)
 * to be used:
 *    "1,000,000"
 *    "1 000 000"
 *    "100cm"
 */

function toNumber(s) {
    return Number(s.replace(/[^0-9\.]/g, ""));
}

function compareByColumn(nCol, bDescending, mCol) {
    var c = nCol;
    var d = bDescending;
    var sCols = 13;
    var sCol1 = c;
    var sCol2 = 0;
    var sCol3 = 0;

    var fStatCast = fGone;
    var fKey1Cast = Number;
    var fKey2Cast = Number;
    var fKey3Cast = Number;

    if (nCol >= 9 && nCol <= 12)
        fStatCast = fIgnore;
    if (nCol == 9)
        sCol2 = 3;
    else if (nCol == 10)
        fKey1Cast = String;
    else if (nCol == 11) {
        sCol1 = 2
        fKey1Cast = String;
        sCol2 = c
        fKey2Cast = CaseInsensitiveString;
        }
    else if (nCol == 12)
        fKey1Cast = String;
    else if (nCol == 13)
        sCol1 = 8;
    else if (nCol == 23 || nCol == 33) {
        sCols = nCol
        fStatCast = fBlank;
        fKey1Cast = String;
        }
    else if (nCol >= 14 && nCol <= 32) {
        sCols = nCol
        fStatCast = fBlank;
        }
    else if (nCol == 34) {
        fKey1Cast = fStatus;
        fKey2Cast = fNegNbr;
        fKey3Cast = fNegNbr;
        sCol2 = 9;
        sCol3 = 3;
        }
    else if (nCol >= 35) {
        sCols = nCol
        fStatCast = fBlank;
        sCol1 = nCol - 35 + 4;
        }
    return function (n1, n2) {
        var s1 = fStatCast(getInnerText(n1.cells[sCols])); 	
        var s2 = fStatCast(getInnerText(n2.cells[sCols])); 	
        if (s1 < s2) return -1;
        if (s1 > s2) return +1;
        var s1 = fKey1Cast(getInnerText(n1.cells[sCol1])); 	
        var s2 = fKey1Cast(getInnerText(n2.cells[sCol1])); 	
        if (s1 < s2) return d ? -1 : +1;
        if (s1 > s2) return d ? +1 : -1;
        var s1 = fKey2Cast(getInnerText(n1.cells[sCol2])); 	
        var s2 = fKey2Cast(getInnerText(n2.cells[sCol2])); 	
        if (s1 < s2) return d ? -1 : +1;
        if (s1 > s2) return d ? +1 : -1;
        var s1 = fKey3Cast(getInnerText(n1.cells[sCol3])); 	
        var s2 = fKey3Cast(getInnerText(n2.cells[sCol3])); 	
        if (s1 < s2) return d ? -1 : +1;
        if (s1 > s2) return d ? +1 : -1;
        return 0;
    };
}

function sortColumnWithHold(e) {
    // find table element
    var el = ie5 ? e.srcElement : e.target;
    var table = getParent(el, "TABLE");
    
    // backup old cursor and onclick
    var oldCursor = table.style.cursor;
    var oldClick = table.onclick;
    
    // change cursor and onclick    
    table.style.cursor = "wait";
    table.onclick = null;
    
    // the event object is destroyed after this thread but we only need
    // the srcElement and/or the target
    var fakeEvent = {srcElement : e.srcElement, target : e.target};
    
    // call sortColumn in a new thread to allow the ui thread to be updated
    // with the cursor/onclick
    window.setTimeout(function () {
        sortColumn(fakeEvent);
        // once done resore cursor and onclick
        table.style.cursor = oldCursor;
        table.onclick = oldClick;
    }, 100);
}

function sortColumn(e, bel) {
    if (bel == 1)
        var tmp = document.getElementById(e);
    else
        var tmp = e.target ? e.target : e.srcElement;

    var tHeadParent = getParent(tmp, "THEAD");
    var el = getParent(tmp, "TD");
    if (tHeadParent == null) {
        getAllRounds(tmp);
        return;
    }
        
    if (el != null) {
        var p = el.parentNode;
        var i;

        // typecast to Boolean
        el._descending = !Boolean(el._descending);

        if (tHeadParent.arrow != null) {
            if (tHeadParent.arrow.parentNode != el) {
                tHeadParent.arrow.parentNode._descending = null;    //reset sort order      
            }
            tHeadParent.arrow.parentNode.removeChild(tHeadParent.arrow);
        }

        if (el._descending)
            tHeadParent.arrow = arrowUp.cloneNode(true);
        else
            tHeadParent.arrow = arrowDown.cloneNode(true);

        el.appendChild(tHeadParent.arrow);

            

        // get the index of the td
        var cells = p.cells;
        var l = cells.length;
        for (i = 0; i < l; i++) {
            if (cells[i] == el) break;
        }

        srttab = getParent(el, "TABLE");
        // can't fail
        
        srtcol = i;
        srtdir = el._descending;
        doBtnArrow(el);
        sortTable(srttab,srtcol,srtdir, l);
    }
}

function reSortColumn() {
    var tmp = document.getElementById("sscol" + srtcol);

    var tHeadParent = getParent(tmp, "THEAD");
    var el = getParent(tmp, "TD");
    if (tHeadParent == null)
        return;
        
    if (el != null) {
        var p = el.parentNode;
        var i;

        el._descending = srtdir;

        if (tHeadParent.arrow != null) {
            if (tHeadParent.arrow.parentNode != el) {
                tHeadParent.arrow.parentNode._descending = null;    //reset sort order      
            }
            tHeadParent.arrow.parentNode.removeChild(tHeadParent.arrow);
        }

        if (el._descending)
            tHeadParent.arrow = arrowUp.cloneNode(true);
        else
            tHeadParent.arrow = arrowDown.cloneNode(true);

        el.appendChild(tHeadParent.arrow);

        // get the index of the td
        var cells = p.cells;
        var l = cells.length;
        for (i = 0; i < l; i++) {
            if (cells[i] == el) break;
        }

        srttab = getParent(el, "TABLE");
        // can't fail
        
        doBtnArrow(el);
        sortTable(srttab,srtcol,srtdir, l);
    }
}


function getInnerText(el) {
    if (ie5) 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 += getInnerText(cs[i]);
                break;
            case 3: //TEXT_NODE
                str += cs[i].nodeValue;
                break;
        }
        
    }
    
    return str;
}

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);
}
