import string
import re
from Tkinter import *
import tkMessageBox

def get(root):
    if not hasattr(root, "_searchengine"):
        root._searchengine = SearchEngine(root)
        # XXX This will never garbage-collect -- who cares
    return root._searchengine

class SearchEngine:

    def __init__(self, root):
        self.root = root
        # State shared by search, replace, and grep;
        # the search dialogs bind these to UI elements.
        self.patvar = StringVar(root)           # search pattern
        self.revar = BooleanVar(root)           # regular expression?
        self.casevar = BooleanVar(root)         # match case?
        self.wordvar = BooleanVar(root)         # match whole word?
        self.wrapvar = BooleanVar(root)         # wrap around buffer?
        self.wrapvar.set(1)                     # (on by default)
        self.backvar = BooleanVar(root)         # search backwards?

    # Access methods

    def getpat(self):
        return self.patvar.get()

    def setpat(self, pat):
        self.patvar.set(pat)

    def isre(self):
        return self.revar.get()

    def iscase(self):
        return self.casevar.get()

    def isword(self):
        return self.wordvar.get()

    def iswrap(self):
        return self.wrapvar.get()

    def isback(self):
        return self.backvar.get()

    # Higher level access methods

    def getcookedpat(self):
        pat = self.getpat()
        if not self.isre():
            pat = re.escape(pat)
        if self.isword():
            pat = r"\b%s\b" % pat
        return pat

    def getprog(self):
        pat = self.getpat()
        if not pat:
            self.report_error(pat, "Empty regular expression")
            return None
        pat = self.getcookedpat()
        flags = 0
        if not self.iscase():
            flags = flags | re.IGNORECASE
        try:
            prog = re.compile(pat, flags)
        except re.error, what:
            try:
                msg, col = what
            except:
                msg = str(what)
                col = -1
            self.report_error(pat, msg, col)
            return None
        return prog

    def report_error(self, pat, msg, col=-1):
        # Derived class could overrid this with something fancier
        msg = "Error: " + str(msg)
        if pat:
            msg = msg + "\np\Pattern: " + str(pat)
        if col >= 0:
            msg = msg + "\nOffset: " + str(col)
        tkMessageBox.showerror("Regular expression error",
                               msg, master=self.root)

    def setcookedpat(self, pat):
        if self.isre():
            pat = re.escape(pat)
        self.setpat(pat)

    def search_text(self, text, prog=None, ok=0):
        """Search a text widget for the pattern.

        If prog is given, it should be the precompiled pattern.
        Return a tuple (lineno, matchobj); None if not found.

        This obeys the wrap and direction (back) settings.

        The search starts at the selection (if there is one) or
        at the insert mark (otherwise).  If the search is forward,
        it starts at the right of the selection; for a backward
        search, it starts at the left end.  An empty match exactly
        at either end of the selection (or at the insert mark if
        there is no selection) is ignored  unless the ok flag is true
        -- this is done to guarantee progress.

        If the search is allowed to wrap around, it will return the
        original selection if (and only if) it is the only match.

        XXX When wrapping around and failing to find anything, the
        portion of the text after the selection is searched twice :-(
        """
        if not prog:
            prog = self.getprog()
            if not prog:
                return None # Compilation failed -- stop
        wrap = self.wrapvar.get()
        first, last = get_selection(text)
        if self.isback():
            if ok:
                start = last
            else:
                start = first
            line, col = get_line_col(start)
            res = self.search_backward(text, prog, line, col, wrap, ok)
        else:
            if ok:
                start = first
            else:
                start = last
            line, col = get_line_col(start)
            res = self.search_forward(text, prog, line, col, wrap, ok)
        return res

    def search_forward(self, text, prog, line, col, wrap, ok=0):
        chars = text.get("%d.0" % line, "%d.0" % (line+1))
        while chars:
            m = prog.search(chars[:-1], col)
            if m:
                if ok or m.end() > col:
                    return line, m
            line = line + 1
            col = 0
            ok = 1
            chars = text.get("%d.0" % line, "%d.0" % (line+1))
            if not chars and wrap:
                wrap = 0
                line = 1
                chars = text.get("1.0", "2.0")
        return None

    def search_backward(self, text, prog, line, col, wrap, ok=0):
        chars = text.get("%d.0" % line, "%d.0" % (line+1))
        while 1:
            m = search_reverse(prog, chars[:-1], col)
            if m:
                i, j = m.span()
                if ok or m.start() < col:
                    return line, m
            line = line - 1
            ok = 1
            if line <= 0:
                if not wrap:
                    break
                wrap = 0
                pos = text.index("end-1c")
                line, col = map(int, string.split(pos, "."))
            chars = text.get("%d.0" % line, "%d.0" % (line+1))
            col = len(chars) - 1
        return None

# Helper to search backwards in a string.
# (Optimized for the case where the pattern isn't found.)

def search_reverse(prog, chars, col):
    m = prog.search(chars)
    if not m:
        return None
    found = None
    i, j = m.span()
    while i < col and j <= col:
        found = m
        if i == j:
            j = j+1
        m = prog.search(chars, j)
        if not m:
            break
        i, j = m.span()
    return found

# Helper to get selection end points, defaulting to insert mark.
# Return a tuple of indices ("line.col" strings).

def get_selection(text):
    try:
        first = text.index("sel.first")
        last = text.index("sel.last")
    except TclError:
        first = last = None
    if not first:
        first = text.index("insert")
    if not last:
        last = first
    return first, last

# Helper to parse a text index into a (line, col) tuple.

def get_line_col(index):
    line, col = map(int, string.split(index, ".")) # Fails on invalid index
    return line, col
