/**
* autosuggest - A jQuery plugin
* Description: This plugin creates faux autosuggests
* Author: Kellan Craddock
* @argument {object} a jquery object of elements to turn into autosuggests
* @returns false
*/

(function($) {

	//Create plugin obj
	$.fn.autosuggest = function(options) {
		return this.each(function(i) {
			$.fn.autosuggest.createInstance($(this), options);
		});
	}
	
	$.fn.autosuggest.defaults = {
		dataUrl: false,
		delineator: ', ',
		minCharLimit: 0,
		delay: 0,
		onInputSubmit: function() {}
	}
	
	//Aquire plugin instance
	$.fn.autosuggest.createInstance = function(element, options) {
		if (element.data('autosuggest')) {
			//Existing Instance
			return element.data('autosuggest');
		} else {
			//New Instance
			var instance = new $.fn.autosuggest.instance(element, options);
			element.data('autosuggest').init(element, options);
			return element.data('autosuggest');
		}
	}
	
	//Instance
	$.fn.autosuggest.instance = function(element, options) {
	
		var self = this;
		this.options;
		this.element = element;
		this.timeout = false;
		
		//Initialize 
		this.init = function(element, options) {
			//Extend the default options obj
			self.options = $.extend({}, $.fn.autosuggest.defaults, options);
			//Create default elements
			self.options.autoInput = self.element;
			self.options.form = $(self.options.autoInput).parents('form');
			self.options.autoInput.attr('autocomplete', 'off');
			self.options.autoInput.addClass('auto_input');
			self.options.autoList = $('<ul class="auto_list closed"></ul>');
			self.options.autoInput.after(self.options.autoList);
			//Bind keyup events
			self.options.autoInput.bind('keyup', function(e) {
				//if keycode is numeric or alphabetic
				if (e.keyCode >= 48 && e.keyCode <= 90) {
					self.suggest();
				//else if keycode is delete or backspace
				} else if (e.keyCode == 46 || e.keyCode == 8) {
					if ($(this).val() == '') {
						self.options.autoList.empty().removeClass('open').addClass('closed');
					} else {
						self.suggest();
					}
				} 
			});
			
			//Bind keypress events
			self.options.autoInput.bind('keyup', function(e) {
				//If enter or return keyup
				if (e.keyCode == 13 || e.keyCode == 9) {					
					self.preSubmit();
				//If arrow press
				} else if (e.keyCode >= 37 && e.keyCode <= 40) {
					self.moveList(e.keyCode);
				}
			});
			
			//Bind to form submit button
			$('input[type="submit"], button', self.options.form).bind('mouseup', function() {
				self.preSubmit();
			});
			

		}
		
		this.preSubmit = function() {
			var hover  = self.options.autoList.children('li.hover');
			//If there is a match
			if (hover.length) {
				self.options.autoInput.val(self.options.autoList.children('li.hover').data('title'));
				self.inputSubmit(self.options.autoList.children('li.hover'));
			} else {
				self.inputSubmit(self.options.autoInput.val());
			}
		}
		
		this.suggest = function() {
			//If timout has not been set, make the call
			if (!self.timeout) {
				self.timeout = setTimeout(function() {
					if (self.options.dataUrl && self.options.autoInput.val() != '' && self.options.autoInput.val().length >= self.options.minCharLimit) {
						$.ajax({
							url: self.options.dataUrl,
							data: 'query=' + self.options.autoInput.val(),
							dataType: 'json',
							type: 'post', 
							success: function(returnData) {
								self.timeout = false;
			        			self.updateSuggestList(returnData);
			      			}
			      		});
		      		} else {
		      			self.timeout = false;
		      		}
	      		}, self.options.delay);
			}
		}
		
		this.updateSuggestList = function(data) {
			self.options.autoList.removeClass('closed').addClass('open').empty();
			if (data != '' && data != undefined) {
				$(data).each(function() {
					var pop_title = (this.pop_title) ? ' - ' + this.pop_title : '';
					var item = $('<li>' + this.title + '<span>' + pop_title + '</span></li>')
						.data('key', this.key).data('title', this.title)
						.bind('mouseover', function() {
							$(this).siblings('li').removeClass('hover');
							$(this).addClass('hover');
						}).bind('click', function(){
							self.options.autoInput.val(self.options.autoList.children('li.hover').data('title'));
							self.inputSubmit(self.options.autoList.children('li.hover'));
						})
					self.options.autoList.append(item);
				});
				self.options.autoList.children('li').eq(0).addClass('hover');
			} else {
				//Reset the auto list
				self.options.autoList.removeClass('open').addClass('closed').empty();
			}
		}
		
		this.moveList = function(code) {
			var li  = self.options.autoList.children('li');
			var hover  = self.options.autoList.children('li.hover');
			//Move down
			if (code == 40) {
				if (hover.length) {
					hover.next('li').trigger('mouseover');
				} else {
					li.eq(0).trigger('mouseover');
				}
			//Move up
			} else if (code == 38) {
				if (hover.length) {
					hover.prev('li').trigger('mouseover');
				} else {
					li.last().trigger('mouseover');
				} 
			}
		}
		
		this.inputSubmit = function(data) {
			self.options.onInputSubmit(data);
			self.updateSuggestList();
		}
		
	    //Set plugin instance to data
	    element.data('autosuggest', this);
	}
	
})(jQuery);
