
var AutoSuggest = Class.create({
	initialize: function(name) {
	  this.name = name;
	  this.x = 0;
	  this.y = 0;
	  this.width = 0;
	  this.height = 0;
	  this.alpha = 0;
	  this.data = null;
	  this.border = '#0093E7';
	  this.hasFocus = false;
	  this.owner = null;
	  q = document.createElement('select');
	  q.id = 'scroll_'+this.name;
	  q.multiple = true;
	  q.size = 10;
	  q.style.position = 'absolute';
	  q.style.zIndex = '10000';
	  q.style.left = this.x+'px'
	  q.style.top = this.y+'px';
	  q.style.width = this.width+'px';
	  q.style.display = 'none';
	  q.style.border = '1px solid ' + this.border;
	  q.style.borderTop = 'none';
	  this.domRef = document.body.appendChild(q);

	  var thisObj = this;
	  var name = 'scroll_'+this.name;

	  $(name).observe('focus', function(event)
	  {
		thisObj.hasFocus = true;
		Element.show(thisObj.domRef);
	  });

	  $(name).observe('blur', function(event)
	  {
		thisObj.hasFocus = false;
		thisObj.domRef.fire('autosuggest:blur', {name:thisObj.name});
		Element.hide(thisObj.domRef);
	  });

	  $(name).observe('change', function(event)
	  {
		thisObj.hasFocus = true;
		var n = Event.element(event);
		var index = -1;
		var value,text;
		index = n.selectedIndex;
		value = n.options[index].value;
		text = n.options[index].text;
		thisObj.domRef.fire('autosuggest:change', {name:thisObj.name, value:value, text:text});
	  });

	  document.observe('autosuggest:moveup', function(event)
	  {
		if(event.memo.name == thisObj.name){
			thisObj.moveup();
		}
	  });

	  document.observe('autosuggest:movedown', function(event)
	  {
		if(event.memo.name == thisObj.name){
			thisObj.movedown();
		}
	  });
	},

	getDiv: function()
	{
		return this.domRef;
	},
	setX: function(num)
	{
		this.x = num;
		this.domRef.style.left = this.x+'px';
	},
	setY: function(num)
	{
		this.y = num;
		this.domRef.style.top = this.y+'px';
	},
	getWidth: function()
	{
		return this.width;
	},
	setWidth: function(num)
	{
		this.width = num;
		this.domRef.style.width = this.width+'px';
	},
	getHeight: function()
	{
		return this.height;
	},
	setHeight: function(num)
	{
		this.height = num;
		this.domRef.style.height = this.height+'px';
	},
	getDepth: function()
	{
		return this.domRef.style.zIndex;
	},
	setDepth: function(num)
	{
		this.domRef.style.zIndex = num;
	},
	setData: function(val)
	{
		this.data = val;
	},
	getOwner: function()
	{
		return this.owner;
	},
	setOwner: function(str)
	{
		this.owner = str;
	},
	setBorderColor: function(val)
	{
		this.border = val;
		this.domRef.style.border = '1px solid ' + this.border;
		this.domRef.style.borderTop = 'none';
	},
	clear: function()
	{
		Element.update(this.domRef, '');
	},
	setFocus: function()
	{
		this.hasFocus = true;
		this.domRef.focus();
	},
	gotFocus: function()
	{
		return this.hasFocus;
	},
	getValue: function()
	{
		return this.domRef.value;
	},
	getSelectedIndex: function()
	{
		return this.domRef.selectedIndex;
	},
	setSelectedIndex: function(index)
	{
		this.domRef.selectedIndex = index;
	},
	getSelectedData: function()
	{
		//index = this.domRef.selectedIndex;
		var index = this.getSelectedIndex();
		var data = new Array();
		var value = this.domRef.options[index].value;
		var text = this.domRef.options[index].text;
		data.push(value, text);
		return data;
	},
	showList: function()
	{
		this.clear();
		Element.update(this.domRef, this.data);
		if(this.domRef.options.length >= 5){
			this.domRef.size = 5;
		} else {
			this.domRef.size = this.domRef.options.length;
		}
		Element.show(this.domRef);
		this.setSelectedIndex(-1);
	},
	hide: function()
	{
		this.hasFocus = false;
		this.setSelectedIndex(-1);
		Element.hide(this.domRef);
	},
	moveup: function()
	{
		index = this.domRef.selectedIndex;
		
		if(index <= 0)
		{
			this.domRef.selectedIndex = this.domRef.length - 1;
		}
		else
		{
			this.domRef.selectedIndex = index - 1;
		}
	},
	movedown: function()
	{
		index = this.domRef.selectedIndex;
		
		if(index == this.domRef.length - 1)
		{
			this.domRef.selectedIndex = 0;
		}
		else
		{
			this.domRef.selectedIndex = index + 1;
		}
	}
});
var AutoSuggestInitializer = Class.create({
	initialize: function(domObj, name) {
	  this.domObj = domObj;
	  this.pe = null;
	  this.name = name;
	  this.url = null;
	  this.number = null;
	  this.suggest = null;
	  this.sequence = 0;
	  this._default = null;
	  this.fnCallBack = null;
	  this.fnOnResponse = null;
	  this.scroll = new AutoSuggest(this.name);
	  this.scroll.setOwner(this.name);

	  var thisObj = this;
	  Event.observe(this.domObj, 'keyup', function(event){
		var key = event.keyCode;
		if(thisObj.pe)
		{
			thisObj.pe.stop();
			thisObj.pe = null;
		}
		thisObj.pe = new PeriodicalExecuter(function(p) {
			    p.stop();
  				if((key != Event.KEY_TAB) && (key != Event.KEY_DOWN) && (key != Event.KEY_UP)) thisObj.lookup(event);
			}, .4);
		Event.stop(event);
		return false;
	  });
	  Event.observe(this.domObj, 'keydown', function(event){
		if(event.keyCode)
		{
			if(event.keyCode == Event.KEY_DOWN)
			{
				//thisObj.scroll.movedown();
				thisObj.domObj.fire('autosuggest:movedown', {name:thisObj.name});
				thisObj.domObj.value = thisObj.scroll.getValue();
				Event.stop(event);
				return false;
			}
			else if(event.keyCode == Event.KEY_UP)
			{
				//thisObj.scroll.moveup();
				thisObj.domObj.fire('autosuggest:moveup', {name:thisObj.name});
				thisObj.domObj.value = thisObj.scroll.getValue();
				Event.stop(event);
				return false;
			}
			else if(event.keyCode == Event.KEY_RETURN)
			{
				var data = thisObj.scroll.getSelectedData();
				var value = data[0];
				var text = data[1];
				thisObj.callback(value, text);
				Event.stop(event);
				return false;
			}
		}
	  });
	  Event.observe(this.domObj, 'focus', function(event){
		thisObj.lookup(event);
		Event.stop(event);
		return false;
	  });
	  Event.observe(this.domObj, 'blur', function(event){
		if(thisObj.pe)
		{
			thisObj.pe.stop();
			thisObj.pe = null;
		}
		thisObj.pe = new PeriodicalExecuter(function(p) {
			p.stop();
			if(!thisObj.scroll.gotFocus())
			{
			 	thisObj.scroll.hide();
				if(thisObj.domObj.value == thisObj.number)
				{
				}
				else if(thisObj.domObj.value == thisObj._default)
				{
				}
				else
				{
					thisObj.callback('', '');
				}
			}
		}, .2);
		Event.stop(event);
		return false;
	  });

	  document.observe('autosuggest:change', function(event)
	  {
		if(event.memo.name == thisObj.name){
			thisObj.callback(event.memo.value, event.memo.text);
		}
	  });
	  document.observe('autosuggest:blur', function(event)
	  {
		if(event.memo.name == thisObj.name){
			thisObj.blur();
		}
	  });
	},
	getUrl: function()
	{
		return this.url;
	},
	setUrl: function(str)
	{
		this.url = str;
	},
	getName: function()
	{
		return this.name;
	},
	setName: function(str)
	{
		this.name = str;
	},
	getFnCallBack: function(){
		return this.fnCallBack;
	},
	setFnCallBack: function(fn){
		this.fnCallBack = fn;
	},
	getFnOnResponse: function(){
		return this.fnOnResponse;
	},
	setFnOnResponse: function(fn){
		this.fnOnResponse = fn;
	},
	setBorderColor: function(val)
	{
		this.scroll.setBorderColor(val);
	},
	callAjax: function(){
		var n = this.domObj;
		this.scroll.setOwner(this.name);
		var t = Element.cumulativeOffset(n);
		var url = this.url + n.value +'&seq='+this.sequence;
		this.sequence++;
		var thisObj = this;
		new Ajax.Request(url, {
		  method: 'get',
		  onSuccess: thisObj.onAJAXCallback.bind(thisObj)
		});
	},
	/*
	*/
	lookup: function(evt)
	{
		if(!evt)
		{
			evt = window.event;
		}
		var n = Event.element(evt);
		if(n.value != '' && !n.value.match(/^\s+$/) && n.value.length > 1)
		{
			if(n.value != this.suggest)
			{
				this.suggest = n.value;
				var url = this.url + n.value +'&seq='+this.sequence;
				var t = Element.cumulativeOffset(n);
				this.scroll.setOwner(this.name);
				this.sequence++;
				var thisObj = this;
				new Ajax.Request(url, {
				  method: 'get',
				  onSuccess: thisObj.onAJAXCallback.bind(thisObj)
				});
			}
		}
		else
		{
			//this.scroll.hide();
		}
	},
	onAJAXCallback: function(transport){
		var resp = transport.responseText.evalJSON();
		//$('error_1').innerHTML = transport.responseText+'<br/>';
		//$('error_2').innerHTML += resp.seq+' ' + this.sequence+'<br/>';
		if(parseInt(resp.seq) == (this.sequence - 1)){
			var n = this.domObj;
			var t = Element.cumulativeOffset(n);
			
			//$('error_3').innerHTML = transport.responseText;
			if(this.fnOnResponse) this.fnOnResponse(resp);
			
			this.scroll.setX(t[0]);
			this.scroll.setY(t[1] + n.getHeight() - 1);
			this.scroll.setWidth(n.getWidth());
			this.scroll.setData(resp.data);
			this.scroll.showList();
		}
	},
	callback: function(value, text)
	{
		this.scroll.hide();
		if(this.scroll.getOwner() == this.name)
		{
			if(this.fnCallBack) this.fnCallBack(value, text);
			this.domObj.value = value;
			this.number = value;
			this.suggest = value;
		}
	},
	blur: function()
	{
		if(this.domObj.value == this.number)
		{
		}
		else if(this.domObj.value == this._default)
		{
		}
		else
		{
			this.callback('', '');
		}
	}
});
