/**
 * (c) COPYRIGHT AVIATION SOFTWARE INC. 2003-2011
 */

/** Own implementation of sorttable feature. 
  * Works together with the tr.sortHeader CSS class in style sheet, and assumes existence of border-arrow-*.gif images. 
  *
  * Browser Compatiblity: Tested and working on IE6 and FireFox
  *
  * Usage: 
  *   <table>
  *     <thead>
  *       <tr class="sortHeader">
  *         <th onclick="sortTable(this[, <value type ('text|number|auto')>])">Col 1</th>
  *         ...
  *       </tr>
  *     </thead>
  *     <tfoot>
  *       ...
  *     </tfoot>
  *     <tbody class="highlight">
  *       <tr>
  *         <td>data1</td>
  *         ...
  *       </tr>
  *     </tbody>
  *     <tbody>
  *      ...
  *     </tbody>
  *   </table>
  *
  * Note: the default value type is 'auto', in which the script will try to determine the column data type based on the two
  *       values compared. While it works in most cases, it will get confused if some column has a mixture of number and text values.
  *       In this case, manually dictating the value type in sortTable() will be justified.
  */
var IDX;
var last_sort_th;
var _value_type; // 'text', 'number', 'auto'


function sortTable(th, value_type)
{
    if (!value_type) { value_type = 'auto'; }
    _value_type = value_type;

    IDX = getOwnIndex(th);
    if (!document.all) { // fix weird firefox issue
        IDX = (IDX - 1) / 2;
    }

    var tbl = getParentTable(th);

    var arrow_up = 'url(../images/border-arrow-up.gif)';
    var arrow_down = 'url(../images/border-arrow-down.gif)';

    var direction = 'dsc';
    if (th == last_sort_th) {
        if (th.style.backgroundImage == arrow_up) { 
            direction = 'dsc';
            th.style.backgroundImage = arrow_down; 
        } else {
            direction = 'asc';
            th.style.backgroundImage = arrow_up; 
        }
    } else {
        direction = 'dsc';
        th.style.backgroundImage = arrow_down; 

        if (last_sort_th) {
            last_sort_th.style.backgroundImage = '';
        }
    }

    var tbs = tbl.tBodies;
    var cs;
    var subGroups = new Array();
    for (var i = 0; i < tbs.length; i++) {
        if (i == 0) {
            cs = new Array();
        } else if (getFirstTr(tbs[i-1]).className == 'subtotal') {
            subGroups.push(cs);
            cs = new Array();
        }
        cs.push(tbs[i]);
    }
    if (cs) {
        subGroups.push(cs);
    }
    for (var j = 0; j < subGroups.length; j++) {
        sortSubTable(tbl, subGroups[j], direction);
    }

    last_sort_th = th;
}

// sort table groups (to preserve subtotal)
function sortSubTable(tbl, cs, direction)
{
    var arr = new Array();
    for (var i = 0; i < cs.length; i ++) {
        arr.push(cs[i].cloneNode(true));
    }

    if (direction == 'dsc') {
        arr.sort(compareTbodyDsc);
    } else {
        arr.sort(compareTbodyAsc);
    }

    for (var i = 0; i < cs.length; i ++) {
        arr[i].className = cs[i].className;
        tbl.replaceChild(arr[i], cs[i]);
    }
}


function compareTbodyAsc(tb1, tb2)
{
    return compareTbody(tb1, tb2, 'asc');
}


function compareTbodyDsc(tb1, tb2)
{
    return compareTbody(tb1, tb2, 'dsc');
}


function compareTbody(tb1, tb2, direction)
{
    // always leave subtotal at the botom
    var class1 = getFirstTr(tb1).className;
    var class2 = getFirstTr(tb2).className;
    if (class1 == 'subtotal') {
        return 1;
    } else if (class2 == 'subtotal') {
        return -1;
    }

    var td1 = getTd(getFirstTr(tb1), IDX);
    var td2 = getTd(getFirstTr(tb2), IDX);

    if (!td1 || !td2) {
        if (!td1 && !td2) {
            return 0;
        } else if (!td1) {
            return direction == 'asc' ? -1 : 1;
        } else {
            return direction == 'asc' ? 1 : -1;
        }
    }

    while (td1.firstChild && td1.firstChild.nodeType == 1) {
        td1 = td1.firstChild;
    }
    while (td2.firstChild && td2.firstChild.nodeType == 1) {
        td2 = td2.firstChild;
    }

    var v1 = td1.innerHTML;
    var v2 = td2.innerHTML;

    if (_value_type == 'number' || _value_type == 'auto') {
        v1 = v1.replace(",", "");
        v2 = v2.replace(",", "");

        v1 = v1.replace(" ", "");
        v2 = v2.replace(" ", "");

        var reg = /^[\d\.]+$/;
        if (reg.test(v1) && reg.test(v1)) {
            v1 = parseFloat(v1);
            v2 = parseFloat(v2);
        } else {
            if (_value_type == 'number') {
                if (reg.test(v1)) {
                    v1 = parseFloat(v1);
                } else {
                    v1 = 0;
                }

                if (reg.test(v2)) {
                    v2 = parseFloat(v2);
                } else {
                    v2 = 0;
                }
            }
        }
    }

    if (v1 == v2) {
        return 0;
    } else if (v1 < v2) {
        return direction == 'asc' ? -1 : 1;
    } else {
        return direction == 'asc' ? 1 : -1;
    }
}


function getTd(tr, n)
{
    var nds = tr.childNodes;
    var cur_td_idx = 0;
    for (var i = 0; i < nds.length; i++) {
        var cur_nd = nds[i];
        if (cur_nd.tagName == 'td' || cur_nd.tagName == 'TD') {
            cur_td_idx ++;
        }
        if (cur_td_idx == n + 1) {
            return cur_nd;
        }
    }
    return null;
}


function getFirstTr(tb)
{
    var nds = tb.childNodes;
    for (var i = 0; i < nds.length; i++) {
        if (nds[i].tagName == 'TR' || nds[i].tagName == 'tr') {
            return nds[i];
        }
    }
    return null;
}


function getOwnIndex(chld)
{
    var par = chld.parentNode;
    var sbls = par.childNodes;

    for (var i = 0; i < sbls.length; i++) {
        if (sbls[i] == chld) {
            return i;
        }
    }

    return -1;
}


function getParentTable(th)
{
    var tbl = th.parentNode;
    while (tbl.tagName != 'table' && tbl.tagName != 'TABLE') {
        tbl = tbl.parentNode;
        if (tbl.tagName == 'body' && tbl.tagName == 'BODY') {
            return null;
        }
    }
    return tbl;
}

