// autoSuggest object //
/**
* class autoSuggest - simple ajax class for dynamic suggestions loading
*
* @author Szymon Kosydor aka BuBi
* @link http://szymon.kosydor.pl
* 

przykłady:
		div.responses { position:absolute; display:none; }
		div.responses table { background-color:#FFFFFF; font-family:Verdana, Arial, Helvetica, sans-serif; font-size:11px; margin:0; padding:0; border:1px solid #FFCC33; width:200px}
		div.responses td {border-bottom:1px solid #FFCC33; cursor:hand}

		var as1 = new autoSuggest( 'client_name', 'client_id', 'autoResponser', '/dane.php' );

<input value="" id="client_name" name="client_name" type="text"/>
<input value="" id="client_id" name="client_id" type="hidden"/>
<div id="autoResponser" class="responses"></div>

<results>
	<rs id="123" info="abc">def</rs>
	...
</results>
*/

function autoSuggest( inputer, autoresponser ) {
	this.uri = '/ajax/';
	this.imageLoadingSrc = '/graph/loading.gif';
	this.backupStyle = '';
	this.blankColor = '#ffffff';
	this.highlightColor = '#CEDEFD';
	this.inputer = inputer;
	this.autoresponser = autoresponser;
	this.selectedId = 0;
	var as = this;
	this.as = as;
	this.tbl = null;
	this.cacheStr = '';
	this.resp = '';
	this.isResponser = false;
	this.cn = null;
	this.tick = null;
	this.addparam = '';
	this.action = 'auto_suggest';
	this.setAjaxVars();
}

autoSuggest.prototype.setAjaxVars = function() {
	cn = this.get( this.inputer );
	this.cn = cn;
	var as = this;
	this.isResponser = false;
	this.doInterval = true;
	this.cacheStr = cn.value;
	cn.onkillfocus = cn.onblur = function(e) { return as.onBlur( e ); }
	cn.onkeyup = function(e) { return as.onKeyUp( e ); }
}

autoSuggest.prototype.putHtml = function( str ) {this.get( 'info' ).innerHTML = str;}
autoSuggest.prototype.get = function( str ) {if( typeof( str ) == 'string' ) {return document.getElementById( str );} else if( typeof( str ) == 'object' ) {return str;} else {return false;}}
autoSuggest.prototype.hide = function( str ){var h = this.get( str );if( h != false ) {h.style.display = "none";}}
autoSuggest.prototype.show = function( str ) {var h = this.get( str );h.style.display = "block";}
autoSuggest.prototype.trim = function( s ) {s = this.trimLeft( s );s = this.trimRight( s );return s;}
autoSuggest.prototype.trimLeft = function( s ) {while( s.substring( 0, 1 ) == " " ){s = s.substr( 1 );}return s;}
autoSuggest.prototype.trimRight = function( s ) {while( s.charAt( s.length - 1 ) == " " ) {s = s.substr( 0, s.length - 1 );}return s;}
autoSuggest.prototype.highlight = function( elem ) {elem.style.background = this.highlightColor;}
autoSuggest.prototype.dehighlight = function( elem ) {elem.style.background = this.blankColor;}

autoSuggest.prototype.loadXMLString = function(txt) {
	try {
	  xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
	  xmlDoc.async = "false";
	  xmlDoc.loadXML( txt );
	  return( xmlDoc ); 
	} catch( e ) {
		try {
			parser = new DOMParser();
			xmlDoc = parser.parseFromString( txt,"text/xml" );
			return( xmlDoc );
		} catch( e ) {
			//alert(e.message)
		}
	} 
	return(null);
}

autoSuggest.prototype.useThis = function( val ) {
	this.get( this.inputer ).value = val;
	this.doInterval = false;
	this.hide( this.autoresponser );
	this.onSelected();
}
autoSuggest.prototype.onSelected = function(){}

autoSuggest.prototype.moveNextOnList = function() {
	if( this.selectedId > 0 ) {
		this.selectedId--;
	}
	this.renderList();
}
autoSuggest.prototype.movePrevOnList = function() {
	if( this.responseList.length > this.selectedId - 1 ) {
		this.selectedId++;
	}
	this.renderList();
}
autoSuggest.prototype.renderList = function() {
	for( var i in this.responseList ) {
		var cell = this.responseList[ i ];
		if( typeof( cell ) == 'object' ) {
			if( i == this.selectedId ){
				this.highlight( cell );
			} else {
				this.dehighlight( cell );
			}
		}
	}
}

autoSuggest.prototype.onBlur = function( e ) {
	ar = this.autoresponser;
	as = this;
	setTimeout( function() { as.hide( ar ); }, 300 );
}

autoSuggest.prototype.onKeyUp = function( e ) {
	if ( !e ) e = window.event;
	if ( !e ) return true;
	var key = (typeof e.keyCode != 'undefined' ? e.keyCode : e.charCode);
	var trimVal = this.trim( this.cn.value );		
	if ( ( key >= 48 && key <= 57) || ( key >= 65 && key <= 90 ) || ( key == 8 ) || ( key == 46 ) || ( key == 32 ) ){
		if( ( this.value != this.cacheStr ) && ( trimVal != '' ) ) {
			clearTimeout( this.tick );
			var as = this;
			this.tick = setTimeout( function() { as.checkAjax() }, 500 );
		} else if( this.trim( this.cn.value ) == '' ) {
			this.hide( this.autoresponser );
		}
	} else {
		switch( key ) {
			case 40: // strzalka w dol
				this.moveNextOnList();
				break;
			case 38: // strzalka w gore
				this.movePrevOnList();
				break;
			case 13: // ENTER
				this.useThis( this.responseList[ this.selectedId ].val );
				break;
		}
	}
}

autoSuggest.prototype.checkAjax = function() {
	if( !this.isResponser ) {
		this.cacheStr = this.cn.value;
		if( this.trim( this.cacheStr ) != '' ) {
			this.onSend();
			var as = this;
			var ajax = new myAjax();
			this.showLoader();
			ajax.uri = this.uri;
			ajax.action = this.action;
			var addStr = ( this.trim( this.addparam ) != '' ) ? '&'+this.addparam : '';
			ajax.post( 'q='+this.cacheStr+addStr );
			ajax.onLoad = function() { 
		
			as.resp = this.response; return as.onLoader(); }
		}
	}
}

autoSuggest.prototype.onLoad = function() { }
autoSuggest.prototype.onLoader = function() {
	this.isResponser = false;
	this.trav();
	this.hideLoader();
	this.onLoad();
}

autoSuggest.prototype.showLoader = function() {
	this.backupStyle = "#ffffff";
	this.cn.style.background = "url('"+this.imageLoadingSrc+"') right no-repeat #ffffff";
}

autoSuggest.prototype.hideLoader = function() {
	this.cn.style.background = this.backupStyle;
}

autoSuggest.prototype.trav = function() {
	var x 		= this.loadXMLString( this.resp );
	var results 	= x.getElementsByTagName( 'results' );
	var fc	 	= results[0].childNodes;
	if( fc.length > 0 ) {
		this.tbl 		= document.createElement( "table" );
		this.tbl.setAttribute( 'id', 'responseTable' );
		this.tbl.setAttribute( 'cellpadding', 2 );
		this.tbl.setAttribute( 'cellspacing', 0 );
		var tblBody = document.createElement("tbody");
		var l 		= fc.length;
		var i = 0;
		var dcs = this.cacheStr;
		this.responseList = new Array();
		while( i != l ) {
			var elem = fc[ i ];
			var att = elem.attributes;
	//		var id = elem.getAttribute( 'id' );
			var val = elem.childNodes[0].nodeValue;
//			this.putHtml( val );
			var row = document.createElement("tr");
			var cell = document.createElement("td");
			var s = val;
			s = s.split( dcs ).join( "<b>"+dcs+"</b>" );
			s = s.split( dcs.toUpperCase() ).join( "<b>"+dcs.toUpperCase()+"</b>" );
			s = s.split( dcs.toLowerCase() ).join( "<b>"+dcs.toLowerCase()+"</b>" );
			this.responseList.unshift( cell );
			this.selectedId = this.responseList.length;
			cell.innerHTML = s;
			cell.val = val;
	//		cell.valId = id;
			var as = this;
			cell.onmouseover = function() { as.highlight(this); };
			cell.onmouseout = function() { as.dehighlight(this); };
			cell.onclick = function() { as.useThis( this.val ); };
	
			row.appendChild(cell);
			tblBody.appendChild(row);
			i++;
		}
		this.tbl.appendChild( tblBody );
		var ar = this.get( this.autoresponser );
		while (ar.childNodes[0]) {
			ar.removeChild(ar.childNodes[0]);
		}
		ar.appendChild( this.tbl );
		this.show( this.autoresponser );
	} else {
		this.hide( this.autoresponser );
	}
}
