import { __assign, __decorate, __extends, __metadata } from "tslib";
import { Component, Prop, Watch } from 'vue-property-decorator';
import { Icon } from '../Icon';
import BaseComponent from '../BaseComponent';
import { IconButton } from '../Button/IconButton/IconButton';
import { Position } from '../../utilities/positioning';
import { calculatePrecision, classNamesFunction, precisionRound, } from '@uifabric-vue/utilities';
import { getArrowButtonStyles } from './SpinButton.styles';
export var KeyboardSpinDirection;
(function (KeyboardSpinDirection) {
    KeyboardSpinDirection[KeyboardSpinDirection["down"] = -1] = "down";
    KeyboardSpinDirection[KeyboardSpinDirection["notSpinning"] = 0] = "notSpinning";
    KeyboardSpinDirection[KeyboardSpinDirection["up"] = 1] = "up";
})(KeyboardSpinDirection || (KeyboardSpinDirection = {}));
var getClassNames = classNamesFunction();
var SpinButtonBase = /** @class */ (function (_super) {
    __extends(SpinButtonBase, _super);
    function SpinButtonBase() {
        var _this = _super !== null && _super.apply(this, arguments) || this;
        _this.Position = Position;
        _this.getArrowButtonStyles = getArrowButtonStyles;
        _this.customUpArrowButtonStyles = {};
        _this.customDownArrowButtonStyles = {};
        _this.internalValue = _this.value || _this.defaultValue;
        _this.INITIAL_STEP_DELAY = 400;
        _this.STEP_DELAY = 75;
        _this.isFocused = false;
        _this.keyboardSpinDirection = KeyboardSpinDirection.notSpinning;
        return _this;
    }
    Object.defineProperty(SpinButtonBase.prototype, "classNames", {
        get: function () {
            var _a = this, theme = _a.theme, styles = _a.styles, className = _a.className, disabled = _a.disabled, isFocused = _a.isFocused, keyboardSpinDirection = _a.keyboardSpinDirection, labelPosition = _a.labelPosition;
            return getClassNames(styles, {
                theme: theme,
                disabled: disabled,
                isFocused: isFocused,
                keyboardSpinDirection: keyboardSpinDirection,
                labelPosition: labelPosition,
                className: className,
            });
        },
        enumerable: false,
        configurable: true
    });
    SpinButtonBase.prototype.onValueChanged = function (value) {
        this.$emit('input', value);
    };
    SpinButtonBase.prototype.updateValue = function (value) {
        var newValue = precisionRound(value, this.precision);
        this.internalValue = newValue;
        return newValue;
    };
    SpinButtonBase.prototype.onIncrement = function () {
        var newValue = Math.min(this.internalValue + this.step, this.max);
        return this.updateValue(newValue);
    };
    SpinButtonBase.prototype.onDecrement = function () {
        var newValue = Math.max(this.internalValue - this.step, this.min);
        return this.updateValue(newValue);
    };
    SpinButtonBase.prototype.startSpin = function (dir) {
        var _this = this;
        var newValue = dir === 1 ? this.onIncrement() : this.onDecrement();
        newValue = precisionRound(newValue, this.precision);
        this.internalValue = newValue;
        this.timeout = setTimeout(function () {
            _this.interval = setInterval(function () {
                var newValue = dir === 1 ? _this.onIncrement() : _this.onDecrement();
                newValue = precisionRound(newValue, _this.precision);
                _this.internalValue = newValue;
            }, _this.STEP_DELAY);
        }, this.INITIAL_STEP_DELAY);
    };
    Object.defineProperty(SpinButtonBase.prototype, "precision", {
        get: function () {
            var precision = Math.max(calculatePrecision(this.step), 0);
            return precision;
        },
        enumerable: false,
        configurable: true
    });
    SpinButtonBase.prototype.stopSpin = function () {
        clearTimeout(this.timeout);
        clearInterval(this.interval);
    };
    SpinButtonBase.prototype.render = function (h) {
        var _this = this;
        var _a = this, theme = _a.theme, customUpArrowButtonStyles = _a.customUpArrowButtonStyles, customDownArrowButtonStyles = _a.customDownArrowButtonStyles, classNames = _a.classNames, labelPosition = _a.labelPosition, iconProps = _a.iconProps, label = _a.label, internalValue = _a.internalValue;
        var $label = h('div', { class: classNames.labelWrapper }, [
            iconProps && h(Icon, {
                class: classNames.icon,
                props: __assign({}, iconProps),
            }),
            h('Label', {
                class: classNames.label,
                attrs: {
                    for: "SpinButton".concat(this.uid),
                },
            }, label),
        ]);
        var $spinButtonWrapper = h('div', { class: classNames.spinButtonWrapper }, [
            h('input', {
                class: classNames.input,
                attrs: {
                    id: "SpinButton".concat(this.uid),
                    value: internalValue,
                    type: 'text',
                    role: 'spinbutton',
                },
                on: {
                    focus: function () { return (_this.isFocused = true); },
                    blur: function () { return (_this.isFocused = false); },
                    onput: function (ev) { return (_this.internalValue = +(ev.target.value || 0)); },
                },
            }),
            h('span', { class: classNames.arrowBox }, [
                h(IconButton, {
                    staticClass: 'ms-UpButton',
                    props: {
                        styles: getArrowButtonStyles(theme, true, customUpArrowButtonStyles),
                        iconProps: { iconName: 'ChevronUpSmall' },
                    },
                    nativeOn: {
                        mousedown: function () { return _this.startSpin(1); },
                        mouseup: function () { return _this.stopSpin(); },
                    },
                }),
                h(IconButton, {
                    staticClass: 'ms-DownButton',
                    props: {
                        styles: getArrowButtonStyles(theme, false, customDownArrowButtonStyles),
                        iconProps: { iconName: 'ChevronDownSmall' },
                    },
                    nativeOn: {
                        mousedown: function () { return _this.startSpin(-1); },
                        mouseup: function () { return _this.stopSpin(); },
                    },
                }),
            ]),
        ]);
        return h('div', { class: classNames.root }, [
            (labelPosition !== Position.bottom && (iconProps || label)) && $label,
            $spinButtonWrapper,
            (labelPosition === Position.bottom && (iconProps || label)) && $label,
        ]);
    };
    __decorate([
        Prop({ type: Boolean, default: false }),
        __metadata("design:type", Boolean)
    ], SpinButtonBase.prototype, "disabled", void 0);
    __decorate([
        Prop({ type: Boolean, default: false }),
        __metadata("design:type", Boolean)
    ], SpinButtonBase.prototype, "required", void 0);
    __decorate([
        Prop({ type: Number, default: 0 }),
        __metadata("design:type", Number)
    ], SpinButtonBase.prototype, "defaultValue", void 0);
    __decorate([
        Prop({ type: Number, default: null }),
        __metadata("design:type", Number)
    ], SpinButtonBase.prototype, "value", void 0);
    __decorate([
        Prop({ type: String, default: null }),
        __metadata("design:type", String)
    ], SpinButtonBase.prototype, "label", void 0);
    __decorate([
        Prop({ type: Number, default: Position.start }),
        __metadata("design:type", Number)
    ], SpinButtonBase.prototype, "labelPosition", void 0);
    __decorate([
        Prop({ type: Number, default: 0 }),
        __metadata("design:type", Number)
    ], SpinButtonBase.prototype, "min", void 0);
    __decorate([
        Prop({ type: Number, default: 10 }),
        __metadata("design:type", Number)
    ], SpinButtonBase.prototype, "max", void 0);
    __decorate([
        Prop({ type: Number, default: 1 }),
        __metadata("design:type", Number)
    ], SpinButtonBase.prototype, "step", void 0);
    __decorate([
        Prop({ type: Object, default: function () { } }),
        __metadata("design:type", Object)
    ], SpinButtonBase.prototype, "iconProps", void 0);
    __decorate([
        Watch('internalValue'),
        __metadata("design:type", Function),
        __metadata("design:paramtypes", [String]),
        __metadata("design:returntype", void 0)
    ], SpinButtonBase.prototype, "onValueChanged", null);
    SpinButtonBase = __decorate([
        Component
    ], SpinButtonBase);
    return SpinButtonBase;
}(BaseComponent));
export { SpinButtonBase };
//# sourceMappingURL=SpinButton.base.js.map