//<![CDATA[
var NUMBER = 1;
var DATE = 2;
var TIME = 3;
var TEXT = 4;

//-----------------------------------------------------------------------------
// sortTable(id, p_Column, p_Descending)
//
//  id  - ID of the TABLE, TBODY, THEAD or TFOOT element to be sorted.
//  p_Column - Index of the column to sort, 0 = first column, 1 = second column,
//        etc.
//  p_Descending - If true, the p_Column is sorted in reverse (descending) order
//        initially.
//
//-----------------------------------------------------------------------------

function SortTable(id, p_Column, p_Descending, p_DataType) 
{
    // Get the table or table section to sort.
    var tblEl = document.getElementById(id);
    
    // Change the cursor to busy (wait) to indicate we are sorting the data
    tblEl.style.cursor = "wait";

  // The first time this function is called for a given table, set up an
  // array of reverse sort flags.
  if (tblEl.reverseSort == null) {
    tblEl.reverseSort = new Array();
    // Also, assume the race column is initially sorted.
    tblEl.lastColumn = 1;
  }

  // If this column has not been sorted before, set the initial sort direction.
  if (tblEl.reverseSort[p_Column] == null)
    tblEl.reverseSort[p_Column] = p_Descending;

  // If this column was the last one sorted, reverse its sort direction.
  if (p_Column == tblEl.lastColumn)
    tblEl.reverseSort[p_Column] = !tblEl.reverseSort[p_Column];

  // Remember this column as the last one sorted.
  tblEl.lastColumn = p_Column;

  // Set the table display style to "none" - necessary for Netscape 6 
  // browsers.
  var oldDsply = tblEl.style.display;
  tblEl.style.display = "none";

  // Sort the rows based on the content of the specified column using a
  // selection sort.

  var tmpEl;
  var i, j, k;
  var minVal, minIdx;
  var testVal;
  var cmp;

  for (i = 0; i < tblEl.rows.length - 1; i++) {

    // Assume the current row has the minimum value.
    minIdx = i;
    minVal = getTextValue(tblEl.rows[i].cells[p_Column]);

    // Search the rows that follow the current one for a smaller value.
    for (j = i + 1; j < tblEl.rows.length; j++) {
      testVal = getTextValue(tblEl.rows[j].cells[p_Column]);
      cmp = compareValues(minVal, testVal, p_DataType);
      // Negate the comparison result if the reverse sort flag is set.
      if (tblEl.reverseSort[p_Column])
        cmp = -cmp;
      if (cmp > 0) {
        minIdx = j;
        minVal = testVal;
      }
    }

    // By now, we have the row with the smallest value. Remove it from the
    // table and insert it before the current row.
    if (minIdx > i) {
      tmpEl = tblEl.removeChild(tblEl.rows[minIdx]);
      tblEl.insertBefore(tmpEl, tblEl.rows[i]);
    } 
  }

    // Highlight alternate rows and sorted column
    setStyle(tblEl, p_Column);
  
  // Restore the table's display and cursor style
  tblEl.style.display = oldDsply;
  tblEl.style.cursor = "auto";
  return false;
}

//-----------------------------------------------------------------------------
// Functions to get and compare values during a sort.
//-----------------------------------------------------------------------------
function getTextValue(el) {

  var i;
  var s;

  // Find and concatenate the values of all text nodes contained within the
  // element.
  s = "";
  for (i = 0; i < el.childNodes.length; i++)
    if (el.childNodes[i].nodeType == document.TEXT_NODE)
      s += el.childNodes[i].nodeValue;
    else if (el.childNodes[i].nodeType == document.ELEMENT_NODE &&
             el.childNodes[i].tagName.toLowerCase() == "br")
      s += " ";
    else
      // Use recursion to get text within sub-elements.
      s += getTextValue(el.childNodes[i]);

  return normalizeString(s);
}

function compareValues(v1, v2, p_DataType) {

  var value1, value2;

  // If the values are numeric, convert them to floats.
  switch (p_DataType) {
      case NUMBER:
        // Numerical values
        value1 = parseFloat(v1);
        value2 = parseFloat(v2);
      break;
      case DATE:
        // Date values
        // Extract the date value in seconds
        value1 = Date.parse(v1) * 1000;
        value2 = Date.parse(v2) * 1000;
      break;
      case TIME:
        // Time values of the form hh:mm:ss
        // Extract the hours, minutes and second units and convert to
        // a value in seconds
        var timeSting1 = new String(v1);
        var timeSting2 = new String(v2);        
        var timeUnits1 = timeSting1.split(":");
        var timeUnits2 = timeSting2.split(":");
        value1 = timeUnits1[0] * 3600 + // hours
                 timeUnits1[1] * 60 + // minutes
                 timeUnits1[2];       // seconds
        value2 = timeUnits2[0] * 3600 + // hours
                 timeUnits2[1] * 60 + // minutes
                 timeUnits2[2];       // seconds
        value1 = parseFloat(value1);
        value2 = parseFloat(value2);
      break;
      default :
        // All other values, type TEXT
        value1 = v1;
        value2 = v2;
      break;      
  } 

  // Compare the two values.
  if (value1 == value2)
    return 0;
  if (value1 > value2)
    return 1
  return -1;
}

// Regular expressions for normalizing white space.
var whtSpEnds = new RegExp("^\\s*|\\s*$", "g");
var whtSpMult = new RegExp("\\s\\s+", "g");

function normalizeString(s) {

  s = s.replace(whtSpMult, " ");  // Collapse any multiple whites space.
  s = s.replace(whtSpEnds, "");   // Remove leading or trailing white space.

  return s;
}

function setStyle(p_TableEle, p_Column) {
    for (var i = 0; i < p_TableEle.rows.length; i++) {
        // highlight alternate rows
        if (p_TableEle.rows[i].className != "result-row-template") {
            if (i % 2 == 0) {
                p_TableEle.rows[i].className = 'highlighted';
            } else {
                p_TableEle.rows[i].className = 'unhighlighted';
            }
 
            // Highlight the sorted column
            for (var k = 0; k < p_TableEle.rows[i].cells.length; k++) {
                var cellEl = p_TableEle.rows[i].cells[k];
                if (k == p_Column) {
                    cellEl.className = 'sortedColumn';
                } else {
                    cellEl.className = '';
                }
            }
        }
    }
}

//]]>
