/*
	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++) {
					//Si pas déjà dedans, je l'ajoute
					if (!return_nodes.find(lastElementsNodes[k])) return_nodes.push(lastElementsNodes[k]);
				}
			}
		}
	}
	return return_nodes;
}

/*
	Name : getElementsBySimpleSelector
	Param : selector, 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;
	//Que j'ai un selector de type #conteneur.fun ou a.showTooltip ou a#conteneur.focus.sectionHeader je dois pouvoir le cibler, pour ca il faut découper
	//On va le transformer en Array(a, #conteneur, .focus, .sectionHeader);
	var selectorArray = Array();
	
	splitDiese = selector.split("#");
	for (var i=0;i!=splitDiese.length;i++) {
		splitPoint = splitDiese[i].split(".");
		for (var j =0;j!=splitPoint.length;j++) {
			if (splitPoint[j]!="") {
				//Si je trouve #truc, ou .truc ou truc je l'ajoute avec le préfixe qui convient
				if (selector.find("#"+splitPoint[j])) selectorArray.push("#"+splitPoint[j]);
				else if (selector.find("."+splitPoint[j])) selectorArray.push("."+splitPoint[j]);
				else selectorArray.push(splitPoint[j]);
			}
		}
	}

	//vd(selectorArray);
	
	//Je prends un tableau qui contient tout les noeuds à tester (qui commence par l'objet à tester)
	var test_nodes = Array(obj);
	//A coté de ca j'ai un tableau qui contient tout les noeuds testés et vérifiés
	var return_nodes = Array();
	for (var i=0;i!=selectorArray.length;i++) {
		return_nodes = Array(); //On le re-remplit de facon épuré à chaque tour de boucle
		
		
		//Un id, je prend celui qui a cet id dans le document
		if (selectorArray[i].find("#")) {
			var id_split = selectorArray[i].split("#");
			//Si c'est le premier du selecteur, je vais chercher celui qui porte cette id
			if (i==0 && document.getElementById(id_split[1])) return_nodes[0] = document.getElementById(id_split[1]);
			//Si c'est pas le premier, je passe en revue ceux de ma liste pour ne garder que ceux qui ont cette id
			if (i>0) {
				for (var j=0;j!=test_nodes.length;j++) {
					//Si l'élément à l'id donnée c'est bon, on le garde et on continue la boucle (un seul élément par #id)
					if (test_nodes[j].id==id_split[1]) 	return_nodes[0] = document.getElementById(id_split[1]);
				}
			}
		}
		
		//Une sélection de classe, on prends les éléments de ce tag, avec cette classe
		else if (selectorArray[i].find(".")) {
			var class_split = selectorArray[i].split(".");
			//Si c'est le premier du selecteur, je passe en revue tout les nodes de la page pour trouver ceux qui ont la classe
			if (i==0) test_nodes = obj.getElementsByTagName("*");
			if (!test_nodes && document.all) test_nodes = document.all; //Pour IE5 qui ne connait pas * comme selecteur

			
			//Sinon je passe en revue que ceux de test_nodes que j'ai déjà
			for (var j=0;j!=test_nodes.length;j++) {
				if (isOfClass(test_nodes[j],class_split[1])) {
					//Si pas déjà dedans, je l'ajoute
					if (!return_nodes.find(test_nodes[j])) return_nodes.push(test_nodes[j]);
				}
			}
		}
		else {
			//De base, on prends tous les tags avec ce nom
			for (var j=0;j!=test_nodes.length;j++) {
				//Je fais la liste des éléments simples (a) dans chaque partie de test_nodes
				simpleElementsNode = test_nodes[j].getElementsByTagName(selectorArray[i]);
				for (var k=0;k!=simpleElementsNode.length;k++) 
					if (!return_nodes.find(simpleElementsNode[k])) return_nodes.push(simpleElementsNode[k]);
			}
		}
		
		//Pour le tour de boucle suivant, je vais tester dans la liste de nodes que je viens d'épurer
		test_nodes = return_nodes;
		//vd(test_nodes);
	}
	//vd("####################################");
	//vd(return_nodes);
	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;
	
	var split = obj_class.split(" ");
	for (var i=0;i!=split.length;i++) if (split[i]==className) return true;
	return false;
}



/* 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) {
	if (obj.x)	return obj.x;
	var ret = 0;
	while (obj.offsetParent) {
		ret += obj.offsetLeft;
		obj = obj.offsetParent;
	}
	return ret;
}

function getY(obj) {
	if (obj.y) return obj.y;
	var ret = 0;
	while (obj.offsetParent) {
		ret += obj.offsetTop;
		obj = obj.offsetParent;
	}
	return ret;
}

/*
	Name : removeEmptyTextNodesChild
	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 ]
*/
function getElementByTagName(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];
}


//Trouve la largeur de la page (Thanks Quirksmode)
function getPageWidth() {
	//Selon les méthodes connues :
	if (self.innerWidth) return self.innerWidth;
	else if (document.documentElement && document.documentElement.clientWidth) return document.documentElement.clientWidth;
	else if (document.body) return document.body.clientWidth;
}
function getPageHeight() {
	//Selon les méthodes connues :
	if (self.innerHeight) return self.innerHeight;
	else if (document.documentElement && document.documentElement.clientWidth) return document.documentElement.clientHeight;
	else if (document.body) return document.body.clientHeight;
}
