var aForms = new Array();
var temp = new Array();

function oInput( obj ) {
	if( !obj ) return false;
	this.form = aForms[ obj.form.id ];
	this.input = obj;
	this.id = obj.id;
	this.name = obj.name;
	this.type = obj.type;
	this.required = false;
	this.pattern = false;
	this.error = false;
	this.correct = false;
	
	this.checked = function() {
		return this.input.checked;
	}

	this.val = function() {
		return this.input.value;
	}

	this.defaultHandler = function() {
		switch( this.type ) {
			case 'checkbox' : {
				if( this.checked() ) {
					return true;
				} else {
					return false;
				}
			};
			default : {
				var pattern = new RegExp( this.pattern );
				if( !pattern.test( this.input.value ) ) {
					return false;
				} else {
					return true;
				}
			};
		}
	}

	this.checkInput = function( handler ) {
		var cInput = this;
		if( !handler ) handler = this.defaultHandler();
		
		if( typeof( handler ) == 'function') handler = handler();
		
		if( handler ) {
			this.error = false;
			this.correct = true;
			if( !this.form.firstCheck ) this.form.succesHandle.call( this );
		} else {
			this.error = true;
			this.correct = false;
			if( !this.form.firstCheck ) this.form.errorHandle.call( this );
		}
		
		if( !this.form.firstCheck ) {
			this.form.checkForm();
		}
	}

	this.addHandler = function( ev, handler ) {
		var cInput = this;
		if( document.addEventListener ) {
			this.input.addEventListener( ev.toString(), function() { temp[0] = cInput; temp[1] = handler; setTimeout( 'temp[0].checkInput( temp[1] )', 0 ) }, false );
		} else {
			this.input.attachEvent( 'on' + ev.toString(), function() { cInput.checkInput( handler ); } );
		}
	}
}

function oForm( obj ) {
	if( !obj ) return false;
	this.form = document.getElementById( obj.form );
	this.id = this.form.id;
	this.valid = false;
	this.firstCheck = true;
	this.error = false;
	this.enabled = obj.enabled ? true : false;
	this.succesHandle = obj.succesHandle ? obj.succesHandle : function() {};
	this.errorHandle = obj.errorHandle ? obj.errorHandle : function() {};

	this.findByType = function( types ) {
		var result = new Array();
		types = types.split(', ');
		for( var o = 0; o < types.length; o++ ) {
			for( var oInput in this.all ) {
				if( this.all[ oInput ].input.nodeName == 'BUTTON' ) continue;
				if( this.all[ oInput ].type == types[o] ) {
					var cInput = this.all[ oInput ];
					if( cInput.id ) {
						result[ cInput.id ] = cInput;
					} else {
						result.push( cInput );
					}
				}
			}
		}
		return result;
	}

	this.checkForm = function() {
		var correctCount = 0;
		var requiredCount = 0;

		for(var oInput in this.required ) {
			if( this.all[ oInput ].correct ) correctCount++;
			if( this.all[ oInput ].required ) requiredCount++;
		}

		if( !this.firstCheck ) this.error = this.updateError();
		
		if( correctCount == requiredCount ) {
			this.valid = true;
			if( !this.firstCheck ) {
				if( !this.enabled ) this.submitDisable( false );
				return true;
			}
		} else {
			this.valid = false;
			if( !this.firstCheck ) {
				if( !this.enabled ) this.submitDisable( true );
				return false;
			}
		}
	}

	this.onSubmit = function() {
		//return aForms[ this.id ].checkForm();
		return true;
	};

	this.updateError = function() {
		var result = new Array();
		for( var oErrorInput in this.all ) {
			var cInput = this.all[ oErrorInput ];
			if( cInput.error ) result.push( cInput.input );
		}
		return result;
	}

	this.submitDisable = function( flag ) {
		var disPattern = /disabled/i;
		if( flag ) {
			for( var cSubmit in this.submit ) {
				var cInput = this.submit[ cSubmit ].input;
				if( !disPattern.test( cInput.className.toString() )) cInput.className += " disabled";
				cInput.disabled = flag;
			}
		} else {
			for( var cSubmit in this.submit ) {
				var cInput = this.submit[ cSubmit ].input;
				var sClassName = cInput.className;
				cInput.className = sClassName.replace( disPattern, '');
				cInput.disabled = flag;
			}
		}
		return true;
	}

	this.add = function( id, pattern ) {
		if( !this.form[id] ) return false;
		this.required[ id ] = pattern;
		var cInput = this.all[ id ];
		cInput.required = true;
		cInput.pattern = pattern;

		var eventType = new Array();
		switch( cInput.type ) {
			case 'text' : ;
			case 'textarea' : eventType.push('keyup'); eventType.push('change'); eventType.push('blur'); break;
			case 'select-one' : ;
			case 'select-multiple' : eventType.push('change'); break;
			case 'checkbox' : eventType.push('click'); break;
		}

		for(var i = 0; i < eventType.length; i++ ) {
			cInput.addHandler( eventType[i] );
		}
		
		return true;
	}

	this.remove =  function( id ) {
		if( !this.form[id] ) return false;
		delete this.required[ id ];
		this.all[ id ].required = false;
		this.all[ id ].pattern = false;
		return true;
	}

	this.init = function() {
		aForms[ this.id ] = this;
		this.all = new Array();
		var tempInputArray = new Array();

		for( var i = 0; i < this.form.length; i++ ) {
			tempInputArray[i] = this.form[i];
		}

		var inputTypeImage = this.form.getElementsByTagName('input');
		for( var i = 0; i < inputTypeImage.length; i++ ) {
			if( inputTypeImage[i].type == 'image' ) tempInputArray.push( inputTypeImage[i] );
		}

		for( var i = 0; i < tempInputArray.length; i++ ) {
			var cInput = new oInput( tempInputArray[i] );
			if( cInput.id ) {
				this.all[ cInput.id ] = cInput;
			} else {
				this.all.push( cInput );
			}
		}

		if( obj.required ) {
			this.required = new Object()
			for( var oRequired in obj.required ) {
				if( this.all[ oRequired ] ) {
					this.required[ oRequired ] = obj.required[ oRequired ];
				}
			}

			if( obj.required.checkbox ) {
				for( var i = 0; i < obj.required.checkbox.length; i++ ) {
					var cCheckBox = obj.required.checkbox[i];
					if( this.all[ cCheckBox ] && this.all[ cCheckBox ].type == 'checkbox' ) {
						this.required[ cCheckBox ] = cCheckBox;
					}
				}
			}
		} else {
			this.required = null;
		}
		
		this.initRequired = obj.initRequired ? obj.initRequired : function() {};
		this.initRequired();
		
		for(var oInputId in this.required ) {
			var cInput = this.all[ oInputId ];
			if( cInput ) {
				cInput.required = true;
				cInput.pattern = this.required[ oInputId ];
				cInput.checkInput();

				var eventType = new Array();
				switch( cInput.type ) {
					case 'text' : ;
					case 'textarea' : eventType.push('keyup'); eventType.push('change'); eventType.push('blur'); break;
					case 'select-one' : ;
					case 'select-multiple' : eventType.push('change'); break;
					case 'checkbox' : eventType.push('click'); break;
				}

				for(var i = 0; i < eventType.length; i++ ) {
					cInput.addHandler( eventType[i] );
				}
			}
		}

		this.text = this.findByType('text, search');
		this.select = this.findByType('select-one, select-multiple');
		this.textarea = this.findByType('textarea');
		this.checkbox = this.findByType('checkbox');
		this.hidden = this.findByType('hidden');
		this.submit = this.findByType('submit, image');

		if( !this.enabled ) this.submitDisable( true );
		
		this.submitHandler = obj.onSubmit ? obj.onSubmit : this.onSubmit;

		this.form.onsubmit = function() {
			for( var c in aForms[ this.id ].all ) {
				var cIn = aForms[ this.id ].all[c];
				if( cIn.required ) {
					if( cIn.error ) {
						aForms[ this.id ].errorHandle.call( cIn );
					} else {
						aForms[ this.id ].succesHandle.call( cIn );
					}
				}
			}
			
			if( aForms[ this.id ].valid ) {
				aForms[ this.id ].submitHandler();
			} else {
				return false;
			}
		}

		this.checkForm();
		this.firstCheck = false;
	}
	this.init();
}
