/**
 * Format text message for output
 *
 * @param string sKey - key of message
 * @param string sField - Human readable name of field
 *
 * @returns  string formatted message.
 **/
function validator_formatMes(sKey, sField, $sDef)
{
	var aMes = new Array();
		aMes['minlen']  = 'field value is too short.';
		aMes['maxlen']  = 'field value is too long.';
		aMes['max']     = 'field value is more than allowed.';
		aMes['min']     = 'field value is less then allowed.';
		aMes['pattern'] = 'field value has inadmissible format.';

	return ('"'+sField + '" : ' + ($sDef ? $sDef: aMes[sKey]));
}

/**
 * Get field value depending on field type
 * @param object oField field
 *
 * @returns string value of field
 * @todo add support for dates
 */
function validator_getValue(oField){
	var sVal = oField.value;
	if(oField.type.toLowerCase() == 'checkbox' && !oField.checked )
		sVal = '';
	return sVal;
}
/**
 * Check is form valid
 *
 * @param object oForm  - form to validate
 * @param array aShema  - array of validation shemas (hash) related to certan field
 * @param array aRules  - array of validation rules bentween 2 fields
 *
 * @returns  boolean  true if all is ok or false + alert wiht error messages if form contains errors.
 **/
function validator_isValid(oForm, aShema, aRules) {
	// errors
	var aErr  = new Array();

	// for each fields
	for( i=0; i< aShema.length; ++i )
	{
		var oShema = aShema[i];
		var sVal = validator_getValue(oForm.elements[aShema[i].field]);

		//optional param
		if( typeof(oShema.optional) != 'undefined' && !sVal.length)
			continue;
		$sMes = ( typeof(oShema.message) != 'undefined' ? oShema.message : '');

		// validation
		if ( typeof(oShema.minlen) != 'undefined' &&  oShema.minlen > sVal.length)
			aErr[aErr.length] = validator_formatMes('minlen', oShema.title, $sMes);

		if ( typeof(oShema.maxlen) != 'undefined' &&  oShema.maxlen < sVal.length)
			aErr[aErr.length] = validator_formatMes('maxlen', oShema.title, $sMes);

		if ( typeof(oShema.pattern) != 'undefined' && sVal.search(oShema.pattern) == -1 )
			aErr[aErr.length] = validator_formatMes('pattern', oShema.title, $sMes);

		if ( typeof(oShema.min) != 'undefined' &&  oShema.min > sVal)
			aErr[aErr.length] = validator_formatMes('min', oShema.title, $sMes);

		if ( typeof(oShema.max) != 'undefined' &&  oShema.max < sVal)
			aErr[aErr.length] = validator_formatMes('max', oShema.title, $sMes);
	}

	// for each rules
	if ( 'undefined' != typeof(aRules) ){
		for( i=0; i < aRules.length; ++i ) { // for each rules  0 - first op, 1 - second op, 2 - operation, 3 - Error message text
			var v1 = oForm.elements[aRules[i][0]].value;
			var v2 = oForm.elements[aRules[i][1]].value;
			switch( aRules[i][2] ){
				case '==' :
					if ( v1 != v2 )
						aErr[aErr.length] = aRules[i][3];
				break;
				
				case '<=' :
					if ( v1 > v2 )
						aErr[aErr.length] = aRules[i][3];
				break;
				
				case '!=' :
					if ( v1 == v2 )
						aErr[aErr.length] = aRules[i][3];
				case 'req' :
					if ( v1 && !v2 )
						aErr[aErr.length] = aRules[i][3];
				break;
			}
		}
	}
	//end rules

	if ( aErr.length ) {
		alert(aErr.join("\n\n"));
		return false;
	}
	return true;
}