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

/** @class */
jscape.AccountTemplateInfo = Class.extend(
    /** @lends {jscape.AccountTemplateInfo.prototype} */
{
    /** @constructor */
    initialize: function(a, b) {
        this.name = a || "";
        this.tags = b || [];
    },

    isDefault: function() {
        return "DEFAULT" === (this.name || "").toUpperCase();
    }
});
jscape.AccountTemplateInfo.fromJSON = function(data) {
    return data ? new jscape.AccountTemplateInfo(data.name, data.tags) : null;
};

/** @class */
jscape.AccountTemplate = Class.extend(
    /** @lends {jscape.AccountTemplate.prototype} */
{
    /** @constructor */
    initialize: function(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q) {
        this.name = a || "";
        this.username = b || "";
        this.emailAddress = c || "";
        this.company = d || null;
        this.phone = e || null;
        this.owner = f || "";
        this.expirationDate = g ||null;
        this.expirationPeriodMillis = h ||null;
        this.enabled = i != undefined ? !!i : true;
        this.secured = j || false;
        this.groups = k || [];
        this.bindedKeys = l || [];
        this.passwordChangingAllowed = m || false;
        this.emailFileTransferAllowed = n || false;
        this.usePhoneAuthentication = o || false;
        this.ignorePasswordAgingRules = p || false;
        this.resources = [];
        this.quotas = new jscape.AccountTransferQuotas();
        this.ipAccessVerifier = new jscape.IpAccessVerifier();
        this.administration = null;
        this.webOptions = new jscape.WebOptions();
        this.tags = q || [];
    },

    toJSON: function () {
        return $.extend({},
                        this,
                        {
                            expirationDate: this.expirationDate ? this.expirationDate.getTime() : null,
                            quotas: undefined,
                            webOptions: undefined
                        },
                        $.parseJSON(JSON.stringify(this.quotas)),
                        $.parseJSON(JSON.stringify(this.webOptions))
        );
    }
});
jscape.AccountTemplate.fromJSON = function(data) {
    return $.extend(new jscape.AccountTemplate(), data, {
        phone: jscape.Phone.fromJSON(data.phone),
        groups: $.isArray(data.groups) ? data.groups : [],
        expirationDate: $.isNumeric(data.expirationDate) ? new Date(data.expirationDate) : null,
        expirationPeriodMillis: $.isNumeric(data.expirationPeriodMillis) ? parseInt(data.expirationPeriodMillis) : null,
        resources: $.map(data.resources || [], jscape.VirtualFile.fromJSON),
        quotas: jscape.AccountTransferQuotas.fromJSON(data),
        ipAccessVerifier: jscape.IpAccessVerifier.fromJSON(data.ipAccessVerifier),
        administration: jscape.DomainAdministration.fromJSON(data.administration),
        webOptions: jscape.WebOptions.fromJSON(data),
        tags: $.isArray(data.tags) ? data.tags : []
    });
};

/** @class */
jscape.domain.AccountTemplatesController = jscape.ui.DatagridController.extend(
    /** @lends {jscape.domain.AccountTemplatesController.prototype} */
{
    view: null,

    /** @constructor */
    initialize: function() {
        this._initValidators();
    },

    onCreate: function (managementService, domainName) {
        this.managementService = managementService;
        this.domainName = domainName;

        this.addController = new jscape.domain.AddAccountTemplateController();
        this.editController = new jscape.domain.EditAccountTemplateController();
        this.deleteController = new jscape.domain.DeleteAccountTemplateController();
    },

    onStart: function () {
        if (this.view == null) {
            this.view = new jscape.domain.AccountTemplatesView();
        }
        this.view.show(this);
    },

    onResume: function() {
        this.view.refresh();
    },
    onRefresh: function() {
        return this.managementService.listAccountTemplates(this.domainName);
    },

    onAddTemplate: function() {
        this.addController.start(this.managementService, this.domainName)
                .done($.proxy(this._templateAdded, this))
                .done($.proxy(this._fireApplySuccess, this));
    },

    onEditTemplate: function(template) {
        var index = $.inArray(template, this.view.getTemplates());
        if (index != -1) {
            this.editController.start(this.managementService, this.domainName, template.name)
                    .done($.proxy(this._templateEdited, this, index))
                    .done($.proxy(this._fireApplySuccess, this, index));
        }
    },

    onDeleteTemplate: function(template) {
        this.deleteController.start(this.managementService, this.domainName, template.name)
                .done($.proxy(this._templateDeleted, this, template));
    },

    _templateAdded: function(template) {
        this._recordAdded(template);
    },

    _templateEdited: function(index, template) {
        this._recordEdited(template);
    },

    _templateDeleted: function (template) {
        this._recordDeleted(template);
    },

    _initValidators: function() {
        var v = new jscape.Validator();
        v.rule("usertemplate_unique", $.proxy(this._templateNotExists, this), window.R.string.USER_TEMPLATES_ERROR_ALREADY_EXIST);
    },

    _templateNotExists: function (value) {
        var names = $.map(this.view.getTemplates(), function(template) { return template.name.toUpperCase(); });
        return $.inArray((value || "").toUpperCase(), names) == -1;
    },

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

/** @class */
jscape.domain.AccountTemplatesView = jscape.ui.DatagridView.extend(
    /** @lends {jscape.domain.AccountTemplatesView.prototype} */
{
    selection: null,

    /** @constructor */
    initialize: function() {
        var initializing = true;

        this.fieldset = $("fieldset[name=usertemplatesfields]");

        this.data = $("table[role=grid][aria-label=usertemplates]", this.fieldset);
        this.data.datagrid({
            fit: true,
            fitColumns: true,
            singleSelect: true,
            ctrlSelect: true,
            remoteSort: false,
            pagination: true,
            search: true,
            idField: "name",
            sortName: "name",
            columns: [[
                {field: "name", title: $("thead th:nth-child(1)", this.data).text(), sortable: true, width: 300},
                {field: "tags", title: $("thead th:nth-child(2)", this.data).text(), width: 80, formatter: function(value) { return String($.isArray(value) ? value.join(", ") : value).escapeXml(); }}
            ]],
            onSelect: $.proxy(this._adjustState, this),
            onUnselect: $.proxy(this._adjustState, this),
            onDblClickRow: $.proxy(this._onClick$EditButton, this),
            onBeforeLoad: function() { return !initializing; },
            loader: $.proxy(this._onLoad$Data, this),
            onLoadSuccess: $.proxy(this._adjustState, 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)});

        initializing = false;
    },

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

    getTemplates: function() {
        return this.getRecords();
    },

    _onLoad$Data: function (params, success, error) {
        this.listener.onRefresh(params).done(success).fail(error);
    },

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

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

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

    _adjustState: function() {
        this.selection = this.data.datagrid("getSelections");
        var defaultTemplateSelected = $.grep(this.selection, function(template) { return template.isDefault(); }).length != 0;
        this.editButton.linkbutton(this.selection.length == 1 ? "enable" : "disable");
        this.deleteButton.linkbutton(this.selection.length != 0 && !defaultTemplateSelected ? "enable" : "disable");
    }
});
jscape.domain.AccountTemplatesView.LISTENER = {
    onRefresh: $.noop,
    onAddTemplate: $.noop,
    onEditTemplate: $.noop,
    onDeleteTemplate: $.noop
};

/** @class */
jscape.domain.AddAccountTemplateController = Class.extend(
    /** @lends {jscape.domain.AddAccountTemplateController.prototype} */
{
    DEFAULT_TEMPLATE: $.extend(new jscape.AccountTemplate(), {
        resources: [jscape.VirtualFile.local("/", undefined, false, false, true, "%installdir%/users/%domain%/%username%", true)]
    }),
    VARIABLES: ["installdir", "domain", "username", "queryattr['name']"],

    infoController: null,
    vfsController: null,
    quotasController: null,
    ipAccessController: null,
    domainAdminController: null,
    webController: null,

    deferred: null,

    /** @constructor */
    initialize: function() {
        this.variableController = new jscape.VariableController();
    },

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

    onAddVariable: function(input) {
        this.variableController.start(input, this.VARIABLES);
    },

    onSubmit: function (dialog) {
        var template = this._createTemplate(dialog);
        dialog.destroy();

        this.managementService.addAccountTemplate(this.domainName, template)
                .done($.proxy(function(template) { this.deferred.resolve(template); this.deferred = null; }, this))
                .fail($.proxy(function() { this.deferred.reject(); this.deferred = null; }, this))
                .always($.proxy(this._cleanup, this));
    },

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

    _setupDialog: function () {
        var dialog = new jscape.domain.AddAccountTemplateDialog();
        this._createView(dialog.container());
        window.setTimeout($.proxy(function () {
            try {
                this._setupView(this.DEFAULT_TEMPLATE);
            } catch (e) {
                dialog.destroy();
                this._cleanup();
            } finally {
                dialog = null;
            }
        }, this), 0);
        return dialog;
    },

    _createView: function (parent) {
        this._cleanup();
        this.infoController = new jscape.domain.AddUserTemplateInfoController(parent);
        this.vfsController = new jscape.vfs.VirtualFilesController(parent);
        this.quotasController = new jscape.domain.QuotasController(parent);
        this.ipAccessController = new jscape.domain.UserIpAccessController(parent);
        this.domainAdminController = new jscape.domain.DomainAdministrationController(parent, this.vfsController);
        this.webController = new jscape.domain.WebOptionsController(parent);
    },

    _setupView: function (template) {
        this.infoController.start(this.managementService, this.domainName);
        this.vfsController.start(this.managementService, this.domainName, template.resources);
        this.quotasController.start();
        this.ipAccessController.start();
        this.domainAdminController.start(this.managementService, this.domainName);
        this.webController.start();
    },

    _createTemplate: function (dialog) {
        var template = this.infoController.createAccountTemplate();
        return $.extend(template, {
            resources: this.vfsController.getDescriptors(),
            quotas: this.quotasController.getQuotas(),
            ipAccessVerifier: this.ipAccessController.getIpAccess(),
            administration: this.domainAdminController.getDomainAdministration(),
            webOptions: this.webController.getWebOptions()
        });
    },

    _cleanup: function () {
        this.infoController = null;
        this.vfsController = null;
        this.quotasController = null;
        this.ipAccessController = null;
        this.domainAdminController = null;
        this.webController = null;
    }
});

/** @class */
jscape.domain.EditAccountTemplateController = Class.extend(
    /** @lends {jscape.domain.EditAccountTemplateController.prototype} */
{
    VARIABLES: ["installdir", "domain", "username", "queryattr['name']"],

    infoController: null,
    vfsController: null,
    quotasController: null,
    ipAccessController: null,
    domainAdminController: null,
    webController: null,

    deferred: null,

    /** @constructor */
    initialize: function() {
        this.variableController = new jscape.VariableController();
    },

    start: function(managementService, domainName, templateName) {
        this.managementService = managementService;
        this.domainName = domainName;
        this.templateName = templateName;
        this.deferred = $.Deferred();
        this.managementService.getAccountTemplate(domainName, templateName)
                .done($.proxy(function(template) { this._setupDialog(template).show(this); }, this))
                .fail($.proxy(function() { this.deferred.reject(); this.deferred = null; }, this));
        return this.deferred.promise();
    },

    onAddVariable: function(input) {
        this.variableController.start(input, this.VARIABLES);
    },

    onSubmit: function(dialog) {
        var template = this._createTemplate(dialog);
        dialog.destroy();

        this.managementService.setTemplate(this.domainName, this.templateName, template)
                .done($.proxy(function(template) { this.deferred.resolve(template); this.deferred = null; }, this))
                .fail($.proxy(function() { this.deferred.reject(); this.deferred = null; }, this))
                .always($.proxy(this._cleanup, this));
    },

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

    _setupDialog: function(template) {
        var dialog = new jscape.domain.EditAccountTemplateDialog();
        dialog.setTemplateName(template.name);
        this._createView(dialog.container());
        window.setTimeout($.proxy(function () {
            try {
                this._setupView(template);
            } catch (e) {
                dialog.destroy();
                this._cleanup();
            } finally {
                dialog = null;
            }
        }, this), 0);
        return dialog;
    },

    _createView: function (container) {
        this._cleanup();
        this.infoController = new jscape.domain.EditUserTemplateInfoController(container);
        this.vfsController = new jscape.vfs.VirtualFilesController(container);
        this.quotasController = new jscape.domain.QuotasController(container);
        this.ipAccessController = new jscape.domain.UserIpAccessController(container);
        this.domainAdminController = new jscape.domain.DomainAdministrationController(container, this.vfsController);
        this.webController = new jscape.domain.WebOptionsController(container);
    },

    _setupView: function (template) {
        this.infoController.start(this.managementService, this.domainName, template);
        this.vfsController.start(this.managementService, this.domainName, template.resources);
        this.quotasController.start(template.quotas);
        this.ipAccessController.start(template.ipAccessVerifier);
        this.domainAdminController.start(this.managementService, this.domainName, template.administration);
        this.webController.start(template.webOptions);
    },

    _createTemplate: function (dialog) {
        var template = this.infoController.createAccountTemplate();
        return $.extend(template, {
            resources: this.vfsController.getDescriptors(),
            quotas: this.quotasController.getQuotas(),
            ipAccessVerifier: this.ipAccessController.getIpAccess(),
            administration: this.domainAdminController.getDomainAdministration(),
            webOptions: this.webController.getWebOptions()
        });
    },

    _cleanup: function() {
        this.infoController = null;
        this.vfsController = null;
        this.quotasController = null;
        this.ipAccessController = null;
        this.domainAdminController = null;
        this.webController = null;
    }
});

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

    start: function(managementService, domainName, templateName) {
        this.managementService = managementService;
        this.domainName = domainName;
        this.deferred = $.Deferred();
        this._confirmDelete(templateName)
                .done($.proxy(this._deleteConfirmed, this, templateName))
                .fail($.proxy(function() { this.deferred.reject(); this.deferred = null; }, this));
        return this.deferred.promise();
    },

    _confirmDelete: function(templateName) {
        return jscape.ConfirmDialog.confirm(
                window.R.string.USER_TEMPLATES_CONFIRM_DELETE_TITLE,
                window.R.string.USER_TEMPLATES_CONFIRM_DELETE_MESSAGE.supplant({0: templateName}));
    },

    _deleteConfirmed: function (templateName) {
        $.when.apply(jQuery, [this.managementService.deleteTemplate(this.domainName, templateName)])
                .done($.proxy(function () { this.deferred.resolve(); this.deferred = null; }, this))
                .fail($.proxy(function () { this.deferred.reject(); this.deferred = null; }, this));
    }
});

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

    /** @constructor */
    initialize: function(dialog) {
        this.dialog = dialog.clone().attr("id", "");
        this.dialog.dialog({
            width: 800, 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)
        }).keydown($.proxy(function(e) {
            if (e.keyCode == 13) {
                e.stopPropagation();
                this._onSubmit();
            } else if (e.keyCode == 27) {
                e.stopPropagation();
                this._onCancel();
            }
        }, this)).show();

        this.tabs = $("div[role=tablist]", this.dialog).tabs({tabPosition: "top", plain: true});

        this.addVariableButton = $("a[role=button][name=addvar]", this.dialog).linkbutton({disabled: true, onClick: $.proxy(this._onClick$AddVariableButton, this)});

        this.dialog
                .focusin($.proxy(function (e) {
                             var target = $(e.target);
                             if (target.is(this.addVariableButton)) {
                                 return;
                             }
                             if (target.is(":input[type=text], textarea") && target.is(":not(.numberbox):not([readonly])")) {
                                 this.focusInField = target;
                             } else {
                                 this.focusInField = null;
                             }
                             this._onChange$FocusInField();
                         }, this))
                .focusout($.proxy(function (e) {
                              if ($(e.target).is(this.focusInField)
                                  && $(e.relatedTarget).is(this.addVariableButton)) {
                                  return;
                              }
                              this.focusInField = null;
                              this._onChange$FocusInField();
                          }, this));
    },

    container: function() {
        return this.dialog;
    },

    show: function (listener) {
        this.listener = listener;
        this.dialog.dialog("center").dialog("open");
    },

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

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

    _onClick$AddVariableButton: function () {
        if (this.focusInField && this.focusInField.length && this.focusInField.is(":visible")) {
            this.addVariableButton.linkbutton("disable");
            this.listener.onAddVariable(this.focusInField);
        }
    },

    _onChange$FocusInField: function() {
        this.addVariableButton.linkbutton(this.focusInField != null ? "enable" : "disable");
    },

    _onSubmit: function () {
        if (this._valid()) {
            this.hide();
            this.listener.onSubmit(this);
        }
    },

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

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

    _valid: function () {
        return new jscape.Validator().validateTabs(this.tabs);
    }
});

/** @class */
jscape.domain.AddAccountTemplateDialog = jscape.domain.AccountTemplateDialog.extend(
    /** @lends {jscape.domain.AddAccountTemplateDialog.prototype} */
{
    /** @constructor */
    initialize: function() {
        this._super($("#d-usertemplate-add"));
    }
});

/** @class */
jscape.domain.EditAccountTemplateDialog = jscape.domain.AccountTemplateDialog.extend(
    /** @lends {jscape.domain.EditAccountTemplateDialog.prototype} */
{
    /** @constructor */
    initialize: function() {
        this._super($("#d-usertemplate-edit"));

        this.title = this.dialog.dialog("header").text() || "";
    },

    setTemplateName: function (value) {
        this.dialog.dialog("setTitle", this.title.supplant({0: value}));
    }
});

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

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

        this._setupView();
    },

    createAccountTemplate: function() {
        var company = this.view.getCompany().trim().length ? this.view.getCompany() : null;
        var phone = $.isNumeric(this.view.getPhoneCode()) ? new jscape.Phone(this.view.getPhoneCode(), this.view.getPhoneNumber(), this.view.getPhoneExtension()) : null;
        return new jscape.AccountTemplate(this.view.getName(),
                                          this.view.getUsername(),
                                          this.view.getEmail(),
                                          company,
                                          phone,
                                          this.view.getOwner(),
                                          this.view.getExpirationDate(),
                                          this.view.getExpiresAfterPeriod(),
                                          this.view.getEnabled(),
                                          this.view.getSecured(),
                                          this.view.getGroups(),
                                          this.view.getClientKeys(),
                                          this.view.getAllowPasswordChanging(),
                                          this.view.getAllowAdHocTransfers(),
                                          this.view.getUseMultiFactorAuthentication(),
                                          this.view.getIgnorePasswordAgingRules(),
                                          this.view.getTags());
    },

    _setupView: function () {
        this.view.setEnabled(true);
        this.view.setAllowAdHocTransfers(true);
        this.view.setAllowPasswordChanging(true);

        this.managementService.getAccountAdminNames(this.domainName)
                .done($.proxy(function(owners) { this.view.setAvailableOwners(owners); }, this));
        this.managementService.getGroupNames(this.domainName)
                .done($.proxy(function(groups) { this.view.setAvailableGroups(groups.sort()); }, this));
        $.when(this.managementService.getClientPublicKeys(this.domainName),
               this.managementService.getClientCertificates(this.domainName))
                .done($.proxy(function (publicKeys, certificates) {
                          publicKeys = $.map(publicKeys, function (key) { return key.name; });
                          certificates = $.map(certificates, function (key) { return key.name; });

                          this.view.setAvailableClientKeys(publicKeys.concat(certificates));
                      }, this));
        this.managementService.getDomainTags(this.domainName)
                .done($.proxy(function (tags) { this.view.setAvailableTags(tags); this.view.setTags(tags); }, this));
    }
});

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

    start: function(managementService, domainName, template) {
        this.managementService = managementService;
        this.domainName = domainName;
        this.templateName = template.name;
        this.view.show(this);

        this._setupView(template);
    },

    createAccountTemplate: function() {
        var company = this.view.getCompany().trim().length ? this.view.getCompany() : null;
        var phone = $.isNumeric(this.view.getPhoneCode()) ? new jscape.Phone(this.view.getPhoneCode(), this.view.getPhoneNumber(), this.view.getPhoneExtension()) : null;
        return new jscape.AccountTemplate(this.templateName,
                                          this.view.getUsername(),
                                          this.view.getEmail(),
                                          company,
                                          phone,
                                          this.view.getOwner(),
                                          this.view.getExpirationDate(),
                                          this.view.getExpiresAfterPeriod(),
                                          this.view.getEnabled(),
                                          this.view.getSecured(),
                                          this.view.getGroups(),
                                          this.view.getClientKeys(),
                                          this.view.getAllowPasswordChanging(),
                                          this.view.getAllowAdHocTransfers(),
                                          this.view.getUseMultiFactorAuthentication(),
                                          this.view.getIgnorePasswordAgingRules(),
                                          this.view.getTags());
    },

    _setupView: function (template) {
        if (template) {
            this.view.setUsername(template.username);
            this.view.setEmail(template.emailAddress);
            this.view.setCompany(template.company != null ? template.company.name : "");
            if (template.phone != null) {
                this.view.setPhoneCode(template.phone.code);
                this.view.setPhoneNumber(template.phone.number);
                this.view.setPhoneExtension(template.phone.extension);
            }
            this.view.setExpirationDate(template.expirationDate);
            this.view.setExpiresAfterPeriod(template.expirationPeriodMillis);
            this.view.setEnabled(template.enabled);
            this.view.setSecured(template.secured);
            this.view.setUseMultiFactorAuthentication(template.usePhoneAuthentication);
            this.view.setAllowAdHocTransfers(template.emailFileTransferAllowed);
            this.view.setAllowPasswordChanging(template.passwordChangingAllowed);
            this.view.setIgnorePasswordAgingRules(template.ignorePasswordAgingRules);
            this.view.setIgnorePasswordAgingRules(template.ignorePasswordAgingRules);
        }

        this.managementService.getAccountAdminNames(this.domainName)
                .done($.proxy(function (owners) {
                          this.view.setAvailableOwners(owners);
                          template && this.view.setOwner(template.owner);
                      }, this));
        this.managementService.getGroupNames(this.domainName)
                .done($.proxy(function (groups) {
                          this.view.setAvailableGroups(groups.sort());
                          template && this.view.setGroups(template.groups);
                      }, this));
        $.when(this.managementService.getClientPublicKeys(this.domainName),
               this.managementService.getClientCertificates(this.domainName))
                .done($.proxy(function (publicKeys, certificates) {
                          publicKeys = $.map(publicKeys, function (key) { return key.name; });
                          certificates = $.map(certificates, function (key) { return key.name; });

                          this.view.setAvailableClientKeys(publicKeys.concat(certificates));
                          template && this.view.setClientKeys(template.bindedKeys);
                      }, this));
        this.managementService.getDomainTags(this.domainName)
                .done($.proxy(function (tags) {
                          this.view.setAvailableTags(tags);
                          template && this.view.setTags(template.tags);
                      }, this));
    }
});

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

        this.expires = $("input[name=expires]", this.fieldset).change($.proxy(function () {
            var enabled = this.expires.is(":checked");
            this.expirationDate.datebox(enabled ? "enable" : "disable").datebox(enabled ? "enableValidation" : "disableValidation");

            this.expiresAfter.prop("disabled", this.expires.is(":checked:not(:disabled)"));
        }, this));
        this.expirationDate = $("input[name=expirationdate]", this.fieldset);
        this.expirationDate.datebox({
            required: true,
            editable: false,
            disabled: true,
            width: 120,
            formatter: function (date) {
                return jscape.DateFormat.format(date, "{MM}/{dd}/{yy}");
            },
            parser: function (text) {
                var matches = /(\d{1,2})\/(\d{1,2})\/(\d{2,4})/.exec(text);
                if (matches != null && matches.length == 4) {
                    var m = parseInt(matches[1], 10), d = parseInt(matches[2], 10), y = parseInt(matches[3], 10);
                    if (!isNaN(d) && !isNaN(m) && !isNaN(y)) {
                        return new Date(y, m - 1, d);
                    }
                }
                return new Date();
            }
        });
        this.expirationDate.datebox("calendar").calendar({
            validator: function (date) {
                var now = new Date();
                now.setHours(date.getHours());
                now.setMinutes(date.getMinutes());
                now.setSeconds(date.getSeconds());
                now.setMilliseconds(date.getMilliseconds());
                return now.getTime() <= date.getTime();
            }
        });
        this.expirationDate.datebox("setValue", this.expirationDate.datebox("options").formatter(new Date()));

        this.expiresAfter = $("input[name=expiresafter]:checkbox", this.fieldset).change($.proxy(function() {
            var enabled = this.expiresAfter.is(":checked");
            this.expiresAfterPeriod.numberspinner(enabled ? "enable" : "disable").numberspinner(enabled ? "enableValidation" : "disableValidation");
            this.expiresAfterUnit.combobox(enabled ? "enable" : "disable").combobox(enabled ? "enableValidation" : "disableValidation");

            this.expires.prop("disabled", this.expiresAfter.is(":checked:not(:disabled)"));
        }, this));
        this.expiresAfterPeriod = $("input[name=expiresafterperiod]", this.fieldset).numberspinner({min: 1, max: 1000, step: 1, value: 1, disabled: true, width: 90});
        this.expiresAfterUnit = $("select[name=expiresafterunit]", this.fieldset).combobox({required: true, editable: false, disabled: true, panelHeight: "auto", width: 90});

        this.useMultiFactorAuth = $("input[name=multifactorauth]:checkbox", this.fieldset);
        $("a[role=button][name=resettotp]", this.fieldset).hide();
    },

    getExpirationDate: function() {
        return this.expires.is(":checked:not(:disabled)")
                ? this.expirationDate.datebox("calendar").calendar("options").current
                : null;
    },

    setExpirationDate: function(value) {
        var formatter = this.expirationDate.datebox("options").formatter;
        if (value != null) {
            this.expires.prop("checked", true).change();
            this.expirationDate.datebox("setValue", formatter(value)).datebox("enable");
        } else {
            this.expires.prop("checked", false).change();
            this.expirationDate.datebox("setValue", formatter(new Date()));
        }
    },

    getExpiresAfterPeriod: function() {
        if (this.expiresAfter.is(":checked:not(:disabled)")) {
            var factor = parseInt(this.expiresAfterUnit.combobox("getValue"));
            return parseInt(this.expiresAfterPeriod.numberspinner("getValue")) * factor;
        }
        return null;
    },

    setExpiresAfterPeriod: function(value) {
        if (value != null) {
            var factor = $.fn._unitValueFor(this.expiresAfterUnit, value);
            this.expiresAfter.prop("checked", true).change();
            this.expiresAfterPeriod.numberspinner("setValue", value / factor);
            this.expiresAfterUnit.combobox("select", factor + "");
        } else {
            this.expiresAfter.prop("checked", false).change();
        }
    },

    getUseMultiFactorAuthentication: function() {
        return this.useMultiFactorAuth.is(":checked");
    },

    setUseMultiFactorAuthentication: function(value) {
        this.useMultiFactorAuth.prop("checked", !!value)
    }
});

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

        this.name = $("input[name=name]", this.fieldset).textbox({required: true, validType: ["non_empty", "usertemplate_unique"], missingMessage: window.R.string.USER_TEMPLATES_ERROR_BAD_NAME, invalidMessage: window.R.string.USER_TEMPLATES_ERROR_BAD_NAME, width: "60%"});
    },

    getName: function () {
        return this.name.textbox("getValue");
    }
});

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