import * as i0 from '@angular/core';
import { EventEmitter, forwardRef, Component, ViewChild, Input, Output, HostListener, NgModule } from '@angular/core';
import { NG_VALUE_ACCESSOR } from '@angular/forms';
import { NgClass } from '@angular/common';
import { TooltipDirective } from '@seniorsistemas/angular-components/tooltip';

/**
 * @description Componente de controle deslizante (slider) para seleção de valores numéricos
 * dentro de um intervalo definido. Suporta modo simples (um valor) e modo de intervalo
 * (dois valores: início e fim). Implementa {@link ControlValueAccessor} para integração
 * com Reactive Forms e Template-driven Forms do Angular.
 *
 * @example
 * ```html
 * <!-- Slider simples -->
 * <s-slider formControlName="volume" [min]="0" [max]="100" [step]="5" />
 *
 * <!-- Slider de intervalo -->
 * <s-slider formControlName="faixa" [multiple]="true" [min]="0" [max]="1000" />
 * ```
 *
 * @category Inputs
 */
class SliderComponent {
    MAX_RANGE_VALUE = 100;
    MIN_RANGE_VALUE = 0;
    track;
    /**
     * @description Habilita o modo de intervalo, permitindo selecionar um valor mínimo e máximo.
     * Quando `true`, o valor do componente é um array `[inicio, fim]`.
     *
     * @default false
     */
    multiple = false;
    /**
     * @description Valor atual do slider. No modo simples é um número; no modo de
     * intervalo (`multiple: true`) é um array `[inicio, fim]`.
     *
     * @default 0
     */
    value = 0;
    /**
     * @description Emitido sempre que o valor do slider é alterado pelo usuário.
     * Emite o novo valor (número ou array de dois números no modo de intervalo).
     */
    valueChange = new EventEmitter();
    /**
     * @description Incremento aplicado a cada movimento do thumb do slider.
     *
     * @default 1
     */
    step = 1;
    /**
     * @description Oculta visualmente o thumb (botão arrastável) do slider.
     * Útil para visualizações onde apenas a faixa de progresso deve ser exibida.
     *
     * @default false
     */
    hiddenThumb = false;
    /**
     * @description Desabilita a interação do usuário com o slider.
     *
     * @default false
     */
    disabled = false;
    /**
     * @description Valor mínimo permitido no slider.
     *
     * @default 0
     */
    min = this.MIN_RANGE_VALUE;
    /**
     * @description Valor máximo permitido no slider.
     *
     * @default 100
     */
    max = this.MAX_RANGE_VALUE;
    /**
     * @description Label exibido abaixo ou ao lado do valor mínimo do slider.
     * Útil para indicar semanticamente os extremos do intervalo.
     */
    minValueLabel;
    /**
     * @description Label exibido abaixo ou ao lado do valor máximo do slider.
     * Útil para indicar semanticamente os extremos do intervalo.
     */
    maxValueLabel;
    /**
     * @description Índice de tabulação do elemento, controlando a ordem de foco via teclado.
     *
     * @default 0
     */
    tabindex = 0;
    startValue = 0;
    endValue = 0;
    movingProgressBar = false;
    progressLeft = 0;
    progressWidth = '';
    onChange = () => { };
    onTouched = () => { };
    draggingThumb = null;
    progressBarEventPositionStart = -1;
    startValueBeforeProgressBarEvent = -1;
    rangeBetweenElementsBeforeProgressBarEvent = -1;
    totalRangeBeforeProgressBarEvent = -1;
    /**
     * Map of valid values for values in range.
     * @example
     * with min = -10 and max = 10 will have this map.
     * {
     *     -10: { 0 },
     *     -9: { 10 },
     *      ...
     *     10: { 10 }
     * }
     */
    mapRangeValuesForSlider = new Map();
    activeMouseDown = false;
    focusActive = false;
    ngOnInit() {
        this.setUserRangeMapValues();
    }
    ngOnChanges(changes) {
        const hasChangesOnMin = changes['min'] && !changes['min'].firstChange;
        const hasChangesOnMax = changes['max'] && !changes['max'].firstChange;
        const hasChanges = hasChangesOnMin || hasChangesOnMax;
        if (hasChanges) {
            this.setUserRangeMapValues();
            setTimeout(() => {
                this.setRangeValues();
            });
        }
    }
    ngAfterViewInit() {
        setTimeout(() => {
            this.setRangeValues();
        });
    }
    onKeydown($event) {
        if (this.focusActive && !this.disabled) {
            const isArrowKeyLeft = $event.key === 'ArrowLeft';
            const isArrowKeyRight = $event.key === 'ArrowRight';
            if (isArrowKeyLeft) {
                this.handleArrowKeyLeft();
            }
            else if (isArrowKeyRight) {
                this.handleArrowKeyRight();
            }
        }
    }
    get tooltipStartText() {
        return Array.isArray(this.value) ? this.value[0]?.toString() : this.value?.toString();
    }
    get tooltipEndText() {
        return Array.isArray(this.value) ? this.value[1]?.toString() : this.value?.toString();
    }
    writeValue(obj) {
        this.value = obj;
        this.setRangeValues();
    }
    registerOnChange(fn) {
        this.onChange = fn;
    }
    registerOnTouched(fn) {
        this.onTouched = fn;
    }
    setDisabledState(isDisabled) {
        this.disabled = isDisabled;
    }
    onFocusIn() {
        this.focusActive = true;
    }
    onBlur() {
        this.focusActive = false;
    }
    onTrackClick(evt) {
        if (this.disabled || this.movingProgressBar || this.activeMouseDown) {
            return;
        }
        const trackClickPercentage = this.getPercentageByEvent(evt);
        const trackClickToUserRange = this.getValueFromMapByValue(trackClickPercentage);
        const _trackClickValid = this.needParseValues ? trackClickToUserRange : trackClickPercentage;
        const _setEndValue = () => {
            const _endValueUserValue = this.getValueFromMapByValue(this.endValue);
            const _endValue = (this.needParseValues
                ? this.mapRangeValuesForSlider.get(trackClickToUserRange)
                : trackClickPercentage) ?? 0;
            if (this.needParseValues && _endValueUserValue !== trackClickToUserRange) {
                this.endValue = _endValue;
            }
            else if (!this.needParseValues) {
                this.endValue = trackClickPercentage;
            }
        };
        const _setStartValue = () => {
            const _startValueUserValue = this.getValueFromMapByValue(this.startValue);
            if (this.needParseValues && _startValueUserValue !== trackClickToUserRange) {
                const _startValue = (this.needParseValues
                    ? this.mapRangeValuesForSlider.get(trackClickToUserRange)
                    : trackClickPercentage) ?? 0;
                this.startValue = _startValue;
            }
            else if (!this.needParseValues) {
                this.startValue = trackClickPercentage;
            }
        };
        if (this.multiple) {
            const [start, end] = this.value;
            const validStart = (this.needParseValues ? this.mapRangeValuesForSlider.get(start) : start) ?? 0;
            const validEnd = (this.needParseValues ? this.mapRangeValuesForSlider.get(end) : end) ?? 0;
            const _updateStart = () => {
                _setStartValue();
                this.setValue([trackClickPercentage, validEnd]);
            };
            const _updateEnd = () => {
                _setEndValue();
                this.setValue([validStart, trackClickPercentage]);
            };
            const clickPercentageBetweenRange = isInRange(_trackClickValid, start, end);
            if (_trackClickValid < start) {
                _updateStart();
            }
            else if (_trackClickValid > end) {
                _updateEnd();
            }
            else if (clickPercentageBetweenRange) {
                const middle = (start + end) / 2;
                const trackClickPercentageIsExactiddle = _trackClickValid === middle;
                if (trackClickPercentageIsExactiddle) {
                    _updateStart();
                }
                else {
                    const setStart = _trackClickValid < middle;
                    const setEnd = _trackClickValid > middle;
                    if (setStart) {
                        _updateStart();
                    }
                    else if (setEnd) {
                        _updateEnd();
                    }
                }
            }
        }
        else {
            this.setValue(trackClickPercentage);
            _setEndValue();
        }
        this.setProgress();
    }
    onProgressMouseDown(evt) {
        if (!this.multiple || this.disabled) {
            return;
        }
        this.progressBarEventPositionStart = this.getPercentageByEvent(evt);
        this.startValueBeforeProgressBarEvent = this.startValue;
        this.rangeBetweenElementsBeforeProgressBarEvent = this.endValue - this.startValue;
        if (this.multiple) {
            const [start, end] = this.value;
            this.totalRangeBeforeProgressBarEvent = end - start;
        }
        document.addEventListener('mousemove', this.handleProgressBarMove);
        document.addEventListener('mouseup', this.handleProgressBarMoveEnd);
    }
    onMouseDown(_, thumb) {
        if (this.disabled)
            return;
        this.draggingThumb = thumb;
        this.activeMouseDown = true;
        document.addEventListener('mousemove', this.onThumbMove);
        document.addEventListener('mouseup', this.onMouseUp);
    }
    setRangeValues() {
        const _setStartAndEndValue = (startValue, endValue) => {
            this.startValue = this.getClosestValueFromMapSlider(startValue);
            this.endValue = this.getClosestValueFromMapSlider(endValue);
        };
        if (this.value === null || this.value === undefined) {
            return;
        }
        if (Array.isArray(this.value) && !this.multiple) {
            throw new Error('You must use "multiple" with value as array');
        }
        if (this.multiple && Array.isArray(this.value)) {
            this.startValue = this.value[0];
            this.endValue = this.value[1];
        }
        else if (!this.multiple) {
            this.startValue = this.value;
            this.endValue = this.value;
        }
        _setStartAndEndValue(this.startValue, this.endValue);
        if (this.multiple) {
            let [_startValue, _endValue] = this.value;
            const difference = getDifference(_endValue, _startValue);
            const endValueIsGreatherThanMax = _endValue > this.max;
            const startValueIsLessThanMin = _startValue < this.min;
            const needUpdateValues = endValueIsGreatherThanMax || startValueIsLessThanMin;
            if (endValueIsGreatherThanMax) {
                _endValue = this.max;
                _startValue = _endValue - difference;
            }
            else if (startValueIsLessThanMin) {
                _startValue = this.min;
                _endValue = _startValue + difference;
            }
            if (needUpdateValues) {
                _setStartAndEndValue(_startValue, _endValue);
                this.setValue([this.startValue, this.endValue]);
            }
        }
        else {
            let _value = this.value;
            const valueGreatherThanMax = _value > this.max;
            const valueLessThanMin = _value < this.min;
            const needUpdateValue = valueGreatherThanMax || valueLessThanMin;
            if (valueGreatherThanMax) {
                _value = this.max;
            }
            else if (valueLessThanMin) {
                _value = this.min;
            }
            if (needUpdateValue) {
                this.setValue(_value, false);
            }
        }
        this.setProgress();
    }
    onThumbMove = (event) => {
        if (this.movingProgressBar || !this.draggingThumb)
            return;
        let newPosition = this.getPercentageByEvent(event);
        if ((this.multiple && this.draggingThumb === 'start' && newPosition > this.endValue) ||
            (this.multiple && this.draggingThumb === 'end' && newPosition < this.startValue)) {
            return;
        }
        const positionInUserRange = this.getValueFromMapByValue(newPosition);
        if (this.multiple) {
            if (this.draggingThumb === 'start') {
                this.startValue =
                    (this.needParseValues ? this.mapRangeValuesForSlider.get(positionInUserRange) : newPosition) ?? 0;
            }
            else if (this.draggingThumb === 'end') {
                this.endValue =
                    (this.needParseValues ? this.mapRangeValuesForSlider.get(positionInUserRange) : newPosition) ?? 0;
            }
            this.setValue([this.startValue, this.endValue]);
            const [start, end] = this.value;
            if (start === end && this.draggingThumb === 'start') {
                this.startValue = this.endValue;
            }
            else if (start === end && this.draggingThumb === 'end') {
                this.endValue = this.startValue;
            }
        }
        else {
            const currentValue = this.value;
            const _value = this.needParseValues ? positionInUserRange : newPosition;
            const isAtSameValue = this.needParseValues ? positionInUserRange === this.value : false;
            const hasStep = this.step !== 0;
            const newValueIsValidByStep = hasStep
                ? currentValue + this.step === _value || currentValue - this.step === _value
                : false;
            if (isAtSameValue && !newValueIsValidByStep) {
                return;
            }
            this.endValue =
                (this.needParseValues ? this.mapRangeValuesForSlider.get(positionInUserRange) : newPosition) ?? 0;
            this.startValue = this.endValue;
            this.setValue(this.endValue);
        }
        this.setProgress();
    };
    onMouseUp = () => {
        this.draggingThumb = null;
        document.removeEventListener('mousemove', this.onThumbMove);
        document.removeEventListener('mouseup', this.onMouseUp);
        setTimeout(() => {
            this.activeMouseDown = false;
        }, 150);
    };
    handleProgressBarMove = (event) => {
        this.movingProgressBar = true;
        const newCenter = this.getPercentageByEvent(event);
        const startPositionBeforeEvent = this.progressBarEventPositionStart;
        const startValueBeforeEvent = this.startValueBeforeProgressBarEvent;
        const range = this.rangeBetweenElementsBeforeProgressBarEvent;
        let { newStart, newEnd } = calculateNewRange(startValueBeforeEvent, startValueBeforeEvent + range, startPositionBeforeEvent, newCenter);
        if (newStart < this.MIN_RANGE_VALUE || newEnd > this.MAX_RANGE_VALUE) {
            return;
        }
        if (this.needParseValues) {
            const startValueBeforeEventUserRange = this.getValueFromMapByValue(startValueBeforeEvent);
            const startPositionBeforeEventUserRange = this.getValueFromMapByValue(startPositionBeforeEvent);
            const centerUserRange = this.getValueFromMapByValue(newCenter);
            const valueRange = this.totalRangeBeforeProgressBarEvent;
            let { newStart, newEnd } = calculateNewRange(startValueBeforeEventUserRange, startValueBeforeEventUserRange + valueRange, startPositionBeforeEventUserRange, centerUserRange);
            if (newStart < this.min || newEnd > this.max) {
                return;
            }
            this.startValue = this.mapRangeValuesForSlider.get(newStart) ?? 0;
            this.endValue = this.mapRangeValuesForSlider.get(newEnd) ?? 0;
        }
        else {
            this.startValue = newStart;
            this.endValue = newEnd;
        }
        this.setValue([this.startValue, this.endValue]);
        this.setProgress();
    };
    handleProgressBarMoveEnd = () => {
        this.progressBarEventPositionStart = -1;
        this.startValueBeforeProgressBarEvent = -1;
        this.rangeBetweenElementsBeforeProgressBarEvent = -1;
        this.totalRangeBeforeProgressBarEvent = -1;
        document.removeEventListener('mousemove', this.handleProgressBarMove);
        document.removeEventListener('mouseup', this.handleProgressBarMoveEnd);
        setTimeout(() => {
            this.movingProgressBar = false;
        }, 150);
    };
    setProgress() {
        if (this.multiple) {
            this.progressLeft = this.startValue;
            this.progressWidth = `calc(${this.endValue - this.startValue}% + 10px)`;
        }
        else {
            this.progressLeft = 0;
            this.progressWidth = `calc(${this.endValue}% + 10px)`;
        }
    }
    /**
     * Get the percentage of a mouse event from the track's left edge
     * @param mouseEvent mouse event
     * @returns percentage from the left edge
     */
    getPercentageByEvent(mouseEvent) {
        const trackRect = this.track.nativeElement.getBoundingClientRect();
        let newLeft = Math.round(((mouseEvent.clientX - trackRect.left) / trackRect.width) * this.MAX_RANGE_VALUE);
        newLeft = Math.max(0, Math.min(newLeft, this.MAX_RANGE_VALUE));
        return newLeft;
    }
    setValue(value, parse = true) {
        if (this.disabled) {
            return;
        }
        if (this.needParseValues && parse) {
            if (Array.isArray(value)) {
                value = value.map((x) => this.getValueFromMapByValue(x));
            }
            else {
                value = this.getValueFromMapByValue(value);
            }
        }
        this.value = value;
        this.valueChange.emit(value);
        this.writeValue(this.value);
        this.onChange(this.value);
        this.onTouched(this.value);
    }
    setUserRangeMapValues() {
        const start = this.min;
        const end = this.max;
        if (start > end) {
            throw new Error('Max value must be greater than min value');
        }
        this.mapRangeValuesForSlider.clear();
        const range = end - start;
        const decimalPlaces = 2;
        const stepCount = Math.floor(range / this.step);
        const values = [];
        for (let value = start; value <= end; value += this.step) {
            values.push(value);
        }
        if (values[values.length - 1] !== end) {
            values.push(end);
        }
        const mappedValues = values.map((value) => {
            let mapped = ((value - start) / range) * this.MAX_RANGE_VALUE;
            return parseFloat(mapped.toFixed(decimalPlaces));
        });
        mappedValues[0] = 0;
        mappedValues[mappedValues.length - 1] = this.MAX_RANGE_VALUE;
        const error = this.MAX_RANGE_VALUE - mappedValues[mappedValues.length - 1];
        const errorPerStep = error / stepCount;
        for (let i = 1; i < mappedValues.length - 1; i++) {
            mappedValues[i] += errorPerStep;
            mappedValues[i] = parseFloat(mappedValues[i].toFixed(decimalPlaces));
        }
        values.forEach((value, index) => {
            this.mapRangeValuesForSlider.set(value, mappedValues[index]);
        });
    }
    /**
     * Returns the user value from the given slider value by using the map of range values.
     * @example
     * If the map is 0: { 0 }, 1: { 10 }, 2: { 30 }, 3: { 40 }, 4: { 50 }
     * and the sliderValue is 37, the function returns 3
     * or the slider value is 40, the function returns 4
     * @param sliderValue the value of the slider (values only between range MIN and MAX)
     * @returns the user value from the given slider value
     */
    getValueFromMapByValue(sliderValue) {
        const mapToArray = Array.from(this.mapRangeValuesForSlider).map(([value, mapped]) => ({ value, mapped }));
        const exactValue = mapToArray.find((x) => x.mapped == sliderValue);
        const closest = mapToArray.reduce((prev, curr) => Math.abs(curr.mapped - sliderValue) < Math.abs(prev.mapped - sliderValue) ? curr : prev);
        return exactValue ? exactValue.value : closest.value;
    }
    /**
     * Retrieves the key from the map that is closest to the given slider value.
     * @param userValue - The value to find the closest key for. (values only between 0 - 100)
     * @returns The key that corresponds to the closest mapped value.
     */
    getClosestValueFromMapSlider(userValue) {
        const mapToArray = Array.from(this.mapRangeValuesForSlider).map(([value, mapped]) => ({ value, mapped }));
        if (userValue >= this.max) {
            return mapToArray[mapToArray.length - 1].mapped;
        }
        else if (userValue <= this.min) {
            return mapToArray[0].mapped;
        }
        const exactValue = mapToArray.find((x) => x.value == userValue);
        const closestValue = mapToArray.reduce((prev, curr) => Math.abs(curr.value - userValue) < Math.abs(prev.value - userValue) ? curr : prev);
        const item = exactValue || closestValue;
        const isFirstItem = mapToArray[0] === item;
        const isLastItem = mapToArray[mapToArray.length - 1] === item;
        if (isFirstItem && userValue > this.min) {
            return getMidpoint(item.mapped, mapToArray[1].mapped);
        }
        else if (isLastItem && userValue < this.max) {
            return getMidpoint(item.mapped, mapToArray[mapToArray.length - 2].mapped);
        }
        else {
            return item.mapped;
        }
    }
    handleArrowKeyLeft() {
        if (this.multiple) {
            this._incrementOrDecrementStartAndEndValue(false);
        }
        else {
            this._incrementOrDecrementEndValue(false);
        }
        this.setProgress();
    }
    handleArrowKeyRight() {
        if (this.multiple) {
            this._incrementOrDecrementStartAndEndValue(true);
        }
        else {
            this._incrementOrDecrementEndValue(true);
        }
        this.setProgress();
    }
    _incrementOrDecrementStartAndEndValue(increment) {
        let [start, end] = this.value;
        const difference = getDifference(end, start);
        if (increment) {
            start += this.step;
            end += this.step;
        }
        else {
            start -= this.step;
            end -= this.step;
        }
        const startLessThanMin = start < this.min;
        const endGreaterThanMax = end > this.max;
        if (startLessThanMin || endGreaterThanMax) {
            if (startLessThanMin) {
                start = this.min;
                end = start + difference;
            }
            else if (endGreaterThanMax) {
                end = this.max;
                start = end - difference;
            }
        }
        if (start < this.min || end > this.max) {
            return;
        }
        this.setValue([start, end], false);
        if (this.needParseValues) {
            start = this.getClosestValueFromMapSlider(start);
            end = this.getClosestValueFromMapSlider(end);
        }
        this.startValue = start;
        this.endValue = end;
    }
    _incrementOrDecrementEndValue(increment) {
        let value = this.value;
        if (increment) {
            value += this.step;
        }
        else {
            value -= this.step;
        }
        let _newEndValue = value;
        if (this.needParseValues) {
            _newEndValue = this.getClosestValueFromMapSlider(_newEndValue);
        }
        if (_newEndValue < this.MIN_RANGE_VALUE || _newEndValue > this.MAX_RANGE_VALUE) {
            return;
        }
        this.endValue = _newEndValue;
        this.startValue = this.endValue;
        this.setValue(_newEndValue);
    }
    get needParseValues() {
        return this.max !== this.MAX_RANGE_VALUE || this.min !== this.MIN_RANGE_VALUE;
    }
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: SliderComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
    static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: SliderComponent, isStandalone: true, selector: "s-slider", inputs: { multiple: "multiple", value: "value", step: "step", hiddenThumb: "hiddenThumb", disabled: "disabled", min: "min", max: "max", minValueLabel: "minValueLabel", maxValueLabel: "maxValueLabel", tabindex: "tabindex" }, outputs: { valueChange: "valueChange" }, host: { listeners: { "document:keydown": "onKeydown($event)" } }, providers: [
            {
                provide: NG_VALUE_ACCESSOR,
                useExisting: forwardRef(() => SliderComponent),
                multi: true,
            },
        ], viewQueries: [{ propertyName: "track", first: true, predicate: ["track"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div\r\n    class=\"slider-container\"\r\n    [ngClass]=\"{ 'slider-container--disabled': disabled }\"\r\n    [tabindex]=\"tabindex\"\r\n    (click)=\"onTrackClick($event)\"\r\n    (focus)=\"onFocusIn()\"\r\n    (blur)=\"onBlur()\"\r\n>\r\n    <div\r\n        #track\r\n        class=\"slider-track\"\r\n        [ngClass]=\"{\r\n            'slider-track--hidden-thumb': hiddenThumb,\r\n            'slider-track--moving-multiple-thumbs': movingProgressBar,\r\n        }\"\r\n    >\r\n        <div\r\n            class=\"slider-progress\"\r\n            (mousedown)=\"onProgressMouseDown($event)\"\r\n            [style.left.%]=\"progressLeft\"\r\n            [style.width]=\"progressWidth\"\r\n        ></div>\r\n        @if (multiple) {\r\n            <div\r\n                class=\"slider-thumb\"\r\n                [sTooltip]=\"tooltipStartText\"\r\n                [showDelay]=\"0\"\r\n                (mousedown)=\"onMouseDown($event, 'start')\"\r\n                [style.left.%]=\"startValue\"\r\n            ></div>\r\n        }\r\n        <div\r\n            [sTooltip]=\"tooltipEndText\"\r\n            class=\"slider-thumb\"\r\n            [showDelay]=\"0\"\r\n            (mousedown)=\"onMouseDown($event, 'end')\"\r\n            [style.left.%]=\"endValue\"\r\n        ></div>\r\n    </div>\r\n    <div class=\"footer\">\r\n        <span>{{ minValueLabel || min }}</span>\r\n        <span>{{ maxValueLabel || max }}</span>\r\n    </div>\r\n</div>\r\n", styles: [".slider-container{height:20px;padding:16px 0 40px;position:relative;-webkit-user-select:none;user-select:none;width:100%}.slider-container .slider-track{background-color:#ddd;border-radius:3px;cursor:pointer;height:6px;position:relative;width:100%}.slider-container .slider-track .slider-progress{background-color:#428bca;border-radius:3px;cursor:pointer;height:100%;left:0;position:absolute;top:0;width:0}.slider-container .slider-track .slider-thumb{background-color:#fff;border:2px solid #428bca;border-radius:50%;cursor:pointer;height:20px;position:absolute;transform:translateY(-50%);top:50%;width:20px}.slider-container .slider-track .slider-thumb:active{box-shadow:0 0 0 4px #428bca33}.slider-container .slider-track--hidden-thumb:not(:hover) .slider-thumb{opacity:0}.slider-container .slider-track--moving-multiple-thumbs .slider-thumb{box-shadow:0 0 0 4px #428bca33}.slider-container .footer{color:#212533;display:flex;font-family:Open Sans,sans-serif;font-size:14px;justify-content:space-between;margin-top:8px}.slider-container--disabled .slider-track{cursor:default}.slider-container--disabled .slider-track .slider-thumb{border-color:#a5a5b2;cursor:default}.slider-container--disabled .slider-track .slider-thumb:active{box-shadow:none}.slider-container--disabled .slider-track .slider-progress{background-color:#a5a5b2;cursor:default}.slider-container:focus-visible{outline:none}.slider-container:focus-visible .slider-thumb{box-shadow:0 0 0 4px #428bca33}\n"], dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: TooltipDirective, selector: "[sTooltip]", inputs: ["sTooltip", "tooltipPosition", "showDelay", "displayTime", "tooltipEvent", "escape", "visible", "mobileBehavior", "focusedInputRef", "checkTruncatedText"] }] });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: SliderComponent, decorators: [{
            type: Component,
            args: [{ selector: 's-slider', providers: [
                        {
                            provide: NG_VALUE_ACCESSOR,
                            useExisting: forwardRef(() => SliderComponent),
                            multi: true,
                        },
                    ], standalone: true, imports: [NgClass, TooltipDirective], template: "<div\r\n    class=\"slider-container\"\r\n    [ngClass]=\"{ 'slider-container--disabled': disabled }\"\r\n    [tabindex]=\"tabindex\"\r\n    (click)=\"onTrackClick($event)\"\r\n    (focus)=\"onFocusIn()\"\r\n    (blur)=\"onBlur()\"\r\n>\r\n    <div\r\n        #track\r\n        class=\"slider-track\"\r\n        [ngClass]=\"{\r\n            'slider-track--hidden-thumb': hiddenThumb,\r\n            'slider-track--moving-multiple-thumbs': movingProgressBar,\r\n        }\"\r\n    >\r\n        <div\r\n            class=\"slider-progress\"\r\n            (mousedown)=\"onProgressMouseDown($event)\"\r\n            [style.left.%]=\"progressLeft\"\r\n            [style.width]=\"progressWidth\"\r\n        ></div>\r\n        @if (multiple) {\r\n            <div\r\n                class=\"slider-thumb\"\r\n                [sTooltip]=\"tooltipStartText\"\r\n                [showDelay]=\"0\"\r\n                (mousedown)=\"onMouseDown($event, 'start')\"\r\n                [style.left.%]=\"startValue\"\r\n            ></div>\r\n        }\r\n        <div\r\n            [sTooltip]=\"tooltipEndText\"\r\n            class=\"slider-thumb\"\r\n            [showDelay]=\"0\"\r\n            (mousedown)=\"onMouseDown($event, 'end')\"\r\n            [style.left.%]=\"endValue\"\r\n        ></div>\r\n    </div>\r\n    <div class=\"footer\">\r\n        <span>{{ minValueLabel || min }}</span>\r\n        <span>{{ maxValueLabel || max }}</span>\r\n    </div>\r\n</div>\r\n", styles: [".slider-container{height:20px;padding:16px 0 40px;position:relative;-webkit-user-select:none;user-select:none;width:100%}.slider-container .slider-track{background-color:#ddd;border-radius:3px;cursor:pointer;height:6px;position:relative;width:100%}.slider-container .slider-track .slider-progress{background-color:#428bca;border-radius:3px;cursor:pointer;height:100%;left:0;position:absolute;top:0;width:0}.slider-container .slider-track .slider-thumb{background-color:#fff;border:2px solid #428bca;border-radius:50%;cursor:pointer;height:20px;position:absolute;transform:translateY(-50%);top:50%;width:20px}.slider-container .slider-track .slider-thumb:active{box-shadow:0 0 0 4px #428bca33}.slider-container .slider-track--hidden-thumb:not(:hover) .slider-thumb{opacity:0}.slider-container .slider-track--moving-multiple-thumbs .slider-thumb{box-shadow:0 0 0 4px #428bca33}.slider-container .footer{color:#212533;display:flex;font-family:Open Sans,sans-serif;font-size:14px;justify-content:space-between;margin-top:8px}.slider-container--disabled .slider-track{cursor:default}.slider-container--disabled .slider-track .slider-thumb{border-color:#a5a5b2;cursor:default}.slider-container--disabled .slider-track .slider-thumb:active{box-shadow:none}.slider-container--disabled .slider-track .slider-progress{background-color:#a5a5b2;cursor:default}.slider-container:focus-visible{outline:none}.slider-container:focus-visible .slider-thumb{box-shadow:0 0 0 4px #428bca33}\n"] }]
        }], propDecorators: { track: [{
                type: ViewChild,
                args: ['track']
            }], multiple: [{
                type: Input
            }], value: [{
                type: Input
            }], valueChange: [{
                type: Output
            }], step: [{
                type: Input
            }], hiddenThumb: [{
                type: Input
            }], disabled: [{
                type: Input
            }], min: [{
                type: Input
            }], max: [{
                type: Input
            }], minValueLabel: [{
                type: Input
            }], maxValueLabel: [{
                type: Input
            }], tabindex: [{
                type: Input
            }], onKeydown: [{
                type: HostListener,
                args: ['document:keydown', ['$event']]
            }] } });
/**
 * Calculates a new range based on the old range and the positions clicked and finalized.
 *
 * @param oldStart - The starting value of the old range.
 * @param oldEnd - The ending value of the old range.
 * @param clickedPosition - The position where the click occurred.
 * @param finalPosition - The position where the range should end.
 * @returns An object containing the new start and end values of the range.
 */
const calculateNewRange = (oldStart, oldEnd, clickedPosition, finalPosition) => {
    const range = oldEnd - oldStart;
    const newStart = finalPosition - (clickedPosition - oldStart);
    const newEnd = newStart + range;
    return { newStart, newEnd };
};
const isInRange = (value, rangeStart, rangeEnd) => {
    const [min, max] = rangeStart < rangeEnd ? [rangeStart, rangeEnd] : [rangeEnd, rangeStart];
    return value >= min && value <= max;
};
const getMidpoint = (start, end) => {
    const midpoint = (start + end) / 2;
    return parseFloat(midpoint.toFixed(2));
};
const getDifference = (end, start) => {
    return Math.abs(end - start);
};

class SliderModule {
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: SliderModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
    static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "18.2.14", ngImport: i0, type: SliderModule, imports: [SliderComponent], exports: [SliderComponent] });
    static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: SliderModule });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: SliderModule, decorators: [{
            type: NgModule,
            args: [{
                    imports: [SliderComponent],
                    exports: [SliderComponent],
                }]
        }] });

/**
 * Generated bundle index. Do not edit.
 */

export { SliderComponent, SliderModule };
//# sourceMappingURL=seniorsistemas-angular-components-slider.mjs.map
