"""A call-tip window class for Tkinter/IDLE.

After tooltip.py, which uses ideas gleaned from PySol.
Used by calltip.py.
"""
from tkinter import Label, LEFT, SOLID, TclError

from idlelib.tooltip import TooltipBase

HIDE_EVENT = "<<calltipwindow-hide>>"
HIDE_SEQUENCES = ("<Key-Escape>", "<FocusOut>")
CHECKHIDE_EVENT = "<<calltipwindow-checkhide>>"
CHECKHIDE_SEQUENCES = ("<KeyRelease>", "<ButtonRelease>")
CHECKHIDE_TIME = 100  # milliseconds

MARK_RIGHT = "calltipwindowregion_right"


class CalltipWindow(TooltipBase):
    """A call-tip widget for tkinter text widgets."""

    def __init__(self, text_widget):
        """Create a call-tip; shown by showtip().

        text_widget: a Text widget with code for which call-tips are desired
        """
        # Note: The Text widget will be accessible as self.anchor_widget
        super(CalltipWindow, self).__init__(text_widget)

        self.label = self.text = None
        self.parenline = self.parencol = self.lastline = None
        self.hideid = self.checkhideid = None
        self.checkhide_after_id = None

    def get_position(self):
        """Choose the position of the call-tip."""
        curline = int(self.anchor_widget.index("insert").split('.')[0])
        if curline == self.parenline:
            anchor_index = (self.parenline, self.parencol)
        else:
            anchor_index = (curline, 0)
        box = self.anchor_widget.bbox("%d.%d" % anchor_index)
        if not box:
            box = list(self.anchor_widget.bbox("insert"))
            # align to left of window
            box[0] = 0
            box[2] = 0
        return box[0] + 2, box[1] + box[3]

    def position_window(self):
        "Reposition the window if needed."
        curline = int(self.anchor_widget.index("insert").split('.')[0])
        if curline == self.lastline:
            return
        self.lastline = curline
        self.anchor_widget.see("insert")
        super(CalltipWindow, self).position_window()

    def showtip(self, text, parenleft, parenright):
        """Show the call-tip, bind events which will close it and reposition it.

        text: the text to display in the call-tip
        parenleft: index of the opening parenthesis in the text widget
        parenright: index of the closing parenthesis in the text widget,
                    or the end of the line if there is no closing parenthesis
        """
        # Only called in calltip.Calltip, where lines are truncated
        self.text = text
        if self.tipwindow or not self.text:
            return

        self.anchor_widget.mark_set(MARK_RIGHT, parenright)
        self.parenline, self.parencol = map(
            int, self.anchor_widget.index(parenleft).split("."))

        super(CalltipWindow, self).showtip()

        self._bind_events()

    def showcontents(self):
        """Create the call-tip widget."""
        self.label = Label(self.tipwindow, text=self.text, justify=LEFT,
                           background="#ffffd0", foreground="black",
                           relief=SOLID, borderwidth=1,
                           font=self.anchor_widget['font'])
        self.label.pack()

    def checkhide_event(self, event=None):
        """Handle CHECK_HIDE_EVENT: call hidetip or reschedule."""
        if not self.tipwindow:
            # If the event was triggered by the same event that unbound
            # this function, the function will be called nevertheless,
            # so do nothing in this case.
            return None

        # Hide the call-tip if the insertion cursor moves outside of the
        # parenthesis.
        curline, curcol = map(int, self.anchor_widget.index("insert").split('.'))
        if curline < self.parenline or \
           (curline == self.parenline and curcol <= self.parencol) or \
           self.anchor_widget.compare("insert", ">", MARK_RIGHT):
            self.hidetip()
            return "break"

        # Not hiding the call-tip.

        self.position_window()
        # Re-schedule this function to be called again in a short while.
        if self.checkhide_after_id is not None:
            self.anchor_widget.after_cancel(self.checkhide_after_id)
        self.checkhide_after_id = \
            self.anchor_widget.after(CHECKHIDE_TIME, self.checkhide_event)
        return None

    def hide_event(self, event):
        """Handle HIDE_EVENT by calling hidetip."""
        if not self.tipwindow:
            # See the explanation in checkhide_event.
            return None
        self.hidetip()
        return "break"

    def hidetip(self):
        """Hide the call-tip."""
        if not self.tipwindow:
            return

        try:
            self.label.destroy()
        except TclError:
            pass
        self.label = None

        self.parenline = self.parencol = self.lastline = None
        try:
            self.anchor_widget.mark_unset(MARK_RIGHT)
        except TclError:
            pass

        try:
            self._unbind_events()
        except (TclError, ValueError):
            # ValueError may be raised by MultiCall
            pass

        super(CalltipWindow, self).hidetip()

    def _bind_events(self):
        """Bind event handlers."""
        self.checkhideid = self.anchor_widget.bind(CHECKHIDE_EVENT,
                                                   self.checkhide_event)
        for seq in CHECKHIDE_SEQUENCES:
            self.anchor_widget.event_add(CHECKHIDE_EVENT, seq)
        self.anchor_widget.after(CHECKHIDE_TIME, self.checkhide_event)
        self.hideid = self.anchor_widget.bind(HIDE_EVENT,
                                              self.hide_event)
        for seq in HIDE_SEQUENCES:
            self.anchor_widget.event_add(HIDE_EVENT, seq)

    def _unbind_events(self):
        """Unbind event handlers."""
        for seq in CHECKHIDE_SEQUENCES:
            self.anchor_widget.event_delete(CHECKHIDE_EVENT, seq)
        self.anchor_widget.unbind(CHECKHIDE_EVENT, self.checkhideid)
        self.checkhideid = None
        for seq in HIDE_SEQUENCES:
            self.anchor_widget.event_delete(HIDE_EVENT, seq)
        self.anchor_widget.unbind(HIDE_EVENT, self.hideid)
        self.hideid = None


def _calltip_window(parent):  # htest #
    from tkinter import Toplevel, Text, LEFT, BOTH

    top = Toplevel(parent)
    top.title("Test call-tips")
    x, y = map(int, parent.geometry().split('+')[1:])
    top.geometry("250x100+%d+%d" % (x + 175, y + 150))
    text = Text(top)
    text.pack(side=LEFT, fill=BOTH, expand=1)
    text.insert("insert", "string.split")
    top.update()

    calltip = CalltipWindow(text)
    def calltip_show(event):
        calltip.showtip("(s='Hello world')", "insert", "end")
    def calltip_hide(event):
        calltip.hidetip()
    text.event_add("<<calltip-show>>", "(")
    text.event_add("<<calltip-hide>>", ")")
    text.bind("<<calltip-show>>", calltip_show)
    text.bind("<<calltip-hide>>", calltip_hide)

    text.focus_set()

if __name__ == '__main__':
    from unittest import main
    main('idlelib.idle_test.test_calltip_w', verbosity=2, exit=False)

    from idlelib.idle_test.htest import run
    run(_calltip_window)
