var AutoComplete	= new Class({
	Implements: Options,
	options: {
		'field': null,
		'fieldValue': null,
		'minLength': 0,
		'url': null,
		'data': {},
		'onSuccess': $lambda,
		'debug': false
	},
	
	initialize: function(options) {
		this.setOptions(options);
		this.setField(this.options.field);
		
		this.viewing	= false;
		this.focused	= false;
		this.request	= new Request.JSON({
			'url': this.options.url,
			'onSuccess': this.finishCapture.bind(this)
		});
	},
	
	setField: function(field) {
		if(field == null) return;
		
		this.options.field	= $(field);
		this.options.field.set({
			'autocomplete': 'off',
			'events': {
				'keyup': this.startCapture.bind(this),
				'focus': this.startCapture.bind(this),
				'blur': this.hideResults.bind(this, [true])
			}
		});
		
		this.createResultBox();
	},
	
	createResultBox: function() {
		var coords	= this.options.field.getCoordinates();
		this.resultBox = new Element('div', {
			'class': 'autocomplete-results',
			'styles': {
				'position': 'absolute',
				'z-index': '1000',
				'top': coords.top+coords.height,
				'left': coords.left,
				'opacity': 0
			},
			'events': {
				'mouseenter': this.setViewing.bind(this, true),
				'mouseleave': this.setViewing.bind(this, false)
			}
		}).inject($(document.body), 'top');
	},
	
	setViewing: function(v) {
		this.viewing = v;
		
		if(!v && !this.focused) {
			this.hideResults();
		}
	},
	
	startCapture: function() {
		this.focused = true;
		var value	= this.options.field.get('value');
		if(value.length < this.options.minLength) {
			this.hideResults();
			return;
		}
		
		var hash	= new Hash(this.options.data);
		hash.set(this.options.fieldValue, this.options.field.get('value'));
		
		this.request.cancel().get(hash);
	},
	
	finishCapture: function(obj, text) {
		if(this.options.debug) {
			console.log(obj);
			alert(text);
		}
		
		this.options.onSuccess.run([obj]);
	},
	
	display: function(element) {
		this.positionResultBox();
		this.resultBox.empty().adopt(element).fade(1);
	},
	
	hideResults: function(delay) {
		this.focused = false;
		
		if(this.viewing) return;
		var time	= $chk(delay) ? 500 : 0;
		(function() {
			this.resultBox.fade(0);
		}.bind(this)).delay(time);
	},
	
	setFieldValue: function(value) {
		this.options.field.set('value', value);
		this.hideResults();
	},
	
	positionResultBox: function() {
		var coords	= this.options.field.getCoordinates();
		this.resultBox.setStyles({
			'top': coords.top+coords.height,
			'left': coords.left
		});
	}
	
});


/* Zip Code AutoComplete */
AutoComplete.ZipCode	= new Class({
	
	initialize: function(field) {
		this.ac	= new AutoComplete({
			'url': Site.url+'/request/zipcode',
			'field': $(field),
			'fieldValue': 'zip',
			'minLength': 2,
			'onSuccess': this.display.bind(this)
		});
	},
	
	display: function(obj) {
		var container	= new Element('ul');
		var zip, i, el;
		
		for(i = 0; i < obj.length; i++) {
			zip	= obj[i];
			el	= new Element('li').adopt(
				new Element('a', {
					'events': {
						'click': this.ac.setFieldValue.bind(this.ac, [zip.zip])
					}
				}).adopt(
					new Element('span', {
						'class': 'zip-city',
						'text': zip.city
					}),
					new Element('span', {'text': ' - '}),
					new Element('span', {
						'class': 'zip-zip',
						'text': zip.zip
					})
				)
			);
			
			container.adopt(el);
		}
		
		this.ac.display(container);
	}
	
});

/* City Name AutoComplete */
AutoComplete.City	= new Class({
	
	initialize: function(field) {
		this.ac	= new AutoComplete({
			'url': Site.url+'/request/city',
			'field': $(field),
			'fieldValue': 'city',
			'minLength': 2,
			'onSuccess': this.display.bind(this)
		});
	},
	
	display: function(obj) {
		var container	= new Element('ul');
		var zip, i, el;
		
		for(i = 0; i < obj.length; i++) {
			zip	= obj[i];
			el	= new Element('li').adopt(
				new Element('a', {
					'events': {
						'click': this.ac.setFieldValue.bind(this.ac, [zip.city])
					}
				}).adopt(
					new Element('span', {
						'class': 'city-city',
						'text': zip.city
					}),
					new Element('span', {'text': ' - '}),
					new Element('span', {
						'class': 'city-zip',
						'text': zip.zip
					})
				)
			);
			
			container.adopt(el);
		}
		
		this.ac.display(container);
	}
	
});

/* Hospital Name AutoComplete */
AutoComplete.Hospital	= new Class({
	
	initialize: function(field) {
		this.ac	= new AutoComplete({
			'url': Site.url+'/request/hospital',
			'field': $(field),
			'fieldValue': 'hospital',
			'minLength': 2,
			'onSuccess': this.display.bind(this)
		});
	},
	
	display: function(obj) {
		var container	= new Element('ul');
		var o, i, el;
		
		for(i = 0; i < obj.length; i++) {
			o	= obj[i];
			el	= new Element('li').adopt(
				new Element('a', {
					'events': {
						'click': this.setHospital.bind(this, [o])
					}
				}).adopt(
					new Element('span', {
						'class': 'hospital-name',
						'text': o.name
					}),
					new Element('span', {
						'class': 'hospital-location',
						'text': o.city.trim()+', '+o.state
					})
				)
			);
			
			container.adopt(el);
		}
		
		this.ac.display(container);
	},
	
	setHospital: function(o) {
		this.ac.setFieldValue(o.name);
		$('hospital-id').set('value', o.id);
	}
	
});

/* Location Name AutoComplete */
AutoComplete.Location	= new Class({
	
	initialize: function(field) {
		this.ac	= new AutoComplete({
			'url': Site.url+'/request/location',
			'field': $(field),
			'fieldValue': 'name',
			'minLength': 2,
			'onSuccess': this.display.bind(this),
			'debug': false
		});
	},
	
	display: function(obj) {
		var container	= new Element('ul');
		var o, i, el;
		
		for(i = 0; i < obj.length; i++) {
			o	= obj[i];
			el	= new Element('li').adopt(
				new Element('a', {
					'events': {
						'click': this.ac.setFieldValue.bind(this.ac, [o.name])
					}
				}).adopt(
					new Element('span', {
						'class': 'location-name',
						'text': o.name
					})
				)
			);
			
			container.adopt(el);
		}
		
		this.ac.display(container);
	}
	
});

/* Job Keyword AutoComplete */
AutoComplete.JobKeyword	= new Class({
	
	initialize: function(field) {
		this.ac	= new AutoComplete({
			'url': Site.url+'/careers/search',
			'field': $(field),
			'fieldValue': 'keyword',
			'minLength': 2,
			'onSuccess': this.display.bind(this),
			'debug': false,
			'data': {
				'json': '1',
				'type': 'keyword'
			}
		});
	},
	
	display: function(obj) {
		var container	= new Element('ul');
		var o, i, el;
		
		for(i = 0; i < obj.length; i++) {
			o	= obj[i];
			el	= new Element('li').adopt(
				new Element('a', {
					'events': {
						'click': this.ac.setFieldValue.bind(this.ac, [o.title])
					}
				}).adopt(
					new Element('span', {
						'class': 'keyword-title',
						'text': o.title
					})
				)
			);
			
			container.adopt(el);
		}
		
		this.ac.display(container);
	}
	
});