
var KariFormRegistry = {};

var KariForm = Class.create({
    initialize: function(options) {
        this.options = Object.extend({
            form: null,
            formErrorsBox: null
        }, options);

        this.form = $(this.options.form);
        KariFormRegistry[this.form.id] = this;
        this.requestParams = {};
        this.formErrorsBox = (null == this.options.formErrorsBox) ? null : $(this.options.formErrorsBox);

        Event.observe(this.form, 'submit', this.onSubmit.bindAsEventListener(this));

        this.shouldEnable = [];
    },

    request: function(params)
    {
        if (!params) {
            params = {};
        }
        Object.extend({
            onSuccess: null,
            parameters: {}
        }, params);
        this.requestParams = params;

        this.form.request({
            parameters: this.requestParams.parameters,

            onCreate: function(request) {
                this.disableForm();
            }.bind(this),

            onComplete: function(request) {
                this.enableForm();
            }.bind(this),

            onFailure: function(response) {
                window.alert('Request failed!');
            }.bind(this),

            onSuccess: function(response) {
                var result = response.responseText.evalJSON();
                this.updateErrors((undefined == result.errors) ? {} : result.errors);
                if ('undefined' != typeof(result.url)) {
                    if ('' == result.url) {
                        window.location.reload();
                    } else {
                        window.location.assign(result.url);
                    }
                    return;
                }
                if ('undefined' != typeof(result.script)) {
                    eval(result.script);
                }

                if (this.requestParams.onSuccess) {
                    this.requestParams.onSuccess(response);
                }
            }.bind(this),

            onException: function(request, exception) {
                alert(exception);
            }
        });
    },

    onSubmit: function(event) {
        event.stop();

        // FCKeditor fields auto-detection
        if (typeof(FCKeditorAPI) != 'undefined') {
            $A(Form.getElements(this.form)).each(function(element) {
                var tail = '___Config';
                if (element.id.substr(element.id.length - tail.length, tail.length) == tail) {
                    var editor = FCKeditorAPI.GetInstance(element.id.substr(0, element.id.length - tail.length));
                    if (editor) {
                        editor.UpdateLinkedField();
                    }
                }
            });
        }

        this.request();
    },

    updateErrorBox: function(box, error, context) {
        Element.getElementsBySelector(box, '.errors').each(function(element) {
            element.remove();
        });

        if ('object' != typeof(error)) {
            error = {
                placement: 'APPEND',
                content: error
            }
        }

        var placeholder = document.createElement('span');
        if ('APPEND' == error.placement) {
            box.appendChild(placeholder);
        } else {
            box.insertBefore(placeholder, element);
        }
        Element.replace(placeholder, error.content);

        if (!context.scrollTo) {
            context.scrollTo = box;
        }
    },

    updateErrors: function(errors) {
        var context = {
            scrollTo: null
        }

        if ('undefined' != typeof(errors['']) && this.formErrorsBox) {
            this.updateErrorBox(this.formErrorsBox, errors[''], context);
        }

        $A(Form.getElements(this.form)).each(function(errors, context, element) {
            var box;
            if ('' == element.id || !(box = $(element.id + '-element'))) {
                return;
            }

            this.updateErrorBox(box, errors[element.id], context);
        }.bind(this, errors, context));

        if (context.scrollTo) {
            $(context.scrollTo).scrollTo();
        }
    },

    disableForm: function() {
        this.form.getElements().each(function(element) {
            if (!element.disabled) {
                element.disable();
                this.shouldEnable.push(element);
            }
        }.bind(this));
    },

    enableForm: function() {
        while (this.shouldEnable.length) {
            this.shouldEnable.pop().enable();
        }
    }
});
