package taskblocks.modelimpl;
import java.util.ArrayList;
import java.util.List;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
public class UndoManager {
int _index;
List<UndoAction> _actions;
UndoActionGroup _group;
ChangeListener _changeListener;
public UndoManager() {
_actions = new ArrayList<UndoAction>();
}
public void beginGroup(String name) {
if(_group != null && !_group.isEmpty()) {
addActionImpl(_group);
}
_group = new UndoActionGroup(name);
}
public void endGroup() {
if(_group != null && !_group.isEmpty()) {
addActionImpl(_group);
}
_group = null;
}
private void trimToIndex() {
if(_index < _actions.size()) {
_actions.subList(_index, _actions.size()).clear();
}
}
private void addActionImpl(UndoAction a) {
_actions.add(_index, a);
_index++;
trimToIndex();
fireChange();
}
public void addAction(UndoAction a) {
if(_group != null) {
_group.addAction(a);
trimToIndex();
} else {
addActionImpl(a);
}
}
public boolean canUndo() {
return _index > 0;
}
public boolean canRedo() {
return _index < _actions.size();
}
public void undo() {
endGroup();
if(_index <= 0) {
throw new IndexOutOfBoundsException();
}
_index--;
_actions.get(_index).undo();
fireChange();
}
public void redo() {
endGroup();
if(_index >= _actions.size()) {
throw new IndexOutOfBoundsException();
}
_index++;
_actions.get(_index-1).redo();
fireChange();
}
public String getFirstUndoActionLabel() {
if(_group != null && !_group.isEmpty()) {
return _group.getUndoLabel();
}
if(_index > 0) {
return _actions.get(_index - 1).getUndoLabel();
}
return null;
}
public String getFirstRedoActionLabel() {
if(_index < _actions.size()) {
return _actions.get(_index).getRedoLabel();
}
return null;
}
public void setChangeListener(ChangeListener l) {
_changeListener = l;
}
private void fireChange() {
if(_changeListener != null) {
_changeListener.stateChanged(new ChangeEvent(this));
}
}
}