if (!window.Node) {
    var Node = {            // If there is no Node object, define one
        ELEMENT_NODE: 1,    // with the following properties and values.
        ATTRIBUTE_NODE: 2,  // Note that these are HTML node types only.
        TEXT_NODE: 3,       // For XML-specific nodes, you need to add
        COMMENT_NODE: 8,    // other constants here.
        DOCUMENT_NODE: 9,
        DOCUMENT_FRAGMENT_NODE: 11
    }
}
var sortTblID = "";
var sortCol = -1;
var dir = -1;

function createRowsArray (table) {
  var rows = new Array();
  var r = 0;
  if (table.tHead == null && table.tFoot == null)
    for (var r1 = 1; r1 < table.rows.length; r1++, r++)
      rows[r] = table.rows[r1];
  else  
    for (var t = 0; t < table.tBodies.length; t++)
      for (var r1 = 0; r1 < table.tBodies[t].rows.length; r1++, r++)
        rows[r] = table.tBodies[t].rows[r1];
  return rows;
}

function insertSortedRows(table, rows) {
  if (document.all) var rowsCopy = new Array(rows.length)
  for (var r = 0; r < rows.length; r++) {
    if (document.all) rowsCopy[r] = rows[r].cloneNode(true);
    table.deleteRow(rows[r].rowIndex);
  }
  var tableSection = table.tBodies[table.tBodies.length - 1];
  for (var r = 0; r < rows.length; r++) {
    var row = document.all ? rowsCopy[r] : rows[r];
    tableSection.appendChild(row);
  }
}

function sortTable (table, sortFun) {
  var color0 = table.rows[1].currentStyle.backgroundColor;
  var color1 = table.rows[2].currentStyle.backgroundColor;
  var rows = createRowsArray(table);
  if(rows.length > 1) {
    rows.sort(sortFun);
    insertSortedRows(table, rows);
    recolorTable(table, color0, color1);
  }
}

function sortRowsAlpha (row1 , row2) {
  var column = sortRowsAlpha.col;
  var cell1 = row1.cells[column].firstChild.nodeValue.toLowerCase();
  var cell2 = row2.cells[column].firstChild.nodeValue.toLowerCase();
  if (dir == 1) {
    return cell1 < cell2 ? - 1 : (cell1 == cell2 ? 0 : 1);  //sort asc
  } else {
    return cell1 > cell2 ? - 1 : (cell1 == cell2 ? 0 : 1);  //sort desc
  }
}

function sortRowsCheckbox (row1 , row2) {
  var column = sortRowsCheckbox.col;
  var cell1 = findFirstCheckboxChild(row1.cells[column]).checked;
  var cell2 = findFirstCheckboxChild(row2.cells[column]).checked;
  if (dir == 1) {
    return cell1 < cell2 ? - 1 : (cell1 == cell2 ? 0 : 1);  //sort asc
  } else {
    return cell1 > cell2 ? - 1 : (cell1 == cell2 ? 0 : 1);  //sort desc
  }
}

function sortRowsDate (row1 , row2) {
  var column = sortRowsDate.col;
  var cell1 = RemoveInvalidDateCharacters(row1.cells[column].firstChild.nodeValue);
  var cell2 = RemoveInvalidDateCharacters(row2.cells[column].firstChild.nodeValue);
  var cell1Date = new Date(cell1);
  var cell2Date = new Date(cell2);
  if (dir == 1) {
    return cell1Date < cell2Date ? - 1 : (cell1Date == cell2Date ? 0 : 1);  //sort asc
  } else {
    return cell1Date > cell2Date ? - 1 : (cell1Date == cell2Date ? 0 : 1);  //sort desc
  }
}

function sortRowsNumber (row1 , row2) {
  var column = sortRowsNumber.col;
  var cell1 = parseFloat(row1.cells[column].firstChild.nodeValue);
  var cell2 = parseFloat(row2.cells[column].firstChild.nodeValue);
  if (dir == 1) {
    return cell1 < cell2 ? - 1 : (cell1 == cell2 ? 0 : 1);  //sort asc
  } else {
    return cell1 > cell2 ? - 1 : (cell1 == cell2 ? 0 : 1);  //sort desc
  }
}

function sortRowsMoney (row1 , row2) {
  var column = sortRowsNumber.col;
  var cell1 = row1.cells[column].firstChild.nodeValue;
  var cell2 = row2.cells[column].firstChild.nodeValue;
//get rid of the commas, spaces and $ then convert to numbers
  cell1 = parseFloat(cell1.replace(/,|\s|\$/g,""));
  cell2 = parseFloat(cell2.replace(/,|\s|\$/g,""));
  
  if (dir == 1) {
    return cell1 < cell2 ? - 1 : (cell1 == cell2 ? 0 : 1);  //sort asc
  } else {
    return cell1 > cell2 ? - 1 : (cell1 == cell2 ? 0 : 1);  //sort desc
  }
}

function sortRowsLink (row1 , row2) {
  var column = sortRowsLink.col;
  var cell1 = findFirstLinkChild(row1.cells[column]).href;
  var cell2 = findFirstLinkChild(row2.cells[column]).href;
  if (dir == 1) {
    return cell1 < cell2 ? - 1 : (cell1 == cell2 ? 0 : 1);  //sort asc
  } else {
    return cell1 > cell2 ? - 1 : (cell1 == cell2 ? 0 : 1);  //sort desc
  }
}

function sortRowsLinkText (row1 , row2) {
  var column = sortRowsLinkText.col;
  var cell1 = findFirstLinkTextChild(row1.cells[column]).data.toLowerCase();
  var cell2 = findFirstLinkTextChild(row2.cells[column]).data.toLowerCase();
  if (dir == 1) {
    return cell1 < cell2 ? - 1 : (cell1 == cell2 ? 0 : 1);  //sort asc
  } else {
    return cell1 > cell2 ? - 1 : (cell1 == cell2 ? 0 : 1);  //sort desc
  }
}

function findFirstCheckboxChild (el) {
  var child = el.firstChild;
  while (child.tagName != 'INPUT')
    child = child.nextSibling;
  return child;
}

function findFirstLinkChild (el) {
  var child = el.firstChild;
  while (child.tagName != 'A')
    child = child.nextSibling;
  return child;
}

//find the text string associated with the a link
function findFirstLinkTextChild (el) {
  var child = el.firstChild;
  while (child.tagName != 'A')
    child = child.nextSibling;
  return child.firstChild;
}

function setSortDir(table, col) {
  if ((col == sortCol) && sortTblID == table.id ) {
    dir = dir * -1;
  } else {
    dir = 1;
    sortCol = col;
    sortTblID = table.id;
  }
}  

function tsortTable(table, col) {
  sortRowsAlpha.col = col;
  setSortDir(table, col);  
  sortTable(table, sortRowsAlpha);
}

function tsortTableMoney (table, col) {
  sortRowsNumber.col = col;
  setSortDir(table, col);
  sortTable(table, sortRowsMoney);
}

function tsortTableCheckbox (table, col) {
  sortRowsCheckbox.col = col;
  setSortDir(table, col);
  sortTable(table, sortRowsCheckbox);
}

function tsortTableDate (table, col) {
  sortRowsDate.col = col;
  setSortDir(table, col);
  sortTable(table, sortRowsDate);
}

function tsortTableNumerical (table, col) {
  sortRowsNumber.col = col;
  setSortDir(table, col);
  sortTable(table, sortRowsNumber);
}

function tsortTableLinks (table, col) {
  sortRowsLink.col = col;
  setSortDir(table, col);
  sortTable(table, sortRowsLink);
}

function tsortTableLinkText (table, col) {
  sortRowsLinkText.col = col;
  setSortDir(table, col);
  sortTable(table, sortRowsLinkText);
}


function findTableParent (node) {
  while (node.tagName.toUpperCase() != 'TABLE')
    node = node.parentNode;
  return node;
}

function recolorTable (table, color0, color1) {
  var color= new Array();
  color[0] = color0;
  color[1] = color1;
  for(var r = 1; r < table.rows.length; r++) {
    table.rows[r].bgColor = color[r % 2];
    table.rows[r].style.backgroundColor = color[r % 2];
    for(var c = 0; c < table.rows[r].cells.length; c++) {
      table.rows[r].cells[c].bgColor = color[r % 2];
      table.rows[r].cells[c].style.backgroundColor = color[r % 2];
    }
  }
}


function RemoveInvalidDateCharacters(oldString) {
  var validCharacters = "0123456789/";
  var newString = "";
  for(var i = 0; i < oldString.length; i++) {
	  var temp = "" + oldString.substring(i, i+1);
    if(validCharacters.indexOf(temp) != "-1") {
      newString += oldString.charAt(i);
    }
  }
  return newString; 
}
