from WidgetRedirector import WidgetRedirector
from Delegator import Delegator

class Percolator:

    def __init__(self, text):
        # XXX would be nice to inherit from Delegator
        self.text = text
        self.redir = WidgetRedirector(text)
        self.top = self.bottom = Delegator(text)
        self.bottom.insert = self.redir.register("insert", self.insert)
        self.bottom.delete = self.redir.register("delete", self.delete)
        self.filters = []

    def close(self):
        while self.top is not self.bottom:
            self.removefilter(self.top)
        self.top = None
        self.bottom.setdelegate(None); self.bottom = None
        self.redir.close(); self.redir = None
        self.text = None

    def insert(self, index, chars, tags=None):
        # Could go away if inheriting from Delegator
        self.top.insert(index, chars, tags)

    def delete(self, index1, index2=None):
        # Could go away if inheriting from Delegator
        self.top.delete(index1, index2)

    def insertfilter(self, filter):
        # Perhaps rename to pushfilter()?
        assert isinstance(filter, Delegator)
        assert filter.delegate is None
        filter.setdelegate(self.top)
        self.top = filter

    def removefilter(self, filter):
        # XXX Perhaps should only support popfilter()?
        assert isinstance(filter, Delegator)
        assert filter.delegate is not None
        f = self.top
        if f is filter:
            self.top = filter.delegate
            filter.setdelegate(None)
        else:
            while f.delegate is not filter:
                assert f is not self.bottom
                f.resetcache()
                f = f.delegate
            f.setdelegate(filter.delegate)
            filter.setdelegate(None)


def main():
    class Tracer(Delegator):
        def __init__(self, name):
            self.name = name
            Delegator.__init__(self, None)
        def insert(self, *args):
            print self.name, ": insert", args
            self.delegate.insert(*args)
        def delete(self, *args):
            print self.name, ": delete", args
            self.delegate.delete(*args)
    root = Tk()
    root.wm_protocol("WM_DELETE_WINDOW", root.quit)
    text = Text()
    text.pack()
    text.focus_set()
    p = Percolator(text)
    t1 = Tracer("t1")
    t2 = Tracer("t2")
    p.insertfilter(t1)
    p.insertfilter(t2)
    root.mainloop()
    p.removefilter(t2)
    root.mainloop()
    p.insertfilter(t2)
    p.removefilter(t1)
    root.mainloop()

if __name__ == "__main__":
    from Tkinter import *
    main()
