"""An IDLE extension to avoid having very long texts printed in the shell.

A common problem in IDLE's interactive shell is printing of large amounts of
text into the shell. This makes looking at the previous history difficult.
Worse, this can cause IDLE to become very slow, even to the point of being
completely unusable.

This extension will automatically replace long texts with a small button.
Double-cliking this button will remove it and insert the original text instead.
Middle-clicking will copy the text to the clipboard. Right-clicking will open
the text in a separate viewing window.

Additionally, any output can be manually "squeezed" by the user. This includes
output written to the standard error stream ("stderr"), such as exception
messages and their tracebacks.
"""
import re

import tkinter as tk
from tkinter.font import Font
import tkinter.messagebox as tkMessageBox

from idlelib.config import idleConf
from idlelib.textview import view_text
from idlelib.tooltip import Hovertip
from idlelib import macosx


def count_lines_with_wrapping(s, linewidth=80, tabwidth=8):
    """Count the number of lines in a given string.

    Lines are counted as if the string was wrapped so that lines are never over
    linewidth characters long.

    Tabs are considered tabwidth characters long.
    """
    pos = 0
    linecount = 1
    current_column = 0

    for m in re.finditer(r"[\t\n]", s):
        # process the normal chars up to tab or newline
        numchars = m.start() - pos
        pos += numchars
        current_column += numchars

        # deal with tab or newline
        if s[pos] == '\n':
            linecount += 1
            current_column = 0
        else:
            assert s[pos] == '\t'
            current_column += tabwidth - (current_column % tabwidth)

            # if a tab passes the end of the line, consider the entire tab as
            # being on the next line
            if current_column > linewidth:
                linecount += 1
                current_column = tabwidth

        pos += 1 # after the tab or newline

        # avoid divmod(-1, linewidth)
        if current_column > 0:
            # If the length was exactly linewidth, divmod would give (1,0),
            # even though a new line hadn't yet been started. The same is true
            # if length is any exact multiple of linewidth. Therefore, subtract
            # 1 before doing divmod, and later add 1 to the column to
            # compensate.
            lines, column = divmod(current_column - 1, linewidth)
            linecount += lines
            current_column = column + 1

    # process remaining chars (no more tabs or newlines)
    current_column += len(s) - pos
    # avoid divmod(-1, linewidth)
    if current_column > 0:
        linecount += (current_column - 1) // linewidth
    else:
        # the text ended with a newline; don't count an extra line after it
        linecount -= 1

    return linecount


class ExpandingButton(tk.Button):
    """Class for the "squeezed" text buttons used by Squeezer

    These buttons are displayed inside a Tk Text widget in place of text. A
    user can then use the button to replace it with the original text, copy
    the original text to the clipboard or view the original text in a separate
    window.

    Each button is tied to a Squeezer instance, and it knows to update the
    Squeezer instance when it is expanded (and therefore removed).
    """
    def __init__(self, s, tags, numoflines, squeezer):
        self.s = s
        self.tags = tags
        self.numoflines = numoflines
        self.squeezer = squeezer
        self.editwin = editwin = squeezer.editwin
        self.text = text = editwin.text

        # the base Text widget of the PyShell object, used to change text
        # before the iomark
        self.base_text = editwin.per.bottom

        button_text = "Squeezed text (%d lines)." % self.numoflines
        tk.Button.__init__(self, text, text=button_text,
                           background="#FFFFC0", activebackground="#FFFFE0")

        button_tooltip_text = (
            "Double-click to expand, right-click for more options."
        )
        Hovertip(self, button_tooltip_text, hover_delay=80)

        self.bind("<Double-Button-1>", self.expand)
        if macosx.isAquaTk():
            # AquaTk defines <2> as the right button, not <3>.
            self.bind("<Button-2>", self.context_menu_event)
        else:
            self.bind("<Button-3>", self.context_menu_event)
        self.selection_handle(
            lambda offset, length: s[int(offset):int(offset) + int(length)])

        self.is_dangerous = None
        self.after_idle(self.set_is_dangerous)

    def set_is_dangerous(self):
        dangerous_line_len = 50 * self.text.winfo_width()
        self.is_dangerous = (
            self.numoflines > 1000 or
            len(self.s) > 50000 or
            any(
                len(line_match.group(0)) >= dangerous_line_len
                for line_match in re.finditer(r'[^\n]+', self.s)
            )
        )

    def expand(self, event=None):
        """expand event handler

        This inserts the original text in place of the button in the Text
        widget, removes the button and updates the Squeezer instance.

        If the original text is dangerously long, i.e. expanding it could
        cause a performance degradation, ask the user for confirmation.
        """
        if self.is_dangerous is None:
            self.set_is_dangerous()
        if self.is_dangerous:
            confirm = tkMessageBox.askokcancel(
                title="Expand huge output?",
                message="\n\n".join([
                    "The squeezed output is very long: %d lines, %d chars.",
                    "Expanding it could make IDLE slow or unresponsive.",
                    "It is recommended to view or copy the output instead.",
                    "Really expand?"
                ]) % (self.numoflines, len(self.s)),
                default=tkMessageBox.CANCEL,
                parent=self.text)
            if not confirm:
                return "break"

        self.base_text.insert(self.text.index(self), self.s, self.tags)
        self.base_text.delete(self)
        self.squeezer.expandingbuttons.remove(self)

    def copy(self, event=None):
        """copy event handler

        Copy the original text to the clipboard.
        """
        self.clipboard_clear()
        self.clipboard_append(self.s)

    def view(self, event=None):
        """view event handler

        View the original text in a separate text viewer window.
        """
        view_text(self.text, "Squeezed Output Viewer", self.s,
                  modal=False, wrap='none')

    rmenu_specs = (
        # item structure: (label, method_name)
        ('copy', 'copy'),
        ('view', 'view'),
    )

    def context_menu_event(self, event):
        self.text.mark_set("insert", "@%d,%d" % (event.x, event.y))
        rmenu = tk.Menu(self.text, tearoff=0)
        for label, method_name in self.rmenu_specs:
            rmenu.add_command(label=label, command=getattr(self, method_name))
        rmenu.tk_popup(event.x_root, event.y_root)
        return "break"


class Squeezer:
    """Replace long outputs in the shell with a simple button.

    This avoids IDLE's shell slowing down considerably, and even becoming
    completely unresponsive, when very long outputs are written.
    """
    @classmethod
    def reload(cls):
        """Load class variables from config."""
        cls.auto_squeeze_min_lines = idleConf.GetOption(
            "main", "PyShell", "auto-squeeze-min-lines",
            type="int", default=50,
        )

    def __init__(self, editwin):
        """Initialize settings for Squeezer.

        editwin is the shell's Editor window.
        self.text is the editor window text widget.
        self.base_test is the actual editor window Tk text widget, rather than
            EditorWindow's wrapper.
        self.expandingbuttons is the list of all buttons representing
            "squeezed" output.
        """
        self.editwin = editwin
        self.text = text = editwin.text

        # Get the base Text widget of the PyShell object, used to change text
        # before the iomark. PyShell deliberately disables changing text before
        # the iomark via its 'text' attribute, which is actually a wrapper for
        # the actual Text widget. Squeezer, however, needs to make such changes.
        self.base_text = editwin.per.bottom

        self.expandingbuttons = []
        from idlelib.pyshell import PyShell  # done here to avoid import cycle
        if isinstance(editwin, PyShell):
            # If we get a PyShell instance, replace its write method with a
            # wrapper, which inserts an ExpandingButton instead of a long text.
            def mywrite(s, tags=(), write=editwin.write):
                # only auto-squeeze text which has just the "stdout" tag
                if tags != "stdout":
                    return write(s, tags)

                # only auto-squeeze text with at least the minimum
                # configured number of lines
                numoflines = self.count_lines(s)
                if numoflines < self.auto_squeeze_min_lines:
                    return write(s, tags)

                # create an ExpandingButton instance
                expandingbutton = ExpandingButton(s, tags, numoflines,
                                                  self)

                # insert the ExpandingButton into the Text widget
                text.mark_gravity("iomark", tk.RIGHT)
                text.window_create("iomark", window=expandingbutton,
                                   padx=3, pady=5)
                text.see("iomark")
                text.update()
                text.mark_gravity("iomark", tk.LEFT)

                # add the ExpandingButton to the Squeezer's list
                self.expandingbuttons.append(expandingbutton)

            editwin.write = mywrite

    def count_lines(self, s):
        """Count the number of lines in a given text.

        Before calculation, the tab width and line length of the text are
        fetched, so that up-to-date values are used.

        Lines are counted as if the string was wrapped so that lines are never
        over linewidth characters long.

        Tabs are considered tabwidth characters long.
        """
        # Tab width is configurable
        tabwidth = self.editwin.get_tk_tabwidth()

        # Get the Text widget's size
        linewidth = self.editwin.text.winfo_width()
        # Deduct the border and padding
        linewidth -= 2*sum([int(self.editwin.text.cget(opt))
                            for opt in ('border', 'padx')])

        # Get the Text widget's font
        font = Font(self.editwin.text, name=self.editwin.text.cget('font'))
        # Divide the size of the Text widget by the font's width.
        # According to Tk8.5 docs, the Text widget's width is set
        # according to the width of its font's '0' (zero) character,
        # so we will use this as an approximation.
        # see: http://www.tcl.tk/man/tcl8.5/TkCmd/text.htm#M-width
        linewidth //= font.measure('0')

        return count_lines_with_wrapping(s, linewidth, tabwidth)

    def squeeze_current_text_event(self, event):
        """squeeze-current-text event handler

        Squeeze the block of text inside which contains the "insert" cursor.

        If the insert cursor is not in a squeezable block of text, give the
        user a small warning and do nothing.
        """
        # set tag_name to the first valid tag found on the "insert" cursor
        tag_names = self.text.tag_names(tk.INSERT)
        for tag_name in ("stdout", "stderr"):
            if tag_name in tag_names:
                break
        else:
            # the insert cursor doesn't have a "stdout" or "stderr" tag
            self.text.bell()
            return "break"

        # find the range to squeeze
        start, end = self.text.tag_prevrange(tag_name, tk.INSERT + "+1c")
        s = self.text.get(start, end)

        # if the last char is a newline, remove it from the range
        if len(s) > 0 and s[-1] == '\n':
            end = self.text.index("%s-1c" % end)
            s = s[:-1]

        # delete the text
        self.base_text.delete(start, end)

        # prepare an ExpandingButton
        numoflines = self.count_lines(s)
        expandingbutton = ExpandingButton(s, tag_name, numoflines, self)

        # insert the ExpandingButton to the Text
        self.text.window_create(start, window=expandingbutton,
                                padx=3, pady=5)

        # insert the ExpandingButton to the list of ExpandingButtons, while
        # keeping the list ordered according to the position of the buttons in
        # the Text widget
        i = len(self.expandingbuttons)
        while i > 0 and self.text.compare(self.expandingbuttons[i-1],
                                          ">", expandingbutton):
            i -= 1
        self.expandingbuttons.insert(i, expandingbutton)

        return "break"


Squeezer.reload()


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

    # Add htest.
