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

/** @class */
jscape.OftpMessage = Class.extend(
    /** @lends {jscape.OftpMessage.prototype} */
{
    /** @constructor */
    initialize: function(a, b, c, d, e, f, g, h, i, j, k) {
        this.id = a || "";
        this.date = parseInt(b) || 0;
        this.type = c || jscape.OftpMessage.Type.REQUEST;
        this.direction = d || jscape.OftpMessage.Direction.UNKNOWN;
        this.originator = e || "";
        this.destination = f || "";
        this.username = g || "";
        this.tradingPartner = h || "";
        this.filename = i || "";
        this.fileDate = parseInt(j) || 0;
        this.status = k || jscape.OftpMessage.Status.PENDING;
    }
});
jscape.OftpMessage.fromJSON = function(data) {
    return data ? $.extend(new jscape.OftpMessage(), data) : null;
};
jscape.OftpMessage.Type = {REQUEST: "REQUEST", RECEIPT: "RECEIPT"};
jscape.OftpMessage.Direction = {INCOMING: "INCOMING", OUTGOING: "OUTGOING", UNKNOWN: "UNKNOWN"};
jscape.OftpMessage.Status = {PENDING: "PENDING", SUCCESS: "SUCCESS", FAILURE: "FAILURE", RELAY_RECEIVED: "RELAY_RECEIVED", RELAY_SENT: "RELAY_SENT", RELAY_FAILURE: "RELAY_FAILURE"};

/** @class */
jscape.OftpSendFileData = Class.extend(
    /** @lends {jscape.OftpSendFileData.prototype} */
{
    /** @constructor */
    initialize: function(path, type, maxRecordSize, destinationPartner, virtualFile, description, placeToOutbox, debugFile) {
        this.path = path || "";
        this.type = type || null;
        this.maxrecordsize = parseInt(maxRecordSize) || 0;
        this.destinationPartner = destinationPartner || null;
        this.virtualfilename = virtualFile || null;
        this.description = description || null;
        this.placetooutbox = !!placeToOutbox;
        this.debugfile = debugFile || "";
    }
});

/** @class */
jscape.OftpSendReceiptData = Class.extend(
    /** @lends {jscape.OftpSendFileData.prototype} */
{
    /** @constructor */
    initialize: function(receiptType, reason, description, connectionPartner, placeToOutbox, debugFile) {
        this.receiptType = receiptType || null;
        this.reason = reason || "";
        this.description = description || "";
        this.connectionPartner = connectionPartner || null;
        this.placeToOutbox = !!placeToOutbox;
        this.debugFile = debugFile || "";
    }
});

/** @class */
jscape.OftpSendCertidicateData = Class.extend(
    /** @lends {jscape.OftpSendCertidicateData.prototype} */
{
    /** @constructor */
    initialize: function(certificate, type, destinationPartner, placeToOutbox, debugFile) {
        this.certificate = certificate || null;
        this.type = type || "";
        this.destinationPartner = destinationPartner || null;
        this.placeToOutbox = !!placeToOutbox;
        this.debugFile = debugFile || "";
    }
});

/** @class */
jscape.domain.OftpModule = jscape.domain.DomainModule.extend(
    /** @lends {jscape.domain.OftpModule.prototype} */
{
    onCreate: function () {
        this._super.apply(this, arguments);

        this.controller = new jscape.domain.OftpMessagesController();
        this.controller.onCreate(this.managementService, this.domainName);
    },

    onStart: function () {
        this.controller.onStart();
    },

    onResume: function () {
        this.controller.onResume();
    }
});

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

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

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

        this.sendFileController = new jscape.domain.OftpSendFileController();
        this.sendReceiptController = new jscape.domain.OftpSendReceiptController();
        this.sendCertificateController = new jscape.domain.OftpSendCertificateController();
        this.resendMessageController = new jscape.domain.OftpResendMessageController();
        this.viewController = new jscape.domain.OftpViewMessageController();
        this.deleteController = new jscape.domain.OftpDeleteMessageController();
    },

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

    onResume: function () {
        return this.view.refresh();
    },

    onRefresh: function (params) {
        params = jscape.Page.requestParameters(params);
        return this.managementService.listOftpMessages(this.domainName, params.startIndex, params.count, params.query)
                .then(jscape.Page.datagridFormatter());
    },

    onSendFile: function() {
        return this.sendFileController.start(this.managementService, this.domainName)
                .done($.proxy(this._refreshAfter, this, 1000));
    },

    onSendCertificate: function() {
        return this.sendCertificateController.start(this.managementService, this.domainName);
    },

    onSendReceipt: function(message) {
        return this.sendReceiptController.start(this.managementService, this.domainName, message)
                .done($.proxy(this._refreshAfter, this, 1000));
    },

    onResendMessage: function(message) {
        return this.resendMessageController.start(this.managementService, this.domainName, message)
                .done($.proxy(this._refreshAfter, this, 1000));
    },

    onViewMessage: function(message) {
        this.viewController.start(this.managementService, this.domainName, message);
    },

    onDeleteMessage: function(messages) {
        return this.deleteController.start(this.managementService, this.domainName, messages)
                .done($.proxy(this._messageDeleted, this, messages));
    },

    _refreshAfter: function(delay) {
        setTimeout($.proxy(function() { this.view.refresh(); }, this), delay || 0);
    },

    _messageDeleted: function(messages) {
        this._recordDeleted(messages);
    },

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

    _virtualFilenameValid: function(value) {
        return /^[A-Z0-9/\-.&()]{1,26}$/.test(value);
    }
});

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

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

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

        this.data = $("table[role=grid][aria-label=oftpmessages]", this.fieldset);
        this.data.datagrid({
            fit: true,
            fitColumns: true,
            ctrlSelect: true,
            pagination: true,
            search: true,
            remoteSearch: true,
            remoteSort: true,
            sortName: "date",
            sortOrder: "desc",
            columns: [[
                {field: "id", title: $("thead th:nth-child(6)", this.data).text(), sortable: true, width: 150},
                {field: "date", title: $("thead th:nth-child(1)", this.data).text(), sortable: true, width: 120, align: "right", finder: "datebox", formatter: function(value) { return new Date(value).toLocaleString(); }},
                {field: "type", title: $("thead th:nth-child(4)", this.data).text(), sortable: true, width: 130, formatter: $.proxy(this._formatType, this), finder: this._finderFor([jscape.OftpMessage.Type.RECEIPT, jscape.OftpMessage.Type.REQUEST], $.proxy(this._formatType, this))},
                {field: "direction", title: $("thead th:nth-child(5)", this.data).text(), sortable: true, width: 130, formatter: $.proxy(this._formatDirection, this), finder: this._finderFor([jscape.OftpMessage.Direction.INCOMING, jscape.OftpMessage.Direction.OUTGOING], $.proxy(this._formatDirection, this))},
                {field: "originator", title: $("thead th:nth-child(8)", this.data).text(), sortable: true, width: 120},
                {field: "destination", title: $("thead th:nth-child(9)", this.data).text(), sortable: true, width: 150},
                {field: "filename", title: $("thead th:nth-child(7)", this.data).text(), sortable: true, width: 180},
                {field: "username", title: $("thead th:nth-child(2)", this.data).text(), sortable: true, width: 90},
                {field: "tradingPartner", title: $("thead th:nth-child(3)", this.data).text(), sortable: true, width: 120},
                {field: "status", title: $("thead th:nth-child(10)", this.data).text(), sortable: true, width: 100, formatter: $.proxy(this._formatStatus, this), styler: $.proxy(this._formatStatusStyle, this), finder: this._finderFor([jscape.OftpMessage.Status.PENDING, jscape.OftpMessage.Status.SUCCESS, jscape.OftpMessage.Status.FAILURE, jscape.OftpMessage.Status.RELAY_RECEIVED, jscape.OftpMessage.Status.RELAY_SENT, jscape.OftpMessage.Status.RELAY_FAILURE], $.proxy(this._formatStatus, this))}
            ]],
            onSelect: $.proxy(this._adjustRowSelection, this),
            onUnselect: $.proxy(this._adjustRowSelection, this),
            onDblClickRow: $.proxy(this._onClick$ViewButton, this),
            loader: $.proxy(this._onLoad$Data, this),
            onBeforeLoad: function() { return !initializing; },
            onLoadSuccess: $.proxy(this._adjustRowSelection, this)
        });

        this.sendFileButton = $("a[role=button][name=sendfile]", this.fieldset).linkbutton({onClick: $.proxy(this._onClick$SendFileButton, this)});
        this.sendCertificateButton = $("a[role=button][name=sendCertificate]", this.fieldset).linkbutton({onClick: $.proxy(this._onClick$SendCertificateButton, this)});
        this.viewButton = $("a[role=button][name=view]", this.fieldset).linkbutton({disabled: true, onClick: $.proxy(this._onClick$ViewButton, this)});
        this.sendReceiptButton = $("a[role=button][name=sendreceipt]", this.fieldset).linkbutton({disabled: true, onClick: $.proxy(this._onClick$SendReceiptButton, this)});
        this.resendButton = $("a[role=button][name=resend]", this.fieldset).linkbutton({disabled: true, onClick: $.proxy(this._onClick$ResendButton, 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.OftpMessagesView.LISTENER;
        this.data.datagrid("resize");
        this._adjustRowSelection();
    },

    _finderFor: function (values, formatter) {
        return {type: "combobox", options: {panelHeight: "auto", data: $.map(values, function (value) { return {text: formatter(value), value: value}; })}};
    },

    _formatType: function(value) {
        return window.R.string[("OFTP_MESSAGES_TYPE_" + value).toUpperCase()] || "";
    },

    _formatDirection: function(value) {
        return window.R.string[("OFTP_MESSAGES_DIRECTION_" + value).toUpperCase()] || "";
    },

    _formatStatus: function(value) {
        return window.R.string[("OFTP_MESSAGES_STATUS_" + value).toUpperCase()] || "";
    },

    _formatStatusStyle: function(value) {
        switch (value) {
            case jscape.OftpMessage.Status.PENDING:
                return "color:grey";
            case jscape.OftpMessage.Status.SUCCESS:
                return "color:green";
            case jscape.OftpMessage.Status.FAILURE:
                return "color:red";
            case jscape.OftpMessage.Status.RELAY_RECEIVED:
                return "color:grey";
            case jscape.OftpMessage.Status.RELAY_SENT:
                return "color:grey";
            case jscape.OftpMessage.Status.RELAY_FAILURE:
                return "color:red";
            default:
                return "";
        }
    },

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

    _onClick$SendFileButton: function() {
        this.sendFileButton.linkbutton("disable");
        this.listener.onSendFile()
                .always($.proxy(function() { this.sendFileButton.linkbutton("enable"); }, this));
    },

    _onClick$SendCertificateButton: function() {
        this.sendCertificateButton.linkbutton("disable");
        this.listener.onSendCertificate()
                .always($.proxy(function() { this.sendCertificateButton.linkbutton("enable"); }, this))
    },

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

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

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

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

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

    _adjustButtonsState: function() {
        var message = this.selection.length == 1 ? this.selection[0] : null;
        var isRequest = message && jscape.OftpMessage.Type.REQUEST;

        this.viewButton.linkbutton(this.selection.length == 1 ? "enable" : "disable");
        this.resendButton.linkbutton(isRequest && jscape.OftpMessage.Direction.OUTGOING == message.direction ? "enable" : "disable");
        this.sendReceiptButton.linkbutton(isRequest && jscape.OftpMessage.Direction.INCOMING == message.direction ? "enable" : "disable");
        this.deleteButton.linkbutton(this.selection.length != 0 ? "enable" : "disable");
    }});
jscape.domain.OftpMessagesView.LISTENER = {
    onSendFile: $.noop,
    onSendReceipt: $.noop,
    onSendCertificate: $.noop,
    onViewMessage: $.noop,
    onResendMessage: $.noop,
    onDeleteMessage: $.noop,
    onRefresh: $.noop
};

/** @class */
jscape.domain.OftpSendFileController = Class.extend(
    /** @lends {jscape.domain.OftpSendFileController.prototype} */
{
    PROTOCOLS: ["OFTP"],
    DEFAULTS: {fileType: "UNSTRUCTURED", maxRecordSize: 128},

    deferred: null,

    start: function(managementService, domainName) {
        this.managementService = managementService;
        this.domainName = domainName;
        this.deferred = $.Deferred();
        this.managementService.getTradingPartnerNames(this.domainName, this.PROTOCOLS)
                .done($.proxy(function (partnerNames) {
                          if (partnerNames.length) {
                              partnerNames = partnerNames.sort(function(a, b) { return a.toUpperCase() > b.toUpperCase(); });
                              this._setupDialog(partnerNames).show(this);
                          } else {
                              this._showNoPartnersError();
                              this.deferred.reject();
                              this.deferred = null;
                          }
                      }, this))
                .fail($.proxy(function () {
                          this._showNoPartnersError();
                          this.deferred.reject();
                          this.deferred = null;
                      }, this));
        return this.deferred.promise();
    },

    onSelectFile: function(dialog) {
        new SelectPathController($.proxy(this.managementService.listFileSystem, this.managementService),
                                 $.proxy(this.managementService.createFileSystemDir, this.managementService))
                .selectFile()
                .done(function(entry) { dialog.setFile(entry.path); });
    },

    onSelectDebugFile: function (dialog) {
        new SelectPathController($.proxy(this.managementService.listDebugDir, this.managementService),
                                 $.proxy(this.managementService.createDebugDir, this.managementService))
                .selectFile()
                .done($.proxy(function (entry) { dialog.setDebugFile(entry.path); }, this));
    },

    onSubmit: function (dialog) {
        var partnerName = dialog.getPartner();
        var data = this._createData(dialog);
        dialog.destroy();

        this.managementService.sendTradingPartnerFile(this.domainName, partnerName, data)
                .done($.proxy(function () { this.deferred.resolve(); this.deferred = null; }, this))
                .fail($.proxy(function () { this.deferred.reject(); this.deferred = null; }, this));
    },

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

    _createData: function(dialog) {
        return new jscape.OftpSendFileData(dialog.getFile(),
                                           dialog.getFileType(),
                                           dialog.getMaxRecordSize(),
                                           dialog.getDestinationPartner(),
                                           dialog.getVirtualFile(),
                                           dialog.getDescription(),
                                           dialog.isPlaceToOutbox(),
                                           dialog.getDebugFile());
    },

    _setupDialog: function(partners) {
        var dialog = new jscape.domain.OftpSendFileDialog();
        dialog.setPartners(partners);
        dialog.setDestinationPartners(partners);
        dialog.setFileType(this.DEFAULTS.fileType);
        dialog.setMaxRecordSize(this.DEFAULTS.maxRecordSize);
        return dialog;
    },

    _showNoPartnersError: function () {
        $.messager.alert(window.R.string.APPLICATION_ERROR_TITLE,
                         window.R.string.OFTP_MESSAGES_ERROR_NO_PARTNERS,
                         "warning");
    }
});

/** @class */
jscape.domain.OftpSendFileDialog = Class.extend(
    /** @lends {jscape.domain.OftpSendFileDialog.prototype} */
{
    /** @constructor */
    initialize: function() {
        this.dialog = $("#d-oftp-sendfile").clone().attr("id", "");
        this.dialog.dialog({
            width: 600, 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=oftpsendfilefields]", this.dialog);

        this.partner = $("select[name=partner]", this.fieldset).combobox({required: true, editable: false, width: 170, panelHeight: "auto", panelMaxHeight: "40%"});
        this.destinationPartner = $("select[name=destinationpartner]", this.fieldset).combobox({required: true, editable: false, width: 170, panelHeight: "auto"});

        this.file = $("input[name=file]", this.fieldset).textbox({required: true, tipPosition: "bottom", missingMessage: window.R.string.OFTP_MESSAGES_ERROR_BAD_FILE, width: "50%"});
        this.browseFileButton = $("a[role=button][name=browsefile]", this.fieldset).linkbutton({onClick: $.proxy(this._onClick$BrowseFileButton, this)});

        this.type = $("select[name=type]", this.fieldset).combobox({required: true, editable: false, width: 170, panelHeight: "auto", onChange: $.proxy(this._onChange$FileType, this)});
        this.maxRecordSize = $("input[name=recordsize]", this.fieldset).numberspinner({disabled: true, min: 1, max: 99999, value: 1, width: 120});
        this.description = $("input[name=description]", this.fieldset).textbox({width: "50%"});

        this.virtualFile = $("input[name=virtualfile]", this.fieldset).textbox({validType: "oftp_send_virtual_file", width: "50%"});
        this.placeToOutbox = $("input[name=placetooutbox]:checkbox", this.fieldset);
        this.debugFile = $("input[name=debugfile]", this.fieldset).textbox({width: "50%"});
        this.browseDebugFileButton = $("a[role=button][name=browsedebugfile]", this.fieldset).linkbutton({onClick: $.proxy(this._onClick$BrowseDebugFileButton, this)});
    },

    getPartner: function() {
        return this.partner.combobox("getValue");
    },

    setPartners: function(values) {
        this.partner.combobox("loadData", values);
    },

    getDestinationPartner: function() {
        return this.destinationPartner.combobox("getValue");
    },

    setDestinationPartners: function(values) {
        this.destinationPartner.combobox("loadData", values);
    },

    getFile: function() {
        return this.file.textbox("getValue");
    },

    setFile: function(value) {
        this.file.textbox("setValue", value);
    },

    getFileType: function() {
        return this.type.combobox("getValue");
    },

    setFileType: function(value) {
        this.type.combobox("select", value);
    },

    getMaxRecordSize: function() {
        return this.maxRecordSize.is(":disabled") ? 0 : parseInt(this.maxRecordSize.numberspinner("getValue"));
    },

    setMaxRecordSize: function(value) {
        return this.maxRecordSize.numberspinner("setValue", parseInt(value));
    },

    getDescription: function() {
        return this.description.textbox("getValue");
    },

    getVirtualFile: function() {
        return this.virtualFile.textbox("getValue");
    },

    isPlaceToOutbox: function() {
        return this.placeToOutbox.is(":checked");
    },

    getDebugFile: function() {
        return this.debugFile.textbox("getValue");
    },

    setDebugFile: function(value) {
        this.debugFile.textbox("setValue", value);
    },

    show: function (listener) {
        this.listener = listener || jscape.domain.OftpSendFileDialog.LISTENER;
        this.dialog.dialog("center").dialog("open");
        this.fieldset.form("validate");
        this.fieldset.find("input:first").focus();
        this._onChange$FileType();
    },

    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");
    },

    _onClick$BrowseFileButton: function() {
        this.listener.onSelectFile(this);
    },

    _onClick$BrowseDebugFileButton: function() {
        this.listener.onSelectDebugFile(this);
    },

    _onChange$FileType: function() {
        var enabled = /^(fixed|variable)$/i.test(this.getFileType());
        this.maxRecordSize.numberspinner(enabled ? "enable" : "disable");
    },

    _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;
    }
});
jscape.domain.OftpSendFileDialog.LISTENER = {
    onSelectFile: $.noop,
    onSelectDebugFile: $.noop
};

/** @class */
jscape.domain.OftpSendReceiptController = Class.extend(
    /** @lends {jscape.domain.OftpSendReceiptController.prototype} */
{
    PROTOCOLS: ["OFTP"],

    deferred: null,

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

    onSubmit: function (dialog) {
        var data = this._createData(dialog);
        dialog.destroy();

        this.managementService.sendOftpMessageReceipt(this.domainName, this.messageId, data)
                .done($.proxy(function () { this.deferred.resolve(); this.deferred = null; }, this))
                .fail($.proxy(function () { this.deferred.reject(); this.deferred = null; }, this));
    },

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

    onSelectDebugFile: function (dialog) {
        new SelectPathController($.proxy(this.managementService.listDebugDir, this.managementService),
                                 $.proxy(this.managementService.createDebugDir, this.managementService))
                .selectFile()
                .done($.proxy(function (entry) { dialog.setDebugFile(entry.path); }, this));
    },

    _createData: function(dialog) {
        return new jscape.OftpSendReceiptData(dialog.getType(),
                                              dialog.getReason(),
                                              dialog.getDescription(),
                                              dialog.getPartner(),
                                              dialog.isPlaceToOutbox(),
                                              dialog.getDebugFile());
    },

    _setupDialog: function() {
        var dialog = new jscape.domain.OftpSendReceiptDialog();
        this.managementService.getTradingPartnerNames(this.domainName, this.PROTOCOLS)
                .done(function(names) { dialog.setPartners(names.sort(function(a, b) { return a.toUpperCase() > b.toUpperCase(); })); });
        dialog.setType("POSITIVE");
        return dialog;
    }
});

/** @class */
jscape.domain.OftpSendReceiptDialog = Class.extend(
    /** @lends {jscape.domain.OftpSendReceiptDialog.prototype} */
{
    /** @constructor */
    initialize: function() {
        this.dialog = $("#d-oftp-sendreceipt").clone().attr("id", "");
        this.dialog.dialog({
            width: 600, 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=oftpsendreceiptfields]", this.dialog);

        this.type = $("select[name=type]", this.fieldset).combobox({required: true, editable: false, onChange: $.proxy(this._onChange$Type, this), width: 310, panelHeight: "auto"});
        this.reason = $("select[name=reason]", this.fieldset).combobox({required: true, editable: false, width: 310, panelHeight: "auto"});
        this.description = $("input[name=description]", this.fieldset);
        this.placeToOutbox = $("input[name=placetooutbox]:checkbox", this.fieldset);

        this.usePartner = $("input[name=usepartner]:checkbox", this.fieldset).change($.proxy(function() {
            var enabled = this.usePartner.is(":checked");
            this.partner.combobox(enabled ? "enable" : "disable").combobox(enabled ? "enableValidation" : "disableValidation");
        }, this));
        this.partner = $("select[name=partner]", this.fieldset).combobox({required: true, editable: false, width: 170, panelHeight: "auto"});

        this.debugFile = $("input[name=debugfile]", this.fieldset);
        this.browseDebugFileButton = $("a[role=button][name=browsedebugfile]", this.fieldset).linkbutton({onClick: $.proxy(this._onClick$BrowseDebugFileButton, this)});
    },

    getType: function() {
        return this.type.combobox("getValue");
    },

    setType: function(value) {
        this.type.combobox("select", value);
    },

    getReason: function() {
        return !this.reason.combobox("options").disabled ? this.reason.combobox("getValue") : null;
    },

    getDescription: function() {
        return !this.description.prop("disabled") ? this.description.val() : null;
    },

    getPartner: function() {
        return this.usePartner.is(":checked") ? this.partner.combobox("getValue") : null;
    },

    setPartners: function(values) {
        this.partner.combobox("loadData", values);
    },

    isPlaceToOutbox: function() {
        return this.placeToOutbox.is(":checked");
    },

    getDebugFile: function() {
        return this.debugFile.val();
    },

    setDebugFile: function(value) {
        this.debugFile.val(value);
    },

    show: function (listener) {
        this.listener = listener || jscape.domain.OftpSendReceiptDialog.LISTENER;
        this.dialog.dialog("center").dialog("open");
        this.fieldset.form("validate");
        this.usePartner.change();
        this._onChange$Type();
    },

    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");
    },

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

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

    _onChange$Type: function() {
        var enabled = "NEGATIVE" === this.getType();
        this.reason.combobox(enabled ? "enable" : "disable");
        this.description.prop("disabled", !enabled);
    },

    _onClick$BrowseDebugFileButton: function() {
        this.listener.onSelectDebugFile(this);
    },

    _closed: function () {
        return !!this.dialog.dialog("options").closed;
    }
});
jscape.domain.OftpSendReceiptDialog.LISTENER = {
    onSelectDebugFile: $.noop
};

/** @class */
jscape.domain.OftpSendCertificateController = Class.extend(
    /** @lends {jscape.domain.OftpSendCertificateController.prototype} */
{
    PROTOCOLS: ["OFTP"],
    DEFAULT_TYPE: "REQUEST",

    deferred: null,

    start: function(managementService, domainName) {
        this.managementService = managementService;
        this.domainName = domainName;
        this.deferred = $.Deferred();
        $.when(this.managementService.getTradingPartnerNames(this.domainName, this.PROTOCOLS),
               this.managementService.getServerKeys())
                .done($.proxy(function (partnerNames, serverKeys) {
                          if (partnerNames.length) {
                              partnerNames = partnerNames.sort(function(a, b) { return a.toUpperCase() > b.toUpperCase(); });
                              serverKeys = $.map(serverKeys, function(key) { return key.name; });
                              this._setupDialog(partnerNames, serverKeys).show(this);
                          } else {
                              this._showNoPartnersError();
                              this.deferred.reject();
                              this.deferred = null;
                          }
                      }, this))
                .fail($.proxy(function () {
                          this._showNoPartnersError();
                          this.deferred.reject();
                          this.deferred = null;
                      }, this));
        return this.deferred.promise();
    },

    onSubmit: function (dialog) {
        var partnerName = dialog.getPartner();
        var data = this._createData(dialog);
        dialog.destroy();

        return this.managementService.sendOftpPartnerCertificate(this.domainName, partnerName, data)
                .done($.proxy(function () { this.deferred.resolve(); this.deferred = null; }, this))
                .fail($.proxy(function () { this.deferred.reject(); this.deferred = null; }, this));
    },

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

    onSelectDebugFile: function (dialog) {
        new SelectPathController($.proxy(this.managementService.listDebugDir, this.managementService),
                                 $.proxy(this.managementService.createDebugDir, this.managementService))
                .selectFile()
                .done($.proxy(function (entry) { dialog.setDebugFile(entry.path); }, this));
    },

    _createData: function(dialog) {
        return new jscape.OftpSendCertidicateData(dialog.getCertificate(),
                                                  dialog.getType(),
                                                  dialog.getDestinationPartner(),
                                                  dialog.isPlaceToOutbox(),
                                                  dialog.getDebugFile());
    },

    _setupDialog: function(partners, certificates) {
        var dialog = new jscape.domain.OftpSendCertificateDialog();
        dialog.setPartners(partners);
        dialog.setDestinationPartners(partners);
        dialog.setCertificates(certificates);
        dialog.setType(this.DEFAULT_TYPE);
        return dialog;
    },

    _showNoPartnersError: function () {
        $.messager.alert(window.R.string.APPLICATION_ERROR_TITLE,
                         window.R.string.OFTP_MESSAGES_ERROR_NO_PARTNERS,
                         "warning");
    }
});

/** @class */
jscape.domain.OftpSendCertificateDialog = Class.extend(
    /** @lends {jscape.domain.OftpSendCertificateDialog.prototype} */
{
    /** @constructor */
    initialize: function() {
        this.dialog = $("#d-oftp-sendcert").clone().attr("id", "");
        this.dialog.dialog({
            width: 600, 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=oftpsendcertificatefields]", this.dialog);

        this.partner = $("select[name=partner]", this.fieldset).combobox({required: true, editable: false, width: 210, panelHeight: "auto"});
        this.destinationPartner = $("select[name=destinationpartner]", this.fieldset).combobox({required: true, editable: false, width: 210, panelHeight: "auto"});
        this.certificate = $("select[name=certificate]", this.fieldset).combobox({required: true, editable: false, width: 210, panelHeight: "auto"});
        this.type = $("select[name=type]", this.fieldset).combobox({required: true, editable: false, width: 210, panelHeight: "auto"});
        this.placeToOutbox = $("input[name=placetooutbox]:checkbox", this.fieldset);
        this.debugFile = $("input[name=debugfile]", this.fieldset).textbox({width: "70%"});
        this.browseDebugFileButton = $("a[role=button][name=browsedebugfile]", this.fieldset).linkbutton({onClick: $.proxy(this._onClick$BrowseDebugFileButton, this)});
    },

    getPartner: function() {
        return this.partner.combobox("getValue");
    },

    setPartners: function(values) {
        this.partner.combobox("loadData", values);
    },

    getDestinationPartner: function() {
        return this.destinationPartner.combobox("getValue");
    },

    setDestinationPartners: function(values) {
        this.destinationPartner.combobox("loadData", values);
    },

    getCertificate: function() {
        return this.certificate.combobox("getValue");
    },

    setCertificates: function(values) {
        this.certificate.combobox("loadData", values);
    },

    getType: function() {
        return this.type.combobox("getValue");
    },

    setType: function(value) {
        this.type.combobox("select", value);
    },

    isPlaceToOutbox: function() {
        return this.placeToOutbox.is(":checked");
    },

    getDebugFile: function() {
        return this.debugFile.textbox("getValue");
    },

    setDebugFile: function(value) {
        this.debugFile.textbox("setValue", value);
    },

    show: function (listener) {
        this.listener = listener || jscape.domain.OftpSendCertificateDialog.LISTENER;
        this.dialog.dialog("center").dialog("open");
        this.fieldset.form("validate");
        this.fieldset.find("input:first").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");
    },

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

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

    _onClick$BrowseDebugFileButton: function() {
        this.listener.onSelectDebugFile(this);
    },

    _closed: function () {
        return !!this.dialog.dialog("options").closed;
    }
});
jscape.domain.OftpSendCertificateDialog.LISTENER = {
    onSelectDebugFile: $.noop
};

/** @class */
jscape.domain.OftpResendMessageController = Class.extend(
    /** @lends {jscape.domain.OftpResendMessageController.prototype} */
{
    start: function(managementService, domainName, message) {
        var deferred = $.Deferred();
        this._confirmResend(message)
                .then(function () { return managementService.resendOftpMessage(domainName, message.id); })
                .done(function () { deferred.resolve(); deferred = null; })
                .fail(function () { deferred.reject(); deferred = null; });
        return deferred.promise();
    },

    _confirmResend: function(message) {
        var deferred = $.Deferred();
        var win = $.messager.confirm(window.R.string.OFTP_MESSAGES_CONFIRM_RESEND_TITLE,
                                     window.R.string.OFTP_MESSAGES_CONFIRM_RESEND_MESSAGE.supplant({0: message.id}),
                                     function(confirmed) { if (confirmed) { deferred.resolve(); } else { deferred.reject(); }});
        win.window("resize", {width: 470}).window("center");
        return deferred.promise();
    }
});

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

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

    onSubmit: function(dialog) {
        dialog.destroy();
        this.deferred.resolve();
        this.deferred = null;
    },

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

    _setupDialog: function (message) {
        var dialog = new jscape.domain.OftpMessageViewDialog();
        dialog.setTitle(jscape.OftpMessage.Type.REQUEST == message.type
                        ? window.R.string.OFTP_MESSAGES_VIEW_DIALOG_TITLE_REQUEST
                        : window.R.string.OFTP_MESSAGES_VIEW_DIALOG_TITLE_RECEIPT);
        this.managementService.getOftpMessageRecordView(this.domainName, message.id)
                .done($.proxy(function (data) { dialog.setRecord(data); }, this))
                .fail($.proxy(function () { this.deferred.reject(); this.deferred = null; }, this));
        return dialog;
    }
});

/** @class */
jscape.domain.OftpMessageViewDialog = Class.extend(
    /** @lends {jscape.domain.OftpMessageViewDialog.prototype} */
{
    /** @constructor */
    initialize: function() {
        this.dialog = $("#oftp-viewrecord").clone().attr("id", "");
        this.dialog.dialog({
            width: 700, height: "auto",
            modal: true, resizable: false, closable: true, closed: true,
            buttons: [
                {text: window.R.string.DIALOG_BUTTON_CLOSE || "Close", handler: $.proxy(this._onCancel, this)}
            ],
            onClose: $.proxy(function () {if (!this.closing) { this._onCancel(); }}, this)
        }).show();

        this.data = $("table[role=grid][aria-label=oftpmessagerecord]", this.dialog);
        this.data.propertygrid({height: 500});
    },

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

    setRecord: function(record) {
        var data = $.map(record || {}, function(value, key) { return {name: key, value: value}; });
        this.data.propertygrid("loading").propertygrid("loadData", data).propertygrid("loaded");
    },

    show: function (listener) {
        this.listener = listener || jscape.domain.OftpMessageViewDialog.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");
    },

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

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

    _closed: function () {
        return !!this.dialog.dialog("options").closed;
    }
});
jscape.domain.OftpMessageViewDialog.LISTENER = {};


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

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

    _confirmDelete: function(messages) {
        return jscape.ConfirmDialog.confirm(
                window.R.string.OFTP_MESSAGES_CONFIRM_DELETE_TITLE,
                window.R.string.OFTP_MESSAGES_CONFIRM_DELETE_MESSAGE);
    },

    _deleteConfirmed: function(messages) {
        $.when.apply(jQuery, $.map(messages, $.proxy(function(message) { return this.managementService.deleteOftpMessage(this.domainName, message.id); }, this)))
                .done($.proxy(function() { this.deferred.resolve(messages); this.deferred = null; }, this))
                .fail($.proxy(function() { this.deferred.reject(); this.deferred = null; }, this));
    }
});
