import { SelectTool, SelectToolView } from "./select_tool";
import { Modifiers, satisfies_modifiers } from "./common";
import { execute } from "../../../core/util/callbacks";
import { SelectionMode } from "../../../core/enums";
import { TapBehavior, TapGesture } from "../../../core/enums";
import { prepend } from "../../../core/util/arrayable";
import { tool_icon_tap_select, tool_icon_toggle_mode } from "../../../styles/icons.css";
export class TapToolView extends SelectToolView {
    static __name__ = "TapToolView";
    _tap(ev) {
        const is_tap = this.model.gesture == "tap";
        if (is_tap) {
            this._handle_tap(ev);
        }
        return is_tap;
    }
    _doubletap(ev) {
        const is_doubletap = this.model.gesture == "doubletap";
        if (is_doubletap) {
            this._handle_tap(ev);
        }
        return is_doubletap;
    }
    _handle_tap(ev) {
        if (!satisfies_modifiers(this.model.modifiers, ev.modifiers)) {
            return;
        }
        const { sx, sy } = ev;
        const { frame } = this.plot_view;
        if (!frame.bbox.contains(sx, sy)) {
            return;
        }
        this._clear_other_overlays();
        const geometry = { type: "point", sx, sy };
        if (this.model.behavior == "select") {
            this._select(geometry, true, this._select_mode(ev.modifiers));
        }
        else {
            this._inspect(geometry, ev.modifiers);
        }
    }
    _select(geometry, final, mode) {
        const renderers_by_source = this._computed_renderers_by_data_source();
        for (const [, renderers] of renderers_by_source) {
            const sm = renderers[0].get_selection_manager();
            const r_views = renderers.map((r) => this.plot_view.views.find_one(r)).filter((r) => r != null);
            const did_hit = sm.select(r_views, geometry, final, mode);
            if (did_hit) {
                const [rv] = r_views;
                this._emit_callback(rv, geometry, sm.source);
            }
        }
        this._emit_selection_event(geometry);
        this.plot_view.state.push("tap", { selection: this.plot_view.get_selection() });
    }
    _inspect(geometry, modifiers) {
        for (const r of this.computed_renderers) {
            const rv = this.plot_view.views.find_one(r);
            if (rv == null) {
                continue;
            }
            const sm = r.get_selection_manager();
            const did_hit = sm.inspect(rv, geometry);
            if (did_hit) {
                this._emit_callback(rv, geometry, sm.source, modifiers);
            }
        }
    }
    _emit_callback(rv, geometry, source, modifiers) {
        const { callback } = this.model;
        if (callback != null) {
            const x = rv.coordinates.x_scale.invert(geometry.sx);
            const y = rv.coordinates.y_scale.invert(geometry.sy);
            const data = {
                geometries: { ...geometry, x, y },
                source,
                event: { modifiers },
            };
            void execute(callback, this.model, data);
        }
    }
}
export class TapTool extends SelectTool {
    static __name__ = "TapTool";
    constructor(attrs) {
        super(attrs);
    }
    static {
        this.prototype.default_view = TapToolView;
        this.define(({ Any, Nullable }) => ({
            mode: [SelectionMode, "toggle"],
            behavior: [TapBehavior, "select"],
            gesture: [TapGesture, "tap"],
            modifiers: [Modifiers, {}],
            callback: [Nullable(Any /*TODO*/), null],
        }));
        this.register_alias("click", () => new TapTool({ behavior: "inspect" }));
        this.register_alias("tap", () => new TapTool());
        this.register_alias("doubletap", () => new TapTool({ gesture: "doubletap" }));
    }
    tool_name = "Tap";
    tool_icon = tool_icon_tap_select;
    event_type = "tap";
    default_order = 10;
    get menu() {
        const menu = super.menu;
        if (menu == null) {
            return null;
        }
        else {
            return prepend(menu, {
                icon: tool_icon_toggle_mode,
                tooltip: "Toggle the current selection",
                active: () => this.mode == "toggle",
                handler: () => {
                    this.mode = "toggle";
                    this.active = true;
                },
            });
        }
    }
}
//# sourceMappingURL=tap_tool.js.map