var FormManager=Class.create();
FormManager.prototype = {
   initialize: function(formId) {
	this.formElement=$(formId);
	this.formDivisions = $A(this.formElement.getElementsByTagName('span'));
	this.formDivisions.each(function (fDiv)
		{
		if($(fDiv).hasClassName('input'))
			{
			fDiv.field=fDiv.getElementsByTagName('input')[0];
			$(fDiv.field).observe('change', this.handleFieldEvent.bind(this));
			$(fDiv.field).observe('blur', this.handleFieldEvent.bind(this));
			if($(fDiv).hasClassName('date'))
				{
				fDiv.replacementDiv=new DatePicker(fDiv);
				}
			else if($(fDiv).hasClassName('int'))
				{
				fDiv.replacementDiv=new NumberMaker(fDiv);
				fDiv.type='int';
				}
			}
		else if($(fDiv).hasClassName('password'))
			{
			fDiv.field=fDiv.getElementsByTagName('input')[0];
			$(fDiv.field).observe('change', this.handleFieldEvent.bind(this));
			$(fDiv.field).observe('blur', this.handleFieldEvent.bind(this));
			}
		else if($(fDiv).hasClassName('textarea'))
			{
			fDiv.field=fDiv.getElementsByTagName('textarea')[0];
			$(fDiv.field).observe('change', this.handleFieldEvent.bind(this));
			$(fDiv.field).observe('blur', this.handleFieldEvent.bind(this));
			}
		else if($(fDiv).hasClassName('select'))
			{
			fDiv.field=fDiv.getElementsByTagName('select')[0];
			$(fDiv.field).observe('change', this.handleFieldEvent.bind(this));
			}
		else if($(fDiv).hasClassName('checkbox'))
			{
			fDiv.field=fDiv.getElementsByTagName('input')[0];
			$(fDiv.field).observe('change', this.handleFieldEvent.bind(this));
			}
		if(fDiv.replacementDiv)
			{
			fDiv.replacementDiv.container.style.position='absolute';
			fDiv.replacementDiv.container.style.zIndex='2';
			fDiv.insertBefore(fDiv.replacementDiv.container,fDiv.field);
			//document.body.appendChild(fDiv.replacementDiv.container);
			fDiv.replacementDiv.container.style.left=$(fDiv.field).positionedOffset()[0]+'px';
			fDiv.replacementDiv.container.style.top=$(fDiv.field).positionedOffset()[1]+'px';
			fDiv.replacementDiv.container.style.width=$(fDiv.field).getDimensions().width+'px';
			fDiv.replacementDiv.container.style.height=$(fDiv.field).getDimensions().height+'px';
			//$(fDiv.field).hide();
			$(fDiv.field).setOpacity(0);
			}
		}.bind(this));
	$(this.formElement).observe('submit', this.submit.bind(this));
   },
   handleFieldEvent: function(event) {
		this.checkField(Event.element(event));
   },
   checkField: function(field) {
		if(field)
			{
			var parent=field.parentNode;
			while(parent.tagName.toLowerCase()!='span')
				parent=parent.parentNode;
			if(((!$F(field))&&$(parent).hasClassName('required'))
				||(($(parent).hasClassName('parameter'))&&!this.checkParameter($F(field)))
				||(($(parent).hasClassName('iparameter'))&&!this.checkIParameter($F(field)))
				||(($(parent).hasClassName('mail'))&&!this.checkEmail($F(field)))
				||(($(parent).hasClassName('phone'))&&!this.checkPhone($F(field)))
				||(($(parent).hasClassName('int'))&&!this.checkInt($F(field)))
				||(($(parent).hasClassName('date'))&&!this.checkDate($F(field)))
			)
				{
				$(parent).removeClassName('valid');
				$(parent).addClassName('invalid');
				}
			else
				{
				$(parent).removeClassName('invalid');
				$(parent).addClassName('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]{2,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;
   },
   submit: function(event) {
		if($(this.formDivisions).detect(function (fDiv)
			{
			if(fDiv.field&&!this.checkField(fDiv.field))
				{
				$(fDiv).scrollTo();
				return true;
				}
			return false;
			}.bind(this)))
			{
			Event.stop(event);
			return false;
			}
		this.formDivisions.each(function (fDiv)
			{
			if(fDiv.replacementDiv)
				{
				$(fDiv.replacementDiv.container).hide();
				$(fDiv.field).setOpacity(100);
				}
			});
	return true;
   }
};

var DatePicker=Class.create();
DatePicker.prototype = {
	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).update(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).update((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).update((n<9?0:'')+''+(n+1));
			this.day.appendChild(opt);
			}.bind(this));
		this.day.style.width='33%';
		this.container.appendChild(this.day);
		$(this.year).observe('change', this.updateField.bind(this));
		$(this.month).observe('change', this.updateField.bind(this));
		$(this.day).observe('change', this.updateField.bind(this));
		if($F(this.field))
			{
			var dSplit=$F(this.field).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.value=$F(this.year)+'-'+$F(this.month)+'-'+$F(this.day);
		this.field.focus();
	}	
};

var NumberMaker=Class.create();
NumberMaker.prototype = {
	initialize: function(fDiv) {
		this.fDiv=fDiv;
		this.field=fDiv.field;
		this.container=document.createElement('div');
		this.input=document.createElement('input');
		$(this.input).writeAttribute('type','text');
		$(this.input).writeAttribute('value',0);
		this.input.style.width='78%';
		this.container.appendChild(this.input);
		this.more=document.createElement('input');
		$(this.more).writeAttribute('type','button');
		$(this.more).writeAttribute('value','+');
		this.more.style.width='10%';
		this.container.appendChild(this.more);
		this.less=document.createElement('input');
		$(this.less).writeAttribute('type','button');
		$(this.less).writeAttribute('value','-');
		this.less.style.width='10%';
		this.container.appendChild(this.less);
		$(this.more).observe('click', this.putMore.bind(this));
		$(this.less).observe('click', this.putLess.bind(this));
		$(this.input).observe('change', this.putNumber.bind(this));
		if($F(this.field))
			this.input.value=new Number($F(this.field));
		this.updateField();
	},

	putMore : function(event)
		{
		this.input.value=new Number($F(this.input))+1;
		this.updateField();
	},

	putLess : function(event)
		{
		this.input.value=new Number($F(this.input))-1;
		this.updateField();
	},

	putNumber : function(event)
		{
		this.input.value=new Number($F(this.input));
		if($F(this.input)=='NaN')
			this.input.value=0;
		this.updateField();
	},

	updateField : function(event)
		{
		this.field.value=$F(this.input);
		this.field.focus();
	}
};

var formManager=new FormManager('form');