/*
	Name : getElementsBySelector
	Param : selectorList, obj, return_nodes
	Return: un tableau de tout les blocs correspondants à la selection
	On donne une selection comme en css :
		Exemple : .menu strong, ul.menu li a, #bottom, #bottom .copyright a, etc
	Et il nous retourne un tableau des éléments qui correspondent à la recherche
	On passe les paramètres obj et return_nodes pour la recursion
*/
function getElementsBySelector(selectorList, obj, return_nodes) {
	//On va retourner un tableau contenant tout les nodes qui correspondent aux criteres
	if (return_nodes==null) var return_nodes = Array();
	//On peut appliquer cette fonction à partir d'un certain niveau si précisé
	if (obj==null) obj = document;
	//On découpe pour chaque selector (ils sont séparés par une virgule)
	var selectorListArray = selectorList.split(",");
	for (var i=0;i!=selectorListArray.length;i++) {
		//On va maintenant découper la requete par niveau
		var selectorLevelArray = selectorListArray[i].split(" ");
		//On continue au niveau inférieur
		if (selectorLevelArray.length>1) {
			//On prends le premier des tags (ul li a => ul), On prends tout les ul de la page et on leur applique la selection sur "li a "
			var first_el = selectorLevelArray.unpop();
			var firstElementNodes = getElementsBySimpleSelector(first_el, obj);
			for (var j=0;j!=firstElementNodes.length;j++) return_nodes = getElementsBySelector(selectorLevelArray.join(" "), firstElementNodes[j], return_nodes);
		}
		//Arrivé ici je suis au plus bas de la recherche, je suis dans l'avant dernier niveau et je veux trouver le dernier (exemple je suis dans un li et je cherche un a)
		else {
			var lastElementsNodes = getElementsBySimpleSelector(selectorLevelArray[0],obj);
			if (lastElementsNodes.length>0) {
				//Je mets donc chaque truc que je trouve dans mon tableau à retourner
				for (var k=0;k!=lastElementsNodes.length;k++) return_nodes.push(lastElementsNodes[k]);
			}
		}
	}
	return return_nodes;
}

/*
	Name : getElementsBySimpleSelector
	Param : selectorList, obj
	Return: un tableau de tout les blocs correspondants à la selection
	On donne une selection comme en css mais à un seul niveau
		Exemple : a.class, #bottom, a, .item
	Il nous retourne les éléments qui correspondent à ce critere sans récursion. C'est la fin de la fonction getElementsBySelector
*/
function getElementsBySimpleSelector(selector, obj) {
	if (!obj) obj = document;
	var return_nodes = Array();
	switch (true) {
		//Un id, je prend celui qui a cet id dans le document
		case (selector.find("#")):
			var id_split = selector.split("#");
			if (document.getElementById(id_split[1])) return_nodes[0] = document.getElementById(id_split[1]);
		break;
		
		//Une sélection de classe, on prends les éléments de ce tag, avec cette classe
		//Il faut qu'ils aient exactement cette classe ou qu'elle soit dans sa liste d'attribut en entier (début, fin ou milieu)
		case (selector.find(".")):
			var class_split = selector.split(".");
			//Si selection de classe simplement, on prends toutes les classes, dans tout le document
			if (class_split[0]=="") class_split[0] = "*";
			var tmp_nodes = obj.getElementsByTagName(class_split[0]);
			//IE 5ne prends pas le selector *, on prends document.all pour lui
			if (!tmp_nodes && document.all) tmp_nodes = document.all;
			var node_class, class_search = class_split[1];
			
			for (var i=0;i!=tmp_nodes.length;i++) {
					if (isOfClass(tmp_nodes[i],class_search))  return_nodes.push(tmp_nodes[i]);
			}						
		break;
		
		//De base, on prends tous les tags avec ce nom
		default :
			return_nodes = obj.getElementsByTagName(selector);
		break;	
	}
		
	return return_nodes;
}

/*
	Name : isOfClass
	Param : obj, className
	Retourne si obj possede la classe className
*/
function isOfClass(obj, className) {
	if (!className) return false;
	var obj_class;
	//Ie va chercher le nom de la classe dans l'attribut "className" et Mozzy dans class
	if (obj.getAttribute("class")) obj_class = obj.getAttribute("class");
	if (obj.getAttribute("className")) obj_class = obj.getAttribute("className");
	if (!obj_class) return false;
	
	return (obj_class==className 
	 || (obj_class.find(" "+className+" ")) 
	 || (obj_class.indexOf(className+" ")==0)
	 || (obj_class.indexOf(" "+className)==((obj_class.length)-(className.length)-1) && (obj_class.indexOf(" "+className)!=-1))
	 );
}



/* Trouve la position d'un élément dans la page
Mozzila trouve la position exacte à partir des .x et .y mais IE ne connait pas
Il utilise .offsetLeft et .offsetTop (Mozzy aussi) mais ils les placent différemment, chacun en fonction du <div, <span conteneur
mais ils ne considérent pas tous les mêmes balises comme des conteneurs ou non... td, li, etc
Donc on fait une boucle à partir de l'élement parent .offsetParent jusqu'à ce qu'il n'y ai plus de parent, on additionne les positions à chaque fois et on aura la vraie position à la fin !
*/
function getX(obj)
{
	var ret = 0;
	if (obj.offsetParent) {
		while (obj.offsetParent) {
			ret += obj.offsetLeft;
			obj = obj.offsetParent;
		}
	}
	else if (obj.x)	ret += obj.x;
	return ret;
}

function getY(obj) {
	var ret = 0;
	if (obj.offsetParent) {
		while (obj.offsetParent) {
			ret += obj.offsetTop;
			obj = obj.offsetParent;
		}
	}
	else if (obj.y) ret += obj.y;
	return ret;
}

/*
	Name : removeEmptyTextNodes
	Param : obj
	Supprime tout les nodes de texte vides (Mozzy en ajoute lors des sauts de ligne)
*/
function removeEmptyTextNodesChild(obj) {
	for (var i=0;i!=obj.childNodes.length;i++) {	
		//Si c'est pas un texte c'est bon
		if (obj.childNodes[i].nodeType!=3) continue;
		//Je regarde chaque lettre, si c'est autre chose qu'un espace ou saut de ligne alors le noeud est bon, si à la fin j'ai que du vide, alors j'efface ce node
		for (var j=0; j!=obj.childNodes[i].nodeValue.length;j++) {
			if (obj.childNodes[i].nodeValue.charAt(j)!='\n' && obj.childNodes[i].nodeValue.charAt(j)!=' ' && obj.childNodes[i].nodeValue.charAt(j)!='\t') break;
		}
		//Si je suis allé au bout de la boucle c'est que c'est du vide, je supprime donc cette entrée du tableau
		if (j==obj.childNodes[i].nodeValue.length) {
			obj.removeChild(obj.childNodes[i]);
			i--;
		}
	}
}


/*
	Name : getElementByTagName
	Param : TagName, obj (facultatif)
	Return : Node
	On ajoute une methode pour choisir un élément à partir de son nom de tag.
	Utile pour les <head, <body, <html qui ne sont présents qu'une seule fois dans la page	
	[ J'aurais voulu l'ajouter dans le Node.prototype mais Ie ne permet pas d'ajout à ce prototype, donc ca reste une fonction simple ]
*/
getElementByTagName = function(TagName, obj) {
	//On peut spécifier un niveau ou commencer, ou sinon dans la page générale
	if (obj==null) obj = document; 
	return obj.getElementsByTagName(TagName)[0];
}



