var FormDetector=new Class({
	detected:false,
	initialize: function() {
	this.forms=$$('form.xcform');
	if(this.forms.length)
		FormDetector.detected=true;
	this.forms.each(function (form)
		{
		new FormManager(form);
		}, this);
	}
});

var FormManager=new Class(
	{
	initialize: function(form)
		{
		this.formElement=form;
		this.formDivisions = form.getElements('span');
		this.formDivisions.each(function (fDiv)
			{
			if($(fDiv).hasClass('input'))
				{
				fDiv.field=fDiv.getElementsByTagName('input')[0];
				if($(fDiv).hasClass('date'))
					{
					fDiv.replacementDiv=new DatePicker(fDiv);
					}
				else if($(fDiv).hasClass('int'))
					{
					fDiv.replacementDiv=new NumberMaker(fDiv);
					fDiv.type='int';
					}
				else if($(fDiv).hasClass('timestamp'))
					{
					fDiv.replacementDiv=new TimePicker(fDiv);
					}
				else
					{
					$(fDiv.field).addEvent('change', this.handleFieldEvent.bind(this));
					$(fDiv.field).addEvent('blur', this.handleFieldEvent.bind(this));
					$(fDiv.field).addEvent('focus', this.handleFieldEvent.bind(this));
					$(fDiv.field).addEvent('keyup', this.handleFieldEvent.bind(this));
					}
				}
			else if($(fDiv).hasClass('password'))
				{
				fDiv.field=fDiv.getElementsByTagName('input')[0];
				$(fDiv.field).addEvent('change', this.handleFieldEvent.bind(this));
				$(fDiv.field).addEvent('blur', this.handleFieldEvent.bind(this));
				$(fDiv.field).addEvent('focus', this.handleFieldEvent.bind(this));
				$(fDiv.field).addEvent('keyup', this.handleFieldEvent.bind(this));
				}
			else if($(fDiv).hasClass('textarea'))
				{
				fDiv.field=fDiv.getElementsByTagName('textarea')[0];
				$(fDiv.field).addEvent('change', this.handleFieldEvent.bind(this));
				$(fDiv.field).addEvent('blur', this.handleFieldEvent.bind(this));
				$(fDiv.field).addEvent('focus', this.handleFieldEvent.bind(this));
				$(fDiv.field).addEvent('keyup', this.handleFieldEvent.bind(this));
				}
			else if($(fDiv).hasClass('select'))
				{
				fDiv.field=fDiv.getElementsByTagName('select')[0];
				$(fDiv.field).addEvent('change', this.handleFieldEvent.bind(this));
				}
			else if($(fDiv).hasClass('checkbox'))
				{
				fDiv.field=fDiv.getElementsByTagName('input')[0];
				$(fDiv.field).addEvent('change', this.handleFieldEvent.bind(this));
				}
			if(fDiv.field&&/(^| )(max|min)([0-9]+)($| )/.test($(fDiv.field).get('class')))
				{
				if(/(^| )max([0-9]+)($| )/.test($(fDiv.field).get('class')))
					{
					fDiv.field.max=$(fDiv.field).get('class').replace(/(?:^| )max([0-9]+)(?:$| )/,'$1')
					}
				if(/(^| )min([0-9]+)($| )/.test($(fDiv.field).get('class')))
					{
					fDiv.field.min=$(fDiv.field).get('class').replace(/(?:^| )max([0-9]+)(?:$| )/,'$1')
					}
				}
			if(fDiv.replacementDiv)
				{
				fDiv.replacementDiv.container.style.position='absolute';
				fDiv.replacementDiv.container.style.zIndex=999;
				fDiv.insertBefore(fDiv.replacementDiv.container,fDiv.field);
				//document.body.appendChild(fDiv.replacementDiv.container);
				$(fDiv.replacementDiv.container).setPosition($(fDiv.field).getPosition());
				$(fDiv.replacementDiv.container).setStyle('width',$(fDiv.field).getSize().x+'px');
				$(fDiv.replacementDiv.container).setStyle('height',$(fDiv.field).getSize().y+'px');
				$(fDiv.field).setOpacity(0);
				//$(fDiv.field).parentNode.setStyle('height',$(fDiv.field).getSize().y+'px');
				//$(fDiv.field).disabled=true;
				// $(fDiv.field).setAttribute('disabled','disabled');
				$(fDiv.field).set('disabled','disabled');
				//$(fDiv.field).setStyle('display','none');
				}
			},this);
		$(this.formElement).addEvent('submit', this.submit.bind(this));
		},
   handleFieldEvent: function(event)
		{
			this.checkField(event.target);
			this.redraw();
		},
   checkField: function(field)
		{
		if(field)
			{
			var parent=field.parentNode;
			while(parent.tagName.toLowerCase()!='span')
				parent=parent.parentNode;
			if(field.get('value')&&field.max)
				{
				if(($(parent).hasClass('parameter')||$(parent).hasClass('iparameter')||$(parent).hasClass('url'))&&field.get('value').length>field.max)
					{
					field.set('value',field.get('value').substring(0,field.max));
					}
				if(($(parent).hasClass('parameter')||$(parent).hasClass('iparameter')||$(parent).hasClass('url'))&&field.get('value')>field.max)
					{
					field.set('value',field.max);
					}
				}
			if($(parent).hasClass('required')&&(
				(!field.get('value'))
				||(($(parent).hasClass('parameter'))&&!this.checkParameter(field.get('value')))
				||(($(parent).hasClass('iparameter'))&&!this.checkIParameter(field.get('value')))
				||(($(parent).hasClass('mail'))&&!this.checkEmail(field.get('value')))
				||(($(parent).hasClass('url'))&&!this.checkUrl(field.get('value')))
				||(($(parent).hasClass('phone'))&&!this.checkPhone(field.get('value')))
				||(($(parent).hasClass('int'))&&!this.checkInt(field.get('value')))
				||(($(parent).hasClass('date'))&&!this.checkDate(field.get('value')))
				||(($(parent).hasClass('timestamp'))&&!this.checkTimestamp(field.get('value'))))
				)
				{
				$(parent).removeClass('valid');
				$(parent).addClass('invalid');
				}
			else
				{
				$(parent).removeClass('invalid');
				$(parent).addClass('valid');
				return true;
				}
			}
		return false;
		},
   checkInt: function(value) {
		if(/^([\+\-]?[0-9]+)$/.test(value))
			return true;
		return false;
   },
   checkParameter: function(value) {
		if(/^([a-z0-9_]+)$/.test(value))
			return true;
		return false;
   },
   checkIParameter: function(value) {
		if(/^([a-z0-9_]+)$/i.test(value))
			return true;
		return false;
   },
   checkEmail: function(value) { /* !#$%&'*+-/=?^_`.{|}~ */
		if(/^([0-9a-z_\-\.]+)@([0-9a-z_\-\.]+)\.([0-9a-z]+)$/i.test(value))
			return true;
		return false;
   },
   checkPhone: function(value) {
		if(/^(\+[0-9]{1,3}\.)?([0-9]+)$/.test(value))
			return true;
		return false;
   },
   checkDate: function(value) {
		if(value)
			{
			var dSplit=value.split('-');
			var date = new Date(dSplit[0],dSplit[1]-1,dSplit[2]);
			if(dSplit[2]==date.getDate())
				return true
			}
		return false;
   },
   checkTimestamp: function(value) {
		if(value)
			{
			var dSplit=value.split(/[\-: ]+/);
			var date = new Date(dSplit[0],dSplit[1]-1,dSplit[2],dSplit[3],dSplit[4],dSplit[5]);
			if(dSplit[2]==date.getDate())
				return true
			}
		return false;
   },
   checkUrl: function(value) {
		if(/^(http:\/\/)?([^\/\?#]+)([^\?#]*)(\?([^#]*))?(#(.*))?$/.test(value))
			return true;
		return false;
   },
   redraw: function(event) {
		$$(this.formDivisions).each(function (fDiv)
			{
			if(fDiv.replacementDiv)
				{
				$(fDiv.replacementDiv.container).setPosition($(fDiv.field).getPosition());
				}
			}, this);
   },
   submit: function(event) {
		if($$(this.formDivisions).some(function (fDiv)
			{
			if(fDiv.field&&!this.checkField(fDiv.field))
				{
				window.scrollTo($(fDiv).getPosition().x,$(fDiv).getPosition().y-20);
				return true;
				}
			return false;
			},this))
			{
			event.stop();
			event.stopPropagation();
			this.redraw();
			return false;
			}
			
		var fhash=$('fhash');
		var fpass=$('fpassword');
		var fcode=$('fcode');
		if(fhash&&fcode&&fpass&&SHA1)
			{
			fhash.set('value',SHA1(fpass.value+fcode.value.toLowerCase()));
			fpass.value=""; fcode.value="";
			}
		$$(this.formDivisions).each(function (fDiv)
			{
			if(fDiv.replacementDiv)
				{
				$(fDiv.replacementDiv.container).setStyle('display','none');
				//$(fDiv.field).setStyle('display','inline');
				//$(fDiv.field).disabled=false;
				//$(fDiv.field).setAttribute('disabled','');
				$(fDiv.field).erase('disabled');
				$(fDiv.field).setOpacity(100);
				fDiv.replacementDiv.updateField();
				}
			}, this);
	return true;
   }
});

var DatePicker=new Class({
	initialize: function(fDiv) {
		this.fDiv=fDiv;
		this.field=$(fDiv.field);
		this.container=document.createElement('div');
		this.year=document.createElement('select');
		new Number(200).times(function(n)
			{
			var opt=document.createElement('option');
			$(opt).set('html',new Date().getFullYear()-100+n);
			this.year.appendChild(opt);
			}.bind(this));
		this.year.style.width='33%';
		this.container.appendChild(this.year);
		this.month=document.createElement('select');
		new Number(12).times(function(n)
			{
			var opt=document.createElement('option');
			$(opt).set('html',(n<9?0:'')+''+(n+1));
			this.month.appendChild(opt);
			}.bind(this));
		this.month.style.width='33%';
		this.container.appendChild(this.month);
		this.day=document.createElement('select');
		new Number(31).times(function(n)
			{
			var opt=document.createElement('option');
			$(opt).set('html',(n<9?0:'')+''+(n+1));
			this.day.appendChild(opt);
			}.bind(this));
		this.day.style.width='33%';
		this.container.appendChild(this.day);
		$(this.year).addEvent('change', this.updateField.bind(this));
		$(this.month).addEvent('change', this.updateField.bind(this));
		$(this.day).addEvent('change', this.updateField.bind(this));
		if(this.field.get('value'))
			{
			var dSplit=this.field.get('value').split('-');
			var date = new Date(dSplit[0],dSplit[1]-1,dSplit[2]);
			}
		else
			var date = new Date();
		this.updateSelect(date);
		this.updateField();
		},

	updateSelect: function(selectedDate) {
		$A(this.year.childNodes).each(function (opt)
			{
			if(opt.value==(selectedDate.getFullYear())||opt.innerHTML==(selectedDate.getFullYear()))
				opt.setAttribute('selected','selected');
			else
				opt.removeAttribute('selected');
			});
		$A(this.month.childNodes).each(function (opt)
			{
			if(opt.value==(selectedDate.getMonth()+1)||opt.innerHTML==(selectedDate.getMonth()+1))
				opt.setAttribute('selected','selected');
			else
				opt.removeAttribute('selected');
			});
		$A(this.day.childNodes).each(function (opt)
			{
			if(opt.value==selectedDate.getDate()||opt.innerHTML==selectedDate.getDate())
				opt.setAttribute('selected','selected');
			else
				opt.removeAttribute('selected');
			});
	},

	updateField: function() {
		$(this.field).set('value',this.year.options[this.year.selectedIndex].value
			+'-'+this.month.options[this.month.selectedIndex].value
			+'-'+this.day.options[this.day.selectedIndex].value);
		this.field.focus();
	}	
});

var TimePicker=new Class({
	initialize: function(fDiv) {
		this.fDiv=fDiv;
		this.field=$(fDiv.field);
		this.container=document.createElement('div');
		this.year=document.createElement('select');
		new Number(200).times(function(n)
			{
			var opt=document.createElement('option');
			$(opt).set('html',new Date().getFullYear()-100+n);
			this.year.appendChild(opt);
			}.bind(this));
		this.year.style.width='33%';
		this.container.appendChild(this.year);
		this.month=document.createElement('select');
		new Number(12).times(function(n)
			{
			var opt=document.createElement('option');
			$(opt).set('html',(n<9?0:'')+''+(n+1));
			this.month.appendChild(opt);
			}.bind(this));
		this.month.style.width='33%';
		this.container.appendChild(this.month);
		this.day=document.createElement('select');
		new Number(31).times(function(n)
			{
			var opt=document.createElement('option');
			$(opt).set('html',(n<9?0:'')+''+(n+1));
			this.day.appendChild(opt);
			}.bind(this));
		this.day.style.width='33%';
		this.container.appendChild(this.day);
		this.hour=document.createElement('select');
		new Number(24).times(function(n)
			{
			var opt=document.createElement('option');
			$(opt).set('html',(n<=9?0:'')+''+(n));
			this.hour.appendChild(opt);
			}.bind(this));
		this.hour.style.width='33%';
		this.container.appendChild(this.hour);
		this.minute=document.createElement('select');
		new Number(60).times(function(n)
			{
			var opt=document.createElement('option');
			$(opt).set('html',(n<=9?0:'')+''+(n));
			this.minute.appendChild(opt);
			}.bind(this));
		this.minute.style.width='33%';
		this.container.appendChild(this.minute);
		this.second=document.createElement('select');
		new Number(60).times(function(n)
			{
			var opt=document.createElement('option');
			$(opt).set('html',(n<=9?0:'')+''+(n));
			this.second.appendChild(opt);
			}.bind(this));
		this.second.style.width='33%';
		this.container.appendChild(this.second);
		$(this.year).addEvent('change', this.updateField.bind(this));
		$(this.month).addEvent('change', this.updateField.bind(this));
		$(this.day).addEvent('change', this.updateField.bind(this));
		$(this.hour).addEvent('change', this.updateField.bind(this));
		$(this.minute).addEvent('change', this.updateField.bind(this));
		$(this.second).addEvent('change', this.updateField.bind(this));
		if(this.field.get('value'))
			{
			var dSplit=this.field.get('value').split(/[\-: ]+/);
			var date = new Date(dSplit[0],dSplit[1]-1,dSplit[2],dSplit[3],dSplit[4],dSplit[5]);
			}
		else
			var date = new Date();
		this.updateSelect(date);
		this.updateField();
		},

	updateSelect: function(selectedDate) {
		$A(this.year.childNodes).each(function (opt)
			{
			if(opt.value==(selectedDate.getFullYear())||opt.innerHTML==(selectedDate.getFullYear()))
				opt.setAttribute('selected','selected');
			else
				opt.removeAttribute('selected');
			});
		$A(this.month.childNodes).each(function (opt)
			{
			if(opt.value==(selectedDate.getMonth()+1)||opt.innerHTML==(selectedDate.getMonth()+1))
				opt.setAttribute('selected','selected');
			else
				opt.removeAttribute('selected');
			});
		$A(this.day.childNodes).each(function (opt)
			{
			if(opt.value==selectedDate.getDate()||opt.innerHTML==selectedDate.getDate())
				opt.setAttribute('selected','selected');
			else
				opt.removeAttribute('selected');
			});
		$A(this.hour.childNodes).each(function (opt)
			{
			if(opt.value==selectedDate.getHours()||opt.innerHTML==selectedDate.getHours())
				opt.setAttribute('selected','selected');
			else
				opt.removeAttribute('selected');
			});
		$A(this.minute.childNodes).each(function (opt)
			{
			if(opt.value==selectedDate.getMinutes()||opt.innerHTML==selectedDate.getMinutes())
				opt.setAttribute('selected','selected');
			else
				opt.removeAttribute('selected');
			});
		$A(this.second.childNodes).each(function (opt)
			{
			if(opt.value==selectedDate.getSeconds()||opt.innerHTML==selectedDate.getSeconds())
				opt.setAttribute('selected','selected');
			else
				opt.removeAttribute('selected');
			});
	},

	updateField: function() {
		$(this.field).set('value',this.year.options[this.year.selectedIndex].value
			+'-'+this.month.options[this.month.selectedIndex].value
			+'-'+this.day.options[this.day.selectedIndex].value
			+' '+this.hour.options[this.hour.selectedIndex].value
			+':'+this.minute.options[this.minute.selectedIndex].value
			+':'+this.second.options[this.second.selectedIndex].value);
		this.field.focus();
	}	
});

var NumberMaker=new Class({
	initialize: function(fDiv) {
		this.fDiv=fDiv;
		this.field=fDiv.field;
		this.container=document.createElement('div');
		this.input=document.createElement('input');
		$(this.input).setProperty('type','text');
		$(this.input).setProperty('value',0);
		this.input.style.width='76%';
		this.container.appendChild(this.input);
		this.more=document.createElement('input');
		$(this.more).setProperty('type','button');
		$(this.more).setProperty('value','+');
		this.more.style.width='10%';
		this.container.appendChild(this.more);
		this.less=document.createElement('input');
		$(this.less).setProperty('type','button');
		$(this.less).setProperty('value','-');
		this.less.style.width='10%';
		this.container.appendChild(this.less);
		$(this.more).addEvent('click', this.putMore.bind(this));
		$(this.less).addEvent('click', this.putLess.bind(this));
		$(this.input).addEvent('change', this.putNumber.bind(this));
		$(this.field).addEvent('change', this.syncronizeField.bind(this));
		if(this.field.get('value'))
			this.input.value=new Number(this.field.get('value'));
		this.updateField();
	},

	putMore : function(event)
		{
		this.input.value=new Number(this.input.get('value'))+1;
		this.updateField();
	},

	putLess : function(event)
		{
		this.input.value=new Number(this.input.get('value'))-1;
		this.updateField();
	},

	putNumber : function(event)
		{
		this.input.value=new Number(this.input.get('value'));
		if(this.input.get('value')=='NaN')
			this.input.value=0;
		this.updateField();
	},

	updateField : function(event)
		{
		this.field.value=$(this.input).get('value');
		//this.field.focus();
	},

	syncronizeField : function(event)
		{
		if(this.field.get('value')!=this.input.get('value'))
			{
			this.input.value=this.field.get('value');
			this.field.focus();
			}
	}
});

window.addEvent('domready', function() {
    new FormDetector();
});
