/*
---
DESCRIPTION: QuickSearch Class, a base Ether.Flex component.

LICENSE: Closed License

AUTHORS:
- Jan Kassens
- Luis Merino
- Nathan Querido

COPYRIGHT:
- QUERIDODESIGN, Switzerland - http://www.queridodesign.net/

DEPENDENCIES:
- MooTools-Core 1.2.4

- MooTools-More 1.2.4
...
*/

// OBSERVER CLASS :: JanK
var Observer = new Class({

	Implements: [Options, Events],

	options: {
		interval: 100,
		duration: 0
	},

	initialize: function(element, property, options){
		this.setOptions(options);
		this.element = $(element);
		this.element.store('valueObserver', this);
		this.property = property;
		this.value = this.element.get(property);
		this.start();
	},

	check: function() {
		var value = this.element.get(this.property);
		if (value == this.value || value == 'search') return;
		this.value = value;
		this.fireEvent('onChange', [value]);
	},

	start: function() {
		this.stop();
		this.interval = this.check.periodical(this.options.interval, this);
	},

	stop: function() {
		$clear(this.interval);
	},
	
	set: function(value) {
		this.stop();
		this.value = value;
		this.element.set(this.property, value);
		this.start();
	}

});

Element.Events.observedChange = {

	onAdd: function(fn){
		new Observer(this, 'value', {onChange: fn});
	}

};

// FALLBACK FOR IE :: JanK
Element.implement({

	fadeOut: function(){
		this.fade(Browser.Engine.trident ? 'hide' : 'out');
	},

	fadeIn: function(){
		this.fade(Browser.Engine.trident ? 'show' : 'in');
	}

});

// LIVE SEARCH CLASS :: JanK, Rendez, nfq
var LiveSearch = new Class({

	initialize: function(field, spinner, results){
		this.selected = null;
		var inputText = $(field).retrieve('inputText', false);
		if(inputText) this.defaultText = inputText.text;
		else this.defaultText = $(field).value;
		this.search  = $(field).addEvents({
			'focus': (function(){
				if (this.hasResults) this.showResults();
			}).bind(this),
			'blur':  (function(){
				if(!this.search.value || this.search.value == this.defaultText) this.hasResults = false;
			}).bind(this)
		});
		this.spinner = $(spinner).set('tween', {duration: 250}).fade('hide');
		this.results = $(results);
		// this.searchBox = document.getElement('div.search_box');
		this.resultWrapper = this.results.getParent().set('tween', {duration: 250}).fade('hide');
		this.request = new Request({ url: baseHref + 'search', link: 'cancel',
			onRequest: Element.fade.pass([this.spinner, 'show']),
			onSuccess: function(html){
				this.results.set('html', html);
				this.showResults();
			}.bind(this),
			onComplete: Element.fadeOut.pass(this.spinner)
		});

		this.userInteract();
	},

	hideResults: function(){
		this.resultWrapper.fadeOut();
		// this.searchBox.setStyle.delay(100, this.searchBox, ['background-position', 'top left']);
		this.request.cancel();
		this.spinner.fadeOut();
		this.selected = null;
	},

	showResults: function(){
		this.hasResults = true;
		this.resultWrapper.fadeIn();
		// this.searchBox.setStyle.delay(100, this.searchBox, ['background-position', 'top right']);
		this.results.getElements('li.search_entry_selected').removeClass('search_entry_selected');
		this.selected = this.results.getElement('li').addClass('search_entry_selected');
	},

	changePosition: function(direction){
		if (!this.selected) return;

		var other;
		switch ($type(direction)) {
			case 'event':
				other = $(direction.target);
				if (!other.match('li.search_result')) other = other.getParent('li.search_results');
				break;
			case 'string':
				other = this.selected[(direction == 'up') ? 'getPrevious' : 'getNext']('li.search_results');
		}
		if (!other) return;

		this.selected.removeClass('search_entry_selected');
		other.addClass('search_entry_selected');
		this.selected = other;
	},

	selectResult: function(event){
		var el;

		if (event) {
			el = event.stop().target;
			if (el.get('tag') != 'a') el = el.getParent('a');
		}

		else if (!this.selected) return;
		else el = this.selected.getElement('a');

		window.location.href = el.get('href');

		this.hideResults();
	},

	userInteract: function(){
		document.addEvent('mousedown', function(event){
			if($(event.target).getParent) { 
				if(!$(event.target).getParent('div.search')) this.hideResults();
			} else {
				// on IE flash object/embed element doesn't have a getParent
				// so hide it anyway if you're clicking on such an element
				this.hideResults();		
			}
		}.bind(this));

		this.search.addEvents({
			observedChange: function(value){
				(value.length > 2) ? this.request.post({search: value}) : this.hideResults();
			}.bind(this),
			keydown: function(event){
				switch(event.key){
					case 'esc':
						this.hideResults();
						break;
					case 'up': case 'down':
						this.changePosition(event.key);
						break;
					case 'enter':
						this.selectResult();
				}
			}.bind(this)
		});

		this.resultWrapper.addEvent('mouseover', this.changePosition.bind(this));
	}

});

window.addEvent('domready', function(){
	new LiveSearch('search_input', 'spinner_search', 'search_results');
});
