/**
 * 
 * Routes Online - LiveSearch.js
 * Copyright © Fluid Creativity 2008
 *
 * Live Search functionality. Dependent on Mootools 1.2 SVN
 *
 * This is pretty tied in specifically to the routes site,
 * though it shouldn't be too difficult to re-use the code
 * with some minor changes (the markup for the results is
 * pretty unique to routes though).
 *
 */

var LiveSearch = new Class({
	
	Implements: Options,
	
	el: null,
	url: null,
	data: null,
	mode: 'full',
	timer: null,
	markup: null,
	fieldset: null,
	
	open: false,
	
	options: {
		duration: 300,
		transition: 'quad:out',
		searchDelay: 1000
	},
	
	initialize: function (el, url, options) {
		this.el = $(el);
		this.url = url;
		this.setOptions(options);
		this.setup();
		$('searchForm').addEvent('submit', this.onSubmit.bindWithEvent(this));
		this.el.addEvent('keyup', this.processEvent.bindWithEvent(this));
		this.el.addEvent('blur', this.hideResults.bindWithEvent(this));
	},
	
	setup: function () {
		this.fieldset = $('searchForm').getElement('fieldset');
		this.fieldset.store('originalHeight', this.fieldset.getSize().y);
	},
	
	processEvent: function (event) {
		switch (event.key) {
			case 'up':
				
				break;
			
			case 'down':
				
				break;
			
			case 'esc':
				this.hideResults();
				break;
			
			default:
				if (!event.alt && !event.meta) {
					this.mode = $('searchForm').getElement('ul.tabList').getElement('li.selected a').rel;
					
					if (this.timer) this.timer = $clear(this.timer);
					
					// delay searching until "hesitation" (no keypress for n seconds)
					this.timer = this.getResults.bind(this).delay(this.options.searchDelay);
				}
		}
	},
	
	// if you want to do anything special on form submission
	onSubmit: function (event) {
		event.stop();
	},
	
	getResults: function () {
		new Request.JSON({
			url: this.url,
			onComplete: function (data) {
				this.data = data;
				if (!this.open) {
					this.markup = this.buildResults();
					this.markup.inject(this.el, 'after');
					this.calculateNewHeight();
					this.displayResults();
				} else {
					this.markup.destroy();
					this.markup = this.buildResults().fade('show');
					this.markup.inject(this.el, 'after');
					this.calculateNewHeight();
					this.setNewHeight();
				}
			}.bind(this)
		}).get({ type: "live", lang: MultiLingual.langCode, query: this.el.value, mode: this.mode, limit: (this.mode == "airports" ? 5 : 3)});
	},
	
	// build the html content of the live search
	buildResults: function () {
		var search = new Element('div');
		var span = new Element('span').set('text', 'Results').inject(search);
		var em = new Element('em').set('text', 'Live').inject(span, 'top');
		var dl = new Element('dl').inject(search);
		var hasResults = false;
		
		$each(this.data, function (value, key) {
			if (value.length) {
				hasResults = true;
				var dt = new Element('dt').set('text', key).inject(dl);
				var dd = new Element('dd').inject(dl);
				var ul = new Element('ul').inject(dd);
				
				$each(value, function (el) {
					var li = new Element('li').inject(ul);
					var a = new Element('a', {
						'text': el.title.truncate(23),
						'href': el.url
					}).inject(li);
				});
			}
		});
		
		if (!hasResults) {
			new Element('p', { 'text': 'No Results' }).inject(search);
		}
		
		return search.fade('hide');
	},
	
	// display the live search
	displayResults: function () {
		var fx = new Fx.Tween(this.fieldset, {
			duration: this.options.duration,
			link: 'cancel',
			onComplete: function () {
				
				if (this.markup) {
					this.markup.fade('in');
				}
				
				if ($('liveSearchClose')) {
					$('liveSearchClose').destroy();
				} else {
					/* Adds a close button which doesn't really do anything, clicking it
					   simply moves the focus away from the form input, firing the blur event. */
					new Element('a', { id: 'liveSearchClose' }).set('text', MultiLingual.getString('js_close')).inject(this.fieldset);
				}
			}.bind(this)
		});
		
		this.fieldset.store('fx', fx);
		fx.start('height', this.fieldset.retrieve('newHeight'));
		this.open = true;
	},
	
	calculateNewHeight: function () {
		this.fieldset.store('newHeight', this.markup.getSize().y + parseInt(this.markup.getStyle('margin-bottom'), 10));
	},
	
	setNewHeight: function () {
		this.fieldset.setStyle('height', this.fieldset.retrieve('newHeight'));
	},
	
	// hide then destroy the live search markup and popup
	hideResults: function () {
		if (this.open && this.markup) {
			this.open = false;
			
			this.fieldset.setStyle('height', this.fieldset.retrieve('newHeight'));
			
			new Fx.Tween(this.markup).start('opacity', 0).chain(function () {
				this.markup = this.markup.destroy();
				this.fieldset.retrieve('fx').start('height', this.fieldset.retrieve('newHeight'), this.fieldset.retrieve('originalHeight'));
			}.bind(this));
		}
	}
	
});

