var knockoutControllerBase = function (options) {
    _.extend(this, options);

    this.show = function () {

        knockoutControllerBase.current = this;

        var self = this;

        if (typeof this.ajax != 'undefined') {

            var ajaxData = this.ajax();

            ajaxData.success = function (data) {

                if (data) {

                    var $region = self.getRegion();

                    $('#section-carregar-mais').empty();
                    $region.empty();
                    $region.html(data);

                    var callback = $.proxy(self.controllerRenderizado, self);
                    callback();

                }
            };

            global.ajax(ajaxData);

        } else {
            this.renderizar($.proxy(this.controllerRenderizado, this));
        }

    };

    this.controllerRenderizado = function () {

        if (typeof this.antesRenderizacaoCompleta != 'undefined') {
            this.antesRenderizacaoCompleta();
        }

        var region = this.getRegion();

        region.show();


        if (typeof this.renderizado != 'undefined') {
            var callback = $.proxy(this.renderizado, this);
            callback();
        }


        ko.cleanNode(region[0]);
        this.initializeComponents();
        this.attachEvents();
        this.initializeForm();
        ko.applyBindings(this, region[0]);


        if (typeof this.aposBinding != 'undefined') {
            var aposBindingCallBack = $.proxy(this.aposBinding, this);
            aposBindingCallBack();
        }

    };

    this.initializeComponents = function() {

        global.addValidators();
        global.applyMasks();
        $.iniciaSelect2();

    };

    this.attachEvents = function () {

        var events = typeof this.events != 'undefined' && this.events ? this.events : null;

        if (!events) {
            return;
        }


        for (var key in events) {

            var arr = key.split(' ');

            if (arr.length == 2) {
                $(arr[1]).on(arr[0], $.proxy(this[events[key]], this));
            }
        }

    };

    this.getFormData = function() {

        var $form = $(this.formConfig.selector);

        if ($form.length == 0) {
            return null;
        }

        return global.convertFormToJSON({
            element: $form
        });
    };

    this.initializeForm = function () {

        if (typeof this.formConfig == 'undefined' || !this.formConfig) {
            return;
        }

        if (typeof this.formConfig.submit != 'undefined' && this.formConfig.submit) {

            var $submit = $(this.formConfig.submit.selector);

            if ($submit.length > 0) {
                $submit.click($.proxy(this.submitForm, this, 1));
            }

            if (this.formConfig.submit.submitOnEnter) {

                $(this.formConfig.selector).keypress(function(e) {
                    if (e.which == 13) {
                        e.preventDefault();
                        try {
                            $submit.trigger('click');
                        } catch (ex) { }
                        return false;
                    }
                });

                //$(':input', $(this.formConfig.selector)).keypress(function(e) {

                //    if (e.which == 13) {
                //        try {
                //            $submit.trigger('click');
                //        } catch (ex) { }
                //        return false;
                //    }

                    

                //});
            }

        }

        global.configForm(this.formConfig);
        
    };

    this.submitForm = function (pagina, e) {

        var self = this;

        if (e) {
            e.preventDefault();
        }

        var $form = $(this.formConfig.selector);

        if (!$form.valid()) {
            return false;
        }

        var submitConfig = this.formConfig.submit;
        var $e = $(e.target);

        if (submitConfig.loadingText) {
            submitConfig.text = $e.html();
            $e.html(submitConfig.loadingText);
        }


        var submitCallback = typeof submitConfig.callback != 'undefined' && submitConfig.callback ? this[submitConfig.callback] : null;
        var ajax = typeof this.formConfig.ajax != 'undefined' && this.formConfig.ajax ? this.formConfig.ajax : null;
        

        if (submitConfig.beforeSubmit) {
            this[submitConfig.beforeSubmit]();
        }

        var afterSubmitCallback = null;

        if (submitConfig.afterSubmit) {
            afterSubmitCallback = this[submitConfig.afterSubmit];
        }

        var modelData = submitConfig.type == 'model'
            ? ko.mapping.toJS(this.model)
            : global.convertFormToJSON({
                element: $form
            });

        if (submitCallback) {
            var callback = $.proxy(submitCallback, self, modelData, e);
            callback();
        }

        if (ajax) {

            var ajaxData = {};

            if (ajax.param) {
                ajaxData[ajax.param] = modelData;
            } else {
                ajaxData = modelData;
            }

            ajax.contentType = 'application/json';
            ajax.data = JSON.stringify(ajaxData);

            ajax.success = function(data) {

                if (submitConfig.text) {
                    $e.html(submitConfig.text);
                }

                if (data) {
                    global.resolveDates(data);
                }

                if (afterSubmitCallback) {
                    afterSubmitCallback(data);
                }
            };

            global.ajax(ajax);
        } else {
            if (submitConfig.text) {
                $e.html(submitConfig.text);
            }
        }
    };
    
    this.toJS = function(value) {
        
        if (!value) {
            return null;
        }

        return ko.mapping.toJS(value);
    },

    this.getRegion = function () {

        if (!this.region) {
            return null;
        }

        return $(this.region);

    },


    this.hide = function () {

        var $region = this.getRegion();

        if (!$region) {
            return;
        }

        $region.hide();
    };

    this.createModel = function() {

        if (!this.model) {
            this.model = {};
        }

    };

    this.setModel = function (model) {
        if (model) {
            global.resolveDates(model);
            this.model = ko.mapping.fromJS(model);
        } else {
            this.createModel();
        }
    };

    this.appendToModel = function(name, model) {
        

        this.createModel();

        if (!model) {
            return;
        }
        
        switch (typeof model) {
            case 'function':
                model = $.proxy(model, this.model);
                break;
            case 'object':

                if (Array.isArray(model)) {
                    model = ko.observableArray(model);
                } else {
                    model = ko.observable(model);
                }

                break;
        }
        
        this.model[name] = model;
        
    };

    if (this.initialize) {
        this.initialize();
    }

};

knockoutControllerBase.extend = _extendControllerBase;

ko.bindingHandlers.enterkey = {
    init: function (element, valueAccessor, allBindings, viewModel) {
        var callback = valueAccessor();
        $(element).keypress(function (event) {
            var keyCode = (event.which ? event.which : event.keyCode);
            if (keyCode === 13) {
                callback.call(viewModel);
                return false;
            }
            return true;
        });
    }
};


