// Calendar: a Javascript class for Mootools that adds accessible and unobtrusive date pickers to your form elements <http://electricprism.com/aeron/calendar>
// Calendar RC4, Copyright (c) 2007 Aeron Glemann <http://electricprism.com/aeron>, MIT Style License.
// Mootools 1.2 compatibility by Davorin Šego

var DropDown = new Class({	

	// initialize: calendar constructor
	// @param obj (obj) a js object containing the form elements and format strings { id: 'format', id: 'format' etc }
	// @param props (obj) optional properties
	values: [],

	/**
	 * inp: id nel DOM dell'input che contiene il testo da cercare
	 * inpButton: id nel DOM del tasto per avviare la ricerca (non utilizzato, viene solo nascosto per ora)
	 * inpHidden: id nel DOM dell'input hidden che conterrà il valore da passare nel form
	 * inpLabel: id nel DOM dell'elemento nel quale verrà scritta in automatico la descrizione dell'oggetto selezionato
	 * list: id nel DOM dell'UL che conterrà i risultati della ricerca
	 * url: stringa che rappresenta la chiamata asincrona da fare per ottenere il risultato della ricerca.
	 *      le viene incollato subito dietro il valore contenuto nel tag inp 
	 */

	initialize: function(inp, inpButton, inpHidden, inpLabel, list, url, selectCB) {
	
		var populate = this.populate; 
		var refreshList = this.refreshList; 
		this.input = { 
				el: $(inp),
				button: $(inpButton),
				hidden: $(inpHidden),
				label: $(inpLabel)
		};
		this.target = {
				updated: false,
				selected: 0,
				hovered: 0,
				opened: false,
				name: list, 
				el: $(list)
		};
		this.input.button.setStyle('display', 'none');
		this.target.el.setStyle('class', 'ddBox');
		this.contractList();

		// valore di default preso dall'input hidden
		this.target.selected = this.input.hidden.get('value');

		this.selectCB = selectCB;
		
		this.input.el.addEvent('focus', function(e){
		}.bind(this));

		this.input.el.addEvent('keydown', function(e){
			if (e.key=='enter') {
				if (this.target.selected != 0) {
					this.contractList();
					e.stop();
					e.stopPropagation();
					return;
				} else {
					if (this.target.hovered) {
						this.selectVoice(this.target.hovered);
						this.contractList();
					}
					return;
				}
			}
			if (e.key=='tab') {
				if (this.target.selected != 0) {
					this.contractList();
					//e.stop();
					//e.stopPropagation();
					return;
				} else {
					if (this.target.hovered) {
						this.selectVoice(this.target.hovered);
						this.contractList();
					}
					return;
				}
			}
			
		}.bind(this));
		
		this.input.el.addEvent('keypress', function(e){
			if (e.key=='enter') {
				if (this.target.hovered) 
					this.contractList();
				e.stop();
				e.stopPropagation();
				return;
			}
		}.bind(this));
		
		this.input.el.addEvent('blur', function(e){
			if (this.target.el.getChildren().length == 1) {
				var el = this.target.el.getFirst('li');
				var id = el.get('id');
				if ($defined(el) && id!=null) {
					this.selectVoice(id);
					this.contractList();
				}
			}
		}.bind(this));
		
		this.input.el.addEvent('keyup', function(e){
		/* controllo della visibilità dell'elenco */
			var value = this.input.el.value;
			var end = value.length;
			if (end<3) {
				if (this.target.opened) 
					this.contractList();
				
				if (value=='*') {
					$each(this.target.el.getChildren(), function(item) {
						item.removeEvent('click');
						item.destroy();
					});
					this.target.selected = 0;
					this.input.hidden.set('value', -1);
				} else {
					this.selectVoice(0);
				}
				return
			} 
						
			if (e.key=='enter' || e.key=='tab' || e.key=='shift' || e.key=='left' || e.key=='right' || e.key=='home' || e.key=='end' || e.key=='ins') {
				e.stop();
				e.stopPropagation();
				return;
			}

			if (!this.target.opened) 
				this.expandList();
			
			if (e.key=='up') {
				this.hoverPreviousVoice();
				e.stop();
				e.stopPropagation();
				return;
			}
			if (e.key=='down') {
				this.hoverNextVoice();
				e.stop();
				e.stopPropagation();
				return;
			}
	
			
			/* chiamata asincrona per recuperare la lista interessata */
			var start = end;
			for (start=end; start>0 && value.charAt(start)!=','; start-- );
			if (value.charAt(start)==',')
				start++;
	
			if ((end-start) >= 3) {
				var search = value.substring(start);
				
				var myHTMLRequest = new Request.JSON({
					update: this.input.el, // l'elemento che verrà aggiornato al completamento della richiesta
					evalScripts: false, // gli script contenuti nel responso non verranno azionati
					onSuccess: function(res, xml) {
						//res = this.html_entity_decode(res);
						this.populate(res)
						this.refreshList();
					}.bind(this),
					onFailure: function() {
						alert('network error');
					}
				}).post(url+search);
				
			} 
		}.bind(this)) 

		return true;
	},

	
	populate: function(res){
		//alert('populate');
		/* clear the list */
		$each(this.target.el.getChildren(), function(item) {
			item.removeEvent('click');
			item.destroy();
		});

		this.selectVoice(0);
		if ($defined(res) && !$empty(res) && res.length!=0) 
		{
			var id=0;
			$each(res, function(item) {
				var li = new Element('li', {'id': this.target.name+'_'+item.id, 'rel': item.id, 'class': 'ddVoice'})
					.set('html', item.label+''+item.description+'').inject(this.target.el);
				var span = new Element('span', {'id': this.target.name+'_'+item.id+'_name', 'class': 'ddName'})
					.set('html', item.label).inject(li);
				var span = new Element('span', {'id': this.target.name+'_'+item.id+'_descr', 'class': 'ddDescr'})
					.set('html', item.description).inject(li);
			}.bind(this));	
			
			this.target.updated = true;			
			//alert('updated into: '+this.target.updated);
		} else {
			var li = new Element('li', {'class': 'ddVoice'})
				.set('text', 'Nessuno sport trovato').inject(this.target.el);
			this.target.updated = false;
		}
		return this.target.updated;
	},
	
	
	refreshList: function() {
		//alert('refreshList');
		this.target.selected = 0;
		this.target.hovered = 0;
		if (!this.target.updated) return;
		this.target.updated = false;
		
		$each(this.target.el.getChildren('li'), function(item) {
			item.addEvent('click', function(e) {
				this.selectVoice(e.target.id);
				this.contractList();
			}.bind(this));
		}.bind(this));
		
		return true;
	},
	
	
	selectVoice: function(id) {
		if (id!=0) {
			this.hoverVoice(id)
			this.target.selected = id;
			this.input.el.set('value', $(id+'_name').get('text'));
			this.input.hidden.set('value', $(id).get('rel'));
			//this.input.label.set('html', $(id+'_name').get('html')+''+$(id+'_descr').get('html'));

			if (this.selectCB!=undefined)
				this.selectCB();
		} else {
			if (this.target.hovered)
				this.dehoverVoice(this.target.hovered);
			this.target.selected = id;
			this.input.hidden.set('value', 0);
			//this.input.label.set('html', '');
		}
	},
	
	
	hoverVoice: function(id) {
		//alert('hoverVoice');
		if (this.target.hovered)
			this.dehoverVoice(this.target.hovered)
		
		this.target.hovered = id;
		$(id).addClass('selected');
	},
	
	
	dehoverVoice: function(id) {
		var el = $(id);
		if (el!=null)
			el.removeClass('selected');
	},
	
	
	hoverNextVoice: function() {
		//alert('hoverNextVoice');
		if (this.target.hovered) {
			var el = $(this.target.hovered).getNext();
			this.hoverVoice(el.id);
		} else {
			/* seleziona il primo della lista */
			this.target.el.getChildren('li:first-child').each(function(item) {
				//alert(item);
				this.hoverVoice(item.id);
			}.bind(this));
		}
	},
	
	
	hoverPreviousVoice: function(id) {
		if (this.target.hovered) {
			var el = $(this.target.hovered).getPrevious();
			this.hoverVoice(el.id);
		} else {
			/* seleziona il primo della lista */
			this.target.el.getChildren('li:last-child').each(function(item) {
				//alert(item);
				this.hoverVoice(item.id);
			}.bind(this));
		}

	},
	
	
	contractList: function() {
		this.target.el.removeClass('expanded');
		this.target.el.addClass('contracted');
		this.target.opened = false;
	},
	
	
	expandList: function() {
		this.target.el.addClass('expanded');
		this.target.el.removeClass('contracted');
		this.target.opened = true;
	}
	
});

DropDown.implement(new Events, new Options);
