// XML reader

var XML_LOADING       = 1;
var XML_LOADED        = 2;
var XML_INTERACTIVE   = 3;
var XML_COMPLETE      = 4;
function XMLReader() {
	this.xmlhttp = null;

	if (window.XMLHttpRequest) {
		this.xmlhttp = new XMLHttpRequest();
	} else if (window.ActiveXObject) {
		try {
			this.xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
		} catch(e) {
			this.xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
		} 
	}

	if (this.xmlhttp == null) {
		return null;
	}
	this.handlers = new Array(5);
}
XMLReader.prototype.load = function (URL, async, asText) {
	this.asText = (asText) ? true : false;
	this.xmlhttp.open("GET", URL, async);
	var self = this;
	if (async) {
		this.xmlhttp.onreadystatechange = function() {
			self.callHandler(self);
		};
		this.xmlhttp.send(null);
	} else {
		this.xmlhttp.send(null);
		if (asText) {
			return this.xmlhttp.responseText;
		} else {
			return this.xmlhttp.responseXML;
		}
	}
}
XMLReader.prototype.callHandler = function (self) {
	if (self.handlers[self.xmlhttp.readyState]) {
		if (self.xmlhttp.readyState == XML_COMPLETE) {
			if (self.asText)
				self.handlers[self.xmlhttp.readyState](self.xmlhttp.responseText);
			else
				self.handlers[self.xmlhttp.readyState](self.xmlhttp.responseXML);
		} else {
			self.handlers[self.xmlhttp.readyState]();
		}
	}
}
XMLReader.prototype.setHandler = function (state, pointer) {
	this.handlers[state] = pointer;
}
XMLReader.prototype.clearHandlers = function () {
	for (var i=0; i < this.handlers.length; i++) this.handlers[i] = null;
}


// support functions

getSourceElement=function(e){
	if(e && e.target) return e.target;
	if(window.event && window.event.srcElement) return window.event.srcElement;
}

calculateLeft=function(object) {
	if (object) return object.offsetLeft + calculateLeft(object.offsetParent); 
	else return 0;
}

calculateTop=function(object) {
	if (object) return object.offsetTop + calculateTop(object.offsetParent); 
	else return 0;
}

AutoFill=function(obj,url){
	this.values=new Array;
	var self = this;
	if(document.getElementById(obj)){
		this.DOMObject=document.getElementById(obj);
		this.DOMObject.autoComplete="off";
		this.DOMObject.setAttribute("autocomplete","off");
		this.menuActive=false;
		// get data
		this.xml=new XMLReader();
		this.xml.setHandler(4,function(){self.initialise()});
		try {
			this.xml.load(url,true, false);
		} catch(ex){}
	}
}

AutoFill.prototype.initialise=function(){
	// cut up values
	if(!this.xml.xmlhttp.responseXML) return;
	this.loaded=1;
	var u=this.xml.xmlhttp.responseXML.getElementsByTagName("value");
	for(i=0;i<u.length;i++) {
		var val=u[i].childNodes[0].nodeValue;
		var firstChar=val.charAt(0).toLowerCase();
		if(!this.values[firstChar]){
			this.values[firstChar]=new Array();
		}
		this.values[firstChar].push(val);
	}		
	// prep text field
	var self=this;
	this.DOMObject.autocomplete=false;
	this.DOMObject.onfocus=function(){
		if (this.value == this.title) this.value = "";		
	}
	this.DOMObject.onkeyup=function(e){
		self.checkMatch(e);
	}
	this.DOMObject.onblur=function(){
		if(!self.menuActive) self.closeMenu();
		if (this.value == "") this.value = this.title;
	}
	// prep menu
	this.menu=document.createElement("select");
	this.menu.size=4;
	this.menu.multiple=false;
	this.menu.className="af-menu";
	this.menu.title="Maak uw keuze";
	this.menu.style.width=this.DOMObject.offsetWidth+"px";
	this.menu.onchange=
	this.menu.onfocus=function(e){
		self.menuActive=true;
		self.passChoice(this.value);
	}
	this.menu.onblur=
	this.menu.onblur=function(e){
		self.setFieldFocus();
		self.closeMenu();
	}
	this.menu.onmousedown=function(e){
		self.menuActive=true;
	}
	this.menu.onmouseup=function(e){
		if(getSourceElement(e).nodeName!="OPTION" && !window.event) return;
		self.setFieldFocus();
		self.closeMenu();
	}
	this.menu.onkeyup=function(e){
		// space, enter are special
		key=e ? e.keyCode : (window.event ? window.event.keyCode : null);
		if(key==32 || key==13 || key==27){
			self.setFieldFocus();
			self.closeMenu();
			return false;
		}
	}
	document.getElementsByTagName("body")[0].appendChild(this.menu);
	// prep iframe
	if(document.all){
		this.windowpatch=document.createElement("iframe");
		this.windowpatch.className="af-windowpatch";
		this.windowpatch.width=this.windowpatch.height="1";
		this.windowpatch.style.width=this.menu.offsetWidth+"px";
		this.windowpatch.style.height=this.menu.offsetHeight+"px";
		this.windowpatch.style.left=calculateLeft(this.DOMObject)+"px";
		this.windowpatch.style.top=calculateTop(this.DOMObject)+"px";
		document.getElementById("container").appendChild(this.windowpatch);
	}
}

AutoFill.prototype.destroy=function(){
	if(this.loaded) {
		this.DOMObject.autocomplete=
		this.DOMObject.onfocus=
		this.DOMObject.onkeyup=
		this.DOMObject.onblur=
		this.menu.onfocus=
		this.menu.onblur=
		this.menu.onmousedown=
		this.menu.onmouseup=null;
	}
}

AutoFill.prototype.checkMatch=function(e){
	
	// down, tab are special
	key=e ? e.keyCode : (window.event ? window.event.keyCode : null);
	if(key==0 || key==9) return;
	if((key==38 || key==40) && this.menu.className.match("show")) {
		this.menuActive=true;
		this.menu.focus();
		return false;
	}
	if(key==27){
		this.setFieldFocus();
		this.closeMenu();
		return false;
	}
	this.value=this.DOMObject.value.toLowerCase();
	
	// create matches array
	var inp=this.value.toLowerCase();
	var firstChar=inp.charAt(0);
	var charValues=this.values[firstChar]; 
	this.matches=new Array;
	for(var i=0;charValues&&i<charValues.length;i++){
		var txt=charValues[i].toLowerCase();
		if(txt.indexOf(inp)==0) this.matches[this.matches.length]=charValues[i];
	}
	this.renderMatches();
}

AutoFill.prototype.renderMatches=function(){
	var len=this.matches.length;
	if(len==0 || this.value.length<1) {
		ClassName.remove(this.menu,"show");
		if(this.windowpatch) ClassName.remove(this.windowpatch,"show");
		return;
	}
	this.menu.style.left=calculateLeft(this.DOMObject)+"px";
	this.menu.style.top=calculateTop(this.DOMObject)+"px";
	this.menu.style.width=this.DOMObject.offsetWidth+"px";
	ClassName.add(this.menu,"show");
	if(this.windowpatch) ClassName.add(this.windowpatch,"show");
	this.menu.innerHTML="";
	// fill menu with matches
	for(var i=0;i<len;i++){
		var opt=document.createElement("option");
		opt.value=opt.innerHTML=this.matches[i];
		if(i==0) opt.selected=true;
		this.menu.appendChild(opt);
	}
}

AutoFill.prototype.passChoice=function(val){
	this.DOMObject.value=val;
}

AutoFill.prototype.closeMenu=function(){
	this.menuActive=false;
	ClassName.remove(this.menu,"show");
	if(this.windowpatch) ClassName.remove(this.windowpatch,"show");
}

AutoFill.prototype.setFieldFocus=function(){
	this.menu.blur();
	this.DOMObject.focus();	
	this.DOMObject.select();
}

if (onloadHandler) onloadHandler.add(function() {
	new AutoFill("t4searchkey","http://karachi/projects/Aedesnet/html/tools/woordenboek/suggesties.xml");
});

