/**
* Fonction qui renvoie un objet XMLHttpRequest selon le browser
**/
function createXHR(){
    var request = false;
    try{
        request = new ActiveXObject('Msxml2.XMLHTTP');
    }catch(err2) {
        try{
            request = new ActiveXObject('Microsoft.XMLHTTP');
        }catch(err3){
			try {
				request = new XMLHttpRequest();
			}catch(err1){
				request = false;
			}
        }
    }
    return request;
}

/**
* Recupere le premier elt parent trouve parmi les ancetres, null sinon.
* elt : l'element dont on veut trouver le parent
* name : le tagName du parent qu'on veut trouver
**/
function getAncestor(elt, name){
	var parent = elt;
	while(parent.tagName.toLowerCase() != name){
		if(parent.parentNode){
			parent = parent.parentNode;
		}else{
			/*si on ne trouve pas de parent 'table', on retourne null*/
			parent = null;
			break;
		}
	}
	return parent;
}

/**
* Fonction utile pour calculer le nombre de colonnes d'un tableau
* afin par exemple de rajouter un TD avec le bon colSpan
* 
* table : element <TABLE>
**/
function getTableLength(table){
	var tr = table.getElementsByTagName("tr")[0];
	var tds = tr.getElementsByTagName("td");
	if(tds == null || tds.length <= 0){
		tds = tr.getElementsByTagName("th");//dans le cas d'un en-tete
	}
	var result = 0;
	for(var i=0 ; i<tds.length ; i++){
		result += tds[i].colSpan > 0 ? tds[i].colSpan : 1;
	}
	return result;
}

/**
* Fonctions pour rajouter/supprimer une ligne dans un tableau, avec une image et un message pour patienter
* 
* obj : element appartenent a la ligne en-dessous de laquelle on va ajouter une ligne avec l'image pour patienter
*       Typiquement, obj est le bouton sur lequel on a clique, et dans la ligne en-dessous on va mettre le message d'attente
* msg : message d'attente
* discr : discriminant a rajouter pour differencier plusieurs message si l'utilisateur clique a plusieurs endroits a la fois
**/
function showWaitInTable(table, rowIndex, cellIndex, msg, discr){
	var trWait = table.insertRow(rowIndex+1);
	majCellsWithRowspan(table, 1, rowIndex, cellIndex);
	trWait.setAttribute("name", "trWaitMsg" + discr);
	trWait.setAttribute("id", "trWaitMsg" + discr);//pour IE
	
	var td = getTDWithTableLength(table);
	td.innerHTML='<P class="text" style="font-weight:bold;vertical-align:middle;"><IMG align="middle" src="/images/share/loading.gif" /> &nbsp;' + msg + '</P>';
	
	trWait.appendChild(td);
}

function hideWaitInTable(table, discr, rowIndex, cellIndex){
	var trs = document.getElementsByName("trWaitMsg" + discr);
	if(trs != null){
		//Avec IE 6 et 7, les rowspan sont automatiquement decrementes si on supprime des lignes
		//pas avec Firefox. Pour contourner ce pb, on decremente a l'avance
		majCellsWithRowspan(table, -trs.length, rowIndex, cellIndex);
		while(trs.length > 0){
	  		table.deleteRow(trs[0].rowIndex);
	  	}
  	}
}

/**
* Fonction chargee d'inserer les lignes d'un tableau recupere en ajax.
* Hypothese de depart : on recupere au moins un ensemble de lignes <TR>
*                       et chaque ligne contient le meme nombre de colonnes que le tableau existant
* 
* discr : discriminant permettant de retrouver les lignes ajoutees au tableau pour pouvoir les supprimer
* a : element sur lequel on a clique
* message : message d'attente
* url : url a appeler pour recuperer le tableau a inserer
**/
function insertTableLines(a, url, message, discr, img){
	if(!img) {	
		img = a;
	}
	var aTR = getAncestor(a, "tr");
	var aTD = getAncestor(a, "td");
	var tableau = getAncestor(aTR, "table");
	if(img.src.indexOf('plus.gif') != -1){
		var req = null; 
		/*On desactive le clic le tps de l'appel et on le remet apres*/
		var onclick = a.getAttribute("onclick");
		a.setAttribute("onclick",'');
		img.src = img.src.replace(/plus/, "moins");
		
		/*Couleur de la ligne ou on a clique*/
		var color = aTR.getAttribute("bgColor");
		if(color == null || color == ""){//IE renvoie "" au lieu de null
			color = RGBToHex(aTR.style.backgroundColor);
		}
		
		showWaitInTable(tableau, aTR.rowIndex, aTD.cellIndex, message, discr);
		
		req = createXHR();
		req.onreadystatechange = function(){
			if(req.readyState == 4){
				if(req.status == 200){
					/*on enleve le message d'attente*/
					hideWaitInTable(tableau, discr, aTR.rowIndex, aTD.cellIndex);
					if(req.getResponseHeader("FlowERROR")!="true"){
					    var xmlDoc = getXmlDoc(req);
	 			 		var trs = xmlDoc.getElementsByTagName("tr");
	 			 		majCellsWithRowspan(tableau, trs != null ? trs.length : 0, aTR.rowIndex, aTD.cellIndex);
	 			 		var newLine = aTR;
	 			 		if(trs != null && trs.length > 0){
	 			 			while(trs.length > 0){
		 			 			newLine.parentNode.insertBefore(trs[0], newLine.nextSibling);
			 			 		newLine = newLine.nextSibling;
			 			 		newLine.setAttribute("name", discr);
				 				newLine.setAttribute("id", discr);//pour IE
				 				if(color != null) newLine.style.backgroundColor = color;
	 			 			}
			 			}else{
			 				/*on affiche juste la reponse, generalement un message indiquant qu'il n'y a rien a afficher*/
			 				newLine = tableau.insertRow(aTR.rowIndex+1);
			 				newLine.setAttribute("name", discr);
			 				newLine.setAttribute("id", discr);//pour IE
			 				if(color != null) newLine.style.backgroundColor = color;
			 				
			 				var td = getTDWithTableLength(tableau);
							td.innerHTML = req.responseText;
							newLine.appendChild(td);
			 			}
 				 		a.setAttribute("onclick", onclick);
					}else{
						//Affichage de l'erreur dans la page
						var root = document.getElementsByTagName("body")[0]; 
						root.innerHTML = req.responseText;
					}
 				}else{
 					//Affichage de l'erreur dans la page
 					var root = document.getElementsByTagName("body")[0]; 
					root.innerHTML = req.responseText;
 				}
			}
		};
		req.open("GET", url, true); 
		req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); 
		req.send(null); 
	}else{
		img.src = img.src.replace(/moins/, "plus");
		/*suppression des lignes directement liees au clic sur a*/
		var trs = document.getElementsByName(discr);
		majCellsWithRowspan(tableau, trs != null ? -trs.length : 0, aTR.rowIndex, aTD.cellIndex);
		while(trs.length > 0){
			tableau.deleteRow(trs[0].rowIndex);
		}
		
		/*suppression des lignes liees au clic sur une ligne creee en cliquant sur a
		ATTENTION !!! On suppose que le discriminant de a, a servi de prefixe pour les lignes ouvertes par le(s) second(s) clic(s)
		*/
		trs = tableau.getElementsByTagName("tr");
		var array = new Array();/*tableau des 'name' a supprimer*/
		for(var i=0 ; i<trs.length ; i++){
			var name = trs[i].getAttribute("name");
			if(name != null && name.indexOf(discr) == 0){
				array.push(name);
			}
		}
		for(var j=0 ; j<array.length ; j++){
			trs = document.getElementsByName(array[j]);
			while(trs.length > 0){
				tableau.deleteRow(trs[0].rowIndex);
			}
		}
	}
}

/**
* Fonction utilitaire pour recuperer un document XML a partir de la reponse ajax.
* Creee car req.responseXML.getElementsByTagName("tr") ne fonctionnait pas...
**/
function getXmlDoc(req){
	var div = document.createElement("div");
	div.innerHTML = req.responseText;
	return div;
}

/**
* Retourne un TD avec un colSpan du nbre de colonne du tableau
* Utile pour generer le TD contenant le message d'attente
**/
function getTDWithTableLength(table){
	var td = document.createElement("td");
	td.setAttribute("colSpan", getTableLength(table));
	td.setAttribute("align", "center");
	return td;
}

/**
* Fonction qui recupere tous les attributs desires parmi les elements en parametres et les met dans un tableau.
* Exemple : recuperer tous les attributs 'bgColor' des <TD> d'une ligne d'un tableau
*
* list : liste d'objet dont on veut recuperer un attribut
* attr : nom de l'ttribut qu'on veut recuperer
**/
function getAttributeFromNodeList(list, attr){
	var result = new Array();
	if(list != null){
		for(var i=0 ; i<list.length ; i++){
			result.push(list[i].getAttribute(attr));
		}
	}
	return result;
}

/**
* Fonction utile pour convertir les couleurs RGB (RVB) en Hexadecimal.
* Explication du pb : 
* Sous Mozilla/Firefox, .style.backgroundColor retourne qqchose du style rgb(255, 255, 255)
* donc si on veut reutiliser cette valeur autre part, il faut la convertir
*
* ColorString exemples : .getAttribute("bgColor") 
*                        .style.backgroundColor
**/
function RGBToHex(ColorString) {
	var HexDigits = "0123456789abcdef";
	if (ColorString.charAt(0) == '#') {
		return ColorString;
	} else {
		ColorString = ColorString.substr(4);
		pos = ColorString.indexOf(',');
		Result = '#' + HexDigits.substr(Math.floor(ColorString.substr(0, pos) / 16), 1) + HexDigits.substr(ColorString.substr(0, pos) % 16, 1);
		ColorString = ColorString.substr(pos + 1);
		pos = ColorString.indexOf(',');
		Result = Result + HexDigits.substr(Math.floor(ColorString.substr(0, pos) / 16), 1) + HexDigits.substr(ColorString.substr(0, pos) % 16, 1);
		ColorString = ColorString.substr(pos + 1);
		Result = Result + HexDigits.substr(Math.floor(ColorString.substr(0, pos) / 16), 1) + HexDigits.substr(ColorString.substr(0, pos) % 16, 1);
		return Result;
	}
}

/**
* Met a jour les rowspan des cellules a gauche de la cellule ou on clique. 
* Comme on rajoute des lignes, il faut augmenter les eventuels rowspan.
* 
* table : TABLE a laquelle on va ajouter/retirer des lignes
* nbLine : nombre lignes ajoutees (retirees si < 0)
* rowIndex : ligne en-dessous de laquelle on va rajouter/retirer des lignes
* cellIndex : indice de la cellule ou on a clique
**/
function majCellsWithRowspan(table, nbLine, rowIndex, cellIndex){
	if(nbLine == 0){
		return;
	}
	for(var i=rowIndex ; i>=0 ; i--){
		for(var j=cellIndex ; j>=0 ; j--){
			if(cellIndex == j && rowIndex == i){
				continue;//un rowspan sur la case ou on a clique ne doit pas etre modifie
			}
			//s'il y a des cases au-dessus avec des colspan il faut decrementer j pour trouver le premier index de cellule
			while(j>=table.rows[i].cells.length){
				j--;
			}
			var previousCell = table.rows[i].cells[j];
			//Number() utilise sinon Firefox concatene rowspan et nbLine : 192 + 1 = 1921 !
			var rowspan = Number(previousCell.getAttribute("rowSpan"));
			if(rowspan == 1) rowspan = 0;//pour ie7, on force rowspan a 0 comme dans firefox pour que l'algo fonctionne
			if(rowspan != null && rowspan-1+i >= rowIndex){//si le rowspan atteint bien la ligne rowIndex
				previousCell.setAttribute("rowSpan", rowspan + nbLine);
			}
		}
	}
}

function insertFPPAnnexe(divName, url){
	div = document.getElementById(divName);
	div.style.display='none';
	if(document.getElementById('patienter')) {
		document.getElementById('patienter').style.display='block';
	}	
	req = createXHR();
	req.onreadystatechange = function(){
		if(req.readyState == 4){
			if(req.status == 200){
				if(req.getResponseHeader("FlowERROR")!="true"){
		  	 		 var xmlDoc = req.responseText;
		  	 		 if(document.getElementById('patienter')) {
		  	 		 	document.getElementById('patienter').style.display='none';
		  	 		 }
		  	 		 div.style.display='block';
		  	 		 div.innerHTML =xmlDoc;
 			 	}else{
		  	 		//Affichage de l'erreur dans la page
					var root = document.getElementsByTagName("body")[0]; 
					root.innerHTML = req.responseText;
		  	 	}	 
			}else{
				//Affichage de l'erreur dans la page
				var root = document.getElementsByTagName("body")[0]; 
				root.innerHTML = req.responseText;
			}
 		}
 	};
	req.open("GET", url, true); 
	req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); 
	req.send(null); 		
}