#!/usr/bin/env python

from structdata import g_project
from openfilerooms import openRooms
from savefilerooms import saveRooms

class UndoRedo(object):

    """
    classe utilizzata per le operazioni di undo/redo dell'editor.
    La classe salva i vari passi, e' possibile tornare un passo indietro con
    la funzione di undo e tornare un passo avanti con quella di redo. 
    Tutte le volte che si salva un passo di modifica deve essere salvata la
    room correntemente selezionata tramite la funzione addSelectedRoom.
    La classe implementa un template observer per far agli oggetti interessati
    quando e' stato aggiunto uno step di salvataggio
    """

    def __init__(self):
        g_project.subscribe(self)
        self.reset()
        self._subscibers = []

    def reset(self):
        self._list_of_project = []
        self._add_element = True
        self._list_index = -1
        self._list_of_room = []

    def clearUndoRedoList(self):
        self.reset()

    def undo(self):
        self._list_index -= 1
        self._add_element = False
        openRooms(self._list_of_project[self._list_index])

    def redo(self):
        self._add_element = False
        self._list_index += 1
        openRooms(self._list_of_project[self._list_index])


    def getCurrentRoom(self):
        room_id = self._list_of_room[self._list_index]
        room = g_project.data['rooms'][room_id]
        return room

    def addSelectedRoom(self, room=None):
        if room is not None:
            self._list_of_room.append(room.id)
        else:
            self._list_of_room.append("")

    def moreUndo(self):
        if len(self._list_of_project) == 0:
            return False
        return (self._list_index > 0)

    def moreRedo(self):
        if len(self._list_of_project) == 0:
            return False
        return (self._list_index < len(self._list_of_project) - 1)

    def updateData(self):
        if self._add_element:
            self._list_index += 1
            if len(self._list_of_project) > 0:
                self._list_of_project = self._list_of_project[:self._list_index]
                self._list_of_room = self._list_of_room[:self._list_index]
            self._list_of_project.append(saveRooms())
        self._add_element = True
        self.notify()

    def unsubscribe(self, unsubscriber):
        self._subscibers.remove(unsubscriber)

    def subscribe(self, subscriber):
        assert subscriber not in self._subscibers
        self._subscibers.append(subscriber)

    def notify(self):
        for subscriber in self._subscibers:
            subscriber.updateData()


g_undoredo = UndoRedo()

@@ -945,32 +945,178 @@
 RedoList(self):%0A
+        %22%22%22%0A        funzione per cancellare, dal programma che utilizza la classe,%0A        tutte l'elenco di tutte le modifiche fatte%0A        %22%22%22%0A
         self.res
@@ -1432,32 +1432,151 @@
 rentRoom(self):%0A
+        %22%22%22%0A        funzione che ritorna la room che era selezionata per un certo modello%0A        dei dati%0A        %22%22%22%0A
         room_id 
@@ -1725,16 +1725,183 @@
 =None):%0A
+        %22%22%22%0A        funzione per il salvataggio della room selezionata nel momento in%0A        cui viene aggiunto un passo di modifica del modello dei dati%0A        %22%22%22%0A
         
@@ -2041,32 +2041,123 @@
 moreUndo(self):%0A
+        %22%22%22%0A        funzione che ritorna se e' possibile fare un passo di undo%0A        %22%22%22%0A
         if len(s
@@ -2264,32 +2264,123 @@
 moreRedo(self):%0A
+        %22%22%22%0A        funzione che ritorna se e' possibile fare un passo di redo%0A        %22%22%22%0A
         if len(s
@@ -2956,83 +2956,676 @@
     
-self._subscibers.remove(unsubscriber)%0A%0A    def subscribe(self, subscriber):
+%22%22%22%0A        funzione di desottoscrizione alla classe per le istanze che sono%0A        observers della classe. Prende come parametro di ingresso l'istanza%0A        che si vuole sottoscrivere. Se l'istanza non e' trovata viene%0A        lanciata un'eccezione di tipo ValueError%0A        %22%22%22%0A        self._subscibers.remove(unsubscriber)%0A%0A    def subscribe(self, subscriber):%0A        %22%22%22%0A        funzione per la sottoscrizione di un'istanza alla lista di%0A        observer della classe. Prende in ingresso l'istanza che si vuole %0A        sottoscrivere, se l'istanza e' gia' presente nell'elenco di%0A        subscribers viene lanciata un'eccezione di tipo AssertError%0A        %22%22%22
 %0A   

update docstring