//-----------------------------------------------------------------------------
// $Id: Zsorttable.js,v 1.1 2005/11/11 19:30:00
// $Author: Yohann Nauleau
// Description: JavaScript to sort HTML tables, includes secondary, tertiary... Sorting if necessary
//-----------------------------------------------------------------------------
var sortReverse = new Array();

// 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;
	}

//-----------------------------------------------------------------------------
// sortTable(id, col, type) is the main function to sort columns of data.
// id = document object id for the rows (can include several tbodies in a comma separated list)
// col = the column number to be sorted (can include several columns for secondary, tertiary... sorting in a comma searated list)
// type = is the data type (AlphaChars-0), (Numeric-1) (can include several types for secondary, tertiary... sorting in a comma searated list) 
// defaultsort = is the default sorting order (desc or asc) (can include several default sortings for secondary, tertiary... sorting in a comma searated list) 
//-----------------------------------------------------------------------------
function sortTable(id, col, type, defaultsort, notgone)
{
	var reverse;
	var isGone = ((notgone != "undefined")?notgone:false) 
	//get the function paramaters and put the different values in Arrays (comma separeted list)
	//Excludes id
	var tabCol = new Array();
	var tabType = new Array();
	var tabSort = new Array();
	if (col.indexOf(",") != -1)
	{
		tabCol = makeArray(col,1);
		tabType = makeArray(type,1);
		tabSort = makeArray(defaultsort,0);
		if (tabType.length != tabCol.length)
		{
			for (var i=tabType.length;i<tabCol.length;i++)
				tabType[i] = 0;
		}
		if (tabSort.length != tabCol.length)
		{
			for (var i=tabSort.length;i<tabCol.length;i++)
				tabSort[i] = "asc";
		}
	}
	else
	{
		tabCol[0] = parseInt(col,10);
		tabType[0] = parseInt(type,10);
		tabSort[0] = defaultsort;
	}
	//check for sort order. if this one was the last clicked,
	//then reverse the sort order
	if (tabCol[0] == lastsorted)
	{
		if (typeof(sortReverse[tabCol[0]]) == "undefined")
			sortReverse[tabCol[0]] = ((tabSort[0] == "desc")?false:true);
		else
			sortReverse[tabCol[0]] = !sortReverse[tabCol[0]];
		reverse = sortReverse[tabCol[0]];
	}
	else
	{	
		reverse = ((tabSort[0] == "desc")?true:false);
		sortReverse[tabCol[0]] = ((tabSort[0] == "desc")?true:false);
	}
	//get the 'id' paramaters and put the different values in Arrays (comma separeted list)
	var tabId = new Array();
	if (id.indexOf(",") != -1)
		tabId = makeArray(id,0)
	else
		tabId[0] = id;
	
	for(var j=0;j<tabId.length;j++)
	{
		// Get the table or table section to sort.
		var tableElmt = document.getElementById(tabId[j]);
		
		// Set the table display style to "none" - necessary for Netscape 6 
		// browsers.
		var oldDsply = tableElmt.style.display;
		tableElmt.style.display = "none";
		
		// Sort the rows based on the content of the specified column using a
		// selection sort.
		
		var i;
		var value, valuetmp;
		var tempVal;
		var linkName;
		var numRows = tableElmt.rows.length;
		var sortItems = new Array();
		if (tabType[0] == 1)
			var sortItemsTXT = new Array();
		
		var cpt = 0;
		var cpt2 = 0;
		
		for (i=0; i < numRows ; i++)
		{
			value = getTextValue(tableElmt.rows[i].cells[tabCol[0]]);
			if (tabType[0] == 1)
			{
				valuetmp = value;
				value = value.replace(reg2replace,""); //remove commas, spaces, % and ) before sort
				value = value.replace(/\(/g,"-"); //replace ( by - before sort
			}
			if (isNaN(value) && tabType[0] == 1)
			{
				sortItemsTXT[cpt2] = new Array();
				sortItemsTXT[cpt2][0] = tableElmt.rows[i]; 
				sortItemsTXT[cpt2][1] = valuetmp.toLowerCase();
				for(var k=1;k<tabCol.length;k++)
				{
					value2nd = getTextValue(tableElmt.rows[i].cells[tabCol[k]]);
					if (tabType[k] == 1)
					{
						valuetmp = value2nd;
						value2nd = value2nd.replace(reg2replace,""); //remove commas, spaces, % and ) before sort
						value2nd = value2nd.replace(/\(/g,"-"); //replace ( by - before sort
					}
					sortItemsTXT[cpt2][k+1] = value2nd;
				}
				cpt2 += 1;
			}
			else
			{
				sortItems[cpt] = new Array();
				sortItems[cpt][0] = tableElmt.rows[i];
				sortItems[cpt][1] = value.toLowerCase();
				for(var k=1;k<tabCol.length;k++)
				{
					value2nd = getTextValue(tableElmt.rows[i].cells[tabCol[k]]);
					if (tabType[k] == 1)
					{
						valuetmp = value2nd;
						value2nd = value2nd.replace(reg2replace,""); //remove commas, spaces, % and ) before sort
						value2nd = value2nd.replace(/\(/g,"-"); //replace ( by - before sort
					}
					sortItems[cpt][k+1] = value2nd;
				}
				cpt += 1;
			}
		}
		//sort the values in the selected column
		//need to check for numeric values and sort numerically
		if (tabType[0] == 1)//sort numbers
		{ 
			if (reverse)
			{
				sortItems.sort(sortNumbersRev);
				if (sortItemsTXT.length != 0)
				{
					sortItemsTXT.sort(mysortfn);
					sortItemsTXT.reverse();
				}
			}
			else
			{
				sortItems.sort(sortNumbers);
				if (sortItemsTXT.length != 0)
					sortItemsTXT.sort(mysortfn);
			}
		}
		else if ((tabType[0] == 0) && (reverse))
		{
			sortItems.sort(mysortfn);
			sortItems.reverse();
		}
		else
		{
			sortItems.sort(mysortfn);
		}
		
		if (tabType[0] == 1 && sortItemsTXT.length > 0)
			sortItems = sortItems.concat(sortItemsTXT);
		
		if (tabCol.length > 1)
		{
			var tabPref = makeprefix(sortItems.length);
			sortItems = replaceByPref(sortItems,tabPref);
										
			for (var m=1;m<tabCol.length;m++)
			{
				var tabTemp = new Array();
				var tabTempTXT = new Array();
				var cpt = 0;
				var cpt2 = 0;
				for (i = 0; i < sortItems.length; i++)
				{
					if (isNaN(sortItems[i][m+1]) && tabType[m] == 1)
					{
						tabTempTXT[cpt2] = new Array();
						tabTempTXT[cpt2][0] = i;
						tabTempTXT[cpt2][1] = sortItems[i][m+1].toLowerCase();
						cpt2++;
					}
					else
					{
						tabTemp[cpt] = new Array();
						tabTemp[cpt][0] = i;
						tabTemp[cpt][1] = ((tabType[m] == 1)?sortItems[i][m+1]:sortItems[i][m+1].toLowerCase());
						cpt++;
					}
				}
				
				if (tabType[m]==0)
				{
					tabTemp.sort(mysortfn);
					if (tabSort[m] == "desc")
						tabTemp.reverse();
				}
				else
				{
					if (tabSort[m] == "desc")
					{
						tabTemp.sort(sortNumbersRev);
						if (tabTempTXT.length != 0)
						{
							tabTempTXT.sort(mysortfn);
							tabTempTXT.reverse();
						}
					}
					else
					{
						tabTemp.sort(sortNumbers);
						if (tabTempTXT.length != 0)
							tabTempTXT.sort(mysortfn);
					}
				}	
				
				if ((tabType[m]==1) && tabTempTXT.length > 0)
					tabTemp = tabTemp.concat(tabTempTXT);
				
				tabTemp = replaceByPref(tabTemp,tabPref);
				
				for (i = 0; i < tabTemp.length; i++)
				{
					sortItems[tabTemp[i][0]][1] += "/"+tabTemp[i][1];
				}
			}
			sortItems.sort(mysortfn);
		}

		for (i = 0; i < sortItems.length; i++)
		{
			tableElmt.appendChild(sortItems[i][0]);
		}
		
		if (alternaterow)
			makePretty(tableElmt, tabCol[0], isGone);
		
		// Restore the table's display style.
		tableElmt.style.display = oldDsply;
	}
	
	// Change Header and Make table look pretty.
	if (chgelnk)
		swapLink(tabCol[0]);
	else
	{
		if (chgeimg)
		{
			imageName = imgname + tabCol[0];
			swapImage(reverse, imageName, tabCol[0]);
		}
	}
	
	lastsorted = tabCol[0];
	
	return false;
}

function makeArray(tmpStr,pInt)
{
	var cpt = 0;
	var tabtmp = new Array();
	while (tmpStr.indexOf(",") != -1)
	{
		if (pInt ==1)
			tabtmp[cpt] = parseInt(tmpStr.substr(0,tmpStr.indexOf(",")),10);
		else
			tabtmp[cpt] = tmpStr.substr(0,tmpStr.indexOf(","));
		tmpStr = tmpStr.substr(tmpStr.indexOf(",")+1,tmpStr.length);
		cpt += 1;
	}
	if (pInt ==1)
		tabtmp[cpt] = parseInt(tmpStr,10);
	else
		tabtmp[cpt] = tmpStr;
	return tabtmp;
}

function makeprefix(lgth)
{
	var loAZ = "abcdefghijklmnopqrstuvwxyz";
	var mod = 26;
	var tabPrefix = new Array(1)
	var tmp = "";
	var tmp2 = "";
	var cpt = -1;
	var cpt2 = -1;
	for (var i=0;i<lgth;i++)
	{
		if (i%mod == 0 && i!=0)
		{
			cpt++;
			cpt2 = 0;
			tmp = tabPrefix[cpt];
		}
		else
			cpt2 ++;
		tabPrefix[i] = tmp + loAZ.substr(cpt2, 1);
	}
	tabPrefix.sort();
	return tabPrefix;
}

function replaceByPref(tab2Process,tab2Use)
{
	var tmp = "";
	for (i = 0; i < tab2Process.length; i++)
	{
		if ((tmp != tab2Process[i][1])||(i==0))
			var lastPref = tab2Use[i];
		tmp = tab2Process[i][1];
		tab2Process[i][1] = lastPref;
	}
	return tab2Process;
}

function sortNumbersPrefix(a, b)
{
	//get values from the 2-dimensional array
	return a[0]-b[0];
}

function mysortfn(a,b) {
  if (a[1]<b[1]) return -1;
  if (a[1]>b[1]) return 1;
  return 0;
}


function sortNumbers(a, b)
{
	//get values from the 2-dimensional array
	return a[1]-b[1];
}

function sortNumbersRev(a, b)
{
	//get values from the 2-dimensional array
	return b[1]-a[1];
}

//-----------------------------------------------------------------------------
// 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 == "BR")
			s += " ";
		else
			// Use recursion to get text within sub-elements.
			s += getTextValue(el.childNodes[i]);
	return normalizeString(s);
}

// 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;
}

//-----------------------------------------------------------------------------
// Functions to update the table appearance after a sort.
//-----------------------------------------------------------------------------

function makePretty(tblEl,col,notgone)
{
	var i;
	var rowEl, cellEl;
	var isGone = ((notgone != "undefined")?notgone:false)
	// Set style classes on each row to alternate their appearance.
	ctr = 0;
	for (i = 0; i < tblEl.rows.length; i++)
	{
		rowEl = tblEl.rows[i];
		if (isGone && rowEl.className == "notgone") 
		{
			if (ctr % 2 != 0)
			{
				if (rowclass)
					rowEl.className = rowclsnmb;
				else
					rowEl.style.backgroundColor = emphbgcolor;
			}
			else
			{
				if (rowclass)
					rowEl.className = rowclsnm;
				else
					rowEl.style.backgroundColor = bgcolor;
			}
			ctr++;
		}
			
		if (!isGone) 
		{ 
			if (i % 2 != 0)
			{
				if (rowclass)
					rowEl.className = rowclsnmb;
				else
					rowEl.style.backgroundColor = emphbgcolor;
			}
			else
			{
				if (rowclass)
					rowEl.className = rowclsnm;
				else
					rowEl.style.backgroundColor = bgcolor;
			}
		}
	}
}

function swapLink(col)
{
	var temp, temp2;
	var name;

	//swap the lasted sorted column class according to column
	if (lastsorted != col)
	{
		if (lnkclass)
		{
			document.getElementById(lnkname+col).className= lnkclsnmsel;
			document.getElementById(lnkname+lastsorted).className= lnkclsnm;
		}
		else
		{
			var lookfont = "<font color="+lnkcolor.toLowerCase()+">";
			var lookfont2 = '<font color="'+lnkcolor.toLowerCase()+'">';
			var lookfontSel = "<font color="+lnkcolorsel.toLowerCase()+">";
			var lookfontSel2 = '<font color="'+lnkcolorsel.toLowerCase()+'">';
			if (document.getElementById(lnkname+col).innerHTML.toLowerCase().indexOf(lookfont) > -1 || document.getElementById(lnkname+col).innerHTML.toLowerCase().indexOf(lookfont2) > -1)
			{
				var temp = document.getElementById(lnkname+col).innerHTML;
				if (document.getElementById(lnkname+col).innerHTML.toLowerCase().indexOf(lookfont) > -1)
					var temp2 = temp.toLowerCase().indexOf(lookfont) + lookfont.length;
				else
					var temp2 = temp.toLowerCase().indexOf(lookfont2) + lookfont2.length;
				temp = temp.substr(0,temp.toLowerCase().indexOf(lookfont)) + lookfontSel + temp.substr(temp2,temp.length);
				document.getElementById(lnkname+col).innerHTML = temp;
			}
			else
				document.getElementById(lnkname+col).innerHTML = lookfontSel + document.getElementById(lnkname+col).innerHTML + '</font>';
			if (document.getElementById(lnkname+lastsorted).innerHTML.toLowerCase().indexOf(lookfontSel) > -1 || document.getElementById(lnkname+lastsorted).innerHTML.toLowerCase().indexOf(lookfontSel2) > -1)
			{
				var temp = document.getElementById(lnkname+lastsorted).innerHTML;
				if (document.getElementById(lnkname+lastsorted).innerHTML.toLowerCase().indexOf(lookfontSel) > -1)
					var temp2 = temp.toLowerCase().indexOf(lookfontSel) + lookfontSel.length;
				else
					var temp2 = temp.toLowerCase().indexOf(lookfontSel2) + lookfontSel2.length;
				temp = temp.substr(0,temp.toLowerCase().indexOf(lookfontSel)) + lookfont + temp.substr(temp2,temp.length);
				document.getElementById(lnkname+lastsorted).innerHTML = temp;
			}
			else
				document.getElementById(lnkname+lastsorted).innerHTML = lookfont + document.getElementById(lnkname+lastsorted).innerHTML + '</font>';
		}
	}
	return true;
}

function swapImage(imgReverse,imgNm, col)
{
	var temp, temp2;
	var name;

	//if image type is reverse(true or 1), then show down arrow image
	if (document.images)
	{
		//swap the current sort column to the appropriate image
		if (imgReverse)
		{
			temp = eval("image" + col + "down.src");
			document[imgNm].src = temp;
		}
		else
		{
			temp = eval("image" + col + "up.src");
			document[imgNm].src = temp;
		}
		//swap the lasted sorted column to its neutral state image
		if (lastsorted != col)
		{
			name = imgname + lastsorted;
			temp2 = eval("image" + lastsorted + ".src");
			document[name].src = temp2;
		}
	}
	return true;
}

// ---------------------------------------------------- 
// Some Code/Coding Concept were derived from:
// Copyright 2002 by Mike Hall                         
// Please see http://www.brainjar.com for terms of use. 
// http://www.brainjar.com/dhtml/tablesort/demo.html    
// ---------------------------------------------------- 