jscape.domain = jscape.domain || {};

/** @class */
jscape.Quota = Class.extend(
    /** @lends {jscape.Quota.prototype} */
{
    /** @constructor */
    initialize: function(a, b, c) {
        this.bytes = parseInt(a) || 0;
        this.resetPeriod = parseInt(b) || 0;
        this.transferredBytes = parseInt(c) || 0;
    },

    toJSON: function() {
        return {bytes: this.bytes, resetPeriod: this.resetPeriod};
    }
});
jscape.Quota.fromJSON = function(data) {
    return data ? new jscape.Quota(data.bytes, data.resetPeriod, data.transferredBytes) : null;
};

/** @class */
jscape.AccountTransferQuotas = Class.extend(
    /** @lends {jscape.AccountTransferQuotas.prototype} */
{
    /** @constructor */
    initialize: function(a, b, c, d, e, f) {
        this.uploadsQuota = a || null;
        this.downloadsQuota = b || null;
        this.transfersQuota = c || null;
        this.maxUploadsPerSession = parseInt(d) || null;
        this.maxDownloadsPerSession = parseInt(e) || null;
        this.maxTransferRate = parseInt(f) || null;
    }
});
jscape.AccountTransferQuotas.fromJSON = function (data) {
    return data
           ? new jscape.AccountTransferQuotas(jscape.Quota.fromJSON(data.uploadsQuota),
                                              jscape.Quota.fromJSON(data.downloadsQuota),
                                              jscape.Quota.fromJSON(data.transfersQuota),
                                              data.maxUploadsPerSession,
                                              data.maxDownloadsPerSession,
                                              data.maxTransferRate)
           : null;
};

/** @class */
jscape.IpAccessVerifier = Class.extend(
    /** @lends {jscape.IpAccessVerifier.prototype} */
{
    /** @constructor */
    initialize: function(masks) {
        this.masks = masks || [];
    }
});
jscape.IpAccessVerifier.fromJSON = function(data) {
    return new jscape.IpAccessVerifier($.map(data.masks || [], jscape.IpAccessVerifier.IPMask.fromJSON));
};

/** @class */
jscape.IpAccessVerifier.IPMask = Class.extend(
    /** @lends {jscape.IpAccessVerifier.IPMask.prototype} */
{
    /** @constructor */
    initialize: function(a, b, c) {
        this.mask = a || "";
        this.reason = b || "";
        this.allowed = c || false;
    }
});
jscape.IpAccessVerifier.IPMask.fromJSON = function(data) {
    return $.extend(new jscape.IpAccessVerifier.IPMask(), data);
};

/** @class */
jscape.DomainAdministration = Class.extend(
    /** @lends {jscape.DomainAdministration.prototype} */
{
    /** @constructor */
    initialize: function(a, b, c, d, e, f, g, h, i, j, k, l, m, n) {
        this.maxOwnedCount = parseInt(a) || null;
        this.manageNonOwned = b || false;
        this.allowGroupAssignment = c || false;
        this.allowResourceMapping = d || false;
        this.restrictDir = e || null;
        this.shareQuotas = f || false;
        this.allowSetPhoneAuth = g || false;
        this.allowUrlBranding = h || false;
        this.maxUrlBrandings = parseInt(i) || null;
        this.allowDropZone = j || false;
        this.maxDropZones = parseInt(k) || null;
        this.allowManagePublicContact = l || false;
        this.allowSystemPgpKeyAssignment = m || false;
        this.allowedTemplates = n || [];
    }
});
jscape.DomainAdministration.fromJSON = function (data) {
    return data ? $.extend(new jscape.DomainAdministration(), data) : null;
};

/** @class */
jscape.WebOptions = Class.extend(
    /** @lends {jscape.WebOptions.prototype} */
{
    /** @constructor */
    initialize: function (a, b, c, d, e, f, g, h, i, j) {
        this.loginRedirection = a || "storage";
        this.webAccountLinkAvailable = b != undefined ? !!b : true;
        this.webPersonalInformationAvailable = c != undefined ? !!c : true;
        this.webPublicKeyAuthenticationAvailable = d != undefined ? !!d : true;
        this.webOpenPgpEncryptionAvailable = e != undefined ? !!e : true;
        this.webQuotasAvailable = f != undefined ? !!f : true;
        this.webContactsAvailable = g != undefined ? !!g : true;
        this.webAdHocActivityAvailable = h != undefined ? !!h : true;
        this.webDropZonesAvailable = i != undefined ? !!i : true;
        this.webAftpProtocolPreferable = !!j || false;
    },

    toJSON: function() {
        return $.extend({}, this, {loginRedirection: {"target": this.loginRedirection}});
    }
});
jscape.WebOptions.fromJSON = function(data) {
    return new jscape.WebOptions(data.loginRedirection && data.loginRedirection.target,
                                 data.webAccountLinkAvailable,
                                 data.webPersonalInformationAvailable,
                                 data.webPublicKeyAuthenticationAvailable,
                                 data.webOpenPgpEncryptionAvailable,
                                 data.webQuotasAvailable,
                                 data.webContactsAvailable,
                                 data.webAdHocActivityAvailable,
                                 data.webDropZonesAvailable,
                                 data.webAftpProtocolPreferable);
};


/** @class */
jscape.domain.UserInfoView = Class.extend(
    /** @lends {jscape.domain.UserInfoView.prototype} */
{
    /** @constructor */
    initialize: function(fieldset) {
        this.fieldset = fieldset;

        this.username = $("input[name=username]", this.fieldset).textbox({width: "60%"});
        this.email = $("input[name=email]", this.fieldset).textbox({validType: {any: ["variable", "multi_value['email',',']"]}, invalidMessage: window.R.string.USERS_ERROR_BAD_EMAIL, width: "40%"});
        this.company = $("input[name=company]", this.fieldset).textbox({width: "40%"});

        this.phoneCode = $("input[name=phonecode]", this.fieldset).textbox({validType: "pattern['^[\\\\d]+$']", invalidMessage: window.R.string.USERS_ERROR_BAD_PHONE, width: 60});
        this.phoneNumber = $("input[name=phonenum]", this.fieldset).textbox({validType: "pattern['^[\\\\d- ]+$']", invalidMessage: window.R.string.USERS_ERROR_BAD_PHONE, width: 120});
        this.phoneExtension = $("input[name=phoneext]", this.fieldset).textbox({validType: "pattern['^[\\\\d- ]+$']", invalidMessage: window.R.string.USERS_ERROR_BAD_PHONE, width: 60});

        this.groups = $("table[role=grid][aria-label=usergroups]", this.fieldset);
        this.groups.datagrid({
            fit: true,
            fitColumns:true,
            singleSelect: false,
            checkOnSelect: true,
            selectOnCheck: true,
            remoteSort: false,
            onLoadSuccess: function(data) { $(this).datagrid("getPanel").find("div.datagrid-header-check input:checkbox").prop("disabled", data.rows.length == 0); },
            columns: [[
                  {field: "allowed", checkbox: true},
                  {field: "name", title: $("thead th:nth-child(1)", this.groups).text(), width: 100, formatter: function (_, row) {return String(row || "").escapeXml(); }}
            ]]
        });

        this.enabled = $("input[name=enabled]:checkbox", this.fieldset);
        this.allowAdHocTransfers = $("input[name=adhocallowed]:checkbox", this.fieldset);

        this.ownedBy = $("input[name=ownedby]:checkbox", this.fieldset);
        this.ownedBy.on("change", $.proxy(function() {
            var enabled = this.ownedBy.is(":checked:not(:disabled)");
            this.owner.combobox(enabled ? "enable" : "disable").combobox(enabled ? "enableValidation" : "disableValidation");
        }, this));
        this.owner = $("select[name=owners]", this.fieldset).combobox({
            required: true,
            editable: true,
            limitToList: true,
            disabled: true,
            width: 120
        });

        this.secured = $("input[name=secured]:checkbox", this.fieldset);
        this.allowPasswordChange = $("input[name=allowpwdchange]:checkbox", this.fieldset);
        this.ignorePasswordAging = $("input[name=ignorepwdaging]:checkbox", this.fieldset);

        this.clientKeys = $("table[role=grid][aria-label=clientkeys]", this.fieldset);
        this.clientKeys.datagrid({
            fit: true,
            fitColumns:true,
            singleSelect: false,
            checkOnSelect: true,
            selectOnCheck: true,
            remoteSort: false,
            onLoadSuccess: function(data) { $(this).datagrid("getPanel").find("div.datagrid-header-check input:checkbox").prop("disabled", data.rows.length == 0); },
            columns: [[
                {field: "allowed", checkbox: true},
                {field: "alias", title: $("thead th:nth-child(1)", this.clientKeys).text(), sortable: true, width: 100, formatter: function (_, row) { return String(row || "").escapeXml(); }}
            ]]
        });

        this.tags = $("select[name=tags]", this.fieldset).tagbox({limitToList: true, hasDownArrow: true, panelHeight: "auto", width: "70%", onLoadSuccess: function() { $(this).tagbox("clear"); }});
    },

    show: function(listener) {
        this.listener = listener || jscape.domain.UserInfoView.LISTENER;
        this.fieldset.css({visible: "visible"});
        this.fieldset.form("validate");
    },

    getUsername: function() {
        return this.username.textbox("getValue");
    },

    setUsername: function(value) {
        this.username.textbox("setValue", value);
    },

    getEmail: function() {
        return this.email.textbox("getValue");
    },

    setEmail: function(value) {
        this.email.textbox("setValue", value);
    },

    getCompany: function() {
        return this.company.textbox("getValue");
    },

    setCompany: function(value) {
        this.company.textbox("setValue", value);
    },

    getPhoneCode: function() {
        return this.phoneCode.textbox("isValid") ? this.phoneCode.textbox("getValue") : null;
    },

    setPhoneCode: function(value) {
        if (value != null) {
            this.phoneCode.textbox("setValue", value);
        }
    },

    getPhoneNumber: function() {
        return this.phoneNumber.textbox("isValid") ? this.phoneNumber.textbox("getValue") : null;
    },

    setPhoneNumber: function(value) {
        if (value != null) {
            this.phoneNumber.textbox("setValue", value);
        }
    },

    getPhoneExtension: function() {
        return this.phoneExtension.textbox("isValid") ? this.phoneExtension.textbox("getValue") : null;
    },

    setPhoneExtension: function(value) {
        if (value != null) {
            this.phoneExtension.textbox("setValue", value);
        }
    },

    setAvailableClientKeys: function(values) {
        this.clientKeys.datagrid("loading").datagrid("loadData", values).datagrid("loaded");
    },

    getClientKeys: function() {
        return this.clientKeys.datagrid("getChecked");
    },

    setClientKeys: function(values) {
        if (values && values.length) {
            var rows = this.clientKeys.datagrid("getRows");
            for (var i = 0; i < values.length; i++) {
                this.clientKeys.datagrid("checkRow", $.inArray(values[i], rows));
            }
        } else {
            this.clientKeys.datagrid("clearChecked");
        }
    },

    setAvailableGroups: function(values) {
        this.groups.datagrid("loading").datagrid("loadData", values).datagrid("loaded");
    },

    getGroups: function() {
        return this.groups.datagrid("getSelections");
    },

    setGroups: function(values) {
        this.groups.datagrid("clearSelections");

        if (values && values.length) {
            this.groups.datagrid("loadData", this.groups.datagrid("getData").sort(function (o1, o2) {
                var s1 = $.inArray(o1, values) != -1;
                var s2 = $.inArray(o2, values) != -1;
                return s1 && !s2 ? -1 : !s1 && s2 ? 1 : (o1 == o2 ? 0 : o1 > o2 ? 1 : -1);
            }));

            var rows = this.groups.datagrid("getRows");
            for (var i = 0; i < values.length; i++) {
                var index = $.inArray(values[i], rows);
                this.groups.datagrid("selectRow", index);
            }
        }
    },

    setAvailableOwners: function(values) {
        this.owner.combobox("loadData", values);
        this.ownedBy.prop("disabled", values.length == 0).change();
    },

    getOwner: function() {
        return this.ownedBy.is(":checked") ? this.owner.combobox("getValue") : null;
    },

    setOwner: function(value) {
        if (value) {
            this.owner.combobox("select", value);
            this.ownedBy.prop("checked", this.owner.combobox("getValue") === value).change();
        } else {
            this.ownedBy.prop("checked", false).change();
        }
    },

    getEnabled: function() {
        return this.enabled.is(":checked");
    },

    setEnabled: function(value) {
        this.enabled.prop("checked", !!value);
    },

    getSecured: function() {
        return this.secured.is(":checked");
    },

    setSecured: function(value) {
        this.secured.prop("checked", !!value);
    },

    getAllowAdHocTransfers: function() {
        return this.allowAdHocTransfers.is(":checked");
    },

    setAllowAdHocTransfers: function(value) {
        this.allowAdHocTransfers.prop("checked", !!value);
    },

    getAllowPasswordChanging: function() {
        return this.allowPasswordChange.is(":checked");
    },

    setAllowPasswordChanging: function(value) {
        this.allowPasswordChange.prop("checked", !!value);
    },

    getIgnorePasswordAgingRules: function() {
        return this.ignorePasswordAging.is(":checked");
    },

    setIgnorePasswordAgingRules: function(value) {
        this.ignorePasswordAging.prop("checked", !!value);
    },

    setAvailableTags: function(values) {
        this.tags.tagbox("loadData", values);
    },

    getTags: function() {
        return this.tags.tagbox("getValues");
    },

    setTags: function(values) {
        this.tags.tagbox("setValues", values);
    }
});
jscape.domain.UserInfoView.LISTENER = {};

/** @class */
jscape.domain.QuotasController = Class.extend(
    /** @lends {jscape.domain.QuotasController.prototype} */
{
    /** @constructor */
    initialize: function(container) {
        this.view = new jscape.domain.UserQuotaView(container);
    },

    start: function(quotas) {
        this.view.show(this);

        this._setupView(quotas || null);
    },

    getQuotas: function () {
        return new jscape.AccountTransferQuotas(this.view.getUploadsQuota(),
                                                this.view.getDownloadsQuota(),
                                                this.view.getTransfersQuota(),
                                                this.view.getMaxUploadsPerSession(),
                                                this.view.getMaxDownloadsPerSession(),
                                                this.view.getMaxTransferRate());
    },

    _setupView: function(quotas) {
        if (quotas != null) {
            this.view.setDownloadsQuota(quotas.downloadsQuota);
            this.view.setUploadsQuota(quotas.uploadsQuota);
            this.view.setTransfersQuota(quotas.transfersQuota);
            this.view.setMaxDownloadsPerSession(quotas.maxDownloadsPerSession);
            this.view.setMaxUploadsPerSession(quotas.maxUploadsPerSession);
            this.view.setMaxTransferRate(quotas.maxTransferRate);
        } else {
            this.view.setDownloadsQuota(null);
            this.view.setUploadsQuota(null);
            this.view.setTransfersQuota(null);
            this.view.setMaxDownloadsPerSession(null);
            this.view.setMaxUploadsPerSession(null);
            this.view.setMaxTransferRate(null);
        }
    }
});

/** @class */
jscape.domain.UserQuotaView = Class.extend(
    /** @lends {jscape.domain.UserQuotaView.prototype} */
{
    PERIOD_FACTOR: 24 * 60 * 60 * 1000,

    /** @constructor */
    initialize: function(container) {
        this.fieldset = $("fieldset[name=quotasfields]", container);

        this.downloadQuota = new jscape.domain.QuotaPane(
                $("input[name=maxdloadenabled]:checkbox", this.fieldset),
                $("input[name=maxdload]", this.fieldset).numberspinner({
                    required: true, min: 0, max: 9999, value: 1000, increment: 10, disabled: true, width: 80,
                    unitbox: $("select[name=maxdloadunit]", this.fieldset).combobox({
                        required: true, editable: false, disabled: true, width: 60, panelHeight: "auto"
                    })
                }),
                $("input[name=maxdloadresetperiod]", this.fieldset).numberspinner({required: true, min: 1, max: 1000, value: 1, disabled: true, width: 80})
        );

        this.uploadQuota = new jscape.domain.QuotaPane(
                $("input[name=maxuploadenabled]:checkbox", this.fieldset),
                $("input[name=maxupload]", this.fieldset).numberspinner({
                    required: true, min: 0, max: 9999, value: 1000, increment: 10, disabled: true, width: 80,
                    unitbox: $("select[name=maxuploadunit]", this.fieldset).combobox({
                        required: true, editable: false, disabled: true, width: 60, panelHeight: "auto"
                    })
                }),
                $("input[name=maxuploadresetperiod]", this.fieldset).numberspinner({required: true, min: 1, max: 1000, value: 1, disabled: true, width: 80})
        );

        this.transferQuota = new jscape.domain.QuotaPane(
                $("input[name=maxtransferenabled]:checkbox", this.fieldset),
                $("input[name=maxtransfer]", this.fieldset).numberspinner({
                    required: true, min: 0, max: 9999, value: 1000, increment: 10, disabled: true, width: 80,
                    unitbox: $("select[name=maxtransferunit]", this.fieldset).combobox({required: true, editable: false, disabled: true, width: 60, panelHeight: "auto"})
                }),
                $("input[name=maxtransferresetperiod]", this.fieldset).numberspinner({required: true, min: 1, max: 1000, value: 1, disabled: true, width: 80})
        );

        this.maxTransferRate = new jscape.domain.QuotaPane(
                $("input[name=maxtransferrateenabled]:checkbox", this.fieldset),
                $("input[name=maxtransferrate]", this.fieldset).numberspinner({
                    required: true, min: 1, max: 9999, value: 1000, disabled: true, width: 80,
                    unitbox: $("select[name=maxtransferrateunit]", this.fieldset).combobox({
                        required: true, editable: false, disabled: true, width: 70, panelHeight: "auto"
                    })
                })
        );

        this.downloadPerSessionEnabled = $("input[name=maxdloadsessionenabled]:checkbox", this.fieldset).click($.proxy(this._adjustDownloadPerSession, this));
        this.downloadPerSession = $("input[name=maxdloadsession]", this.fieldset).numberspinner({required: true, disabled: true, min: 1, max: 1000, value: 1, width: 80});
        this.uploadPerSessionEnabled = $("input[name=maxuploadsessionenabled]:checkbox", this.fieldset).click($.proxy(this._adjustUploadPerSession, this));
        this.uploadPerSession = $("input[name=maxuploadsession]", this.fieldset).numberspinner({required: true, disabled: true, min: 1, max: 1000, value: 1, width: 80});
    },

    show: function(listener) {
        this.listener = listener || jscape.domain.UserQuotaView.LISTENER;
        this.downloadQuota.show(this);
        this.uploadQuota.show(this);
        this.transferQuota.show(this);
        this.maxTransferRate.show(this);
    },

    onStateChanged: function(view) {
        if (view.isEnabled()) {
            if (view == this.transferQuota) {
                this.downloadQuota.setEnabled(false);
                this.uploadQuota.setEnabled(false);
            } else if (view == this.downloadQuota || view == this.uploadQuota){
                this.transferQuota.setEnabled(false);
            }
        }
    },

    getDownloadsQuota: function() {
        return this._getQuota(this.downloadQuota);
    },

    setDownloadsQuota: function(value) {
        this._setQuota(this.downloadQuota, value);
    },

    getUploadsQuota: function() {
        return this._getQuota(this.uploadQuota);
    },

    setUploadsQuota: function(value) {
        this._setQuota(this.uploadQuota, value);
    },

    getTransfersQuota: function() {
        return this._getQuota(this.transferQuota);
    },

    setTransfersQuota: function(value) {
        this._setQuota(this.transferQuota, value);
    },

    getMaxTransferRate: function() {
        return this.maxTransferRate.val();

    },

    setMaxTransferRate: function(value) {
        this.maxTransferRate.val(value);
    },

    getMaxDownloadsPerSession: function() {
        return this.downloadPerSessionEnabled.is(":checked")
               ? parseInt(this.downloadPerSession.numberspinner("getValue"))
               : null;
    },

    setMaxDownloadsPerSession: function(value) {
        value = parseInt(value);
        if (!isNaN(value)) {
            this.downloadPerSessionEnabled.prop("checked", true);
            this.downloadPerSession.numberspinner("setValue", value);
        } else {
            this.downloadPerSessionEnabled.prop("checked", false);
            this.downloadPerSession.numberspinner("reset");
        }
        this._adjustDownloadPerSession();
    },

    getMaxUploadsPerSession: function() {
        return this.uploadPerSessionEnabled.is(":checked")
               ? parseInt(this.uploadPerSession.numberspinner("getValue"))
               : null;
    },

    setMaxUploadsPerSession: function(value) {
        value = parseInt(value);
        if (!isNaN(value)) {
            this.uploadPerSessionEnabled.prop("checked", true);
            this.uploadPerSession.numberspinner("setValue", value);
        } else {
            this.uploadPerSessionEnabled.prop("checked", false);
            this.uploadPerSession.numberspinner("reset");
        }
        this._adjustUploadPerSession();
    },

    _getQuota: function(view) {
        var quota = view.val();
        return quota != null ? new jscape.Quota(quota, view.getResetPeriod() * this.PERIOD_FACTOR) : null;
    },

    _setQuota: function(view, quota) {
        if (quota != null) {
            view.val(quota.bytes);
            view.setResetPeriod(quota.resetPeriod / this.PERIOD_FACTOR);
        } else {
            view.val(null);
        }
    },

    _adjustDownloadPerSession: function() {
        var enabled = this.downloadPerSessionEnabled.is(":checked");
        this.downloadPerSession.numberspinner(enabled ? "enable" : "disable").numberspinner(enabled ? "enableValidation" : "disableValidation");
    },

    _adjustUploadPerSession: function() {
        var enabled = this.uploadPerSessionEnabled.is(":checked");
        this.uploadPerSession.numberspinner(enabled ? "enable" : "disable").numberspinner(enabled ? "enableValidation" : "disableValidation");
    }
});
jscape.domain.UserQuotaView.LISTENER = {};

/** @class */
jscape.domain.QuotaPane = Class.extend(
    /** @lends {jscape.domain.QuotaPane.prototype} */
{
    /** @constructor */
    initialize: function(checkbox, count, resetPeriod) {
        this.enabled = checkbox
                .click($.proxy(this._onClick$Enable, this))
                .change($.proxy(this._onChange$Enable, this));

        this.input = count;
        this.period = resetPeriod;
    },

    show: function(listener) {
        this.listener = listener || jscape.domain.QuotaPane.LISTENER;
    },

    isEnabled: function() {
        return this.enabled.is(":checked");
    },

    setEnabled: function(value) {
        this.enabled.prop("checked", !!value).change();
    },

    getResetPeriod: function() {
        return this.period && this.period.length ? parseInt(this.period.numberspinner("getValue")) : null;
    },

    setResetPeriod: function(value) {
        if (this.period && this.period.length) {
            value = parseInt(value);
            if (!isNaN(value)) {
                this.period.numberspinner("setValue", value);
            }
        }
    },

    val: function (value) {
        if (!arguments.length) {
            return this.isEnabled() ? parseInt(this.input.numberspinner("getValue")) : null;
        } else {
            value = parseInt(value);
            if (isNaN(value)) {
                this.setEnabled(false);
            } else {
                this.setEnabled(true);
                this.input.numberspinner("setValue", value);
            }
        }
    },

    _onChange$Enable: function () {
        var unitbox = this.input.numberspinner("options").unitbox;
        if (this.isEnabled()) {
            this.input.numberspinner("enable").numberspinner("enableValidation");
            if (this.period && this.period.length) {
                this.period.numberspinner("enable").numberspinner("enableValidation");
            }
            if (unitbox && unitbox.length) {
                unitbox.combobox("enable").combobox("enableValidation");
            }
        } else {
            this.input.numberspinner("disable").numberspinner("disableValidation");
            if (this.period && this.period.length) {
                this.period.numberspinner("disable").numberspinner("disableValidation");
            }
            if (unitbox && unitbox.length) {
                unitbox.combobox("disable").combobox("disableValidation");
            }
        }
    },

    _onClick$Enable: function() {
        this.listener.onStateChanged(this);
    }
});
jscape.domain.QuotaPane.LISTENER = {
    onStateChanged: $.noop
};

/** @class */
jscape.domain.UserIpAccessController = Class.extend(
    /** @lends {jscape.domain.UserIpAccessController.prototype} */
{
    rules: null,

    /** @constructor */
    initialize: function(container) {
        this.view = new jscape.domain.UserIpAccessView(container);

        this.addController = new jscape.domain.AddUserIpAccessController();
        this.editController = new jscape.domain.EditUserIpAccessController();
        this.deleteController = new jscape.domain.DeleteUserIpAccessController();

        this._initValidators();
    },

    start: function(ipAccessVerifier) {
        this.rules = ipAccessVerifier ? [].concat(ipAccessVerifier.masks) : [];

        this.view.setRules(this.rules);
        this.view.show(this);
    },

    getIpAccess: function() {
        return new jscape.IpAccessVerifier(this.rules);
    },

    onAddRule: function() {
        this.addController.start().done($.proxy(this._ruleAdded, this));
    },

    onEditRule: function(rule) {
        var index = $.inArray(rule, this.rules);
        if (index != -1) {
            this.editController.start(rule).done($.proxy(this._ruleEdited, this, index));
        }
    },

    onDeleteRule: function(rules) {
        this.deleteController.start(rules).done($.proxy(this._ruleDeleted, this, rules));
    },

    onRuleUp: function(rule) {
        var index = $.inArray(rule, this.rules);
        if (index > 0) {
            this.rules.splice(index - 1, 2, this.rules[index], this.rules[index - 1]);
            this.view.setRules(this.rules);
            this.view.selectRule(rule);
        }
    },

    onRuleDown: function(rule) {
        var index = $.inArray(rule, this.rules);
        if (index != -1 && index < this.rules.length - 1) {
            this.rules.splice(index, 2, this.rules[index + 1], this.rules[index]);
            this.view.setRules(this.rules);
            this.view.selectRule(rule);
        }
    },

    _ruleAdded: function(rule) {
        this.rules.push(rule);
        this.view.setRules(this.rules);
        this.view.selectRule(rule);
    },

    _ruleEdited: function(index, rule) {
        this.rules[index] = rule;
        this.view.setRules(this.rules);
        this.view.selectRule(rule);
    },

    _ruleDeleted: function(rules) {
        var index = -1;
        while (rules.length) {
            index = $.inArray(rules.pop(), this.rules);
            this.rules.splice(index, 1);
        }
        this.view.setRules(this.rules);

        if (this.rules.length) {
            index = Math.max(0, Math.min(index, this.rules.length - 1));
            this.view.selectRule(this.rules[index]);
        }
    },

    _initValidators: function() {
        var v = new jscape.Validator();
        v.nonEmptyRule("user_ipaccess_mask_nonempty", window.R.string.USERS_IP_ACCESS_ERROR_BAD_MASK);
        v.rule("user_ipaccess_unique", $.proxy(this._ruleNotExists, this), window.R.string.USERS_IP_ACCESS_ERROR_ALREADY_EXIST);
    },

    _ruleNotExists: function(value, excludes) {
        return $.grep(this.rules, function(rule) {
            return rule.mask == value && (excludes == undefined || $.inArray(rule.mask, excludes) == -1);
        }).length == 0;
    }
});

/** @class */
jscape.domain.UserIpAccessView = Class.extend(
    /** @lends {jscape.domain.UserIpAccessView.prototype} */
{
    selection: null,

    /** @constructor */
    initialize: function(container) {
        this.fieldset = $("fieldset[name=useripaccessfields]", container);

        this.data = $("table[role=grid][aria-label=rules]", this.fieldset);
        this.data.datagrid({
            fit: true,
            fitColumns: true,
            singleSelect: true,
            columns: [[
                {field: "mask", title: $("thead th:nth-child(1)", this.data).text(), width: 60},
                {field: "allowed", title: $("thead th:nth-child(2)", this.data).text(), width: 15, formatter: $.proxy(this._formatAccess, this), styler: $.proxy(this._styleAccess, this)},
                {field: "reason", title: $("thead th:nth-child(3)", this.data).text(), width: 25}
            ]],
            onDblClickRow: $.proxy(this._onClick$EditButton, this),
            onSelect: $.proxy(this._adjustRowSelection, this),
            onUnselect: $.proxy(this._adjustRowSelection, this),
            onLoadSuccess: $.proxy(this._adjustRowSelection, this)
        });

        this.moveUpButton = $("a[role=button][name=moveup]", this.fieldset).linkbutton({disabled: true, onClick: $.proxy(this._onClick$MoveUpButton, this)});
        this.moveDownButton = $("a[role=button][name=movedown]", this.fieldset).linkbutton({disabled: true, onClick: $.proxy(this._onClick$MoveDownButton, this)});
        this.addButton = $("a[role=button][name=add]", this.fieldset).linkbutton({onClick: $.proxy(this._onClick$AddButton, this)});
        this.editButton = $("a[role=button][name=edit]", this.fieldset).linkbutton({disabled: true, onClick: $.proxy(this._onClick$EditButton, this)});
        this.deleteButton = $("a[role=button][name=delete]", this.fieldset).linkbutton({disabled: true, onClick: $.proxy(this._onClick$DeleteButton, this)});
    },

    show: function(listener) {
        this.listener = listener || jscape.domain.UserIpAccessView.LISTENER;
        this._adjustRowSelection();
    },

    setRules: function(values) {
        this.selection = [];
        this.data.datagrid("loading").datagrid("loadData", values).datagrid("loaded");
    },

    selectRule: function(rule) {
        this.data.datagrid("selectRow", this.data.datagrid("getRowIndex", rule));
    },

    _formatAccess: function(value) {
        return !!value ? window.R.string.USERS_IP_ACCESS_RULE_ALLOWED : window.R.string.USERS_IP_ACCESS_RULE_DENIED;
    },

    _styleAccess: function(value) {
        return !!value ? "color:green" : "color:red";
    },

    _onClick$MoveUpButton: function() {
        this.listener.onRuleUp(this.selection[0]);
    },

    _onClick$MoveDownButton: function() {
        this.listener.onRuleDown(this.selection[0]);
    },

    _onClick$AddButton: function() {
        this.listener.onAddRule();
    },

    _onClick$EditButton: function() {
        this.listener.onEditRule(this.selection[0]);
    },

    _onClick$DeleteButton: function() {
        this.listener.onDeleteRule(this.selection);
    },

    _adjustRowSelection: function() {
        this.selection = this.data.datagrid("getSelections");
        this._adjustButtonsState();
    },

    _adjustButtonsState: function() {
        var index = this.selection.length == 1 ? this.data.datagrid("getRowIndex", this.selection[0]) : -1;
        var count = this.data.datagrid("getRows").length;

        this.moveUpButton.linkbutton(index > 0 && index <= count - 1 ? "enable" : "disable");
        this.moveDownButton.linkbutton(index >= 0 && index < count - 1 ? "enable" : "disable");
        this.editButton.linkbutton(this.selection.length == 1 ? "enable" : "disable");
        this.deleteButton.linkbutton(this.selection.length !=0 ? "enable" : "disable");
    }
});
jscape.domain.UserIpAccessView.LISTENER = {
    onAddRule: $.noop,
    onEditRule: $.noop,
    onDeleteRule: $.noop,
    onRuleUp: $.noop,
    onRuleDown: $.noop
};

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

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

    onSubmit: function (dialog) {
        var rule = this._createRule(dialog);
        dialog.hide();
        this.deferred.resolve(rule);
        this.deferred = null;
    },

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

    _createRule: function(dialog) {
        return new jscape.IpAccessVerifier.IPMask(dialog.getMask(), dialog.getReason(), dialog.getAllowed());
    },

    _setupDialog: function () {
        var dialog = new jscape.domain.UserIpAccessRuleDialog();
        dialog.setTitle(window.R.string.USERS_IP_ACCESS_DIALOG_ADD_TITLE);
        dialog.setAllowed(true);
        return dialog;
    }
});

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

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

    onSubmit: function(dialog) {
        var rule = this._createRule(dialog);
        dialog.hide();
        this.deferred.resolve(rule);
        this.deferred = null;
    },

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

    _createRule: function(dialog) {
        return new jscape.IpAccessVerifier.IPMask(dialog.getMask(), dialog.getReason(), dialog.getAllowed());
    },

    _setupDialog: function (rule) {
        var dialog = new jscape.domain.UserIpAccessRuleDialog();
        dialog.setTitle(window.R.string.USERS_IP_ACCESS_DIALOG_EDIT_TITLE);
        dialog.setMask(rule.mask);
        dialog.setReason(rule.reason);
        dialog.setAllowed(rule.allowed);
        return dialog;
    }
});

/** @class */
jscape.domain.DeleteUserIpAccessController = Class.extend(
    /** @lends {jscape.domain.DeleteUserIpAccessController.prototype} */
{
    start: function(rules) {
        var text = $.map(rules, function(rule) { return rule.mask; }).join(", ");
        return jscape.ConfirmDialog.confirm(
                window.R.string.USERS_IP_ACCESS_CONFIRM_DELETE_TITLE,
                window.R.string.USERS_IP_ACCESS_CONFIRM_DELETE_MESSAGE.supplant({0: text.escapeXml()}),
                false);
    }
});

/** @class */
jscape.domain.UserIpAccessRuleDialog = Class.extend(
    /** @lends {jscape.domain.UserIpAccessRuleDialog.prototype} */
{
    /** @constructor */
    initialize: function() {
        this.dialog = $("#d-user-ipaccess-rule").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=ipaccessrulefields]", this.dialog);

        this.mask = $("input[name=mask]", this.fieldset).textbox({required: true, validType: ["user_ipaccess_mask_nonempty", "user_ipaccess_unique"], missingMessage: window.R.string.USERS_IP_ACCESS_ERROR_BAD_MASK, width: "60%"});
        this.reason = $("input[name=reason]", this.fieldset).textbox({width: "60%"});
        this.allowed = $("input[name=allowed]:radio", this.fieldset);
    },

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

    show: function (listener) {
        this.listener = listener;
        this.dialog.dialog("center").dialog("open");
        this.fieldset.form("validate");
        this.mask.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");
    },

    getMask: function () {
        return this.mask.textbox("getValue");
    },

    setMask: function (value) {
        this.mask.textbox("setValue", value);
        if (value && value.trim().length) {
            this.mask.textbox("textbox").validatebox("options").validType = ["user_ipaccess_mask_nonempty", "user_ipaccess_unique['" + value + "']"];
        }
    },

    getReason: function () {
        return this.reason.textbox("getValue");
    },

    setReason: function (value) {
        this.reason.textbox("setValue", value);
    },

    getAllowed: function () {
        return (/^true$/i).test(this.allowed.filter(":checked").val());
    },

    setAllowed: function (value) {
        this.allowed.filter("[value=" + Boolean(value) + "]").prop("checked", true);
    },

    _onSubmit: function () {
        if (this.fieldset.form("validate")) {
            this.hide();
            this.listener.onSubmit(this);
        }
    },

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

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

/** @class */
jscape.domain.DomainAdministrationController = Class.extend(
    /** @lends {jscape.domain.DomainAdministrationController.prototype} */
{
    /** @constructor */
    initialize: function(container, vfsController) {
        this.view = new jscape.domain.DomainAdministrationView(container);
        this.vfsController = vfsController;
    },

    start: function(managementService, domainName, administration) {
        this.managementService = managementService;
        this.domainName = domainName;
        this.view.show(this);

        this._setupView(administration);
    },

    getDomainAdministration: function() {
        if (!this.view.isDomainAdministrationAllowed()) {
            return null;
        }
        return new jscape.DomainAdministration(this.view.getMaxOwnedUsers(),
                                               this.view.getManageNonOwnedUsersAllowed(),
                                               this.view.getGroupAssignmentAllowed(),
                                               this.view.getProxyMappingAllowed(),
                                               this.view.getRestrictionPath(),
                                               this.view.getShareQuotas(),
                                               this.view.getMultiFactorAuthSettingsAllowed(),
                                               this.view.getUrlBrandingAllowed(),
                                               this.view.getMaxUrlBranding(),
                                               this.view.getDropZoneAllowed(),
                                               this.view.getMaxDropZones(),
                                               this.view.getManagePublicContacts(),
                                               this.view.getSystemPgpKeysAvailable(),
                                               this.view.getTemplates());
    },

    onAdministrationAllowed: function(dialog) {
        var descriptors = this.vfsController.getDescriptors();
        for (var i = 0; i < descriptors.length; ++i) {
            var descriptor = descriptors[i];
            if (descriptor.path === "/" && descriptor.realPath) {
                dialog.setRestrictionPath(descriptor.realPath);
                break;
            }
        }
    },

    onSelectPath: function(dialog) {
        new SelectPathController($.proxy(this.managementService.listUsersRestrictPath, this.managementService),
                                 $.proxy(this.managementService.createUsersRestrictPath, this.managementService))
                .selectDirectory()
                .done(function(entry) { dialog.setRestrictionPath(entry.path); });
    },

    _setupView: function(administration) {
        if (administration) {
            this.view.setDomainAdministrationAllowed(true);
            this.view.setMaxOwnedUsers(administration.maxOwnedCount);
            this.view.setManageNonOwnedUsersAllowed(administration.manageNonOwned);
            this.view.setGroupAssignmentAllowed(administration.allowGroupAssignment);
            this.view.setProxyMappingAllowed(administration.allowResourceMapping);
            this.view.setRestrictionPath(administration.restrictDir);
            this.view.setShareQuotas(administration.shareQuotas);
            this.view.setMultiFactorAuthSettingsAllowed(administration.allowSetPhoneAuth);
            this.view.setUrlBrandingAllowed(administration.allowUrlBranding);
            this.view.setMaxUrlBranding(administration.maxUrlBrandings);
            this.view.setDropZoneAllowed(administration.allowDropZone);
            this.view.setMaxDropZones(administration.maxDropZones);
            this.view.setManagePublicContacts(administration.allowManagePublicContact);
            this.view.setSystemPgpKeysAvailable(administration.allowSystemPgpKeyAssignment);
        } else {
            this.view.setDomainAdministrationAllowed(false);
        }

        var allowedTemplates = administration ? administration.allowedTemplates : [];
        this.managementService.getAccountTemplateNames(this.domainName)
                .done($.proxy(function(templates) {
                                  this.view.setAvailableTemplates(templates);
                                  this.view.setTemplates(allowedTemplates);
                                  allowedTemplates = null;
                              }, this));
    }
});

/** @class */
jscape.domain.DomainAdministrationView = Class.extend(
    /** @lends {jscape.domain.DomainAdministrationView.prototype} */
{
    /** @constructor */
    initialize: function(container) {
        this.fieldset = $("fieldset[name=administrationfields]", container);

        this.allowed = $("input[name=domainadminallowed]:checkbox", this.fieldset);
        this.allowed.change($.proxy(function() {
            if (this.allowed.is(":checked")) {
                this._initRestrictionPath();
            }
            this._adjustFieldState();
        }, this));

        this.manageNonOwned = $("input[name=managenonowned]", this.fieldset);

        this.maxOwnedEnabled = $("input[name=maxowned]:checkbox", this.fieldset);
        this.maxOwnedEnabled.change($.proxy(function() {
            var enabled = this.maxOwnedEnabled.is(":checked");
            this.maxOwned.numberspinner(enabled ? "enable" : "disable").numberspinner(enabled ? "enableValidation" : "disableValidation");
        }, this));
        this.maxOwned = $("input[name=maxownedcount]", this.fieldset).numberspinner({required: true, editable: false, min: 1, max: 1000, value: 1, width: 80});

        this.systemPgpKeysAvailable = $("input[name=systempgpkeysavailable]", this.fieldset);
        this.managePublicContacts = $("input[name=managepubliccontacts]", this.fieldset);
        this.shareQuotas = $("input[name=shareqoutas]", this.fieldset);

        this.templates = $("table[role=grid][aria-label=templates]", this.fieldset);
        this.templates.datagrid({
            fit: true,
            fitColumns:true,
            singleSelect: false,
            checkOnSelect: true,
            selectOnCheck: true,
            remoteSort: false,
            columns: [[
                  {field: "allowed", checkbox: true},
                  {field: "template", title: $("thead th:nth-child(1)", this.templates).text(), sortable: true, width: 100, formatter: function(_, row) { return String(row || "").escapeXml(); }}
            ]],
            onClickRow: $.proxy(function(index, row) {
                if (!this.isDomainAdministrationAllowed()) {
                    var selected = $.inArray(row, this.templates.datagrid("getSelections")) != -1;
                    this.templates.datagrid(selected ? "unselectRow" : "selectRow", index);
                }
            }, this),
            onBeforeCheck: $.proxy(function() { return this.isDomainAdministrationAllowed(); }, this),
            onBeforeUncheck: $.proxy(function() { return this.isDomainAdministrationAllowed(); }, this),
            onLoadSuccess: $.proxy(this._adjustTemplatesFieldState, this)
        });

        this.restrictPathEnabled = $("input[name=restrictpath]:checkbox", this.fieldset);
        this.restrictPathEnabled.change($.proxy(function() {
            var enabled = this.restrictPathEnabled.is(":checked");
            this.restrictPath.textbox(enabled ? "enable" : "disable").textbox(enabled ? "enableValidation" : "disableValidation").textbox("validate");
            this.browsePathButton.linkbutton(enabled ? "enable" : "disable");
        }, this));
        this.restrictPath = $("input[name=restrictpathto]", this.fieldset).textbox({required: true, disabled: true, tipPosition: "bottom", width: "65%"});
        this.browsePathButton = $("a[role=button][name=browse]", this.fieldset).linkbutton({disabled: true, onClick: $.proxy(this._onClick$BrowsePathButton, this)});

        this.groupAssignmentAllowed = $("input[name=groupassignmentallowed]", this.fieldset);
        this.proxyMappingAllowed = $("input[name=proxymappingallowed]", this.fieldset);
        this.setMultiFactorAuthAllowed = $("input[name=setmultifactorauthallowed]", this.fieldset);

        this.dropZoneAllowed = $("input[name=dropzoneallowed]", this.fieldset);
        this.urlBrandingAllowed = $("input[name=urlbrandingallowed]", this.fieldset);

        this.maxDropZonesEnabled = $("input[name=maxdropzones]:checkbox", this.fieldset);
        this.maxDropZonesEnabled.change($.proxy(function() {
            var enabled = this.maxDropZonesEnabled.is(":checked");
            this.maxDropZones.numberspinner(enabled ? "enable" : "disable").numberspinner(enabled ? "enableValidation" : "disableValidation");
        }, this));
        this.maxDropZones = $("input[name=maxdropzonescount]", this.fieldset).numberspinner({required: true, min: 1, max: 1000, value: 1, width: 80});

        this.maxUrlBrandingsEnabled = $("input[name=maxurlbrandings]:checkbox", this.fieldset);
        this.maxUrlBrandingsEnabled.change($.proxy(function() {
            var enabled = this.maxUrlBrandingsEnabled.is(":checked");
            this.maxUrlBrandings.numberspinner(enabled ? "enable" : "disable").numberspinner(enabled ? "enableValidation" : "disableValidation");
        }, this));
        this.maxUrlBrandings = $("input[name=maxurlbrandingscount]", this.fieldset).numberspinner({required: true, editable: false, min: 1, max: 1000, value: 1, width: 80});
    },

    show: function(listener) {
        this.listener = listener || jscape.domain.DomainAdministrationView.LISTENER;
        this.templates.datagrid("fitColumns");
        this._adjustFieldState();
    },

    isDomainAdministrationAllowed: function() {
        return this.allowed.is(":checked");
    },

    setDomainAdministrationAllowed: function(value) {
        this.allowed.prop("checked", !!value).change();
    },

    getMaxOwnedUsers: function() {
        return this.maxOwnedEnabled.is(":checked") ? this.maxOwned.numberspinner("getValue") : null;
    },

    setMaxOwnedUsers: function(value) {
        this.maxOwnedEnabled.prop("checked", value != null).change();
        if (value != null) {
            this.maxOwned.numberspinner("setValue", value);
        } else {
            this.maxOwned.numberspinner("reset");
        }
    },

    getManageNonOwnedUsersAllowed: function() {
        return this.manageNonOwned.is(":checked");
    },

    setManageNonOwnedUsersAllowed: function(value) {
        this.manageNonOwned.prop("checked", !!value);
    },

    getGroupAssignmentAllowed: function() {
        return this.groupAssignmentAllowed.is(":checked");
    },

    setGroupAssignmentAllowed: function(value) {
        this.groupAssignmentAllowed.prop("checked", !!value);
    },

    getProxyMappingAllowed: function() {
        return this.proxyMappingAllowed.is(":checked");
    },

    setProxyMappingAllowed: function(value) {
        this.proxyMappingAllowed.prop("checked", !!value);
    },

    getRestrictionPath: function() {
        return this.restrictPathEnabled.is(":checked:not(:disabled)") ? this.restrictPath.textbox("getValue") : null;
    },

    setRestrictionPath: function(value) {
        if (value != null) {
            this.restrictPathEnabled.prop("checked", true).change();
            this.restrictPath.textbox("setValue", value).textbox("textbox").focus();
        } else {
            this.restrictPathEnabled.prop("checked", false).change();
            this.restrictPath.textbox("reset");
        }
    },

    getShareQuotas: function() {
        return this.shareQuotas.is(":checked");
    },

    setShareQuotas: function(value) {
        this.shareQuotas.prop("checked", !!value);
    },

    getMultiFactorAuthSettingsAllowed: function() {
        return this.setMultiFactorAuthAllowed.is(":checked");
    },

    setMultiFactorAuthSettingsAllowed: function(value) {
        this.setMultiFactorAuthAllowed.prop("checked", !!value);
    },

    getUrlBrandingAllowed: function() {
        return this.urlBrandingAllowed.is(":checked");
    },

    setUrlBrandingAllowed: function(value) {
        this.urlBrandingAllowed.prop("checked", !!value);
    },

    getMaxUrlBranding: function() {
        return this.maxUrlBrandingsEnabled.is(":checked") ? this.maxUrlBrandings.numberspinner("getValue") : null;
    },

    setMaxUrlBranding: function(value) {
        this.maxUrlBrandingsEnabled.prop("checked", value != null).change();
        if (value != null) {
            this.maxUrlBrandings.numberspinner("setValue", value);
        } else {
            this.maxUrlBrandings.numberspinner("reset");
        }
    },

    getDropZoneAllowed: function() {
        return this.dropZoneAllowed.is(":checked");
    },

    setDropZoneAllowed: function(value) {
        this.dropZoneAllowed.prop("checked", !!value);
    },

    getMaxDropZones: function() {
        return this.maxDropZonesEnabled.is(":checked") ? this.maxDropZones.numberspinner("getValue") : null;
    },

    setMaxDropZones: function(value) {
        this.maxDropZonesEnabled.prop("checked", value != null).change();
        if (value != null) {
            this.maxDropZones.numberspinner("setValue", value);
        } else {
            this.maxDropZones.numberspinner("reset");
        }
    },

    getManagePublicContacts: function() {
        return this.managePublicContacts.is(":checked")
    },

    setManagePublicContacts: function(value) {
        this.managePublicContacts.prop("checked", !!value);
    },

    getSystemPgpKeysAvailable: function() {
        return this.systemPgpKeysAvailable.is(":checked")
    },

    setSystemPgpKeysAvailable: function(value) {
        this.systemPgpKeysAvailable.prop("checked", !!value);
    },

    setAvailableTemplates: function(values) {
        this.templates.datagrid("loading").datagrid("loadData", values).datagrid("loaded");
    },

    getTemplates: function () {
        return this.templates.datagrid("getChecked");
    },

    setTemplates: function (values) {
        if (values && values.length) {
            var rows = this.templates.datagrid("getRows");
            for (var i = 0; i < values.length; i++) {
                var index = $.inArray(values[i], rows);
                this.templates.datagrid("checkRow", index);
            }
        } else {
            this.templates.datagrid("clearChecked");
        }
    },

    _onClick$BrowsePathButton: function() {
        this.listener.onSelectPath(this);
    },

    _adjustFieldState: function() {
        var allowed = this.isDomainAdministrationAllowed();
        this.fieldset.find("input:checkbox").not(this.allowed).prop("disabled", !allowed);

        var ownedEnabled = allowed && this.maxOwnedEnabled.is(":checked");
        var pathEnabled = allowed && this.restrictPathEnabled.is(":checked");
        var brandingEnabled = allowed && this.maxUrlBrandingsEnabled.is(":checked");
        var zoneEnabled = allowed && this.maxDropZonesEnabled.is(":checked");

        this.maxOwned.numberspinner(ownedEnabled ? "enable" : "disable").numberspinner(ownedEnabled ? "enableValidation" : "disableValidation");
        this.restrictPath.textbox(pathEnabled ? "enable" : "disable").textbox(pathEnabled ? "enableValidation" : "disableValidation");
        this.browsePathButton.linkbutton(pathEnabled ? "enable" : "disable");
        this.maxDropZones.numberspinner(zoneEnabled ? "enable" : "disable").numberspinner(allowed ? "enableValidation" : "disableValidation");
        this.maxUrlBrandings.numberspinner(brandingEnabled ? "enable" : "disable").numberspinner(allowed ? "enableValidation" : "disableValidation");

        this._adjustTemplatesFieldState();

        this.fieldset.form("validate");
    },

    _adjustTemplatesFieldState: function() {
        var allowed = this.isDomainAdministrationAllowed();
        var rows = this.templates.datagrid("getRows");
        var opts = this.templates.datagrid("options");
        var enabled = rows.length != 0 && allowed;

        for (var i = 0; i < rows.length; i++) {
            var tr = opts.finder.getTr(this.templates[0], i);
            tr.find("input:checkbox").prop("disabled", !enabled);
        }

        this.templates.datagrid("getPanel").find("div.datagrid-header-check input:checkbox").prop("disabled", !enabled);
    },

    _initRestrictionPath: function() {
        if (this.restrictPath.textbox("getValue").trim().length == 0) {
            this.listener.onAdministrationAllowed(this);
        }
    }
});
jscape.domain.DomainAdministrationView.LISTENER = {
    onSelectPath: $.noop
};

/** @class */
jscape.domain.WebOptionsController = Class.extend(
    /** @lends {jscape.domain.WebOptionsController.prototype} */
{
    options: null,

    /** @constructor */
    initialize: function(container) {
        this.view = new jscape.domain.WebOptionsView(container);
    },

    start: function(webOptions) {
        this.options = webOptions || new jscape.WebOptions();
        this.view.show(this);

        this._setupView();
    },

    getWebOptions: function() {
        return new jscape.WebOptions(this.view.getLoginRedirection(),
                                     this.view.getShowAccountLink(),
                                     this.view.getShowPersonalInfo(),
                                     this.view.getShowPublicKeyAuthentication(),
                                     this.view.getShowPgpEncryption(),
                                     this.view.getShowQuotas(),
                                     this.view.getShowContacts(),
                                     this.view.getShowAdHocActivity(),
                                     this.view.getShowDropZones(),
                                     this.view.getPreferAftpForApplet());
    },

    _setupView: function() {
        this.view.setLoginRedirection(this.options.loginRedirection);
        this.view.setShowAccountLink(this.options.webAccountLinkAvailable);
        this.view.setShowPersonalInfo(this.options.webPersonalInformationAvailable);
        this.view.setShowPublicKeyAuthentication(this.options.webPublicKeyAuthenticationAvailable);
        this.view.setShowPgpEncryption(this.options.webOpenPgpEncryptionAvailable);
        this.view.setShowQuotas(this.options.webQuotasAvailable);
        this.view.setShowContacts(this.options.webContactsAvailable);
        this.view.setShowAdHocActivity(this.options.webAdHocActivityAvailable);
        this.view.setShowDropZones(this.options.webDropZonesAvailable);
        this.view.setPreferAftpForApplet(this.options.webAftpProtocolPreferable);
    }
});

/** @class */
jscape.domain.WebOptionsView = Class.extend(
    /** @lends {jscape.domain.WebOptionsView.prototype} */
{
    /** @constructor */
    initialize: function(container) {
        this.fieldset = $("fieldset[name=weboptionsfields]", container);

        this.loginRedirection = $("select[name=loginredirect]", this.fieldset).combobox({required: true, editable: false, width: 130, panelHeight: "auto"});

        this.showAccountLink = $("input[name=showaccountlink]", this.fieldset);
        this.showPersonalInfo = $("input[name=showpersonalinfo]", this.fieldset);
        this.showPublicKeyAuth = $("input[name=showpubkeyauth]", this.fieldset);
        this.showPgpEncryption = $("input[name=showpgpencrypt]", this.fieldset);
        this.showQuotas = $("input[name=showquotas]", this.fieldset);
        this.showContacts = $("input[name=showcontacts]", this.fieldset);
        this.showAdHocActivity = $("input[name=showadhoc]", this.fieldset);
        this.showDropZones = $("input[name=showdropzones]", this.fieldset);
        this.preferAftpForApplet= $("input[name=preferaftpforapplet]", this.fieldset);
    },

    show: function(listener) {
        this.listener = listener || jscape.domain.WebOptionsView.LISTENER;
    },

    reset: function() {
        this.loginRedirection.combobox("reset");
    },

    getLoginRedirection: function() {
        return this.loginRedirection.combobox("getValue");
    },
    setLoginRedirection: function(value) {
        this.loginRedirection.combobox("setValue", value);
    },

    getShowAccountLink: function() {
        return this.showAccountLink.is(":checked");
    },

    setShowAccountLink: function(value) {
        this.showAccountLink.prop("checked", !!value);
    },

    getShowPersonalInfo: function() {
        return this.showPersonalInfo.is(":checked");
    },

    setShowPersonalInfo: function(value) {
        this.showPersonalInfo.prop("checked", !!value);
    },

    getShowPublicKeyAuthentication: function() {
        return this.showPublicKeyAuth.is(":checked");
    },

    setShowPublicKeyAuthentication: function(value) {
        this.showPublicKeyAuth.prop("checked", !!value);
    },

    getShowPgpEncryption: function() {
        return this.showPgpEncryption.is(":checked");
    },

    setShowPgpEncryption: function(value) {
        this.showPgpEncryption.prop("checked", !!value);
    },

    getShowQuotas: function() {
        return this.showQuotas.is(":checked");
    },

    setShowQuotas: function(value) {
        this.showQuotas.prop("checked", !!value);
    },

    getShowContacts: function() {
        return this.showContacts.is(":checked");
    },

    setShowContacts: function(value) {
        this.showContacts.prop("checked", !!value);
    },

    getShowAdHocActivity: function() {
        return this.showAdHocActivity.is(":checked");
    },

    setShowAdHocActivity: function(value) {
        this.showAdHocActivity.prop("checked", !!value);
    },

    getShowDropZones: function() {
        return this.showDropZones.is(":checked");
    },

    setShowDropZones: function(value) {
        this.showDropZones.prop("checked", !!value);
    },

    getPreferAftpForApplet: function() {
        return this.preferAftpForApplet.is(":checked");
    },

    setPreferAftpForApplet: function(value) {
        this.preferAftpForApplet.prop("checked", !!value);
    }
});
jscape.domain.WebOptionsView.LISTENER = {};