///////////////////////////////////////////////////////////
// Class MapFilters
///////////////////////////////////////////////////////////

var MapFilters = Class.create({
	

	///////////////////////////////////////////////////////////
	// initialize
	///////////////////////////////////////////////////////////
	
	initialize:function(){
		
		// instatiate map
		this.map = new Map($('mapContainer'));
		
		// input field
		this.CITY_FIELD = $('cityField');
		this.POSTAL_CODE_FIELD = $('postalCodeField');
		this.FORM = $('findLocationForm');
		
		// keys
		this.KEY_ENTER 		= 13;
		this.KEY_ESC 		= 27;
		this.KEY_UP 		= 38;
		this.KEY_DOWN 		= 40;
		this.KEY_DELETE 	= 46;
		
		// results
		this.CITY_FIELD.up('fieldset').insert({ bottom: '<div id="results"></div>'});
		this.RESULTS_CONTAINER = $('results');
		this.RESULTS_CONTAINER.setStyle({ 
			'left' : this.CITY_FIELD.offsetLeft +'px',
			'top' : this.CITY_FIELD.offsetTop + this.CITY_FIELD.getHeight() + 'px',
			'width' : this.CITY_FIELD.getWidth() - 2 + 'px'
		})
		
		// IE fix
		if(Prototype.Browser.IE){
			this.RESULTS_CONTAINER.setStyle({ 'top': '70px' })
		}
	
		// hide results
		this.hideResults();
		
		// set indexes
		this.currentResultIndex = 0;
		this.currentNumResults	= 0;

		// listen for value change
		new Form.Element.Observer(this.CITY_FIELD, 1, this.onCityFieldChange.bind(this));
		
		// listen for form submit
		this.FORM.observe('submit', this.onFormSubmit.bind(this));
		
		// listen for keys
		this.CITY_FIELD.observe('keydown', this.onKeyDown.bind(this));
		
	},
	
	
	//////////////////////////////////////////////////////////
	// onCityFieldChange
	///////////////////////////////////////////////////////////
	
	onCityFieldChange:function(el){
		
		// if field is empty, no response is given, so results need to be cleared manually
		if($F(el) == '' || $F(el) == $(el).defaultValue){
			this.RESULTS_CONTAINER.update('');
			this.resetCurrentResultIndex();
			this.hideResults();
			
		}else{
		
			// if not in timeout
			if(!this.timeout){
			
				// do ajax request
				new Ajax.Request('.', { 
					parameters: { 
						gemeente: $F(el)
					}, 
					method: "get",
					onSuccess: function(transport){
				
						// show results
						this.showResults();
					
						// reset results
						this.resetCurrentResultIndex();
				
						// json object
						var jsonArr = transport.responseText.evalJSON();
				
						// set current results number
						this.currentNumResults = jsonArr.size();
				
						// results html
						var resultsHTML = '';
					
						// id's: used for filtering
						var resultsArr = [];
					
						// if there are results
						if(jsonArr.size() > 0){
				
							// get all results
							jsonArr.each(function(el, i){
						
								// add class to first and last
								var klass = '';
								if(i == 0){	klass = ' class="first"';	}
								if(i == jsonArr.size() - 1){ klass = ' class="last"'; }
	
								// if more than 1 id is used, split them with ,
								var id = '';
								if(el.ggdlocations.size() > 1){
									for(var l=0; l < el.ggdlocations.size(); ++l){
										id += el.ggdlocations[l].id + ',';
										resultsArr.push(el.ggdlocations[l].id);
									}
							
								// if only 1 location
								}else{
									id = el.ggdlocations[0].id;
									resultsArr.push(el.ggdlocations[0].id);
								}
							
								// legend
								var legend = '';
								var type = el.meta_type;
								if(i > 0){
									if(jsonArr[i-1].meta_type !== el.meta_type){
										if(jsonArr[i+1]){
											if(jsonArr[i+1].meta_type === el.meta_type){
												type = el.meta_type_plural;
											}
										}
										
										legend = '<span class="legend">'+ type.substr(0, 1).toUpperCase() + type.substr(1, type.length) +'</span>';
									}
								}else{
									if(jsonArr[i+1]){
										if(jsonArr[i+1].meta_type === el.meta_type){
											type = el.meta_type_plural;
										}
									}
									legend = '<span class="legend">'+ type.substr(0, 1).toUpperCase() + type.substr(1, type.length) +'</span>';
								}
								// output result
								resultsHTML += '<li'+ klass +'>'+ legend +'<a href="#'+ id +'" title="">'+ el.name +'</a></li>';
							
							
							}.bind(this));
				
							// update results container
							this.RESULTS_CONTAINER.update('<ul>'+ resultsHTML +'</ul>');
					
							// show results
							this.showResults();
					
							// listen for mouse events
							$$('#'+ this.RESULTS_CONTAINER.identify() +' a').invoke('observe', 'mouseover', this.onResultMouseOver.bind(this));
							$$('#'+ this.RESULTS_CONTAINER.identify() +' a').invoke('observe', 'click', this.selectFromMouse.bind(this));
					
						// if there are no results	
						}else{
							this.hideResults();
						}
					
						// live filter on map
						this.map.filter(resultsArr);
				
					}.bind(this)
				})
			}
		}
	},
	
	
	//////////////////////////////////////////////////////////
	// onPostalCodeFieldChange
	///////////////////////////////////////////////////////////
	
	onPostalCodeFieldChange:function(el){
	
			// do ajax request
			new Ajax.Request('.', { 
				parameters: { 
					postcode: $F(el)
				}, 
				method: "get",
				onSuccess: function(transport){
					
					// json object
					var jsonArr = transport.responseText.evalJSON();
					
					// id's: used for filtering
					var resultsArr = [jsonArr.id];
					
					this.hideResults();
					
					// filter on map
					this.map.filter(resultsArr);
				
				}.bind(this)
			})
		
	},
	
		
	//////////////////////////////////////////////////////////
	// onKeyDown
	///////////////////////////////////////////////////////////
	
	onKeyDown:function(e){

		var code;
		if (!e) var e = window.event;
		if (e.keyCode) code = e.keyCode;
		else if (e.which) code = e.which;
		var character = String.fromCharCode(code);
		
		switch(code){
			
			// key down
			case this.KEY_DOWN:
				this.down(e);
			break;
			
			// key up
			case this.KEY_UP:
				this.up(e);
			break;

			// key enter
			case this.KEY_ENTER:
				this.selectFromKeyboard(e);
			break;
			
			// key up
			case this.KEY_ESC:
				this.hideResults();
			break;
			
		}
		
	},
		
		
	//////////////////////////////////////////////////////////
	// moveDown
	///////////////////////////////////////////////////////////
	
	down:function(e){
		Event.stop(e);
		if(this.resultsAreHidden && this.currentNumResults > 0){
			this.showResults();
		}else{
			if(this.currentResultIndex < this.currentNumResults){
				++this.currentResultIndex;
			}else{
				this.currentResultIndex = 1;
			}
		
			// set active class
			this.setActiveClass();
		
		}
	},
	
	
	//////////////////////////////////////////////////////////
	// moveUp
	///////////////////////////////////////////////////////////
	
	up:function(e){
		Event.stop(e);
		if(this.resultsAreHidden && this.currentNumResults > 0){
			this.showResults();
		}else{
			
			if(this.currentResultIndex > 1){
				--this.currentResultIndex;
			}else{
				this.currentResultIndex = this.currentNumResults;
			}
		
			// set active class
			this.setActiveClass();
		}
	},
	
		
	//////////////////////////////////////////////////////////
	// select
	///////////////////////////////////////////////////////////
	
	selectFromKeyboard:function(e){
		
		// stop event
		Event.stop(e);
		
		// select
		this.select();
	},	
	
	
	selectFromMouse:function(e){
		
		// stop event
		Event.stop(e);
		
		// set current result
		this.setResultIndexByElement(Event.element(e));
		
		// select
		this.select();
	},
	
	
	select:function(){
		
		// find current list item
		var li = $$('#results ul li')[this.currentResultIndex-1];
		
		// if none selected (yet), select the first
		if(this.currentResultIndex == 0 && !li){
			li = $$('#results ul li')[0];
			this.currentResultIndex = 1;
			this.setActiveClass();
		}
		
		if(li){
			
			// set a timeout: Form observer will trigger change event when value changes
			this.timeout = setTimeout(this.deleteTimeout.bind(this), 1000);
		
			// get list item values (text, id)
			var values = this.getListItemValues(li);
			var ids = values.id.split(',');
		
			// put it in input
			this.setInputValue(values.text);
		
			// hide results
			this.hideResults();
		
			// show on map
			this.map.filter(ids);
			
		}
		
	},
	
		
	//////////////////////////////////////////////////////////
	// getListItemValue
	///////////////////////////////////////////////////////////
	
	getListItemValues:function(li){
		var values = {};
		values.text = li.down('a').innerHTML;
		values.id = li.down('a').readAttribute('href').split('#')[1];
		
		return values;
	},
	
		
	//////////////////////////////////////////////////////////
	// setInputValue
	///////////////////////////////////////////////////////////
	
	setInputValue:function(val){
		this.CITY_FIELD.value = val.unescapeHTML();
	},
	
	
	//////////////////////////////////////////////////////////
	// setActiveClass
	///////////////////////////////////////////////////////////

	setActiveClass:function(){
		$$('#results ul li').each(function(el, index){
			if(index == this.currentResultIndex - 1){
				el.addClassName('active');
			}else{
				el.removeClassName('active');
			}
		}.bind(this))
	},	
	
		
	//////////////////////////////////////////////////////////
	// show / hide results
	///////////////////////////////////////////////////////////
	
	hideResults:function(){
		this.resultsAreHidden = true;
		this.RESULTS_CONTAINER.hide();
	},
	
	showResults:function(){
		this.resultsAreHidden = false;
		this.RESULTS_CONTAINER.show();
	},
	
	
	//////////////////////////////////////////////////////////
	// current result index
	///////////////////////////////////////////////////////////
	
	resetCurrentResultIndex:function(val){
		this.currentResultIndex = 0
	},	
	
	
	setResultIndexByElement:function(origEl){
		
		// find all results
		$$('#results ul li a').each(function(el, index){
			
			// match em to the one hovered
			if(el.identify() == origEl.identify()){
				
				// set result index
				this.currentResultIndex = index+1;
				
				// set active class
				this.setActiveClass();
			}
		}.bind(this));
	},
	
	
	//////////////////////////////////////////////////////////
	// deleteTimeout
	///////////////////////////////////////////////////////////
	
	deleteTimeout:function(){
		clearTimeout(this.timeout);
		delete this.timeout;
	},
	
	
	//////////////////////////////////////////////////////////
	// onResultMouseOver
	///////////////////////////////////////////////////////////
	
	onResultMouseOver:function(e){
		this.setResultIndexByElement(Event.element(e));
	},
	
		
	//////////////////////////////////////////////////////////
	// onResultMouseOver
	///////////////////////////////////////////////////////////
	
	onFormSubmit:function(e){
		Event.stop(e);
		
		// postal code is empty
		if(!isEmpty(this.POSTAL_CODE_FIELD)){
			this.onPostalCodeFieldChange(this.POSTAL_CODE_FIELD);
			return true;
		}
		
		// city field is empty
		if(!isEmpty(this.CITY_FIELD)){
			this.onCityFieldChange(this.CITY_FIELD);
			return true;
		}
		
	}
});



//////////////////////////////////////////////////////////////////////////

document.observe('dom:loaded', function(){
	
	// new map
	mapFilters = new MapFilters();

});
