// Version 1.7
// Теперь поодерживается проврка на заполнение "как минимум 1 поля" 
// (для этого первым параметром нужно передать список имен полей формы
// через запятую - вместо одного имени) и "от 1 до X полей" 
// (для этого в 5-м поле вместо длины указывается максимальное количество 
// заполняемых полей). Группу полей в этих случаях можно проверить на тип,
// но нельзя проверить на длину. Применимо главным образом для 
// checkBox с разными именами.
// (c) 2000-2001 Matvey Bogatov, Dmitriy Schetinin, Nikolai Bobrov
// Thanx to A.Systems Internet team
// If you use this script, you are obliged to mention the authors and site of origin
// 

var _check_err_empty = 0, _check_err_maxlen = 1, _check_err_invalid = 2, _check_err_atleast = 3, _check_err_inset=4;
var _check_err_templates_ru = new Array(
        'Поле "--fieldDesc--" не может быть пустым',
        'Максимальным количеством символов в поле "--fieldDesc--" является --fieldLen--',
        'Поле "--fieldDesc--" заполнено некорректно',
        'В разделе "--fieldDesc--" должно быть выбрано хотя бы одно значение',
        'В разделе "--fieldDesc--" должно быть выбрано от 1 до --fieldLen-- значений'
);
var _check_err_templates_en = new Array(
        '"--fieldDesc--" cannot be empty',
        'Maximum length of "--fieldDesc--" cannot be greater than --fieldLen--',
        '--fieldDesc-- is invalid',
        '"--fieldDesc--" section must have at least 1 value selected',
        '"--fieldDesc--" section must have 1 to --fieldLen-- values selected'
        
);

// -----------------------------------------------------------------------------------------------

var _check_err_count = 0;
var _check_err_form = null;
var _check_err = null;

function t_check_err()
{
    this.text = '';
    this.field_name = '';
    this.field_desc = '';
    this.field_type = '';
    this.focus = null;
}

// -----------------------------------------------------------------------------------------------

function form_check(form_obj, cfg_line, lang, err_count, alert_no_check)
{   if(!cfg_line.length && alert_no_check)
    { if(lang=='ru')
        alert('Ни одно из полей не проверяется!');
      else
        alert('No fields to check specified!');
    }
    if(cfg_line.substr(cfg_line.length-2,2)==';;') {
        cfg_line=cfg_line.substr(0,cfg_line.length-2);
    }
    _check_err_form = null;

    if(!form_obj) return false;
    if(typeof(form_obj) == 'string') form_obj = eval("document.forms['" + form_obj + "']");
    if(!cfg_line) return false;
    if(!lang || !eval('_check_err_templates_' + lang)) lang = 'en';

    lang = lang.toLowerCase();
    if(!err_count) err_count = 9999999;

    _check_err_form = form_obj;


    function validateChars(str, chars)
    {   var n;
        for(n = 0; n < str.length; n++) {
            if(chars.indexOf(str.charAt(n)) < 0) return false;
        }
        return true;
    }
    
    function AddError(errType, lang, fldDesc, fldName, fldType, Focus, MaxLen)
    {
        if(!MaxLen) MaxLen = 0;

        var newi = _check_err_count, txt;

        _check_err[newi] = new t_check_err();
        _check_err[newi].field_desc = fldDesc;
        _check_err[newi].field_name = fldName;
        _check_err[newi].field_type = fldType;
        _check_err[newi].focus = Focus;
        _check_err[newi].text = ('' + eval('_check_err_templates_' + lang)[errType].toString()).replace('--fieldDesc--', fldDesc).replace('--fieldLen--', MaxLen.toString());
        _check_err_count++;
    }
    
    function trim(ss)
    {
        if(!ss) return ss;
        var n, spac = ' \t\n\r';
        ss = ss.toString();
        for(n = 0; n < ss.length; n++)
            if(spac.indexOf(ss.charAt(n)) < 0) break;
        ss = ss.substring(n, ss.length);
        for(n = ss.length - 1; n >= 0; n--)
            if(spac.indexOf(ss.charAt(n)) < 0) break;
        ss = ss.substring(0, n + 1);
        return ss;
    }

    var char_lat_lo = 'abcdefghijklmnopqrstuvwxyz';
    var char_lat_hi = char_lat_lo.toUpperCase();
    var char_lat = char_lat_lo + char_lat_hi;
    var char_rus_lo = 'абвгдеёжзийклмнопрстуфхцчшщъыьэюя';
    var char_rus_hi = char_rus_lo.toUpperCase();
    var char_rus = char_rus_lo + char_rus_hi;
    var char_digits = '1234567890';
    var char_quotes = '"\'`';
    var char_spaces = ' \t\n\r';
//    var char_signs_basic = '+-*/.,=%()';
    var char_signs_basic = '!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~';
    var char_signs = '!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~';
    var char_names = char_lat + char_rus + char_spaces + '_\'&.,';

    var char_email = char_lat + char_digits + '@._-';
    var char_phone = char_digits + '()[] +-';
    var char_number = char_digits + '+- .,eE';
    var char_integer = char_digits + '+- ';


    _check_err = null;
    _check_err = new Array();
    _check_err_count = 0;

    var cfg = cfg_line.split(';;');
    var m;
    // ...............................................................
    for(m = 0; m < cfg.length; m++) {

        var cfg_detail = cfg[m].split("::");
        var fld_name = cfg_detail[0];
        var fld_desc = cfg_detail[1];
        var fld_attrs = cfg_detail[2];
        var fld_req = (cfg_detail[3] == 'req'); 
        var fld_maxlen = Number.MAX_VALUE;
        if(cfg_detail[4]) fld_maxlen = parseInt(cfg_detail[4]);
        var fld_focus = null;
        var fld_collection = null, fld_element = null;
        var fld_set=fld_name.split(",");
        if(!(fld_set.length-1)){
        if(!form_obj.elements[fld_name]) { 
            alert('INTERNAL ERROR:\nПоля с именем "' + fld_name + '" не существет в форме!'); 
            continue;
        }
    
        if(form_obj.elements[fld_name].type) {
            fld_element = form_obj.elements[fld_name];
            fld_focus = fld_element;
            fld_type = form_obj.elements[fld_name].type;
        }
        else {
            fld_collection = form_obj.elements[fld_name];
            fld_focus = fld_collection[0];
            fld_type = fld_focus.type;
        }
        
        // ...............................................................

        fld_value = ''; 
        switch(fld_type) {

            case 'radio': 
                if(fld_collection)
                  for (oo = 0; oo < fld_collection.length; oo++) {
                      if(fld_collection[oo].checked) fld_value += fld_collection[oo].value + ', ';
                  }
                else
                  if(fld_element.checked) fld_value += fld_element.value + ', ';
                break;
            case 'checkbox':
                if(fld_collection)
                  for (oo = 0; oo < fld_collection.length; oo++) {
                      if(fld_collection[oo].checked) fld_value += fld_collection[oo].value + ', ';
                  }
                else
                  if(fld_element.checked) fld_value += fld_element.value + ', ';
                break;

            case 'select-one': 
                if(fld_element.selectedIndex >= 0) {
                    fld_value = fld_element.options[fld_element.selectedIndex].value;
                    //if(!fld_value) fld_value = fld_element.options[fld_element.selectedIndex].text;
                }
                break;

            case 'select-multiple':
                fld_value = '';
                fld_collection = fld_element.options;
                for (oo = 0; oo < fld_collection.length; oo++) {
                    var el = fld_collection[oo].value;
                    //if(!el) el = fld_collection[oo].text;
                    if(fld_collection[oo].selected && el) fld_value += el + ', ';
                }
                break;

            default:
                fld_value = fld_element.value;
                

        }

        // ...............................................................

        fld_value = trim(fld_value);
        suberr = true;

        if(fld_value) if(fld_value.length > fld_maxlen) {
            suberr = true;
            AddError(_check_err_maxlen, lang, fld_desc, fld_name, fld_type, fld_focus, fld_maxlen);
            continue;
        }

        if(fld_req && fld_value == '') {
            suberr = true;
            AddError(_check_err_empty, lang, fld_desc, fld_name, fld_type, fld_focus, fld_maxlen);
            continue;
        }

        // ...............................................................


        suberr = true;
        fld_attrs = fld_attrs.toLowerCase();
        if(fld_value == '') { suberr = false; continue; }

        switch(fld_attrs) {

            case 'email': case 'e-mail':
                if(validateChars(fld_value, char_email) && fld_value.length >= 5) {
                    var indAt, indPt, len;
                    indAt = fld_value.indexOf('@');
                    indPt = fld_value.lastIndexOf('.');
                    len = fld_value.length;
                    if(indAt > 0 && indPt > indAt + 1 && indPt < len - 1) suberr = false;
                }
                break;

            case 'phone': case 'fax': case 'phone number':
                if(validateChars(fld_value, char_phone)) suberr = false;
                break;

            case 'number':
                if(validateChars(fld_value, char_number)) suberr = false;
                break;

            case 'integer':
                if(validateChars(fld_value, char_integer)) suberr = false;
                break;

            case 'string':
                if(validateChars(fld_value, char_names + char_digits + char_signs_basic)) suberr = false;
                break;

            case 'date':
                var dfmt = 'mm/dd/yy [hh:mm]';
                if(lang == 'ru') dfmt = 'dd.mm.yy [hh:mm]';
                if(check_date(fld_value, dfmt) == 0) suberr = false;
                break;
            case 'longdate':
                var dfmt = 'mm/dd/yy [hh:mm]';
                if(lang == 'ru') dfmt = 'dd.mm.yy [hh:mm]';
                if(check_date(fld_value, dfmt, 'long') == 0) suberr = false;
                break;
            case 'shortdate':
                var dfmt = 'mm/dd/yy [hh:mm]';
                if(lang == 'ru') dfmt = 'dd.mm.yy [hh:mm]';
                if(check_date(fld_value, dfmt, 'short') == 0) suberr = false;
                break;

            case 'datetime':
                var dfmt = 'mm/dd/yy hh:mm';
                if(lang == 'ru') dfmt = 'dd.mm.yy hh:mm';
                if(check_date(fld_value, dfmt) == 0) suberr = false;
                break;
            default:
                if(fld_attrs.substring(0, 1) == '+') {
                    var attrs_sub = fld_attrs.split('+');
                    var ats;
                    var char_test;

                    for(ats = 1, char_test = ''; ats < attrs_sub.length; ats++) {
                        if(attrs_sub[ats].substring(0, 1) == '#')
                            char_test += String.fromCharCode(parseInt(attrs_sub[ats].substring(1, attrs_sub[ats].length)));
                        else if(eval('char_' + attrs_sub[ats]))
                            char_test += eval('char_' + attrs_sub[ats]);
                    }
                    if(validateChars(fld_value, char_test)) suberr = false;
                }
                else suberr = false;
                break;
        }
        if(suberr) {
            AddError(_check_err_invalid, lang, fld_desc, fld_name, fld_type, fld_focus, fld_maxlen);
            err = true;
        }
        if(suberr) if(_check_err_count >= err_count) break;
        }
        else
        { var _any_checked = 0;
          for(i=0;i<fld_set.length;i++)
          { if(form_obj.elements[fld_set[i]].type.toLowerCase().indexOf('text')<0)
            { if(form_obj.elements[fld_set[i]].checked)
                _any_checked++;
            }
            else
            { if(form_obj.elements[fld_set[i]].value.length)
                _any_checked++;
            }
          }
          if(_any_checked<1 || _any_checked>=fld_maxlen)
          { if(fld_maxlen==Number.MAX_VALUE)
              AddError(_check_err_atleast, lang, fld_desc, fld_set[0], fld_set[0].type, fld_focus, fld_maxlen);
            else
              AddError(_check_err_inset, lang, fld_desc, fld_set[0], fld_set[0].type, fld_focus, fld_maxlen);
            err = true;
          }
          if(fld_attrs!='any')
          { for(nwi=0;nwi<fld_set.length;nwi++)
            { cfg[cfg.length]=fld_set[nwi]+'::'+fld_desc+'::'+fld_attrs;
            }
          }
        }
    }       // for(... in ...)

    // ...............................................................

    return (_check_err_count == 0);
}


function form_check_msg(msg_delimeter)
{
    var n, ret = '';
    if(!msg_delimeter) msg_delimeter = '\n';

    for(n = 0; n < _check_err_count; n++)
        ret += _check_err[n].text + (n < _check_err_count - 1 ? msg_delimeter : '');

    return ret;
}

function form_check_getfield(err_n)
{
    if(!err_n) err_n = 0;
    if(err_n < _check_err_count) {
        var obj = _check_err_form.elements[_check_err[err_n].field_name];
        if(obj.type) return obj; else return obj[0];
    }
    return null;
}
