/*
	Written by Yannick Van Avermaet
	v2.1 23/06/2009 14:35:46
	All rights reserved © 2009
*/

var i = 0;
			
var cAutocompleter = { }
cAutocompleter = Class.create({
	initialize: function(element, options) {
		element = $(element);
		this.element = element;
		this.options = options || {};
		this.inputs = this.options.input || {};
		this.errors = this.options.error || {};
		this.div = this.options.div || {};
		this.autocomp = this.options.autocomp || {};

		this.insertAfter = this.options.insertAfter || this.element;
		
		if(this.errors.message){
			this.error = document.createElement('span');
			
			if(this.errors.id && !$(this.errors.id)) this.error.id = this.errors.id;
			if(this.errors.message) this.error.innerHTML = this.errors.message;
			if(this.errors.className) this.error.className = this.errors.className;

			this.insertElement(this.error, this.insertAfter);
		}
		
		this.choices = document.createElement('div');
		
		this.choices.id = (this.div.id && !$(this.div.id)) ? this.div.id : 'choices'+x;
		if(this.div.className) this.choices.className = this.div.className;
		this.choices.style.display = 'none';
		
		this.insertElement(this.choices, this.element);		
		
		this.input = document.createElement('input');
		this.input.id = this.inputs.id && !$(this.inputs.id) ? this.inputs.id : 'autocompleter'+x;
		this.input.name = this.inputs.name || 'autocompleter'+x;
		if(this.inputs.className) this.input.className = this.inputs.className;
		this.input.value = this.inputs.value ? this.inputs.value : this.inputs.standard ? this.inputs.standard : '';
		
		if(this.inputs.size && this.inputs.size != '')
			this.input.size = this.inputs.size;
		
		this.insertElement(this.input, this.element);
			
		Event.observe(this.input,'focus',this.checkData.bindAsEventListener(this));
		Event.observe(this.input,'blur',this.checkData.bindAsEventListener(this));
		Event.observe(this.input,'keypress',this.checkData.bindAsEventListener(this));
	},
	
	addHiddenFields: function(arr){
		this.hiddenFields = arr;
		arr.each(function(tmp){		  	
			var obj = document.createElement('input');
			
			for(param in tmp){	
				var val = tmp[param];
				if(val != '') eval('obj.'+param+' = val;')
			}

			obj.type = 'hidden';
			this.insertElement(obj, this.insertAfter);
			
			eval('this.' + obj.id + ' = obj;');
			}.bind(this));
		},
	
	insertElement: function(div, after){
		$(after).insert({
			'after' : div
		});
	},
	
	resetHidden: function(){
		if(this.hiddenFields){
			this.hiddenFields.each(function(tmp){
				$(tmp.id).value = '';					
			});
		}
	},
	
	checkData: function(event){
		switch(event.type){
			case 'blur':
				if(this.input.value != ''){
					this.input.value = this.input.value;
					if(!this.verifyData(this.input.value)){
						this.timer = setTimeout(function(){
							this.timer = null;
							if(this.error) $(this.error.id).style.display = 'block';
							
							if(this.inputs.errorClass) $(this.input.id).addClassName(this.inputs.errorClass);
							
							eval(this.onFailed+'()');
							this.resetHidden();
						 }.bind(this),100);
					}
					else{
						if(this.inputs.errorClass) $(this.input.id).removeClassName(this.inputs.errorClass);
						if(this.inputs.className) $(this.input.id).addClassName(this.inputs.className);
					}
				}
				else{
					this.input.value = this.inputs.standard || '';
					if(this.error) $(this.error.id).style.display = 'none';
					if(this.inputs.errorClass) $(this.input.id).removeClassName(this.inputs.errorClass);
					
					eval(this.onFailed+'()');
					this.resetHidden();
				}
				break;
			case 'focus':
				if(this.timer) clearTimeout(this.timer);
				this.input.value = (this.input.value != this.inputs.standard) ? this.input.value : '';
				break;
			case 'keypress':
				break;
		}
	},
	
	verifyData: function(value){
		var regexFilter = /^(.*)\s-\s(.{4})$/i;
		return regexFilter.test(value);
	},
	
	parseData: function(text, li){
		var value;
		var regexFilter = /^(.*)\<strong\>(.*)\<\/strong\>(.*)$/i;
		if(regexFilter.test(li.innerHTML)){
			value = RegExp.$1 + '' + RegExp.$2 + '' + RegExp.$3;
			
			var obj = li;
			obj.setAttribute('value', value);
			
			$(this.input).value = value;
			if(this.error) $(this.error.id).style.display = 'none';
			if(this.options.input && this.options.input.errorClass)	$(this.input.id).removeClassName(this.options.input.errorClass);
			eval(this.onSucceed+'(obj)');
		}
		else{
			eval(this.onFailed+'()');
			this.resetHidden();
		}
	},
	
	execute: function(func1, func2){
		this.onFailed = func1;
		this.onSucceed = func2;
		this.element.remove();
		
		new Autocompleter.cLocal(this.input.id, this.choices.id, cities_a, {
			frequency : this.options.autocomp && this.options.autocomp.frequency ? this.options.autocomp.frequency : 0.000001,
			minChars : this.options.autocomp && this.options.autocomp.minChars ? this.options.autocomp.minChars : 2,
			afterUpdateElement : this.parseData.bind(this)
		});
	}
}),

/*
* Unlike Autocompleter.Local you can now pass along arrays in an array.
* The output will be <ul><li id=''></li></ul> instead of <ul><li></li></ul>
* It now has the same functionality as the basic autocompleter with ajax request
*/		
Autocompleter.cLocal = Class.create(Autocompleter.Base, {
	initialize: function(element, update, array, options) {
		this.baseInitialize(element, update, options);
		this.options.array = array;
	},

	getUpdatedChoices: function() {
		this.updateChoices(this.options.selector(this));
	},
	
	setOptions: function(options) {
		this.options = Object.extend({
			partialSearch: true,
			partialChars: 1,
			ignoreCase: true,
			fullSearch: false,
			selector: function(instance) {
				var ret       = []; // Beginning matches
				var partial   = []; // Inside matches
				var entry     = instance.getToken();
				var count     = 0;
		
				var first_letter;
				if(entry.length >= 1){
					first_letter = entry.substring(0,1).toLowerCase();
				}

				try{
					instance.options.array = eval('cities_'+first_letter);
				}
				catch(err){
					instance.options.array = eval('cities_special');	
				}
				for (var i = 0; i < instance.options.array.length; i++) { 
					if(instance.options.array[i] !== undefined){
						var elem = instance.options.array[i];
		
						var foundPos = instance.options.ignoreCase ? 
						elem[0].toLowerCase().indexOf(entry.toLowerCase()) : 
						elem[0].indexOf(entry);
		
						while (foundPos != -1) {
		
						if (foundPos == 0 && elem[0].length != entry.length) { 
							ret.push('<li id=\''+elem[1]+'\'><strong>' + elem[0].substr(0, entry.length) + '</strong>' + 
							elem[0].substr(entry.length) + '</li>');
							break;
						} 
						else if (entry.length >= instance.options.partialChars && instance.options.partialSearch && foundPos != -1) {
							if (instance.options.fullSearch || /\s/.test(elem[0].substr(foundPos-1,1)) || elem[0].substr(foundPos-1,1) == 0) {
								partial.push('<li id=\''+elem[1]+'\'>' + elem[0].substr(0, foundPos) + '<strong>' +
								elem[0].substr(foundPos, entry.length) + '</strong>' + elem[0].substr(foundPos + entry.length) + '</li>');
								break;
							}
						}
						foundPos = instance.options.ignoreCase ? 
						elem[0].toLowerCase().indexOf(entry.toLowerCase(), foundPos + 1) : 
						elem[0].indexOf(entry, foundPos + 1);
					}
				}
			}
			if (partial.length)
				ret = ret.concat(partial)
				
				if(ret == ''){
					return '<ul><li style=\'display:none\'></li></ul>';	
				}
				return '<ul>' + ret.join('') + '</ul>';
			}
		}, options || { });
	}
});

String.prototype.trim = function() {
    return this.replace(/^\s+|\s+$/, '');
}