/**
 * Autocompleter extension for match with BT search engine json and specific functionality
 *
 * @author Pascal Bleuse
 * @version 20 oct 2010
 */

Autocompleter.BTSE = new Class({

	Extends: Autocompleter.Request.JSON,

	options: {
		forceComplete: true,
		withCountry: false,
		ignoreGroup: false,
		zIndex: 10000,
		autoSubmit: false,
		selectMode: false,
		selectFirst: true,
		filterSubset: false,
		anywhere: 'Anywhere'
	},

	initialize: function(el, url, options) {
		this.parent(el, url, options);
		this.baseMaxChoices = this.options.maxChoices;
		this.clearFocus = true;
		
		// Get value for 'ANYWHERE' if exist
		if( _d( 'ANYWHERE' ) != null ) this.options.anywhere = _d( 'ANYWHERE' );
	},
	
	onCommand: function(e) {
		if (!e && this.focussed) return this.prefetch();
		if (e && e.key && !e.shift) {
			switch (e.key) {
				case 'enter':
					if (this.element.value != this.opted) return true;
					if (this.selected && this.visible) {
						this.choiceSelect(this.selected);
						return !!(this.options.autoSubmit);
					}
					break;
				case 'tab':
					if (this.element.value != this.opted) return true;
					if (this.selected && this.visible) {
						this.choiceSelect(this.selected);
					}
					break;
				case 'up': case 'down':
					if (!this.prefetch() && this.queryValue !== null) {
						var up = (e.key == 'up');
						this.choiceOver((this.selected || this.choices)[
							(this.selected) ? ((up) ? 'getPrevious' : 'getNext') : ((up) ? 'getLast' : 'getFirst')
						](this.options.choicesMatch), true);
					}
					return false;
				case 'esc':
					this.hideChoices(true);
					break;
			}
		}
		return true;
	},
	
	setSelection: function(finish) {
		var input = this.selected.inputValue, value = input;
		var start = this.queryValue.length, end = input.length;
		if (input.substr(0, start).toLowerCase() != this.queryValue.toLowerCase()) start = 0;
		if (this.options.multiple) {
			var split = this.options.separatorSplit;
			value = this.element.value;
			start += this.queryIndex;
			end += this.queryIndex;
			var old = value.substr(this.queryIndex).split(split, 1)[0];
			value = value.substr(0, this.queryIndex) + input + value.substr(this.queryIndex + old.length);
			if (finish) {
				var tokens = value.split(this.options.separatorSplit).filter(function(entry) {
					return this.test(entry);
				}, /[^\s,]+/);
				if (!this.options.allowDupes) tokens = [].combine(tokens);
				var sep = this.options.separator;
				value = tokens.join(sep) + sep;
				end = value.length;
			}
		}
		this.observer.setValue(value);
		this.opted = value;
		if (finish || this.selectMode == 'pick') start = end;
		if(this.focussed) this.element.selectRange(start, end);
		this.fireEvent('onSelection', [this.element, this.selected, value, input]);
	},

	update: function(tokens) {
		if($type(tokens) == false){
			this.fireEvent('onFailure');
			return false;
		}
		this.choices.empty();
		// Reset maxChoices to default
		this.options.maxChoices = this.baseMaxChoices;
		tokens = this.searchEngineGetObject( tokens, this.options.forceComplete );
		this.cached = tokens;
		var type = tokens && $type(tokens);
		if ((!type || (type == 'array' && !tokens.length) || (type == 'hash' && !tokens.getLength())) && this.options.forceComplete == true) {
			(this.options.emptyChoices || this.hideChoices).call(this);
		} else {
			if (this.options.maxChoices < tokens.length && !this.options.overflow) tokens.length = this.options.maxChoices;
			enabledGroup = new Array();
			tokens.each(this.options.injectChoice || function(token){
				iata = this.searchEngineGetToken( token, 'iata' );
				iso = this.searchEngineGetToken( token, 'iso' );
				groupAirport = this.searchEngineGetToken( token, 'groupAirport' );
				isGroup = this.searchEngineGetToken( token, 'isGroup' );
				if( isGroup == 'true' )
					enabledGroup.push( iata );
				isCountry = this.searchEngineGetToken( token, 'isCountry' );
				txt = this.searchEngineGetToken( token, 'phrase' );
				var choice = new Element('li', {'html': this.markQueryValue(txt)}).store('id', {'iata': iata, 'iso': iso});
				if(!this.options.ignoreGroup && groupAirport != null && groupAirport != "" && enabledGroup.contains( groupAirport ) ) choice.addClass( 'isgroup' );
				choice.inputValue = txt;
				this.addChoiceEvents(choice).inject(this.choices);
			}, this);
			
			this.addAnywhere();
			
		}
	},
	
	addAnywhere: function() {
		if( this.options.forceComplete == false ) {
			// Add 1 row to maxChoices
			this.options.maxChoices = this.baseMaxChoices + 1;
			var choice = new Element('li', {'html': this.options.anywhere}).store('id', {'iata': null, 'iso': null});
			choice.inputValue = this.options.anywhere;
			this.addChoiceEvents(choice).inject(this.choices);
		}

		if(!this.focussed) {
			this.choiceSelect(this.choices.getFirst());
		} else
			this.showChoices();
	},
	
	choiceSelect: function(choice) {
		if (choice) this.choiceOver(choice);
		this.searchEngineSetSelection( this.selected.retrieve( 'id' ) );
		this.setSelection(true);
		this.queryValue = false;
		this.hideChoices();
	},
	
	searchEngineGetObject: function( tokens, forceComplete ) {
		if( forceComplete == true ) {
			if( tokens.search.length > 0 ) {
				this.element.removeClass( 'error' );
				return tokens.search;
			} else {
				this.element.addClass( 'error' );
				return false;
			}
		} else {
			return tokens.search;
		}
	},
	
	searchEngineGetToken: function( token, field ) {
		return token[field];
	},
	
	searchEngineSetSelection: function( value ) {
		// Prevent error
		if( value == null )
			value = {'iata': null, 'iso': null};

		this.iata = value.iata;
		this.iso = value.iso;
	}
	
} );

