/* set altrows param 1 to true if you are using alterate
rows and then give the 1st and 2nd row classes */
var altrows = new Array(true,'one','two');

addLoadListener(initSortableTables);

function initSortableTables() {
  if (identifyBrowser() != "ie5mac") {
    var tables = getElementsByAttribute("class", "sorttable");
    for (var i = 0; i < tables.length; i++) {
      var ths = tables[i].getElementsByTagName("th");

      for (var k = 0; k < ths.length; k++) {
        var newA = document.createElement("a");
        newA.setAttribute("href", "javascript:;");
        newA.setAttribute("title", "Sort by this column in descending order");

        for (var m = 0; m < ths[k].childNodes.length; m++) {
          if (ths[k].childNodes[m].nodeType == "3") {
			newA.appendChild(ths[k].childNodes[m]);
			textNode = true;
		  } else {
			textNode = false;
		  }
        }
        if (textNode == true) {
		  ths[k].appendChild(newA);
		}

        addEvent(newA, "click", sortColumn, false);
      }
    }
  }
  return true;
}

function sortColumn(event) {
  if (typeof event == "undefined") {
    event = window.event;
  }
  var targetA = getEventTarget(event);
  while (targetA.nodeName.toLowerCase() != "a") {
  targetA = targetA.parentNode;
  }

  var targetTh = targetA.parentNode;
  var targetTr = targetTh.parentNode;
  var targetTrChildren = targetTr.getElementsByTagName("th");
  var targetTable = targetTr.parentNode.parentNode;
  var targetTbody = targetTable.getElementsByTagName("tbody")[0];
  var targetTrs = targetTbody.getElementsByTagName("tr");
  var targetColumn = 0;

  for (var i = 0; i < targetTrChildren.length; i++) {
    targetTrChildren[i].className = targetTrChildren[i].className.replace(/(^| )sorteddescending( |$)/, "$1");
    targetTrChildren[i].className = targetTrChildren[i].className.replace(/(^| )sortedascending( |$)/, "$1");

    if (targetTrChildren[i] == targetTh) {
      targetColumn = i;
      if (targetTrChildren[i].sortOrder == "descending" && targetTrChildren[i].clicked) {
        targetTrChildren[i].sortOrder = "ascending";
        targetTrChildren[i].className += " sortedascending";
        targetA.setAttribute("title", "Sort by this column in descending order");
      } else {
        if (targetTrChildren[i].sortOrder == "ascending" && !targetTrChildren[i].clicked) {
          targetTrChildren[i].className += " sortedascending";
        } else {
          targetTrChildren[i].sortOrder = "descending";
          targetTrChildren[i].className += " sorteddescending";
          targetA.setAttribute("title", "Sort by this column in ascending order");
        }
      }
      targetTrChildren[i].clicked = true;
    } else {
      targetTrChildren[i].clicked = false;
      if (targetTrChildren[i].sortOrder == "ascending") {
        targetTrChildren[i].firstChild.setAttribute("title", "Sort by this column in ascending order");
      } else {
        targetTrChildren[i].firstChild.setAttribute("title", "Sort by this column in descending order");
      }
    }
  }

  var newTbody = targetTbody.cloneNode(false);
  for (var i = 0; i < targetTrs.length; i++) {
    var newTrs = newTbody.childNodes;
    var targetValue = getInternalText(targetTrs[i].getElementsByTagName("td")[targetColumn]);

    for (var j = 0; j < newTrs.length; j++) {
      var newValue = getInternalText(newTrs[j].getElementsByTagName("td")[targetColumn]);
      if (targetValue == parseInt(targetValue, 10) && newValue == parseInt(newValue, 10)) {
        targetValue = parseInt(targetValue, 10);
        newValue = parseInt(newValue, 10);
      } else if (targetValue == parseFloat(targetValue) && newValue == parseFloat(newValue)) {
        targetValue = parseFloat(targetValue, 10);
        newValue = parseFloat(newValue, 10);
      } if (targetTrChildren[targetColumn].sortOrder == "descending") {
        if (targetValue >= newValue) {
          break;
        }
      } else {
        if (targetValue <= newValue) {
          break;
        }
      }
    }

    if (j >= newTrs.length) {
      newTbody.appendChild(targetTrs[i].cloneNode(true));
    } else {
      newTbody.insertBefore(targetTrs[i].cloneNode(true), newTrs[j]);
    }
  }
  targetTable.replaceChild(newTbody, targetTbody);
  stopDefaultAction(event);
  if (altrows[0] == true) {
	  for (var k = 0; k < newTrs.length; k++) {
		k % 2 == 0 ? newTrs[k].className = altrows[1] : newTrs[k].className = altrows[2];
	  }
  }
  return false;
}

function getInternalText(target) {
  var elementChildren = target.childNodes;
  var internalText = "";

  for (var i = 0; i < elementChildren.length; i++) {
    if (elementChildren[i].nodeType == 3) {
      if (!/^\s*$/.test(elementChildren[i].nodeValue)) {
        internalText += elementChildren[i].nodeValue;
      }
    } else {
      internalText += getInternalText(elementChildren[i]);
    }
  }
  return internalText;
}
