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.

        """
        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):
        wrapped = 0
        startline = line
        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
            if wrapped and line > startline:
                break
            col = 0
            ok = 1
            chars = text.get("%d.0" % line, "%d.0" % (line+1))
            if not chars and wrap:
                wrapped = 1
                wrap = 0
                line = 1
                chars = text.get("1.0", "2.0")
        return None

    def search_backward(self, text, prog, line, col, wrap, ok=0):
        wrapped = 0
        startline = line
        chars = text.get("%d.0" % line, "%d.0" % (line+1))
        while 1:
            m = search_reverse(prog, chars[:-1], col)
            if m:
                if ok or m.start() < col:
                    return line, m
            line = line - 1
            if wrapped and line < startline:
                break
            ok = 1
            if line <= 0:
                if not wrap:
                    break
                wrapped = 1
                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
