/**
 * 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]));
     return $sDef ? $sDef: '`'+sField + '` : ' + 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();
        var oFld  = null; // first field with error

        // for each fields
        for( i=0; i< aShema.length; ++i )
        {
                var oShema = aShema[i];
                var sVal = validator_getValue(oForm.elements[oShema.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);

                if (aErr.length && oFld == null) // if first error
                        oFld = oForm.elements[oShema.field];

        }

        // 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 ( parseFloat(v1) > parseFloat(v2) )
                                                aErr[aErr.length] = aRules[i][3];
                                break;
                                case '>=' :
                                        if ( parseFloat(v1) < parseFloat(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;
                        }

                        if (aErr.length && oFld == null) // if first error
                            oFld = oForm.elements[aRules[i][0]];
                }
        }
        //end rules

        if ( aErr.length ) {
                alert(aErr.join("\n"));
                oFld.focus();
                return false;
        }
        return true;
}

