jscape.storage = jscape.storage || {};

/** @class */
jscape.storage.StorageApplication = jscape.Application.extend(
    /** @lends {jscape.storage.StorageApplication.prototype} */
{
    onLogout: function() {
        jscape.API.logout();
    },

    /** @override */
    onReady: function() {
        this._super();
        this.view.show(this);

        this._forceStartModule("password-compliance");
        this._forceStartModule("account-inactivity");
        this._forceStartModule("file-upload");
    },

    /** @override */
    _createView: function() {
        this._super();
        this.view = new jscape.storage.StorageView();
    },

    /** @override */
    _destroy: function() {
        this._forceStopModule("file-upload");
        this._forceStopModule("account-inactivity");
        this._forceStopModule("password-compliance");
        this._super();
    }
});

/** @class */
jscape.storage.StorageView = jscape.DashboardView.extend(
    /** @lends {jscape.storage.StorageView.prototype} */
{
    /** @constructor */
    initialize: function () {
        this._super($());
    },

    show: function (listener) {
        this._super(listener || jscape.storage.StorageView.LISTENER);
    }
});
jscape.storage.StorageView.LISTENER = {
    onLogout: $.noop
};

/** @class */
jscape.storage.PasswordComplianceModule = jscape.ApplicationModule.extend(
    /** @lends {jscape.storage.PasswordComplianceModule.prototype} */
{
    passwordChanged: false,

    onCreate: function(username) {
        this.username = username;
        this.view = new jscape.storage.PasswordComplianceView();
    },

    onStart: function() {
        if (!this.passwordChanged) {
            this.view.show(this);
        }
    },

    onStop: function() {
        if (this.view) {
            this.view.destroy();
            this.view = null;
        }
    },

    onChangePassword: function(dialog) {
        dialog.destroy();
        var controller = new jscape.storage.ChangePasswordController();
        controller.start(this.username)
                .done($.proxy(function() { this.passwordChanged = true; this._firePasswordChanged(); }, this));
    },

    onClose: function(dialog) {
        dialog.destroy();
    },

    _firePasswordChanged: function() {
        $(document).triggerHandler("broadcast", [window.R.string.USER_CHANGE_PASSWORD_MESSAGE]);
    }
});

/** @class */
jscape.storage.PasswordComplianceView = Class.extend(
    /** @lends {jscape.storage.PasswordComplianceView.prototype} */
{
    /** @constructor */
    initialize: function() {
        this.holder = $("#logininfo");
        var reminder = $("#password-reminder");

        if (this.holder.length && reminder.length) {
            this.holder.tooltip({
                content: reminder.html(),
                showEvent: "none",
                hideEvent: "none",
                onShow: $.proxy(function () {
                    this.holder.tooltip("tip")
                            .addClass("tooltip-tip-black")
                            .one("click", $.proxy(function () { this.holder.tooltip("destroy"); }, this))
                            .find("a[role=button][name=changepwd]").linkbutton({onClick: $.proxy(this._onClick$ChangePasswordButton, this)});
                    this.holder.tooltip("reposition");
                }, this),
                onHide: function() { $(this).tooltip("destroy"); }
            });
        }
    },

    show: function(listener) {
        this.listener = listener || jscape.storage.PasswordComplianceView.LISTENER;
        if (this.holder.length) {
            this.holder.tooltip("show");
            $(window).on("resize.password_reminder", $.proxy(function () {
                this.holder.tooltip("reposition");
            }, this));
        }
    },

    destroy: function() {
        if (this.holder.length) {
            this.holder.tooltip("destroy");
            $(window).off("resize.password_reminder");
        }
    },

    _onClick$ChangePasswordButton: function() {
        this.listener.onChangePassword(this);
    }
});
jscape.storage.PasswordComplianceView.LISTENER = {
    onChangePassword: $.noop
};

/** @class */
jscape.storage.ChangePasswordController = Class.extend(
    /** @lends {jscape.storage.ChangePasswordController.prototype} */
{
    deferred: null,

    initialize: function() {
        this._initValidators();
    },

    start: function(username) {
        this.username = username;
        this.deferred = $.Deferred();
        this._setupDialog().show(this);
        return this.deferred.promise();
    },

    onSubmit: function(dialog) {
        var password = dialog.getPassword();
        dialog.destroy();

        jscape.API.changeUserPassword(this.username, password)
                .done($.proxy(function() { this.deferred.resolve(); this.deferred = null; }, this))
                .fail($.proxy(function() { this.deferred.reject(); this.deferred = null; }, this));
    },

    onCancel: function(dialog) {
        dialog.destroy();
        this.deferred.reject();
        this.deferred = null;
    },

    _setupDialog: function() {
        var dialog = new jscape.storage.ChangePasswordDialog();
        dialog.setUsername(this.username);
        return dialog;
    },

    _initValidators: function() {
        var v = new jscape.Validator();
        v.rule("pi_password_compliance", $.proxy(this._passwordCompliant, this), "");
        v.rule("pi_password_confirm", $.proxy(this._passwordConfirmed, this), window.R.string.USER_ERROR_CONFIRM_PWD);
    },

    _passwordCompliant: function (value, params) {
        var accountName = params && params.length ? params[0] : null;
        var result = jscape.API.testPasswordCompliance(accountName, value);
        if ($.isPlainObject(result)) {
            if (result.valid === false && result.message) {
                new jscape.Validator().ruleMessage("pi_password_compliance", result.message);
            }
            return !!result.valid;
        }
        return true;
    },

    _passwordConfirmed: function (value, params) {
        return params && params.length && $(params[0]).val() == value;
    }
});

/** @class */
jscape.storage.ChangePasswordDialog = Class.extend(
    /** @lends {jscape.storage.ChangePasswordDialog.prototype} */
{
    /** @constructor */
    initialize: function() {
        this.dialog = $("#d-user-changepwd").clone().attr("id", "");
        this.dialog.dialog({
            width: 530, height: "auto",
            modal: true, resizable: false, closable: true, closed: true,
            buttons: [
                {text: window.R.string.DIALOG_BUTTON_OK || "Ok", handler: $.proxy(this._onSubmit, this)},
                {text: window.R.string.DIALOG_BUTTON_CANCEL || "Cancel", handler: $.proxy(this._onCancel, this)}
            ],
            onClose: $.proxy(function () {if (!this.closing) { this._onCancel(); }}, this)
        }).show();

        this.fieldset = $("fieldset[name=userpasswordfields]", this.dialog);

        var id = "newpwd_" + $.now().toString(36);
        this.password = $("input[name=password]", this.fieldset).textbox({validType: "pi_password_compliance", delay: 700, width: "70%"});
        this.password.textbox("textbox")
                .on("input", $.proxy(function() { this.confirmPassword.textbox({required: this.password.textbox("textbox").val().length != 0}); }, this))
                .attr("id", id);

        this.confirmPassword = $("input[name=confirmpwd]", this.fieldset).textbox({validType: "pi_password_confirm['#" + id + "']", missingMessage: window.R.string.USER_ERROR_CONFIRM_PWD, width: "70%"});
    },

    getPassword: function() {
        return this.password.textbox("getValue");
    },

    setUsername: function(value) {
        this._adjustPasswordRequirements(value);
    },

    show: function (listener) {
        this.listener = listener;
        this.dialog.dialog("center").dialog("open");
        this.fieldset.form("validate");
        this.password.textbox("textbox").focus();
    },

    hide: function () {
        if (!this._closed()) {
            this.closing = true;
            this.dialog.dialog("close");
            this.fieldset.form("disableValidation");
            this.closing = false;
        }
    },

    destroy: function() {
        this.dialog.dialog("destroy");
    },

    _adjustPasswordRequirements: function(username) {
        var compliant = new jscape.Validator().isSatisfied("pi_password_compliance", "", username);
        var options = this.password.textbox("textbox").validatebox("options");
        options.validType = "pi_password_compliance" + (username ? "['" + username + "']" : "");
        options.required = !compliant;
    },

    _onSubmit: function () {
        if (this.confirmPassword.textbox("isValid") && this.password.textbox("isValid")) {
            this.listener.onSubmit(this);
        }
    },

    _onCancel: function () {
        this.hide();
        this.listener.onCancel(this);
    },

    _closed: function () {
        return !!this.dialog.dialog("options").closed;
    }
});