var form_ = function(form_id, check_on_blur) {

    this.form = $(form_id);
    to = $(form_id).action;

    if(check_on_blur == null) {
        check_on_blur = false;
    }

    var els = $(this.form).getElements();


        for(var i = 0; i < els.length; i++) {
            Event.observe(els[i], 'focus', function() {
                this.value_ = this.value;
                this.addClassName('focus');
            });
            Event.observe(els[i], 'blur', function(event) {
                this.removeClassName('focus');
                if(check_on_blur) {
                    if(this.value_ != this.value) {
                        form_.fieldCheck(this, to);
                    }
                }
                event.stop();
            });
        }

    Event.observe(this.form, 'submit', function(event) {
        $('submit').setAttribute('disabled', 'disabled');
        form_.send(this, to);
        event.stop();
    });

    var els = $(this.form).getElementsBySelector('fieldset div span')
    for(var i = 0; i < els.length; i++) {
        var s = new Element('div', {className: 'err'});
        els[i].insertAdjacentElement("beforeBegin", s);
    }
}

form_.send = function(obj, to) {
    try {
        notify.update(form_.notify.process);
    }
    catch(e) { }

    var params = $(obj).serialize(true);

    new Ajax.Request(to, {
        parameters: params,
        onComplete: function(t) {
            var json = t.responseText.evalJSON();

            var els = $(obj).getElements();

            if(json.location != undefined) {
               window.location = json.location;
               exit;
            }
            else if (json.notify != undefined) {
               notify.update(form_.notify[json.notify], json.notify_type);
            }

            $('submit').removeAttribute('disabled', 'disabled');
 
            if (json.values != undefined) {
                for (k in json.values) {
                    var o = $(obj).getElementsBySelector('[name="'+k+'"]')[0].value = json.values[k];
                }
            }

            if (json.errors != undefined) {
                for (k in json.errors) {
                    form_.setError($(obj).getElementsBySelector('[name="'+k+'"]')[0], json.errors[k]);
                }
            }
            else {
                for(var i = 0; i < els.length; i++) {
                    form_.setError(els[i]);
                }
            }
        },
        onFailure: function() {
            $('submit').removeAttribute('disabled', 'disabled');
        }
    });
}

form_.setError = function(field, error)
{
    var o = $(field).parentNode.getElementsBySelector('div.err')[0];

    if(error == null || error == undefined) {
        $(field).removeClassName('error');
        if (!o.newline_entity && o.firstChild) o.removeChild(o.firstChild);
        o.removeClassName('show');
    }
    else {
        $(field).addClassName('error');
        if (!o.newline_entity && o.firstChild) o.removeChild(o.firstChild);
//        o.appendChild(document.createTextNode(form_.err[error]));
        o.setAttribute('title', form_.err[error]);
        o.addClassName('show');
    }
}

form_.fieldCheck = function(field, to) {
    var name = $(field).name;

    new Ajax.Request(to, {
        parameters: {value: $F(field), checkOne: true, field: name},
        onComplete: function(t) {
            var json = t.responseText.evalJSON();
            form_.fieldResult(field, json);
        }
    });
}

form_.fieldResult = function(field, json) {
    if (json.values != undefined) {
        $(field).value = json.values[field.name];
    }
    try {
        form_.setError(field, json.errors[field.name]);
    }
    catch(e) {
        form_.setError(field);
    }
}

form_.time = function(id) {
    $(id + '_all').value = $F(id + '_h') + ':' + $F(id + '_m');
}

form_.err = {
    null_: 'Заполните обязательное поле.',
    minlength: 'Недостаточно заполненое поле.',
    maxlength: 'Превышена максимальная длина.',
    false_: 'Пожалуйста, не используйте специальные символы.',
    email: 'E-mail задан неверно.',
    take_login: 'К сожалению, логин уже занят. Выберите другой.',
    take_email: 'К сожалению, e-mail уже используется другим пользователем.',
    captcha: 'Вы неправильно ввели контрольные цифры.',
    not_equal: 'Пароли не совпадают',
    notexists_email: 'Пользователь с таким e-mail не найден.',
    date_format: 'Неверный формат даты.',
    date: 'Несуществующая дата.',
    no_valid_city: 'Указанный Вами город не существует.'
};

form_.notify = {
    saved: 'Изменения примерены',
    process: 'Сохранение...',
    errors: 'Что-то произошло!!!11'
}


// insertAdjacentHTML(), insertAdjacentText() and insertAdjacentElement
// for Netscape 6/Mozilla by Thor Larholm me@jscript.dk
// Usage: include this code segment at the beginning of your document
// before any other Javascript contents.

if(typeof HTMLElement!="undefined" && ! HTMLElement.prototype.insertAdjacentElement)
{
    HTMLElement.prototype.insertAdjacentElement = function(where, parsedNode)
    {
        switch (where) {
        case 'beforeBegin':
            this.parentNode.insertBefore(parsedNode,this)
            break;
        case 'afterBegin':
            this.insertBefore(parsedNode,this.firstChild);
            break;
        case 'beforeEnd':
            this.appendChild(parsedNode);
            break;
        case 'afterEnd':
            if (this.nextSibling)
                this.parentNode.insertBefore(parsedNode,this.nextSibling);
            else this.parentNode.appendChild(parsedNode);
                break;
        }
    }
    HTMLElement.prototype.insertAdjacentHTML = function(where, htmlStr)
    {
        var r = this.ownerDocument.createRange();
        r.setStartBefore(this);
        var parsedHTML = r.createContextualFragment(htmlStr);
        this.insertAdjacentElement(where,parsedHTML)
    }
    HTMLElement.prototype.insertAdjacentText = function(where, txtStr)
    {
        var parsedText = document.createTextNode(txtStr)
        this.insertAdjacentElement(where,parsedText)
    }
}
