/********
FILENAME: autoSort.js
VERSION:  1.2
AUTHOR:   Kevin Hastie
CREATED:  2004-07-07
MODIFIED: 2004-08-11 by Tricia Woodruff
SUMMARY:  Autosorting and autohighlighting script

DESCRIPTION: 
Client-side sorting script to sort tables without making calls to the server. Includes code to automatically alternate row colors/styles and to highlight the column headers.

CHANGELOG:
1.3   - made more generic for general use - twoodruff
1.2   - Column header now highlights to indicate which column the data is sorted on
      - Modified to support Mozilla
1.1   - Addressed IE5 multi-threading bug

********/
  if (is_mac_ie5x) { // Hide table header links in Mac IE5.x - this will disable the sorting
    document.writeln("<style type=\"text/css\">.sorterLink {text-decoration: none;}</style>");
  }

var allowSorting = false;
var functionString;
var sortedOn = -1; // Remembers column # you are currently sorted by.
var secondarySort = -1; // The column to do a secondary sort on
var numColumns;
var sortDirection = 'inc';
var imgArrowInc = '/features/overviews/images/arrow_up.gif';
var imgArrowDec = '/features/overviews/images/arrow_down.gif';

// Sort the table with id=tableId by the values in column number sortOn
function SortTable(tableId, sortOn, sortType, numColumns, rowShade, colorOffset, secondSortIn) {
   if (!is_mac_ie5x) {
secondarySort=secondSortIn
      var table = document.getElementById(tableId);
      var tbody = table.getElementsByTagName('tbody')[0]; // Only the rows in <TBODY> will be affected
      var rows = tbody.getElementsByTagName('tr');
      
      // Make a copy of the array of row elements
      var rowArray = new Array();
      for (var i=0, length=rows.length; i<length; i++) {
         rowArray[i] = rows[i].cloneNode(true);
      }
   
      // If already sorted by this column, reverse the order & handle TBD types
      if (sortOn == sortedOn) {
         rowArray.reverse();
         flipSortArrow(sortedOn);
      	if (sortType.toLowerCase() == "tbd") {
         rowArray.sort(RowCompareTBD);
      	}
   
      // Otherwise sort by this column
      } else {
         sortedOn = sortOn;
		 sortDirection = 'inc';
         // Use the appropriate sort for the type of data in the column
         // this is determined by the sortType parameter.
         if (sortType.toLowerCase() == "tbd") {
            rowArray.sort(RowCompareTBD);
         }
         else if (sortType.toLowerCase() == "link") {
            rowArray.sort(RowCompareLinkIds);
         }
         else if (sortType.toLowerCase() == "idtext") {
            rowArray.sort(RowCompareIdText);
         }
         else if (sortType.toLowerCase() == "date") {
            rowArray.sort(RowCompareDate);
         } 
         else if (sortType.toLowerCase() == "sttext") {
            rowArray.sort(RowCompareStraightText);
         }
         else if (sortType.toLowerCase() == "dollars") {
            rowArray.sort(RowCompareDollars);
         } 
         else { // default sort
            rowArray.sort(RowCompare);
         }

         toggleSortArrowsOff(numColumns);
         toggleSortArrowOn(sortOn);
      
      }
   
      // Build a new <TBODY> and replace the old one
      var newTbody = document.createElement('tbody');
      for (var i=0, length=rowArray.length; i<length; i++) {
         newTbody.appendChild(rowArray[i]);
      }
      table.replaceChild(newTbody, tbody);
   }
   
   // Highlight appropriate column header
	
   highlightColumnHeader(tableId, sortOn, colorOffset);
   if(rowShade==1)alternateRowClasses(tableId, 0, 'oddRow', 'evenRow');
   // Ensures that the page is not refreshed when onClick="return SortTable(...)" is used
   return false;
}
  
	// Default compare function
	// So 10 < 2 (compares the string '10' to the string '2')
	function RowCompare(a, b) {
	 var aCell = a.getElementsByTagName('td')[sortedOn];
    var bCell = b.getElementsByTagName('td')[sortedOn];    

    var aNodeValue = aCell.firstChild.nodeValue;
    var bNodeValue = bCell.firstChild.nodeValue;
    var aVal;
	var bVal;
      
    if (aNodeValue != null) { // Check for null
      aVal = aNodeValue.toLowerCase();
    } else {
      aVal = aCell.innerHtml;
    }
    
    if (bNodeValue != null) { // Check for null
      bVal = bNodeValue.toLowerCase();
    } else {
      bVal = bCell.innerHtml;
    }
    
		

    if (aVal == bVal && (sortedOn != secondarySort)) { // Perform secondary sort
      rememberSortedOn = sortedOn;
      sortedOn = secondarySort; // temporarily pretend you're sorting on column[secondarySort]
      returnVal = RowCompareLinkIds(a, b);
      sortedOn = rememberSortedOn;
      return returnVal;    

    } else return (aVal > bVal ? 1 : -1);
	}

	
	
	// Compare function for currency (removes dollar signs and commas)
	function RowCompareDollars(a, b) {

    var aCell = a.getElementsByTagName('td')[sortedOn];
    var bCell = b.getElementsByTagName('td')[sortedOn];
	 
	var aInnerHTML = aCell.innerHTML;
    var bInnerHTML = bCell.innerHTML;

ahHold = aInnerHTML.toUpperCase()
if(ahHold.indexOf("DIV")>-1)aInnerHTML = aInnerHTML.substring(aInnerHTML.indexOf('>')+1,aInnerHTML.indexOf('</'));

bhHold = bInnerHTML.toUpperCase()
if(bhHold.indexOf("DIV")>-1)bInnerHTML = bInnerHTML.substring(bInnerHTML.indexOf('>')+1,bInnerHTML.indexOf('</'));

	 if(aInnerHTML.indexOf("-")>-1)aInnerHTML=aInnerHTML.substring(0,aInnerHTML.indexOf("-"));
	 if(bInnerHTML.indexOf("-")>-1)bInnerHTML=bInnerHTML.substring(0,bInnerHTML.indexOf("-"));
 

    	// Uses a regexp to strip commas and dollar signs, then parses out the (first) float
		var aVal = parseFloat(aInnerHTML.replace(/,|\$/g,''));
		var bVal = parseFloat(bInnerHTML.replace(/,|\$/g,''));


    if (isNaN(aVal) || isNaN(bVal)){
  		return (aInnerHTML == bInnerHTML ? 0 : (aInnerHTML > bInnerHTML ? 1 : -1));
    } else return (aVal > bVal ? 1 : -1);
}
	

	function MM_swapImage() { //v3.0
	  var i,j=0,x,a=MM_swapImage.arguments; document.MM_sr=new Array; for(i=0;i<(a.length-2);i+=3)
	   if ((x=MM_findObj(a[i]))!=null){document.MM_sr[j++]=x; if(!x.oSrc) x.oSrc=x.src; x.src=a[i+2];}
	}

	// Hides all sort arrows (based on numColumns)
	function toggleSortArrowsOff(numColumns) {
		for (var i = 0; i < numColumns; i++) {
			MM_swapImage('sortArrow' + i,'','/images/pixel.gif');
		}
	}
  
  // Displays the increasing sort arrow for column n
  function toggleSortArrowOn(n) {
    MM_swapImage('sortArrow' + n,'',imgArrowInc);
  }

	// Flips the sortArrow for column indicated by param:column. Also flips sortDirection.
	function flipSortArrow(column) {
		if (sortDirection == 'inc') { // if currently in increasing order
			MM_swapImage('sortArrow' + column, '',imgArrowDec);
			sortDirection = 'dec';
		} else { // if currently in decreasing order
			MM_swapImage('sortArrow' + column, '',imgArrowInc);
			sortDirection = 'inc';
		}
	}




	  
  function RowCompareLinkIds(a, b) {

    var aCell = a.getElementsByTagName('td')[sortedOn];
    var bCell = b.getElementsByTagName('td')[sortedOn];    


	var aInnerHTML = aCell.innerHTML;
    var bInnerHTML = bCell.innerHTML;
    
    return (aInnerHTML == bInnerHTML ? 0 : (aInnerHTML > bInnerHTML ? 1 : -1));
    
  }





  function RowCompareStraightText(a, b) {

    var aCell = a.getElementsByTagName('td')[sortedOn];
    var bCell = b.getElementsByTagName('td')[sortedOn];    


	var aInnerHTML = aCell.innerHTML;
    var bInnerHTML = bCell.innerHTML;
	 
	 
	 var atextStr = aInnerHTML.substring(aInnerHTML.indexOf('">'),aInnerHTML.indexOf('</'));
	 var btextStr = bInnerHTML.substring(bInnerHTML.indexOf('">'),bInnerHTML.indexOf('</')); 	 

  //  return (atextStr == btextStr ? 0 : (atextStr > btextStr ? 1 : -1));
    


    if (atextStr == btextStr && (sortedOn != secondarySort)) { // Perform secondary sort
      rememberSortedOn = sortedOn;
      sortedOn = secondarySort; // temporarily pretend you're sorting on column[secondarySort]
      returnVal = RowCompareLinkIds(a, b);
      sortedOn = rememberSortedOn;
      return returnVal;
    } else return (atextStr > btextStr ? 1 : -1);
  }







  function RowCompareIdText(a, b) {

    var aCell = a.getElementsByTagName('td')[sortedOn];
    var bCell = b.getElementsByTagName('td')[sortedOn];    

    var aID = aCell.id;
    var bID= bCell.id;
    
    return (aID == bID ? 0 : (aID > bID ? 1 : -1));
    
  }
  
  function RowCompareDate(a, b) {

    var aCell = a.getElementsByTagName('td')[sortedOn];
    var bCell = b.getElementsByTagName('td')[sortedOn];    

    var aInnerHTML = aCell.innerHTML;
    var bInnerHTML = bCell.innerHTML;
    
    aDate = new Date(aInnerHTML);
    bDate = new Date(bInnerHTML);

    return (aDate.getTime() == bDate.getTime() ? 0 : (aDate.getTime() > bDate.getTime() ? 1 : -1));
    
  }
  
  function RowCompareTBD(a, b) {
    // If TBD (or TBA) is contained in the string anywhere, that string should
    // be considered greater than any other value.

    var aCell = a.getElementsByTagName('td')[sortedOn];
    var bCell = b.getElementsByTagName('td')[sortedOn];    
    var aNodeValue = aCell.firstChild.nodeValue;
    var bNodeValue = bCell.firstChild.nodeValue;
    var aVal;
    var bVal;
    var rememberSortedOn;
    var returnVal;
    
    if (aNodeValue != null) { // Check for null
      aVal = aNodeValue.toLowerCase();
    } else {
      aVal = '';
    }
    
    if (bNodeValue != null) { // Check for null
      bVal = bNodeValue.toLowerCase();
    } else {
      bVal = '';
    }

    if (aVal.indexOf('tbd') != -1 || aVal.indexOf('tba') != -1) {
      if (bVal.indexOf('tbd') != -1 || bVal.indexOf('tba') != -1) {
        // if both contain 'tbd' then sort alphabetically on column[secondarySort]
        rememberSortedOn = sortedOn;
        sortedOn = secondarySort; // temporarily pretend you're sorting on column[secondarySort]
        returnVal = RowCompareLinkIds(a, b);
        sortedOn = rememberSortedOn;
        return returnVal;

      } else { // 'TBD' > anything
        return 1;
      }
    } else if (bVal.indexOf('tbd') != -1 || bVal.indexOf('tba') != -1) { // anything < 'TBD'
      return -1;
    } else { 
  		if (sortedOn == 3) {
        if (sortDirection == 'inc'){
    			return (RowCompareNumbers(a,b));
        } else {
    			return (RowCompareNumbers(b,a));        
        }
  		} else if (sortedOn == 2) {
        if (sortDirection == 'inc') {
    			return (RowCompareDollars(a,b));
        } else {
          return (RowCompareDollars(b,a));
        }
      }
    }
  }




	// Compare function for integers (removes commas & number signs, then parses an int)
	// So 1,000 > 200 (compares the int 1000 to the int 200)
	function RowCompareNumbers(a, b) {

    var aCell = a.getElementsByTagName('td')[sortedOn];
    var bCell = b.getElementsByTagName('td')[sortedOn];
    var aNodeValue = aCell.firstChild.nodeValue;
    var bNodeValue = bCell.firstChild.nodeValue;
    
		var aVal = parseInt(aNodeValue.replace(/,|\#/g,''));
		var bVal = parseInt(bNodeValue.replace(/,|\#/g,''));
		

    if (isNaN(aVal) || isNaN(bVal)){
  		return (aNodeValue == bNodeValue ? 0 : (aNodeValue > bNodeValue ? 1 : -1));
    } else if (aVal == bVal && (sortedOn != secondarySort)) { // Perform secondary sort
      rememberSortedOn = sortedOn;
      sortedOn = secondarySort; // temporarily pretend you're sorting on column[secondarySort]
      returnVal = RowCompareLinkIds(a, b);
      sortedOn = rememberSortedOn;
      return returnVal;
    } else return (aVal > bVal ? 1 : -1);
	}





	function alternateRowClasses (tableId, startAt, firstClassName, secondClassName) {
    var table = document.getElementById(tableId);
    var tbody = document.getElementById(tableId).getElementsByTagName('tbody')[0];
    var tbodyRows = document.getElementById(tableId).getElementsByTagName('tbody')[0].getElementsByTagName('tr');
    
		for (var i = startAt; i < tbodyRows.length; i++) {
    
			for (var j = 0; j < tbodyRows[i].getElementsByTagName('td').length; j++) {
      
				if (i%2 == 0) { // "odd" rows, starting at row[startAt] (so row[0] is considered odd)
					document.getElementById(tableId).getElementsByTagName('tbody')[0].getElementsByTagName('tr')[i].getElementsByTagName('td')[j].className = firstClassName;
          
				} else { // "even" rows, starting at row[startAt + 1] (so row[1] is considered even)
					document.getElementById(tableId).getElementsByTagName('tbody')[0].getElementsByTagName('tr')[i].getElementsByTagName('td')[j].className = secondClassName;
				}
			}
		}
	}
  
  // Highlights the column header by which the data is sorted
  function highlightColumnHeader(tableId, sortOn, colorOffset) {
  	if(colorOffset)sortOn=sortOn-colorOffset;
    var headerRow = document.getElementById(tableId).getElementsByTagName('thead')[0].getElementsByTagName('tr')[0];
    for (var i = 0; i < headerRow.getElementsByTagName('td').length; i++) {
      if (i == sortOn) {
        headerRow.getElementsByTagName('td')[i].style.backgroundColor = '#636563'; // Highlight sorted column header
      } else {
        headerRow.getElementsByTagName('td')[i].style.backgroundColor = '#9A9C9A'; // Unhighlight other column headers
      }
    }
  }

	function MM_findObj(n, d) { //v4.01
	  var p,i,x;  if(!d) d=document; if((p=n.indexOf("?"))>0&&parent.frames.length) {
		d=parent.frames[n.substring(p+1)].document; n=n.substring(0,p);}
	  if(!(x=d[n])&&d.all) x=d.all[n]; for (i=0;!x&&i<d.forms.length;i++) x=d.forms[i][n];
	  for(i=0;!x&&d.layers&&i<d.layers.length;i++) x=MM_findObj(n,d.layers[i].document);
	  if(!x && d.getElementById) x=d.getElementById(n); return x;
	}

