"""
An auto-completion window for IDLE, used by the AutoComplete extension
"""
from Tkinter import *
from MultiCall import MC_SHIFT
import AutoComplete

HIDE_VIRTUAL_EVENT_NAME = "<<autocompletewindow-hide>>"
HIDE_SEQUENCES = ("<FocusOut>", "<ButtonPress>")
KEYPRESS_VIRTUAL_EVENT_NAME = "<<autocompletewindow-keypress>>"
# We need to bind event beyond <Key> so that the function will be called
# before the default specific IDLE function
KEYPRESS_SEQUENCES = ("<Key>", "<Key-BackSpace>", "<Key-Return>",
                      "<Key-Up>", "<Key-Down>", "<Key-Home>", "<Key-End>")
KEYRELEASE_VIRTUAL_EVENT_NAME = "<<autocompletewindow-keyrelease>>"
KEYRELEASE_SEQUENCE = "<KeyRelease>"
LISTUPDATE_SEQUENCE = "<ButtonRelease>"
WINCONFIG_SEQUENCE = "<Configure>"
DOUBLECLICK_SEQUENCE = "<Double-ButtonRelease>"

class AutoCompleteWindow:

    def __init__(self, widget):
        # The widget (Text) on which we place the AutoCompleteWindow
        self.widget = widget
        # The widgets we create
        self.autocompletewindow = self.listbox = self.scrollbar = None
        # The default foreground and background of a selection. Saved because
        # they are changed to the regular colors of list items when the
        # completion start is not a prefix of the selected completion
        self.origselforeground = self.origselbackground = None
        # The list of completions
        self.completions = None
        # A list with more completions, or None
        self.morecompletions = None
        # The completion mode. Either AutoComplete.COMPLETE_ATTRIBUTES or
        # AutoComplete.COMPLETE_FILES
        self.mode = None
        # The current completion start, on the text box (a string)
        self.start = None
        # The index of the start of the completion
        self.startindex = None
        # The last typed start, used so that when the selection changes,
        # the new start will be as close as possible to the last typed one.
        self.lasttypedstart = None
        # Do we have an indication that the user wants the completion window
        # (for example, he clicked the list)
        self.userwantswindow = None
        # event ids
        self.hideid = self.keypressid = self.listupdateid = self.winconfigid \
        = self.keyreleaseid = self.doubleclickid                         = None

    def _change_start(self, newstart):
        i = 0
        while i < len(self.start) and i < len(newstart) and \
              self.start[i] == newstart[i]:
            i += 1
        if i < len(self.start):
            self.widget.delete("%s+%dc" % (self.startindex, i),
                               "%s+%dc" % (self.startindex, len(self.start)))
        if i < len(newstart):
            self.widget.insert("%s+%dc" % (self.startindex, i),
                               newstart[i:])
        self.start = newstart

    def _binary_search(self, s):
        """Find the first index in self.completions where completions[i] is
        greater or equal to s, or the last index if there is no such
        one."""
        i = 0; j = len(self.completions)
        while j > i:
            m = (i + j) // 2
            if self.completions[m] >= s:
                j = m
            else:
                i = m + 1
        return min(i, len(self.completions)-1)

    def _complete_string(self, s):
        """Assuming that s is the prefix of a string in self.completions,
        return the longest string which is a prefix of all the strings which
        s is a prefix of them. If s is not a prefix of a string, return s."""
        first = self._binary_search(s)
        if self.completions[first][:len(s)] != s:
            # There is not even one completion which s is a prefix of.
            return s
        # Find the end of the range of completions where s is a prefix of.
        i = first + 1
        j = len(self.completions)
        while j > i:
            m = (i + j) // 2
            if self.completions[m][:len(s)] != s:
                j = m
            else:
                i = m + 1
        last = i-1

        # We should return the maximum prefix of first and last
        i = len(s)
        while len(self.completions[first]) > i and \
              len(self.completions[last]) > i and \
              self.completions[first][i] == self.completions[last][i]:
            i += 1
        return self.completions[first][:i]

    def _selection_changed(self):
        """Should be called when the selection of the Listbox has changed.
        Updates the Listbox display and calls _change_start."""
        cursel = int(self.listbox.curselection()[0])

        self.listbox.see(cursel)

        lts = self.lasttypedstart
        selstart = self.completions[cursel]
        if self._binary_search(lts) == cursel:
            newstart = lts
        else:
            i = 0
            while i < len(lts) and i < len(selstart) and lts[i] == selstart[i]:
                i += 1
            while cursel > 0 and selstart[:i] <= self.completions[cursel-1]:
                i += 1
            newstart = selstart[:i]
        self._change_start(newstart)

        if self.completions[cursel][:len(self.start)] == self.start:
            # start is a prefix of the selected completion
            self.listbox.configure(selectbackground=self.origselbackground,
                                   selectforeground=self.origselforeground)
        else:
            self.listbox.configure(selectbackground=self.listbox.cget("bg"),
                                   selectforeground=self.listbox.cget("fg"))
            # If there are more completions, show them, and call me again.
            if self.morecompletions:
                self.completions = self.morecompletions
                self.morecompletions = None
                self.listbox.delete(0, END)
                for item in self.completions:
                    self.listbox.insert(END, item)
                self.listbox.select_set(self._binary_search(self.start))
                self._selection_changed()

    def show_window(self, comp_lists, index, complete, mode, userWantsWin):
        """Show the autocomplete list, bind events.
        If complete is True, complete the text, and if there is exactly one
        matching completion, don't open a list."""
        # Handle the start we already have
        self.completions, self.morecompletions = comp_lists
        self.mode = mode
        self.startindex = self.widget.index(index)
        self.start = self.widget.get(self.startindex, "insert")
        if complete:
            completed = self._complete_string(self.start)
            self._change_start(completed)
            i = self._binary_search(completed)
            if self.completions[i] == completed and \
               (i == len(self.completions)-1 or
                self.completions[i+1][:len(completed)] != completed):
                # There is exactly one matching completion
                return
        self.userwantswindow = userWantsWin
        self.lasttypedstart = self.start

        # Put widgets in place
        self.autocompletewindow = acw = Toplevel(self.widget)
        # Put it in a position so that it is not seen.
        acw.wm_geometry("+10000+10000")
        # Make it float
        acw.wm_overrideredirect(1)
        try:
            # This command is only needed and available on Tk >= 8.4.0 for OSX
            # Without it, call tips intrude on the typing process by grabbing
            # the focus.
            acw.tk.call("::tk::unsupported::MacWindowStyle", "style", acw._w,
                        "help", "noActivates")
        except TclError:
            pass
        self.scrollbar = scrollbar = Scrollbar(acw, orient=VERTICAL)
        self.listbox = listbox = Listbox(acw, yscrollcommand=scrollbar.set,
                                         exportselection=False, bg="white")
        for item in self.completions:
            listbox.insert(END, item)
        self.origselforeground = listbox.cget("selectforeground")
        self.origselbackground = listbox.cget("selectbackground")
        scrollbar.config(command=listbox.yview)
        scrollbar.pack(side=RIGHT, fill=Y)
        listbox.pack(side=LEFT, fill=BOTH, expand=True)

        # Initialize the listbox selection
        self.listbox.select_set(self._binary_search(self.start))
        self._selection_changed()

        # bind events
        self.hideid = self.widget.bind(HIDE_VIRTUAL_EVENT_NAME,
                                       self.hide_event)
        for seq in HIDE_SEQUENCES:
            self.widget.event_add(HIDE_VIRTUAL_EVENT_NAME, seq)
        self.keypressid = self.widget.bind(KEYPRESS_VIRTUAL_EVENT_NAME,
                                           self.keypress_event)
        for seq in KEYPRESS_SEQUENCES:
            self.widget.event_add(KEYPRESS_VIRTUAL_EVENT_NAME, seq)
        self.keyreleaseid = self.widget.bind(KEYRELEASE_VIRTUAL_EVENT_NAME,
                                             self.keyrelease_event)
        self.widget.event_add(KEYRELEASE_VIRTUAL_EVENT_NAME,KEYRELEASE_SEQUENCE)
        self.listupdateid = listbox.bind(LISTUPDATE_SEQUENCE,
                                         self.listupdate_event)
        self.winconfigid = acw.bind(WINCONFIG_SEQUENCE, self.winconfig_event)
        self.doubleclickid = listbox.bind(DOUBLECLICK_SEQUENCE,
                                          self.doubleclick_event)

    def winconfig_event(self, event):
        if not self.is_active():
            return
        # Position the completion list window
        acw = self.autocompletewindow
        self.widget.see(self.startindex)
        x, y, cx, cy = self.widget.bbox(self.startindex)
        acw.wm_geometry("+%d+%d" % (x + self.widget.winfo_rootx(),
                                    y + self.widget.winfo_rooty() \
                                    -acw.winfo_height()))


    def hide_event(self, event):
        if not self.is_active():
            return
        self.hide_window()

    def listupdate_event(self, event):
        if not self.is_active():
            return
        self.userwantswindow = True
        self._selection_changed()

    def doubleclick_event(self, event):
        # Put the selected completion in the text, and close the list
        cursel = int(self.listbox.curselection()[0])
        self._change_start(self.completions[cursel])
        self.hide_window()

    def keypress_event(self, event):
        if not self.is_active():
            return
        keysym = event.keysym
        if hasattr(event, "mc_state"):
            state = event.mc_state
        else:
            state = 0

        if (len(keysym) == 1 or keysym in ("underscore", "BackSpace")
            or (self.mode==AutoComplete.COMPLETE_FILES and keysym in
                ("period", "minus"))) \
           and not (state & ~MC_SHIFT):
            # Normal editing of text
            if len(keysym) == 1:
                self._change_start(self.start + keysym)
            elif keysym == "underscore":
                self._change_start(self.start + '_')
            elif keysym == "period":
                self._change_start(self.start + '.')
            elif keysym == "minus":
                self._change_start(self.start + '-')
            else:
                # keysym == "BackSpace"
                if len(self.start) == 0:
                    self.hide_window()
                    return
                self._change_start(self.start[:-1])
            self.lasttypedstart = self.start
            self.listbox.select_clear(0, int(self.listbox.curselection()[0]))
            self.listbox.select_set(self._binary_search(self.start))
            self._selection_changed()
            return "break"

        elif keysym == "Return" and not state:
            # If start is a prefix of the selection, or there was an indication
            # that the user used the completion window, put the selected
            # completion in the text, and close the list.
            # Otherwise, close the window and let the event through.
            cursel = int(self.listbox.curselection()[0])
            if self.completions[cursel][:len(self.start)] == self.start or \
               self.userwantswindow:
                self._change_start(self.completions[cursel])
                self.hide_window()
                return "break"
            else:
                self.hide_window()
                return

        elif (self.mode == AutoComplete.COMPLETE_ATTRIBUTES and keysym in
              ("period", "space", "parenleft", "parenright", "bracketleft",
               "bracketright")) or \
             (self.mode == AutoComplete.COMPLETE_FILES and keysym in
              ("slash", "backslash", "quotedbl", "apostrophe")) \
             and not (state & ~MC_SHIFT):
            # If start is a prefix of the selection, but is not '' when
            # completing file names, put the whole
            # selected completion. Anyway, close the list.
            cursel = int(self.listbox.curselection()[0])
            if self.completions[cursel][:len(self.start)] == self.start \
               and (self.mode==AutoComplete.COMPLETE_ATTRIBUTES or self.start):
                self._change_start(self.completions[cursel])
            self.hide_window()
            return

        elif keysym in ("Home", "End", "Prior", "Next", "Up", "Down") and \
             not state:
            # Move the selection in the listbox
            self.userwantswindow = True
            cursel = int(self.listbox.curselection()[0])
            if keysym == "Home":
                newsel = 0
            elif keysym == "End":
                newsel = len(self.completions)-1
            elif keysym in ("Prior", "Next"):
                jump = self.listbox.nearest(self.listbox.winfo_height()) - \
                       self.listbox.nearest(0)
                if keysym == "Prior":
                    newsel = max(0, cursel-jump)
                else:
                    assert keysym == "Next"
                    newsel = min(len(self.completions)-1, cursel+jump)
            elif keysym == "Up":
                newsel = max(0, cursel-1)
            else:
                assert keysym == "Down"
                newsel = min(len(self.completions)-1, cursel+1)
            self.listbox.select_clear(cursel)
            self.listbox.select_set(newsel)
            self._selection_changed()
            return "break"

        elif (keysym == "Tab" and not state):
            # The user wants a completion, but it is handled by AutoComplete
            # (not AutoCompleteWindow), so ignore.
            self.userwantswindow = True
            return

        elif reduce(lambda x, y: x or y,
                    [keysym.find(s) != -1 for s in ("Shift", "Control", "Alt",
                                                    "Meta", "Command", "Option")
                     ]):
            # A modifier key, so ignore
            return

        else:
            # Unknown event, close the window and let it through.
            self.hide_window()
            return

    def keyrelease_event(self, event):
        if not self.is_active():
            return
        if self.widget.index("insert") != \
           self.widget.index("%s+%dc" % (self.startindex, len(self.start))):
            # If we didn't catch an event which moved the insert, close window
            self.hide_window()

    def is_active(self):
        return self.autocompletewindow is not None

    def complete(self):
        self._change_start(self._complete_string(self.start))
        # The selection doesn't change.

    def hide_window(self):
        if not self.is_active():
            return

        # unbind events
        for seq in HIDE_SEQUENCES:
            self.widget.event_delete(HIDE_VIRTUAL_EVENT_NAME, seq)
        self.widget.unbind(HIDE_VIRTUAL_EVENT_NAME, self.hideid)
        self.hideid = None
        for seq in KEYPRESS_SEQUENCES:
            self.widget.event_delete(KEYPRESS_VIRTUAL_EVENT_NAME, seq)
        self.widget.unbind(KEYPRESS_VIRTUAL_EVENT_NAME, self.keypressid)
        self.keypressid = None
        self.widget.event_delete(KEYRELEASE_VIRTUAL_EVENT_NAME,
                                 KEYRELEASE_SEQUENCE)
        self.widget.unbind(KEYRELEASE_VIRTUAL_EVENT_NAME, self.keyreleaseid)
        self.keyreleaseid = None
        self.listbox.unbind(LISTUPDATE_SEQUENCE, self.listupdateid)
        self.listupdateid = None
        self.autocompletewindow.unbind(WINCONFIG_SEQUENCE, self.winconfigid)
        self.winconfigid = None

        # destroy widgets
        self.scrollbar.destroy()
        self.scrollbar = None
        self.listbox.destroy()
        self.listbox = None
        self.autocompletewindow.destroy()
        self.autocompletewindow = None
