// Copyright (c) Jupyter Development Team.
// Distributed under the terms of the Modified BSD License.
import { Widget } from '@lumino/widgets';
import { Dialog, showDialog } from './dialog';
import { Styling } from './styling';
const INPUT_DIALOG_CLASS = 'jp-Input-Dialog';
const INPUT_BOOLEAN_DIALOG_CLASS = 'jp-Input-Boolean-Dialog';
/**
 * Namespace for input dialogs
 */
export var InputDialog;
(function (InputDialog) {
    /**
     * Create and show a input dialog for a boolean.
     *
     * @param options - The dialog setup options.
     *
     * @returns A promise that resolves with whether the dialog was accepted
     */
    function getBoolean(options) {
        return showDialog(Object.assign(Object.assign({}, options), { body: new InputBooleanDialog(options), buttons: [
                Dialog.cancelButton({ label: options.cancelLabel }),
                Dialog.okButton({ label: options.okLabel })
            ], focusNodeSelector: 'input' }));
    }
    InputDialog.getBoolean = getBoolean;
    /**
     * Create and show a input dialog for a number.
     *
     * @param options - The dialog setup options.
     *
     * @returns A promise that resolves with whether the dialog was accepted
     */
    function getNumber(options) {
        return showDialog(Object.assign(Object.assign({}, options), { body: new InputNumberDialog(options), buttons: [
                Dialog.cancelButton({ label: options.cancelLabel }),
                Dialog.okButton({ label: options.okLabel })
            ], focusNodeSelector: 'input' }));
    }
    InputDialog.getNumber = getNumber;
    /**
     * Create and show a input dialog for a choice.
     *
     * @param options - The dialog setup options.
     *
     * @returns A promise that resolves with whether the dialog was accepted
     */
    function getItem(options) {
        return showDialog(Object.assign(Object.assign({}, options), { body: new InputItemsDialog(options), buttons: [
                Dialog.cancelButton({ label: options.cancelLabel }),
                Dialog.okButton({ label: options.okLabel })
            ], focusNodeSelector: options.editable ? 'input' : 'select' }));
    }
    InputDialog.getItem = getItem;
    /**
     * Create and show a input dialog for a text.
     *
     * @param options - The dialog setup options.
     *
     * @returns A promise that resolves with whether the dialog was accepted
     */
    function getText(options) {
        return showDialog(Object.assign(Object.assign({}, options), { body: new InputTextDialog(options), buttons: [
                Dialog.cancelButton({ label: options.cancelLabel }),
                Dialog.okButton({ label: options.okLabel })
            ], focusNodeSelector: 'input' }));
    }
    InputDialog.getText = getText;
    /**
     * Create and show a input dialog for a password.
     *
     * @param options - The dialog setup options.
     *
     * @returns A promise that resolves with whether the dialog was accepted
     */
    function getPassword(options) {
        return showDialog(Object.assign(Object.assign({}, options), { body: new InputPasswordDialog(options), buttons: [
                Dialog.cancelButton({ label: options.cancelLabel }),
                Dialog.okButton({ label: options.okLabel })
            ], focusNodeSelector: 'input' }));
    }
    InputDialog.getPassword = getPassword;
})(InputDialog || (InputDialog = {}));
/**
 * Base widget for input dialog body
 */
class InputDialogBase extends Widget {
    /**
     * InputDialog constructor
     *
     * @param label Input field label
     */
    constructor(label) {
        super();
        this.addClass(INPUT_DIALOG_CLASS);
        this._input = document.createElement('input');
        this._input.classList.add('jp-mod-styled');
        this._input.id = 'jp-dialog-input-id';
        if (label !== undefined) {
            const labelElement = document.createElement('label');
            labelElement.textContent = label;
            labelElement.htmlFor = this._input.id;
            // Initialize the node
            this.node.appendChild(labelElement);
        }
        this.node.appendChild(this._input);
    }
}
/**
 * Widget body for input boolean dialog
 */
class InputBooleanDialog extends InputDialogBase {
    /**
     * InputBooleanDialog constructor
     *
     * @param options Constructor options
     */
    constructor(options) {
        super(options.label);
        this.addClass(INPUT_BOOLEAN_DIALOG_CLASS);
        this._input.type = 'checkbox';
        this._input.checked = options.value ? true : false;
    }
    /**
     * Get the text specified by the user
     */
    getValue() {
        return this._input.checked;
    }
}
/**
 * Widget body for input number dialog
 */
class InputNumberDialog extends InputDialogBase {
    /**
     * InputNumberDialog constructor
     *
     * @param options Constructor options
     */
    constructor(options) {
        super(options.label);
        this._input.type = 'number';
        this._input.value = options.value ? options.value.toString() : '0';
    }
    /**
     * Get the number specified by the user.
     */
    getValue() {
        if (this._input.value) {
            return Number(this._input.value);
        }
        else {
            return Number.NaN;
        }
    }
}
/**
 * Widget body for input text dialog
 */
class InputTextDialog extends InputDialogBase {
    /**
     * InputTextDialog constructor
     *
     * @param options Constructor options
     */
    constructor(options) {
        var _a;
        super(options.label);
        this._input.type = 'text';
        this._input.value = options.text ? options.text : '';
        if (options.placeholder) {
            this._input.placeholder = options.placeholder;
        }
        this._initialSelectionRange = Math.min(this._input.value.length, Math.max(0, (_a = options.selectionRange) !== null && _a !== void 0 ? _a : this._input.value.length));
    }
    /**
     *  A message handler invoked on an `'after-attach'` message.
     */
    onAfterAttach(msg) {
        super.onAfterAttach(msg);
        if (this._initialSelectionRange > 0 && this._input.value) {
            this._input.setSelectionRange(0, this._initialSelectionRange);
        }
    }
    /**
     * Get the text specified by the user
     */
    getValue() {
        return this._input.value;
    }
}
/**
 * Widget body for input password dialog
 */
class InputPasswordDialog extends InputDialogBase {
    /**
     * InputPasswordDialog constructor
     *
     * @param options Constructor options
     */
    constructor(options) {
        super(options.label);
        this._input.type = 'password';
        this._input.value = options.text ? options.text : '';
        if (options.placeholder) {
            this._input.placeholder = options.placeholder;
        }
    }
    /**
     *  A message handler invoked on an `'after-attach'` message.
     */
    onAfterAttach(msg) {
        super.onAfterAttach(msg);
        if (this._input.value) {
            this._input.select();
        }
    }
    /**
     * Get the text specified by the user
     */
    getValue() {
        return this._input.value;
    }
}
/**
 * Widget body for input list dialog
 */
class InputItemsDialog extends InputDialogBase {
    /**
     * InputItemsDialog constructor
     *
     * @param options Constructor options
     */
    constructor(options) {
        super(options.label);
        this._editable = options.editable || false;
        let current = options.current || 0;
        let defaultIndex;
        if (typeof current === 'number') {
            defaultIndex = Math.max(0, Math.min(current, options.items.length - 1));
            current = '';
        }
        this._list = document.createElement('select');
        options.items.forEach((item, index) => {
            const option = document.createElement('option');
            if (index === defaultIndex) {
                option.selected = true;
                current = item;
            }
            option.value = item;
            option.textContent = item;
            this._list.appendChild(option);
        });
        if (options.editable) {
            /* Use of list and datalist */
            const data = document.createElement('datalist');
            data.id = 'input-dialog-items';
            data.appendChild(this._list);
            this._input.type = 'list';
            this._input.value = current;
            this._input.setAttribute('list', data.id);
            if (options.placeholder) {
                this._input.placeholder = options.placeholder;
            }
            this.node.appendChild(data);
        }
        else {
            /* Use select directly */
            this._input.remove();
            this.node.appendChild(Styling.wrapSelect(this._list));
        }
    }
    /**
     * Get the user choice
     */
    getValue() {
        if (this._editable) {
            return this._input.value;
        }
        else {
            return this._list.value;
        }
    }
}
//# sourceMappingURL=inputdialog.js.map