/*
 * This autocompleter should be constructed with a given populator function.
 * The populator function should call the setChoices(choices) method on this autocompleter
 * where 'choices' is the array of choices to be displayed in the autocomplete div.
 */
Autocompleter.DWR = Class.create();
Autocompleter.DWR.prototype = Object.extend(new Autocompleter.Base(), {
	
	parentFormId: null,
	
	initialize: function(element, update, populator, options, parentFormId) {
		this.baseInitialize(element, update, options);
		this.options.array = new Array(0);
		this.populator = populator;
		this.options.frequency = 0;
		this.parentFormId = parentFormId;
	},

	// called by the autocompleter on an event.
	getUpdatedChoices: function() {
		this.populator(this, this.getToken()); // this is the populator specified in the constructor.
	},

	// should be called by the populator (specified in the constructor)
	setChoices: function(array) {
		this.options.array = array;
		this.updateChoices(this.options.selector(this));
	},
	
	setOptionChoices: function(choices) {
		this.options.choices = choices;
	},
	
	setOptionSuffix: function(suffix) {
		this.options.suffix = suffix;
	},
	
	selectEntry: function() {
		this.active = false;
		var currentEntry = this.getCurrentEntry();
		try {
			if(currentEntry.id == 'autocompletion_more' ||
				currentEntry.id == 'autocompletion_less' ||
				currentEntry.id == 'autocompletion_out' ||
				currentEntry.id == 'autocompletion_headline')
				return;
		}
		catch(e) {}
		this.updateElement(this.getCurrentEntry());
		$(this.parentFormId).submit();
	},
	
	onClick: function(event) {
		var currentEntry = this.getCurrentEntry();
		try {
			if(currentEntry.id == 'autocompletion_more' ||
				currentEntry.id == 'autocompletion_less' ||
				currentEntry.id == 'autocompletion_out')
				return;
		}
		catch(e) {}
		var element = Event.findElement(event, 'LI');
		this.index = element.autocompleteIndex;
		this.selectEntry();
		this.hide();
	},
  
	onBlur: function(event) {
		var currentEntry = this.getCurrentEntry();
		try {
			if(currentEntry.id == 'autocompletion_more' ||
				currentEntry.id == 'autocompletion_less')
				return;
		}
		catch(e) {}
		// needed to make click events working
		setTimeout(this.hide.bind(this), 250);
		this.hasFocus = false;
		this.active = false;     
	}, 

	setOptions: function(options) {
		this.options = Object.extend({
			choices: 10,
			partialSearch: true,
			partialChars: 2,
			ignoreCase: true,
			fullSearch: false,
			prefixStart: '',
			prefixEnd_a: '',
			prefixEnd_b: '',
			suffix: '',
			selector: function(instance) {
			
				// don't display auto completion list if click lock is active
				if (document.getElementById('klicksperre')) {
					if (document.getElementById('klicksperre').style.display == 'block') {
						return "<ul></ul>";
					}
				}
			
				var ret       = []; // Beginning matches
				var partial   = []; // Inside matches
				var entry     = instance.getToken();
				var count     = 0;

				for (var i = 0; i < instance.options.array.length &&
					ret.length < instance.options.choices ; i++) {

					try {
						var elem = instance.options.array[i];
						var foundPos = instance.options.ignoreCase ?
										elem.toLowerCase().indexOf(entry.toLowerCase()) :
										elem.indexOf(entry);

						while (foundPos != -1) {
							if (foundPos == 0 && elem.length != entry.length) {
								ret.push("<li><strong>" + elem.substr(0, entry.length) + "</strong>" +
											elem.substr(entry.length) + "</li>");
								break;
							} else if (entry.length >= instance.options.partialChars &&
										instance.options.partialSearch && foundPos != -1) {
								if (instance.options.fullSearch || /\s|-/.test(elem.substr(foundPos-1,1))) {
									partial.push("<li>" + elem.substr(0, foundPos) + "<strong>" +
													elem.substr(foundPos, entry.length) + "</strong>" + elem.substr(
													foundPos + entry.length) + "</li>");
									break;
								}
							}

							foundPos = instance.options.ignoreCase ?
										elem.toLowerCase().indexOf(entry.toLowerCase(), foundPos + 1) :
										elem.indexOf(entry, foundPos + 1);

						}
					}
					catch (e) {}
				}
				
				if (partial.length)
					ret = ret.concat(partial.slice(0, instance.options.choices - ret.length))
				if (ret.length) {
					if (ret.length == 1)
						return "<ul>" + instance.options.prefixStart + ret.length + instance.options.prefixEnd_b + ret.join('') + instance.options.suffix + "</ul>";
					else
						return "<ul>" + instance.options.prefixStart + ret.length + instance.options.prefixEnd_a + ret.join('') + instance.options.suffix + "</ul>";
				}
				else 
					return "<ul>" + ret.join('') + "</ul>";
			}
		}, options || {});
	}
});