var _a;
import { __awaiter, __decorate, __extends, __generator } from "tslib";
import { Component, Emit, Prop, Ref, 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 './auto-horizontal-scroll-unscoped.scss';
import WithRender from './auto-horizontal-scroll.html?style=./auto-horizontal-scroll.scss';
export var MAutoHorizontalScrollGradientStyle;
(function (MAutoHorizontalScrollGradientStyle) {
    MAutoHorizontalScrollGradientStyle["Any"] = "Any";
    MAutoHorizontalScrollGradientStyle["White"] = "white";
    MAutoHorizontalScrollGradientStyle["Light"] = "light";
    MAutoHorizontalScrollGradientStyle["Dark"] = "dark";
    MAutoHorizontalScrollGradientStyle["GreyBlack"] = "grey-black";
    MAutoHorizontalScrollGradientStyle["Interactive"] = "interactive";
    MAutoHorizontalScrollGradientStyle["InteractiveDark"] = "interactive-dark";
    MAutoHorizontalScrollGradientStyle["InteractiveDarker"] = "interactive-darker";
    MAutoHorizontalScrollGradientStyle["CurrentColor"] = "current-color";
})(MAutoHorizontalScrollGradientStyle || (MAutoHorizontalScrollGradientStyle = {}));
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 = -1;
        _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 () {
            return __generator(this, function (_a) {
                switch (_a.label) {
                    case 0: return [4 /*yield*/, this.$nextTick()];
                    case 1:
                        _a.sent();
                        this.scrollLeftCounter++;
                        if (this.scrollAnimationActive) {
                            this.stopScrollAnimation();
                            return [2 /*return*/];
                        }
                        if (this.refBody &&
                            this.horizontalScrollOffset !== this.refBody.scrollLeft) {
                            if (this.scrollLeftCounter <= 0) {
                                this.refBody.scrollLeft = this.horizontalScrollOffset;
                            }
                            else {
                                this.startScrollAnimation();
                            }
                        }
                        return [2 /*return*/];
                }
            });
        });
    };
    MAutoHorizontalScroll.prototype.onRightGradientActiveChange = function () {
        this.checkGradientPresence();
    };
    Object.defineProperty(MAutoHorizontalScroll.prototype, "componentHeightStyle", {
        get: function () {
            return {
                height: !this.displayHorizontalScrollbar ? this.componentHeight : undefined
            };
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(MAutoHorizontalScroll.prototype, "buttonAreaHeightStyle", {
        get: function () {
            return {
                height: this.componentHeight
            };
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(MAutoHorizontalScroll.prototype, "hasLeftGradient", {
        get: function () {
            return this.leftGradientActive && this.couldHaveLeftContent;
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(MAutoHorizontalScroll.prototype, "hasRightGradient", {
        get: function () {
            return this.rightGradientActive && this.couldHaveRightContent;
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(MAutoHorizontalScroll.prototype, "hasPreviousButton", {
        get: function () {
            return this.previousButtonActive && this.couldHaveLeftContent;
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(MAutoHorizontalScroll.prototype, "hasNextButton", {
        get: function () {
            return this.nextButtonActive && this.couldHaveRightContent;
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(MAutoHorizontalScroll.prototype, "isGradientStyleDark", {
        get: function () {
            return (this.gradientStyle ===
                MAutoHorizontalScrollGradientStyle.Dark);
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(MAutoHorizontalScroll.prototype, "isGradientStyleInteractive", {
        get: function () {
            return (this.gradientStyle ===
                MAutoHorizontalScrollGradientStyle.Interactive);
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(MAutoHorizontalScroll.prototype, "isGradientStyleGreyBlack", {
        get: function () {
            return (this.gradientStyle ===
                MAutoHorizontalScrollGradientStyle.GreyBlack);
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(MAutoHorizontalScroll.prototype, "isGradientStyleInteractiveDark", {
        get: function () {
            return (this.gradientStyle ===
                MAutoHorizontalScrollGradientStyle.InteractiveDark);
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(MAutoHorizontalScroll.prototype, "isGradientStyleInteractiveDarker", {
        get: function () {
            return (this.gradientStyle ===
                MAutoHorizontalScrollGradientStyle.InteractiveDarker);
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(MAutoHorizontalScroll.prototype, "iconButtonSkin", {
        get: function () {
            return this.isGradientStyleDark ||
                this.isGradientStyleGreyBlack ||
                this.isGradientStyleInteractive ||
                this.isGradientStyleInteractiveDark ||
                this.isGradientStyleInteractiveDarker
                ? MIconButtonSkin.Dark
                : MIconButtonSkin.Light;
        },
        enumerable: false,
        configurable: true
    });
    MAutoHorizontalScroll.prototype.startScrollAnimation = function () {
        return __awaiter(this, void 0, void 0, function () {
            var initialScrollLeft, difference, intervalDelay_1, increment_1, isPositiveIncrement_1, counter_1, scrollAnimationInterval_1;
            var _this = this;
            return __generator(this, function (_a) {
                switch (_a.label) {
                    case 0:
                        this.scrollAnimationActive = true;
                        return [4 /*yield*/, this.$nextTick()];
                    case 1:
                        _a.sent();
                        if (this.refBody) {
                            initialScrollLeft = this.refBody.scrollLeft;
                            difference = this.horizontalScrollOffset - initialScrollLeft <=
                                this.refBody.scrollWidth
                                ? this.horizontalScrollOffset - initialScrollLeft
                                : this.refBody.scrollWidth;
                            intervalDelay_1 = difference > 500 ? 7 : 10;
                            increment_1 = difference / intervalDelay_1;
                            isPositiveIncrement_1 = increment_1 > 0;
                            counter_1 = 0;
                            scrollAnimationInterval_1 = window.setInterval(function () {
                                counter_1 += intervalDelay_1;
                                if (!_this.scrollAnimationActive ||
                                    !_this.refBody ||
                                    _this.refBody.scrollLeft === undefined ||
                                    ((isPositiveIncrement_1 &&
                                        _this.refBody.scrollLeft >= _this.horizontalScrollOffset) ||
                                        (!isPositiveIncrement_1 &&
                                            _this.refBody.scrollLeft <= _this.horizontalScrollOffset) ||
                                        counter_1 >= 5000)) {
                                    _this.stopScrollAnimation();
                                    window.clearInterval(scrollAnimationInterval_1);
                                }
                                else {
                                    _this.setScrollLeftOffset(_this.refBody.scrollLeft += increment_1);
                                }
                            }, intervalDelay_1);
                        }
                        return [2 /*return*/];
                }
            });
        });
    };
    MAutoHorizontalScroll.prototype.stopScrollAnimation = function () {
        this.scrollAnimationActive = false;
        this.onScroll();
    };
    MAutoHorizontalScroll.prototype.onScroll = function () {
        return __awaiter(this, void 0, void 0, function () {
            return __generator(this, function (_a) {
                switch (_a.label) {
                    case 0:
                        if (this.refBody && !this.scrollAnimationActive) {
                            this.emitUpdateHorizontalScrollOffset(this.refBody.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.refBody.offsetLeft;
        this.scrollLeftDragging = this.refBody.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.refBody.offsetLeft;
        var walk = (x - this.startXDragging) * 2;
        this.refBody.scrollLeft = this.scrollLeftDragging - walk;
    };
    MAutoHorizontalScroll.prototype.mounted = function () {
        this.resizeComponent();
        this.$on('resizeDone', this.resizeComponent);
        if (this.refBodyContent) {
            this.observer.observe(this.refBodyContent, {
                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 = Boolean(this.refBodyContent)
                            ? this.refBodyContent.clientHeight + "px"
                            : '';
                        this.emitResize({
                            element: this.$el,
                            hasHorizontalScroll: this.hasHorizontalScroll,
                            componentWidth: this.componentWidth,
                            horizontalScollbarWidth: this.refBodyContent.scrollWidth
                                ? this.refBodyContent.scrollWidth
                                : 0
                        });
                        this.checkGradientPresence();
                        return [2 /*return*/];
                }
            });
        });
    };
    MAutoHorizontalScroll.prototype.setScrollLeftOffset = function (scrollLeftOffset) {
        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();
                        if (!this.refBody) {
                            return [2 /*return*/];
                        }
                        maxScrollLeft = this.refBodyContent.scrollWidth - this.refBody.clientWidth;
                        if (scrollLeftOffset < 0) {
                            this.refBody.scrollLeft = 0;
                            this.scrollAnimationActive = false;
                        }
                        else if (scrollLeftOffset >= maxScrollLeft) {
                            this.refBody.scrollLeft = maxScrollLeft - 0.5;
                            this.scrollAnimationActive = false;
                        }
                        else {
                            this.refBody.scrollLeft = scrollLeftOffset;
                        }
                        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.refBody) &&
                                this.refBody.scrollLeft > 2;
                        this.couldHaveRightContent =
                            this.hasHorizontalScroll &&
                                Boolean(this.refBody) &&
                                this.refBody.scrollLeft <=
                                    Math.round(this.refBody.scrollWidth -
                                        this.refBody.clientWidth -
                                        2);
                        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: MAutoHorizontalScrollGradientStyle.White,
            validator: function (value) {
                return Enums.toValueArray(MAutoHorizontalScrollGradientStyle).includes(value);
            }
        })
    ], MAutoHorizontalScroll.prototype, "gradientStyle", 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([
        Ref('body')
    ], MAutoHorizontalScroll.prototype, "refBody", void 0);
    __decorate([
        Ref('bodyContent')
    ], MAutoHorizontalScroll.prototype, "refBodyContent", 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