"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.AdaptableNumberEditor = exports.AdaptableReactNumberEditor = exports.getStartValue = void 0;
const tslib_1 = require("tslib");
const React = tslib_1.__importStar(require("react"));
const renderWithAdaptableContext_1 = require("../../../View/renderWithAdaptableContext");
const InternalAdaptableNumberEditor_1 = require("./InternalAdaptableNumberEditor");
const core_1 = require("ag-grid-community");
const react_1 = require("react");
function shouldClearExistingValue(params) {
    return params.eventKey === core_1.KeyCode.BACKSPACE || params.eventKey === core_1.KeyCode.DELETE;
}
function isValidChar(char) {
    // allow only digits
    return ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'].includes(char);
    // we do NOT allow key shortcuts for starting non-digits (minus sign, decimal separators) as the input[number] handling is very buggy and we would open a can of worms
}
function getStartValue(params) {
    if (shouldClearExistingValue(params)) {
        return '';
    }
    if (params.eventKey && isValidChar(params.eventKey)) {
        return Number(params.eventKey);
    }
    return params.value;
}
exports.getStartValue = getStartValue;
const defaultValueParser = ({ newValue, oldValue: _ }) => {
    return newValue;
};
const style = {
    position: 'absolute',
    top: '0px',
    left: '0px',
    right: '0px',
    bottom: '0px',
};
exports.AdaptableReactNumberEditor = (0, react_1.forwardRef)((props, ref) => {
    var _a, _b;
    const [initialValue] = (0, react_1.useState)(() => getStartValue(props));
    const valueRef = (0, react_1.useRef)(initialValue);
    const columnId = props.column.getColId();
    const adaptable = props.context.__adaptable;
    const colValueParser = props.column.getColDef().valueParser;
    const valueParser = typeof colValueParser === 'function' ? colValueParser : defaultValueParser;
    function onValueChange(value) {
        var _a;
        value = valueParser
            ? valueParser(Object.assign(Object.assign({}, props), { oldValue: props.value, newValue: value }))
            : value;
        valueRef.current = value;
        (_a = props.onValueChange) === null || _a === void 0 ? void 0 : _a.call(props, value);
    }
    const editorRef = (0, react_1.useRef)(null);
    (0, react_1.useImperativeHandle)(ref, () => {
        return {
            focusIn() {
                var _a;
                (_a = editorRef.current) === null || _a === void 0 ? void 0 : _a.focus();
            },
            // the final value to send to the grid, on completion of editing
            getValue() {
                return valueRef.current;
            },
        };
    });
    const editorElement = (React.createElement(InternalAdaptableNumberEditor_1.InternalAdaptableNumberEditor, { defaultValue: initialValue, showClearButton: (_a = props.showClearButton) !== null && _a !== void 0 ? _a : true, emptyValue: (_b = props.emptyValue) !== null && _b !== void 0 ? _b : '', onValueChange: onValueChange, ref: (editor) => {
            editorRef.current = editor;
            editor === null || editor === void 0 ? void 0 : editor.focus();
        } }));
    function onKeyDown(keyDownEvent) {
        adaptable._emit('CellEditorKeyDown', {
            keyDownEvent,
            cellValue: valueRef.current,
            columnId,
            updateValueCallback: (updatedValue) => {
                editorRef.current.setValue(updatedValue);
            },
        });
    }
    return (React.createElement("div", { style: style, onKeyDown: onKeyDown }, (0, renderWithAdaptableContext_1.renderWithAdaptableContext)(editorElement, adaptable)));
});
exports.AdaptableReactNumberEditor.displayName = 'AdaptableReactNumberEditor';
/**
 * Number Editor provided by AdapTable and used by default for all `abColDefNumber` columns
 */
class AdaptableNumberEditor {
    constructor() {
        this.valueParser = defaultValueParser;
        this.onValueChange = (value) => {
            this.value = this.valueParser
                ? this.valueParser(Object.assign(Object.assign({}, this.params), { oldValue: this.params.value, newValue: value }))
                : value;
        };
    }
    init(params) {
        this.value = getStartValue(params);
        this.params = params;
        this.columnId = params.column.getColId();
        const { valueParser } = params.column.getColDef();
        if (typeof valueParser === 'function') {
            this.valueParser = valueParser;
        }
        this.el = document.createElement('div');
        Object.keys(style).forEach((key) => {
            //@ts-ignore
            this.el.style[key] = style[key];
        });
    }
    /* Component Editor Lifecycle methods */
    // gets called once when grid ready to insert the element
    getGui() {
        return this.el;
    }
    // the final value to send to the grid, on completion of editing
    getValue() {
        return this.value;
    }
    focusIn() {
        var _a;
        (_a = this.editor) === null || _a === void 0 ? void 0 : _a.focus();
    }
    focusOut() { }
    // after this component has been created and inserted into the grid
    afterGuiAttached() {
        var _a, _b;
        const adaptable = this.params.context.__adaptable;
        const defaultValue = this.value;
        const editorElement = (React.createElement(InternalAdaptableNumberEditor_1.InternalAdaptableNumberEditor, { defaultValue: defaultValue, showClearButton: (_a = this.params.showClearButton) !== null && _a !== void 0 ? _a : true, emptyValue: (_b = this.params.emptyValue) !== null && _b !== void 0 ? _b : '', onValueChange: this.onValueChange, ref: (editor) => {
                this.editor = editor;
                editor === null || editor === void 0 ? void 0 : editor.focus();
            } }));
        this.unmountReactRoot = adaptable.renderReactRoot((0, renderWithAdaptableContext_1.renderWithAdaptableContext)(editorElement, adaptable), this.el);
        this.getGui().addEventListener('keydown', (keyDownEvent) => {
            adaptable._emit('CellEditorKeyDown', {
                keyDownEvent,
                cellValue: this.value,
                columnId: this.columnId,
                updateValueCallback: (updatedValue) => {
                    this.editor.setValue(updatedValue);
                },
            });
        });
    }
    destroy() {
        var _a;
        (_a = this.unmountReactRoot) === null || _a === void 0 ? void 0 : _a.call(this);
    }
}
exports.AdaptableNumberEditor = AdaptableNumberEditor;
