/**********************************************************************************
 * Set  of  classes and functions for validations processing.
 * 
 * The MIT License
 * 
 * Copyright (c) 2008 Victor Denisenkov aka Mr.V!T
 * 
 * Permission  is hereby granted, free of charge, to any person obtaining a copy of
 * this  software  and  associated documentation files (the "Software"), to deal in
 * the  Software  without  restriction,  including without limitation the rights to
 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
 * the  Software, and to permit persons to whom the Software is furnished to do so,
 * subject to the following conditions:
 * 
 * The  above  copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 * 
 * THE  SOFTWARE  IS  PROVIDED  "AS  IS",  WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
 * FOR  A  PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
 * COPYRIGHT  HOLDERS  BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 * IN  AN  ACTION  OF  CONTRACT,  TORT  OR  OTHERWISE,  ARISING  FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 *
 * @package vit-lib
 * @author Victor Denisenkov aka Mr.V!T
 * @version 1.0
\**********************************************************************************/

/*--------------------------------------------------------------------------------*\
|	validateElement
|----------------------------------------------------------------------------------
| Validates input element using validators specified on it and applies given class 
| if failed.
| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|	Params:
|		element	object	- DOM element object to validate.
|		options	object	- Basic object with settings.
|	Return:
|		NULL
\*--------------------------------------------------------------= by Mr.V!T =-----*/
function validateElement (element, options) {
	
	if ( !options ) options = {};

	var fail_class = options.FailClass;
	if ( !fail_class ) fail_class = 'required';

	var validations = element.getAttribute('validations');
	
	if ( !validations ) validations = '';
	
	if ( (element.className.indexOf('required') != -1) && ( validations.indexOf('required') == -1 ) ) {
		validations += 'required';
	} //IF required set by class
	
	if ( !validations ) return true;

	var value = '';
	switch (element.type) {
		case 'checkbox'	:
			//value = (element.checked)? '1' : '';
			return true;
		case 'radio'	:
			//if (el.checked == false) 
			return true;
		case 'select-one'	:
			value	= getValue_Select(element);
			break;
		case 'select-multiple'	:
			value	= ''+getValue_MutliSelect(element);
			break;
		default	:
			value = element.value;
	} //SWITCH
	
	var res = value.validate(validations);
	
	elclass = element.className;
	
	elclass = elclass.replace(fail_class, '');
	if ( res === false )
		elclass += (elclass?' ':'') + fail_class;
	
	element.className = elclass;

	return res;
} //FUNC validateElement

/*--------------------------------------------------------------------------------*\
|	validateForm
|----------------------------------------------------------------------------------
| Validates form using validators specified on it and applies given class on ones 
| failed.
| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|	Params:
|		form	object	- DOM form object to validate.
|		options	object	- Basic object with settings.
|	Return:
|			object	- Basic object with validation results.
\*--------------------------------------------------------------= by Mr.V!T =-----*/
function validateForm (form, options) {

	if ( !options ) options = {};

	var res = true;
	
	for ( i = 0; i < form.elements.length; i++ ) {
		
		el = form.elements.item(i);
		
		res = validateElement(el, options) && res;
		
	} //FOR each element
	return res;
} //FUNC validateForm

/*--------------------------------------------------------------------------------*\
|	String.validate
|----------------------------------------------------------------------------------
| Simple wrapper to massProcessing object.
| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|	Params:
|		processors	string	- List of processors separated by '|'.
|	Return:
|				MIXED
|				string	- Processed value.
|				bool	- FALSE in case if value doesn't match some 
|					reqirements of one of processors.
\*--------------------------------------------------------------= by Mr.V!T =-----*/
String.prototype.validate = function (processors) {
	var str = this;
	var validator = new MassProcessing();
	return validator.process(str, processors);
} //FUNC String.validate

/*--------------------------------------------------------------------------------*\
|	CLASS MassProcessing
|----------------------------------------------------------------------------------
| Simple class for processing several functions over value.
| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|	Params:
|		NONE
\*---------------------------------------------------------------= by Mr.V!T =----*/
var MassProcessing = function () {
} //CONSTRUCTOR Validation

MassProcessing.prototype = {

	Fails		: [],
	collectFails	: false,
	
	allowRegularFunctions	: false,

	/*--------------------------------------------------------------------------------*\
	|	process
	|----------------------------------------------------------------------------------
	| Initiates value processing.
	| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
	|	Params:
	|		value		string	- Value to process.
	|		processors	string	- List of processors separated by '|'.
	|	Return:
	|				MIXED
	|				string	- Processed value.
	|				bool	- FALSE in case if value doesn't match some 
	|					reqirements of one of processors.
	\*--------------------------------------------------------------= by Mr.V!T =-----*/
	process		 : function (value, processors) {
		
		var ex = processors.split('|');
		
		for ( var i = 0; i < ex.length; i++ ) {
			
			var proc = ex[i];
			
			if ( !proc ) continue;
			
			var tmp = true;
			
			if ( value[proc] ) {
				
				tmp = value[proc]();
				
			} else if ( this[proc] ) { //IF deafult string processor called
			
				tmp = this[proc](value);
				
			} else if ( this.allowRegularFunctions ) { //IF internal processor called
				if ( eval("typeof " + proc + " == 'function'") )
					tmp =  eval(proc + "('"+value+"')");
			} //IF regular function with such name exists
			
			if ( typeof(tmp) != 'boolean' ) {
				value = tmp;
			} else { //IF value returned
				if (!tmp) {
					if ( !this.collectFails ) return false;
					this.Fails.push(proc);
				} //IF get failed
			} //IF boolean return
			
		} //FOR each processor
		
		if (this.collectFails && this.Fails.length != 0) return false;
		return value;		
	},

// ---- Validation processors ----
	
	//Simple check if value is not empty.
	required	: function (value) {
		if ( !(''+value) ) return false;
		return value;
	},
	
	//Simple check if given string is valid email.
	valid_email	: function (value) {
		return isMail(value);
	},
	
	//Simple check if givn string contain valid number
	numeric		: function (value) {
		return !isNaN(value);
	}
} //CLASS
