﻿if (RONIN.TableSortMultiple == null || typeof (RONIN.TableSortMultiple) != "object") { RONIN.TableSortMultiple = new Object(); }

//This namespace allows for client-side table sorting.  It is very quick.
// !!!!! This can current only handle five columns and can only sort letters, numbers, and currency !!!!
RONIN.TableSortMultiple = {


    //sets which table is being sorted and the first row to start the sort (ie where the header rows end and the data rows start)
    initializeTable: function(strTableID, intRowNum, intColumnCount, oddClass, evenClass) {
        if (RONIN.TableSortMultiple.Counter == null) {
            RONIN.TableSortMultiple.Counter = -1;
        }
        RONIN.TableSortMultiple.Counter++;

        if (RONIN.TableSortMultiple.Indexer == null) {
            RONIN.TableSortMultiple.Indexer = new Array();
        }
        RONIN.TableSortMultiple.Indexer[RONIN.TableSortMultiple.Counter] = strTableID;

        if (RONIN.TableSortMultiple.TableArray == null || typeof (RONIN.TableSortMultiple.TableArray) != "object") {
            RONIN.TableSortMultiple.TableArray = new Array();
        }
        RONIN.TableSortMultiple.objSortTable = eval(strGetItemPrefix + strTableID + strGetItemSuffix);

        if (RONIN.TableSortMultiple.objSortTable == null) {
            alert('null table');
        }

        if (RONIN.TableSortMultiple.intStartRow == null || typeof (RONIN.TableSortMultiple.intStartRow) != "object") {
            RONIN.TableSortMultiple.intStartRow = new Array();
        }
        RONIN.TableSortMultiple.intStartRow[RONIN.TableSortMultiple.Counter] = intRowNum;

        // <TR classes for alternating rows
        if (RONIN.TableSortMultiple.OddClass == null || typeof (RONIN.TableSortMultiple.OddClass) != "object") {
            RONIN.TableSortMultiple.OddClass = new Array();
        }
        RONIN.TableSortMultiple.OddClass[RONIN.TableSortMultiple.Counter] = oddClass;

        if (RONIN.TableSortMultiple.EvenClass == null || typeof (RONIN.TableSortMultiple.EvenClass) != "object") {
            RONIN.TableSortMultiple.EvenClass = new Array();
        }
        RONIN.TableSortMultiple.EvenClass[RONIN.TableSortMultiple.Counter] = evenClass;

        // array of column data types.
        if (RONIN.TableSortMultiple.ColumnTypes == null) {
            RONIN.TableSortMultiple.ColumnTypes = new Array();
        }
        if (RONIN.TableSortMultiple.arySortType == null) {
            RONIN.TableSortMultiple.arySortType = new Array();
        }
        for (intInitializeCounter = 0; intInitializeCounter < intColumnCount; intInitializeCounter++) {
            RONIN.TableSortMultiple.arySortType[intInitializeCounter] = "str";
        }
        //save columns
        RONIN.TableSortMultiple.ColumnTypes[RONIN.TableSortMultiple.Counter] = RONIN.TableSortMultiple.arySortType;

        RONIN.TableSortMultiple.TableArray[RONIN.TableSortMultiple.Counter] = RONIN.TableSortMultiple.objSortTable;
    },

    // initilizes the data type for each column.  The default is string so if your table contians
    // any columns that aren't strings this will need to be called once for each of those columns
    setSortType: function(colNum, sortType) {
        RONIN.TableSortMultiple.arySortType[colNum] = sortType;
    },

    //Sorts the table by the column number
    sortTable: function(tableId, column) {

        var ArrayId = 0;
        for (i = 0; i < RONIN.TableSortMultiple.Indexer.length; i++) {
            if (RONIN.TableSortMultiple.Indexer[i] == tableId) {
                ArrayId = i;
            }
        }

        // get the table and whatnot
        RONIN.TableSortMultiple.objSortTable = RONIN.TableSortMultiple.TableArray[ArrayId];

        if (RONIN.TableSortMultiple.objSortTable == null)
            RONIN.TableSortMultiple.objSortTable = document.getElementById('sortTable');
        if (RONIN.TableSortMultiple.SORT_COLUMN == column) {
            RONIN.TableSortMultiple.SORT_DESC = !RONIN.TableSortMultiple.SORT_DESC;
        } else {
            RONIN.TableSortMultiple.SORT_DESC = false;
            RONIN.TableSortMultiple.SORT_COLUMN = column;
        }

        // copy the rows into a new array
        var sortingTable = new Array();
        for (i = RONIN.TableSortMultiple.intStartRow[ArrayId]; i < RONIN.TableSortMultiple.objSortTable.rows.length; i++) {
            sortingTable[i - RONIN.TableSortMultiple.intStartRow[ArrayId]] = RONIN.TableSortMultiple.objSortTable.rows[i];
        }
        RONIN.TableSortMultiple.arySortType = RONIN.TableSortMultiple.ColumnTypes[ArrayId];

        // sort this array by the appropriate column
        if (RONIN.TableSortMultiple.arySortType[column] == "str")
            sortingTable.sort(RONIN.TableSortMultiple.fnSortStr);
        else if (RONIN.TableSortMultiple.arySortType[column] == "num")
            sortingTable.sort(RONIN.TableSortMultiple.fnSortStr);
        else if (RONIN.TableSortMultiple.arySortType[column] == "$$$")
            sortingTable.sort(RONIN.TableSortMultiple.fnSortMoney);
        else if (RONIN.TableSortMultiple.arySortType[column] == "date")
            sortingTable.sort(RONIN.TableSortMultiple.fnSortStr);
        else if (RONIN.TableSortMultiple.arySortType[column] == "input")
            sortingTable.sort(RONIN.TableSortMultiple.fnSortInputBox);

        // re-append the rows to the table in the correct order
        for (i = 0; i < sortingTable.length && !RONIN.TableSortMultiple.SORT_DESC; i++) {
            RONIN.TableSortMultiple.objSortTable.tBodies[0].appendChild(sortingTable[i]);
        }
        for (i = sortingTable.length - 1; i >= 0 && RONIN.TableSortMultiple.SORT_DESC; i--)
            RONIN.TableSortMultiple.objSortTable.tBodies[0].appendChild(sortingTable[i]);

        // that's all
        RONIN.TableSortMultiple.alternate(ArrayId, RONIN.TableSortMultiple.objSortTable);
    },

    //string comparison function
    fnSortStr: function(a, b) {
        var RegExp = /^[-+]?[0-9]*\.?[0-9]+(?:[eE][-+]?[0-9]+)?$/;
        firstRow = a.cells[RONIN.TableSortMultiple.SORT_COLUMN].innerText.toLowerCase();
        secondRow = b.cells[RONIN.TableSortMultiple.SORT_COLUMN].innerText.toLowerCase();
        // determine if we have a number
        if (firstRow.match(RegExp) != null && secondRow.match(RegExp) != null) return (parseFloat(firstRow) - parseFloat(secondRow));
        // determine if we have a date
        if (Date.parse(firstRow).toString() != 'NaN' && Date.parse(secondRow).toString() != 'NaN') {
            firstRow = Date.parse(firstRow);
            secondRow = Date.parse(secondRow);
        }
        if (firstRow == secondRow) return 0;
        if (firstRow > secondRow) return 1;
        return -1;
    },

    //number comparison function
    //fnSortNum: function (a,b) {
    //    return a.cells[RONIN.TableSortMultiple.SORT_COLUMN].innerText - b.cells[RONIN.TableSortMultiple.SORT_COLUMN].innerText;
    //},

    //money comparison function
    fnSortMoney: function(a, b) {
        aa = a.cells[RONIN.TableSortMultiple.SORT_COLUMN].innerText.replace(/[^0-9.]/g, '');
        bb = b.cells[RONIN.TableSortMultiple.SORT_COLUMN].innerText.replace(/[^0-9.]/g, '');
        return parseFloat(aa) - parseFloat(bb);
    },

    //date comparison function
    fnSortDate: function(a, b) {
        var aText = a.cells[RONIN.TableSortMultiple.SORT_COLUMN].innerText;
        var bText = b.cells[RONIN.TableSortMultiple.SORT_COLUMN].innerText;
        if (aText.length != 0 && bText.length == 0) return 1;
        if (aText.length == 0 && bText.length != 0) return -1;
        if (aText.length == 0 && bText.length == 0) return 0;
        var firstRow = Date.parse(aText);
        var secondRow = Date.parse(bText);
        if (firstRow == secondRow) return 0;
        if (firstRow > secondRow) return 1;
        return -1;
    },

    //input box string value comparison function
    fnSortInputBox: function(a, b) {
        var RegExp = /^[-+]?[0-9]*\.?[0-9]+(?:[eE][-+]?[0-9]+)?$/;
        firstRow = a.cells[RONIN.TableSortMultiple.SORT_COLUMN].firstChild.value.toLowerCase();
        secondRow = b.cells[RONIN.TableSortMultiple.SORT_COLUMN].firstChild.value.toLowerCase();
        // determine if we have a number
        if (firstRow.match(RegExp) != null && secondRow.match(RegExp) != null) return (parseFloat(firstRow) - parseFloat(secondRow));
        // determine if we have a date
        if (Date.parse(firstRow).toString() != 'NaN' && Date.parse(secondRow).toString() != 'NaN') {
            firstRow = Date.parse(firstRow);
            secondRow = Date.parse(secondRow);
        }
        if (firstRow == secondRow) return 0;
        if (firstRow > secondRow) return 1;
        return -1;
    },

    alternate: function(ArrayId, table) {

        // Take object table and get all it's tbodies.
        var tableBodies = table.getElementsByTagName("tbody");
        // Loop through these tbodies

        for (var i = 0; i < tableBodies.length; i++) {
            // Take the tbody, and get all it's rows
            var tableRows = tableBodies[i].getElementsByTagName("tr");
            // Loop through these rows
            // Start at 1 because we want to leave the heading row untouched

            for (var j = 2; j < tableRows.length; j++) {
                // Check if j is even, and apply classes for both possible results

                if ((j % 2) == 0) {
                    if (!(tableRows[j].className.indexOf(RONIN.TableSortMultiple.OddClass[ArrayId]) == -1)) {
                        tableRows[j].className = tableRows[j].className.replace(RONIN.TableSortMultiple.OddClass[ArrayId], RONIN.TableSortMultiple.EvenClass[ArrayId]);
                    } else {
                        if (tableRows[j].className.indexOf(RONIN.TableSortMultiple.EvenClass[ArrayId]) == -1) {
                            tableRows[j].className += RONIN.TableSortMultiple.EvenClass[ArrayId];
                        }
                    }
                } else {
                    if (!(tableRows[j].className.indexOf(RONIN.TableSortMultiple.EvenClass[ArrayId]) == -1)) {
                        tableRows[j].className = tableRows[j].className.replace(RONIN.TableSortMultiple.EvenClass[ArrayId], RONIN.TableSortMultiple.OddClass[ArrayId]);
                    } else {
                        if (tableRows[j].className.indexOf(RONIN.TableSortMultiple.OddClass[ArrayId]) == -1) {
                            tableRows[j].className += RONIN.TableSortMultiple.OddClass[ArrayId];
                        }
                    }
                }

            }
        }
    }


    ////////////////////////////////////////////////////////////////////////////////////////////////////////////
    // if you need to sort by a different data type than the three above add the comparison function here //////
    // and then add the data type to the SortTable function on lines 36-41								  //////
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////
};

//which column are we sorting
RONIN.TableSortMultiple.SORT_COLUMN = 0;
// are we sorting descending?
RONIN.TableSortMultiple.SORT_DESC = false;
// table that is being sorted
RONIN.TableSortMultiple.objSortTable = null;
// first data row int he table
RONIN.TableSortMultiple.intStartRow = 1;
