//Dropdown Menu functions
	timeoutIds = [];
	function finishHiding(id) {
		if ($(id) != null) {
			$(id).blindUp({ duration: 0.15 });
			//Opera doesn't clear the menus properly, so I have to make it redraw.
			timeoutIds[id] = setTimeout('operaCheck()', 150);
		}
	}

	function operaCheck() {
		//This is a hack to force opera to redraw the window.
		if (window.opera)
		   document.body.style += "";	// Force Opera redraw.
	}

	//Scrolls the menu down when the user hovers over it.
	function showMenu(id) {
		//Check to see if any close timeouts are pending and clear them.
		if(timeoutIds[id]) {
			clearTimeout(timeoutIds[id]);
		}
		
		//If display isn't none, the menu is either scrolling down or scrolled down.
		//We only want to scroll the menu down if it is fully closed.
		ThisElement = document.getElementById(id);
		if (ThisElement != null)  {
			ThisDisplay = ThisElement.style.display;
			if(ThisDisplay == "none") {
				//When the user moves across menus quickly the height can get messed up 
				//(causing the menu to only scroll partway down)
				//The sets it back to auto before trying to scroll then menu down again.
				ThisElement.style.height = 'auto';
				//scroll the blind down.
				$(id).blindDown({ duration: 0.15});
			}
		}
	}
	
	//Starts hiding the menu when the user leaves it.
	function hideMenu(id) {
		//The user will often pop out for a split second
		//To accomodate, the program waits a moment before scrolling the menu up.
		codeToExec = 'finishHiding("' + id + '");';
		timeoutIds[id] = setTimeout(codeToExec, 150);
	}
	
	// Browser Stuff
	function setForm() {
		var browser=navigator.appName;
		//if(browser != "Microsoft Internet Explorer"){ /* Browser sniffing is bad. You never saw this. */
			var s = document.getElementById('JumpToMenu');
			selectReplacement(s);
		
			document.onclick = function(){
				if(menuOpen == true){
					//alert("BODY");
					closeSel(menuLi);
				}
			}
		//}
	}
	
	function selectReplacement(obj) {
	obj.className += ' replaced';
	var ul = document.createElement('ul');
	ul.className =  'selectReplacement';
	var opts = obj.options;
	for (var i=0; i<opts.length; i++) {
		var selectedOpt;
		if (opts[i].selected) {
			selectedOpt = i;
			break;
		} else {
			selectedOpt = 0;
		}
	}
	for (var i=0; i<opts.length; i++) {
		var li = document.createElement('li');
		var txt = document.createTextNode(opts[i].text);
		li.appendChild(txt);
		li.selIndex = opts[i].index;
		if(i == opts.length-1){
			li.id += 'selectLast';
		}
		else if(i == 1){
			li.id += 'selectFirst';
		}
		li.selectID = obj.id;
		if(opts[i].value != -1){
			li.onclick = function(e) {
				//alert(this.selIndex);
				menuLi = li;
				menuOpen = false;
				//alert("1 - Select");
				selectMe(this);
			}
		}
		if (i == selectedOpt) {
			menuLi = li;
			li.className = 'selected';
			li.onclick = function(e) {
				//alert("2 - Open");
				this.parentNode.className += ' selectOpen';	
				
				this.onclick = function(e) {
					//alert("3 - Close");
					menuOpen = false;
					menuLi = this;
					selectMe(this);
				}
				popBubble(e);
				menuOpen = true;
			}
		}
		if (window.attachEvent) {
			li.onmouseover = function() {
				this.className += ' hover';
			}
			li.onmouseout = function() {
				this.className = 
				this.className.replace(new RegExp(" hover\\b"), '');
			}
		}
		ul.appendChild(li);
	}
	// add the input and the ul
	obj.parentNode.appendChild(ul);
}

function toggleDivDisplay(id){
	if (document.getElementById(id).style.display == 'block') document.getElementById(id).style.display = 'none';
	else document.getElementById(id).style.display = 'block';
}
/* Error backtrace JS */
function toggleBacktrace(id) {
	var myDiv = document.getElementById(id);
	if(myDiv.style.display == 'block')
		myDiv.style.display = 'none';
	else
		myDiv.style.display = 'block';
}


/*********************************/
/*******Select replacement********/
var menuOpen = false;
var menuLi;
function selectReplacement(obj) {
	obj.className += ' replaced';
	var ul = document.createElement('ul');
	ul.className =  'selectReplacement';
	var opts = obj.options;
	for (var i=0; i<opts.length; i++) {
		var selectedOpt;
		if (opts[i].selected) {
			selectedOpt = i;
			break;
		} else {
			selectedOpt = 0;
		}
	}
	for (var i=0; i<opts.length; i++) {
		var li = document.createElement('li');
		var txt = document.createTextNode(opts[i].text);
		li.appendChild(txt);
		li.selIndex = opts[i].index;
		if(i == opts.length-1){
			li.id += 'selectLast';
		}
		else if(i == 1){
			li.id += 'selectFirst';
		}
		li.selectID = obj.id;
		if(opts[i].value != -1){
			li.onclick = function(e) {
				//alert(this.selIndex);
				menuLi = li;
				menuOpen = false;
				//alert("1 - Select");
				selectMe(this);
			}
		}
		if (i == selectedOpt) {
			menuLi = li;
			li.className = 'selected';
			li.onclick = function(e) {
				//alert("2 - Open");
				this.parentNode.className += ' selectOpen';	
				
				this.onclick = function(e) {
					//alert("3 - Close");
					menuOpen = false;
					menuLi = this;
					selectMe(this);
				}
				popBubble(e);
				menuOpen = true;
			}
		}
		if (window.attachEvent) {
			li.onmouseover = function() {
				this.className += ' hover';
			}
			li.onmouseout = function() {
				this.className = 
				this.className.replace(new RegExp(" hover\\b"), '');
			}
		}
		ul.appendChild(li);
	}
	// add the input and the ul
	obj.parentNode.appendChild(ul);
}
function selectMe(obj) {
	var lis = obj.parentNode.getElementsByTagName('li');
	for (var i=0; i<lis.length; i++) {
		if (lis[i] != obj) { // not the selected list item
			lis[i].className='';
			objList = document.getElementById(obj.selectID);
			if(objList.options[i].value != -1){
				lis[i].onclick = function(e) {
						//alert("4 - Select");
						menuLi = this;
						menuOpen = false;
						selectMe(this);
				}
			}
		} else {
			setVal(obj.selectID, obj.selIndex);
			obj.className='selected';
			obj.parentNode.className = 
				obj.parentNode.className.replace(new RegExp(" selectOpen\\b"), '');
			obj.onclick = function(e) {
				//alert("5 - Open");
				menuLi = obj;
				obj.parentNode.className += ' selectOpen';
				this.onclick = function(e) {
					//alert("6 - Close");
					menuLi = this;
					menuOpen = false;					
					selectMe(this);
				}
				popBubble(e);
				menuOpen = true;
			}
		}
	}
}
function setVal(objID, selIndex) {
	var obj = document.getElementById(objID);

	if(obj.options[selIndex].value != -1){
		obj.selectedIndex = selIndex;
		obj.onchange()
	}
	else{
		newLi = menuLi.parentNode.getElementsByTagName('li');
		newLi = newLi[1];
		closeSel(newLi);
	}

}
function setForm() {
	var browser=navigator.appName;
	//if(browser != "Microsoft Internet Explorer"){ /* Browser sniffing is bad. You never saw this. */
		// var s = document.getElementById('JumpToMenu');
		// selectReplacement(s);
	
		document.onclick = function(){
			if(menuOpen == true){
				//alert("BODY");
				closeSel(menuLi);
			}
		}
	//}
}
function closeSel(obj) {
	if(obj.parentNode.className){
		obj.parentNode.className =	obj.parentNode.className.replace(new RegExp(" selectOpen\\b"), '');
		selectMe(obj);
	}
}


/* Listing JS --------------------------------------- */
var listings = new Array();var queries = new Array();var queryValues = new Array();
function listing(id,ctgs){this.id=id;this.ctgs=ctgs;}
function ctg(id,count){this.id=id;this.count=count;}

function listCat(listId, catId)
{
var list = document.getElementById(listId);var curChild = list.firstChild;
for (var i=0;curChild!=null;i++){if (i!=catId){ curChild.style.display = 'none'; } else { curChild.style.display = 'block'; }curChild = curChild.nextSibling;}
}
function listAll(listId)
{
var list = document.getElementById(listId); var curChild = list.firstChild;
for (var i=0;curChild!=null;i++){curChild.style.display = 'block';curChild = curChild.nextSibling;}
document.getElementById(listId + '_noresults').style.display='none';
}
function queryLists()
{
for (var i=0;i<listings.length;i++)
{
	var curValue = document.getElementById(queries[i]).value; var curValLen = curValue.length;
	if (curValue == 'Search this list'){ curValue = ''; } else { var lastChar = curValue.substring(curValLen - 1, curValLen); var nextLastChar = curValue.substring(curValLen - 2, curValLen - 1); var nextNextLastChar = curValue.substring(curValLen - 3, curValLen - 2);
	if (lastChar == 's' || lastChar == 'S') { curValue = curValue.substring(0, curValLen-1); } else if ((lastChar == 'g' || lastChar == 'G')  && (nextLastChar == 'n' || nextLastChar == 'N') && (nextNextLastChar == 'i' || nextNextLastChar == 'I')) { curValue = curValue.substring(0, curValLen-3);} 
	else { curValue = curValue.substring(0, curValLen); } } 
	if (curValue != queryValues[i]){ queryValues[i] = curValue; limitList(listings[i],curValue);}
}
setTimeout("queryLists();", 300);
}
function limitList(list,query)
{
/* parse the search query into an array */
if ((query.indexOf(" ") != -1) && (query.indexOf(" ") != (query.length -1))) { // if there is white space
	var searchterms = query.split(" "); // split on the white space
} else { // if no white space
	var searchterms = new Array(); // make the search terms be a 1-elt array
	searchterms[0] = query;
}
whiteSpace = /[ \t]/g; // create whitespace pattern
for (var a = 0; a < searchterms.length; a++) { searchterms[a].replace(whiteSpace, ""); } // grep for extra white space and kill it 


/* start doing the actual searching and results tabulation */
l = document.getElementById(list.id);
var countTotalMatch = countTotal = 0;	/* counters for total matches and total items in the list */
for(var i=0;i<list.ctgs.length;i++) {	/* foreach list category */
	var countByCtg = 0;					/* counter for matching items in category */
	for(var j=0;j<list.ctgs[i].count;j++){	/* loop through the expected ids of the elements, choosing whether to display based on content */
		var row = document.getElementById(list.id + '_ctg' + i + '_' + j);	/* get the item */
		var result = searchRow(row,searchterms);	/* do the query */
		if(!result){ row.style.display='none'; } else	/* show or hide matching/nonmatching elements, and increment category counter */
		{ row.style.display='block'; countByCtg++;}
	}
	var ctgdom = document.getElementById(list.id + '_ctg' + i);	/* if nothing in this category, hide the whole thing (including header) */
	if (countByCtg == 0){ctgdom.style.display='none';} else {ctgdom.style.display='block';}
	document.getElementById(list.id + '_ctg' + i + '_count').innerHTML = "(" + countByCtg + ")";	/* otherwise, set the count display in the header */
	countTotalMatch += countByCtg;	/* update total matches and total number */
	countTotal += list.ctgs[i].count;
}
var nores = document.getElementById(list.id + '_noresults');
if (countTotalMatch == 0){nores.style.display='block';} else {nores.style.display='none';}
var resultsString = countTotal + " items total";
if (query != ""){ resultsString += "; " + countTotalMatch + " match" + ((countTotalMatch==1) ? "" : "es") + " to your query"; }
document.getElementById(list.id + "query_results").innerHTML = resultsString;
}
function searchRow(obj,query)
{	
	var doesmatch = false; var rExp;
	for (var b=0; b<query.length; b++){
		rExp = new RegExp(query[b], "i");
		doesmatch = (doesmatch || getInnerText(obj).match(rExp));
	} return doesmatch;
}
/* this function taken from a sorting script by Mingyi Liu */
function getInnerText(el)
  {
  	if (typeof el == "string") return el;
  	if (typeof el == "undefined") { return el };
  	if (el.innerText) return el.innerText;	//Not needed but it is faster
  	var str = "";
  	
  	var cs = el.childNodes;
  	var l = cs.length;
  	for (var i = 0; i < l; i++) {
  		switch (cs[i].nodeType) {
  			case 1: //ELEMENT_NODE
  				str += getInnerText(cs[i]);
  				break;
  			case 3:	//TEXT_NODE
  				str += cs[i].nodeValue;
  				break;}}
  	return str;
  }

