/*
 * 
 * @author Cosmobile
 * 
 * 
 *Add generic
 * 
 *Text:
 *    id*0
 *    label*
 *    orientation (LEFT | TOP ) (default LEFT)
 *    lenght (in caratteri) (default 80)
 * 	  maxlenght (in caratteri) (default = lenght)
 * 	  minlenght (in caratteri) (default = 0)
 * 	  required (true | false ) (default false)
 *
 *File
 *
 *Div
 *
 *Hidden
 *
 *Price
 *
 *Date 
 *
 *Time 
 *
 *Number
 *
 *Password
 *
 *Combo
 *
 *ComboByUrl
 *
 *Radio
 *
 *Checkbox
 *
 *TextArea
 *
 *Captcha
 *
 *List
 * 
 *combo by url
 *
 *multicheckbox by url
 *
 *Autocompleter
 *
 *Autocombo
 *
 *AutocomboDynamic
 *
 *MapPicker
 *
 *ColorPicker
 *
 *ImagePicker
 *
 *FilePicker
 */



var CosMooFC = new Class({
	Implements: [Events, Options],
	
	version:'0.7.1', //sistemati problemi di validazione (imagePicker e MultiField) by Jumpy
	LEFT: 'left',
	TOP: 'top',
	RIGHT: 'right',
	groups: new Array(),
	
	options:
	{
		id:'',
		lang: 'it',
		method: 'post',
		action: '',
		async: false,
		root_path: '',
		afterSubmit: null
	},

	initialize: function(options)
	{
		this.setOptions(options);
		this.id = this.options.id;
		this.form = this.createForm(this.options.action, this.options.method);
		this.validationForm;
		if(this.options.lang=="ita" || this.options.lang=="it" || this.options.lang==null)
			FormValidator.language = "itIT";
		else if(this.options.lang=="eng" || this.options.lang=="en")
			FormValidator.language = "enUS";
			
	},
	
	
	add: function(json)
	{
		var obj = this;
		if (!json.input) json.input = 'text';
		var action = 'create'+json.input.substr(0,1).toUpperCase() + json.input.substr(1);
		var res = eval('obj.'+action+'(json)');
		if(json.postLabel && json.input!="hidden")
		{
			var div = new Element('div', {'id':json.id+'PostLabel', 'class':'postLabel', 'html':json.postLabel});
			res.push(div);
		}
		
		if (json.tabindex)
		{
			if (res[1]) res[1].set('tabindex', json.tabindex);
			else if (json.input == 'submit' || json.input == 'button' || json.input == 'reset') res[0].set('tabindex', json.tabindex);
		}
		
		var hidden = false
		if (json.input=='hidden') hidden = true; 
		if (json.input=='group') return res;
		else return this.grab(json.id+'Content', res, hidden, json.group, json.classCnt); 
	},
	
	/*
	 * options: title, parent, className
	 */
	createGroup: function(options)
	{
		if (!options) options = {'name':'group'};
		var name = options.name || options.id;
		if (!this.groups.contains(name)) this.groups.push(name);
		var group = new Element('div', {'id':this.id+name+'Group'});
		
		if (options.title) 
		{
			var titDiv = new Element('div', {'html':options.title});
			titDiv.addClass('GroupTitle');
			group.grab(titDiv);
		}
		
		group.addClass('Groups');
		var cntGroup = this.form;
		if (options.parent)
		{
			var parent = this.getGroup(options.parent);
			if (parent) cntGroup = parent;
		}
		
		if (options.className) group.addClass(options.className);
		cntGroup.grab(group);
		return group;
	},
	
	removeGroup: function(name)
	{
		if (!this.groups.contains(name)) return; 
		this.groups.pop(name);
		var div = this.form.getChildren("#"+this.id+name+'Group');
		if (div.length!=0) div.destroy();
	},
	
	getGroup: function(name, parent)
	{
		if (!parent) parent = this.form;
		var obj = this;
		if (!this.groups.contains(name)) return false; 
		
		var div = parent.getChildren('#'+this.id+name+'Group');
		if (div.length>0) return div;
		//Else search into children
		div = parent.getChildren('.Groups');
		for(var i = 0; i<div.length; i++)
		{
			var res = this.getGroup(name, div[i]);
			if (res.length>0) return res;
		}
		
		return false;
		
	},
	
	getForm: function(){
		return this.form;
	},
	
	createForm: function(action, method)
	{
		var form = new Element('form',{'id':this.id+'Form', 'name':this.id+'Form','class':'forms','action':action, 'method':method});
		return form;
	},
	
	show: function(where)
	{
		$(where).set('html','');
		$(where).grab(this.form);
		
		//per compatibilita con ie7 devo checcare le checkbox dopo averle messe nel dom
		$$(".boxChecked").each(function(el){
			el.set("checked", "checked");
		});
	},
	
	addValidation: function(){
		try{this.validationForm = new FormValidator.Inline(this.form);}
		catch(ex){this.validationForm = new FormValidator(this.form);}
	},
	
	grab: function(id,els, hidden, group, classCnt)
	{
		var obj = this;
		var div;
		var cnt = this.form;
		if (group)
		{
			var groupDiv = obj.getGroup(group);
			if (groupDiv) cnt = groupDiv;
		}
	
		if (hidden)
		{
			div = els;
		}
		else
		{
			if (id)
				div = new Element('div',{'id':id,'class':'formRow'});
			else
				div = new Element('div',{'class':'formRow'});
			els.each(function(el){
				if(el)
					div.grab(el);
			});
		}
		
		if (classCnt) div.addClass(classCnt);
		
		cnt.grab(div);
		return div;
	},
	
	/*
	 * TODO: test populate
	 */
	populate: function(data)
	{
		this.form.getElements("input, select").each(function(el){
			if (['checkbox', 'radio'].contains(el.get('type'))) 
			{
				if (data[el.get('name')] && data[el.get('name')].value== el.value) el.checked = true;
			}
			else if (data[el.get('name')]) el.value =  data[el.get('name')].value;
		});
	},
	
	submitAction: function()
	{
		var obj = this;
		
		if (!this.modalizer)
		{
			this.modalizer = new Modalizer();
			this.modalizer.setModalOptions({'hideOnClick':false, 'layerId': 'SubmitLayer'});	
		}
		
		if (!this.options.action) return false;
		var req = new Request.JSON({
			async: false,
			url: obj.options.action,
			onRequest: function()
			{
				obj.modalizer.modalShow();
			},
			onComplete: function(json){
				obj.modalizer.modalHide();
				if (json && json.result && json.result=='ok')
				{
					if (obj.options.afterSubmit)
					{
						obj.options.afterSubmit(json);
					}
					else
					{
						var sticky = new StickyWin.Modal({'content':'Dati salvati correttamente', 'destroyOnClose':true, 'className': 'alertWin'});
						(function(){sticky.hide()}).delay(2000);
					}
					
					if (json.id) obj.lastInsertId = json.id;
				}
				else
				{
					var content = 'Errore';
					if (json && json.msg) content+= ': '+json.msg;
					new StickyWin.Modal({'content':content, 'destroyOnClose':true, 'className': 'alertWin'});
				}
					
			},
			onError: function(){
				new StickyWin.Modal({'content':'Generic Error Failure', 'destroyOnClose':true, 'className': 'alertWin'});
			}
		});
		
		if (this.method=='get') req.get(this.form);
		else req.post(this.form);
	},
	
	createEmptyRow: function(opt){
		var div = new Element('div', {
			'class': 'emptyRow'
		});

		if (opt.height!=null) div.setStyle('height',opt.height);
		return [div];
	},
	
	createDiv: function(opt){
		return [new Element('div', {'id':opt.id,'class':opt.classcss,'html':opt.html})];
	},
	
	createHidden: function(opt){
		var hidden = new Element('input',{'id':opt.id,'type':'hidden','value':opt.value, 'name':opt.name || opt.id});
		return hidden;
	},
	
	createSubmit: function(opt){
		var obj = this;
		if(opt.type=="button" || !opt.type)
			var valid = new Element('input',{'id':obj.id+'Submit','type':'button','value':opt.value});
		else if(opt.type=="img")
			var valid = new Element('input',{'id':obj.id+'Submit','type':'image','src':opt.value});
		else if(opt.type=="html")
			var valid = new Element('div',{'id':obj.id+'Submit', 'html':opt.value, 'style':'cursor: pointer;'});
		
		valid.addEvent('click',function(){
			if(!obj.validationForm || obj.validationForm.validate()==true)
			{
				if (opt.submitAction)
				{
					if ($type(opt.submitAction)=='string') eval(opt.submitAction);
					else opt.submitAction();
				}
				else obj.submitAction();
			}
		});
		
		return [valid];
	},
	
	createReset: function(opt){
		var obj = this;
		var button = new Element('input',{'id':opt.id,'type':'reset','value':opt.value});
		if(opt.className)
			button.set("class", opt.className);
		return [button];
	},
	
	createButton: function(opt){
		var obj = this;
		var button = new Element('input',{'id':opt.id, 'type':'button','value':opt.value});
		if(opt.className)
			button.set("class", opt.className);
		
		if (opt.action)
		{
			button.addEvent('click', function(ev){
				if($type(opt.action=='string')) eval(opt.action);
				else opt.action();
			});
		}
		return [button];
	},
	
	getLabel: function(opt){
		if(!opt.label)
			return null;
		var label = new Element('label',{'id':opt.id+'Label','class':'tfcLabel'});
		if (opt.orientation)
		{
			if (opt.orientation == this.LEFT)
			{
				label.setStyle('display','block');
				label.setStyle('float','left');
			}
			
			if (opt.orientation == this.RIGHT)
			{
				label.setStyle('display','block');
				label.setStyle('float','right');
			}
			
			if (opt.orientation == this.TOP)
			{
				label.setStyle('display','block');
			}
		}
		else
		{
			label.setStyle('display','block');
			label.setStyle('float','left');
		}
		label.set('html',opt.label);
		return label;
	},
	
	createText: function(opt)
	{
		if (!opt.id) alert('Manca id in addText!!');
		
		var text = new Element('input',{'type': 'text', 'id': opt.id, 'name': opt.name || opt.id, 'value': opt.value});
		var label = this.getLabel(opt);
		
		if (opt.width)
		{
			text.setStyle('width',opt.width);
		}
		//else text.setStyle('width',80);
		
		var validatorprops = new Hash();
		if (opt.maxLength){
			text.addClass('maxLength');
			validatorprops.include('maxLength',opt.maxLength);
		}
		else{
			validatorprops.include('maxLength',text.get('size'));
		}
		if (opt.minLength){
			text.addClass('minLength');
			validatorprops.include('minLength',opt.minLength);
		}		

		if (opt.email){
			text.addClass('validate-email');
			validatorprops.include('validate-email',opt.email);
		}
		
		if(opt.numeric)
		{
			text.addClass('validate-numeric');
			validatorprops.include('validate-numeric',opt.numeric);
		}
		
		if(opt.integer)
		{
			text.addClass('validate-integer');
			validatorprops.include('validate-integer',opt.integer);
		}
		
		if (opt.required){
			text.addClass('required');
			validatorprops.include('required',opt.required);
		}
		
		if (opt.msgPos)
			text.addClass("msgPos:'"+opt.msgPos+"'");
		
		if (validatorprops.getLength()!=0)
			text.setProperty('validatorprops',JSON.encode(validatorprops));
		
		if (opt.readonly){
			text.set('readonly', opt.readonly);
		}	
		
		return [label,text];
	},
	
	createCombo: function(opt)
	{	
		if (!opt.id) alert('Manca id in addComboByUrl!!');
		
	    var combo = new Element('select',{'id': opt.id, 'name': opt.name || opt.id});
		var label = this.getLabel(opt);

		if(opt.firstOption)
			var firstOption=opt.firstOption;
		else
			var firstOption='-- --- ---';
		var option = new Element('option',{'id':'re_none'+ opt.id, 'name': opt.id, 'value':'','html':firstOption});
		combo.grab(option);
		
		if(opt.width)				
			combo.setStyle('width',opt.width+'px');
		
		if (opt.opts)
		{
			opt.opts.each(function(op,index){
				var option = new Element('option',{'id':'re_'+opt.id+'_'+op.id,'value':op.id,
				'html':op.description});
				if (op.id==opt.value) option.set('selected', 'selected');
				combo.grab(option);
			});
		}
		
		if (opt.required){
			combo.addClass('required');
		}
		if (opt.readonly){
			combo.set('disabled', 'disabled');
		}
		
				
		return [label,combo];

	},
	
	//ComboByUrl
	createComboByUrl: function(opt)
	{	
		if (!opt.id) alert('Manca id in addComboByUrl!!');
		
	    var combo = new Element('select',{'id': opt.id, 'name': opt.id});
		var label = this.getLabel(opt);
		if(opt.firstOption)
			var firstOption=opt.firstOption;
		else
			var firstOption='-- --- ---';
		var option = new Element('option',{'id':'re_none'+ opt.id, 'name': opt.id, 'value':'','html':firstOption});
		combo.grab(option);
		if(opt.width)					
			combo.setStyle('width',opt.width+'px');
		
		if (opt.jsonp)
		{
			var req = new Request.JSONP({
				url: opt.url+'?rand=' + $random(0, 99999),
				data: {
					'requestType': opt.reqType
				},
				encode: 'utf-8',
				async:false,
				onComplete: function(resp){
					if(resp.opts)
					{
						resp.opts.each(function(op,index){
							var option = new Element('option',{'id':'re_'+op.id,'value':op.id,
							'html':op.description});
							if (op.id==opt.value) option.set('selected', 'selected');
							combo.grab(option);
						});
					}
				}
			}).send();
		}
		else
		{
			var req = new Request.JSON({
				url: opt.url+'?rand=' + $random(0, 99999),
				encode: 'utf-8',
				async:false,
				onComplete: function(resp){
					if(resp.opts)
					{
						resp.opts.each(function(op,index){
							var option = new Element('option',{'id':'re_'+op.id,'value':op.id,
							'html':op.description});
							if (op.id==opt.value) option.set('selected', 'selected');
							combo.grab(option);
						});
					}
				}
			}).post({
				'requestType': opt.reqType
			});
		}
		
		if (opt.required)
		{
			combo.addClass('required');
		}
		if (opt.readonly){
			combo.set('disabled', 'disabled');
		}
		
				
		return [label,combo];

	},
	//TextArea
	createTextArea: function(opt)
	{	
		if (!opt.id) alert('Manca id in addText!!');
		
		var text = new Element('textarea',{'id': opt.id, 'name': opt.id});
		var label = this.getLabel(opt);
		
		if(opt.value)
		{
			text.value = opt.value;
		}
		
		if (opt.width){
			text.setStyle('width',opt.width);
		}
		else if (opt.cols){
			text.set('cols',opt.cols);
		}else
			text.set('cols',50);
		if (opt.rows){
			text.set('rows',opt.rows);
		}else
			text.set('rows',5);
		
		var validatorprops = new Hash();
		if (opt.maxLength){
			text.addClass('maxLength');
			validatorprops.include('maxLength',opt.maxLength);
		}else{
			validatorprops.include('maxLength',text.get('size'));
		}
		if (opt.minLength){
			text.addClass('minLength');
			validatorprops.include('minLength',opt.minLength);
		}		
		if (validatorprops.getLength()!=0)
			text.setProperty('validatorprops',JSON.encode(validatorprops));

		if (opt.required){
			text.addClass('required');
			validatorprops.include('required',opt.required);
		}
		
		if (opt.readonly){
			text.set('readonly', opt.readonly);
		}
		//faccio lo store della tfc per ottenre il validator in caso di editor
		text.store("tfc", this);
		
		return [label,text];
	},
	
	//Password
	createPassword: function(opt)
	{	
		if (!opt.id) alert('Manca id in addPassword!!');
		
		var text = new Element('input',{'id': opt.id, 'type': 'password', 'name': opt.id, 'value': opt.value});
		var label = this.getLabel(opt);
		
		var validatorprops = new Hash();
		
		if (opt.width)
		{
			text.setStyle('width',opt.width);
		}
		
		if (opt.maxLength){
			text.addClass('maxLength');
			validatorprops.include('maxLength',opt.maxLength);
		}else{
			validatorprops.include('maxLength',text.get('size'));
		}
		if (opt.minLength){
			text.addClass('minLength');
			validatorprops.include('minLength',opt.minLength);
		}		
		if (validatorprops.getLength()!=0)
			text.setProperty('validatorprops',JSON.encode(validatorprops));

		if (opt.required){
			text.addClass('required');
			validatorprops.include('required',opt.required);
		}
		
		if (opt.readonly){
			text.set('readonly', opt.readonly);
		}
		
		return [label,text];
	},
	
	//Captcha
	createCaptcha: function(opt)
	{	
		var obj = this;
		var idcaptcha;
		var req = new Request.JSON({
			url: opt.url+'?rand=' + $random(0, 99999),
			encode: 'utf-8',
			async:false,
			onComplete: function(rsp){
				idcaptcha = rsp.idcaptcha;
			}
		}).post();
		var el = this.createText(opt);
		var captchaInput = new Element('div', {'id':opt.id+'Input'});
		captchaInput.grab(el[0]);
		captchaInput.grab(el[1]);
		var captchaCnt = new Element('div', {'id':opt.id+'Cnt'});
		var captchaImg = new Element('img', {'id':opt.id+'Img', 'src':opt.urlImg+idcaptcha+'.png', 'align':'absmiddle'});
		captchaImg.setStyle('border', '1px solid');
		captchaImg.setStyle('vertical-align', 'top');
		captchaCnt.grab(captchaImg);
		captchaCnt.grab(new Element('input', {'id':opt.id+'Id', 'name':opt.id+'Id', 'value': idcaptcha, 'type': 'hidden'}));
		captchaCnt.grab(new Element('div', {'html':'<a href="javascript: void(null);" onclick="refreshCaptcha()">clicca qui</a> per ottenere una nuova immagine', 'id':'captchaText'}));

		return [captchaInput, captchaCnt];
	},
	
    //Date
	createDate: function(opt)
	{	
		var el = this.createText(opt);
		if (!opt.immagine) opt.immagine = this.options.root_path+'immagini/calendarImg.gif';
		if (!opt.nopopup && !opt.readonly) el[2] = new Element('img', {'class':'calendarImg', 'src':opt.immagine, 'align': 'absmiddle'});
		if (!opt.width) el[1].setStyle('width', 100);
		if (!opt.readonly)
		{
			el[2].store('open', false);
			el[2].addEvent("click", function(){
				if (this.retrieve('open')) return;
				
				this.store('open', true);
				var dp = new DatePicker(el[1], {
					  'calendarId': 'FCCalendar'+opt.id, 
					  'format': '%d/%m/%Y',
					  'additionalShowLinks': new Array(this),
					  'showOnInputFocus': false,
					  'stickyWinOptions': {
						'zIndex': 50000
					  }
					});
				
				if (!opt.nopopup) dp.show();
				
				el[1].addEvent('keypress', function(ev){
					if (ev.key=='tab') dp.hide(); 
				});
			});
		}
		return el;
	},
	
	//ImagePicker
	createImagePicker: function(opt)
	{	
		var obj = this;
		if(!opt.urlAddImg)
			opt.urlAddImg = "funzioni/imgadd";
		if(!opt.urlDelImg)
			opt.urlDelImg = "funzioni/imgdel";
		
		opt.msgPos = opt.id+'Immagine';
		var el = this.createText(opt);
		el[1].set("readonly", "readonly");
		var immagine = new Element('div', {'id':opt.id+'Immagine', 'style':'overflow:hidden;'});
		var imagePick = new Element('div', {'id':opt.id+'Picker', 'style':'overflow:hidden;'});
		var buttCambia = new Element('div', {'class':'imagePickerButton', 'id':'linkImg'+opt.id});
		var buttDel = new Element('div', {'class':'imagePickerButton'});
		var imgDel = new Element('img', {'src':obj.options.root_path+"immagini/immagini_admin/icone/icona_delimg.png"});
		buttDel.set('html','<br/>Cancella');
		buttDel.grab(imgDel, "top");
		
		if(opt.value)
		{
			var img = new Element('img', {'id':opt.id+'Img', 'class':'imagePickerImg', 'src':obj.options.root_path+"scripts/imgresize.php?pic="+opt.path+"/"+opt.value+"&h=60&w=100", 'align':'absmiddle'});
			imagePick.grab(img);
			var divButt = new Element('div', {'id':opt.id+'Buttons', 'class':'imagePickerButtons', 'style':'overflow:hidden;'});
			var imgCambia = new Element('img', {'src':obj.options.root_path+"immagini/immagini_admin/icone/icona_cambiaimg.png"});
			buttCambia.set('html','<br/>Cambia');
			buttCambia.grab(imgCambia, "top");
		}
		else
		{
			var divButt = new Element('div', {'id':opt.id+'Buttons', 'class':'imagePickerButtons', 'style':'overflow:hidden;'});
			var imgCarica = new Element('img', {'src':obj.options.root_path+"immagini/immagini_admin/icone/icona_caricaimg.png"});
			buttCambia.set('html','<br/>Carica');
			buttCambia.grab(imgCarica, "top");
			buttDel.hide();
		}
		
		buttDel.addEvent('click', function(){
			var name = $(opt.id).value;
			var req = new Request.JSON({
				url: obj.options.root_path+opt.urlDelImg+'?rand=' + $random(0, 99999),
				encode: 'utf-8',
				async:false,
				onComplete: function(rsp){
					if(rsp.result=="ok")
					{
						var imgCnt = $(opt.id+'Picker');
						imgCnt.getFirst('img.imagePickerImg').destroy();
						$(opt.id).value = "";
						$('linkImg'+opt.id).set('html','<br/>Carica');
						var imgCarica = new Element('img', {'src':obj.options.root_path+"immagini/immagini_admin/icone/icona_caricaimg.png"});
						$('linkImg'+opt.id).grab(imgCarica, "top");
						buttDel.hide();
					}
					else
						alert(rsp.msg);
				}
			}).post({'img':name, 'url':opt.path});
		});
		
		divButt.grab(buttCambia);
		divButt.grab(buttDel);
		imagePick.grab(divButt);
		
		buttCambia.store('open', false);
		
		buttCambia.addEvent('mouseover', function(){
			if (this.retrieve('open')) return;
			this.store('open', true);
			var upl = new CosMooUpload({
				rootPath: obj.options.root_path,
				link: this,
				url: obj.options.root_path+opt.urlAddImg,
				linkAfter: '<img src="'+obj.options.root_path+'immagini/immagini_admin/icone/icona_cambiaimg.png"><br/>Cambia',
				target: el[1],
				targetPath: opt.path,
				limitMB: opt.limitMB || 2,
				typeFilter: {
					'Images (*.jpg, *.jpeg, *.gif, *.png)': '*.jpg; *.jpeg; *.gif; *.png'
				}
			});
			
		});
		
		buttCambia.addEvent('fileComplete', function(data){
			var imgCnt = $(opt.id+'Picker');
			if(imgCnt.getFirst('img.imagePickerImg'))
				imgCnt.getFirst('img.imagePickerImg').destroy();
			
			var newImg = new Element('img', {'src':obj.options.root_path+'scripts/imgresize.php?pic='+opt.path+'/'+data.file+'&h=60&w=100', 'class':'imagePickerImg'});
			newImg.inject(imgCnt.getChildren()[0], 'before');
			
			obj.validationForm.validateField(opt.id, true);
			buttDel.show();
		});
		
		el[1].addClass('imagePicker');

		immagine.grab(el[1]);
		immagine.grab(imagePick);
		return [el[0], immagine];
	},
	
	//ImagePicker
	createFilePicker: function(opt)
	{	
		var obj = this;
		if(!opt.urlAdd)
			opt.urlAdd = "funzioni/fileadd";
		if(!opt.urlDel)
			opt.urlDel = "funzioni/filedel";

		var el = this.createText(opt);
		el[1].set("readonly", "readonly");
		var immagine = new Element('div', {'id':opt.id+'Immagine', 'style':'overflow:hidden;'});
		var imagePick = new Element('div', {'id':opt.id+'Picker', 'style':'overflow:hidden;'});
		var buttCambia = new Element('div', {'class':'imagePickerButton', 'id':'linkImg'+opt.id});
		var buttDel = new Element('div', {'class':'imagePickerButton'});
		var imgDel = new Element('img', {'src':obj.options.root_path+"immagini/immagini_admin/icone/icona_delfile.png"});
		buttDel.set('html','<br/>Cancella');
		buttDel.grab(imgDel, "top");
		if(opt.value)
		{
			var size = '';
			if (opt.size) size = ' ('+opt.size+')';
			var a = new Element('a', {'html':opt.value+size, 'href':obj.options.root_path+opt.path+'/'+opt.value, 'target':'_blank'});
			var newFile = new Element('div', { 'class':'filePickerFile'});
			newFile.grab(a);
			imagePick.grab(newFile);
			
			var divButt = new Element('div', {'id':opt.id+'Buttons', 'class':'imagePickerButtons', 'style':'overflow:hidden;'});
			var imgCambia = new Element('img', {'src':obj.options.root_path+"immagini/immagini_admin/icone/icona_cambiafile.png"});
			buttCambia.set('html','<br/>Cambia');
			buttCambia.grab(imgCambia, "top");
			
		}
		else
		{
			var divButt = new Element('div', {'id':opt.id+'Buttons', 'class':'imagePickerButtons', 'style':'overflow:hidden;'});
			var imgCambia = new Element('img', {'src':obj.options.root_path+"immagini/immagini_admin/icone/icona_caricafile.png"});
			buttCambia.set('html','<br/>Carica');
			buttCambia.grab(imgCambia, "top");
			buttDel.hide();
		}
		
		
		buttDel.addEvent('click', function(){
			var name = $(opt.id).value;
			var req = new Request.JSON({
				url: obj.options.root_path+opt.urlDel+'?rand=' + $random(0, 99999),
				encode: 'utf-8',
				async:false,
				onComplete: function(rsp){
					if(rsp.result=="ok")
					{
						var imgCnt = $(opt.id+'Picker');
						imgCnt.getElements('.filePickerFile').each(function(el){
							el.destroy();
						});
						$(opt.id).value = "";
						$('linkImg'+opt.id).set('html','<br/>Carica');
						var imgCarica = new Element('img', {'src':obj.options.root_path+"immagini/immagini_admin/icone/icona_caricafile.png"});
						$('linkImg'+opt.id).grab(imgCarica, "top");
						buttDel.hide();
					}
					else
						alert(rsp.msg);
				}
			}).post({'file':name, 'url':opt.path});
		});
		
		divButt.grab(buttCambia);
		divButt.grab(buttDel);
		imagePick.grab(divButt);
		
		
		buttCambia.store('open', false);
		
		buttCambia.addEvent('mouseover', function(){
			if (this.retrieve('open')) return;
			this.store('open', true);
			var upl = new CosMooUpload({
				rootPath: obj.options.root_path,
				link: this,
				url: obj.options.root_path+opt.urlAdd,
				target: el[1],
				linkAfter: '<img src="'+obj.options.root_path+'immagini/immagini_admin/icone/icona_cambiafile.png"><br/>Cambia',
				targetPath: opt.path,
				typeFilter: opt.typeFilter || {
					'Tutti i files': '*.*'
				},
				limitMB: opt.limitMB || 8
			});
			
		});
				
		buttCambia.addEvent('fileComplete', function(data){
			var imgCnt = $(opt.id+'Picker');
			imgCnt.getElements('div.filePickerFile').each(function(img){
				img.destroy();
			});
			
			var a = new Element('a', {'html':data.file+' ('+data.size+')', 'href':obj.options.root_path+opt.path+'/'+data.file, 'target':'_blank'});
			var newFile = new Element('div', { 'class':'filePickerFile'});
			newFile.grab(a);
			newFile.inject(imgCnt.getChildren()[0], 'before');
			
			buttDel.show();
		});
		
		
		el[1].addClass('filePicker');
		immagine.grab(el[1]);
		immagine.grab(imagePick);
		return [el[0], immagine];
	},
	
    //File
	createFile: function(opt)
	{
		if (!opt.id) alert('Manca id in addFile!!');
		this.form.set('enctype','multipart/form-data');
		
		var text = new Element('input',{'type': 'file', 'id': opt.id, 'name': opt.id, 'value': opt.value});
		var label = this.getLabel(opt);
		
		var validatorprops = new Hash();
		if (opt.required){
			text.addClass('required');
			validatorprops.include('required',opt.required);
		}
		
		if (opt.readonly){
			text.set('readonly', opt.readonly);
		}	
		
		return [label,text];
	},

	//Price
	createPrice: function(opt)
	{
		var el = this.createText(opt)
		el[1].addEvent('change',function(){
			//TODO: approssimare e forzare n. decimali (a seconda della specifica di opt)
		});
		el[1].addClass('validate-numeric');
		return el;
	},
	
	//time
	createTime: function(opt)
	{
		if (!opt.step) opt.step = 5;
		if (!opt.minHour) opt.minHour = 0;
		if (!opt.maxHour) opt.maxHour = 24;
		
		opt.lenght = 5;
		opt.maxLength = 5;
		var el = this.createText(opt);
		el[1].addClass('isTime');
		el[1].addClass('minMaxTime');
		
		el[1].store('minHour', opt.minHour);
		el[1].store('maxHour', opt.maxHour);
		
		el[1].addEvent('focus', function(ev){
			$$('.timeOptCnt').each(function(el){el.destroy();});
			
			var div = new Element('div');
			div.addClass('timeOptCnt');
			div.setStyles({
				'position':'absolute',
				'z-index':20000
			});
			
			var hour = opt.minHour;
			var min = 0;
			var count=0;
			var scrollTo = null;
			do
			{
				var divHour = new Element('div', {'class':'divHour'});
				var txt = '';
				if (hour<10) txt+='0';
				txt+=hour+':';
				if (min<10) txt+='0';
				txt+=min;
				
				divHour.set('html', txt);
				
				if (txt==this.value)
				{
					scrollTo = divHour;
					divHour.addClass('selected');
				}
				
				min+=opt.step;
				if (min>=60)
				{
					hour++;
					min=0;
				}
				
				count++;
				div.grab(divHour);
				
				divHour.addEvent('click', function(ev){
					el[1].value = this.get('html');
					this.getParent().destroy();
				});
				
				
			}while(hour<opt.maxHour || hour==opt.maxHour && min==0);
			
			var coords = this.getPosition(this.getParent().getParent());
			var dim = this.getSize();
			div.setStyles({
				'top':coords.y,
				'left':coords.x+dim.x+5
			});
			
			div.addEvent('keyup', function(ev){
				if (ev.key!='esc') return;
				this.destroy();
			});
			
			div.inject(this.getParent().getParent());
			
			
			new Fx.Scroll(div, {'duration':0, 'offset':{'y':-40}}).toElement(scrollTo);

			this.store('timeDiv', div);
		});
		
		el[1].addEvent('keyup', function(ev){
			if (ev.key!='esc') return;
			var div = this.retrieve('timeDiv');
			div.destroy();
		});
		
		return el;
	},
	
	//Number
	createNumber: function(opt)
	{
		var el = this.createText(opt)
		el[1].addClass('validate-numeric');
		return el;
	},
	
	//Radio
	createRadio: function(opt)
	{	
		var obj = this;
		var divRadio = new Element('div',{'id':opt.id+'Div'});
		divRadio.addClass('tfcRadioList');
		
		if (!opt.id || !opt.opts) alert('Manca id o opts in Radio!!');
		obj._fillMultiField('radio', opt.opts, divRadio, opt);
		
		var label = this.getLabel(opt);

		return [label, divRadio];
	},
	
	//radioBool
	createRadioBool: function(opt)
	{	
		var obj = this;
		var divRadio = new Element('div',{'id':opt.id+'Div'});
		divRadio.addClass('tfcRadioList');
		
		if (!opt.id) alert('Manca id in RadioBool!!');
		if(!opt.yesValue)	opt.yesValue=1;
		if(!opt.yesDesc)	opt.yesDesc='si';
		if(!opt.noDesc)		opt.noDesc='no';
		
		var radios = [{'id':'si', 'value':opt.yesValue, 'description':opt.yesDesc, 'checked':(opt.checkValue==opt.yesValue)}, {'id':'no', 'value':opt.noValue, 'description':opt.noDesc, 'checked':(opt.checkValue==opt.noValue)}];
		opt.opts = radios;
		
		obj._fillMultiField('radio', opt.opts, divRadio, opt);
		
		var label = this.getLabel(opt);

		return [label, divRadio];
	},
	
	//RadioByUrl
	createRadioByUrl: function(opt)
	{	
		var obj = this;
		var divRadio = new Element('div',{'id':opt.id+'Div'});
		divRadio.addClass('tfcRadioList');
		if (!opt.id || !opt.url) alert('Manca id o url in Radio!!');
		
		if (opt.jsonp)
		{
			var req = new Request.JSONP({
				url: opt.url+'?rand=' + $random(0, 99999),
				data: {
					'requestType': opt.reqType
				},
				encode: 'utf-8',
				async:false,
				onComplete: function(rsp){
					obj._fillMultiField('radio', rsp.opts, divRadio, opt);
				}
			}).send();
		}
		else
		{
			var req = new Request.JSON({
				url: opt.url+'?rand=' + $random(0, 99999),
				encode: 'utf-8',
				async:false,
				onComplete: function(rsp){
					obj._fillMultiField('radio', rsp.opts, divRadio, opt);
				}
			}).post({
				'requestType': opt.reqType
			});
		}
		var label = this.getLabel(opt);

		return [label, divRadio];
	},
	
	//checkbox
	createCheckbox: function(opt)
	{	
		if (!opt.id) alert('Manca id in Checkbox!!');
		if(!opt.value)	opt.value=1;
		var nullvalue;
		if(isNaN(opt.value))	nullvalue='';
		else	nullvalue=0;
		
		var hiddenCheck;
		if(!opt.nohidden)
			hiddenCheck = new Element('input',{'type': 'hidden', 'id': opt.id+'Hidden', 'name': opt.name || opt.id, 'value': nullvalue});
		else
			hiddenCheck = null;
		var check = new Element('input',{'type': 'checkbox', 'id': opt.id, 'name': opt.name || opt.id, 'value': opt.value});
		check.addClass('checkbox');
		var label = this.getLabel(opt);
		
		if (opt.checkValue && opt.value == opt.checkValue)
		{
			check.set("checked", "checked");
			check.addClass("boxChecked");
		}
		
		if (opt.required) check.addClass('checkRequired');
		
		if (opt.orientation && label)
		{
			if (opt.orientation == this.LEFT)
			{
				label.setStyle('display','block');
				label.setStyle('float','left');
			}
			
			if (opt.orientation == this.RIGHT)
			{
				label.setStyle('display','block');
				label.setStyle('float','right');
			}
			
			if (opt.orientation == this.TOP)
			{
				label.setStyle('display','block');
			}
		}
		if (label) label.set('html',opt.label);
		
		var validatorprops = new Hash();
		if (validatorprops.getLength()!=0)
			check.setProperty('validatorprops',JSON.encode(validatorprops));
		
		if (opt.isChecked){
			check.addClass('isChecked');
			validatorprops.include('isChecked',opt.isChecked);
		}	
		
		if (!opt.width) check.setStyle('width', 20);
		
		return[label, hiddenCheck, check];
	},
	
	//MultiCheckboxByUrl
	createMultiCheckboxByUrl: function(opt)
	{	
		var obj = this;
		var divMultiCheck = new Element('div',{'id':opt.id+'Div'});
		divMultiCheck.addClass('tfcCheckList');
		if (!opt.id || !opt.url) alert('Manca id o url in MultiCheckbox!!');
		
		if (opt.jsonp)
		{
			var req = new Request.JSONP({
				url: opt.url+'?rand=' + $random(0, 99999),
				data: {
					'requestType': opt.reqType
				},
				encode: 'utf-8',
				async:false,
				onComplete: function(rsp){
					obj._fillMultiField('checkbox', rsp.opts, divMultiCheck, opt);
				}
			}).send();
		}
		else
		{
			var req = new Request.JSON({
				url: opt.url+'?rand=' + $random(0, 99999),
				encode: 'utf-8',
				async:false,
				onComplete: function(rsp){
					obj._fillMultiField('checkbox', rsp.opts, divMultiCheck, opt);
				}
			}).post({
				'requestType': opt.reqType
			});
		}
		var label = this.getLabel(opt);
		/*
		
		var validatorprops = new Hash();
		if (validatorprops.getLength()!=0)
			check.setProperty('validatorprops',JSON.encode(validatorprops));
		
		if (opt.isChecked){
			check.addClass('isChecked');
			validatorprops.include('isChecked',opt.isChecked);
		}	*/
		return [label, divMultiCheck];
	},
	
	//MultiCheckbox
	createMultiCheckbox: function(opt)
	{	
		var obj = this;
		var divMultiCheck = new Element('div',{'id':opt.id+'Div'});
		divMultiCheck.addClass('tfcCheckList');
		
		if (!opt.id || !opt.opts) alert('Manca id o opts in MultiCheckbox!!');
		obj._fillMultiField('checkbox', opt.opts, divMultiCheck, opt);
		
		var label = this.getLabel(opt);

		return [label, divMultiCheck];
	},
	
	_fillMultiField: function(type, json, cnt, opt)
	{
		var obj = this;
		if (!opt.name) opt.name = opt.id;
		if (type!='radio') opt.name+='[]';
		if(opt.tutte && type=="checkbox")
		{
			var tutte = new Element('input',{'type': type});
			tutte.addClass(type);
			tutte.setStyle('float','left');
			var subLabel = obj.getLabel({'label':'Seleziona tutti', 'orientation':obj.LEFT});
			subLabel.addClass('tfcList');
			var divCheck = new Element('div',{'id':opt.id+'_'+'TuttiDiv'});
			divCheck.grab(tutte);
			divCheck.grab(subLabel);
			cnt.grab(divCheck);
			
			tutte.addEvent("click", function(){
				var boxes = $$('#'+cnt.id+' input');
				if(tutte.checked==true)
				{
					boxes.each(function(el){el.checked=true;});
				}
				else
				{
					boxes.each(function(el){el.checked=false;});
				}
			});
		}
		json.each(function(op,index){
			var check = new Element('input',{'type': type, 'id': opt.id+'_'+op.id, 'name': opt.name, 'value': op.value});
			check.addClass(type);
			
			if (op.checked) check.set('checked', 'checked');
			else if(opt.checkValues && opt.checkValues.contains(op.id))
			{
				check.set("checked", "checked");
				check.addClass("boxChecked");
			}
			
			if (opt.required && index==0)
			{
				check.addClass('oneRequired');
				check.addClass("msgPos:'"+opt.id+"Content'");
			}
			if(opt.required && index>0)
			{
				check.addEvent('change', function(){
					obj.validationForm.validateField(opt.id+'_'+json[0].id, true);
				});
			}
			
			check.setStyle('float','left');
			
			var subLabel = obj.getLabel({'id':opt.id+'_'+op.id, 'label':op.description, 'orientation':opt.orientation});
			subLabel.addClass('tfcList');
			
			var divCheck = new Element('div',{'id':opt.id+'_'+op.id+'Div'});
			if(opt.classBox)
				divCheck.addClass(opt.classBox)
			
			
			divCheck.grab(check);
			divCheck.grab(subLabel);
			
			
			cnt.grab(divCheck);
		});
		if (opt.openOpt)
		{
			cnt.grab(new Element('input',{'type': 'text', 'id': opt.id+'_altro', 'name': opt.name}));
		}
		cnt.grab(new Element('div',{'styles':{'clear':'both'}}));	
	},
	
	createAutocompleter: function(opt)
	{
		if (!opt.id) alert('Manca id in addText!!');
		var obj = this;
		
		var text = new Element('input',{'type': 'text', 'autocomplete':'off', 'id': opt.id, 'name': opt.id, 'value': opt.value});
		var label = this.getLabel(opt);
		
		if (opt.width)
		{
			text.setStyle('width',opt.width);
		}
		
		var validatorprops = new Hash();
				
		if (opt.required){
			text.addClass('required');
			validatorprops.include('required',opt.required);
		}
		
		if (opt.readonly){
			text.set('readonly', opt.readonly);
		}	
		else
		{
			var tokens = opt.opts;
		    var completer1 = new Autocompleter.Local(text, tokens, {
		    	  'delay': 100,
		    	  'zIndex': opt.zIndex,
		    	  'filterSubset': false,
		    	  'filterTokens': function() {
		    	  var regex = new RegExp(this.queryValue.escapeRegExp(), 'i');
		    	  return this.tokens.filter(function(token){
		    		  return (regex.test(token[0]) || regex.test(token[1]));
		    	  });
		      },
		      'injectChoice': function(choice) {
		    	  var el = new Element('li');
		    	  el.set('html',this.markQueryValue(choice[0]));
		    	  el.adopt(new Element('span', {'class': 'example-info'}).set('html',this.markQueryValue(choice[1])));
		    	  el.inputValue = choice[0];
		    	  this.addChoiceEvents(el).injectInside(this.choices);
		      }
		      });
		 }
	     return [label,text];
	},

    createMapPicker: function(opt)
	{
		if (!opt.id) alert('Manca id in addText!!');
		var obj = this;

		var text = new Element('input',{'type': 'text', 'autocomplete':'off', 'id': opt.id, 'name': opt.id, 'value': opt.value});
		var label = this.getLabel(opt);

                var hiddenFld = new Array();
                
                ['Localita','Regione','Nazione','X','Y'].each(function(label){
                    hiddenFld.push(new Element('input',{'type': 'hidden', 'id': opt.id+'Geoloc'+label, 'name': opt.id+'Geoloc['+label.toLowerCase()+']'}));
                });

                opt.mapwidth = opt.mapwidth || 100;
                opt.mapheight = opt.mapheight || 100;

                opt.maptype = opt.maptype || 'roadmap';

                opt.mapkey = googleMapKey;

		if (opt.width)
		{
			text.setStyle('width',opt.width);
		}

		var validatorprops = new Hash();

		if (opt.required){
			text.addClass('required');
			validatorprops.include('required',opt.required);
		}

		if (opt.readonly){
			text.set('readonly', opt.readonly);
		}
		else
		{
                    Autocompleter.Request.Map = new Class({

                            Extends: Autocompleter.Request,

                            initialize: function(el, options) {
                                    this.parent(el, options);
                                    this.completeData = new Hash();
                                    this.coder = new google.maps.Geocoder({
                                        mapkey: opt.mapkey
                                    });
                                    this.request = null;

                                   
                            },
                            
                            query: function()
                            {
                                    var obj = this;
                                    var data = $unlink(this.options.postData) || {};
                                    data[this.options.postVar] = this.queryValue;
                                    var indicator = $(this.options.indicator);
                                    if (indicator) indicator.setStyle('display', '');
                                    var cls = this.options.indicatorClass;
                                    if (cls) this.element.addClass(cls);
                                    this.fireEvent('onRequest', [this.element, this.request, data, this.queryValue]);
                                    this.coder.geocode({'address': this.queryValue}, function(result, status) {
                                            var parsed = obj.parse(result, status);
                                            obj.queryResponse(parsed);
                                    });
                            },

                            parse: function(results, status) {
                                var obj = this;
                                var query = this.queryValue;
				var parsed = [];
				if (results && status && status == 'OK') {
					results.each(function( result, key) {
						if (result.geometry && result.geometry.viewport) {
							// place is first matching segment, or first segment
							parsed.push(result.formatted_address);
                                                        if (!obj.completeData.has(result.formatted_address))
                                                        {
                                                               obj.completeData.set(result.formatted_address, result);
                                                        }
						}
					});
				}
				return parsed;
                            },

                            queryResponse: function(response) {
                                    this.parent();
                                    this.update(response);
                            },

                            formatItem: function(item) {
                                var data = this.completeData.get(item);
				var src = 'http://maps.google.com/maps/api/staticmap?visible=' + data.geometry.viewport.getSouthWest().toUrlValue() + '|' + data.geometry.viewport.getNorthEast().toUrlValue() + '&size=' + opt.mapwidth + 'x' + opt.mapheight + '&maptype=' + opt.maptype + '&key=' + opt.mapkey + '&sensor=' + (opt.mapsensor ? 'true' : 'false');
				var place = data.formatted_address.replace(/,/gi, ',<br/>');

                                var img = new Element('img', {'src':src, width: opt.mapwidth, height: opt.mapheight});
                                img.setStyle('float', 'left');
                                var cnt = new Element('div');
                                cnt.setStyles({'clear':'both','margin-bottom':5, 'overflow': 'hidden'});
                                var txt = new Element('div', {'class':'place', 'html':place});
                                cnt.grab(img);
                                cnt.grab(txt);
                                return cnt;
                            },

                            setSelection: function(finish) {
                                this.parent(finish);
                                var data = this.completeData.get(this.selected.inputValue);
                                $(opt.id+'GeolocX').value = data.geometry.location.Ng;
                                $(opt.id+'GeolocY').value = data.geometry.location.Pg;

                                var addLnt = data.address_components.length;
                                $(opt.id+'GeolocLocalita').value = (addLnt>2)?data.address_components[addLnt-3].short_nam:data.address_components[0].short_name;
                                $(opt.id+'GeolocRegione').value = data.address_components[addLnt-2].short_name;
                                $(opt.id+'GeolocNazione').value = data.address_components[addLnt-1].short_name;
                            }

                    });

                    var completer1 = new Autocompleter.Request.Map(text, {
		    	  'delay': 100,
		    	  'zIndex': opt.zIndex,
		    	  'width': 200,
                          minLength: 3,
                           'injectChoice': function(choice) {
                              var el = this.formatItem(choice);
                              el.inputValue = choice;
                              this.addChoiceEvents(el).injectInside(this.choices);
                          }
                    });

                    
		 }
	     return [label,text].extend(hiddenFld);

	},
	
	
	createAutocombo: function(opt)
	{
		if (!opt.id) alert('Manca id in Autocombo!!');
		var obj = this;
		
		var fakeValue;
		var realValue;
		
		if (opt.value)
		{
			fakeValue = opt.value[0];
			realValue = opt.value[1];
		}
		
		var text = new Element('input',{'type': 'text', 'autocomplete':'off', 'id': opt.id+'Text', 'value': fakeValue});
		var input = new Element('input',{'type': 'hidden', 'id': opt.id, 'name': opt.id, 'value': realValue});
		var label = this.getLabel(opt);
		
		if (opt.width)
		{
			text.setStyle('width',opt.width);
		}
		else
			text.setStyle('width',80);
		
		var validatorprops = new Hash();
				
		if (opt.required){
			text.addClass('required');
			validatorprops.include('required',opt.required);
		}
		
		if (opt.readonly){
			text.set('readonly', opt.readonly);
		}	
		else
		{
			var tokens = null;
			if (opt.opts) tokens = opt.opts;
			else if (opt.url)
			{
				var req = new Request.JSON({
					url: opt.url,
					async: false,
					onComplete: function(resp)
					{
						resp.opt.each(function(el)
						{
							//TODO: converti in formato [[],[],[]]
						});
					}
				}).post();
			}
		    var completer1 = new Autocompleter.Local(text, tokens, {
		    	  'delay': 100,
		    	  'zIndex': opt.zIndex,
		    	  'width': 'auto',
		    	  'filterSubset': true,
		    	  'filterTokens': function() {
		    	  var regex = new RegExp(this.queryValue.escapeRegExp(), 'i');
		    	  return this.tokens.filter(function(token){
		    		  return (regex.test(token[0]));
		    	  });
		      },
		      'injectChoice': function(choice) {
		    	  var el = new Element('li');
		    	  el.set('html',this.markQueryValue(choice[0]));
		    	  //el.adopt(new Element('span', {'class': 'example-info'}).set('html',this.markQueryValue(choice[1])));
		    	  el.inputValue = choice[0];
		    	  el.store('idVal',choice[1])
		    	  this.addChoiceEvents(el).injectInside(this.choices);
		      }
		      });
	    	
		    input.store('completer',completer1);
		    input.addClass('isAutocombo');
		    
		    completer1.addEvent('select', function(el, sel,selection){
	    		$(opt.id).value = $(sel).retrieve('idVal');
	    	});
	    	
	    	completer1.addEvent('blur', function(el){
	    		el = $(el);
	    		var ok = false;
	    		var id = 0;
	    		opt.opts.each(function(token){
	    			if (token[0]==el.value)
	    			{
	    				id = token[1];
	    				ok = true;
	    			}
	    		});
	    		
	    		if (ok)
	    		{
	    			if ($(opt.id).value!=id) $(opt.id).value = id;
	    		}
	    		else $(opt.id).value = 0;
	    	});
		 }
		
		
	     return [label,text, input];
	},
	
	
	createAutocomboDynamic: function(opt)
	{
		if (!opt.id || !opt.url) alert('Manca id o url in AutocomboDynamic!!');
		var obj = this;
		
		var fakeValue;
		var realValue;
		
		if (opt.value)
		{
			fakeValue = opt.value[0];
			realValue = opt.value[1];
		}
		
		var text = new Element('input',{'type': 'text', 'autocomplete':'off', 'id': opt.id+'Text', 'value': fakeValue});
		var input = new Element('input',{'type': 'hidden', 'id': opt.id, 'name': opt.id, 'value': realValue});
		var label = this.getLabel(opt);
		
		if (opt.width)
		{
			text.setStyle('width',opt.width);
		}
		else
			text.setStyle('width',80);
		
		var validatorprops = new Hash();
				
		if (opt.required){
			input.addClass('required');
			validatorprops.include('required',opt.required);
		}
		
		var completer1 = null;
		
		if (opt.readonly){
			text.set('readonly', opt.readonly);
		}	
		else
		{
			var tokens = new Array();
			var onDigitF = null;
			if (opt.opts) tokens = opt.opts;
			else if (opt.url)
			{
				onDigitF = function()
				{
					flag = false;
					if (!this.req)
						this.req = new Request.JSON({
							url: opt.url,
							async: false,
							onRequest: function(){
								flag = true;
							},
							onComplete: function(resp)
							{
								completer1.tokens = resp;
								flag = false;
							},
							onCancel: function()
							{
								flag = false;
							}
						});
					
					if (!text.retrieve('lastValue') || !text.retrieve('lastValue').contains(this.lastValue) || 1)
					{
						if (flag) this.req.cancel();
						this.req.post({'filter':text.get('value')});
					}
					text.store('lastValue', text.get('value'));
				};

			}
			
			if (!opt.zIndex) opt.zIndex = 20000;
			
			var injectChoice = function(choice) {
		    	  var el = new Element('li');
		    	  el.set('html',this.markQueryValue(choice[0]));
		    	  //el.adopt(new Element('span', {'class': 'example-info'}).set('html',this.markQueryValue(choice[1])));
		    	  el.inputValue = choice[0];
		    	  el.store('idVal',choice[1])
		    	  this.addChoiceEvents(el).injectInside(this.choices);
		      };
			
		      if (opt.opts) completer1 = new Autocompleter.Local(text, tokens, {
		    	  'delay': 100,
		    	  'zIndex': opt.zIndex,
		    	  'width': 'auto',
		    	  'filterSubset': true,
		    	  'injectChoice': injectChoice
		      });
		      else
		      {
		    	  completer1 = new Autocompleter.Request.JSON(text, opt.url, {
						'delay': 100,
						'zIndex': opt.zIndex,
						'width': 'auto',
						//'TextDigit': onDigitF,
						'filterSubset': true,
						'injectChoice': injectChoice,
						'indicator': null,
						'multiple': true,
						'selectFirst': true,
						'selectMode': false,
						'minLength': 2

			      });

		      }
			
			//completer1.options.TextDigit();
	    	
		    input.store('completer',completer1);
		    input.addClass('isAutocombo');
		    
		    completer1.addEvent('select', function(el, sel,selection){
	    		$(opt.id).value = $(sel).retrieve('idVal');
	    	});
	    	
	    	/*completer1.addEvent('blur', function(el){
	    		el = $(el);
	    		var ok = false;
	    		var id = 0;

	    		this.tokens.each(function(token){
	    			
	    			if (token[0]==el.value)
	    			{
	    				id = token[1];
	    				ok = true;
	    			}
	    		});
	    		
	    		if (ok)
	    		{
	    			if ($(opt.id).value!=id) $(opt.id).value = id;
	    		}
	    		else $(opt.id).value = 0;
	    	});*/
		 }
		
		
	     return [label,text, input];
	},
	
	
	
	createColorPicker: function(opt){
		var els = this.createText(opt);
		var label = els[0];
		var text = els[1];
		var imgPick = new Element('img',{'src':'img/colorpicker.png','alt':'Scegli il colore', 'title':'Scegli il colore'});
		var picker = new Element('div');
		picker.grab(imgPick);
		text.setStyle('float','left');
		text.set('readonly','readonly');
		
		var start = 0;
		if (opt.start) start = opt.start;
		
		var stop = 256;
		if (opt.stop) stop = opt.stop;
		
		var step = 68;
		if (opt.step) step = opt.step;
		
		picker.addEvent('click',function(){
			
			if (this.win)
			{
				this.win.show();
			}
			else
			{
				var divCnt = new Element('div', {'id':'picker'+opt.id});
				divCnt.setStyle('overflow','hidden');
				
				for(var r = start;r<stop;r+=step)
					for(var g = start;g<stop;g+=step)
						for(var b = start;b<stop;b+=step)
						{
							var divCol = new Element('div',{'id':'rgb('+r+','+g+','+b+')'});
							divCol.setStyle('background-color','rgb('+r+','+g+','+b+')');
							divCol.setStyle('float','left');
							divCol.addClass('unpickedColor');
							
							if (text.value == divCol.get('id').rgbToHex())
							{
								divCol.addClass('pickedColor');
							}
							
							divCol.addEvent('click',function(){
								$$('.pickedColor').each(function(el2){ el2.removeClass('pickedColor')});
								this.addClass('pickedColor');
							})
							
							divCnt.grab(divCol);
						}
				
				this.win = new StickyWin({
					  content: StickyWin.ui('Scegli il colore', divCnt, {
					    width: '400px',
					    buttons: [
					      {
					        text: 'Chiudi', 
					        onClick: function(){}
					      },
					      {
						        text: 'Rimuovi', 
						        onClick: function(){
					    	  		text.set('value','');
					      		}
						  },
					      {
					        text: 'Scegli', 
					        onClick: function(){
							  var selEl = $$('.pickedColor');
							  if (selEl.length)
							  {
								  var selCol = selEl[0].get('id');
								  text.set('value',selCol.rgbToHex());
							  }
						  	}
					      }
					    ]
					  })
					});
				}
		});
		
		return [label, text, picker];
	},
	
	
	/*
	 * It evaluates a JSON like this:
	 *  
	 *  {
	 *  	voices: 
	 *  	[
	 *  		"id":id,
	 *  		... //all requested fields,
	 *  		"input": text|password|emptyRow|...
	 *  	]
	 *  }
	 */
	createByJSON: function(json)
	{
		var obj = this;
		json.voices.each(function(voice, index){             
         	if (voice.orientation) voice.orientation = eval('obj.'+voice.orientation.toUpperCase());         	
         	//var action = 'add'+voice.input.substr(0,1).toUpperCase() + voice.input.substr(1);
         	//eval('obj.'+action+'(voice)');
         	obj.add(voice);
         });
	},
	
	createByUrl: function(url, post)
	{
		var obj = this;
		if (!this.options.action) this.options.action = url;
		var r = new Request.JSON({
	       url: url,
	       async: obj.options.async,
	       onComplete: function(json){
                        if (json.voices)
                       {
			  obj.createByJSON(json);
			  obj.addValidation();
			  obj.fireEvent('createdByUrl');
                       }
                       else{
                           var msg = 'Errore interno';
                           if (json.msg) msg = json.msg;
                           $try(function() {new Sticky.Alert('Operazione fallita',msg);} , function(){alert(msg);});
                       }
	       }
		}).post(post);
	},
	
	/* 
	 * FUNZIONI PER LA RETROCOMPATIBILITA'
	 */
	
	addDiv: function(opt)
	{		
		opt.input = 'div';
		return this.add(opt);
	},
	
	addText: function(opt)
	{		
		opt.input = 'text';
		return this.add(opt);
	},
	
	addEmptyRow: function(opt)
	{		
		if (!opt) opt = {};
		opt.input = 'emptyRow';
		return this.add(opt);
	},
	
	addHidden: function(opt)
	{		
		opt.input = 'hidden';
		return this.add(opt);
	},
	
	addSubmit: function(opt)
	{		
		opt.input = 'submit';
		return this.add(opt);
	},
	
	addButton: function(opt)
	{		
		opt.input = 'button';
		return this.add(opt);
	},
	
	addReset: function(opt)
	{		
		opt.input = 'reset';
		return this.add(opt);
	},
	
	addRadio: function(opt)
	{		
		opt.input = 'radio';
		return this.add(opt);
	},
	
	addRadioBool: function(opt)
	{		
		opt.input = 'radioBool';
		return this.add(opt);
	},
	
	addRadioBUrl: function(opt)
	{		
		opt.input = 'radioByUrl';
		return this.add(opt);
	},
	
	addCombo: function(opt)
	{		
		opt.input = 'combo';
		return this.add(opt);
	},
	
	addComboByUrl: function(opt)
	{		
		opt.input = 'comboByUrl';
		return this.add(opt);
	},
	
	addTextArea: function(opt)
	{		
		opt.input = 'textArea';
		return this.add(opt);
	},
	
	addPassword: function(opt)
	{		
		opt.input = 'password';
		return this.add(opt);
	},
	
	addCaptcha: function(opt)
	{		
		opt.input = 'captcha';
		return this.add(opt);
	},
	
	addDate: function(opt)
	{		
		opt.input = 'date';
		return this.add(opt);
	},
	
	addImagePicker: function(opt)
	{		
		opt.input = 'imagePicker';
		return this.add(opt);
	},
	
	addFile: function(opt)
	{		
		opt.input = 'file';
		return this.add(opt);
	},
	
	addPrice: function(opt)
	{		
		opt.input = 'price';
		return this.add(opt);
	},
	
	addTime: function(opt)
	{		
		opt.input = 'time';
		return this.add(opt);
	},
	
	addNumber: function(opt)
	{		
		opt.input = 'number';
		return this.add(opt);
	},
	
	addCheckbox: function(opt)
	{		
		opt.input = 'checkbox';
		return this.add(opt);
	},
	
	addMultiCheckboxByUrl: function(opt)
	{		
		opt.input = 'multiCheckboxByUrl';
		return this.add(opt);
	},
	
	addAutocompleter: function(opt)
	{		
		opt.input = 'autocompleter';
		return this.add(opt);
	},
	
	addAutocombo: function(opt)
	{		
		opt.input = 'autocombo';
		return this.add(opt);
	},
	
	addColorPicker: function(opt)
	{		
		opt.input = 'colorPicker';
		return this.add(opt);
	},
	
	addGroup: function(name, opt)
	{		
		if (!opt) opt = {};
		opt.input = 'group';
		opt.name = name;
		return this.add(opt);
	}
	
});

FormValidator.implement({
	isVisible : function(field){
		if (!this.options.ignoreHidden) return true;
		while(field != document.body){
			if(document.id(field).get('tag')=="textarea" && document.id(field).getParent().hasClass('textEditor'))	return true;
			if(document.id(field).hasClass("imagePicker"))	return true;
			if (document.id(field).getStyle('display') == 'none') return false;
			field = field.getParent();
		}
		return true;
	}
});

DatePicker.implement({
	setUpObservers: function(){
		this.inputs.each(function(input) {
			if (this.options.showOnInputFocus) input.addEvent('focus', this.show.bind(this));
			input.addEvent('blur', function(e){
				if(!this.value)
				{
					return;
				}
				if (e) {
					this.selectedDates = this.getDates(null, true);
					this.fillCalendar(this.selectedDates.start);
					if (this.options.updateOnBlur) this.updateInput();
				}
			}.bind(this));
		}, this);
		this.options.additionalShowLinks.each(function(lnk){
			document.id(lnk).addEvent('click', this.show.bind(this))
		}, this);
	}
});


FormValidator.resources = {
	'enUS': {
		required:'This field is required.',
		isChecked:'This input field must be checked',
		isAutocombo:'The value inserted is not within the list of possibilities',
		isTime: 'Insert a valid time format',
		minMaxTime: 'Inserire a time between {min}:00 and {max}:00',
		minLength:'Please enter at least {minLength} characters (you entered {length} characters).',
		maxLength:'Please enter no more than {maxLength} characters (you entered {length} characters).',
		integer:'Please enter an integer in this field. Numbers with decimals (e.g. 1.25) are not permitted.',
		numeric:'Please enter only numeric values in this field (i.e. "1" or "1.1" or "-1" or "-1.1").',
		digits:'Please use numbers and punctuation only in this field (for example, a phone number with dashes or dots is permitted).',
		alpha:'Please use letters only (a-z) with in this field. No spaces or other characters are allowed.',
		alphanum:'Please use only letters (a-z) or numbers (0-9) only in this field. No spaces or other characters are allowed.',
		dateSuchAs:'Please enter a valid date such as {date}',
		dateInFormatMDY:'Please enter a valid date such as MM/DD/YYYY (i.e. "12/31/1999")',
		email:'Please enter a valid email address.',
		url:'Please enter a valid URL such as http://www.google.com.',
		currencyDollar:'Please enter a valid $ amount. For example $100.00 .',
		oneRequired:'Please enter something for at least one of these inputs.',
		errorPrefix: 'Error: ',
		warningPrefix: 'Warning: '
	},
	'itIT': {
		required:'Il campo deve essere compilato',
		isChecked:'La casella deve essere selezionata',
		isAutocombo:'Il campo inserito non e\' tra quelli disponibili',
		isTime: 'Inserire un orario valido',
		minMaxTime: 'Inserire un orario compreso tra le {min}:00 e le {max}:00',
		minLength:'Devono essere inseriti almeno {minLength} caratteri (ne hai inseriti {length}).',
		maxLength:'Possono essere inseriti al massimo {maxLength} caratteri (ne hai inseriti {length}).',
		integer:'Questo campo richiede un intero. Numeri decimali (es. 1.25) non sono consentiti.',
		numeric:'Questo campo richiede valori numerici (es. "1" o "1.1" o "-1" o "-1.1").',
		digits:'Questo campo richiede solo valori numerici con separatori (ad esempio, un numero di telefono con linette o punti).',
		alpha:'Inserire solo lettere (a-z) in questo campo. Spazi e altri caratteri non sono consentiti.',
		alphanum:'Inserire solo lettere (a-z) o numeri (0-9) in questo campo. Spazi e altri caratteri non sono consentiti.',
		dateSuchAs:'Inserire una data valida come {date}',
		dateInFormatMDY:'Inserire una data valida in formato MM/GG/AAAA (es. "12/31/1999")',
		email:'Inserire un indirizzo email valido.',
		url:'Inserire un url valido (es. http://www.google.com)',
		currencyDollar:'Inserire un importo in dollari valido. Ad esempio $100.00 .',
		oneRequired:'Compilare almeno uno di questi campi.',
		errorPrefix: 'Errore: ',
		warningPrefix: 'Attenzione: '
	}
};

MooTools.lang.set('en-US', 'FormValidator', {

	required:'This field is required.',
	isChecked:'This input field must be checked',
	isAutocombo:'The value inserted is not within the list of possibilities',
	isTime: 'Insert a valid time format',
	minLength:'Please enter at least {minLength} characters (you entered {length} characters).',
	maxLength:'Please enter no more than {maxLength} characters (you entered {length} characters).',
	integer:'Please enter an integer in this field. Numbers with decimals (e.g. 1.25) are not permitted.',
	numeric:'Please enter only numeric values in this field (i.e. "1" or "1.1" or "-1" or "-1.1").',
	digits:'Please use numbers and punctuation only in this field (for example, a phone number with dashes or dots is permitted).',
	alpha:'Please use letters only (a-z) with in this field. No spaces or other characters are allowed.',
	alphanum:'Please use only letters (a-z) or numbers (0-9) only in this field. No spaces or other characters are allowed.',
	dateSuchAs:'Please enter a valid date such as {date}',
	dateInFormatMDY:'Please enter a valid date such as MM/DD/YYYY (i.e. "12/31/1999")',
	email:'Please enter a valid email address. For example "fred@domain.com".',
	url:'Please enter a valid URL such as http://www.google.com.',
	currencyDollar:'Please enter a valid $ amount. For example $100.00 .',
	oneRequired:'Please enter something for at least one of these inputs.',
	errorPrefix: 'Error: ',
	warningPrefix: 'Warning: ',

	//FormValidator.Extras

	noSpace: 'There can be no spaces in this input.',
	reqChkByNode: 'No items are selected.',
	requiredChk: 'This field is required.',
	reqChkByName: 'Please select a {label}.',
	match: 'This field needs to match the {matchName} field',
	startDate: 'the start date',
	endDate: 'the end date',
	currendDate: 'the current date',
	afterDate: 'The date should be the same or after {label}.',
	beforeDate: 'The date should be the same or before {label}.',
	startMonth: 'Please select a start month',
	sameMonth: 'These two dates must be in the same month - you must change one or the other.'
});

MooTools.lang.set('it-IT', 'FormValidator', {

	required:'Il campo deve essere compilato',
	isChecked:'La casella deve essere selezionata',
	isAutocombo:'Il campo inserito non e\' tra quelli disponibili',
	isTime: 'Inserire un orario valido',
	minMaxTime: 'Inserire un orario compreso tra le {min}:00 e le {max}:00',
	minLength:'Devono essere inseriti almeno {minLength} caratteri (ne hai inseriti {length}).',
	maxLength:'Possono essere inseriti al massimo {maxLength} caratteri (ne hai inseriti {length}).',
	integer:'Questo campo richiede un intero. Numeri decimali (es. 1.25) non sono consentiti.',
	numeric:'Questo campo richiede valori numerici (es. "1" o "1.1" o "-1" o "-1.1").',
	digits:'Questo campo richiede solo valori numerici con separatori (ad esempio, un numero di telefono con linette o punti).',
	alpha:'Inserire solo lettere (a-z) in questo campo. Spazi e altri caratteri non sono consentiti.',
	alphanum:'Inserire solo lettere (a-z) o numeri (0-9) in questo campo. Spazi e altri caratteri non sono consentiti.',
	dateSuchAs:'Inserire una data valida come {date}',
	dateInFormatMDY:'Inserire una data valida in formato MM/GG/AAAA (es. "12/31/1999")',
	email:'Inserire un indirizzo email valido.',
	url:'Inserire un url valido (es. http://www.google.com)',
	currencyDollar:'Inserire un importo in dollari valido. Ad esempio $100.00 .',
	oneRequired:'Compilare almeno uno di questi campi.',
	errorPrefix: 'Errore: ',
	warningPrefix: 'Attenzione: ',
	
	//FormValidator.Extras

	noSpace: 'There can be no spaces in this input.',
	reqChkByNode: 'No items are selected.',
	requiredChk: 'This field is required.',
	reqChkByName: 'Please select a {label}.',
	match: 'This field needs to match the {matchName} field',
	startDate: 'the start date',
	endDate: 'the end date',
	currendDate: 'the current date',
	afterDate: 'The date should be the same or after {label}.',
	beforeDate: 'The date should be the same or before {label}.',
	startMonth: 'Please select a start month',
	sameMonth: 'These two dates must be in the same month - you must change one or the other.'
});

FormValidator.language = "itIT";
MooTools.lang.setLanguage("it-IT");

FormValidator.add('isChecked', {
	errorMsg: function(element, props){
		return FormValidator.getMsg('isChecked');
	}, 
	test: function(element) {
		return element.checked;
	}
});

FormValidator.add('isAutocombo', {
	errorMsg: function(element, props){
		return FormValidator.getMsg('isAutocombo');
	}, 
	test: function(element) {
		el = $(element);
		completer = el.retrieve('completer');
		var res = false;
		completer.tokens.each(function(token){
			if (token[1]==el.value)
			{
				res = true;
			}
		});
		
		return res;
		
	}
});

FormValidator.add('isTime', {
	errorMsg: function(element, props){
		return FormValidator.getMsg('isTime');
	}, 
	test: function(element) {
		var val = element.value;
		var firstNumber = '';
		var i;
		for(i =0; i<2, i<val.length; i++)
		{
			var c = val.charAt(i);
			if (c==':' || c=='.') break;
			else c = Number(c);
			if (isNaN(c)) return false;
			firstNumber+=''+c;
		}
		while (firstNumber.length<2) firstNumber = '0'+firstNumber;
		
		if (Number(firstNumber)>23) return false;
		
		var secondNumber = '';
		i++;
		for(i; i<val.length; i++)
		{
			var c = val.charAt(i);
			c = Number(c);
			if (isNaN(c)) return false;
			secondNumber+=''+c;
			if (secondNumber.length==2) break;
		}
		while (secondNumber.length<2) secondNumber = '0'+secondNumber;
		if (Number(secondNumber)>59) return false;
		
		element.value = firstNumber+':'+secondNumber;
		
		return true;
	}
});

FormValidator.add('minMaxTime', {
	errorMsg: function(element, props){
		var min = element.retrieve('minHour');
		var max = element.retrieve('maxHour');
		return FormValidator.getMsg('minMaxTime').substitute({
			'min':min,
			'max':max
		});
	}, 
	test: function(element) {
		var val = element.value;
		
		var min = element.retrieve('minHour');
		var max = Number(element.retrieve('maxHour'));
		
		if (min<10) min = '0'+min;
		if (max<10) max = '0'+max;
		
		if (val<min+':00' || val > max+':00' ) return false;
		
		return true;
	}
});

FormValidator.add('oneRequired', {
	errorMsg: FormValidator.getMsg.pass('oneRequired'), 
	test: function (element) {
		var p = element.parentNode.parentNode;
		return p.getElements('input').some(function(el) {
			if (['checkbox', 'radio'].contains(el.get('type'))) return el.get('checked');
			return el.get('value');
		});
	}
});

FormValidator.add('checkRequired', {
	errorMsg: FormValidator.getMsg.pass('required'), 
	test: function (element) {
		return element.get('checked');
	}
});

MooTools.lang.set('it-IT', 'Date', {

	months: ['Gennaio', 'Febbraio', 'Marzo', 'Aprile', 'Maggio', 'Giugno', 'Luglio', 'Agosto', 'Settembre', 'Ottobre', 'Novembre', 'Dicembre'],
	days: ['Domenica', 'Lunedi', 'Martedi', 'Mercoledi', 'Giovedi', 'Venerdi', 'Sabato'],
	dateOrder: ['date', 'month', 'year', '/'],
	shortDate: '%d/%m/%Y',
	shortTime: '%H:%M',
	AM: 'AM',
	PM: 'PM',

	/* Date.Extras */
	ordinal: function(dayOfMonth){
		//1st, 2nd, 3rd, etc.
		return (dayOfMonth > 3 && dayOfMonth < 21) ? 'th' : ['th', 'st', 'nd', 'rd', 'th'][Math.min(dayOfMonth % 10, 4)];
	},

	lessThanMinuteAgo: 'less than a minute ago',
	minuteAgo: 'about a minute ago',
	minutesAgo: '{delta} minutes ago',
	hourAgo: 'about an hour ago',
	hoursAgo: 'about {delta} hours ago',
	dayAgo: '1 day ago',
	daysAgo: '{delta} days ago',
	lessThanMinuteUntil: 'less than a minute from now',
	minuteUntil: 'about a minute from now',
	minutesUntil: '{delta} minutes from now',
	hourUntil: 'about an hour from now',
	hoursUntil: 'about {delta} hours from now',
	dayUntil: '1 day from now',
	daysUntil: '{delta} days from now'

});

MooTools.lang.setLanguage('it-IT');