function diForm()
{
  this.colors = form_colors_ar;
  this.inputs = new Array;
  this.hints = new Array;
  this.containers = new Array;
  this.holds = new Array;
  this.error_flags = new Array;
  this.handlers = new Array;
  this.properties = new Array;
  this.submit_obj = {id: false, error_msg: ''};
  this.hold_hints = false;
}

diForm.prototype.colors;
diForm.prototype.inputs;
diForm.prototype.hints;
diForm.prototype.containers;
diForm.prototype.holds;
diForm.prototype.error_flags;
diForm.prototype.handlers;
diForm.prototype.properties;
diForm.prototype.submit_element;
diForm.prototype.hold_hints;

// set color
diForm.prototype.setColor = function(status, color)
{
  this.colors[status] = color;
}

// set input
diForm.prototype.setInput = function(id, handler, hold)
{
  this.inputs[id] = _ge(id);
  this.hints[id] = _ge(id+'_hint');
  this.handlers[id] = handler;
  this.holds[id] = hold;
  this.error_flags[id] = 0;
  this.properties[id] = {min_len: 0, max_len: 0, check_on_submit: true, necessary: false};
}

diForm.prototype.setInputProperty = function(id, key, value)
{
  eval('this.properties[id].'+key+' = value;');
}

diForm.prototype.setSubmit = function(id, error_msg)
{
  this.submit_obj.id = id;
  this.submit_obj.error_msg = error_msg;
  this.inputs[id] = _ge(id+'_btn');
  this.hints[id] = _ge(id+'_hint');
  this.containers[id] = _ge(id+'_container');
}

diForm.prototype.holdHints = function(to_hold)
{
  this.hold_hints = to_hold;
}

// raise error
diForm.prototype.showError = function(id, hint, color_idx)
{
  if (this.inputs[id]) this.inputs[id].style.backgroundColor = this.colors[color_idx];
  if (this.hints[id]) this.hints[id].innerHTML = hint;
  else if (id.substr(0,4) == 'dob_') this.hints['dob'].innerHTML = hint;

  this.error_flags[id] = 1;
}

// hide error
diForm.prototype.hideError = function(id)
{
  var hint = diForm.prototype.hideError.arguments.length >= 2 ? diForm.prototype.hideError.arguments[1] : '';
  var color_idx = diForm.prototype.hideError.arguments.length >= 3 ? diForm.prototype.hideError.arguments[2] : 'ok';

  if (this.inputs[id]) this.inputs[id].style.backgroundColor = this.colors[color_idx];
  if (this.hints[id]) this.hints[id].innerHTML = hint;
  else if (id.substr(0,4) == 'dob_') this.hints['dob'].innerHTML = hint;

  this.error_flags[id] = 0;
}

// run checker by handler
diForm.prototype.check = function(id)
{
  if (this.hold_hints && this.holds[id]) return false;

  this.handlers[id](this, id);

  if (this.submit_obj.id && this.hints[this.submit_obj.id] && id != 'tags')
  {
    this.hints[this.submit_obj.id].innerHTML = '';
    //!!!//
    if (this.containers[this.submit_obj.id]) this.containers[this.submit_obj.id].style.backgroundColor = this.colors['bg_ok'];
  }
}

diForm.prototype.clear = function()
{
  for (var i in this.inputs)
  {
    if (i == 'in_array' || i == this.submit_obj.id) continue;

    this.hideError(i, '', 'empty');
  }

  if (this.submit_obj.id && this.hints[this.submit_obj.id])
  {
    this.hints[this.submit_obj.id].innerHTML = '';
    //!!!//
    if (this.containers[this.submit_obj.id]) this.containers[this.submit_obj.id].style.backgroundColor = this.colors['bg_ok'];
  }
}

// did any errors happen
diForm.prototype.errorsHappened = function()
{
  var r = false;

  for (var i in this.error_flags)
  {
    if (i == 'in_array') continue;

    if (this.error_flags[i])
    {
      r = true;
      break;
    }
  }

  return r;
}

// on submit
diForm.prototype.onSubmit = function()
{
  var r = true;

  for (var i in this.error_flags)
  {
    if (i == 'in_array') continue;

    if (this.properties[i] && this.properties[i].check_on_submit)
      this.check(i);

    if (this.error_flags[i])
    {
      r = false;
    }
  }

  if (this.submit_obj.id && this.hints[this.submit_obj.id])
  {
    if (r)
    {
      this.hints[this.submit_obj.id].innerHTML = '';
      //!!!//
      if (this.containers[this.submit_obj.id]) this.containers[this.submit_obj.id].style.backgroundColor = this.colors['bg_ok'];
    }
    else
    {
      this.hints[this.submit_obj.id].innerHTML = this.submit_obj.error_msg;
      //!!!//
      if (this.containers[this.submit_obj.id]) this.containers[this.submit_obj.id].style.backgroundColor = this.colors['bg_error'];
    }
  }

  if (r)
  {
    this.inputs[this.submit_obj.id].disabled = true;
  }

  return r;
}

// --[ standard handle functions ]---------------------------------------------------------------

// form - diForm object
// id - id of the input to get checked
function __check_login(form, id)
{
  var e = form.inputs[id];
  var p = form.properties[id];

  if (e.value.length && !check_correct_latin_symbols(e.value))
    form.showError(id, 'Используйте только латинские буквы, цифры или символы &quot;_&quot;, &quot;-&quot;, &quot;.&quot;', 'error');
  else if (e.value.length < 3)
    form.showError(id, 'Минимальная длина - 3 символа', 'warning');
  else if (e.value.length > 15)
    form.showError(id, 'Максимальная длина - 15 символов', 'warning');
  else
    form.hideError(id);
}

function __check_password(form, id)
{
  var id2 = id+'2';
  var e = form.inputs[id];
  var e2 = form.inputs[id2];

  if (e.value.length < 6)
    form.showError(id, 'Минимальная длина - 6 символов', 'warning');
  else
  {
    form.hideError(id, '', 'empty');

    if (e.value != e2.value && e.value.substr(0, e2.value.length) == e2.value)
      form.hideError(id2, '', 'warning');
    else if (!e2.value.length)
      form.hideError(id2, '', 'empty');
    else if (e.value.length && e2.value.length && e.value == e2.value)
    {
      form.hideError(id, '', 'ok');
      form.hideError(id2, '', 'ok');
    }
    else //if (e.value.length && e2.value.length && e.value != e2.value)
      form.showError(id2, 'Введенные пароли не совпадают', 'error');
  }
}

function __check_string(form, id)
{
  var e = form.inputs[id];
  var p = form.properties[id];

  if (p.min_len && e.value.length < p.min_len)
    form.showError(id, 'Минимальная длина - '+p.min_len+' символ(а)', 'warning');
  else if (p.necessary && !p.min_len && e.value.length == 0)
    form.showError(id, 'Это поле обязательно для заполнения', 'warning'); //'Введите '+fields_ar[id]
  else if (p.max_len && e.value.length > p.max_len)
    form.showError(id, 'Максимальная длина - '+p.max_len+' символ(ов)', 'error');
  else
    form.hideError(id);
}

function __check_number(form, id)
{
  var e = form.inputs[id];
  var p = form.properties[id];

  if (e.value.length && !check_correct_digits(e.value))
    form.showError(id, 'Требуется ввести цифровое значение', 'error');
  else if (p.necessary && e.value.length == 0)
    form.showError(id, 'Это поле обязательно для заполнения', 'warning');
  else if (p.max_len && e.value.length > p.max_len)
    form.showError(id, 'Максимальная длина - '+p.max_len+' символов', 'error');
  else
    form.hideError(id);
}

function __check_email(form, id)
{
  var id2 = id+'2';
  var e = form.inputs[id];
  var e2 = form.inputs[id2];
  var p = form.properties[id];

  if (p.necessary && e.value.length == 0)
    form.showError(id, 'Это поле обязательно для заполнения', 'warning');
  else if (e.value.length > 60)
    form.showError(id, 'Максимальная длина - 60 символов', 'error');
  else if (!check_correct_email(e.value))
    form.showError(id, 'Введите корректный E-mail', 'warning');
  else
  {
    form.hideError(id);

    if (e2)
    {
      if (e.value != e2.value && e.value.substr(0, e2.value.length) == e2.value)
        form.hideError(id2, '', 'warning');
      else if (!e2.value.length)
        form.hideError(id2, '', 'empty');
      else if (e.value.length && e2.value.length && e.value == e2.value)
      {
        form.hideError(id, '', 'ok');
        form.hideError(id2, '', 'ok');
      }
      else //if (e.value.length && e2.value.length && e.value != e2.value)
        form.showError(id2, 'Введенные E-mail не совпадают', 'error');
    }
  }
}

function __check_url(form, id)
{
  var e = form.inputs[id];
  var p = form.properties[id];

  if (p.necessary && e.value.length == 0)
    form.showError(id, 'Это поле обязательно для заполнения', 'warning');
  else if (p.max_len && e.value.length > p.max_len)
    form.showError(id, 'Максимальная длина - '+p.max_len+' символов', 'error');
  else if (e.value != "http://" && e.value != "" && !/^(http[s]?:\/\/)?(www\.)?[0-9a-zA-Z]([-._]?[0-9a-zA-Z])*[.]{1}[a-zA-Z]{2,4}(\/.*)?$/.test(e.value))
    form.showError(id, 'Введите корректную ссылку', 'warning');
  else
    form.hideError(id);
}

function __check_random_code(form, id)
{
  var e = form.inputs[id];
  var hash = _ge(id+'_hash');
  var cur_value = hex_md5(e.value);

  if (e.value.length != 4)
    form.showError(id, 'Длина кода - 4 символа', 'warning');
  else if (hash && hash.value != cur_value)
    form.showError(id, 'Введен неверный код', 'error');
  else
    form.hideError(id);
}

var hobby_err_s = 'Выберите по крайней мере одно увлечение';

function __check_tags(form, id)
{
  var f = _ge('registration_form');
  var at_least_1 = false;

  for (var i = 0; i < f.elements.length; i++)
  {
    var e = f.elements[i];

    if (e.name && e.name.substr(0,6) == 'tags[]')
    {
      if (e.checked)
      {
        at_least_1 = true;
        break;
      }
    }
  }

  if (!at_least_1)
  {
    form.showError(id, hobby_err_s, 'error');

    //_ge('tags_table_td').style.backgroundColor = '#f66';
    //_ge('tags_table__').style.backgroundColor = '#f66';

    form.hints[form.submit_obj.id].innerHTML = form.submit_obj.error_msg;
    if (form.containers[form.submit_obj.id]) form.containers[form.submit_obj.id].style.backgroundColor = form.colors['bg_error'];
    form.inputs[form.submit_obj.id].disabled = true;
  }
  else
  {
    form.hideError(id, '', 'empty');

    //_ge('tags_table_td').style.backgroundColor = '#FAD78A';
    //_ge('tags_table__').style.backgroundColor = '#FAD78A';

    form.hints[form.submit_obj.id].innerHTML = '';
    if (form.containers[form.submit_obj.id]) form.containers[form.submit_obj.id].style.backgroundColor = form.colors['bg_ok'];
    form.inputs[form.submit_obj.id].disabled = false;
  }
}

function __check_tags2(form, id)
{
  var f = _ge('setup_tags_form');
  var at_least_1 = false;

  for (var i = 0; i < f.elements.length; i++)
  {
    var e = f.elements[i];

    if (e.name.substr(0,6) == 'tags[]')
    {
      if (e.checked)
      {
        at_least_1 = true;
        break;
      }
    }
  }

  if (!at_least_1)
  {
    form.showError(id, hobby_err_s, 'error');

    form.hints[form.submit_obj.id].innerHTML = form.submit_obj.error_msg;
    if (form.containers[form.submit_obj.id]) form.containers[form.submit_obj.id].style.backgroundColor = form.colors['bg_error'];
    form.inputs[form.submit_obj.id].disabled = true;
  }
  else
  {
    form.hideError(id, '', 'empty');

    form.hints[form.submit_obj.id].innerHTML = '';
    if (form.containers[form.submit_obj.id]) form.containers[form.submit_obj.id].style.backgroundColor = form.colors['bg_ok'];
    form.inputs[form.submit_obj.id].disabled = false;
  }
}

function __check_select(form, id)
{
  var e = form.inputs[id];
  var p = form.properties[id];

  var msg = id == 'sex' ? 'Выберите пол' : 'Это поле обязательно для заполнения';

  if (p.necessary && !e.value)
    form.showError(id, msg, 'warning');
  else
    form.hideError(id);
}

function __check_dob_select(form, id)
{
  __check_dob_selects(form, 'dob');
  return;

  //var id2 = (id && id.substr(0,4) == 'dob_') ? 'dob' : id;
}

function __check_dob_select2(form, id)
{
  var e = form.inputs[id];
  var p = form.properties[id];

  //alert(p.necessary+' '+e.value);

  if (p.necessary && !e.value)
  {
    form.showError(id, 'Введите дату рождения', 'warning');

    return false;
  }
  else
  {
    form.hideError(id);

    return true;
  }
}

function __check_dob_selects(form, id)
{
  if (id == 'dob')
  {
    var r1 = __check_dob_select2(form, 'dob_d');
    var r2 = __check_dob_select2(form, 'dob_m');
    var r3 = __check_dob_select2(form, 'dob_y');

    if (!r1 || !r2 || !r3)
      form.showError(id, 'Введите дату рождения', 'warning');
    else
      form.hideError(id);
  }
}

function __check_city(form, id)
{
  var id2 = id+'2';

  var e = form.inputs[id];
  var e2 = form.inputs[id2];
  var p = form.properties[id];

  var msg = 'Это поле обязательно для заполнения';

  if (!e || !e2) return;

  if (e.value == -1)
  {
    e2.style.visibility = 'visible';

    if (!e2.value)
    {
      form.showError(id, 'Введите город', 'warning');
      form.showError(id2, 'Введите город', 'warning');
    }
    else
    {
      form.hideError(id);
      form.hideError(id2);
    }
  }
  else
  {
    e2.style.visibility = 'hidden';

    if (p.necessary && !e.value)
      form.showError(id, msg, 'warning');
    else
      form.hideError(id);
  }
}

function __check_empty(form, id)
{
}
