/**
 * @license
 * Copyright Tyler Technologies, Inc. 
 * License: Apache-2.0
 */
import { getShadowElement, toggleAttribute, toggleClass } from '@tylertech/forge-core';
import { internals } from '../constants';
import { BaseAdapter } from '../core/base/base-adapter';
import { elementsOverlapping, isPointerOverElement } from '../core/utils/utils';
import { STATE_LAYER_CONSTANTS } from '../state-layer';
import { SLIDER_CONSTANTS } from './slider-constants';
import { createLabel, createStartHandleElement, createStartInputElement } from './slider-utils';
export class SliderAdapter extends BaseAdapter {
    constructor(component) {
        super(component);
        this._rootElement = getShadowElement(component, SLIDER_CONSTANTS.selectors.ROOT);
        this._trackElement = getShadowElement(component, SLIDER_CONSTANTS.selectors.TRACK);
        this._handleContainerElement = getShadowElement(component, SLIDER_CONSTANTS.selectors.HANDLE_CONTAINER);
        this._endInputElement = getShadowElement(component, SLIDER_CONSTANTS.selectors.END_INPUT);
        this._endHandleElement = getShadowElement(component, SLIDER_CONSTANTS.selectors.END_HANDLE);
        this._endHandleThumbElement = getShadowElement(component, SLIDER_CONSTANTS.selectors.END_HANDLE_THUMB);
        this._endLabelContentElement = getShadowElement(component, SLIDER_CONSTANTS.selectors.END_LABEL_CONTENT);
    }
    addInputListener(type, listener) {
        const inputs = this._getInputs();
        inputs.forEach(input => input.addEventListener(type, listener));
    }
    update({ startFraction, endFraction, tickCount }) {
        this._rootElement.style.setProperty(SLIDER_CONSTANTS.cssCustomProperties.START_FRACTION, String(startFraction));
        this._rootElement.style.setProperty(SLIDER_CONSTANTS.cssCustomProperties.END_FRACTION, String(endFraction));
        this._rootElement.style.setProperty(SLIDER_CONSTANTS.cssCustomProperties.TICK_COUNT, String(tickCount));
    }
    updateLabels(labelStart, labelEnd) {
        var _a;
        if (this._startLabelContentElement) {
            this._startLabelContentElement.textContent = labelStart;
        }
        if (this._endLabelContentElement) {
            this._endLabelContentElement.textContent = labelEnd;
        }
        (_a = this._startInputElement) === null || _a === void 0 ? void 0 : _a.setAttribute('aria-valuetext', labelStart);
        this._endInputElement.setAttribute('aria-valuetext', labelEnd);
    }
    updateHandleLayering() {
        const isEndFocused = this._endInputElement.matches(':focus');
        if (this._startHandleElement) {
            toggleClass(this._startHandleElement, !isEndFocused, SLIDER_CONSTANTS.classes.ON_TOP);
        }
        toggleClass(this._endHandleElement, isEndFocused, SLIDER_CONSTANTS.classes.ON_TOP);
    }
    tryHoverStartHandle(coords) {
        var _a, _b, _c;
        if (this._startHandleThumbElement && isPointerOverElement(coords, this._startHandleThumbElement)) {
            this._handleContainerElement.classList.add(SLIDER_CONSTANTS.classes.HOVER);
            (_a = this._startHandleElement) === null || _a === void 0 ? void 0 : _a.classList.add(SLIDER_CONSTANTS.classes.HOVER);
        }
        else if (!((_b = this._startInputElement) === null || _b === void 0 ? void 0 : _b.matches(':focus'))) {
            this._handleContainerElement.classList.remove(SLIDER_CONSTANTS.classes.HOVER);
            (_c = this._startHandleElement) === null || _c === void 0 ? void 0 : _c.classList.remove(SLIDER_CONSTANTS.classes.HOVER);
        }
    }
    tryHoverEndHandle(coords) {
        if (isPointerOverElement(coords, this._endHandleThumbElement)) {
            this._handleContainerElement.classList.add(SLIDER_CONSTANTS.classes.HOVER);
            this._endHandleElement.classList.add(SLIDER_CONSTANTS.classes.HOVER);
        }
        else if (!this._endInputElement.matches(':focus')) {
            this._handleContainerElement.classList.remove(SLIDER_CONSTANTS.classes.HOVER);
            this._endHandleElement.classList.remove(SLIDER_CONSTANTS.classes.HOVER);
        }
    }
    tryDetectOverlap() {
        if (this._startHandleElement) {
            const isOverlapping = elementsOverlapping(this._startHandleElement, this._endHandleElement);
            toggleClass(this._endHandleElement, isOverlapping, SLIDER_CONSTANTS.classes.OVERLAPPING);
            toggleClass(this._startHandleElement, isOverlapping, SLIDER_CONSTANTS.classes.OVERLAPPING);
        }
    }
    leaveHandleContainer() {
        this._handleContainerElement.classList.remove(SLIDER_CONSTANTS.classes.HOVER);
    }
    syncInputValues(valueStart, valueEnd) {
        if (this._startInputElement) {
            this._startInputElement.valueAsNumber = valueStart;
        }
        this._endInputElement.valueAsNumber = valueEnd;
        if (this._startInputElement) {
            const data = new FormData();
            data.append(this._component.nameStart, String(valueStart));
            data.append(this._component.nameEnd, String(valueEnd));
            this._component[internals].setFormValue(data);
        }
        else {
            this._component[internals].setFormValue(String(valueEnd));
        }
    }
    setRange(value) {
        var _a, _b;
        this._rootElement.classList.toggle(SLIDER_CONSTANTS.classes.RANGE, value);
        if (value) {
            // Create start input
            this._startInputElement = createStartInputElement(this._component);
            this._rootElement.insertAdjacentElement('afterbegin', this._startInputElement);
            // Ensure the end input is updated to the valueEnd property value now that we are in range mode
            this._endInputElement.valueAsNumber = this._component.valueEnd;
            // Create start handle
            const thumbLabel = this._startInputElement.value;
            this._startHandleElement = createStartHandleElement(thumbLabel);
            this._handleContainerElement.insertAdjacentElement('afterbegin', this._startHandleElement);
            this._startHandleThumbElement = getShadowElement(this._component, SLIDER_CONSTANTS.selectors.START_HANDLE_THUMB);
            this._startLabelContentElement = getShadowElement(this._component, SLIDER_CONSTANTS.selectors.START_LABEL_CONTENT);
        }
        else {
            (_a = this._startInputElement) === null || _a === void 0 ? void 0 : _a.remove();
            (_b = this._startHandleElement) === null || _b === void 0 ? void 0 : _b.remove();
            this._startInputElement = undefined;
            this._startHandleElement = undefined;
            this._startHandleThumbElement = undefined;
            this._startLabelContentElement = undefined;
        }
    }
    setTickmarks(value) {
        this._trackElement.classList.toggle(SLIDER_CONSTANTS.classes.TICKMARKS, value);
    }
    setStep(step) {
        const inputs = this._getInputs();
        inputs.forEach(input => input.step = String(step));
    }
    setMin(value) {
        const inputs = this._getInputs();
        inputs.forEach(input => input.min = String(value));
    }
    setMax(value) {
        const inputs = this._getInputs();
        inputs.forEach(input => input.max = String(value));
    }
    setDisabled(value) {
        const inputs = this._getInputs();
        inputs.forEach(input => input.disabled = value);
        const stateLayers = this._rootElement.querySelectorAll(STATE_LAYER_CONSTANTS.elementName);
        stateLayers.forEach(sl => sl.disabled = value);
    }
    setReadonly(value) {
        const inputs = this._getInputs();
        inputs.forEach(input => input.readOnly = value);
    }
    toggleLabels(value) {
        var _a;
        const labels = this._rootElement.querySelectorAll(SLIDER_CONSTANTS.selectors.LABEL);
        labels.forEach(label => label.remove());
        this._endLabelContentElement = undefined;
        this._startLabelContentElement = undefined;
        if (value) {
            const endLabelEl = createLabel(this._endInputElement.value);
            this._endHandleElement.insertAdjacentElement('beforeend', endLabelEl);
            this._endLabelContentElement = getShadowElement(this._component, SLIDER_CONSTANTS.selectors.END_LABEL_CONTENT);
            if (this._startInputElement) {
                const startLabelEl = createLabel(this._startInputElement.value);
                (_a = this._startHandleElement) === null || _a === void 0 ? void 0 : _a.insertAdjacentElement('beforeend', startLabelEl);
                this._startLabelContentElement = getShadowElement(this._component, SLIDER_CONSTANTS.selectors.START_LABEL_CONTENT);
            }
        }
    }
    setStartAriaLabel(value) {
        if (this._startInputElement) {
            toggleAttribute(this._startInputElement, !!value, 'aria-label', value);
        }
    }
    setEndAriaLabel(value) {
        toggleAttribute(this._endInputElement, !!value, 'aria-label', value);
    }
    _getInputs() {
        const inputs = [];
        if (this._startInputElement) {
            inputs.push(this._startInputElement);
        }
        return [...inputs, this._endInputElement];
    }
}
