from __future__ import annotations

from .tkstate import state


class tkCrosshairController:
    def __init__(self, events):
        self.events = events
        self.state = state(is_active=True, fig=None, entries=[])
        self._install_proxy()

    def _install_proxy(self):
        self.state.add = self.add
        self.state.activate = self.activate

    def add(self, ax, line="dashed", width=0.5, marker=None, size=3.0, color="red"):
        vline = ax.axvline(0, linestyle=line, linewidth=width, color=color, visible=False)
        hline = ax.axhline(0, linestyle=line, linewidth=width, color=color, visible=False)
        point, = ax.plot([], [], marker=marker or "o", markersize=size, color=color, visible=False)
        self.state.entries.append((ax, vline, hline, point))
        return point

    def activate(self, flag=True):
        self.state.is_active = bool(flag)
        if not flag:
            for _, vline, hline, point in self.state.entries:
                vline.set_visible(False); hline.set_visible(False); point.set_visible(False)
            if self.state.fig is not None:
                self.state.fig.canvas.draw_idle()

    def register(self, fig, activate=True, on_mouse_move=None):
        self.state.fig = fig
        self.activate(activate)

        def callback(event):
            if not self.state.is_active:
                return
            changed = False
            for ax, vline, hline, point in self.state.entries:
                visible = event.inaxes is ax and event.xdata is not None and event.ydata is not None
                vline.set_visible(visible); hline.set_visible(visible); point.set_visible(visible)
                if visible:
                    vline.set_xdata([event.xdata]); hline.set_ydata([event.ydata]); point.set_data([event.xdata], [event.ydata])
                    changed = True
            if changed:
                fig.canvas.draw_idle()
            if on_mouse_move is not None:
                on_mouse_move(event)

        return self.events.connect(fig, "motion_notify_event", callback, key=("crosshair", id(fig)))
