/*
	elaborated from
	http://old.easy-designs.net/articles/replaceSelect/
	
	FacetBrowserLib is a combination of 
	FilterBox and FancySelector, to be found in 
	http://pike.kw.nl/browse/files/software/recent/javascript

	fire
	
*/


	


// Bridge XMLHTTP to XMLHttpRequest in pre-7.0 Internet Explorers

if( typeof XMLHttpRequest == "undefined" ) {
  XMLHttpRequest = function() {
	try { return new ActiveXObject("Msxml2.XMLHTTP.6.0"); } catch(e) {};
	try { return new ActiveXObject("Msxml2.XMLHTTP.3.0"); } catch(e) {};
	try { return new ActiveXObject("Msxml2.XMLHTTP"); }     catch(e) {};
	try { return new ActiveXObject("Microsoft.XMLHTTP"); }  catch(e) {};
 
	throw new Error("This browser does not support XMLHttpRequest or XMLHTTP.");
  };
}




/*
	base def
*/

var FacetBrowserLib = {
	debug				: false,
	benchmarks			: new Array(),
	ActiveTimers		: new Array(),
	ActiveRequests		: new Array(),
	RequestTimeout		: 60000,
	throttleTimer		: null,
	throttleTreshold	: 0,
	throttleTimeout		: 500,
	chunkTimers			: new Array(),
	chunkTreshold		: 500,
	chunkTimeout		: 1500,
	CurrentBrowserPop	: "",
	mouseX				: FBLibMouseX,
	mouseY				: FBLibMouseY,
	mouseLeaving		: FBLibMouseLeaving,
	showBrowserPop 		: FBLibShowBrowserPop,
	hideBrowserPop 		: FBLibHideBrowserPop,
	toggleBrowserPop 	: FBLibToggleBrowserPop,
	writeSelectors 		: FBLibWriteSelectors,
	writeSelector 		: FBLibWriteSelector,
	deselectValue		: FBLibDeselectValue,
	reset				: FBLibReset,
	toggleSelectors		: FBLibToggleSelectors,
	updateBrowser 		: FBLibUpdateBrowser,
	abortUpdate			: FBLibAbortUpdate,
	updateCallback		: FBLibUpdateCallback,
	drawFancySelector 	: FBDrawFancySelector,
	throttleFancySelector: FBThrottleFancySelector,
	chunkFancySelector : FBChunkFancySelector,
	selectLI			: FBLibSelectLI,
	selectOption		: FBLibSelectOption,
	drawFancySelectors 	: FBDrawFancySelectors
	
}

/* move to sitetools */

function FBLibMouseX(evt) {
	if (evt.pageX) return evt.pageX;
	else if (evt.clientX)
		return evt.clientX +  (document.documentElement.scrollLeft ?
			document.documentElement.scrollLeft :
			document.body.scrollLeft);
	else return null;
}
function FBLibMouseY(evt) {
	if (evt.pageY) return evt.pageY;
	else if (evt.clientY)
		return evt.clientY +  (document.documentElement.scrollTop ?
			document.documentElement.scrollTop :
			document.body.scrollTop);
	else return null;
}
function FBLibMouseLeaving(elm,event) {
	var tg = (window.event) ? event.srcElement : event.target;
	//alert(tg);
	if (tg != elm) return false;
	var reltg = (event.relatedTarget) ? event.relatedTarget : event.toElement;
	while (reltg != tg && reltg.nodeName != 'BODY'  && reltg.nodeName != 'HTML') {
		reltg= reltg.parentNode;
		if (reltg==elm) return false;
	}	
	return true;
}
function FBLibClickOutside(elm,event) {
	var target = (window.event) ? event.srcElement : event.target;
	if (target==elm) return false;
	while (target.nodeName != 'BODY'  && target.nodeName != 'HTML') {
		target= target.parentNode;
		if (target==elm) return false;
	}	
	return true;
}

/* ---------------------
	From SelectBox
 --------------------- */

function FBLibShowBrowserPop(id,event) {
	
	var x = FacetBrowserLib.mouseX(event);
	var y = FacetBrowserLib.mouseY(event);
	var elm = document.getElementById(id);
	if (elm) {
		elm.style.left=(x-20)+"px";
		// since click outside hides the current anyway,
		// this is not needed anymore
		// if (FacetBrowserLib.CurrentBrowserPop) FacetBrowserLib.hideBrowserPop();
		elm.style.display="block";
		// by default, fold open upward, but keep mouse inside
		var top = y-elm.offsetHeight+15;
		// unless that places the element outside of the screen,
		// then fold open downward, but keep mouse inside
		if (top<0) top = y-15;
		elm.style.top= top+"px";
		FacetBrowserLib.CurrentBrowserPop = id;
	}
	// clickoutside code
	if (document.addEventListener) {
	 	document.addEventListener ("mouseup",FBLibClickOutsideCurrent,false);
	} else if (document.attachEvent) {
	 	document.attachEvent ("onmouseup",FBLibClickOutsideCurrent);
	} else {
		//document.onmouseup= FBLibClickOutsideCurrent;
	}
 
}

function FBLibHideBrowserPop(id) {
	if (!id) id = FacetBrowserLib.CurrentBrowserPop;
	var elm = document.getElementById(id);
	if (elm) {
		elm.style.display="none";
		FacetBrowserLib.CurrentBrowserPop = "";
		// in this version, the search is not persistent.
		// search box emptied and pattern removed on close
		var selectelms = elm.getElementsByTagName('select');
		if (selectelms.length) {
			var selectid = selectelms[0].id;
			if (selectid) {
				var searchelm = document.getElementById(selectid+"_search");
				var fancyelm = document.getElementById(selectid+"_fancy");
				if (searchelm) searchelm.value = searchelm.getAttribute("default");
				if (fancyelm) fancyelm.setAttribute("pattern","");
				
			}
		}
	} 
	// clickoutside code
	if (document.removeEventListener) {
	 	document.removeEventListener ("mouseup",FBLibClickOutsideCurrent,false);
	} else if (document.detachEvent) {
	 	document.detachEvent ("onmouseup",FBLibClickOutsideCurrent);
	} else {
		//document.onmouseup= FBLibClickOutsideCurrent;
	}
	
}

function FBLibToggleBrowserPop(id,event) {
	// only hide the elm if we are really leaving the elm
	var elm = document.getElementById(id);
	if (elm) {
		//alert(elm.style.display);
		if (elm.style.display!="block") {
			FacetBrowserLib.showBrowserPop(id,event);
		} else {
			FacetBrowserLib.hideBrowserPop(id);
		}
	}
}

function FBLibClickOutsideCurrent(event) {
	var current = document.getElementById(FacetBrowserLib.CurrentBrowserPop);
	if (FBLibClickOutside(current,event)) {
		FacetBrowserLib.hideBrowserPop();
	}
}



function FBLibWriteSelectors(facetfilterid) {
	var facetfilterelm = document.getElementById(facetfilterid);
	if (facetfilterelm) {
		var selectors = facetfilterelm.getElementsByTagName('select');
		for (var sc=0;sc<selectors.length;sc++) {
			//for (var oc=0;oc<selectors[sc].options.length;oc++) {
				//selectors[sc].options[oc].selected=false;
			//}
			FacetBrowserLib.writeSelector(selectors[sc]);
		}
		if (!selectors.length) {
			if (FacetBrowserLib.debug) alert("debug: filter contains no selectors "+facetfilterid);
		}
	} else {
		if (FacetBrowserLib.debug) alert("debug: cant find facetfilter "+facetfilterid);
	}
}

function FBLibWriteSelector(selelm) {
	
	// find or create and wipe the outputdiv
	var outputdiv = document.getElementById(selelm.id+'_output');
	if (!outputdiv) {
		outputdiv = document.createElement('div');
		outputdiv.setAttribute('id',selelm.id+'_output');
		outputdiv.setAttribute('class',selelm.id+'selection');
		selelm.parentNode.parentNode.appendChild(outputdiv);
	}
	while (outputdiv.childNodes.length) {
		outputdiv.removeChild(outputdiv.childNodes[0]);
	}
	//alert(outputdiv);
	// loop the sel elm, and write a link for each selected option
	var comma = null;
	for (var sc=0; sc<selelm.options.length;sc++) {
		if (selelm.options[sc].selected) {
			//alert('selected');
			var span = document.createElement('span');
			span.setAttribute('class','nowrap');
			var link = document.createElement('a');
			link.setAttribute('href','javascript:FacetBrowserLib.deselectValue(\''+selelm.options[sc].value+'\',\''+selelm.id+'\')');
			link.appendChild(document.createTextNode('[\u2013] '));
			span.appendChild(link);
			if (selelm.options[sc].hasAttribute('href')) {
				var link = document.createElement('a');
				link.setAttribute('href',selelm.options[sc].getAttribute('href'));
				link.setAttribute('target','_blank');
				link.appendChild(document.createTextNode(selelm.options[sc].text));
				span.appendChild(link);
			} else {
				span.appendChild(document.createTextNode(selelm.options[sc].text));
			}
			if (comma) outputdiv.appendChild(comma);
			outputdiv.appendChild(span);
			comma = document.createTextNode(', ');
		}
	}
	
}


function FBLibDeselectValue(value,selelmid) {
	var selector = document.getElementById(selelmid);
	var changed = false;
	for (var oc=0;oc<selector.options.length;oc++) {
		if (selector.options[oc].value==value) {
			if (selector.options[oc].selected) {
				selector.options[oc].selected=false;	
				changed = true;
			}
		}
	} 
	if (changed && selector.onchange) selector.onchange();	
	if (changed && FacetBrowserLib) FacetBrowserLib.drawFancySelector(selector);						
}


function FBLibReset(facetfilterid) {
	var facetfilterelm = document.getElementById(facetfilterid);
	if (facetfilterelm) {
		facetfilterelm["Phrase"].value = facetfilterelm["DefPhrase"].value;
		var selectors = facetfilterelm.getElementsByTagName('select');
		for (var sc=0;sc<selectors.length;sc++) {
			var changed = false;
			for (var oc=0;oc<selectors[sc].options.length;oc++) {
				if (selectors[sc].options[oc].selected) {
					selectors[sc].options[oc].selected=false;
					changed=true;
				}
				if (selectors[sc].options[oc].disabled) {
					selectors[sc].options[oc].disabled=false;
					changed=true;
				}
			}
			if (changed) {
				FacetBrowserLib.drawFancySelector(selectors[sc]);
				FacetBrowserLib.writeSelector(selectors[sc]);
			}
		}
		FacetBrowserLib.updateBrowser(facetfilterid);
	}
}

function FBLibToggleSelectors(facetfilterid) {
	var facetfilterelm = document.getElementById(facetfilterid);
	if (facetfilterelm) {
		var selectors = facetfilterelm.getElementsByTagName('select');
		for (var sc=0;sc<selectors.length;sc++) {
			selectors[sc].style.display=(selectors[sc].style.display=="block")?"none":"block";
		}
	}			
}


/* 
	xmlhttp stuff. to update the browser, we send an ajax request
	to /[ext]/ajaxfacetfilter (this is defined in the
	calling facetbrwoser form). this returns xml to display 
	- how many 'remaining' nodes are currently related to the selected facets
	- which 'remaining' facets can be selected, based on those nodes
	
	this allows the widget to disable any facets that would return
	zero results *if* you were to you this facetbrowser as a filter
	(for 'faceted browsing'). note, you may not really need this in
	elements that are not used for faceted browsing (eg not when using
	the facetbrowser in 'edit forms' of nodes that contain facets). 
	
	this method is called in the "onchange" event of a "select" 
	element in the facetbrowser form - so can remove it where you
	dont need it.
	
*/

function FBLibUpdateBrowser(facetfilterid) {


	var facetfilterelm = document.getElementById(facetfilterid);
	if (facetfilterelm) {

		// create query (topNodeID,facetTopNodeID,facetObjectIDs)
		
		var query = facetfilterelm["AjaxCallbackURL"].value;
		if (query) {
			query += "?TopNodeID="+facetfilterelm["TopNodeID"].value;
			query += "&FacetTopNodeID="+facetfilterelm["FacetTopNodeID"].value;
			var selectors = facetfilterelm.getElementsByTagName('select');
			for (var sc=0;sc<selectors.length;sc++) {
				for (var oc=0;oc<selectors[sc].options.length;oc++) {
					if (selectors[sc].options[oc].selected) {
						query += "&FacetObjectIDs[]="+selectors[sc].options[oc].value;
					}				
				}
			}
			if (facetfilterelm["Phrase"] && facetfilterelm["Phrase"].value!=facetfilterelm["DefPhrase"].value) {
				query += "&Phrase="+facetfilterelm["Phrase"].value;
			}
			if (facetfilterelm["classnames"] && facetfilterelm["classnames"].value!="") {
				query += "&classnames="+facetfilterelm["classnames"].value;
			}
			if (facetfilterelm["classfilter"] && facetfilterelm["classfilter"].value!="") {
				query += "&classfilter="+facetfilterelm["classfilter"].value;
			}
			if (facetfilterelm["attrfilter"] && facetfilterelm["attrfilter"].value!="") {
				query += "&attrfilter="+facetfilterelm["attrfilter"].value;
			}
			
			// abort if there's already a request
			FacetBrowserLib.abortUpdate(facetfilterid);

			var request =  new XMLHttpRequest();
			request.open("POST", query, true);
			request.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
			
			// the scope of an anonymous function is a bit weird
			// check the that=this examples online. it works.
			
			request.onreadystatechange = function() {
				if (request.readyState == 4) {
					//if (request.status == 200) {
						// note .. mozilla is known to lose responseXML on some conditions:
						// http://www.quirksmode.org/blog/archives/2005/09/xmlhttp_notes_a_1.html
						if (request.responseXML) {
							FacetBrowserLib.updateCallback(facetfilterid,request.responseXML);
						} else {
							if (FacetBrowserLib.debug) alert('debug: ajax response not in expected format ');
							FacetBrowserLib.abortUpdate(facetfilterid);
						}
					//}
				}
			};
			
			request.send(null); 
			
			// feedback
			var feedbackelm = document.getElementById(facetfilterid+"_feedback");
			if (feedbackelm) feedbackelm.innerHTML = facetfilterelm["PendingResultsMsg"].value;
			
			// benchmark
			if (FacetBrowserLib.debug) FacetBrowserLib.benchmarks = {"requestsend":(new Date()).getTime()};
			// start timeout
			FacetBrowserLib.ActiveRequests[facetfilterid] = request;
			FacetBrowserLib.ActiveTimers[facetfilterid] = setTimeout(
				"FacetBrowserLib.abortUpdate('"+facetfilterid+"')",FacetBrowserLib.RequestTimeout); 
			
		} else {
			if (FacetBrowserLib.debug) alert('debug: cant find callback url in '+facetfilterid);
		}
	} else {
		if (FacetBrowserLib.debug) alert('debug: cant find filter '+facetfilterid);
	}
}

function FBLibAbortUpdate(facetfilterid){
	// abort if there's already a request
	if (FacetBrowserLib.ActiveRequests[facetfilterid]) {
		if (FacetBrowserLib.debug) {
			alert('debug: aborting running ajax request for '+facetfilterid);
			FacetBrowserLib.benchmarks = new Array();		
		}
		FacetBrowserLib.ActiveRequests[facetfilterid].onreadystatechange = function () {}
		FacetBrowserLib.ActiveRequests[facetfilterid].abort();
		FacetBrowserLib.ActiveRequests[facetfilterid] = null;
	}
	if (FacetBrowserLib.ActiveTimers[facetfilterid])
		clearTimeout(FacetBrowserLib.ActiveTimers[facetfilterid]);
	// feedback
	var feedbackelm = document.getElementById(facetfilterid+"_feedback");
	if (feedbackelm) feedbackelm.innerHTML = "";


}

function FBLibUpdateCallback(facetfilterid,xmlDoc) {
	//alert('callback');
	// parse result (topNodeID,facetTopNodeID,revDisabledNodeIDs)
	// loop all selectors
	// 	disable any if needed
	//alert(xmlDoc);
	
	// end timeout
	FacetBrowserLib.ActiveRequests[facetfilterid] = null;
	clearTimeout(FacetBrowserLib.ActiveTimers[facetfilterid]);
	
	var remainingoids = new Array(); 
	var numremaining = 0;
	
	if (FacetBrowserLib.debug) FacetBrowserLib.benchmarks["responsereceived"] = (new Date()).getTime();
	
	if (xmlDoc) {
		
		if (FacetBrowserLib.debug) FacetBrowserLib.benchmarks["xmlparsed"] = (new Date()).getTime();
		
		
		// parse xml
		
		var resnodes = xmlDoc.getElementsByTagName('remainingFacetObjectIDs');
		//alert(resnodes.length);
		if (resnodes[0]) {
			var remainnodes=resnodes[0].getElementsByTagName('objectID');
			//alert(remainnodes.length);
			for (var nc=0;nc<remainnodes.length;nc++) {
				var remainingoid = remainnodes[nc].childNodes[0].nodeValue;
				//alert(remainingoid);
				remainingoids[parseInt(remainingoid)]=true;
			}
		} else {
			// no result
			var errnodes = xmlDoc.getElementsByTagName('error');
			if (errnodes.length) {
				if (FacetBrowserLib.debug) alert("error: "+remainnodes[nc].errornodes[0].nodeValue);
			} else {
				if (FacetBrowserLib.debug) alert("debug: no results");
			}
		}
	
		var facetfilterelm = document.getElementById(facetfilterid);
		if (facetfilterelm) {
		
			// feedback
			var feedbackelm = document.getElementById(facetfilterid+"_feedback");
			if (feedbackelm) {
				var	countnodes = xmlDoc.getElementsByTagName('numRemainingNodes');
				if (countnodes.length) {
					if (countnodes[0].childNodes[0].nodeValue) {
						feedbackelm.innerHTML = facetfilterelm["ResultsMsg"].value.replace('%',countnodes[0].childNodes[0].nodeValue);
					} else {
						feedbackelm.innerHTML = facetfilterelm["ZeroResultsMsg"].value;
					}
				} else {
					feedbackelm.innerHTML = "";
				}
			}
			
			// store parsed xml
			
			var selectors = facetfilterelm.getElementsByTagName('select');
			var selectorsChanged = new Array();
			for (var sc=0;sc<selectors.length;sc++) {
				//alert('b');
				var changed = false;
				for (var oc=0;oc<selectors[sc].options.length;oc++) {
					
					if (!remainingoids[selectors[sc].options[oc].value]) {
						// disable option
						if (!selectors[sc].options[oc].getAttribute("disabled")) {
							selectors[sc].options[oc].setAttribute("disabled","true");
							selectors[sc].options[oc].setAttribute("title",facetfilterelm["ZeroResultsMsg"].value);
							changed = true;
						} 
					} else {
						//enable option
						if (selectors[sc].options[oc].getAttribute("disabled")) {
							selectors[sc].options[oc].removeAttribute("disabled");
							selectors[sc].options[oc].removeAttribute("title");
							changed = true;
						}
					}
				}
				selectorsChanged[sc] = changed;
				
			}
		
		
			if (FacetBrowserLib.debug) FacetBrowserLib.benchmarks["selectorschanged"] = (new Date()).getTime();
			
			// now rewrite the changed selectors
			for (var cc=0;cc<selectors.length;cc++) {
				if (selectorsChanged[cc]) {
					FacetBrowserLib.drawFancySelector(selectors[cc]);
				}
			}
			if (FacetBrowserLib.debug) {
				FacetBrowserLib.benchmarks["selectorsdrawn"] = (new Date()).getTime();
				alert(
					"debug:\n"+
					"responsereceived\t@"+(FacetBrowserLib.benchmarks["responsereceived"]-FacetBrowserLib.benchmarks["requestsend"])+"msecs\n"+
					"xmlparsed\t@"+(FacetBrowserLib.benchmarks["xmlparsed"]-FacetBrowserLib.benchmarks["requestsend"])+"msecs\n"+
					"selectorschanged\t@"+(FacetBrowserLib.benchmarks["selectorschanged"]-FacetBrowserLib.benchmarks["requestsend"])+"msecs\n"+
					"selectorsdrawn\t@"+(FacetBrowserLib.benchmarks["selectorsdrawn"]-FacetBrowserLib.benchmarks["requestsend"])+"msecs\n"
				);
			}
			
		} else {
			if (FacetBrowserLib.debug) alert("debug: can't find facetfilter "+facetfilterid);
		}

	} else {
		if (FacetBrowserLib.debug) alert("debug: ajax returned no xml document");
	}
	

	
}

/* ---------------------
	From FancySelector:
 --------------------- */

// this is called from the interactive search
// it stalls the command a bit, waiting for you to type more

function FBThrottleFancySelector(selobj,pattern) {
	if (!pattern || pattern.length> this.throttleTreshold) {
	
		if (this.throttleTimer) clearTimeout(this.throttleTimer);
		if (this.chunkTimers[selobj.id]) {
			clearTimeout(this.chunkTimers[selobj.id]);
		}
		//alert('timing');
		this.throttleTimer = setTimeout(
			"FacetBrowserLib.drawFancySelector(document.getElementById(\""+selobj.id+"\"),\""+pattern+"\")",
			this.throttleTimeout
		);
	} 
}

// this will be called on huge select boxes
// to prevent 'unresponsive script' stuff. it chunks the
// drawing with delays in between if needed

function FBChunkFancySelector(selobj,pattern,offset,limit) {
	
	if (this.chunkTimers[selobj.id]) {
		clearTimeout(this.chunkTimers[selobj.id]);
	}
	
	var max = selobj.options.length;
	if (!offset) offset = 0;
	if (!limit) limit = Math.min(max,this.chunkTreshold);
	if (!pattern) pattern='';
	this.drawFancySelector(selobj,pattern,offset,limit);
	
	if (offset+limit<max) {
		this.chunkTimers[selobj.id] = setTimeout(
			"FacetBrowserLib.chunkFancySelector(document.getElementById(\""
				+selobj.id+"\"),\""+pattern+"\","
				+(offset+limit)+","+limit+")",this.chunkTimeout
		);
	}
	return true;
}

function FBDrawFancySelector(selobj,pattern,offset,limit) {

	if (FacetBrowserLib.debug) alert("drawFancySelector "+selobj.id);

	var selopts = selobj.options;
	if (!offset) 	offset = 0;
	if (!limit) 	{
		if (selopts.length>this.chunkTreshold) {
			// this thing is too big to do at once: chunk it
			return this.chunkFancySelector(selobj,pattern);
		} 
		var chunking = false;
	} else {
		var chunking = true;
	}
	
	var size = selobj.getAttribute('size');
	if (!size) size=1;
	
	
	
	var currentul = document.getElementById(selobj.id+'_fancy');
	if (currentul) {
		// make pattern persistent
		oldpattern = currentul.getAttribute('pattern');
		if (pattern || pattern==='') currentul.setAttribute('pattern',pattern);
		else {
			if (oldpattern) pattern = oldpattern;
		}
	}
	
	// this can happen with the throttle:
	if (pattern && pattern==oldpattern && !chunking) {
		//alert('nothing changed afaik');
		return true;
	}
	
	//alert(pattern+":"+oldpattern);
	
	// regexp from pattern or fail
	if (pattern) {
		//alert(pattern);
		try {
			var rxstring = "("+pattern+")";
			//alert(rxstring);
			var rxpattern = new RegExp(rxstring,"i");
			//alert(pattern);
		} catch (e) {
			//alert("err" +pattern);
			var rxpattern = null;
			pattern=null;	
		}
	} else {
		var rxpattern = null;
	}	
	
	if (currentul) {
	
		// if we are refining a search, we dont have to redraw the whole 
		// thing, just remove nonmatching items from the existing list.
		// to speed things up, this code is here:
		
		if (pattern && oldpattern && !chunking) {

			if (pattern.indexOf(oldpattern)!=-1) {
				//alert('refining '+pattern);
				for (var cc=0;cc<currentul.childNodes.length;cc++) {
					var text = currentul.childNodes[cc].childNodes[0].nodeValue;
					if (!text.match(rxpattern)) {
						currentul.removeChild(currentul.childNodes[cc]);
						cc--; 
					} 
				}
				// thats all
				return true;
			}
			
		}
		
		// else remove all items and write all again
		if (!chunking || offset==0) {
			while (currentul.childNodes.length) {
				currentul.removeChild(currentul.childNodes[0]);
			}
		}
		
		ul = currentul;
		
		// set selectbox, close any open popup
		if (size>1) {
			if (ul.className.indexOf("fancySelectBox")==-1) ul.className += " fancySelectBox ";
		} else {
			if (ul.className.indexOf("fancySelectPopOpen")==-1) ul.className += " fancySelectPop ";
			else ul.className = ul.className.replace(new RegExp("fancySelectPopOpen"), 'fancySelectPop');
		}
		
	} else {
		// else create brand new list
		ul = document.createElement('ul');
		ul.setAttribute('id',selobj.id+'_fancy');
		if (size>1) ul.className = 'fancySelectBox ';
		else ul.className = 'fancySelectPop ';
	}
	

	if (selobj.className.indexOf("replaced")==-1) selobj.className += ' replaced';
	
	//alert('drawing '+offset+':'+Math.min(selopts.length,offset+limit));
	if (!chunking) limit=selopts.length;
	for (var i=offset; i< Math.min(selopts.length,offset+limit); i++) {
		if (!rxpattern || selopts[i].text.match(rxpattern)) {
		
			var li = document.createElement('li');
			var txt = document.createTextNode(selopts[i].text);
			//alert('attach '+txt.textContent);
			li.appendChild(txt);
			li.selIndex = selopts[i].index;
			li.selectID = selobj.id;
			
			/* inherit classes from select elm */
			if (selopts[i].className) li.className = selopts[i].className;
			/* inherit title from select elm */
			if (selopts[i].getAttribute("title")) li.setAttribute("title",selopts[i].getAttribute("title"));
			if (selopts[i].selected) li.className += ' selected';

			if (size>1) {
									
				if (!selopts[i].getAttribute("disabled")) {
					
					li.onclick = function() {
						FacetBrowserLib.selectLI(this);
					}
					
				} else {
					li.className += ' disabled';
				}

			} else {
					
				/* single select pop */
				
				if (!selopts[i].selected) {		
						
					if (!selopts[i].getAttribute("disabled")) {
						li.onclick = function() {
							FacetBrowserLib.selectLI(this);
							//this.parentNode.className = 
							//	this.parentNode.className.replace(new RegExp("fancySelectPopOpen"), 'fancySelectPop');
						}
					} else {
						li.className += ' disabled';
					}
				
				} else {

					// selected selectpop should open when you click this element,
					// and change its own onclick if not disabled.
					if (size<=1) {
						if (selopts[i].getAttribute("disabled")) {
							li.onclick = function() {
								//alert(this.parentNode.className);
								this.parentNode.className = 
									this.parentNode.className.replace(new RegExp("fancySelectPop"), 'fancySelectPopOpen');
								//alert(this.parentNode.className);
								//this.parentNode.className += ' fsopen';
							}
						} else {
							li.onclick = function() {
								//alert(this.parentNode.className);
								this.parentNode.className =
									this.parentNode.className.replace(new RegExp("fancySelectPop"), 'fancySelectPopOpen');
								//alert(this.parentNode.className);
								//this.parentNode.className += ' fsopen';
								this.onclick = function() { selectLI(this); }
							}
						}
						
					}
					
				}
				
			}
			
			// if its not disabled, it should have hover effect
			if (!selopts[i].getAttribute("disabled")) {
				if (window.attachEvent) {
					li.onmouseover = function() {
						this.className += ' hover';
					}
					li.onmouseout = function() {
						this.className = 
							this.className.replace(new RegExp(" hover\\b"), '');
					}
				}
			}
				
			ul.appendChild(li);
			
		} else {
			// element text doesnt match pattern
		}
		
		
		
	} // loop for all elements
	//alert('done chunk '+ul.childNodes.length);
	if (!currentul) selobj.parentNode.appendChild(ul,selobj);
}

function FBLibSelectLI(lielm) {
	var ulelm = lielm.parentNode;
	var ulid = ulelm.getAttribute('id');
	var selelmid = ulid.substring(0,ulid.length-6);
	//alert(selelmid);
	var selelm = document.getElementById(selelmid);
	if (selelm) {
		FacetBrowserLib.selectOption(selelm,lielm);
		FacetBrowserLib.drawFancySelector(selelm);
	}
}

function FBLibSelectOption(selelm,lielm) {
	selelm.options[lielm.selIndex].selected=!selelm.options[lielm.selIndex].selected;
	if (selelm.onchange) selelm.onchange();
}

function FBDrawFancySelectors(topelmid) {
	if (!topelmid) selectors = document.getElementsByTagName('select');
	else {
		var topelm = document.getElementById(topelmid);
		if (topelm) {
			var selectors = topelm.getElementsByTagName('select');
			for (var sc=0; sc<selectors.length; sc++) {
				FacetBrowserLib.drawFancySelector(selectors[sc]);
			}
		}
	}
}
