/**************************************************************/
// This file contains javascript funtions for sorting tables. 
//
// Developed by Stevan Dunkin, 2007-2008
/**************************************************************/
var TableSorter = {

    me : false,
    
    currentCol : 0,
    previousCol : -1,
    
    
    init : function()
    {
        this.me = this;
        
    },

    CompareAlphaIgnore : function(a, b) 
    {
        var me = TableSorter.me;
        
	    var strA = a[me.currentCol].toLowerCase();
	    var strB = b[me.currentCol].toLowerCase();
	    if (strA < strB) { return -1; }
	    else 
	    {
		    if (strA > strB) { return 1; }
		    else { return 0; }
	    }
    },

    CompareAlphaIgnoreAsc : function(a, b) 
    {
         var me = TableSorter.me;
         
	    var strA = a[me.currentCol].replace(/<[^>]+>/g,"").toLowerCase();
	    var strB = b[me.currentCol].replace(/<[^>]+>/g,"").toLowerCase();
	    if (strA < strB) { return -1; }
	    else 
	    {
		    if (strA > strB) { return 1; }
		    else { return 0; }
	    }
    },

    CompareAlphaIgnoreDesc : function(a, b) 
    {
         var me = TableSorter.me;
         
	    var strA = a[me.currentCol].replace(/<[^>]+>/g,"").toLowerCase();
	    var strB = b[me.currentCol].replace(/<[^>]+>/g,"").toLowerCase();
	    if (strA < strB) { return 1; }
	    else 
	    {
		    if (strA > strB) { return -1; }
		    else { return 0; }
	    }
    },


    CompareNumeric : function(a, b) 
    {
      var me = TableSorter.me;
       
      var aa = me.getInnerText(a[me.currentCol]);
      var bb = me.getInnerText(b[me.currentCol]);
	    var numA = aa.replace(/[^0-9.]/g,'');
	    var numB = bb.replace(/[^0-9.]/g,'');
	    if (isNaN(numA)) { return 0;}
	    else 
	    {
		    if (isNaN(numB)) { return 0; }
		    else { return numA - numB; }
	    }
    },

    CompareCurrency : function(a, b)
    {
      var me = TableSorter.me;
       
      var aa = me.getInnerText(a[me.currentCol]);
      var bb = me.getInnerText(b[me.currentCol]);
      var curA = aa.replace(/[^0-9.]/g,'');
      var curB = bb.replace(/[^0-9.]/g,'');
      return parseFloat(curA) - parseFloat(curB);
    },
    
    CompareDateObjAsc : function(a, b)
    {
      var me = TableSorter.me;
      
      var aa = new Date(me.getInnerText(a[me.currentCol]));
      var bb = new Date(me.getInnerText(b[me.currentCol]));
      
      if (aa < bb) { return -1; }
	    else 
	    {
		    if (aa > bb) { return 1; }
		    else { return 0; }
	    }
    },
	
    //Following function written by Neil Crosby from http://www.workingwith.me.uk/articles/scripting/standardista_table_sorting 
    CompareDate : function(a, b) 
    {
        var me = TableSorter.me;
        
		  // y2k notes: two digit years less than 50 are treated as 20XX, greater than 50 are treated as 19XX
		  var aa = a[me.currentCol];
		  var bb = b[me.currentCol];
  		
		  var dt1, dt2, yr = -1;
  		
		  if (aa.length == 10) {
			  //dt1 = aa.substr(6,4)+aa.substr(3,2)+aa.substr(0,2);
			  dt1 = aa.substr(6,4)+aa.substr(0,2)+aa.substr(3,2);
		  } else {
			  yr = aa.substr(6,2);
			  if (parseInt(yr) < 50) { 
				  yr = '20'+yr; 
			  } else { 
				  yr = '19'+yr; 
			  }
			  dt1 = yr+aa.substr(0,2)+aa.substr(3,2);
		  }
  		
		  if (bb.length == 10) {
			  dt2 = bb.substr(6,4)+bb.substr(0,2)+bb.substr(3,2);
		  } else {
			  yr = bb.substr(6,2);
			  if (parseInt(yr) < 50) { 
				  yr = '20'+yr; 
			  } else { 
				  yr = '19'+yr; 
			  }
			  dt2 = yr+bb.substr(0,2)+bb.substr(3,2);
		  }
  		
		  if (dt1==dt2) {
			  return 0;
		  } else if (dt1<dt2) {
			  return -1;
		  }
		  return 1;
	  },

    //Create sort indicator HTML
    CreateArrowUpDownTag : function(fontAscending)
    {
        var font = '<span style="font-size:Small;font-weight:bold;" ';
        
        if(fontAscending)
        {
          font += 'id="Asc">';
          font += '&nbsp;&#8593;';
        }
        else
        {
          font += 'id="Dec">';
          font += '&nbsp;&#8595;';
        }
        
        font += '</span>';
        
        return font;
    },

    //Checks for, sets, and removes sort indicators
    GetSortOrder : function(myTable, myCol)
    { 
        var me = TableSorter.me;
        var retVal = 5;
        
        var myStartRow = myTable.tHead.rows.length - 1;
        var rowLength = myTable.rows[myStartRow].cells.length;
        var cellArray = new Array(rowLength);
        
        for(var i=0; i<myTable.rows[myStartRow].cells.length; i++)
        {
            var cellObj = myTable.rows[myStartRow].cells[i];
            var sortDir = cellObj.childNodes[1];
            //alert(sortDir);
            
            if(i==myCol) //Column to sort
            {
                if(sortDir != null)
                {
                    if(sortDir.id == 'Asc')
                    {
                        retVal = 6;
                        sortDir.innerHTML = '&nbsp;&#8595;';
                        sortDir.id = 'Dec';
                    }
                    else
                    {
                        retVal = 5;
                        sortDir.innerHTML = '&nbsp;&#8593;';
                        sortDir.id = 'Asc';
                    }
                }
                else
                {
                    cellObj.innerHTML += me.CreateArrowUpDownTag(true);
                    retVal = 5;
                }
            }
            else // Remove sort indicator from other columns
            {
                if(sortDir != null)
                {
                    //Remove the sort indicator.
                    cellObj.removeChild(cellObj.childNodes[1]);
                }
            }
        }
     
        return retVal;
    },

    GetSortFunction : function(myTable, myCol)
    {
        var me = TableSorter.me;
        var myStartRow = myTable.tHead.rows.length;
        var cellObj = '';
        var firstDataOfSortColumn = '';
        
        //Get first row in the column that has data.
        do{
            cellObj = myTable.rows[myStartRow].cells[myCol];
            firstDataOfSortColumn = (me.getInnerText(cellObj)).replace(/,|^\s*|\s*$/g,'');
            myStartRow++;
        }while((firstDataOfSortColumn == null || firstDataOfSortColumn == '') && myStartRow < myTable.rows.length);
        
        var sortType = me.CompareAlphaIgnoreAsc;
        
        if (firstDataOfSortColumn.match(/^\d\d[\/-]\d\d[\/-]\d\d\d\d$/)) {
			    sortType = me.CompareDate;
		    }
		    if (firstDataOfSortColumn.match(/^\d\d[\/-]\d\d[\/-]\d\d$/)) {
			    sortType = me.CompareDate;
		    }
		    if (firstDataOfSortColumn.match(/^[£$]/)) {
			    sortType = me.CompareCurrency;;
		    }
		    if (firstDataOfSortColumn.match(/^\d?\.?\d+$/)) {
			    sortType = me.CompareNumeric;
		    }
		    if (firstDataOfSortColumn.match(/^[+-]?\d*\.?\d+([eE]-?\d+)?$/)) {
			    sortType = me.CompareNumeric;
		    }
        if(me.isDate(firstDataOfSortColumn))
        {
          sortType = me.CompareDateObjAsc;
        }    
        return sortType;    
    },

    TableSort : function(myTable, myCol, clientFuctionToCall) 
    {        
         var me = TableSorter.me;
        var sortAscending = true;
        
        //Checks if column is sorted and removes sort indicator from last column.
        var sort = this.GetSortOrder(myTable, myCol); 
        
        //Set Sort Direction.
        if(sort == 5)
            {sortAscending = true;}
        else
            {sortAscending = false;}
    
//        if(me.previousCol == myCol)
//        {
//            sortAscending = false;
//        }
    	
      var mySource = myTable;
	    var myStartRow = mySource.tHead.rows.length;
	    var myRows = mySource.rows.length-myStartRow;
	    var myCols = mySource.rows[myStartRow].cells.length;
	    me.currentCol = myCol;
    	
	    // Create a two-dimensional array and fill it with the table's content
	    var myArray = new Array(myRows);
    	
	    for (var i=0, r=myStartRow; i < myRows; i++, r++) 
	    {
		    myArray[i] = new Array(myCols);
		    for (j=0; j < myCols; j++) 
		    {
			    myArray[i][j] = myTable.rows[r].cells[j].innerHTML;
		    }
	    }
    	
	    //Sort rows
	    if(sortAscending) 
	    { 
	        myType = me.GetSortFunction(myTable, myCol);
	        //alert(myType);
	        myArray.sort(myType); 
	    }
	    else { myArray.reverse(); }

	    // Re-write the table contents
	    for (var i=0, r=myStartRow; i < myRows; i++, r++) 
	    {
		    for (var j=0; j < myCols; j++) 
		    {   
			    mySource.rows[r].cells[j].innerHTML = myArray[i][j];
		    }
	    }
    	
    	me.previousCol = myCol;
    	
    	if(clientFuctionToCall)
    	{
    	    clientFuctionToCall.call(me);
    	}
    	
    	
	    return false;
    },
    
    isDate : function(el)
    {
      var date = new Date(el);
      if(date.toString() == 'NaN' || date.toString() == 'Invalid Date')
      {
        return false;
      }
      else
      {
        return true;
      }
    },
    
    //Following function written by Neil Crosby from http://www.workingwith.me.uk/articles/scripting/standardista_table_sorting 
    getInnerText : function(el) {
				 
		if ('string' == typeof el || 'undefined' == typeof el) {
		    //Modified by Stevan Dunkin
		    var index = el.toLowerCase().indexOf('<a');
		    if(index != -1)
		    {
		        var startIndex = el.toLowerCase().indexOf('>', index) + 1;
		        var stopIndex = el.toLowerCase().indexOf('</a>', index);
		        
		        return el.substring(startIndex, stopIndex);
		    }
		    
		    index = el.toLowerCase().indexOf('<span');
		    if(index != -1)
		    {
		        var startIndex = el.toLowerCase().indexOf('>', index) + 1;
		        var stopIndex = el.toLowerCase().indexOf('</span>', index);
		        
		        return el.substring(startIndex, stopIndex);
		    }
		    //end Modified
			return el;
		}
		
		//Modified by Stevan Dunkin
	  //Added to support FireFox and Safari
	  if(typeof(el.textContent) != "undefined")
    {
      return el.textContent;
    }
	  //end Modified
  	
	  if (el.innerText) {
		  return el.innerText;  // Not needed but it is faster
	  }
	  
	  //Modified by Stevan Dunkin
	  if(el.nodeValue)
    {
      return el.nodeValue;
    }
    //end Modified

		var str = el.getAttribute('standardistaTableSortingInnerText');
		if (null != str && '' != str) {
			return str;
		}
		str = '';

		var cs = el.childNodes;
		var l = cs.length;
		for (var i = 0; i < l; i++) {
			// 'if' is considerably quicker than a 'switch' statement, 
			// in Internet Explorer which translates up to a good time 
			// reduction since this is a very often called recursive function
			if (1 == cs[i].nodeType) { // ELEMENT NODE
				str += this.getInnerText(cs[i]);
				break;
			} else if (3 == cs[i].nodeType) { //TEXT_NODE
				str += cs[i].nodeValue;
				break;
			}
		}
		
		// set the innertext for this element directly on the element
		// so that it can be retrieved early next time the innertext
		// is requested
		el.setAttribute('standardistaTableSortingInnerText', str);
		
		return str;
	}
}


function TableSorterInit() {
	TableSorter.init();
}

addEvent(window, 'load', TableSorterInit)