/*
jsTableSort.js
Include this file to be able to sort a table by clicking on the table column header.
Code modified from http://www.brainjar.com/dhtml/tablesort/demo.html to remove style and
assumption of an already sorted column.

For best results, table should have header row(s) in <thead> and table body in <tbody> with
an id for <tbody> being passed in.
*/

/*
Original copyright of code owner
<!--************************************************************************-->
<!--* Table Sort Demo                                                      *-->
<!--*                                                                      *-->
<!--* Copyright 2002 by Mike Hall                                          *-->
<!--* Please see http://www.brainjar.com for terms of use.                 *-->
<!--************************************************************************-->
*/

//-----------------------------------------------------------------------------
// sortTable(id, col, rev)
//
//  id  - ID of the TABLE, TBODY, THEAD or TFOOT element to be sorted.
//  col - Index of the column to sort, 0 = first column, 1 = second column,
//        etc.
//  rev - If true, the column is sorted in reverse (descending) order
//        initially.
//
//-----------------------------------------------------------------------------

function sortTable(id, col, rev) {

  // Get the table or table section to sort.
  var tblEl = document.getElementById(id);


  // 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();
    // set lastColumn to -1 to initialize.
    tblEl.lastColumn = -1;
  }

  // If this column has not been sorted before, set the initial sort direction.
  if (tblEl.reverseSort[col] == null)
    tblEl.reverseSort[col] = rev;

  // If this column was the last one sorted, reverse its sort direction.
  if (col == tblEl.lastColumn)
    	tblEl.reverseSort[col] = !tblEl.reverseSort[col];

  for (i = 0; i < tblEl.rows[0].cells.length - 1; i++) {
	  if(i != col)
  	 	  document.getElementById("img_"+i).src = 'http://www.graintradingonline.com.au/images/spacer.gif';
  }

  //alert(document.getElementById("img_"+col).src);
  if(document.getElementById("img_"+col).src == 'http://www.graintradingonline.com.au/images/spacer.gif'){
	  if(!rev)
	  	  document.getElementById("img_"+col).src = 'http://www.graintradingonline.com.au/images/sort_descending.gif';
	  else
	  	  document.getElementById("img_"+col).src = 'http://www.graintradingonline.com.au/images/sort_asscending.gif';
  }else if(document.getElementById("img_"+col).src == 'http://www.graintradingonline.com.au/images/sort_asscending.gif'){
	  document.getElementById("img_"+col).src = 'http://www.graintradingonline.com.au/images/sort_descending.gif';
  }else if(document.getElementById("img_"+col).src == 'http://www.graintradingonline.com.au/images/sort_descending.gif'){
	  document.getElementById("img_"+col).src = 'http://www.graintradingonline.com.au/images/sort_asscending.gif';
  }

  // Remember this column as the last one sorted.
  tblEl.lastColumn = col;

  // 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;
  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[col]);

    // 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[col]);
      cmp = compareValues(minVal, testVal);
      // Negate the comparison result if the reverse sort flag is set.
      if (tblEl.reverseSort[col])
        cmp = -cmp;
      // If this row has a smaller value than the current minimum, remember its
      // position and update the current minimum value.
      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]);
    }
  }
  //document.getElementById("img_"+col).style.width = "10";
  //document.getElementById("img_"+col).style.display = "block";
  //document.getElementById("link_"+col).style.align = "left";

  // Restore the table's display style.
  tblEl.style.display = oldDsply;

  return false;
}

//-----------------------------------------------------------------------------
// Functions to get and compare values during a sort.
//-----------------------------------------------------------------------------

// This code is necessary for browsers that don't reflect the DOM constants
// (like IE).
if (document.ELEMENT_NODE == null) {
  document.ELEMENT_NODE = 1;
  document.TEXT_NODE = 3;
}

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 == "BR")
      s += " ";
    else
      // Use recursion to get text within sub-elements.
      s += getTextValue(el.childNodes[i]);

  return normalizeString(s);
}

function compareValues(v1, v2) {

  var f1=null, f2=null;
  var p;

  // If the values are both numeric, convert them to floats and compare.
  var re = /^\d+$/;
  if (re.test(v1) && re.test(v2))
    {
    f1=parseFloat(v1);
    f2=parseFloat(v2);

    if (f1 == f2)
      return 0;
    else if (f1 > f2)
      return 1
    else return -1;
    }

  // If the values are both dates, convert them to dates and compare.
  if (isDate(v1) && isDate(v2))
     {
     p = v1.split("/");  // date is mm/dd/yyyy, so p[0] is month, p[1] is day, p[2] is 4 digit year
     f1 = new Date();
     f1.setDate(parseInt(p[1]));
     f1.setMonth(parseInt(p[0]));
     f1.setYear(parseInt(p[2]));
     p = v2.split("/");
     f2 = new Date();
     f2.setDate(parseInt(p[1]));
     f2.setMonth(parseInt(p[0]));
     f2.setYear(parseInt(p[2]));
     if (f1 == f2)
       return 0;
     else if (f1 > f2)
       return 1
     else return -1;
     }

  // otherwise, compare as strings
  if (v1 == v2)
    return 0;
  else if (v1 > v2)
    return 1
  else 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 isDate(str)
   {
   /* Returns true if the field is mm/dd/yyyy because for some reason, the browser is not giving
	   the expected NaN for these fields */
	var re = /^[01]?[0-9]\/[0-9]?[0-9]\/[12][0-9][0-9][0-9]$/;

	if (!str || str.length<1) return false;
	if (!re.test(str)) return false;
	else return true;
   }

