var NRIS_SEPARATOR = ",";
var DESCS_SEPARATOR = "~*!*~";

//--------------------------------------------------------------------------------
//--- Remplace toutes les occurences d'une sous-string par une autre
//--------------------------------------------------------------------------------
function replaceInString(str, oldSubstr, newSubstr, bFirstOccurenceOnly)
{
	if (str==null || oldSubstr==null || newSubstr==null)
		return str;
	
	var result = "";
	//startIdx and idxOld delimit various chunks of aInput; these
	//chunks always end where aOldPattern begins
	var startIdx = 0;
	var idxOld = 0;
	var stopReplace = false;
	while (!stopReplace && (idxOld = str.indexOf(oldSubstr, startIdx))>=0)
	{
		//grab a part of aInput which does not include aOldPattern
		result += str.substring(startIdx, idxOld);
		//add aNewPattern to take place of aOldPattern
		result += newSubstr;

		//reset the startIdx to just after the current match, to see
		//if there are any further matches
		startIdx = idxOld + oldSubstr.length;
		
		if (bFirstOccurenceOnly)
			stopReplace = true;
	}
	// The final chunk will go to the end of aInput
	result += str.substring(startIdx);
	return result;
}

//----------------------------------------------------------------------
//-- Insert la string insertStr dans baseStr à la position insertPost
//----------------------------------------------------------------------
function insertStrAtPos(baseStr, insertStr, insertPos)
{
	return baseStr.substring(0,insertPos) +
	       insertStr +
	       baseStr.substring(insertPos);	        
}

			
//-------------------------------------------------------------------------------------
//-- Cette fonction permet de retirer tous les caractères spéciaux d'une chaîne     ---
//-- de caractères													                ---
//-------------------------------------------------------------------------------------
function removeSpecialCharacters(str)
{
	var allowedCharacters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
	var returnedString = "";
	
	for (var i=0; i<str.length; i++)
	{
		if (allowedCharacters.indexOf(str.charAt(i).toUpperCase()) != -1)
			returnedString += str.charAt(i);
	}	

	return returnedString;
}

//----------------------------------------------------------------------------
//-- Ouvre un popup centré, resizable et sans toolbars             -----------
//-- Retourne l'objet Window                                       -----------
//----------------------------------------------------------------------------
function openWindow(sUrl, sName, iWidth, iHeight, bScrollBars)
{
	return openWindowCustom(sUrl, sName, iWidth, iHeight, bScrollBars, false, "yes", false);
}

//----------------------------------------------------------------------------
//-- Ouvre un popup centré, resizable, sans toolbars avec barre de statut  ---
//-- Retourne l'objet Window                                               ---
//----------------------------------------------------------------------------
function openWindowStatus(sUrl, sName, iWidth, iHeight, bScrollBars)
{
	return openWindowCustom(sUrl, sName, iWidth, iHeight, bScrollBars, false, "yes", true);
}

//----------------------------------------------------------------------------
//-- Ouvre un popup centré, resizable AVEC toolbars et url        ------------
//-- Retourne l'objet Window                                      ------------
//----------------------------------------------------------------------------
function openWindowToolbar(sUrl, sName, iWidth, iHeight, bScrollBars)
{
	return openWindowCustom(sUrl, sName, iWidth, iHeight, bScrollBars, true, "yes", false);
}

//----------------------------------------------------------------------------
//-- Ouvre un popup centré, resizable AVEC toolbars et url  ------------------
//-- Retourne l'objet Window                                ------------------
//----------------------------------------------------------------------------
function openWindowCustom(sUrl, sName, iWidth, iHeight, bScrollBars, bToolBar, sResizable, bStatusBar, bMenuBar)
{	
	// Calculer les vrai hauteur/largeur	
	iWidth  = getRealPopupWidth(iWidth);
	iHeight = getRealPopupHeight(iHeight)

   // Centrer la fenêtre	
   var y = Math.round((screen.availHeight - iHeight)/2);
   if (y<1)
	   y=1;
   var x = Math.round((screen.availWidth - iWidth)/2);
      
   var sScrollBars="no";
   if (bScrollBars)
   		sScrollBars="yes";   

   var sStatusBar="0";
   if (bStatusBar)
   		sStatusBar="1";
   		
   var sMenuBar="0"
   if (bMenuBar)   		
   		sMenuBar="1"
		
   var sToolBar="";
   if (bToolBar)
	   sToolBar=",toolbar,location";
	   
   var params =   "width="+iWidth+
				  ",height="+iHeight+
				  ",left="+x+ 
				  ",top="+y+
				  ",menubar="+sMenuBar+
				  ",scrollbars="+sScrollBars+
				  ",resizable="+sResizable+
				  ",status="+sStatusBar+
				  sToolBar;	   

	try // Pour éviter erreur bizarre dans le browser
	{
   		var oWin = window.open(sUrl, sName, params, true);   		
		// Just in case width and height are ignored
		oWin.resizeTo(iWidth, iHeight);
  		// Just in case left and top are ignored
  		oWin.moveTo(x, y);	
		if (oWin && oWin!=null && oWin.focus)
			oWin.focus();
	}
	catch(e)
	{ 	}
	
	return oWin;
}

//------------------------------------------------------------------
//-- Resize une fenêtre déjà ouverte.                       --------
//------------------------------------------------------------------
function resizeWindow(oWin, iWidth, iHeight)
{	
	// Calculer les vrai hauteur/largeur	
	iWidth  = getRealPopupWidth(iWidth);
	iHeight = getRealPopupHeight(iHeight)
	
	// Centrer la fenêtre
	var y = Math.round((screen.availHeight - iHeight)/2);
	if (y<1)
		y=1;
	var x = Math.round((screen.availWidth - iWidth)/2);   

	oWin.resizeTo(iWidth, iHeight);
	// Just in case left and top are ignored
	oWin.moveTo(x, y);	
	if (oWin && oWin!=null && oWin.focus)
		oWin.focus();
	
	return oWin;
}

//-----------------------------------------------------------
//-- Calcule la LARGEUR réelle de la fenêtre à créer/resizer
//-----------------------------------------------------------
function getRealPopupWidth(iWidth)
{
	// Largeur des scroll bar
	var BROWSER_ADDITIONNAL_WIDTH = 32;
 	// Si largeur négative c'est que l'on veut prendre tout l'écran sauf cette largeur
    if (iWidth<1)
	   iWidth = screen.availWidth + iWidth;
	iWidth  += BROWSER_ADDITIONNAL_WIDTH;	
	return iWidth;	
}

//-----------------------------------------------------------
//-- Calcule la HAUTEUR réelle de la fenêtre à créer/resizer
//-----------------------------------------------------------
function getRealPopupHeight(iHeight)
{
	var BROWSER_ADDITIONNAL_HEIGHT = 96;	
   // Si hauteur négative c'est que l'on veut prendre tout l'écran sauf cette hauteur
   if (iHeight<1)
	   iHeight = screen.availHeight + iHeight;
	//ATTENTION: La hauteur contrôlée par window.open() est celle de l'intérieur,
	//           du document affichée. On ne peut par prédire la hauteur réelle
	//           de la fenêtre puisque ça dépend du nombre de toolbars.
	iHeight += BROWSER_ADDITIONNAL_HEIGHT;
	return iHeight;	
}


//-----------------------------------------------------------------
//--- Retourne en string le chemin du opener de la fenêtre   ------
//--- spécifiée (false si existe pas)                        ------
//-----------------------------------------------------------------
function getOpenerPath(sPointer)
{
	// Extraire le nom du serveur
	var sHostString = top.location.host;

	// Ajouter . manquant
	if (sPointer != "")
		sPointer += ".";
	
	try
	{
		if (eval(sPointer+"top.opener") && 
				(eval("typeof("+sPointer+"top.opener.location.host)")=='string') && 
				(eval(sPointer+"top.opener.location.host")==sHostString))
		{
			sPointer += "top.opener";
			return sPointer;
		}
		else
			return false;
	}
	catch (e)
	{
		return false;
	}
}

//-----------------------------------------------------------------
//--- Enlève les espaces de gauche d'une string  ------------------
//-----------------------------------------------------------------
function trimLeft(str)
{
	var trimmed = false;

	// Trim left        
	for (i = 0; i < str.length; i++)
	{
		if (str.charAt(i) != " ")
		{
			str = str.substring(i, str.length);
			trimmed = true;
			break;
		}
	}
	if (trimmed == false)
		str = "";
	return str;
}

//-----------------------------------------------------------------
//--- Enlève les espaces de droite d'une string  ------------------
//-----------------------------------------------------------------
function trimRight(str)
{
	for (i=str.length-1; i>=0; i--)
	{
		if (str.charAt(i) != " ")
		{
			str = str.substring(0, i+1);
			break;
		}
	}
	return str;
}

//-----------------------------------------------------------------
//--- Enlève les espaces de droite et de gauche d'une string  -----
//-----------------------------------------------------------------
function trim(str)
{
	return trimRight(trimLeft(str));
}

//-----------------------------------------------------------------
//--- Détermine si une string est nulle ou vide  ------------------
//-----------------------------------------------------------------
function isEmpty(str)
{	
	if (str==null || trim(str).length==0)
		return true;
	else
		return false;

}

//-----------------------------------------------------------------
//--- Détermine si une string se termine par un certain suffix ----
//-----------------------------------------------------------------
function endsWith(str, suffix)
{
	if(str==null || suffix==null || str.length<suffix.length)
		return null;
	var ending = str.substring((str.length-suffix.length), str.length);
	
	return (ending==suffix);
}

//-----------------------------------------------------------------
//--- Détermine si une string débute par un certain préfix --------
//-----------------------------------------------------------------
function startsWith(str, prefix)
{
	if(str==null || prefix==null || str.length<prefix.length)
		return null;		
	var starting = str.substring(0, prefix.length);
	
	return (starting==prefix);
}

//-----------------------------------------------------------------
//--- Cette fonction permet de convertir une string de manière  
//--- a ce  qu'elle puisse etre insérer entre "" dans un        
//--- programme Java ou Javascript. Ainsi, les \ sont dédoublés 
//--- et les " sont préfixés d'un \                             
//--- Exemple:                                                  
//---   Mon poids\grandeur est 123lbs/5'9"						
//--- donne:													
//---   Mon poids\\grandeur est 123lbs\\5'9\"					
//-----------------------------------------------------------------
function convertToJavaLiteral(sExpression, sDelimiter)
{
	if (!sDelimiter || sDelimiter==null)
		sDelimiter="\""; // Double-quote par défaut

    if (sExpression.length==0)
        return sExpression;
 
    iLength = sExpression.length;
    // Dédoubler les \
    for (position=0; position<iLength; position++)
    {
      if (sExpression.charAt(position)=="\\")
      {
        sExpression = sExpression.substring(0, position) + "\\\\" + sExpression.substring(position+1);
        iLength++;
        position += 2;				
      }
      // Insérer un \ avant les " ou ' (delimiteur) 
      else if (sExpression.charAt(position) == sDelimiter)
      {
        sExpression = sExpression.substring(0, position) + "\\" + sDelimiter + sExpression.substring(position+1);
        iLength++;
        position++;
      }
    }
    return sExpression;
}

//--------------------------------------------------------------------
//-- Cette fonction permet d'extraire les paramètres d'une 
//-- querystring de la manière suivante. Pour extraire le 
//-- paramètre "client_nri=123" de la querystring courante:
//--        var arg = getArgs();
//--        alert(arg.client_nri);  // Affiche "123"
//--------------------------------------------------------------------
function getArgs() 
{
	var args = new Object();
	// Get Query String
	var query = location.search.substring(1); 
	// Split query at the comma
	var pairs = query.split("&"); 
	
	// Begin loop through the querystring
	for(var i = 0; i < pairs.length; i++) 
	{
		// Look for "name=value"
		var pos = pairs[i].indexOf('='); 
		// if not found, skip to next
		if (pos == -1) 
		{
			args[argname] = null; 
			continue
		}
		// Extract the name
		var argname = pairs[i].substring(0,pos); 
		
		// Extract the value
		var value = pairs[i].substring(pos+1); 
		// Store as a property
		args[argname] = unescape(value);
	}
	return args; // Return the Object
}

//---------------------------------------------------------------------
//-- Ajoute un paramètre à la fin de la querystring
//---------------------------------------------------------------------
function appendArg(url, argName, argValue)
{	
	if (url.indexOf("?")>=0)
		url += "&";
	else
		url += "?"
	url += argName+"="+escape(argValue);
	return url;
}

//----------------------------------------------------------------------------
//-- Cette fonction permet d'identifier si un paramètre est existant      ----
//--  http://machine:80/url?abc=20&def=10&ghi&jkl=1                       ----
//-- argExists(def) retournera TRUE / argExists(xyz) retournera FALSE     ----
//----------------------------------------------------------------------------
function argExists(argToFind) 
{
	var args = new Object();
	// Get Query String
	var query = location.search.substring(1); 
	// Split query at the comma
	var pairs = query.split("&"); 
	var pos;
	var argname;
	
	// Begin loop through the querystring
	for(var i = 0; i < pairs.length; i++) 
	{
		if (pairs[i].indexOf('=')!=-1)
		{
			// Look for "name=value"
			pos = pairs[i].indexOf('='); 
			// Extract the name
			argname = pairs[i].substring(0,pos); 
		}
		else
			argname = pairs[i]; // Extract the name
			
		if (argname.toUpperCase()==argToFind.toUpperCase())
			return true; // Return the Object
	}
	
	return false; // Loop finished, return not found value...
}

//---------------------------------------------------------------------------
//-- Modifie/Ajoute un paramètre dans une URL  ------------------------------
//---------------------------------------------------------------------------
function changeArg(url, paramName, paramValue)
{
	var finalUrl = "";
	var urlAndArgs = url.split("?");
	var bParamChanged = false;
	var anchor=null;

	//-- Ajouter la 1ère partie de l'URL (ex: /servlet/SSSites?) ----
	finalUrl += urlAndArgs[0]+"?";
	//-- Ajouter la 2e partie de l'URL (ex: ?site_nri=1234) ---------
	if (urlAndArgs[1]!=null)
	{
		var aArgsAndAnchor = urlAndArgs[1].split("#");
		if (aArgsAndAnchor.length>0)
			anchor=aArgsAndAnchor[1];
			
		var aParams = aArgsAndAnchor[0].split("&"); 
		for (var i=0; i<aParams.length; i++)
		{
			var aParam = aParams[i].split("="); 
			//-- Ajouter le nom du paramètre ------
			finalUrl += aParam[0]+"="; 
			//-- Ajouter la valeur du paramètre ---
			if (aParam[1]!=null && aParam[1]!='')
			{
				// Paramètre à modifier
				if (aParam[0]==paramName)
				{
					finalUrl += paramValue;
					bParamChanged = true;
				}
				// Paramètre inchangé
				else
					finalUrl += aParam[1];
			}
			finalUrl += "&";
		}
	}
	//--- Paramètre toujours PAS CHANGÉ? L'AJOUTER! ----------------------------
	if (!bParamChanged)
		finalUrl += paramName+"="+paramValue;
	//--- RETIRER le DERNIER CARACTÈRE si INVALIDE -----------------------------
	var urlLastChar = finalUrl.substring(finalUrl.length-1, finalUrl.length);
	if (urlLastChar=="&" || urlLastChar=="?")
		finalUrl = finalUrl.substring(0, finalUrl.length-1);
		
	if (anchor!=null)
		finalUrl+="#"+anchor;

	return finalUrl;
}

//----------------------------------------------------------------------
//-- Ajoute ou remplace un anchor à la fin d'une url.
//----------------------------------------------------------------------
function setUrlAnchor(url, anchorName)
{
	var aUrlAndAnchor = url.split("#");
	var finalUrl=aUrlAndAnchor[0];
	if (anchorName!=null && anchorName!='')
		finalUrl+="#"+anchorName;
	return finalUrl;
}


//----------------------------------------------------------------------
//-- Recharge la page courante en y spécifiant le anchor à atteindre.
//-- Simule l'effet d'un <a href="#myAnchor"> car ce dernier ne semble
//-- pas toujours fiable dans certains context.
//----------------------------------------------------------------------
function jumpTo(anchorName)
{
	window.location.href = setUrlAnchor(window.location.href, anchorName);
}

//----------------------------------------------------------------------
//-- Ajoute "http://" à une url si nécessaire --------------------------
//----------------------------------------------------------------------
function getExternalFullUrl(url)
{
	url = trim(url);
	var aPrefix = ["http://", "https://"];
	var hasPrefix=false;
	for (var i=0; i<aPrefix.length; i++)
	{
		// L'url début déjà par le préfix? 
		if (url.substring(0, aPrefix[i].length).toLowerCase()==aPrefix[i]) 
			hasPrefix=true
	}			
	// Ajouter préfix par défaut si aucun préfix
	if (!hasPrefix)
		url = "http://" + url;
		
	return url;
}

//----------------------------------------------------------------------
//-- Convertir une chaîne de caractères en tableau (Array)      --------
//----------------------------------------------------------------------
function getArrayFromString(str, separator)
{
	if (str==null || str=='')
		return null;
	else
	{
		str = unescape(str);
		return str.split(separator);
	}
}

//----------------------------------------------------------------------
//-- Convertir un array en une string de liste avec séparateurs --------
//----------------------------------------------------------------------
function getListFromArray(array, separator)
{
	var list=null;
	for (var i=0; i<array.length; i++)
	{
		if (list == null)
			list = "";
		else
			list += separator;
		list += array[i];
	}
	return list;
}

//--------------------------------------------------------------------
//-- Détermine position d'un élément dans un tableau (-1 si absent) --
//--------------------------------------------------------------------
function getPosInArray(aArray, element)
{
	for (var i=0; (aArray!=null && i<aArray.length); i++)
		if (aArray[i]!=null && aArray[i]==element)
			return i;
	return -1;
}

//------------------------------------------------------------------
//--- Générer TIMESTAMP --------------------------------------------
//------------------------------------------------------------------
function getTimeStamp()
{
	var date = new Date();
	return date.getTime();
}

//------------------------------------------------------------------
//--- Générer ID unique dans la fenêtre ----------------------------
//------------------------------------------------------------------
function getUniqueId()
{
	if (!document.uniqueIdSequence)
		document.uniqueIdSequence = 1;
	var id = getTimeStamp()+"_"+document.uniqueIdSequence;
	document.uniqueIdSequence++;
	return id;
}

//------------------------------------------------------------------
//--- Vérifie si un bloqueur de popup est actif (goolgebar etc.) ---
//------------------------------------------------------------------
function isPopupBlockingActive()
{
	//####################
	var tstWin = window.open("/bidon.html", "TestWindow");

	if (tstWin == null)
		return true;
	else
	{
		tstWin.close();
		return false;
	}
}

//---------------------------------------------------------------------
//-- Convertie une String en entier  ----------------------------------
//---------------------------------------------------------------------
function getIntValue(sValue, iDefault)
{
	var iValue = iDefault;
	if (sValue!=null && sValue!='')
	{
		try
		{
			iValue = parseInt(sValue);
		}
		catch (e)
		{}
	}
	return iValue;
}

//-------------------------------------------------------
//-- Arrondie un nombre au nombre de décimales spécifié
//-------------------------------------------------------
function round(fNumber, nbDecimals)
{
	var shiftCoef = Math.pow(10, nbDecimals);
	var rounded = Math.round(fNumber*shiftCoef)/shiftCoef;
	return rounded;
}

//---------------------------------------------------------------------
//--- Converti une collection (ex: getElementsByTagName()) en ARRAY ---
//---------------------------------------------------------------------
function collectionToArray(coll)
{
	if (coll == null)
		return null;

	var ar = new Array();	
	for (var i=0; i<coll.length; i++)
		ar[ar.length] = coll[i];

	return ar;
}

//------------------------------------------------------------------------
//-- Cacher un élément (ex: input, table, div, etc...) et stocker son   --
//-- attribut "style.display" original.                                 --
//------------------------------------------------------------------------
function hideElement(oElement)
{
	if (oElement!=null)
	{		
		if (oElement.style.display!="none")
			oElement.setAttribute("originalDisplayStyle", oElement.style.display);
		oElement.style.display = "none";
	}	
}

//------------------------------------------------------------------------
//-- Montrer un élément (ex: input, table, div, etc...) en restaurant ----
//-- son attribut "style.dispkay" original.                           ----
//------------------------------------------------------------------------
function showElement(oElement)
{
	if (oElement!=null)
	{
		var orignalStyle  = oElement.getAttribute("originalDisplayStyle");
		if (orignalStyle==null)
			orignalStyle = "";
		oElement.style.display = orignalStyle;
	}
}

//------------------------------------------------------------------------
//-- Empêche la sélection de texte dans un élément (ex: textbox) afin 
//-- d'éviter le copier/coller. Utile pour username et mot de passe.
//-- IMPORTANT: Ne fonctionne que sur IE.
//------------------------------------------------------------------------
function blockSelectAndDrag(oElement)
{
	if (oElement!=null)
	{
		oElement.ondragstart = new Function("return false");
		oElement.onselectstart = new Function("return false");
	}
}

//------------------------------------------------------------------------
//-- Parcours tous les sous-éléments d'un élément (oRoot) et en extrait
//-- tout ceux dont le id débute par idBegining;
//--  oRoot: Node parent dont les enfant doivent être parcourus
//--  sIdPrefix: Préfix du id ex: "monPrefix" pour trouver "monPrefix1", "monPrefix2", ...
//--  sElementType: Type d'éléments recherchés exemple: "input", "td", etc.
//--  bReturnFirstOnly: si True, ne retourne qu'un seul élément, le 1er
//------------------------------------------------------------------------
function getElementsByIdStartingWith(oRoot, sIdPrefix, sElementType, bReturnFirstOnly)
{
	if (!oRoot || oRoot==null)
		return null;
	
	var elements = new Array();
	var allElements = null;
	//-- Filtrer si le type d'élément est spécifié ex: "input" ---
	if (sElementType!=null && sElementType!='')
		allElements = oRoot.getElementsByTagName(sElementType);		
	//-- TOUS les éléments enfants ------------------------------
	else
		allElements = oRoot.getElementsByTagName("*");		
		
	// Boucler sur tous les sous-éléments du root
	var stop = false;
	for (var i=0; !stop && i<allElements.length; i++)
	{		
		var element = allElements[i];
		// Élément match
		if (element.id!=null && 
		    element.id.substring(0, sIdPrefix.length) == sIdPrefix)
		{
		    elements.push(element);
		    if (bReturnFirstOnly)
		    	stop=true;
		}
	}

	//-- On ne retourne qu'un élément ou un array ---
	if (bReturnFirstOnly && elements.length>0)
		return elements[0];
	else
		return elements;
}

//------------------------------------------------------------------------
//-- Remonte les ancêtres d'un noeud jusqu'à une type de noeud ex:"form"
//------------------------------------------------------------------------
function getNodeFromParents(oNode, searchedNodeName)
{	
	searchedNodeName = searchedNodeName.toUpperCase();
	var oParent = oNode;
	while (oParent && oParent!=null && oParent.nodeName && 
	       oParent.nodeName.toUpperCase()!=searchedNodeName)
	{
		if (oParent && oParent.parentNode)
			oParent=oParent.parentNode;
		else
			oParent=null;		
	}

	if (oParent && oParent!=null && 
	    (!oParent.nodeName || oParent.nodeName.toUpperCase()!=searchedNodeName))
		oParent=null;

	if (!oParent)
		oParent=null;
	return oParent;
}

//------------------------------------------------------------------------
//-- Retourne True si le noeud oPotentialAncestorNode est un ancêtre
//-- du noeud oNode.
//------------------------------------------------------------------------
function isNodeAncestor(oPotentialAncestorNode, oChildNode)
{	
	var isAncestor=false;
	var oParent = oChildNode;
	while (oParent && oParent!=null && oParent!=oPotentialAncestorNode)
	{
		if (oParent && oParent.parentNode)
			oParent=oParent.parentNode;
		else
			oParent=null;		
	}
	if (oParent && oParent!=null && oParent==oPotentialAncestorNode)
		isAncestor=true;

	return isAncestor;
}

//------------------------------------------------------------------------
//-- Retourne l'objet <form> dont l'attribut "action" contient l'action
//-- spécifiée.
//------------------------------------------------------------------------
function getFormByAction(sAction)
{
	var forms = document.getElementsByTagName("form");
	var i=0;
	while(i<forms.length && forms[i].action.indexOf(sAction)==-1)
		i++;
	
	if (i<forms.length)	
		return forms[i];
	else
		return null;
}


//------------------------------------------------------------------------
//-- Intercepter tout changement dans un formulaire.
//--   handlerName_noParam: Nom de la fonction de base qui sera appelée SANS paramètre
//--                        et dans laquelle "this" pourra être utilisé pour
//--                        identifier la source de l'événement.
//--                        ex: handlerName_noParam = "dataModified"
//--                            déclaration = "function dataModified()"       
//--
//--   handlerName_sourceParam: Nom de la fonction dans laquelle "this" NE
//--                            peut PAS être utilisé. Par conséquent, l'objet
//--                            à l'origine de l'événement est passé en paramètre.
//--                            ex: handlerName_sourceParam = "dataModifiedSrc"
//--                                déclaration = "function dataModifiedSrc(oEventSource)"       
//------------------------------------------------------------------------
function trapFormChanges(oRoot, handlerName_noParam, handlerName_sourceParam, bIncludeButtons,
                         exclusionAttrib)
{	
	//var startTime = getTimeStamp();
	
	//--- Tags <input> ------------------------
	aInputs = oRoot.getElementsByTagName("input");
	for (var i=0; i<aInputs.length; i++)
	{		
		var oInput = aInputs[i];
		var type = oInput.type;
		//-- Si ne contient pas un attribut d'exclusion -----
		if (!oInput.getAttribute(exclusionAttrib))
		{
			if (type=="checkbox" || type=="radio" || (type=="button" && bIncludeButtons))
				appendEventHandler(oInput, "onclick", handlerName_noParam, handlerName_sourceParam);
			else if (type=="text" || type=="password")
			{
				appendEventHandler(oInput, "onkeypress", handlerName_noParam, handlerName_sourceParam);	
				appendEventHandler(oInput, "onchange", handlerName_noParam, handlerName_sourceParam);
			}
			else		
				appendEventHandler(oInput, "onchange", handlerName_noParam, handlerName_sourceParam);
		}
	}
	
	//--- Tags <select> (combobox) --------------
	aSelects = oRoot.getElementsByTagName("select");
	for (var i=0; i<aSelects.length; i++)
		appendEventHandler(aSelects[i], "onchange", handlerName_noParam, handlerName_sourceParam);
		
	//--- Tags <textarea> -----------------------
	aTextarea = oRoot.getElementsByTagName("textarea");	
	for (var i=0; i<aTextarea.length; i++)
	{
		appendEventHandler(aTextarea[i], "onchange", handlerName_noParam, handlerName_sourceParam);
		appendEventHandler(aTextarea[i], "onkeypress", handlerName_noParam, handlerName_sourceParam);		
	}		
	//alert("trapFormChanges-->"+(getTimeStamp()-startTime));
}

//------------------------------------------------------------------------
//-- Ajoute un event handler à une propriété d'événement ex: "onchange",
//-- "onclick", ... 
//-- Deux handler doivent être déclarés dans la page: 
//--    1- une fonction SANS paramètre dans laquel "this" représente la source
//--      de l'événement.
//--    2- une fonction AVEC un paramètre: l'objet d'où origine l'événement (this).
//--       Dans cette fonction "this" n'existe pas.
//--#### ATTENTION: Cette fonction ne fonctionne pas lorsque des événements existe déjà!!!
//--####            Voir à implanter un mécanique comme celle-ci:
//--####			   var oldHandler=window.onload;			
//--####               window.onload = function() { oldHandler(); initFlashMap(); }
//------------------------------------------------------------------------
function appendEventHandler(oElement, sEventAttributeName, 
                            sHandlerName_noParam, sHandlerName_sourceParam)
{
	var oldHandler = eval("oElement."+sEventAttributeName);
	//-- Il y a déjà un handler pour l'événement -----------
	if (oldHandler && oldHandler!=null)
	{		
		var ts = getTimeStamp(); // ex: "1343378645641"
		var newFuncName = "document.func"+ts;
		var ctrlVarName = "document.ctrl"+ts;
		var ctrlDeclaration = ctrlVarName+"=oElement";
		// Déclarer la variable globale référant à l'objet source
		eval(ctrlDeclaration);
		var funcDeclaration = newFuncName+"= function () {  "+oElement.attributes[sEventAttributeName].value+";  "+sHandlerName_sourceParam+"("+ctrlVarName+");  }";
		// Déclarer la fonction englobant l'ancien handler et le nouveau
		eval(funcDeclaration);
		oldHandler = eval(newFuncName);
		eval("oElement."+sEventAttributeName+"="+newFuncName);		
	}
	//-- Aucun handler pour l'événement --------------------
	else
		eval("oElement."+sEventAttributeName+"="+sHandlerName_noParam);
}


//----------------------------------------------------------------------
//-- Retourne la fenêtre originale (principale) d'une hiérarchie de 
//-- popups pour un même domaine.
//----------------------------------------------------------------------
function getBaseWin()
{
	var host = top.location.host;
	var oWin = window.top;

	while (oWin.opener && 
	       typeof(oWin.opener.top.location.host)=='string' &&
	       oWin.opener.top.location.host==host)
	       oWin=oWin.opener.top;
	return oWin;
}

//----------------------------------------------------------
//-- Redimensionne en hauteur une iframe selon son contenu
//----------------------------------------------------------
function resizeIframeToFitHeight(oFrame, forcedHeight)
{	
	var BUFFER_HEIGHT = 0;
  	// Find the height of the internal page
  	var iHeight = forcedHeight;
  	if (!iHeight || iHeight==null)
  	{  	
  		iHeight = oFrame.contentWindow.document.body.scrollHeight + BUFFER_HEIGHT;
  		//## Fonctionnait sur IE et Opera dans le cas d'une iFrame dans un popup
  		//var oBody = oFrame.contentWindow.document.body;
  		//iHeight = oBody.scrollHeight + (oBody.offsetHeight - oBody.clientHeight) + 5;
  	}
	oFrame.style.height = iHeight+"px";
	oFrame.height = iHeight;
}

//----------------------------------------------------------
//-- Redimensionne en hauteur et largeur une iframe selon 
//-- son contenu.
//----------------------------------------------------------
function resizeIframeToFit(oFrame, forcedWidth, forcedHeight)
{
	resizeIframeToFitHeight(oFrame, forcedHeight);
  
  	var iWidth = forcedWidth;
  	if (!forcedWidth || forcedWidth==null)
  	{
  		//### Foncionne sur IE et Opera mais pas sur FF ###
		var oBody = oFrame.contentWindow.document.body;
		iWidth = oBody.scrollWidth + (oBody.offsetWidth - oBody.clientWidth) + 5;
  	}
 	 // Change the height of the iframe
	oFrame.style.width = iWidth+"px";
	oFrame.width = iWidth;
}



//-----------------------------------------------------------
//-- Fait clignoter un élément (visible/non-visible) --------
//-----------------------------------------------------------		
function flashingEffect(oElement, nbTimes, initialDelay, delayOn, delayOff)	
{
	id = document.flashingEffectLastId;
	if (!id || id==null)
		id=1;
	else
		id++;

	// Globaliser l'élément afin qu'il soit atteignable par setTimeout
	eval("document.oFlashingElement_"+id+"= oElement;");
	
	absDelay=initialDelay;
	for (var i=0; i<nbTimes; i++)
	{
		window.setTimeout("document.oFlashingElement_"+id+".style.visibility='hidden'", absDelay);
		absDelay+=delayOff;
		window.setTimeout("document.oFlashingElement_"+id+".style.visibility='visible'", absDelay);
		absDelay+=delayOn;				
	}			
	document.flashingEffectLastId = id;
}

//--------------------------------------------------------------
//-- Retire une class CSS à une liste de classes ---------------
//--------------------------------------------------------------
function removeStyleClass(classNames, classNameToRemove)
{	
	// Pas d'autres classes
	if (classNames==classNameToRemove)
		classNames = "";	
	// Plus d'une classe
	else if (classNames && classNames!=null)
		classNames = replaceInString(classNames, classNameToRemove, "", false);
		
	return classNames;
}

//--------------------------------------------------------------
//-- Dans certains car, la méthode Array.concat() ne semble ----
//-- pas fonctionner pour certains types d'array.
//--------------------------------------------------------------
function concatArrays(array1, array2)
{	
	if (array1==null || array2==null)
		return null;
	if (array1.length==0 && array2.length>0)
		return array2;
	if (array1.length>0 && array2.length==0)
		return array1;

	var newArray = new Array(array1.length+array2.length);	

	//-- Insérer l'Array #1 ---
	for (var i=0; i<array1.length; i++)
		newArray[i]=array1[i];
		
	//-- Insérer l'Array #2 ---		
	var startIndex=array1.length;
	for (var i=0; i<array2.length; i++)
		newArray[startIndex+i]=array2[i];		
	
	return newArray;
}

//--------------------------------------------------------------
//-- Retourne la hauteur intérieur de la fenêtre spécifiée
//-- ou courante par défaut.
//--------------------------------------------------------------
function getWindowHeight(oWin)
{		
	if (!oWin)
		oWin = window;
	return oWin.innerHeight ? oWin.innerHeight : oWin.document.documentElement.clientHeight ? oWin.document.documentElement.clientHeight : oWin.document.body.clientHeight;
}

//--------------------------------------------------------------
//-- Retourne la largeur intérieure de la fenêtre courante
//--------------------------------------------------------------
function getWindowWidth()
{		
	return window.innerWidth ? window.innerWidth : document.documentElement.clientWidth ? document.documentElement.clientWidth : document.body.clientWidth;
}

//--------------------------------------------------------------
//-- Retourne la première coordonnée Y visible dans la fenêtre 
//--------------------------------------------------------------
function getVisibleTop()
{
	return document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop;
}

//--------------------------------------------------------------
//-- Calcule la distance verticale entre un objet et le haut de 
//-- de la page (même si l'objet n'est pas visible car il est
//-- trop bas).
//--------------------------------------------------------------
function getDistanceFromPageTop(oElement)
{
   if (!oElement || oElement==null)	
   	return null;
   
   var y = oElement.offsetTop;	
   if (oElement.offsetParent)
       y += getDistanceFromPageTop(oElement.offsetParent);
   return y;
}

//--------------------------------------------------------------
//-- Calcule la distance horizontale entre un objet et la bordure
//-- gauche de de la page (même si l'objet n'est pas visible car 
//-- il est trop à doite).
//--------------------------------------------------------------
function getDistanceFromPageLeft(oElement)
{
	if (!oElement || oElement==null)	
   		return null;
   	
	var x = oElement.offsetLeft;	
	if (oElement.offsetParent)
    	x += getDistanceFromPageLeft(oElement.offsetParent);
	return x;
}

//------------------------------------------------------
//-- Cache les combobox qui se trouvent sous (dessus)
//-- l'élément spécifié. La liste des combos affectées
//-- est retournée (pour réaffichage).
//------------------------------------------------------
function hideOverlayingCombos(oElement)
{
	var aHiddenCombos = null;	
	//-- IE seulement ------------
	if (document.all && oElement && oElement!=null) 
	{
		aHiddenCombos = new Array();
		//-- Coordonnées de l'élément top-niveau -----
		var elementLeft = getDistanceFromPageLeft(oElement);
		var elementTop = getDistanceFromPageTop(oElement);
		var elementRight = elementLeft + oElement.offsetWidth;
		var elementBottom = elementTop + oElement.offsetHeight;
		
		elementLeft += oElement.offsetParent.clientLeft;
		elementTop += oElement.offsetParent.clientTop;
	
		var aCombos = document.getElementsByTagName("select");		
		for(i=0; i <aCombos.length; i++) 
		{
			var oCombo = aCombos[i];
			var comboLeft = getDistanceFromPageLeft(oCombo);
			var comboTop = getDistanceFromPageTop(oCombo);
			var comboRight = comboLeft + oCombo.offsetWidth;
			var comboBottom = comboTop + oCombo.offsetHeight;
			//-- Cas d'intersection element/combo ------
			var bOverlay = false;
			if (comboLeft >= elementLeft && comboLeft<=elementRight &&
			    comboTop>=elementTop && comboTop<=elementBottom) 
			    bOverlay=true;

			if (comboRight>=elementLeft && comboRight<=elementRight &&
			    comboBottom>=elementTop && comboBottom<=elementBottom) 
				bOverlay=true;

	        if (comboLeft<=elementLeft && comboRight>=elementRight && 
	            comboTop>=elementTop && comboBottom<=elementBottom) 
				bOverlay=true;
				
			//-- Vérifier que la combo ne fait pas parti de l'élément à afficher ---
			if (bOverlay && isNodeAncestor(oElement, oCombo))
				bOverlay=false;

			//-- Cacher les combos en conflit (si pas déjà cachée) -------
			if (bOverlay && oCombo.style.visibility!='hidden')
			{
				aHiddenCombos[aHiddenCombos.length] = oCombo;
				oCombo.style.visibility = 'hidden';				
			}
		}			
	}		
	return aHiddenCombos;
}


//------------------------------------------------------
//-- Réafficher les combos qui ont été cachées par 
//-- hideOverlayingCombos().
//------------------------------------------------------
function restoreOverlayingCombos(aHiddenCombos)
{
	if (aHiddenCombos && aHiddenCombos!=null)
	{
		for (var i=0; i<aHiddenCombos.length; i++)
			aHiddenCombos[i].style.visibility = 'visible';
	}
}
