
var formValidator = function ( form, execOptions ) {

	this.form = form;
	this.options = execOptions || {};
	this.isValidForm = true;

	this.states = [];

	this.funcList = [];
	this.exprList = [];

	this.init = FV_init;
	this.createExecStack = FV_createExecStack;
	this.execExpressions = FV_execExpressions;
	this.execFunctions = FV_execFunctions;
}         


var FV_init = function() {
	try {

		this.createExecStack();
		this.execExpressions();
		this.execFunctions();

		return this.isValidForm;

	} catch ( e ) { return false };
}

var FV_createExecStack = function () {
	try {
		var elms = this.form.elements;
		for ( var i=0, l=elms.length; i<l; i++ ) {
			var classList = ( elms[ i ].className.split(" ") );
			for ( var j=0, k=classList.length; j<k; j++ ) {
				var type = false;
				var result = [];
				if ( classList[ j ].indexOf( ":" ) != -1 ){
					var result = classList[ j ].split ( ":" );
					var type = "expr";
				}
				if ( classList[ j ].indexOf( "." ) != -1 ){
					var result = classList[ j ].split ( "." );
					var type = "func";
				}
				if ( type && result ) {
					if ( window[ result[ 0 ] ] ) {
						var tmpObj = { func: window[ result[ 0 ] ], funcName: result[ 0 ], formElement: elms[ i ], options: result.slice( 1 ) };
						if ( type == "expr" ) this.exprList.push( tmpObj );
						if ( type == "func" ) this.funcList.push( tmpObj );
					}  
				}
			}
		}
	} catch ( e ) {};
}

var FV_execExpressions = function () {
	try {

		for ( var i=0, l=this.exprList.length; i<l; i++ ) {
			this.exprList[ i ].func ( this.exprList[ i ], this );
		}

	} catch ( e ) {};
}

var FV_execFunctions = function () {
	try {

		for ( var i=0, l=this.funcList.length; i<l; i++ ) {

			var tmpState = this.funcList[ i ].func ( this.funcList[ i ].formElement, this.funcList[ i ].options, this );

			var errElID = this.funcList[ i ].formElement.id + "_" + this.funcList[ i ].funcName;
			var errElNameID = this.funcList[ i ].formElement.name + "_" + this.funcList[ i ].funcName;
			var errMsgNode = document.getElementById( errElID );
			if ( !errMsgNode ) {
				errMsgNode = document.getElementById( errElNameID );
			}

			if ( errMsgNode ) applyClassName ( errMsgNode, "hiddenBlock", (tmpState) );

			if ( tmpState != "skip" ) {
				applyClassName ( this.funcList[ i ].formElement, ( ( this.options.hlClass )? this.options.hlClass : "hlight" ) , !tmpState );
			}


			if ( !(tmpState) ) {
				
				this.isValidForm  = false;
				
			}
		}


	} catch ( e ) { };
}

var validateForm = function ( form, execOptions ) {
	try {
		var tmpObj = new formValidator ( form, execOptions );
		return tmpObj.init();
	} catch ( e ) { return false };
}



// Functions list

var notEmpty = function ( formElement, options, fvObj ) {
	try {
		if ( options[ 0 ] ) {
			if ( fvObj.states[ options[ 0 ] ] ) {
				return ( formElement.value != "" );
			}
			else return true; 
		}
		return ( formElement.value != "" );
	} catch ( e ) { return false };
}

var isEmail = function ( formElement, options, fvObj ) {
	try {

		if ( formElement.value == "" ) return false;

		var splitted = formElement.value.match("^(.+)@(.+)$");

	    if( splitted !== null && splitted[ 1 ] !== null ) {
	    	var regexp_user=/^\"?[\w-_\.]*\"?$/;
		    if( splitted[ 1 ].match( regexp_user ) !== null && splitted[ 2 ] !== null)
			{
		    	var regexp_domain=/^[\w-\.]*\.[A-Za-z]{2,4}$/;
				var regexp_ip =/^\[\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\]$/;
				if( ( splitted[ 2 ].match( regexp_domain ) !== null) || ( splitted[ 2 ].match( regexp_ip ) !== null))
				{
					return true;
				}
			}
		
		};
		return false;	
	} catch ( e ) { return false };
}

var isMultipleRequired = function ( execOptions, fvObj ) {
	try {
		if ( execOptions.formElement.value != "" ) {
			if ( execOptions.options[ 0 ] ) {
				fvObj.states[ execOptions.options[ 0 ] ] = true;
			}
		}	
	} catch ( e ) {};
}

var checkDup = function ( formElement, options, fvObj ) {
	try {
		if ( options[ 0 ] ) {
			if ( formElement.value == "" ) return "skip";
			if ( fvObj.states[ options[ 0 ] ] == undefined ) {
				fvObj.states[ options[ 0 ] ] = formElement.value;
			}
			var state = ( fvObj.states[ options[ 0 ] ] == formElement.value );
			return state;
		}
		return true;

	} catch ( e ) { return false };
}
