/*
*************************************************
** XMLHttpRequest object
*************************************************
*/

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;
}

/*
*************************************************
** functions to get url
*************************************************
*/
function getUrlWithDataParameters(page, action, speciesId, stageId, organId, level, familyId, geneId)
{
	var url = "?";
	if (page != null) {
		url += "page=" + encodeURIComponent(page) + "&";
	}
	if (action != null) {
		url += "action=" + encodeURIComponent(action) + "&";
	}
	if (speciesId != null) {
		url += "species_id=" + encodeURIComponent(speciesId) + "&";
	}
	if (stageId != null) {
		url += "stage_id=" + encodeURIComponent(stageId) + "&";
	}
	if (organId != null) {
		url += "organ_id=" + encodeURIComponent(organId) + "&";
	}
	if (level != null) {
		url += "level=" + encodeURIComponent(level) + "&";
	}
	if (familyId != null) {
		url += "gene_family_id=" + encodeURIComponent(familyId) + "&";
	}
	if (geneId != null) {
		url += "gene_id=" + encodeURIComponent(geneId) + "&";
	}


	if (document.getElementById("jsDataType")) {
		url += "data_type=" + encodeURIComponent(document.getElementById("jsDataType").value) + "&";
	}
	if (document.getElementById("jsDataQuality")) {
		url += "data_quality=" + encodeURIComponent(document.getElementById("jsDataQuality").value) + "&";
	}
	if (document.getElementById("jsGeneBioType")) {
		url += "gene_biotype=" + encodeURIComponent(document.getElementById("jsGeneBioType").value) + "&";
	}
	if (document.getElementById("jsPredictionMethodId")) {
		url += "prediction_method_id=" + encodeURIComponent(document.getElementById("jsPredictionMethodId").value) + "&";
	}

	if (document.getElementById("jsDataSearchType")) {
		url += "data_search_type=" + encodeURIComponent(document.getElementById("jsDataSearchType").value) + "&";
	}
	if (document.getElementById("jsDataSearchTerm")) {
		url += "data_search_term=" + encodeURIComponent(document.getElementById("jsDataSearchTerm").value) + "&";
	}
	if (document.getElementById("jsDataListType")) {
		url += "data_list_type=" + encodeURIComponent(document.getElementById("jsDataListType").value) + "&";
	}
	if (document.getElementById("jsDataSearchList")) {
		url += "data_search_list=" + encodeURIComponent(document.getElementById("jsDataSearchList").value) + "&";
	}
	if (document.getElementById("jsUseSessionData")) {
		url += "use_session_data=on&";
	}


	if (document.getElementById("jsIncludeOrganChildren")) {
		url += "organ_children=on&";
	}
	if (document.getElementById("jsIncludeStageChildren")) {
		url += "stage_children=on&";
	}
	if (document.getElementById("jsExpressionOnly")) {
		url += "expression_only=on&";
	}
	return url;
}

function getUrl(page, action, speciesId, stageId, organId,
    dataType, dataQuality, level, searchId, searchName, displayType)
{
	var url = "?";
	if (page != null) {
		url += "page=" + encodeURIComponent(page) + "&";
	}
	if (action != null) {
		url += "action=" + encodeURIComponent(action) + "&";
	}
	if (speciesId != null) {
		url += "species_id=" + encodeURIComponent(speciesId) + "&";
	}
	if (stageId != null) {
		url += "stage_id=" + encodeURIComponent(stageId) + "&";
	}
	if (organId != null) {
		url += "organ_id=" + encodeURIComponent(organId) + "&";
	}
	if (dataType != null) {
		url += "data_type=" + encodeURIComponent(dataType) + "&";
	}
	if (dataQuality != null) {
		url += "data_quality=" + encodeURIComponent(dataQuality) + "&";
	}
	if (level != null) {
		url += "level=" + encodeURIComponent(level) + "&";
	}
	if (searchId != null) {
		url += "search_id=" + encodeURIComponent(searchId) + "&";
	}
	if (searchName != null) {
		url += "search_name=" + encodeURIComponent(searchName) + "&";
	}
	if (displayType != null) {
		url += "display_type=" + encodeURIComponent(displayType) + "&";
	}
	return url;
}

/*
**********************************************************
** function to load the stage options of a select element
** after choosing the species
**********************************************************
*/
function loadSpeciesStageFormEvents()
{
	if (document.getElementById("speciesId")) {
    	document.getElementById("speciesId").onchange = function() {
    		loadStageOptions(document.getElementById("speciesId"));
    	};
    }
}

function loadStageOptions(speciesSelect)
{
	var speciesId = speciesSelect.value;
    var url = getUrl("anatomy", "ajax_stage_options",
    speciesId, null, null, null, null, null, null, null);
    if (speciesSelect.id == "speciesIdAllStages") {
    	url += "all_stages=on&amp;";
    }

	var xhr = createXhr();
    xhr.onreadystatechange  = function() {
         if (xhr.readyState  == 4) {
              if (xhr.status  == 200) {
                 document.getElementById("stageOptionsContainer").innerHTML = xhr.responseText;
                 loadSpeciesStageFormEvents();
              }
         }
    };

    xhr.open("GET", url,  true);
    xhr.send(null);
}

/*
**********************************************************
** functions to get the next and previous node of an element
** do not return textnodes, or empty nodes
** function to add node after a node
** function to remove a row from a table
**********************************************************
*/
function nextObject(element) {
	var n = element;
	do {
        n = n.nextSibling;
    } while (n && n.nodeType != 1);
	return n;
}

function previousObject(element) {
	var p = element;
	do {
        p = p.previousSibling;
    } while (p && p.nodeType != 1);
	return p;
}

function insertAfter(referenceNode, newNode)
{
    referenceNode.parentNode.insertBefore(newNode, referenceNode.nextSibling);
}

function createAttribute(attributeName, attributeValue)
{
	var attribute = document.createAttribute(attributeName);
	attribute.nodeValue = attributeValue;
	return attribute;
}

function removeRow(table, row)
{
	var searchedId = row.id;
	var index = -1;
	var rows = table.rows;
	for (var i = 0; i < rows.length; i++) {
		if (rows[i].id == searchedId) {
			index = i;
	        break;
		}
	}
	table.deleteRow(index);
}

/*
**********************************************************
** functions to read / write cookies
**********************************************************
*/
function writeCookie(name, value)
{
	var argv=writeCookie.arguments;
	var argc=writeCookie.arguments.length;
	var expires=(argc > 2) ? argv[2] : null;
	var path=(argc > 3)    ? argv[3] : null;
	var domain=(argc > 4)  ? argv[4] : null;
	var secure=(argc > 5)  ? argv[5] : false;
	document.cookie=name+"="+escape(value)+
	((expires===null) ? "" : ("; expires="+expires.toGMTString()))+
	((path===null)    ? "" : ("; path="+path))+
	((domain===null)  ? "" : ("; domain="+domain))+
	((secure===true)  ? "; secure" : "");
}

function getCookieVal(offset)
{
	var endstr=document.cookie.indexOf (";", offset);
	if (endstr==-1) {
        endstr=document.cookie.length;
    }
	return unescape(document.cookie.substring(offset, endstr));
}
function readCookie(name)
{
	var arg=name+"=";
	var alen=arg.length;
	var clen=document.cookie.length;
	var i=0;
	while (i<clen) {
		var j=i+alen;
		if (document.cookie.substring(i, j)==arg) {
            return getCookieVal(j);
        }
		i=document.cookie.indexOf(" ",i)+1;
		if (i===0) {
            break;
        }
	}
	return null;
}
function deleteCookie(name)
{
	var date=new Date();
	date.setFullYear(date.getFullYear()-1);
	writeCookie(name,null,date);
}

/*
**********************************************************
** functions to manage the feature of hiding / showing
** a section of a page
**********************************************************
*/
function getSectionContentElement(container)
{
    var childList = container.childNodes;
    var contentElement = null;
    var x = 0;
    while (x < childList.length && contentElement === null) {
        if (childList[x].nodeName == "DIV" && (childList[x].className == "content" ||
        		childList[x].className == "hiddenContent")) {
            contentElement = childList[x];
        }
        x++;
    }
    return contentElement;
}

function hideShowContent(sectionContainer, actionElement, contentElement, writeInCookie)
{
    var alreadyInCookie = readCookie("bgeeHiddenSection");
    var arrSection = [];
    var toWriteInCookie = "";
    var x = 0;
    if (writeInCookie) {
	    if (alreadyInCookie !== null) {
	        arrSection = alreadyInCookie.split(" - ");
	    }
    }

    if (contentElement.className == "content") {
        contentElement.className = "hiddenContent";
        contentElement.style.display = "none";
        actionElement.innerHTML = "Show";

        if (writeInCookie) {
	        var found = false;
	        while (arrSection[x] != null && arrSection[x] != "")
	        {
	            if (arrSection[x] == sectionContainer.id) {
	                found = true;
	            }
	            toWriteInCookie += arrSection[x] + " - ";
	            x++;
	        }
	        if (!found) {
	            toWriteInCookie += sectionContainer.id + " - ";
	        }
        }
    } else if (contentElement.className == "hiddenContent") {
        contentElement.className = "content";
        contentElement.style.display = "block";
        actionElement.innerHTML = "Hide";

        if (writeInCookie) {
	        while (arrSection[x] !== null && arrSection[x] != "")
	        {
	            if (arrSection[x] != sectionContainer.id) {
	                toWriteInCookie += arrSection[x] + " - ";
	            }
	            x++;
	        }
        }
    }
    if (writeInCookie) {
        var date=new Date();
        date.setMonth(date.getMonth()+6);
        writeCookie("bgeeHiddenSection", toWriteInCookie, date);
    }
}

function actionHideShowContent(actionElement)
{
    var container = null;
    var child = actionElement;
    var stopSearch = false;
    while (!stopSearch) {
        container = child.parentNode;
        if (container === null || (container.className == "section" && container.nodeName == "DIV")) {
            stopSearch = true;
        } else {
            child = container;
        }
    }
    if (container === null) {
        return;
    }

    var contentDiv = getSectionContentElement(container);
    if (contentDiv === null) {
        return;
    }

    hideShowContent(container, actionElement, contentDiv, true);
}

function getSectionActionElement(container)
{
    var childList = container.childNodes;
    var actionElement = null;
    var x = 0;
    while (x < childList.length && actionElement === null) {
        if (childList[x].nodeName == "A" && childList[x].className == "hideContent") {
            actionElement = childList[x];
        } else {
            actionElement = getSectionActionElement(childList[x]);
        }
        x++;
    }
    return actionElement;
}

function loadHidingEvents()
{
    var aList = document.getElementsByTagName("a");
    var x = 0;
    while (x < aList.length) {
        if (aList[x].className == "hideContent") {
            aList[x].onclick = function() {
                actionHideShowContent(this);
                return false;
            };
        }
        x++;
    }


    var alreadyInCookie = readCookie("bgeeHiddenSection");
    var arrSection = new Array();
    if (alreadyInCookie !== null) {
        arrSection = alreadyInCookie.split(" - ");
    }
    x = 0;
    while (arrSection[x] != null && arrSection[x] != "")
    {
        var section = document.getElementById(arrSection[x]);
        if (section !== null) {
            var contentElement = getSectionContentElement(section);
            var actionElement = getSectionActionElement(section);
            if (contentElement !== null && actionElement !== null) {
                hideShowContent(section, actionElement, contentElement, false);
            }
        }
        x++;
    }
}

/*
**********************************************************
** text utils
**********************************************************
*/
 function htmlEntities(text)
 {
   text = text.replace(/"/g,'&quot;'); // 34 22
	text = text.replace(/&/g,'&amp;'); // 38 26
	text = text.replace(/\'/g,'&#39;'); // 39 27
	text = text.replace(/</g,'&lt;'); // 60 3C
	text = text.replace(/>/g,'&gt;'); // 62 3E
	text = text.replace(/\^/g,'&circ;'); // 94 5E
	text = text.replace(/‘/g,'&lsquo;'); // 145 91
	text = text.replace(/’/g,'&rsquo;'); // 146 92
	text = text.replace(/“/g,'&ldquo;'); // 147 93
	text = text.replace(/”/g,'&rdquo;'); // 148 94
	text = text.replace(/•/g,'&bull;'); // 149 95
	text = text.replace(/–/g,'&ndash;'); // 150 96
	text = text.replace(/—/g,'&mdash;'); // 151 97
	text = text.replace(/˜/g,'&tilde;'); // 152 98
	text = text.replace(/™/g,'&trade;'); // 153 99
	text = text.replace(/š/g,'&scaron;'); // 154 9A
	text = text.replace(/›/g,'&rsaquo;'); // 155 9B
	text = text.replace(/œ/g,'&oelig;'); // 156 9C
	text = text.replace(//g,'&#357;'); // 157 9D
	text = text.replace(/ž/g,'&#382;'); // 158 9E
	text = text.replace(/Ÿ/g,'&Yuml;'); // 159 9F
	// text = text.replace(/ /g,'&nbsp;'); // 160 A0
	text = text.replace(/¡/g,'&iexcl;'); // 161 A1
	text = text.replace(/¢/g,'&cent;'); // 162 A2
	text = text.replace(/£/g,'&pound;'); // 163 A3
	//text = text.replace(/ /g,'&curren;'); // 164 A4
	text = text.replace(/¥/g,'&yen;'); // 165 A5
	text = text.replace(/¦/g,'&brvbar;'); // 166 A6
	text = text.replace(/§/g,'&sect;'); // 167 A7
	text = text.replace(/¨/g,'&uml;'); // 168 A8
	text = text.replace(/©/g,'&copy;'); // 169 A9
	text = text.replace(/ª/g,'&ordf;'); // 170 AA
	text = text.replace(/«/g,'&laquo;'); // 171 AB
	text = text.replace(/¬/g,'&not;'); // 172 AC
	text = text.replace(/-/g,'&shy;'); // 173 AD
	text = text.replace(/®/g,'&reg;'); // 174 AE
	text = text.replace(/¯/g,'&macr;'); // 175 AF
	text = text.replace(/°/g,'&deg;'); // 176 B0
	text = text.replace(/±/g,'&plusmn;'); // 177 B1
	text = text.replace(/²/g,'&sup2;'); // 178 B2
	text = text.replace(/³/g,'&sup3;'); // 179 B3
	text = text.replace(/´/g,'&acute;'); // 180 B4
	text = text.replace(/µ/g,'&micro;'); // 181 B5
	text = text.replace(/¶/g,'&para'); // 182 B6
	text = text.replace(/·/g,'&middot;'); // 183 B7
	text = text.replace(/¸/g,'&cedil;'); // 184 B8
	text = text.replace(/¹/g,'&sup1;'); // 185 B9
	text = text.replace(/º/g,'&ordm;'); // 186 BA
	text = text.replace(/»/g,'&raquo;'); // 187 BB
	text = text.replace(/¼/g,'&frac14;'); // 188 BC
	text = text.replace(/½/g,'&frac12;'); // 189 BD
	text = text.replace(/¾/g,'&frac34;'); // 190 BE
	text = text.replace(/¿/g,'&iquest;'); // 191 BF
	text = text.replace(/À/g,'&Agrave;'); // 192 C0
	text = text.replace(/Á/g,'&Aacute;'); // 193 C1
	text = text.replace(/Â/g,'&Acirc;'); // 194 C2
	text = text.replace(/Ã/g,'&Atilde;'); // 195 C3
	text = text.replace(/Ä/g,'&Auml;'); // 196 C4
	text = text.replace(/Å/g,'&Aring;'); // 197 C5
	text = text.replace(/Æ/g,'&AElig;'); // 198 C6
	text = text.replace(/Ç/g,'&Ccedil;'); // 199 C7
	text = text.replace(/È/g,'&Egrave;'); // 200 C8
	text = text.replace(/É/g,'&Eacute;'); // 201 C9
	text = text.replace(/Ê/g,'&Ecirc;'); // 202 CA
	text = text.replace(/Ë/g,'&Euml;'); // 203 CB
	text = text.replace(/Ì/g,'&Igrave;'); // 204 CC
	text = text.replace(/Í/g,'&Iacute;'); // 205 CD
	text = text.replace(/Î/g,'&Icirc;'); // 206 CE
	text = text.replace(/Ï/g,'&Iuml;'); // 207 CF
	text = text.replace(/Ð/g,'&ETH;'); // 208 D0
	text = text.replace(/Ñ/g,'&Ntilde;'); // 209 D1
	text = text.replace(/Ò/g,'&Ograve;'); // 210 D2
	text = text.replace(/Ó/g,'&Oacute;'); // 211 D3
	text = text.replace(/Ô/g,'&Ocirc;'); // 212 D4
	text = text.replace(/Õ/g,'&Otilde;'); // 213 D5
	text = text.replace(/Ö/g,'&Ouml;'); // 214 D6
	text = text.replace(/×/g,'&times;'); // 215 D7
	text = text.replace(/Ø/g,'&Oslash;'); // 216 D8
	text = text.replace(/Ù/g,'&Ugrave;'); // 217 D9
	text = text.replace(/Ú/g,'&Uacute;'); // 218 DA
	text = text.replace(/Û/g,'&Ucirc;'); // 219 DB
	text = text.replace(/Ü/g,'&Uuml;'); // 220 DC
	text = text.replace(/Ý/g,'&Yacute;'); // 221 DD
	text = text.replace(/Þ/g,'&THORN;'); // 222 DE
	text = text.replace(/ß/g,'&szlig;'); // 223 DF
	text = text.replace(/à/g,'&aacute;'); // 224 E0
	text = text.replace(/á/g,'&aacute;'); // 225 E1
	text = text.replace(/â/g,'&acirc;'); // 226 E2
	text = text.replace(/ã/g,'&atilde;'); // 227 E3
	text = text.replace(/ä/g,'&auml;'); // 228 E4
	text = text.replace(/å/g,'&aring;'); // 229 E5
	text = text.replace(/æ/g,'&aelig;'); // 230 E6
	text = text.replace(/ç/g,'&ccedil;'); // 231 E7
	text = text.replace(/è/g,'&egrave;'); // 232 E8
	text = text.replace(/é/g,'&eacute;'); // 233 E9
	text = text.replace(/ê/g,'&ecirc;'); // 234 EA
	text = text.replace(/ë/g,'&euml;'); // 235 EB
	text = text.replace(/ì/g,'&igrave;'); // 236 EC
	text = text.replace(/í/g,'&iacute;'); // 237 ED
	text = text.replace(/î/g,'&icirc;'); // 238 EE
	text = text.replace(/ï/g,'&iuml;'); // 239 EF
	text = text.replace(/ð/g,'&eth;'); // 240 F0
	text = text.replace(/ñ/g,'&ntilde;'); // 241 F1
	text = text.replace(/ò/g,'&ograve;'); // 242 F2
	text = text.replace(/ó/g,'&oacute;'); // 243 F3
	text = text.replace(/ô/g,'&ocirc;'); // 244 F4
	text = text.replace(/õ/g,'&otilde;'); // 245 F5
	text = text.replace(/ö/g,'&ouml;'); // 246 F6
	text = text.replace(/÷/g,'&divide;'); // 247 F7
	text = text.replace(/ø/g,'&oslash;'); // 248 F8
	text = text.replace(/ù/g,'&ugrave;'); // 249 F9
	text = text.replace(/ú/g,'&uacute;'); // 250 FA
	text = text.replace(/û/g,'&ucirc;'); // 251 FB
	text = text.replace(/ü/g,'&uuml;'); // 252 FC
	text = text.replace(/ý/g,'&yacute;'); // 253 FD
	text = text.replace(/þ/g,'&thorn;'); // 254 FE
	text = text.replace(/ÿ/g,'&yuml;'); // 255 FF
	return text;
}

/*
**********************************************************
** functions to display help
**********************************************************
*/
function displayHelp(link)
{
    var temp = link.className.split("|");
    var help = null;
    if (temp[1]) {
        help = temp[1];
    }

    var xhr = createXhr();
    xhr.onreadystatechange  = function() {
         if (xhr.readyState == 4) {
              if (xhr.status == 200) {
                  var container = link.parentNode;
                  var helpNode = document.createElement("div");
				  helpNode.className = "tooltip";
				  helpNode.innerHTML = xhr.responseText +
				      "<a class='closeTooltip' href='#'>close</a>";
				  container.appendChild(helpNode);

				  var childList = helpNode.childNodes;
			      var x = 0;
			      while (x < childList.length) {
			      if (childList[x].nodeName == "A" &&
                      childList[x].className == "closeTooltip") {
                           childList[x].onclick = function() {
                               container.removeChild(helpNode);
                               return false;
                           };
                      }
                      x++;
			      }
              }
         }
    };
    xhr.open("GET", getUrl("documentation", "ajax_" + help),  true);
    xhr.send(null);
}

function loadHelpEvents()
{
    var aList = document.getElementById("bgeeBody").getElementsByTagName("a");

    for (var i = 0; i < aList.length; i++) {
        if (aList[i].className.indexOf("help|") != -1) {
            aList[i].onclick = function() {
                displayHelp(this);
                return false;
            };
        }
    }
}

function createHelpLink(cat, display)
{
    var helpNode = document.createElement("span");
    helpNode.setAttribute("class", "help");

    var helpNodeLink = document.createElement("a");
    helpNodeLink.setAttribute("href", "#");
    helpNodeLink.setAttribute("class", "help|" + cat);

    helpNodeLink.appendChild(document.createTextNode(display));
    helpNode.appendChild(helpNodeLink);

    return helpNode;
}

/*
**********************************************************
** functions to display/hide part of a too long text
**********************************************************
*/
function displayHideLongText(aLink)
{
    var span = previousObject(aLink);
    if (span.nodeName == "SPAN" &&
       (span.className == "hiddenText" || span.className == "displayedText")) {

       if (aLink.className == "hiddenText") {
           aLink.className = "displayedText";
           span.className = "displayedText";
           span.style.display = "";
       } else if (aLink.className == "displayedText") {
           aLink.className = "hiddenText";
           span.className = "hiddenText";
           span.style.display = "none";
       }
       var childrenSpan = aLink.getElementsByTagName("span");
       var x = 0;
       while (x < childrenSpan.length) {
           if (childrenSpan[x].className == "text") {
               if (aLink.className == "hiddenText") {
                   childrenSpan[x].style.display = "";
               } else {
                   childrenSpan[x].style.display = "none";
               }
           } else if (childrenSpan[x].className == "image") {
               if (aLink.className == "hiddenText") {
                   childrenSpan[x].innerHTML = "<img alt='display all' src='/bgee/images/resultset_next_16x16.png' />";
               } else {
                   childrenSpan[x].innerHTML = " <img alt='hide' src='/bgee/images/resultset_previous_16x16.png' />";
               }
           }
           x++;
       }

    }
}

function loadHidingTextEvents()
{
    var aList = document.getElementsByTagName("a");
    var x = 0;
    while (x < aList.length) {
        if (aList[x].className == "hiddenText" || aList[x].className == "displayedText") {
            aList[x].onclick = function() {
                displayHideLongText(this);
                return false;
            };
        }
        x++;
    }

    var spanList = document.getElementsByTagName("span");
    x = 0;
    while (x < spanList.length) {
        if (spanList[x].className == "hiddenText") {
            spanList[x].style.display = "none";
        }
        x++;
    }
}

function disablesReadOnlyCheckboxes()
{
    var inputList = document.getElementsByTagName("input");
    var x = 0;
    while (x < inputList.length) {
        if (inputList[x].getAttribute('type') == 'checkbox' && 
        		inputList[x].getAttribute('readonly') == 'readonly') {
        	
        	inputList[x].onclick = function() {
        		
                return false;
            };
        }
        x++;
    }
}



/*
**********************************************************
** Function for displaying the menu
**********************************************************
*/
function sfHover()
{
    var sfEls = document.getElementById("menuItems").getElementsByTagName("LI");
	for (var i = 0; i < sfEls.length; i++) {
		sfEls[i].onmouseover = function() {
			this.className = "sfhover";
		};
		sfEls[i].onmouseout = function() {
			this.className = "";
		};
	}
}

/*
**********************************************************
** Function to manage tips
**********************************************************
*/
function hideTips(link)
{
    link.style.display = "none";
    var brotherNodes = link.parentNode.childNodes;
    for (var i=0; i<brotherNodes.length; i++) {
        if (brotherNodes[i].className == 'hiddenTip') {
            brotherNodes[i].style.display = "block";
        } else if (brotherNodes[i].className == 'tip') {
            brotherNodes[i].style.display = "none";
        }
    }
    writeCookie("displayBgeeTip", "no");
}

function displayTips(link)
{
    link.parentNode.style.display = "none";
    var brotherNodes = link.parentNode.parentNode.childNodes;
    for (var i=0; i<brotherNodes.length; i++) {
        if (brotherNodes[i].className == 'tip') {
            brotherNodes[i].style.display = "block";
        } else if (brotherNodes[i].className == 'closeTip') {
            brotherNodes[i].style.display = "";
        }
    }
    deleteCookie("displayBgeeTip");
}

function loadTipEvents()
{
    var divList = document.getElementsByTagName("DIV");
    var tipState = readCookie("displayBgeeTip");
    for (var z=0; z<divList.length; z++) {
        if (divList[z].className == 'tip') {
			divList[z].style.display = "block";
            var closeTips = divList[z].getElementsByTagName("A");
            for (var y=0; y<closeTips.length; y++) {
                if (closeTips[y].className == 'closeTip') {
                    if (tipState == 'no') {
		                closeTips[y].style.display = "none";
		            }
                    closeTips[y].onclick=function() {
                        hideTips(this);
                        return false;
                    };
                }
            }

            var tipList = divList[z].getElementsByTagName("P");
            for (var i=0; i<tipList.length; i++) {
		        if (tipList[i].className == 'tip') {
		            if (tipState == 'no') {
		                tipList[i].style.display = "none";
		            }
		        } else if (tipList[i].className == 'hiddenTip') {
		            if (tipState != 'no') {
		                tipList[i].style.display = "none";
		            }
		            var openTips = tipList[i].getElementsByTagName("A");
		            for (var w=0; w<openTips.length; w++) {
		                if (openTips[w].className == 'displayTip') {
		                    openTips[w].onclick=function() {
		                        displayTips(this);
		                        return false;
		                    };
		                }
		            }
		        }
	        }
        }
	}
}

/*
**********************************************************
** Function to fade in and out
**********************************************************
*/

var fadedOutElems = "";
var fadingOutElems = "";
var fadingInElems = "";
var fadeInvertElems = "";

// makes an element start to fade in or out,
// or inverts it's fading direction if it was already fading
function fade(id, fadeTime, fadeMin, fadeMax)
{
	var e = document.getElementById(id);
	if (e == null) {
		return;
	}
	// if it is not an already fading element
	if(fadingInElems.indexOf(id) == -1 && fadingOutElems.indexOf(id) == -1) {
		// if it hasn't already faded out
		if (fadedOutElems.indexOf(id) == -1 && fadingOutElems.indexOf(id) == -1) {
			e.style.opacity = fadeMax;
            e.style.filter = "alpha(opacity=" + fadeMax*100 + ")";
			fadingOutElems += id + ";";
			animateFade("out", id, fadeTime, fadeMin, fadeMax);
		// if it has already faded out
		} else if (fadingInElems.indexOf(id) == -1){
			e.style.opacity = fadeMin;
            e.style.filter = "alpha(opacity=" + fadeMin + ")";
			e.style.color = "black";
			fadedOutElems = fadedOutElems.replace(id + ";", "");
			fadingInElems += id + ";";
			animateFade("in", id, fadeTime, fadeMin, fadeMax);
		}
	// if it's fading, adding it's id to inverting elements makes it fading direction invert
	} else {
		fadeInvertElems += id + ";";
	}
}

// function wich is called recursively to change step by step the fading state
function animateFade(inOrOut, id, fadeTime, fadeMin, fadeMax) 
{
	var e = document.getElementById(id);
	if (e == null) {
		return;
	}
	// if it's a fade in
	if (inOrOut == "in") {
		// and the element has not to change it's fading direction
		if (fadeInvertElems.indexOf(id) == -1) {
			e.style.opacity = new Number(e.style.opacity) + 0.1;
  			e.style.filter = "alpha(opacity=" + ((new Number(e.style.opacity) - 0.1)*100) + ")";
  			// if it's enough faded in, stop fading
			if (e.style.opacity >= fadeMax ||
				new Number(e.style.filter.replace("alpha(opacity=", "").replace(")", "")) >= fadeMax*100) {
				fadingInElems = fadingInElems.replace(id + ";", "");
				abstractEventFunction("fadeInEvent", e);
			// if not, make the loop again
			} else {
				setTimeout("animateFade('in', '" + id + "', " + fadeTime + ", " + fadeMin +
					", " + fadeMax + ");", 33*fadeTime);
			}
		// if it has to invert, invert the direction
		} else {
			document.getElementById("easySearchToolbar").innerHTML += "<br />inverting " + e.id +
				" from in to out!";
			fadingInElems = fadingInElems.replace(id + ";", "");
			fadingOutElems += id + ";";
			fadeInvertElems = fadeInvertElems.replace(id + ";", "");
			setTimeout("animateFade('out', '" + id + "', " + fadeTime + ", " + fadeMin +
					", " + fadeMax + ");", 33*fadeTime);
		}
	} else if (inOrOut == "out") {
		if (fadeInvertElems.indexOf(id) == -1) {
			e.style.opacity = new Number(e.style.opacity) - 0.1;
  			e.style.filter = "alpha(opacity=" + ((new Number(e.style.opacity) - 0.1)*100) + ")";
			if (e.style.opacity <= fadeMin ||
				new Number(e.style.filter.replace("alpha(opacity=", "").replace(")", "")) <= fadeMin) {
				fadingOutElems = fadingOutElems.replace(id + ";", "");
				fadedOutElems += id + ";";
				abstractEventFunction("fadeOutEvent", e);
			} else {
				setTimeout("animateFade('out', '" + id + "', " + fadeTime + ", " + fadeMin +
					", " + fadeMax + ");", 33*fadeTime);
			}
		} else {
			document.getElementById("easySearchToolbar").innerHTML += "<br />inverting " + e.id +
				" from out to in!";
			fadingOutElems = fadingOutElems.replace(id + ";", "");
			fadedOutElems = fadingOutElems.replace(id + ";", "");
			fadingInElems += id + ";";
			fadeInvertElems = fadeInvertElems.replace(id + ";", "");
			setTimeout("animateFade('in', '" + id + "', " + fadeTime + ", " + fadeMin +
					", " + fadeMax + ");", 33*fadeTime);
		}
	}
}

/*
**********************************************************
** Function to manage the automatic word completion
**********************************************************
*/

// loads the completion's event :
// - completion's request on typing in the completion's box
// - hiding the completion's results when clicking anywhere, but showing the results
//   again when clicking the completion's box. 
function loadCompletion() 
{
	var inputList = document.getElementsByTagName("input");
	var numbCompletionsActiveOnPage = 0;
	for (var i = 0; i < inputList.length; i++) {
		if (inputList[i].id != null && inputList[i].id.match("completionBox")) {
		
			inputList[i].onkeyup = function() {
				doCompletion(this.id.split("_")[1], 1);
			}
			inputList[i].onclick = function() {
				setCompletionsResultsVisible(this.id.split("_")[1], true);
			}
			document.onclick = function(event) {
				if (event != null && event.target != null && event.target.id != null &&
					event.target.id.indexOf("completionBox") == -1 &&
					event.target.id.indexOf("completionResultRow") == -1) {
					setCompletionsResultsVisible(null, false);
				}
			}
			numbCompletionsActiveOnPage++;
			loadDeleteCrossEvent(inputList[i].id.split("_")[1]);
	    }
	}  
}

// hides or shows the completion's results
function setCompletionsResultsVisible(nameCompletion, visible) 
{
	if (visible) {
		document.getElementById("completionResults_" + nameCompletion).className = "";
	} else {
		var divList = document.getElementsByTagName("div");
		for (var i = 0; i < divList.length; i++) {
			if (divList[i].id != null && divList[i].id.indexOf("completionResults_") != -1) {
				divList[i].className = "hidden";	
			}
		}
	}
}


// Add an event on every row of the completion's result list. 
// A click on a row fires an event to add this row to the selected results
function loadCompletionResultsRowEvent(nameCompletion) 
{
	var resultsParentDiv = document.getElementById("completionResults_" + nameCompletion);
	var results = null;
	// finding the right ul list containing the results rows
	if (resultsParentDiv) {
		for (var i = 0; i < resultsParentDiv.childNodes.length; i++) {
			if (resultsParentDiv.childNodes[i] != "#text") {
				results = resultsParentDiv.childNodes[i];
				break;
			}
		}
	}
	if (results) {
		var rows = results.rows;
		for (var y = 0; y < rows.length; y++) {
			var row = rows[y];
			//the header row has no id => no event
			if (row.id != null && row.id != "") {
				// if it's a row to get the next page of results, the next page's completion is required
				if (row.id == "completionNextPageRow_" + nameCompletion) {
					row.onclick = function() {
						document.getElementById("completionInfoPreviousSearch_" + nameCompletion).value = "";
						doCompletion(nameCompletion, 
							document.getElementById("completionNextPageNumber_" + nameCompletion).value);
					} 
					
				// if it's a row to get the previous page of results, the previous page's completion is required 
				} else if (row.id == "completionPreviousPageRow_" + nameCompletion) {
					row.onclick = function() {
						document.getElementById("completionInfoPreviousSearch_" + nameCompletion).value = "";
						doCompletion(nameCompletion, 
							document.getElementById("completionPreviousPageNumber_" + nameCompletion).value);
					}
					
				// if it's a real result row, we add it to the selected list
				} else {
					row.onclick = function() {
						addToSelectedResults(nameCompletion, this.id);
						abstractEventFunction("resultClick", this);
					}
				}
			}
		}
	}
}

// Add the event of deleting lines in the selected list to the small red crosses
function loadDeleteCrossEvent(nameCompletion) 
{
	var imageList = document.getElementsByTagName("img");
	for (var i = 0; i < imageList.length; i++) {
		if (imageList[i].id != null &&
			imageList[i].id.match("deleteCrossFor")) {
			
			// if the image is a delete cross for the selected results
			imageList[i].onclick = function() {
				removeFromSelectedResults(this.id);
				abstractEventFunction("deleteCrossClick", this);
			}
		}
	}
}

// adds a completion's result to the selected results. Returns a boolean telling if the result
// was added or not. (the result is not added in case if it's already selected)
function addToSelectedResults(nameCompletion, rowId) 
{
    var selRes = document.getElementById("completionSelectedResults_" + nameCompletion);
    var rows = selRes.rows;
    var resultId = rowId.replace("completionResultRowFor", "")
    			.replace("_" + nameCompletion, "");
    
    // check if the clicked row is not already in the selected table
    for (var i = 0; i < rows.length; i++) {
    	if (rows[i].id == rowId.replace("completionResultRowFor", "completionSelectedResultRowFor")) {
    		
    		if (rows[i].cells[1].getElementsByTagName("input")[0].checked) {
	    		//alert("This element [" + parseResultRowInfos("contentIfSelected", rowId, false) +
	    		//	"] is already selected !");
				//document.getElementById("completionBox_" + nameCompletion).focus();
				return false;
			} else {
				//rows[i].cells[1].getElementsByTagName("input")[0].checked = true;
				return true;
			}
    	}
    }
    
    var anyStructSelector = document.getElementById(nameCompletion + "_any_structures");
    var anyStruct = false;
    if (anyStructSelector) {
    	anyStruct = anyStructSelector.checked;
    } else if (nameCompletion.match(new RegExp(/anatomy\d/))) {
    	anyStruct = document.getElementById(
    		nameCompletion.replace("anatomy", "speciesOrgans_") + "_any_structures").checked;
    }
    
    // creating the row
	var newRow = selRes.insertRow(rows.length);
    newRow.id = rowId.replace("completionResultRowFor", "completionSelectedResultRowFor");
    
    var searchTypeCell = newRow.insertCell(0);
    searchTypeCell.className = "completionSelectedResultsSearchTypeColumn";
    if (rows.length == 1) {
    	searchTypeCell.innerHTML = "Search for";
    } else if (anyStruct) {
    	searchTypeCell.innerHTML = "OR";
    } else {
    	searchTypeCell.innerHTML = "AND";
    }
    
    var nameCell = newRow.insertCell(1);
    var inputNamePart = "";
    // if the inputs must have a name
    if (document.getElementById("completionInfoInputListName_" + nameCompletion)) {
    	inputNamePart = "name='" + document.getElementById(
    		"completionInfoInputListName_" + nameCompletion).value + "' ";
    }
    var content = parseResultRowInfos("contentIfSelected", rowId, false);
    var link = parseResultRowInfos("link", rowId, false);
    var title = parseResultRowInfos("title", rowId, false);
    if (!content) {
    	content = resultId;
    }
    if (!link) {
    	link = "";
    }
    if (!title) {
    	title = "id: " + resultId;
    }
    nameCell.innerHTML = "<input type='checkbox' value='" + resultId + "' " + inputNamePart +
    	"id='completionSelectedResult" + resultId + "_" + nameCompletion + "' checked='checked'>\n" +
		"<label title='" + title + "' for='completionSelectedResult" + resultId +
		"_" + nameCompletion + "'>" + content + "</label> " + link;
	
	var deleteCrossCell = newRow.insertCell(2);
	deleteCrossCell.innerHTML = "<img title='Delete' id='" +
		rowId.replace("completionResultRowFor", "deleteCrossFor") +
		"' alt='Delete' src='/bgee/images/cross_49.png'>";
    
 	loadDeleteCrossEvent(nameCompletion);
 	document.getElementById("completionBox_" + nameCompletion).value = "";
 	doCompletion(nameCompletion, 1);
 	
 	updateSearchJoin(nameCompletion);
    showHideCompletionSelectedResults(nameCompletion);
    
 	document.getElementById("completionBox_" + nameCompletion).focus();
 	
	return true;
}

// removes an element from the selected results.
function removeFromSelectedResults(selectedResultId)
{
	// take the last _[something] part of the id (which is ALWAYS the nameCompletion)
	var nameCompletion = selectedResultId.split("_")[selectedResultId.split("_").length - 1];
	var resultToRemove = document.getElementById(
		selectedResultId.replace("deleteCrossFor", "completionSelectedResultRowFor"));
	
	// if there is nothing to remove, stop now		
	if (!resultToRemove) {
		return;
	}	
	
	// delete the row in the table
	removeRow(document.getElementById("completionSelectedResults_" + nameCompletion), resultToRemove);
	fadeInvertElems = fadeInvertElems.replace(resultToRemove.id + ";", "");
	fadingOutElems = fadingOutElems.replace(resultToRemove.id + ";", "");
	fadingInElems = fadingInElems.replace(resultToRemove.id + ";", "");
	fadedOutElems = fadedOutElems.replace(resultToRemove.id + ";", "");
	
	updateSearchJoin(nameCompletion);
	showHideCompletionSelectedResults(nameCompletion);
	
    document.getElementById("completionBox_" + nameCompletion).focus();
}

// checks for search join (Search for/AND/OR) and uptades the selected results
function updateSearchJoin(nameCompletion)
{
	var rows = document.getElementById("completionSelectedResults_" + nameCompletion).rows;
	var jointureName = "";
	var anyStructSelector = document.getElementById(nameCompletion + "_any_structures");
    var anyStruct = false;
    if (anyStructSelector) {
    	anyStruct = anyStructSelector.checked;
    } else if (nameCompletion.match(new RegExp(/anatomy\d/))) {
    	anyStruct = document.getElementById(
    		nameCompletion.replace("anatomy", "speciesOrgans_") + "_any_structures").checked;
    } else if (nameCompletion == "gene") {
    	anyStruct = true;
    }
	
	for (var i = 0; i < rows.length; i++) {
		if (i == 0) {
			rows[i].cells[0].innerHTML = "Search for";
		} else if (anyStruct) {
			rows[i].cells[0].innerHTML = "OR";
		} else {
			rows[i].cells[0].innerHTML = "AND";
		}
	}
}

// shows or hides the completions selected results according wether there is some results or not
function showHideCompletionSelectedResults(nameCompletion)
{
	var rows = document.getElementById("completionSelectedResults_" + nameCompletion).rows;
	var selectedResults = document.getElementById("completionSelectedSection_" + nameCompletion);
	if (rows.length == 0) {
		selectedResults.className = selectedResults.className.replace(new RegExp("_hidden"), "");
		selectedResults.className += "_hidden";
	} else {
		selectedResults.className = selectedResults.className.replace(new RegExp("_hidden"), "");
	}
}

// retrieve the right info in the input associated with a row (specified by id).
// as there is two types of info inputs (from the result list or from the selected results list
// there is a boolean "fromSelected" to know if we have to search in the results or in the 
// selected results list
function parseResultRowInfos(infoName, id, fromSelected) {
	// filtering out from li or input element the organ's/hog's id to have a general id
	// in the format of : [id]_[anatomy|homoloy][count]
	var filteredId = id.replace(new RegExp("completion(Selected)?ResultRow(Infos)?For"), "");
	var infoInput;
	if (fromSelected) {
		infoInput = document.getElementById("completionSelectedResultRowInfosFor" + filteredId);
	} else {
		infoInput = document.getElementById("completionResultRowInfosFor" + filteredId);
	}
	if (infoInput && infoInput.value.match(new RegExp(infoName + ":=:.*?;"))) {
		var infos = infoInput.value;
		var searchedInfo = new String(infos.match(new RegExp(infoName + ":=:.*?;")))
			.split(":=:")[1].replace(";", "");
		return searchedInfo;
	} else {
		return null;
	}
}

// computes the informations for the completion, after checking if a request has to be sent
function doCompletion(nameCompletion, pageNumber) {
    var searchTerm = document.getElementById("completionBox_" + nameCompletion).value;
    var lastChars = document.getElementById("completionInfoPreviousSearch_" + nameCompletion).value;
    document.getElementById("completionInfoPreviousSearch_" + nameCompletion).value = searchTerm;
    
    // check if the query has changed since the last query
    if (lastChars != searchTerm) {
	    if (searchTerm.length == 0) {
			document.getElementById("completionInfoAff_" + nameCompletion).innerHTML =
				"Type 3 letters : ";
			document.getElementById("completionResults_" + nameCompletion).innerHTML = "";
		}
		else {			
			if (searchTerm.length < 3) {			
				document.getElementById("completionInfoAff_" + nameCompletion).className = "normalAff";		
				document.getElementById("completionInfoAff_" + nameCompletion).innerHTML =
					"-<div class='complSearchedTermStyle'>" + searchTerm;
				if (searchTerm.length == 1) {
					document.getElementById("completionInfoAff_" + nameCompletion).innerHTML += "..";
				} else {
					document.getElementById("completionInfoAff_" + nameCompletion).innerHTML += ".";
				}
				document.getElementById("completionInfoAff_" + nameCompletion).innerHTML += "</div>-";
				document.getElementById("completionResults_" + nameCompletion).innerHTML = "";
			}
			else {
				var data = "";
				if(document.getElementById("completionInfoToSendData_" + nameCompletion)) {
					data = document.getElementById("completionInfoToSendData_" + nameCompletion).value;
				}
				var url = "?page=search&" + data + "&search_name=" +
					encodeURIComponent(nameCompletion) + "&page_number=" + encodeURIComponent(pageNumber) +
					"&search=" + encodeURIComponent(searchTerm);
			    requestForCompletion(nameCompletion, url, searchTerm, pageNumber);
			    
	    	}
	    }
	}
}

// displays the completion's results
function requestForCompletion(nameCompletion, url, searchTerm, pageNumber) {
    var xhr = createXhr();    
    xhr.onreadystatechange  = function() {
		if (xhr.readyState == 4) {
			if (xhr.status == 200) {
				// inserting the text response from the server into the results div as HTML
				document.getElementById("completionResults_" + nameCompletion).innerHTML = xhr.responseText;
				setCompletionsResultsVisible(nameCompletion, true);
				var complResList = document.getElementById("completionResults_" + nameCompletion).childNodes[0];
				var nResultsFound = 0, resultsPerPage = 0, nResults = 0;
				if (complResList) {
					nResultsFound = document.getElementById("completionNResultsFound_" + nameCompletion).value;
					resultsPerPage = document.getElementById("completionNResultsPerPage_" + nameCompletion).value;
					nResults = document.getElementById("completionNResultsDisplayed_" + nameCompletion).value;
				}
				
				if (nResults > 0) {
				
					loadCompletionResultsRowEvent(nameCompletion);
					// displaying how many results, page numbers...
					document.getElementById("completionInfoAff_" + nameCompletion).className = "normalAff";
					if (nResults == 1) {
						document.getElementById("completionInfoAff_" + nameCompletion).innerHTML =
							"Found 1 result for -" +
							"<div class='complSearchedTermStyle'>" + searchTerm + "</div>-";
					} else {
						// displaying the number of results
						document.getElementById("completionInfoAff_" + nameCompletion).innerHTML =
							"Found " + nResultsFound + " results for -<div class='complSearchedTermStyle'>" +
							searchTerm + "</div>-";
						// displaying at which page we are, if there's more than one page
						if (nResultsFound > nResults) {
							if (nResultsFound - pageNumber*resultsPerPage > 0) {
								document.getElementById("completionInfoAff_" + nameCompletion).innerHTML +=
									", displayed results number " + ((pageNumber-1)*resultsPerPage + 1) +
									"-" + (pageNumber*resultsPerPage);
							} else {
								document.getElementById("completionInfoAff_" + nameCompletion).innerHTML +=
									", displayed results number " + ((pageNumber-1)*resultsPerPage + 1) + 
									"-" + nResultsFound;
							}
						}
					}
					// jumping to the right place on the page : no need to scroll down to results
					try {
						window.location.hash = "#completionPageLocation_" + nameCompletion;
					} catch (err) { }
					
					// calling the generic function
					abstractEventFunction("completionRequestRecieved", null);
					
					document.getElementById("completionBox_" + nameCompletion).focus();
				}
				// no results found
				else {
					document.getElementById("completionInfoAff_" + nameCompletion).className = "errorAff";
					document.getElementById("completionInfoAff_" + nameCompletion).innerHTML = 
						"No results found for -<div class='complSearchedTermStyle'>" + searchTerm + "</div>- !";
					document.getElementById("completionResults_" + nameCompletion).innerHTML = "";
				}
			// problems ! 
	        } else {			              	
				document.getElementById("completionInfoAff_" + nameCompletion).className = "errorAff";
		        document.getElementById("completionInfoAff_" + nameCompletion).innerHTML += 
		        	"Error! Request Failed (xhr.status:" + xhr.status + ")<br/ >";
	        }
		} else if (xhr.readyState == 0) {
			document.getElementById("completionInfoAff_" + nameCompletion).className = "errorAff";
			document.getElementById("completionInfoAff_" + nameCompletion).innerHTML = 
				"Error! Request Failed (xhr.readyState:" + xhr.readyState + ")<br/ >";
		}
	}		         
    xhr.open("GET", url,  true);
    xhr.send(null);
	// waiting message
	document.getElementById("completionInfoAff_" + nameCompletion).className = "normalAff";
	document.getElementById("completionInfoAff_" + nameCompletion).innerHTML =
		"Searching for -<div class='complSearchedTermStyle'>" + searchTerm + "</div>-...";
}

// the abstractEvent aims to make completion more generic by adding the possibility
// to call a function, which can be redefined, at different moment
// of the completion. These functions are "abstract" (must be redefined).
// the new functions must be added to the arrays and inside every funciton
// a check on the triggerer's id must be done (in order to functions of different
// element not to interfer with other's abstractEvent call).

var abstractFunctions = new Array();

function abstractEventFunction(event, triggerer)
{
	if (abstractFunctions[event]) {
		for (var i = 0; i < abstractFunctions[event].length; i++) {
			abstractFunctions[event][i].method(triggerer);
		}
	}	
}

function addNewAbstractFunction(event, func)
{
	if (!abstractFunctions[event]) {
		abstractFunctions[event] = new Array();
	}
	var alreadyIn = false;
	for (var i = 0; i < abstractFunctions[event].length; i++) {
		if (abstractFunctions[event][i].funcId == func.funcId) {
			alreadyIn = true;
		}
	}
	if (!alreadyIn) {
		abstractFunctions[event].push(func);
	}
}

function Func(id, func) {
	this.funcId = id;
	this.method = func;
}

/*
**********************************************************
** Functions to make the tabs interactive
**********************************************************
*/

function loadTabEvents() {
	var divList = document.getElementsByTagName("div");
	var divTabsRoot = null;
	for (var i = 0; i < divList.length; i++) {
		if (divList[i].className == "tabsRoot" || divList[i].className == "tabsRoot_hidden") {		
			var numTabSet = divList[i].id.split("_")[1];							
			var liList = document.getElementsByTagName("li");
			for (var y = 0; y < liList.length; y++) {
				if (liList[y].id.match("tabLink_" + numTabSet)) {					
					liList[y].onclick = function() {
						showTab(this.id);
					}
				}	
			}
		}
	}
	
}

function showTab(id) {
	
	var numTabSet = id.split("_")[1];
	var liList = document.getElementsByTagName("li");
	for (var i = 0; i <  liList.length; i++) {
		if (liList[i].className == "selected_tabSelector" &&
			liList[i].id.match("tabLink_" + numTabSet)) {
			
			 liList[i].className = "tabSelector";
		}	
	}
	document.getElementById(id).className = "selected_tabSelector";
	
	var newTabId = id.replace("tabLink", "tab");
	var divList = document.getElementsByTagName("div");
	for (var i = 0; i < divList.length; i++) {
		if (divList[i].className == "tabContent_shown" &&
			divList[i].id.match("tab_" + numTabSet)) {
			
			divList[i].className = "tabContent_hidden";
		}	
	}
	document.getElementById(newTabId).className = "tabContent_shown";
}

/*
**********************************************************
** Events to load, common to all pages
**********************************************************
*/

function loadCommonEvents()
{
    loadHidingEvents();
    loadHelpEvents();
    loadHidingTextEvents();
    disablesReadOnlyCheckboxes();
    sfHover();
    loadTipEvents();
    loadCompletion();
    if (document.getElementById('search')){
        document.getElementById('search').focus();
    }
}




