/**
 * sortHTMLTable - POO
 * adaptation: lx barjon (12/10/2005)
 * version: 1.0
 *
 * adaptation d'un code libre de droit :
 *		auteur: LARION
 *		URL : http://www.javascriptfr.com/code.aspx?id=29926
 *
 * utilise la très bonne librairie protoype.js (http://prototype.conio.net/)
 *
 * utilisation : apres vos tableau ajouter :
	<script type="text/javascript">
		// Mettre le chemin vers les images qui seront ajoutees dans les entetes pour permettre le tri
		var options = {
			pathToImgUp: chemin_vers_votre_image,
			pathToImgDown: chemin_vers_votre_image
		}
		new sortHTMLTable( tableId, options );
	</script>
	*
	* tableId = id du tableau à gérer
	*
	* Pour gerer plusieurs tableaux sur la meme page, reiterer l'operation...
*/

// index de la cellule qui engendre le tri (variable globale)
var cellIndex;

// class sortHTMLTable
var sortHTMLTable = {};
sortHTMLTable = Class.create();
sortHTMLTable.prototype = {

	initialize: function( tableId, options ) {
		// image par defaut qui seront ajoutees dans les entetes pour permettre le tri
		this.options = {
			pathToImgUp: 'images/icones_liste/fleche_haut.gif',
			pathToImgDown: 'images/icones_liste/fleche_bas.gif'
		}.extend( options || {} );
		if ( !document.getElementById ) return;
		if ( typeof tableId == 'undefined' ) {
			alert("Veuillez fournir l'ID du tableau à trier.");
			return;
		}
		this.tableId = tableId;
		// recup l'objet tableau correspondant a l'id fourni
		this.tableToSort = $(tableId);

		if ( !this.tableToSort ) {
			alert("Le tableau ayant pour ID " + tableId + " est introuvable.");
			return;
		}

		// prepare le tableau javascript qui sera utilise pour le tri
		this.jsTable = new Array();
		for ( var rowCpt = 1; rowCpt < this.tableToSort.rows.length; rowCpt++ ) {
			this.jsTable[rowCpt-1] = new Array();
		}

		
		// initialisation des variables
		// ici on va stocker la fonction de tri correspondante au type de la cellule (sortNumber, sortString)
		this.sortFunction = new Array();
		// ici on stockera le type de donnee (date, number, string)
		var dataType = 'none';
		// contenu de la cellule
		var cellContent = '';
		// nombre total de colonne
		var totalCells = this.tableToSort.rows[0].cells.length;
		// on recup toutes les lignes dans jsTable sauf la ligne d'entete
		// Pour chaque cellule d'entete
		for ( var cellCpt = 0; cellCpt < this.tableToSort.rows[0].cells.length; cellCpt++ ) {
			// recup le contenu de la cellule (je sais pas trop ce que fait cette regexp... si qq sait merci de me communiquer l'info ! ;) )
			cellContent = this.tableToSort.rows[1].cells[cellCpt].innerHTML.replace( /<\/?[^>]+>/gi, "" );
			// chek le type de donnee
			// date (ajouter les date EN AAAA-MM-JJ)
			if ( cellContent.match(/^\d\d[\/-]\d\d[\/-]\d\d\d\d$/) ) {
				this.sortFunction[cellCpt] = this._sortString;
				dataType = 'date';
			// nombre ou monnaie
			} else if ( cellContent.match(/^[0-9$£fF\.\s-]+$/) ) {
				this.sortFunction[cellCpt] = this._sortNumber;
				dataType = 'number';
			// texte (string)
			} else {
				this.sortFunction[cellCpt] = this._sortString;
				dataType = 'string';
			}

			// pour chaque ligne
			for ( var rowCpt = 1; rowCpt < this.tableToSort.rows.length; rowCpt++ ) {
				// recup contenu cellule
				cellContent = this.tableToSort.rows[rowCpt].cells[cellCpt].innerHTML.replace( /<\/?[^>]+>/gi, "" );
				// en fonction du type de donnee on rempli le tableau javascript qui servira au tri avec les donnees adequates
				switch (dataType) {
					case 'date':
					{
						// date ? -> on cree un objet date
						this.jsTable[rowCpt-1][cellCpt] = new Date(cellContent.substring(6),cellContent.substring(3,5),cellContent.substring(0,2));
						break;
					}
					case 'number':
					{
						// nombre? -> on transfomre en nombre
						this.jsTable[rowCpt-1][cellCpt] = parseFloat(cellContent.replace(/[^0-9.-]/g,''));
						break;
					}
					case 'string':
					{
						// texte ? -> on met en minuscule car la methode sort et sensible a la casse (case sensitive)
						this.jsTable[rowCpt-1][cellCpt] = cellContent.toLowerCase();
						break;
					}
				}
				// on stocke la valeur d'origine de la cellule pour pouvoir la restituer au bon moment (this.sortTable)
				this.jsTable[rowCpt-1][cellCpt+totalCells] = this.tableToSort.rows[rowCpt].cells[cellCpt].innerHTML;
			}
		}

		// ajoute les 'images boutons' (img up et down) et y accroche des event onclick
		// on crée les objets images (up et down) et on les stocke dans un tableau pour pouvoir les cloner
		var imgUp = new Array();
		var imgDown = new Array();
		// creation img up
		imgUp[0] = document.createElement('img');
		imgUp[0].src = this.options.pathToImgUp;
		imgUp[0].style.cursor = 'pointer';
		imgUp[0].style.marginLeft = '5px';
		imgUp[0].id = this.tableId + 'up0';
		// creation img down
		imgDown[0] = document.createElement('img');
		imgDown[0].src = this.options.pathToImgDown;
		imgDown[0].style.cursor = 'pointer';
		imgDown[0].id = this.tableId + 'down0';
		// pour chaque cellule
		for ( var cellCpt = 0; cellCpt < this.tableToSort.rows[0].cells.length; cellCpt++ ) {
			// si les premieres images ont ete ajouter dans la page (DOM TREE), on clone pour l'ajout suivant (cellule suivante)
			// on modifie l'id pour avoir un code HTML valide et pour recup l'index de la cellule qui lance l'event
			if ( cellCpt > 0 ) {
				imgUp[cellCpt] = imgUp[0].cloneNode(true);
				imgUp[cellCpt].id = this.tableId + 'up' + cellCpt;
				imgDown[cellCpt] = imgDown[0].cloneNode(true);
				imgDown[cellCpt].id = this.tableId + 'down' + cellCpt;
			}
			// on ajoute les images dans les cellules d'entete
			if((this.tableToSort.rows[0].cells[cellCpt].innerHTML!='') && (this.tableToSort.rows[0].cells[cellCpt].innerHTML.lastIndexOf('<!--notri-->')<1)) {
				this.tableToSort.rows[0].cells[cellCpt].appendChild(imgUp[cellCpt]);
				this.tableToSort.rows[0].cells[cellCpt].appendChild(imgDown[cellCpt]);
				// on recup les objets pour y ajouter les event
				var elementUp = $(imgUp[cellCpt].id);
				var elementDown = $(imgDown[cellCpt].id);
				// ajout des event
				Event.observe( elementUp, 'click', this.sortTable.bindAsEventListener(this), false );
				Event.observe( elementDown, 'click', this.sortTable.bindAsEventListener(this), false );
			}
		}
	},

	sortTable: function(e) {
		// recup l'element qui a declanche l'evenement (imgUp ou imgDown)
		var element = window.event ? window.event.srcElement : e ? e.target : null;
		if ( !element ) return;

		// on verifie l'id de l'element pour etablir l'ordre de tri et on recup l'index correspondant
		if ( element.id.indexOf('up') != -1 ) {
			var sortOrder = 'ASC';
			cellIndex = parseInt( element.id.substr(this.tableId.length + 2) );
		} else {
			var sortOrder = 'DESC';
			cellIndex = parseInt( element.id.substr(this.tableId.length + 4) );
		}

		var totalCells = this.tableToSort.rows[0].cells.length;
		// on tri le tableau js
		this.jsTable.sort(this.sortFunction[cellIndex]);
		// on inverse l'ordre si necessaire (en fonction de l'element qui declenche le tri)
		if ( sortOrder == 'DESC' ) this.jsTable.reverse();
		// on remplace le tableau actuel
		for ( var cellCpt = 0; cellCpt < this.tableToSort.rows[0].cells.length; cellCpt++ ) {
			for ( var rowCpt = 1; rowCpt < this.tableToSort.rows.length; rowCpt++ ) {
				this.tableToSort.rows[rowCpt].cells[cellCpt].innerHTML = this.jsTable[rowCpt-1][cellCpt+totalCells];
			}
		}
	},

	_sortNumber: function( a, b ) {
		return ( a[cellIndex] - b[cellIndex] );
	},

	_sortString: function( a, b ) {
		if ( a[cellIndex] < b[cellIndex] ) return -1;
		else if ( a[cellIndex] > b[cellIndex] ) return 1;
		else return 0;
	}
	
}