# The top-level data structure behind the UI. Corresponds to the MainWindow

import gtkfractal
import undo
import re

# We eavesdrop on parameter-changed notifications from the gtkfractal
# and use those to compile the history

class Model:
    def __init__(self,f):
        # undo history
        self.seq = undo.Sequence()

        # used to prevent undo/redo from triggering new commands
        self.callback_in_progress = False
        self.f = f
        self.old_f = self.f.serialize()
        self.f.connect('parameters-changed',self.onParametersChanged)

    def block_callbacks(self):
        self.callback_in_progress = True

    def unblock_callbacks(self):
        self.callback_in_progress = False

    def callbacks_allowed(self):
        return not self.callback_in_progress
    
    def onParametersChanged(self,*args):
        if not self.callbacks_allowed():
            return

        #print "before:"
        #print self.dump_history()
        
        current = self.f.serialize()

        def set_fractal(val):
            self.f.freeze()
            #print "redo:", current[:100]
            self.f.deserialize(val)
            if self.f.thaw():
                self.block_callbacks()
                self.f.changed()
                self.unblock_callbacks()
                
        self.seq.do(set_fractal,current,set_fractal,self.old_f)
        self.old_f = current

        #print "after:"
        #print self.dump_history()
        
    def extract_x_from_dump(self,dump):
        "Get (x=number) from file"
        x_re = re.compile(r'x=.*')
        m = x_re.search(dump)
        if m:
            return m.group()
        return "eek"
    
    def dump_history(self):
        i=0
        print "(redo,undo)"
        for he in self.seq.history:
            if i == self.seq.pos:
                print "-->",
            else:
                print "   ",
            print "(%s,%s)" % \
                  (self.extract_x_from_dump(he.redo_data),
                   self.extract_x_from_dump(he.undo_data))
            i += 1
        
    def undo(self):
        if self.seq.can_undo():
            #print "before undo:"
            #print self.dump_history()
            self.seq.undo()
            #print "after undo:"
            #print self.dump_history()

    def redo(self):
        if self.seq.can_redo():
            #print "before redo:"
            #print self.dump_history()
            self.seq.redo()
            #print "after redo:"
            #print self.dump_history()
