/*
 * 
 * @author Cosmobile
 * 
 * 
 *Text:
 *    id*
 *    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 
 *
 *Password
 *
 *Combo
 *
 *Radio
 *
 *Checkbox
 *
 *TextArea
 *
 *Captcha
 *
 *List
 * 
 * combo by url
 *
 * multicheckbox by url
 *
 *
 * TODO:
 * Validation in multicheckbox
 */

var TaedoFormCreator = new Class({
	Implements: [Events, Options],
	
	version:'0.0.9',//added addHidden by Jumpy
	LEFT: 'left',
	TOP: 'top',
	RIGHT: 'right',
	
	options:
	{
		id:''
	},

	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";
			
	},
	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);
	},
	
	addValidation: function(){
		this.validationForm = new FormValidator(this.form);
	},
	
	grab: function(id,els)
	{
		var div;
		if (id)
		 div = new Element('div',{'id':id,'class':'formRow'});
		else
		  div = new Element('div',{'class':'formRow'});
		els.each(function(el){div.grab(el);});
		this.form.grab(div);
	},
	
	addEmptyRow: function(){
		this.grab(null,[new Element('div', {
			'class': 'emptyRow'
		})]);
	},
	
	addDiv: function(opt){
		this.grab(null,[new Element('div', {'id':opt.id,'class':opt.classcss,'html':opt.html})]);
	},
	
	addHidden: function(opt){
		var hidden = new Element('input',{'id':opt.id,'type':'hidden','value':opt.value, 'name':opt.name});
		this.grab(null,[hidden]);
	},
	
	addSubmit: function(opt){
		var obj = this;
		if(opt.type=="button")
			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.validate()==true)
				opt.submitAction();
		});
		
		obj.grab(valid.id+'Content',[valid]);
	},
	
	addButton: 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);
		obj.grab(button.id+'Content',[button]);
		return button;
	},
	
	getLabel: function(opt){
		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');
			}
		}
		label.set('html',opt.label);
		return label;
	},
	
	createText: function(opt)
	{
		if (!opt.id || !opt.label) alert('Manca label o id in addText!!');
		
		var text = new Element('input',{'type': 'text', 'id': opt.id, '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 (validatorprops.getLength()!=0)
			text.setProperty('validatorprops',JSON.encode(validatorprops));

		if (opt.email){
			text.addClass('validate-email');
			validatorprops.include('validate-email',opt.email);
		}
		
		if (opt.required){
			text.addClass('required');
			validatorprops.include('required',opt.required);
		}
		
		if (opt.readonly){
			text.set('readonly', opt.readonly);
		}	
		
		return [label,text];
	},
	
	addText: function(opt)
	{		
		this.grab(opt.id+'Content',this.createText(opt));
	},
	
	//ComboByUrl
	addComboByUrl: function(opt)
	{	
		if (!opt.id || !opt.label) alert('Manca label o 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)
			var width=opt.width;
		else
			var width='149';					
		combo.setStyle('width',width+'px');
		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');
			
		}
		
				
		this.grab(opt.id+'Content',[label,combo]);

	},
	//TextArea
	addTextArea: function(opt)
	{	
		if (!opt.id || !opt.label) alert('Manca label o id in addText!!');
		
		var text = new Element('textarea',{'id': opt.id, 'name': opt.id, 'html': opt.value});
		var label = this.getLabel(opt);
		
		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);
		}
		
		this.grab(opt.id+'Content',[label,text]);
	},
	
	//Password
	addPassword: function(opt)
	{	
		if (!opt.id || !opt.label) alert('Manca label o 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);
		}else
			text.setStyle('width',80);
		
		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);
		}
		
		this.grab(opt.id+'Content',[label,text]);
	},
	
	//Captcha
	addCaptcha: function(opt)
	{	
		var el = this.createText(opt);
		el[2] = new Element('img', {'id':'captchaImg', 'src':opt.captchaImg});
		el[1].set('size', 10);
		this.grab('captchaContent', el);
	},
	
    //Date
	addDate: function(opt)
	{	
		var el = this.createText(opt);
		el[2] = new Element('img', {'id':'calendarImg', 'src':'immagini/calendarImg.gif', 'align': 'absmiddle'});
		el[1].set('size', 10);
		this.grab(opt.id+'Content', el);
		new DatePicker(el[1], {
			  //additionalShowLinks:['calendarImg'],
			  format: '%d/%m/%Y'//01/01/2009
			});
	},
	
    //File
	addFile: function(opt)
	{
		if (!opt.id || !opt.label) alert('Manca label o 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);
		}	
		
		el = [label,text];
		this.grab(opt.id+'Content', el);
	},

	//Price
	addPrice: function(opt)
	{
		var el = this.createText(opt)
		el[1].addClass('validate-digits');
		this.grab(opt.id+'Content', el);
	},
	
	//time
	addTime: function(opt)
	{
		opt.lenght = 5;
		opt.minLength = 5;
		opt.maxLength = 5;
		var el = this.createText(opt);
		
		this.grab(opt.id+'Content',el);
		
	},
	
	//radio
	addRadio: function(opt)
	{	
		if (!opt.buttons || !opt.name) alert('Manca buttons o name in addRadio!!');
		
		var obj = this;
		opt.buttons.each(function(el, index){
			var radio = new Element('input',{'id': el.id, 'type': 'radio', 'name': opt.name, 'value': el.value});
			var label = obj.getLabel(el);
			
			var validatorprops = new Hash();
			
			if (opt.required){
				if(index==0)
				{
					radio.checked = true;
				}
			}
			
			if (validatorprops.getLength()!=0)
				radio.setProperty('validatorprops',JSON.encode(validatorprops));
			
			if (opt.readonly){
				radio.set('readonly', opt.readonly);
			}	
			
			obj.grab(el.id+'Content', [label,radio]);
		})
		
		
	},
	
	//checkbox
	addCheckbox: function(opt)
	{	
		if (!opt.id || !opt.label) alert('Manca label o id in Checkbox!!');
		if(!opt.value)	opt.value=1;
		var nullvalue;
		if(isNaN(opt.value))	nullvalue='';
		else	nullvalue=0;
		
		var hiddenCheck = new Element('input',{'type': 'hidden', 'id': opt.id, 'name': opt.id, 'value': nullvalue});
		var check = new Element('input',{'type': 'checkbox', 'id': opt.id, 'name': opt.id, 'value': opt.value});
		var label = this.getLabel(opt);
		
		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');
			}
		}
		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);
		}	
		this.grab(opt.id+'Content',[label, hiddenCheck, check]);
	},
	
	//MultiCheckboxByUrl
	addMultiCheckboxByUrl: function(opt)
	{	
		var obj = this;
		var divMultiCheck = new Element('div',{'id':opt.id+'Div'});
		divMultiCheck.addClass('tfcCheckList');
		if (!opt.id || !opt.label || !opt.url) alert('Manca label o id o url in MultiCheckbox!!');
		var req = new Request.JSON({
			url: opt.url+'?rand=' + $random(0, 99999),
			encode: 'utf-8',
			async:false,
			onComplete: function(rsp){
				rsp.opts.each(function(op,index){
					var check = new Element('input',{'type': 'checkbox', 'id': opt.id+'_'+op.id, 'name': opt.id, 'value': op.value});
					if (op.checked) check.set('checked', 'checked');
					//check.addClass('isChecked');
					var subLabel = obj.getLabel({'id':opt.id+'_'+op.id, 'label':op.description, 'orientation':obj.LEFT});
					
					var divCheck = new Element('div',{'id':opt.id+'_'+op.id+'Div'});
					
					divCheck.grab(subLabel);
					divCheck.grab(check);
					divMultiCheck.grab(divCheck);
				});
				
			}
		}).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);
		}	*/
		this.grab(opt.id+'Content',[label, divMultiCheck]);
	},
	
	/*
	 * 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)');
         });
	}
	
});


FormValidator.resources = {
	'enUS': {
		required:'This field is required.',
		isChecked:'This input field must be checked',
		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: '
	},
	'itIT': {
		required:'Il campo deve essere compilato',
		isChecked:'La casella deve essere selezionata',
		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. Ad esempio "fred@domain.com".',
		url:'Inserire un url valido, come http://www.google.com.',
		currencyDollar:'Inserire un importo in dollari valido. Ad esempio $100.00 .',
		oneRequired:'Inserire qualcosa in almeno uno di questi campi.',
		errorPrefix: 'Errore: ',
		warningPrefix: 'Attenzione: '
	}
};
FormValidator.language = "itIT";

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