/*************************************************
id: autocomplete
version: 1.0 (beta 3)
modified: 2007.10.31
project: Moon (v. 2.1.1)
author: Audrius Naslenas, audrius@vpu.lt
*************************************************/

function autocomplete(inputObj,uri,divObj)
{
	eventAdd(window,'load',
		function (){
            if (typeof (inputObj) == "string") inputObj=$(inputObj);
			if (typeof (divObj) == "string") divObj=$(divObj);
			new autocompleteObject(inputObj,uri,divObj)
		}
	);
	return inputObj;
}

//user can defind events
//autocompleteObject.prototype.onSearchStart (find)
//autocompleteObject.prototype.onSearchEnd (responseText)
//autocompleteObject.prototype.onChoose (visibleHtml, commentContent)

function autocompleteObject(inputObj,uri,divObject)
{
	this.uri=uri;
	this.delimiter= typeof (autocompleteObject.delimiter) == "string" ? autocompleteObject.delimiter : ',';

    if (!divObject) {
		var _completeDiv=document.createElement("DIV");
		_completeDiv.id="autoSuggest";
		_completeDiv.style.display="none";
		_completeDiv.style.position="absolute";
		_completeDiv.style.width=(inputObj.clientWidth-2)+'px';
		document.body.appendChild(_completeDiv);
		divObject=$('autoSuggest');
  	}
	inputObj.setAttribute('autocomplete','off');
	this.inputObj = inputObj;
	this.caretPos=0;
	this._resultCache=new Object;
	this.showingWord='';
	this.divElm = new autocompleteDiv( divObject,this);
    inputObj._autoCompleteObj = this;
	this.ajax=new ajax('text/plain');
    this.ajax.outputToFunction(function (){inputObj._autoCompleteObj.getHTTP()});
    eventAdd(inputObj,'mousedown',this.inputEvent);
	eventAdd(inputObj,'keyup',this.inputEvent);
	eventAdd(inputObj,'blur',this.inputEvent);
	eventAdd(inputObj,'focus',this.inputEvent);
	eventAdd(inputObj,'keydown',this.inputEvent);
}

autocompleteObject.prototype.inputEvent=function(e)
{
    var e = typeof(e) == "undefined" ? window.event : e;
	var myObj=this._autoCompleteObj;
	var kCode=0;
    myObj.lastEvent = e.type;
	switch (e.type) {
	//case "focus":
	case "mousedown": myObj.show();	break;
    case "blur": myObj.divElm.hide(); break;
    case "keydown":
		kCode=e.keyCode;
		switch (kCode) {
		case 38: myObj.cancelEvent(e); myObj.divElm.updown('up'); break; //key up
		case 40: myObj.cancelEvent(e); myObj.divElm.updown('down'); break; //key down
		case 13: myObj.cancelEvent(e); myObj.divElm.updown('press'); break; //press
		}
    case "keyup":
		kCode=e.keyCode;
		switch (kCode) {
		case 38:  //key up
		case 40:  //key down
		case 13: myObj.cancelEvent(e); break; //press
		case 27: myObj.divElm.hide(); break; //Esc
		default:
				var delay = kCode==40 ? 0 : 1000; //no delay if keydown
				myObj.show(delay);
		}

	}
}

autocompleteObject.prototype.show=function(delay)
{
    if(this.lastEvent=='blur') return;
    if (this.started) clearTimeout(this.started);
	if (delay) {
		var me=this;
		this.started=setTimeout(function (){me.show()},delay);
    	return;
	}
    var find=this.getWord();
    if (find!='' && this.showingWord!=find) {
		this.showingWord=find;
		//$('debug').innerHTML=this.showingWord;
        var suggestions=this._resultCache[find];
    	if(typeof (suggestions) !="undefined") this.divElm.showdiv(suggestions);
    	else {
			if (typeof(this.onSearchStart)=="string") eval(this.onSearchStart+"(find)");
			else if (typeof(this.onSearchStart)=="function") this.onSearchStart(find);
            if(encodeURIComponent) find=encodeURIComponent(find);
  			else if(escape) find=escape(find);
			this.ajax.get(this.uri+find);
		}
	}
}

autocompleteObject.prototype.getHTTP=function()
{
	var http=this.ajax.http;
	if(http.readyState==4 && typeof(http.responseText)=="string") {
        var s=http.responseText;
		if (this.showingWord!='') this._resultCache[this.showingWord]=s;
        if (typeof(this.onSearchEnd)=="string") eval(this.onSearchEnd+"(s)");
		else if (typeof(this.onSearchEnd)=="function") this.onSearchEnd(s);
		this.divElm.showdiv(s) ;
	}
}

autocompleteObject.prototype.cancelEvent=function(e)
{
	if (navigator.appName == "Microsoft Internet Explorer") {
		e.returnValue = false;
		e.cancelBubble = true;
	} else if (e.preventDefault) e.preventDefault();
}


autocompleteObject.prototype.getWord=function()
{
	var pos=this.getCaretPos(this.inputObj);
	//$('debug').innerHTML=pos;
	var w=this.inputObj.value;
    if (this.delimiter!='') {
	    var p,p1=-1,p2=-1;
		do {
			p=w.indexOf(this.delimiter,p1);
			if (p!=-1) {
				if (p<pos) p1=p+1;
				else { p2=p; break;	}
			}
		} while (p!=-1);
		if (p2!=-1) w=w.substr(0,p2);
		if (p1!=-1) w=w.substr(p1);
	}
	return this.trim(w);
}

autocompleteObject.prototype.getCaretPos=function(ctrl)
{
	var CaretPos = 0;
	if (document.selection) {
		var Sel = document.selection.createRange ();
		Sel.moveStart ('character', -ctrl.value.length);
		CaretPos = Sel.text.length;
	} else if (ctrl.selectionStart || ctrl.selectionStart == '0')
		CaretPos = ctrl.selectionStart;
	return (CaretPos);
}

autocompleteObject.prototype.myChoise=function (txt)
{
	var reg=/<!(?:--([\s\S]*?)--\s*)?>\s*/g;
	var a=reg.exec(txt);
	var comment= (a && a.length>1) ? this.trim(a[1]) : '';
	a=reg.exec('');  //firefox workaround
	txt=this.trim( txt.replace(/<!(?:--[\s\S]*?--\s*)?>\s*/g,'') );
    if (typeof(this.onChoose)=="string") eval(this.onChoose+"(txt,comment)");
	else if (typeof(this.onChoose)=="function") this.onChoose(txt,comment);
	else {
		var w = comment=="" ?  txt : comment;
		this.inputObj.value =w.replace(/&lt;/,'<').replace(/&gt;/,'>').replace(/&amp;/,'&');
	}
}

autocompleteObject.prototype.trim=function (str)
{
	return str.replace(/\s+$/,"").replace(/^\s+/,"");
}

autocompleteObject.prototype.focus=function () //tik exploreriui reikia
{
	this.inputObj.focus();
    this.inputObj.value=this.inputObj.value;
}


// *********************  Div element ****************
getOffset = function(node, xORy) {
	var x=0,y=0;
	var parentNode = node;
	while (parentNode) {
		x += parentNode.offsetLeft;
		y += parentNode.offsetTop;
		parentNode = parentNode.offsetParent;
	}
	return (xORy=='y' ? y : x);
}


function autocompleteDiv(div,parent)
{
	this.parent=parent;
	this.obj=div;
	this.nr=0;
    this.obj.style.left= getOffset(this.parent.inputObj,'x')+'px';
	this.obj.style.top= (getOffset(this.parent.inputObj,'y')+this.parent.inputObj.clientHeight + 2)+'px';
	//this.obj.style.backgroundColor="red";
	this.ids=new Array();
}

autocompleteDiv.prototype.showdiv=function (txt)
{
    this.nr=0;
	if (txt=='') this.hide();
	else {
		this.obj.innerHTML=txt;
        var kiek=this.obj.childNodes.length;
		var count=0;
		this.ids=new Array();
		for (var i=0;i<kiek;i++) {
            tmpDiv=this.obj.childNodes[i];
			if (tmpDiv.tagName!="DIV") continue;
			tmpDiv.onmousedown=this.divEvent;
			tmpDiv.onmouseover=this.divEvent;
			tmpDiv.onmouseout=this.divEvent;
			tmpDiv.parent=this.parent;
			this.ids[count++]=i;
		}
    	if (this.ids.length) this.obj.style.display = 'block';
		else this.hide();
	}
}

autocompleteDiv.prototype.hide=function (txt)
{
	this.parent.showingWord="";
	this.obj.style.display = 'none';
}

autocompleteDiv.prototype.updown=function (action)
{
    var kiek=this.ids.length;
	if (!kiek) return;
    var nr=this.nr;
	if (action=="press") {
    	if (nr>0 && nr<=kiek)
			this.parent.myChoise(this.obj.childNodes[this.ids[nr-1]].innerHTML);
		this.hide();
		return;
	}
	if (nr>kiek) nr=kiek;
    if (action=='down' && nr<kiek) nr++;
	else if (action=="up" && nr>1) nr--;
	if (nr<1) nr=1;
	else if (nr>kiek) nr=kiek;
	for (var i=0;i<kiek;i++) this.obj.childNodes[this.ids[i]].className= i==(nr-1) ? 'ison' :'';
    this.nr=nr;
}

autocompleteDiv.prototype.divEvent=function (e)
{
    var divObj=this.parent.divElm;
	if (divObj.nr) {//nuvalom jei buvo su keyUp ar keyDown pazymetas
    	divObj.nr=0;
		var kiek=divObj.ids.length;
		for (var i=0;i<kiek;i++) divObj.obj.childNodes[divObj.ids[i]].className='';
	}
	e = typeof(e) == "undefined" ? window.event : e;
	switch (e.type) {
	case "mouseover": this.className = 'ison';	break;
    case "mouseout":  this.className = '';		break;
	case "mousedown":
		this.parent.myChoise(this.innerHTML);
		divObj.hide();
        if (navigator.appName == "Microsoft Internet Explorer") {
		     e.returnValue = false;
			 e.cancelBubble = true;
			 var me=this.parent;
			 setTimeout(function(){me.focus()},10);
		} else 	e.preventDefault();
		break;
	}
}