
	var AutoEntry = Class.create();

	AutoEntry.prototype = {
	
		name: "AutoEntry",
		description: "Given a text input field and a PHP script name, creates a dropdown list beneath the text input field, and populates that field on the fly with data returned by the supplied PHP script which matches the text entered",
		version: "0.1a",
		author: "scott@printelectric.com",
		count: 0,
		
		initialize: function($inputfield, $confpath, $table, $datafield) {
			
			this.loadStyle();
					
			this.$ui = "";
			this.$keys = {};
			this.$keys.shift = 0;
			this.$selected = -1;
		
			/* testing - may need to replace with AutoEntry.prototype.count... this would be more portable if it works */
			AutoEntry.prototype.count++;
			
			/* we have no way of double-checking the $confpath here -
				all verification will have to be done via PHP - however
				we can ensure that something was at least supplied */

			if (!$confpath) {
				return false;
			} else {
				this.$confpath = $confpath;
			}
			
			if (!$table) {
				return false;
			} else {
				this.$table = $table;
			}

			if (!$datafield) {
				return false;
			} else {
				this.$datafield = $datafield;
			}
			
			/* confirm the existence of supplied field and save reference to this */
			if (this.$field = $($inputfield)) {
				if (this.$field.tagName !== 'INPUT' || this.$field.type !== 'text') {
					return false;
				}
			}
			
			this.$req = new Ajax.Request(
			
				'ui/AutoEntry.php',
			
					{
								
						method:'post',
								
						parameters: {confpath:this.$confpath, table:this.$table, field:this.$datafield},
								
						onFailure: function(response) {
							trace("request to AutoEntry.php failed")
						},
			
						onComplete: function(response) {
							if (response.responseText != "") {
								var $tmp = document.createElement("DIV");
								$tmp.id = "autoEntryResponseDiv";
								try {
									$(document.body).insert($tmp);
								} catch(e) {
									$(document.documentElement).insert($tmp);
								}
								$tmp = $($tmp.id);
								$tmp.hide();
								$tmp.insert(response.responseText);
								this.$data = $tmp.childElements();
								this.$data = this.$data.collect(
									function($el) {
										return $el.firstChild.nodeValue;
									}
								)
								$tmp.remove();
								Event.observe(this.$field,"keydown",this._getkeys.bindAsEventListener(this));
								Event.observe(this.$field,"keyup",this._getkeys.bindAsEventListener(this));
							}
						}.bind(this)
			
					}
			
				);
			
				/* end ajax post request */

		},  /* end initialization */
		
		
		loadStyle: function() {
			var $head = $(document.getElementsByTagName('head')[0]);			
			var $css = document.createElement("link");
			$css.type = "text/css";
			$css.rel = "stylesheet";
			$css.href = "ui/AutoEntry.css";
			$head.insert($css);
		},
		
		_getkeys: function(e) {
			if (e.type == "keydown") {
				switch(e.keyCode) {
					case 16:
						trace("shifted");
						this.$keys.shift=1;
						break;
					case 9:
						if (this.$keys.shift == 1) {
							return false;
							break;
						}
						if (this.$suggestion && this.$iscomplete) {
							this._acceptEntry();
						} else {
							this._focusDelay = setTimeout("$('"+this.$field.id+"').focus()",1);
						}
						break;
					
					case 27:
						break;
					
					case 13:
						e.cancelBubble = true;
						e.returnValue = false;
						e.stopPropagation();
						e.preventDefault()
						break;
		
				}
			} else if (e.type == "keyup") {	
				switch(e.keyCode) {
					case 8:
						this.resetList();
						break;
					case 9:
						if (this.$keys.shift==1) {
							this.resetList();
							return false;
							break;
						}
					case 27:
						this.resetList();
						break;
					case 16:
						trace("unshifted");
						break;
					case 40:
						this.selectNext();
						break;
					case 38:
						this.selectPrevious();
						break;
					case 32:
						this.saveCurrentHighlight();
						break;
					case 13:
						this.saveCurrentHighlight();
						/* return */
						e.cancelBubble = true;
						e.returnValue = false;
						e.stopPropagation();
						e.preventDefault()
						return false;
						break;
					default:
						/* handle character input here */
						this._updateUI();
						break;
				}

			}

		},
		
		_checkInput: function() {
			this._createUI();
		},


		selectNext: function() {
			if (typeof(this.$ui) == "object") {
				if (this.$selected+1 < this.$list.childElements().length) {
					if (this.$selected != -1) {
						this.$highlight.removeClassName("highlighted");
					}
					this.$selected++;
					this.$highlight = $(this.$list.childElements()[this.$selected]);
					this.$highlight.addClassName("highlighted");
				}
			}
		},
	
	
		selectPrevious: function() {
			if (typeof(this.$ui) == "object") {
				if (this.$selected-1 >= -1) {
					if (this.$selected != -1) {
						this.$highlight.removeClassName("highlighted");
					}
					this.$selected--;
					this.$highlight = $(this.$list.childElements()[this.$selected]);
					this.$highlight.addClassName("highlighted");
				}
			}
		},

		saveCurrentHighlight: function() {
			if (this.$selected == -1) {
				return false;
			} else {
				var $selection = this.$list.childElements()[this.$selected].firstChild.nodeValue;
				this.$field.value = $selection;
				this.resetList();
			}
		},

		resetList: function() {
			if (isset(this.$list)) {
				if (typeof(this.$list == "object") && $(this.$list.id)) {
					$(this.$list.id).remove();
				}
			}
			if (typeof(this.$ui == "object") && $(this.$ui.id)) {
				$(this.$ui.id).remove();
			}
			this.$list = "";
			this.$ui = "";		
			this.$selected = -1;
			
		},

		_updateUI: function() {		
			if (this.$iscomplete) {
				return false;
			}

			var $input = this.$field.value;
			var $length = $input.length;
			
			this.$listitems = this.$data.select(
				function($item) {
					return $item.substring(0,$length).toLowerCase() == $input.toLowerCase();
				}
			);
			
			var $temp = "";
					
			this.$listitems.inject([],function(array,value,index) {
				if (value.substring(0,$length).toLowerCase() == $input.toLowerCase()) {
					$temp+="<li>" +value+"</li>";
				}
			});
			
			if ($temp !== "") {

				this.$ui = this._createUIElement();
					
				var $list = document.createElement("UL");

				$list.id = this.$listid;

				this.$ui.update($list);

				this.$list = $(this.$listid);

				this.setListStyle();

				this.$list.update($temp);

				this.setListObservers();

			} else {
			
				this._showFullList();
				return false;

			}
			
		},
		
		_showFullList: function() {
		
			this.$listitems = this.$data.select(
				function($item) {
					return $item;
				}
			);
			
			var $temp = "";
					
			this.$listitems.each(function($item) {
				$temp+="<li>" +$item+"</li>";
			});
			
			if ($temp !== "") {

				this.$ui = this._createUIElement();

				var $list = document.createElement("UL");

				$list.id = this.$listid;

				this.$ui.update($list);				

				this.$list = $(this.$listid);

				this.setListStyle();

				this.$list.update($temp);

				this.setListObservers();

			}

		},
		
		setListObservers: function() {
			this.$list.childElements().each(
				function($el) {
					Event.observe($el,"mouseover",function(e){$(e.target).addClassName("highlighted");});
					Event.observe($el,"mouseout",function(e){$(e.target).removeClassName("highlighted");});
					Event.observe($el,"click",function(e){
						this.$field.value = e.target.firstChild.nodeValue;
						this.resetList();
					}.bindAsEventListener(this))
				}.bind(this)
			);
		},
		
		setListStyle: function() {
			var $left = this.$field.cumulativeOffset()[0];
			var $top = this.$field.cumulativeOffset()[1];
			var $width = this.$field.getWidth();
			$top += 23;
			$left += 2;
			this.$ui.setStyle({"position":"absolute"});
			this.$ui.setStyle({zIndex:2000});
			this.$ui.setStyle({"top":$top+"px"});
			this.$ui.setStyle({"left":$left+"px"});
			this.$ui.setStyle({"width":$width+"px"});
			this.$ui.addClassName("dropmenudiv");
		},
		
		_createUIElement: function() {

			if (typeof(this.$ui) == "string") {		
				this.$uiid = "aa_"+this.$field.id;
				this.$listid = "aal_"+this.$field.id;
				
				var $dropdiv = document.createElement("DIV");
				$dropdiv.id = this.$uiid;
				
				try {
					$target = $(document.body);
				} catch(e) {
					$target = $(document.documentElement);
				}

				$target.insert($dropdiv);
				this.$ui = $(this.$uiid);
				this.$ui.addClassName("AutoEntryList");
				
				return this.$ui;
				
			} else {
			
				return this.$ui;
			}

		}
	
		
	} /* end class definition */