addEvent(window, "load", sortables_init);
addEvent(document, "keydown", ts_keydown);
addEvent(document, "keyup", ts_keyup);

var SORT_COLUMN_INDEX;
var bShift;
var sens=new Array();
var iCol=new Array();
var fcts=new Array();

function sortables_init() {
    // Find all tables with class sortable and make them sortable

    var idTable=lireTri();        

	bShift=false;
    if (!document.getElementsByTagName) return;
    tbls = document.getElementsByTagName("table");
    for (ti=0;ti<tbls.length;ti++) {
        thisTbl = tbls[ti];
        if (((' '+thisTbl.className+' ').indexOf("sortable") != -1) && (thisTbl.id)) {
            ts_makeSortable(thisTbl);            
			ts_resortTable_(thisTbl);
        }
    }
}

function lireTri()
{

	var s=document.cookie;
	var i,j,k, ret="";

	liretri="";
	i=s.indexOf("MEMOTRI_"+document.title+"/");
	if (i>=0)
	{
		j=s.indexOf("/",i);
		i=s.indexOf("@(",i);
		ret=s.substring(j+1,i);
		j=s.indexOf(")@",i);
		s=(j>0 ? s=s.substring(i+2,j) : "");
	}
	else 
		s="";
		
	iCol=new Array();
	sens=new Array();
	fcts=new Array();
	if (s!="")
	{
		i=s.indexOf("$")
		j=s.indexOf("$",i+1)
		var a=s.substring(0,i);
		var b=s.substring(i+1,j);
		var c=s.substring(j+1);

		i=a.indexOf("@"); k=0; while(i>0){iCol[k++]=a.substring(0,i); a=a.substring(i+1); i=a.indexOf("@");}
		i=b.indexOf("@"); k=0; while(i>0){sens[k++]=(b.substring(0,i)=="true"); b=b.substring(i+1); i=b.indexOf("@");}
		i=c.indexOf("@"); k=0; while(i>0){fcts[k++]=ajouterFonction(c.substring(0,i)); c=c.substring(i+1); i=c.indexOf("@");}
	}
	
	return ret;
}

function ajouterFonction(f)
{

    if (f == "ts_sort_caseinsensitive") return ts_sort_caseinsensitive;
	else if (f == "ts_sort_date") return ts_sort_date;
	else if (f == "ts_sort_currency") return ts_sort_currency;
	else if (f == "ts_sort_numeric") return ts_sort_numeric;
}


function extraireFonction(f)
{
	var i,j,s=f.toString();

	i = s.indexOf("ts");
	j = s.indexOf("(");

	return s.substring(i,j);
}

function ecrireTri(idTable)
{

	var a="",b="";
	var s=document.cookie;
	var i,j;
	var tri=""
	
	for (i=0 ; i<iCol.length; i++) tri+=iCol[i]+"@"; tri+="$";
	for (i=0 ; i<iCol.length; i++) tri+=sens[i]+"@"; tri+="$";
	for (i=0 ; i<iCol.length; i++) tri+=extraireFonction(fcts[i])+"@";


	i=s.indexOf("MEMOTRI_"+document.title+"/"+idTable+"@(");
	if (i>=0)
	{
		if (i>0) a=s.substr(0,i-1);
		j=s.indexOf(")@",i);
		if (j>0) b=s.substr(j+2);		
	}
	s=a+" MEMOTRI_"+document.title+"/"+idTable+"@("+tri+")@ "+b;
	document.cookie=s;
}


function ts_makeSortable(table) {
    if (table.rows && table.rows.length > 0) {
        var firstRow = table.rows[0];
    }
    if (!firstRow) return;
    
    // We have a first row: assume it's the header, and make its contents clickable links
    for (var i=0;i<firstRow.cells.length;i++) {
        var cell = firstRow.cells[i];
        var txt = ts_getInnerText(cell);
        cell.innerHTML = '<a href="#" class="triable" onclick="ts_resortTable(this);return false;">'+txt+'<span class="sortarrow"></span></a>';
        
    }
}

function ts_getInnerText(el) {
	if (typeof el == "string") return el;
	if (typeof el == "undefined") { return el };
	if (el.innerText) return el.innerText;	//Not needed but it is faster
	var str = "";
	
	var cs = el.childNodes;
	var l = cs.length;
	for (var i = 0; i < l; i++) {
		switch (cs[i].nodeType) {
			case 1: //ELEMENT_NODE
				str += ts_getInnerText(cs[i]);
				break;
			case 3:	//TEXT_NODE
				str += cs[i].nodeValue;
				break;
		}
	}
	return str;
}

function ts_keydown() {

	if (event.keyCode == 16) bShift=true;
}

function ts_keyup() {

	if (event.keyCode == 16) bShift=false;
}

function ts_resortTable(lnk) {

    var td = lnk.parentNode;
    var column = td.cellIndex;
    var table = getParent(td,'TABLE');
    // type de colonne rep?r? sur la premi?re ligne
    if (table.rows.length <= 2) return;
    var itm = ts_getInnerText(table.rows[2].cells[column]);
    sortfn = ts_sort_caseinsensitive;

	if (!isNaN(itm))  sortfn = ts_sort_numeric; //document.write("Num?rique"); else document.write("Non num?rique");

    if (itm.match("\\d\\d/\\d\\d/\\d\\d")!=null) sortfn = ts_sort_date;
    if (itm.match("\\d\\d/\\d\\d/\\d\\d\\d\\d")!=null) sortfn = ts_sort_date;
    if (itm.match("\\d\\d/\\d\\d/\\d\\d.\\d\\d:\\d\\d:\\d\\d")!=null) sortfn = ts_sort_date;
    if (itm.match("\\d\\d/\\d\\d/\\d\\d\\d\\d.\\d\\d:\\d\\d:\\d\\d")!=null) sortfn = ts_sort_date;


    SORT_COLUMN_INDEX = column;

	s="";
	bSens=true;
	if (!bShift)
	{
		if (iCol.length>0 && column==iCol[0]) bSens=!sens[0];
		sens=new Array();
		iCol=new Array();
		fcts=new Array();
		s+="Rev("+bSens+")";
	}
	
	b=true;
	for (i=0 ; i<iCol.length; i++) if (iCol[i]==column) {b=false; sens[i]=!sens[i];}
    if (b) {iCol[i]=column; fcts[i]=sortfn; sens[i]=bSens}
    bSens=false;
  
	ecrireTri(getParent(lnk,"table").id);
	ts_resortTable_(table);
}	
	  
	  
function ts_resortTable_(table) 
{
    // Mise en place des fl?ches
    
    var allspans = document.getElementsByTagName("span");
	var k=0;
	
    for (var ci=0;ci<allspans.length;ci++)
    {
    	if (allspans[ci].className == 'sortarrow') 
        {
        	if (getParent(allspans[ci],"table") == table) // in the same table as us?
            { 
	            var s="";
            	for (i=0; i<iCol.length ; i++)
	           		if (iCol[i]==k) s= '&nbsp;&nbsp;'+(sens[i] ? '&darr;':'&uarr;')+(i+1);
				k++;
                allspans[ci].innerHTML = s;              
            }
        }
    }
    
	//*********************

    var firstRow = new Array();
    var newRows = new Array();
    for (i=0;i<table.rows[0].length;i++) { firstRow[i] = table.rows[0][i]; }
    for (j=1;j<table.rows.length;j++) { newRows[j-1] = table.rows[j]; }

    newRows.sort(ts_sort_row);
    // We appendChild rows that already exist to the tbody, so it moves them rather than creating new ones
    // don't do sortbottom rows
    for (i=0;i<newRows.length;i++) { if (!newRows[i].className || (newRows[i].className && (newRows[i].className.indexOf('sortbottom') == -1))) table.tBodies[0].appendChild(newRows[i]);}
    // do sortbottom rows only
    for (i=0;i<newRows.length;i++) { if (newRows[i].className && (newRows[i].className.indexOf('sortbottom') != -1)) table.tBodies[0].appendChild(newRows[i]);}

    var classe="impair";
    for(i=2; i<table.rows.length ; i++)
    {
    	table.rows[i].className=classe;
    	classe = (classe=="pair" ? "impair" : "pair");
    }
    
}

function getParent(el, pTagName) {
	if (el == null) return null;
	else if (el.nodeType == 1 && el.tagName.toLowerCase() == pTagName.toLowerCase())	// Gecko bug, supposed to be uppercase
		return el;
	else
		return getParent(el.parentNode, pTagName);
}

function ts_sort_row(a,b){

var i;

	for (i=0 ; i<iCol.length ; i++)
	{
		SORT_COLUMN_INDEX = iCol[i];
		r = fcts[i](a,b);
		if (r != 0) return (sens[i] ? r : -r);
	}

	return 0;
}


function ts_sort_caseinsensitive(a,b) {
    aa = ts_getInnerText(a.cells[SORT_COLUMN_INDEX]).toLowerCase();
    bb = ts_getInnerText(b.cells[SORT_COLUMN_INDEX]).toLowerCase();
    if (aa==bb) return 0;
    if (aa<bb) return -1;
    return 1;
}


function ts_sort_date(a,b) {
    // y2k notes: two digit years less than 50 are treated as 20XX, greater than 50 are treated as 19XX
    aa = ts_getInnerText(a.cells[SORT_COLUMN_INDEX]);
    bb = ts_getInnerText(b.cells[SORT_COLUMN_INDEX]);
    
    if (aa.length > 10)
        dt1 = aa.substr(6,4)+aa.substr(3,2)+aa.substr(0,2)+aa.substr(11);
    else if (aa.length == 10)
        dt1 = aa.substr(6,4)+aa.substr(3,2)+aa.substr(0,2);
    else {
        yr = aa.substr(6,2);
        if (parseInt(yr) < 50) { yr = '20'+yr; } else { yr = '19'+yr; }
        dt1 = yr+aa.substr(3,2)+aa.substr(0,2);
    }
    
    if (bb.length > 10) 
        dt2 = bb.substr(6,4)+bb.substr(3,2)+bb.substr(0,2)+bb.substr(11);
    if (bb.length == 10) 
        dt2 = bb.substr(6,4)+bb.substr(3,2)+bb.substr(0,2);
    else {
        yr = bb.substr(6,2);
        if (parseInt(yr) < 50) { yr = '20'+yr; } else { yr = '19'+yr; }
        dt2 = yr+bb.substr(3,2)+bb.substr(0,2);
    }

	if (dt1==dt2) return 0;
    if (dt1>dt2) return -1;
    return 1;
}

function ts_sort_currency(a,b) { 
    aa = ts_getInnerText(a.cells[SORT_COLUMN_INDEX]).replace(/[^0-9.]/g,'');
    bb = ts_getInnerText(b.cells[SORT_COLUMN_INDEX]).replace(/[^0-9.]/g,'');

	return parseFloat(aa) - parseFloat(bb);
}

function ts_sort_numeric(a,b) { 
    aa = parseFloat(ts_getInnerText(a.cells[SORT_COLUMN_INDEX]));
    if (isNaN(aa)) aa = 0;
    bb = parseFloat(ts_getInnerText(b.cells[SORT_COLUMN_INDEX])); 
    if (isNaN(bb)) bb = 0;

    return aa-bb;
}

function ts_sort_default(a,b) {
    aa = ts_getInnerText(a.cells[SORT_COLUMN_INDEX]);
    bb = ts_getInnerText(b.cells[SORT_COLUMN_INDEX]);

    if (aa==bb) return 0;
    if (aa<bb) return -1;
    return 1;
}


function addEvent(elm, evType, fn, useCapture)
// addEvent and removeEvent
// cross-browser event handling for IE5+,  NS6 and Mozilla
// By Scott Andrew
{
  if (elm.addEventListener){
    elm.addEventListener(evType, fn, useCapture);
    return true;
  } else if (elm.attachEvent){
    var r = elm.attachEvent("on"+evType, fn);
    return r;
  } else {
    alert("Handler could not be removed");
  }
} 


function getCookieVal(offset) {
	var endstr=document.cookie.indexOf (";", offset);
	if (endstr==-1)
      		endstr=document.cookie.length;
	return unescape(document.cookie.substring(offset, endstr));
}

function getCookie (name) {
	var arg=name+"=";
	var alen=arg.length;
	var clen=document.cookie.length;
	var i=0;
	while (i<clen) {
		var j=i+alen;
		if (document.cookie.substring(i, j)==arg)
                        return getCookieVal (j);
                i=document.cookie.indexOf(" ",i)+1;
                        if (i==0) break;}
	return null;
}
function setCookie (name, value) {
// un cookie a besoin d'un nom, d'une valeur, d'un nom de domaine, d'une date d'expiration
// 
	var argv=SetCookie.arguments;
	var argc=SetCookie.arguments.length;
	var expires=(argc > 2) ? argv[2] : null;
	var path=(argc > 3) ? argv[3] : null;
	var domain=(argc > 4) ? argv[4] : null;
	var secure=(argc > 5) ? argv[5] : false;
	document.cookie=name+"="+escape(value)+
		((expires==null) ? "" : ("; expires="+expires.toGMTString()))+
		((path==null) ? "" : ("; path="+path))+
		((domain==null) ? "" : ("; domain="+domain))+
		((secure==true) ? "; secure" : "");
}

