#!/usr/bin/python2.4

class Part:
    def __repr__(self):
        return str(self.revs)
    
    def __init__(self, rev, user, letter):
        self.user = user
        self.revs = [[rev, letter, False]]
    
    def add(self, rev, letter):
        self.revs.append([rev, letter, False])

    def undo(self, rev):
        for i in self.revs:
            if i[0] == rev:
                i[2] = True

    def get(self, rev):
        if self.revs[0][0] > rev or self.revs[0][2]:
            return (0,'', True) # Part doenst exist!

        near = self.revs[0]
        for i in self.revs:
            if i[0] > near[0] and i[0] <= rev and not i[2]:
                near = i
        return near
        
class Text:
    rev = 0
    lines = {}
    def insert_word(self, user, line, pos,  word):
        print 'User %i schreibt "%s" in %i:%i' % (user, word , line, pos)
        n = 0
        for i in word:
            self.insert_letter(user,line,pos+n,i, False)
            n +=1

    def insert_letter(self, user, line, pos, letter, view=True):
        if view:
            print 'User %i schreibt ein %s in %i:%i' % (user, letter , line, pos)
        p = Part(self.rev, user, letter)
        if line in self.lines:
           self.lines[line].insert(self._pos(line, pos), p)
        else:
            # new line
            self.lines[line] = [ p ]
    
    def delete(self, user, line, pos):
        print 'User %i loescht an %i:%i' % (user, line, pos)
        target = self.lines[line][ self._pos(line,pos) ]
        target.user = user # TODO
        self.edit(user, line, pos, '')

    def edit(self, user, line, pos, letter):
        target = self.lines[line][ self._pos(line,pos) ]
        if user == target.user:
            target.add(self.rev, letter)
        else:
            print 'phoese'


    def undo(self, user):
        print 'Undo! User %i' % user
        # get revsion for undo
        doRev = 0
        for i in self.lines:
            for j in self.lines[i]:
                this = j.get(self.rev)
                if not this[2] and j.user == user and this[0] > doRev:
                    doRev = this[0]

        # undo!
        for i in self.lines:
            for j in self.lines[i]:
                if j.user == user:
                    j.undo(doRev)
                    

    def render(self, rev = None):
        print 'Text:'
        if not rev:
            rev = self.rev

        output = ''
        for i in self.lines:
            for j in self.lines[i]:
                this = j.get(rev)
                output += this[1]
            output += '\n'
        return output   


    def _pos(self, line, pos, rev=None):
        if not rev:
            rev = self.rev
        internalPos = visiblePos = 0
        for i in self.lines[line]:
            if visiblePos == pos:
                return internalPos

            this = i.get(rev)
            if not this[2]:
                visiblePos += 1
            internalPos += 1
        return internalPos

text = Text()

# User 1 insert "abc", line 1
text.rev += 1
text.insert_word(1,0,0, 'abc')



print text.render()

text.rev += 1
text.delete(1,0,0)

text.rev += 1
text.delete(2,0,1)

text.rev += 1
text.delete(3,0,2)

print text.render()

text.undo(2)
text.undo(1)
text.undo(3)
# print text.lines
print text.render()

text.undo(1)

print text.render()

# print text.lines
# text.undo(2)
# print text.lines
