var _a;
import { __awaiter, __decorate, __extends, __generator } from "tslib";
import { Component, Emit, Prop, Watch } from 'vue-property-decorator';
import { ElementQueries } from '../../mixins/element-queries/element-queries';
import { Enums } from '../../utils/enums/enums';
import { REGEX_CSS_NUMBER_VALUE } from '../../utils/props-validation/props-validation';
import { ModulVue } from '../../utils/vue/vue';
import { AUTO_HORIZONTAL_SCROLL, ICON_BUTTON_NAME } from '../component-names';
import { MIconButton, MIconButtonSkin } from '../icon-button/icon-button';
import WithRender from './auto-horizontal-scroll.html?style=./auto-horizontal-scroll.scss';
export var MAutoHorizontalScrollGradientBackgroundStyle;
(function (MAutoHorizontalScrollGradientBackgroundStyle) {
    MAutoHorizontalScrollGradientBackgroundStyle["White"] = "white";
    MAutoHorizontalScrollGradientBackgroundStyle["Light"] = "light";
    MAutoHorizontalScrollGradientBackgroundStyle["Dark"] = "dark";
    MAutoHorizontalScrollGradientBackgroundStyle["Interactive"] = "interactive";
})(MAutoHorizontalScrollGradientBackgroundStyle || (MAutoHorizontalScrollGradientBackgroundStyle = {}));
var MAutoHorizontalScroll = /** @class */ (function (_super) {
    __extends(MAutoHorizontalScroll, _super);
    function MAutoHorizontalScroll() {
        var _this = _super !== null && _super.apply(this, arguments) || this;
        _this.hasHorizontalScroll = false;
        _this.couldHaveLeftContent = false;
        _this.couldHaveRightContent = false;
        _this.componentWidth = '';
        _this.componentHeight = '';
        _this.scrollLeftCounter = 0;
        _this.scrollAnimationActive = false;
        _this.isDragging = false;
        _this.startXDragging = 0;
        _this.scrollLeftDragging = 0;
        _this.observer = new MutationObserver(function () {
            _this.resizeComponent();
        });
        return _this;
    }
    MAutoHorizontalScroll.prototype.emitResize = function (resizeProperties) { };
    MAutoHorizontalScroll.prototype.emitUpdateHorizontalScrollOffset = function (horizontalScrollOffset) { };
    MAutoHorizontalScroll.prototype.emitPreviousButtonClick = function (event) { };
    MAutoHorizontalScroll.prototype.emitNextButtonClick = function (event) { };
    MAutoHorizontalScroll.prototype.onLeftGradientActiveChange = function () {
        this.checkGradientPresence();
    };
    MAutoHorizontalScroll.prototype.onDisplayHorizontalScrollbarChange = function () {
        this.resizeComponent();
    };
    MAutoHorizontalScroll.prototype.onHorizontalScrollOffsetChange = function () {
        return __awaiter(this, void 0, void 0, function () {
            var maxScrollLeft;
            return __generator(this, function (_a) {
                switch (_a.label) {
                    case 0: return [4 /*yield*/, this.$nextTick()];
                    case 1:
                        _a.sent();
                        maxScrollLeft = this.$refs.bodyContent.scrollWidth - this.$refs.body.clientWidth;
                        if (this.scrollAnimationActive) {
                            this.stopScrollAnimation();
                            return [2 /*return*/];
                        }
                        else if (this.horizontalScrollOffset < 0) {
                            this.emitUpdateHorizontalScrollOffset(0);
                            return [2 /*return*/];
                        }
                        else if (this.horizontalScrollOffset > maxScrollLeft) {
                            this.emitUpdateHorizontalScrollOffset(maxScrollLeft - 0.5);
                            return [2 /*return*/];
                        }
                        if (this.$refs.body &&
                            this.horizontalScrollOffset !== this.$refs.body.scrollLeft) {
                            if (this.scrollLeftCounter <= 0) {
                                this.$refs.body.scrollLeft = this.horizontalScrollOffset;
                            }
                            else {
                                this.startScrollAnimation();
                            }
                        }
                        this.scrollLeftCounter++;
                        return [2 /*return*/];
                }
            });
        });
    };
    MAutoHorizontalScroll.prototype.onRightGradientActiveChange = function () {
        this.checkGradientPresence();
    };
    Object.defineProperty(MAutoHorizontalScroll.prototype, "hasLeftGradient", {
        get: function () {
            return this.leftGradientActive && this.couldHaveLeftContent;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(MAutoHorizontalScroll.prototype, "hasRightGradient", {
        get: function () {
            return this.rightGradientActive && this.couldHaveRightContent;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(MAutoHorizontalScroll.prototype, "hasPreviousButton", {
        get: function () {
            return this.previousButtonActive && this.couldHaveLeftContent;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(MAutoHorizontalScroll.prototype, "hasNextButton", {
        get: function () {
            return this.nextButtonActive && this.couldHaveRightContent;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(MAutoHorizontalScroll.prototype, "isGradientBackgroundStyleWhite", {
        get: function () {
            return (this.gradientBackgroundStyle ===
                MAutoHorizontalScrollGradientBackgroundStyle.White);
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(MAutoHorizontalScroll.prototype, "isGradientBackgroundStyleLight", {
        get: function () {
            return (this.gradientBackgroundStyle ===
                MAutoHorizontalScrollGradientBackgroundStyle.Light);
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(MAutoHorizontalScroll.prototype, "isGradientBackgroundStyleDark", {
        get: function () {
            return (this.gradientBackgroundStyle ===
                MAutoHorizontalScrollGradientBackgroundStyle.Dark);
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(MAutoHorizontalScroll.prototype, "isGradientBackgroundStyleInteractive", {
        get: function () {
            return (this.gradientBackgroundStyle ===
                MAutoHorizontalScrollGradientBackgroundStyle.Interactive);
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(MAutoHorizontalScroll.prototype, "iconButtonSkin", {
        get: function () {
            return this.isGradientBackgroundStyleDark || this.isGradientBackgroundStyleInteractive
                ? MIconButtonSkin.Dark
                : MIconButtonSkin.Light;
        },
        enumerable: true,
        configurable: true
    });
    MAutoHorizontalScroll.prototype.startScrollAnimation = function () {
        return __awaiter(this, void 0, void 0, function () {
            var initialScrollLeft, difference, intervalDelay, increment, isPositiveIncrement, counter;
            var _this = this;
            return __generator(this, function (_a) {
                switch (_a.label) {
                    case 0: return [4 /*yield*/, this.$nextTick()];
                    case 1:
                        _a.sent();
                        initialScrollLeft = this.$refs.body.scrollLeft;
                        difference = this.horizontalScrollOffset - initialScrollLeft <=
                            this.$refs.body.scrollWidth
                            ? this.horizontalScrollOffset - initialScrollLeft
                            : this.$refs.body.scrollWidth;
                        intervalDelay = difference > 500 ? 7 : 10;
                        increment = difference / intervalDelay;
                        isPositiveIncrement = increment > 0;
                        counter = 0;
                        this.scrollAnimationActive = true;
                        this.scrollAnimationInterval = setInterval(function () {
                            counter += intervalDelay;
                            if ((isPositiveIncrement &&
                                _this.$refs.body.scrollLeft >= _this.horizontalScrollOffset) ||
                                (!isPositiveIncrement &&
                                    _this.$refs.body.scrollLeft <= _this.horizontalScrollOffset) ||
                                counter >= 5000) {
                                _this.stopScrollAnimation();
                            }
                            else {
                                _this.$refs.body.scrollLeft += increment;
                            }
                        }, intervalDelay);
                        return [2 /*return*/];
                }
            });
        });
    };
    MAutoHorizontalScroll.prototype.stopScrollAnimation = function () {
        window.clearInterval(this.scrollAnimationInterval);
        this.scrollAnimationActive = false;
        this.onScroll();
    };
    MAutoHorizontalScroll.prototype.onScroll = function () {
        return __awaiter(this, void 0, void 0, function () {
            var bodyEl;
            return __generator(this, function (_a) {
                switch (_a.label) {
                    case 0:
                        bodyEl = this.$refs.body;
                        if (bodyEl && bodyEl.scrollLeft >= 0 && !this.scrollAnimationActive) {
                            this.emitUpdateHorizontalScrollOffset(bodyEl.scrollLeft);
                        }
                        return [4 /*yield*/, this.checkGradientPresence()];
                    case 1:
                        _a.sent();
                        return [2 /*return*/];
                }
            });
        });
    };
    MAutoHorizontalScroll.prototype.onMousedown = function (e) {
        this.isDragging = this.dragActive;
        this.startXDragging = e.pageX - this.$refs.body.offsetLeft;
        this.scrollLeftDragging = this.$refs.body.scrollLeft;
    };
    MAutoHorizontalScroll.prototype.onMouseleave = function () {
        this.isDragging = false;
    };
    MAutoHorizontalScroll.prototype.onMouseup = function () {
        this.isDragging = false;
    };
    MAutoHorizontalScroll.prototype.onMousemove = function (e) {
        if (!this.isDragging) {
            return;
        }
        e.preventDefault();
        var x = e.pageX - this.$refs.body.offsetLeft;
        var walk = (x - this.startXDragging) * 2;
        this.$refs.body.scrollLeft = this.scrollLeftDragging - walk;
    };
    MAutoHorizontalScroll.prototype.mounted = function () {
        this.resizeComponent();
        this.$on('resizeDone', this.resizeComponent);
        if (this.$refs.bodyContent) {
            this.observer.observe(this.$refs.bodyContent, {
                subtree: true,
                childList: true
            });
        }
    };
    MAutoHorizontalScroll.prototype.beforeDestroy = function () {
        this.$off('resizeDone', this.resizeComponent);
        if (this.observer) {
            this.observer.disconnect();
        }
        this.stopScrollAnimation();
    };
    MAutoHorizontalScroll.prototype.resizeComponent = function () {
        return __awaiter(this, void 0, void 0, function () {
            return __generator(this, function (_a) {
                switch (_a.label) {
                    case 0: return [4 /*yield*/, this.$nextTick()];
                    case 1:
                        _a.sent();
                        this.componentWidth = this.$el.clientWidth
                            ? this.$el.clientWidth + "px"
                            : '100%';
                        this.hasHorizontalScroll =
                            this.$el.clientWidth < parseInt(this.minWidth, 10);
                        this.componentHeight =
                            !this.displayHorizontalScrollbar && Boolean(this.$refs.bodyContent)
                                ? this.$refs.bodyContent.clientHeight + "px"
                                : '';
                        this.emitResize({
                            element: this.$el,
                            hasHorizontalScroll: this.hasHorizontalScroll,
                            componentWidth: this.componentWidth,
                            horizontalScollbarWidth: this.$refs.bodyContent.scrollWidth
                                ? this.$refs.bodyContent.scrollWidth
                                : 0
                        });
                        this.checkGradientPresence();
                        return [2 /*return*/];
                }
            });
        });
    };
    MAutoHorizontalScroll.prototype.checkGradientPresence = function () {
        return __awaiter(this, void 0, void 0, function () {
            return __generator(this, function (_a) {
                switch (_a.label) {
                    case 0: return [4 /*yield*/, this.$nextTick()];
                    case 1:
                        _a.sent();
                        this.couldHaveLeftContent =
                            this.hasHorizontalScroll &&
                                Boolean(this.$refs.body) &&
                                this.$refs.body.scrollLeft > 30;
                        this.couldHaveRightContent =
                            this.hasHorizontalScroll &&
                                Boolean(this.$refs.body) &&
                                this.$refs.body.scrollLeft <=
                                    Math.round(this.$refs.body.scrollWidth -
                                        this.$refs.body.clientWidth -
                                        50);
                        return [2 /*return*/];
                }
            });
        });
    };
    __decorate([
        Prop({
            default: '100%',
            validator: function (value) {
                return REGEX_CSS_NUMBER_VALUE.test(value);
            }
        })
    ], MAutoHorizontalScroll.prototype, "minWidth", void 0);
    __decorate([
        Prop({
            default: true
        })
    ], MAutoHorizontalScroll.prototype, "horizontalScrollOffset", void 0);
    __decorate([
        Prop({
            default: true
        })
    ], MAutoHorizontalScroll.prototype, "dragActive", void 0);
    __decorate([
        Prop({
            default: MAutoHorizontalScrollGradientBackgroundStyle.White,
            validator: function (value) {
                return Enums.toValueArray(MAutoHorizontalScrollGradientBackgroundStyle).includes(value);
            }
        })
    ], MAutoHorizontalScroll.prototype, "gradientBackgroundStyle", void 0);
    __decorate([
        Prop({
            default: true
        })
    ], MAutoHorizontalScroll.prototype, "leftGradientActive", void 0);
    __decorate([
        Prop({
            default: true
        })
    ], MAutoHorizontalScroll.prototype, "rightGradientActive", void 0);
    __decorate([
        Prop({
            default: false
        })
    ], MAutoHorizontalScroll.prototype, "previousButtonActive", void 0);
    __decorate([
        Prop({
            default: false
        })
    ], MAutoHorizontalScroll.prototype, "nextButtonActive", void 0);
    __decorate([
        Prop({
            default: function () { return ModulVue.prototype.$i18n.translate('m-auto-horizontal-scroll:previous-button-text'); }
        })
    ], MAutoHorizontalScroll.prototype, "previousButtonText", void 0);
    __decorate([
        Prop({
            default: function () { return ModulVue.prototype.$i18n.translate('m-auto-horizontal-scroll:next-button-text'); }
        })
    ], MAutoHorizontalScroll.prototype, "nextButtonText", void 0);
    __decorate([
        Prop({
            default: false
        })
    ], MAutoHorizontalScroll.prototype, "displayHorizontalScrollbar", void 0);
    __decorate([
        Emit('resize')
    ], MAutoHorizontalScroll.prototype, "emitResize", null);
    __decorate([
        Emit('update:horizontalScrollOffset')
    ], MAutoHorizontalScroll.prototype, "emitUpdateHorizontalScrollOffset", null);
    __decorate([
        Emit('previous-button-click')
    ], MAutoHorizontalScroll.prototype, "emitPreviousButtonClick", null);
    __decorate([
        Emit('next-button-click')
    ], MAutoHorizontalScroll.prototype, "emitNextButtonClick", null);
    __decorate([
        Watch('leftGradientActive')
    ], MAutoHorizontalScroll.prototype, "onLeftGradientActiveChange", null);
    __decorate([
        Watch('displayHorizontalScrollbar')
    ], MAutoHorizontalScroll.prototype, "onDisplayHorizontalScrollbarChange", null);
    __decorate([
        Watch('horizontalScrollOffset', { immediate: true })
    ], MAutoHorizontalScroll.prototype, "onHorizontalScrollOffsetChange", null);
    __decorate([
        Watch('rightGradientActive')
    ], MAutoHorizontalScroll.prototype, "onRightGradientActiveChange", null);
    MAutoHorizontalScroll = __decorate([
        WithRender,
        Component({
            modul: {
                i18n: {
                    'fr': require('./auto-horizontal-scroll.lang.fr.json'),
                    'en': require('./auto-horizontal-scroll.lang.en.json')
                }
            },
            components: (_a = {}, _a[ICON_BUTTON_NAME] = MIconButton, _a),
            mixins: [ElementQueries]
        })
    ], MAutoHorizontalScroll);
    return MAutoHorizontalScroll;
}(ModulVue));
export { MAutoHorizontalScroll };
var AutoHorizontalScrollPlugin = {
    install: function (v, options) {
        v.component(AUTO_HORIZONTAL_SCROLL, MAutoHorizontalScroll);
    }
};
export default AutoHorizontalScrollPlugin;
//# sourceMappingURL=auto-horizontal-scroll.js.map