/********
FILENAME: autoSort.js
VERSION:  1.2
AUTHOR:   Kevin Hastie
CREATED:  2004-07-07
MODIFIED: 2004-08-11 by Tricia Woodruff
		  2004-12-10 by Rick Critchett -- alternateRowClasses() allows for sectionHead rows.
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   - added 'skipVal' to allow for colspans in header row
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

********/

var allowSorting = false;
var functionString;
var sortedOn; // Remembers column # you are currently sorted by.
var numColumns;
var sortDirection = 'inc';
var imgArrowInc = '/crp/buyingGuides/images/arrow_up.gif';
var imgArrowDec = '/crp/buyingGuides/images/arrow_down.gif';

// Sort the table with id=tableId by the values in column number sortOn
function SortTable(tableId, sortOn, sortType, numColumns, skipVal) {
   if (!is_mac_ie5x) {
      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;
         // 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() == "tagtext") {
		 	rowArray.sort(RowCompareTagText);
		}
         else if (sortType.toLowerCase() == "date") {
            rowArray.sort(RowCompareDate);
         }
         else if (sortType.toLowerCase() == "dollars") {
            rowArray.sort(RowCompareDollars);
         } 
         else { // default sort
            rowArray.sort(RowCompare);
         }

         toggleSortArrowsOff(numColumns);
         toggleSortArrowOn(sortOn);
         sortDirection = 'inc';
      
      }
   
      // 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, skipVal);

   // 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) {
	if (null==aCell || null==bCell)
		return 0;
    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;
    }
    
	 return (aVal > bVal ? 1 : -1);
	}

	// 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);
	}

	// 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 aNodeValue = aCell.firstChild.nodeValue;
    var bNodeValue = bCell.firstChild.nodeValue;

    	// Uses a regexp to strip commas and dollar signs, then parses out the (first) float
		var aVal = parseFloat(aNodeValue.replace(/,|\$/g,''));
		var bVal = parseFloat(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);
	}
  
  
  
  
  
  
  
  	// 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 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 RowCompareTagText(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('</')).toLowerCase();
	var btextStr = bInnerHTML.substring(bInnerHTML.indexOf('>'),bInnerHTML.indexOf('</')).toLowerCase(); 	 

    return (atextStr == btextStr ? 0 : (atextStr > btextStr ? 1 : -1));
    
  }

  function RowCompareIdText(a, b) {

    var aCell = a.getElementsByTagName('td')[sortedOn];
    var bCell = b.getElementsByTagName('td')[sortedOn];    

    var aID = aCell.id.toLowerCase();
    var bID= bCell.id.toLowerCase();
    
    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 = '0'; // 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));
        }
      }
    }
  }

  // You can create a comparison function based on your own sorting rules:
	// This one is the same as the default sort comparison
	//
	// function RowCompareExample(a, b) {
	// 	// determine your return value
	// 	// return a negative value if a < b, zero if a == b, or a positive value if a > b
	// }

	// Alternates the classes of the rows in the table identified by id=tableId
	// PARAMS:
	//	tableId - the id of the table to be sorted (NOTE: there should only be one table
	// 			 on the page with that id)
	// startAt - the row number to begin at (does NOT include header rows not found in <TBODY>
	// firstClassName  - the name of the class to be used for 'odd' rows
	// secondClassName - the name of the class to be used for 'even' rows
	//
	function alternateRowClasses (tableId, startAt, firstClassName, secondClassName) {
    var table = document.getElementById(tableId);
    var tbody = table.getElementsByTagName('tbody')[0];
    var tbodyRows = tbody.getElementsByTagName('tr'); //rwc: using prev. var.
	var sectionRow = startAt;
	for (var i = startAt; i < tbodyRows.length; i++)
	{
		// Exclude section heading rows
   		if (tbodyRows[i].className != 'sectionHead' && tbodyRows[i].className != 'colLabels')
		{
			for (var j = 0; j < tbodyRows[i].getElementsByTagName('td').length; j++) 
			{
				if (sectionRow%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;
				}
			}
			sectionRow++;
		}
		else // Reset the section rows counter
			sectionRow = 0;
	}
	}
  
  // Highlights the column header by which the data is sorted
  function highlightColumnHeader(tableId, sortOn,skipVal) {
    var headerRow = document.getElementById(tableId).getElementsByTagName('thead')[0].getElementsByTagName('tr')[0];
        if(skipVal){
            var headCount = headerRow.getElementsByTagName('td').length+1;
            sortOn=sortOn-1;
            for (var i = 0; i < headCount; i++){
                if (i == sortOn){
                    headerRow.getElementsByTagName('td')[i].style.backgroundColor = '#636563'; // Highlight sorted column header
                } else if(i < sortOn){
                    headerRow.getElementsByTagName('td')[i].style.backgroundColor = '#9A9C9A'; // Unhighlight other column headers
                }
            }
        
        } else {
        var headCount = headerRow.getElementsByTagName('td').length;
            for (var i = 0; i < headCount; 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;
	}

	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';
		}
	}

