var Qs_Form = {
    message: new Qs_Message({
        'eng': {
            'invalidInformationEntered': 'Please review the comments marked in red and make appropriate corrections.',
            'pleaseCorrectTheseFields': ''
        }
    }),
    options: {
        errorDisplayMethod: 'HTML'
    },

    formOptions: {},


    init: function (idForm, options)
    {
        var form = document.getElementById(idForm);
        if (!form) {
            alert('Form (id = ' + idForm + ') is not available');
            return false;
        }
        if (!form.tagName || form.tagName != 'FORM') {
            alert('Element (id = ' + idForm + ') is not a form - tagName = ' + form.tagName);
            return false;
        }
        if (options) {
            Qs_Form.formOptions[idForm] = options;
        }
        $(form).unbind('submit.form-plugin').bind('submit.form-plugin', Qs_Form.onSubmit);
        $(':submit,input:image', form).unbind('click.form-plugin').bind('click.form-plugin', Qs_Form.buttonOnClick);
    },

    buttonOnClick: function (e)
    {
        var form = this.form;
        form.clk = this;
        if (this.type == 'image') {
            if (e.offsetX != undefined) {
                form.clk_x = e.offsetX;
                form.clk_y = e.offsetY;
            } else if (typeof $.fn.offset == 'function') { // try to use dimensions plugin
                var offset = $(this).offset();
                form.clk_x = e.pageX - offset.left;
                form.clk_y = e.pageY - offset.top;
            } else {
                form.clk_x = e.pageX - this.offsetLeft;
                form.clk_y = e.pageY - this.offsetTop;
            }
        }
        setTimeout(function() {
            form.clk = form.clk_x = form.clk_y = null;
        }, 10);
    },

    getOption: function (name)
    {
        if (typeof Qs_Form.options[name] == 'undefined') {
            return null;
        }
        return Qs_Form.formOptions[name];
    },

    setErrorDisplayMethod: function (idForm, value)
    {
        Qs_Form.setFormOption(idForm, 'errorDisplayMethod', value);
    },

    getErrorDisplayMethod: function (idForm)
    {
        return Qs_Form.getFormOption(idForm, 'errorDisplayMethod');
    },

    setFormOption: function (idForm, name, value)
    {
        if (typeof Qs_Form.formOptions[idForm] == 'undefined') {
            Qs_Form.formOptions[idForm] = {};
        }
        Qs_Form.formOptions[idForm][name] = value;
    },

    getFormOption: function (idForm, name)
    {
        if (typeof Qs_Form.formOptions[idForm] == 'undefined') {
            return Qs_Form.getOption(name);
        }
        return Qs_Form.formOptions[idForm][name];
    },

    onSubmitSuccess: function (response, form)
    {
        if (response.isValid) {
            if (form) {
                if (response.callback) {
                    if (typeof Qs_Form[response.callback] != ' function') {
                        Qs_Form[response.callback].apply(Qs_Form, response.callbackArgs);
                    } else {
                        alert('Error: unknown callback function!');
                    }
                } else {
                    form.submit();
                }
            }
        } else {
            var displayMethod = Qs_Form.getErrorDisplayMethod($(form).attr('id'));
            switch (displayMethod) {
                case 'ALERT':
                    var message = Qs_Form.message.get('invalidInformationEntered') + '\n';
                    message += Qs_Form.prepareErrorsAlert(response.errors, response.elements);
                    message += '\n\n' + Qs_Form.message.get('pleaseCorrectTheseFields');
                    var key = array_key(response.errors);
                    if (form[key] && form[key].focus) {
                        form[key].focus();
                    } else if (form[key + '[input]'] && form[key + '[input]'].focus) { // встановлення фокуса для каптчі
                        form[key + '[input]'].focus();
                    }
                    $.scrollTo('#' + key + '-label');
                    alert(message);
                    break;
                case 'HTML':
                    Qs_Form.displayErrorsHtml(form, response.errors);
                    var key = array_key(response.errors);
                    var focusKey = null;
                    if (form[key] && form[key].focus) {
                        focusKey = key;
                    } else if (form[key + '[input]'] && form[key + '[input]'].focus) { // встановлення фокуса для каптчі
                        focusKey = key + '[input]';
                    }
                    if (focusKey != null) {
                        if ($('[name="' + focusKey + '"]:visible', form).size()) {
                            form[focusKey].focus();
                        }
                    }
                    $.scrollTo('#' + key + '-label');
                    alert(
                        Qs_Form.message.get('invalidInformationEntered')
                        + '\n'
                        + Qs_Form.message.get('pleaseCorrectTheseFields')
                    );
                    break;
                default:
                    alert('Qs_Form. Unknown errorDisplayMethod "' + displayMethod + '"');
            }

            if (typeof response.captcha == 'object' && response.captcha != null) {
                for (var name in response.captcha) {
                    var captcha = $('#' + name + '-element');
                    if ($(captcha).size() != 0) {
                        $('img:first', captcha).attr('src', response.captcha[name].src);
                        $('#' + name + '-id', captcha).attr('value', response.captcha[name].id);
                        $('#' + name + '-input', captcha).attr('value', '');
                    }
                }
            }
        }
        return response;
    },

    prepareErrorsAlert: function (errors, titles)
    {
        var messages = '';
        for (var element in errors) {
            var message = '';
            var isTitle = true;
            for (var errorIndex in errors[element]) {
                if (typeof errors[element][errorIndex] == 'string') {
                    message += '\n     - ' + errors[element][errorIndex];
                } else {
                    messages += Qs_Form.prepareErrorsAlert(errors[element], titles[element]);
                    isTitle = false;
                    break;
                }
            }
            if (isTitle && message != '') {
                messages += '\n' + titles[element] + ':' + message;
            }
        }
        return messages;
    },

    displayErrorsHtml: function (form, errors, belongsTo)
    {
        for (var element in errors) {
            var html = '';
            var elementName;
            if (typeof belongsTo != 'undefined') {
                elementName = belongsTo + '[' + element + ']';
            } else {
                elementName = element;
            }
            for (var errorIndex in errors[element]) {
                if (typeof errors[element][errorIndex] == 'string') {
                    html += '<li>' + errors[element][errorIndex] + '</li>';
                } else {
                    Qs_Form.displayErrorsHtml(form, errors[element], elementName);
                    break;
                }
            }
            if (html != '') {
                html = '<ul class="errors">' + html + '</ul>';
                var id = elementName.replace(/\[\]$/, '').replace(/\]/g, '').replace(/\[/g, '-') + '-element';
                $('#' + id).append(html);
            }
        }
    },

    onSubmitError: function (response, ioArgs)
    {
        alert(response);
        return response;
    },

    onSubmitComplete: function (XMLHttpRequest, textStatus, form)
    {
        var idForm = $(form).attr('id');
        Qs_Form.formOptions[idForm]['processRequest'] = false;
    },

    removeElementsErrors: function (form)
    {
        $('ul.errors', form).remove();
    },

    onSubmit: function (spec)
    {
        var form;
        if (this.tagName == 'FORM') {
            form = this;
        } else {
            form = spec;
        }
        var idForm = $(form).attr('id');

        if (typeof tinyMCE != 'undefined') {
            tinyMCE.triggerSave();
        }

        if (typeof FCKeditorAPI != 'undefined') {
            for (var i = 0; i < form.elements.length; i++) {
                if (form.elements[i].tagName == 'TEXTAREA') {
                    var fckObject = FCKeditorAPI.GetInstance(form.elements[i].name);
                    if (typeof fckObject != 'undefined') {
                        if (fckObject.IsDirty()) {
                            fckObject.UpdateLinkedField();
                        }
                    }
                }
            }
        }

        Qs_Form.removeElementsErrors(form);

        if (typeof Qs_Form.formOptions[idForm]['processRequest'] == 'undefined'
            || Qs_Form.formOptions[idForm]['processRequest'] != true) {
            Qs_Form.formOptions[idForm]['processRequest'] = true;
            var options = {
                url: $(form).attr('action'),
                type: 'POST',
                dataType: 'json',
                data: Qs_Form.toObject(form),
                success: function (data)
                {
                    Qs_Form.onSubmitSuccess(data, form);
                },
                error: Qs_Form.onSubmitError,
                complete: function (XMLHttpRequest, textStatus)
                {
                    Qs_Form.onSubmitComplete(XMLHttpRequest, textStatus, form)
                }
            };
            $.ajax(options);
        }
        return false;
    },

    setValue: function(/*Object*/obj, /*String*/name, /*String*/value)
    {
        var val = obj[name];
        if(is_string(val)) {
            obj[name] = [val, value];
        } else if (is_array(val)) {
            val.push(value);
        } else {
            obj[name] = value;
        }
    },

    toObject: function (/*DOMNode||String*/ formNode)
    {
        var ret = {};
        var exclude = 'file|submit|image|reset|button|';
        if (is_string(formNode)) {
            formNode = document.getElementById(formNode);
        }
        for (var i = 0; i<formNode.elements.length; i++) {
            var item = formNode.elements[i];
            if (!item) {
                continue;
            }
            var _in = item.name;
            var type = (item.type||"").toLowerCase();
            if(_in && type && exclude.indexOf(type) == -1 && !item.disabled){
                if (type == "radio" || type == 'checkbox') {
                    if (item.checked) {
                        Qs_Form.setValue(ret, _in, item.value);
                    }
                } else if (item.multiple) {
                    ret[_in] = [];
                    for (var j in item.options) {
                        if (
                            item.options[j] != null
                            && typeof item.options[j].tagName == 'string'
                            && item.options[j].tagName == 'OPTION'
                            && item.options[j].selected
                        ) {
                            Qs_Form.setValue(ret, _in, item.options[j].value);
                        }
                    }
                } else {
                    Qs_Form.setValue(ret, _in, item.value);
                    if(type == 'image'){
                        ret[_in+".x"] = ret[_in+".y"] = ret[_in].x = ret[_in].y = 0;
                    }
                }
            }
        }
        if (formNode.clk && !formNode.clk.disabled && formNode.clk.name) {
            if (formNode.clk.type == 'image') {
                ret[formNode.clk.name + '.x'] = formNode.clk_x;
                ret[formNode.clk.name + '.y'] = formNode.clk_y;
            } else {
                ret[formNode.clk.name] = formNode.clk.value;
            }
        }
        return ret; // Object
    },

    _reserveHomeShowThans: function(idForm) {
        var formContainer = $('#' + idForm + '-container');
        var formThanks = $('#' + idForm + '-thanks');
        if ($(formContainer).size() && $(formThanks).size()) {
            $(formContainer).hide();
            $(formThanks).show();
        }
        return true;
    }
}
