from gi.repository import Adw, Gdk, GObject, Gtk


@Gtk.Template(resource_path="/org/gnome/gitlab/cheywood/Iotas/ui/index_search_header_bar.ui")
class IndexSearchHeaderBar(Adw.Bin):
    __gtype_name__ = "IndexSearchHeaderBar"
    __gsignals__ = {
        "changed": (GObject.SignalFlags.RUN_FIRST, None, ()),
    }

    _entry = Gtk.Template.Child()

    def __init__(self):
        super().__init__()
        self.__active = False

    def check_if_starting(
        self, controller: Gtk.EventControllerKey, keyval: int, state: Gdk.ModifierType
    ) -> bool:
        """Check if starting search via type to search.

        :param Gtk.EventControllerKey controller: The key controller
        :param int keyval: The key value
        :param Gdk.ModifierType state: Any modifier state
        :return: Whether search is starting
        :rtype: bool
        """
        if keyval in (
            Gdk.KEY_space,
            Gdk.KEY_Return,
            Gdk.KEY_KP_Enter,
            Gdk.KEY_Tab,
            Gdk.KEY_KP_Tab,
            Gdk.KEY_Left,
            Gdk.KEY_KP_Left,
            Gdk.KEY_Right,
            Gdk.KEY_KP_Right,
            Gdk.KEY_Home,
            Gdk.KEY_KP_Home,
            Gdk.KEY_End,
            Gdk.KEY_KP_End,
            Gdk.KEY_Page_Up,
            Gdk.KEY_KP_Page_Up,
            Gdk.KEY_Page_Down,
            Gdk.KEY_KP_Page_Down,
            Gdk.KEY_Control_L,
            Gdk.KEY_Control_R,
            Gdk.KEY_Alt_L,
            Gdk.KEY_Alt_R,
            Gdk.KEY_Meta_L,
            Gdk.KEY_Meta_R,
            Gdk.KEY_Shift_L,
            Gdk.KEY_Shift_R,
            Gdk.KEY_BackSpace,
            Gdk.KEY_Delete,
            Gdk.KEY_KP_Delete,
        ):
            return Gdk.EVENT_PROPAGATE
        elif state & (Gdk.ModifierType.CONTROL_MASK | Gdk.ModifierType.ALT_MASK):
            return Gdk.EVENT_PROPAGATE
        else:
            self._entry.set_text("")
            if controller.forward(self._entry.get_delegate()):
                return Gdk.EVENT_STOP

        return Gdk.EVENT_PROPAGATE

    def enter(self, clear_text: bool, select_all: bool) -> None:
        """Enter search.

        :param bool clear_text: Whether to clear existing text
        :param bool select_all: Whether to select all text (when not clearing)
        """
        self._entry.grab_focus()
        if clear_text:
            self._entry.set_text("")
        elif select_all:
            self._entry.select_region(0, -1)
        self.active = True

    def exit(self) -> None:
        """Exit search.

        :param bool value: New value
        """
        self.active = False

    @GObject.Property(type=bool, default=False)
    def active(self) -> bool:
        return self.__active

    @active.setter
    def active(self, value: bool) -> None:
        self.__active = value

    @GObject.Property(type=str)
    def text(self) -> str:
        return self._entry.get_text().strip()

    @text.setter
    def text(self, value: str) -> str:
        return self._entry.set_text(value)

    @Gtk.Template.Callback()
    def _on_entry_changed(self, _entry: Gtk.Editable) -> None:
        self.emit("changed")
