/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
*/

/* brooklyn extensions for supporting views */
define([
    "jquery", "underscore", "backbone", "brooklyn-utils",
    "text!tpl/lib/basic-modal.html",
    "text!tpl/lib/config-key-type-value-input-pair.html"
    ], function (
    $, _, Backbone, Util,
    ModalHtml, ConfigKeyInputHtml
) {

    var module = {};

    module.refresh = true;

    /** Toggles automatic refreshes of instances of View. */
    module.toggleRefresh = function () {
        this.refresh = !this.refresh;
        return this.refresh;
    };

    // TODO this customising of the View prototype could be expanded to include
    // other methods from viewutils. see discussion at
    // https://github.com/brooklyncentral/brooklyn/pull/939

    // add close method to all views for clean-up
    // (NB we have to update the prototype _here_ before any views are instantiated;
    //  see "close" called below in "showView")
    Backbone.View.prototype.close = function () {
        // call user defined close method if exists
        this.viewIsClosed = true;
        if (_.isFunction(this.beforeClose)) {
            this.beforeClose();
        }
        _.each(this._periodicFunctions, function (i) {
            clearInterval(i);
        });
        this.remove();
        this.unbind();
    };

    Backbone.View.prototype.viewIsClosed = false;

    /**
     * Registers a callback (cf setInterval) that is unregistered cleanly when the view
     * closes. The callback is run in the context of the owning view, so callbacks can
     * refer to 'this' safely.
     */
    Backbone.View.prototype.callPeriodically = function (uid, callback, interval) {
        if (!this._periodicFunctions) {
            this._periodicFunctions = {};
        }
        var old = this._periodicFunctions[uid];
        if (old) clearInterval(old);

        // Wrap callback in function that checks whether updates are enabled
        var periodic = function () {
            if (module.refresh) {
                callback.apply(this);
            }
        };
        // Bind this to the view
        periodic = _.bind(periodic, this);
        this._periodicFunctions[uid] = setInterval(periodic, interval);
    };

    /**
     * A form that listens to modifications to its inputs, maintaining a model that is
     * submitted when a button with class 'submit' is clicked.
     *
     * Expects a body view or a template function to render.
     */
    module.Form = Backbone.View.extend({
        events: {
            "change": "onChange",
            "submit": "onSubmit"
        },

        initialize: function() {
            if (!this.options.body && !this.options.template) {
                throw new Error("body view or template function required by GenericForm");
            } else if (!this.options.onSubmit) {
                throw new Error("onSubmit function required by GenericForm");
            }
            this.onSubmitCallback = this.options.onSubmit;
            this.model = new (this.options.model || Backbone.Model);
            _.bindAll(this, "onSubmit", "onChange");
            this.render();
        },

        beforeClose: function() {
            if (this.options.body) {
                this.options.body.close();
            }
        },

        render: function() {
            if (this.options.body) {
                this.options.body.render();
                this.$el.html(this.options.body.$el);
            } else {
                this.$el.html(this.options.template());
            }
            // Initialise the model with existing values
            Util.bindModelFromForm(this.model, this.$el);
            return this;
        },

        onChange: function(e) {
            var target = $(e.target);
            var name = target.attr("name");
            this.model.set(name, Util.inputValue(target), { silent: true });
        },

        onSubmit: function(e) {
            e.preventDefault();
            // Could validate model
            this.onSubmitCallback(this.model.clone());
            return false;
        }

    });

    /**
     * A view to render another view in a modal. Give another view to render as
     * the `body' parameter that has an onSubmit function that will be called
     * when the modal's `Save' button is clicked, and/or an onCancel callback
     * that will be called when the modal is closed without saving.
     *
     * The onSubmit callback should return either:
     * <ul>
     *   <li><b>nothing</b>: the callback is treated as successful
     *   <li><b>true</b> or <b>false</b>: the callback is treated as appropriate
     *   <li>a <b>promise</b> with `done' and `fail' callbacks (for example a jqXHR object):
     *     The callback is treated as successful when the promise is done without error.
     *   <li><b>anything else</b>: the callback is treated as successful
     * </ul>
     * When the onSubmit callback is successful the modal is closed.
     *
     * The return value of the onCancel callback is ignored.
     *
     * The modal will still be open and visible when the onSubmit callback is called.
     * The modal will have been closed when the onCancel callback is called.
     */
    module.Modal = Backbone.View.extend({

        id: _.uniqueId("modal"),
        className: "modal",
        template: _.template(ModalHtml),

        events: {
            "hide": "onClose",
            "click .modal-submit": "onSubmit"
        },

        initialize: function() {
            if (!this.options.body) {
                throw new Error("Modal view requires body to render");
            }
            _.bindAll(this, "onSubmit", "onCancel", "show");
            if (this.options.autoOpen) {
                this.show();
            }
        },

        beforeClose: function() {
            if (this.options.body) {
                this.options.body.close();
            }
        },

        render: function() {
            var optionalTitle = this.options.body.title;
            var title = _.isFunction(optionalTitle)
                    ? optionalTitle()
                    : _.isString(optionalTitle)
                        ? optionalTitle : this.options.title;
            this.$el.html(this.template({
                title: title,
                submitButtonText: this.options.submitButtonText || "Apply",
                cancelButtonText: this.options.cancelButtonText || "Cancel"
            }));
            this.options.body.render();
            this.$(".modal-body").html(this.options.body.$el);
            return this;
        },

        show: function() {
            this.render().$el.modal();
            return this;
        },

        onSubmit: function(event) {
            if (_.isFunction(this.options.body.onSubmit)) {
                var submission = this.options.body.onSubmit.apply(this.options.body, [event]);
                var self = this;
                var submissionSuccess = function() {
                    // Closes view via event.
                    self.closingSuccessfully = true;
                    self.$el.modal("hide");
                };
                var submissionFailure = function () {
                    // Better response.
                    console.log("modal submission failed!", arguments);
                };
                // Assuming no value is fine
                if (!submission) {
                    submission = true;
                }
                if (_.isBoolean(submission) && submission) {
                    submissionSuccess();
                } else if (_.isBoolean(submission)) {
                    submissionFailure();
                } else if (_.isFunction(submission.done) && _.isFunction(submission.fail)) {
                    submission.done(submissionSuccess).fail(submissionFailure);
                } else {
                    // assuming success and closing modal
                    submissionSuccess()
                }
            }
            return false;
        },

        onCancel: function () {
            if (_.isFunction(this.options.body.onCancel)) {
                this.options.body.onCancel.apply(this.options.body);
            }
        },

        onClose: function () {
            if (!this.closingSuccessfully) {
                this.onCancel();
            }
            this.close();
        }
    });

    /**
     * Shows a modal with yes/no buttons as a user confirmation prompt.
     * @param {string} question The message to show in the body of the modal
     * @param {string} [title] An optional title to show. Uses generic default if not given.
     * @returns {jquery.Deferred} The promise from a jquery.Deferred object. The
     *          promise is resolved if the modal was submitted normally and rejected
     *          otherwise.
     */
    module.requestConfirmation = function (question, title) {
        var deferred = $.Deferred();
        var Confirmation = Backbone.View.extend({
            title: title || "Confirm action",
            render: function () {
                this.$el.html(question || "");
            },
            onSubmit: function () {
                deferred.resolve();
            },
            onCancel: function () {
                deferred.reject();
            }
        });
        new module.Modal({
            body: new Confirmation(),
            autoOpen: true,
            submitButtonText: "Yes",
            cancelButtonText: "No"
        });
        return deferred.promise();
    };

    /** Creates, displays and returns a modal with the given view used as its body */
    module.showModalWith = function (bodyView) {
        return new module.Modal({body: bodyView}).show();
    };

    /**
     * Presents inputs for config key names/values with  buttons to add/remove entries
     * and a function to extract a map of name->value.
     */
    module.ConfigKeyInputPairList = Backbone.View.extend({
        template: _.template(ConfigKeyInputHtml),
        // Could listen to input change events and add 'error' class to any type inputs
        // that duplicate values.
        events: {
            "click .config-key-row-remove": "rowRemove",
            "keypress .last": "rowAdd"
        },
        render: function () {
            if (this.options.configKeys) {
                var templated = _.map(this.options.configKeys, function (value, key) {
                    return this.templateRow(key, value);
                }, this);
                this.$el.html(templated.join(""));
            }
            this.$el.append(this.templateRow());
            this.markLast();
            return this;
        },
        rowAdd: function (event) {
            this.$el.append(this.templateRow());
            this.markLast();
        },
        rowRemove: function (event) {
            $(event.currentTarget).parent().remove();
            if (this.$el.children().length == 0) {
                this.rowAdd();
            }
            this.markLast();
        },
        markLast: function () {
            this.$(".last").removeClass("last");
            // Marking inputs rather than parent div to avoid weird behaviour when
            // remove row button is triggered with the keyboard.
            this.$(".config-key-type").last().addClass("last");
            this.$(".config-key-value").last().addClass("last");
        },
        templateRow: function (type, value) {
            return this.template({type: type || "", value: value || ""});
        },
        getConfigKeys: function () {
            var cks = {};
            this.$(".config-key-type").each(function (index, input) {
                input = $(input);
                var type = input.val() && input.val().trim();
                var value = input.next().val() && input.next().val().trim();
                if (type && value) {
                    cks[type] = value;
                }
            });
            return cks;
        }
    });

    return module;

});
