/**
 * Attempts to automatically fetch "suggestions" on text input fields. Correct functionality is
 * dependent upon inputs being named correctly per Cake standards.  Also depends on corresponding
 * server-side logic to return results.
 *
 */
/**
 * TODO:
 *	non-cached method could probably use some kind of flood control
 */
jQuery.fn.suggest = function(options){

	var methods = {
		// initialization
		init: function(element){
			if (element.hasClass('ui-suggest-cache')) {
				element.nullData = element.serialize().split('=')[0]+'=';
				jQuery.post(window.location.href+'/ajax_suggest:1', element.nullData, function(data){
					element.cachedList = data.suggestions;
				}, 'json');
			}
			// attach keyup handler
			element.preview = $('<ul>').addClass('preview');
			element.after(element.preview).attr('autocomplete', 'off');
			element = methods.position(element);
			element.bind('keyup', function(){
				if (element.val().length >= options.threshold) {
					if (element.cachedList) {
						element = methods.getResultsCached(element);
					} else {
						element = methods.getResults(element);
					}
				} else {
					element.preview.hide();
				}			
			}).blur(function(){
				element.siblings('ul.preview').hide();
			});
		},
		// positions the preview element
		position: function(element) {
			var offset = element.position();
			offsetTop = offset.top + element.outerHeight();
			width = element.outerWidth() - 10;
			element.preview.css({
				top: offsetTop+'px',
				left: offset.left+'px',
				width: width+'px'
			});
			return element;
		},
		// fetches AJAX resultset
		getResults: function(element) {
			jQuery.post(window.location.href+'/ajax_suggest:1', element.serialize(), function(data){
				if (data.suggestions.length > 0) {
					element = methods.showMatches(element, data.suggestions);
				} else {
					element.preview.hide();
				}
			}, 'json');
			return element;
		},
		// creates cached resultset to display suggestions
		getResultsCached: function(element) {
			var matches = [];
			jQuery.each(element.cachedList, function(){
				if (this.toLowerCase().indexOf(element.val().toLowerCase()) != -1) {
					matches.push(this.toString());
				}
			});
			if (matches.length > 0) {
				element = methods.showMatches(element, matches);
			} else {
				element.preview.hide();
			}
			return element;
		},
		showMatches: function(element, matches) {
			var list = element.siblings('ul.preview');
			// empty the list
			list.html('');
			jQuery.each(matches, function(index, text){
				list.append(methods.createListItem(text).click(function(){
					element.val(text);
					list.hide();
				})	.hover(function(){
						element.unbind('blur');
					}, function(){
						element.blur(function(){
							element.siblings('ul.preview').hide();
						});
					}));
			});
			element.siblings('ul.preview').show();
			return element;
		},
		// generates an <li> containing the passed string
		createListItem: function(text) {
			var li = $('<li>').html(text).addClass('active');
			return li;
		}
	}
	
	var defaults = {
		// text inputs shorter than this will not trigger AJAX requests
		threshold: 2
	}
	options = jQuery.extend(defaults, options);

	$(this).each(function(){
		methods.init($(this));
	});
	return this;

};
