import noUiSlider from "nouislider";
import * as p from "../../../core/properties";
import { div, span, empty } from "../../../core/dom";
import { repeat } from "../../../core/util/array";
import { color2css } from "../../../core/util/color";
import { OrientedControl, OrientedControlView } from "../oriented_control";
import sliders_css, * as sliders from "../../../styles/widgets/sliders.css";
import nouislider_css from "../../../styles/widgets/nouislider.css";
import * as inputs from "../../../styles/widgets/inputs.css";
export class AbstractSliderView extends OrientedControlView {
    static __name__ = "AbstractSliderView";
    behaviour;
    connected = false;
    group_el;
    slider_el;
    title_el;
    _auto_width = "auto";
    _auto_height = "auto";
    *controls() {
        yield this.slider_el;
    }
    _noUiSlider;
    get _steps() {
        return this._noUiSlider.steps;
    }
    _update_slider() {
        this._noUiSlider.updateOptions(this._calc_to(), true);
    }
    connect_signals() {
        super.connect_signals();
        const { direction, orientation, tooltips } = this.model.properties;
        this.on_change([direction, orientation, tooltips], () => this.render());
        const { bar_color } = this.model.properties;
        this.on_change(bar_color, () => {
            this._set_bar_color();
        });
        const { value, title, show_value } = this.model.properties;
        this.on_change([value, title, show_value], () => this._update_title());
        this.on_change(value, () => this._update_slider());
    }
    stylesheets() {
        return [...super.stylesheets(), nouislider_css, sliders_css];
    }
    _update_title() {
        empty(this.title_el);
        const hide_header = this.model.title == null || (this.model.title.length == 0 && !this.model.show_value);
        this.title_el.style.display = hide_header ? "none" : "";
        if (!hide_header) {
            const { title } = this.model;
            if (title != null && title.length > 0) {
                if (this.contains_tex_string(title)) {
                    this.title_el.innerHTML = `${this.process_tex(title)}: `;
                }
                else {
                    this.title_el.textContent = `${title}: `;
                }
            }
            if (this.model.show_value) {
                const { start } = this._calc_to();
                const pretty = start.map((v) => this.pretty(v)).join(" .. ");
                this.title_el.appendChild(span({ class: sliders.slider_value }, pretty));
            }
        }
    }
    _set_bar_color() {
        if (this.connected !== false && !this.model.disabled && this.slider_el != null) {
            const connect_el = this.slider_el.querySelector(".noUi-connect");
            connect_el.style.backgroundColor = color2css(this.model.bar_color);
        }
    }
    render() {
        super.render();
        let tooltips;
        if (this.model.tooltips) {
            const formatter = {
                to: (value) => this.pretty(value),
            };
            const { start } = this._calc_to();
            tooltips = repeat(formatter, start.length);
        }
        else {
            tooltips = null;
        }
        if (this.slider_el == null) {
            this.slider_el = div();
            this._noUiSlider = noUiSlider.create(this.slider_el, {
                ...this._calc_to(),
                behaviour: this.behaviour,
                connect: this.connected,
                tooltips: tooltips ?? false,
                orientation: this.model.orientation,
                direction: this.model.direction,
            });
            this._noUiSlider.on("slide", (_, __, values) => this._slide(values));
            this._noUiSlider.on("change", (_, __, values) => this._change(values));
            const toggle_tooltip = (i, show) => {
                if (tooltips == null || this.slider_el == null) {
                    return;
                }
                const handle = this.slider_el.querySelectorAll(".noUi-handle")[i];
                const tooltip = handle.querySelector(".noUi-tooltip");
                tooltip.style.display = show ? "block" : "";
            };
            this._noUiSlider.on("start", () => this._toggle_user_select(false));
            this._noUiSlider.on("end", () => this._toggle_user_select(true));
            this._noUiSlider.on("start", (_, i) => toggle_tooltip(i, true));
            this._noUiSlider.on("end", (_, i) => toggle_tooltip(i, false));
        }
        else {
            this._update_slider();
        }
        this._set_bar_color();
        if (this.model.disabled) {
            this.slider_el.setAttribute("disabled", "true");
        }
        else {
            this.slider_el.removeAttribute("disabled");
        }
        this.title_el = div({ class: sliders.slider_title });
        this._update_title();
        this.group_el = div({ class: inputs.input_group }, this.title_el, this.slider_el);
        this.shadow_el.appendChild(this.group_el);
        this._has_finished = true;
    }
    _toggle_user_select(enable) {
        const { style } = document.body;
        const value = enable ? "" : "none";
        style.userSelect = value;
        style.webkitUserSelect = value;
    }
    _slide(values) {
        this.model.value = this._calc_from(values);
    }
    _change(values) {
        const value = this._calc_from(values);
        this.model.setv({ value, value_throttled: value });
    }
}
export class AbstractSlider extends OrientedControl {
    static __name__ = "AbstractSlider";
    constructor(attrs) {
        super(attrs);
    }
    static {
        this.define(({ Unknown, Bool, Str, Color, Enum, Nullable }) => {
            return {
                title: [Nullable(Str), ""],
                show_value: [Bool, true],
                value: [Unknown],
                value_throttled: [Unknown, p.unset, { readonly: true }],
                direction: [Enum("ltr", "rtl"), "ltr"],
                tooltips: [Bool, true],
                bar_color: [Color, "#e6e6e6"],
            };
        });
        this.override({
            width: 300, // sliders don't have any intrinsic width
        });
    }
}
//# sourceMappingURL=abstract_slider.js.map