001 /** 002 * Created by IntelliJ IDEA. 003 * User: Wei Wang 004 * Date: May 7, 2003 005 * Time: 1:09:09 PM 006 */ 007 008 package EVolve.util.phasedetectors; 009 010 import java.util.ArrayList; 011 import java.util.HashMap; 012 import java.util.HashSet; 013 import java.util.Iterator; 014 import java.util.Stack; 015 016 import EVolve.Scene; 017 import EVolve.util.HelperFuncs; 018 import EVolve.util.phasedetectors.phasedetectorUI.PhaseDetectorToolBar; 019 import EVolve.visualization.AxesPanel; 020 021 public class PhaseUndoRedo implements Cloneable{ 022 public static final int singlePhase = 0x0, pastedPhases = 0x1; 023 public static final int triggeredPhases = 0x2, detectedPhases = 0x03; 024 public static final int entitySetPhases = 0x4; 025 private Stack undoStack, redoStack; 026 private PhaseFrame currentFrame; 027 private AxesPanel panel; 028 029 public PhaseUndoRedo(AxesPanel panel) { 030 undoStack = new Stack(); 031 redoStack = new Stack(); 032 currentFrame = new PhaseFrame(); 033 this.panel = panel; 034 } 035 036 public void undo() { 037 PhaseDetectorToolBar toolbar = Scene.getUIManager().getPhaseDetectorToolBar(); 038 039 if (currentFrame.undoList.isEmpty()) { 040 redoStack.push(currentFrame); 041 currentFrame = (PhaseFrame)undoStack.pop(); 042 } else { 043 044 currentFrame.redoList.push(currentFrame.undoList.pop()); 045 currentFrame.redoParams.push(currentFrame.undoParams.pop()); 046 047 if (currentFrame.undoList.isEmpty()&&!undoStack.isEmpty()) { 048 redoStack.push(currentFrame); 049 currentFrame = (PhaseFrame)undoStack.pop(); 050 } 051 } 052 HashMap state = null; 053 if (!currentFrame.undoParams.isEmpty()) 054 state = (HashMap)currentFrame.undoParams.peek(); 055 056 if (state != null) 057 toolbar.setToolbarParams(state); 058 update(); 059 } 060 061 public void redo() { 062 PhaseDetectorToolBar toolbar = Scene.getUIManager().getPhaseDetectorToolBar(); 063 if (currentFrame.redoList.isEmpty()) { 064 undoStack.push(currentFrame); 065 currentFrame = (PhaseFrame)redoStack.pop(); 066 if (currentFrame.undoList.isEmpty()&&!currentFrame.redoList.isEmpty()) { 067 currentFrame.undoList.push(currentFrame.redoList.pop()); 068 currentFrame.undoParams.push(currentFrame.redoParams.pop()); 069 } 070 } else { 071 currentFrame.undoList.push(currentFrame.redoList.pop()); 072 currentFrame.undoParams.push(currentFrame.redoParams.pop()); 073 } 074 HashMap state = null; 075 if (!currentFrame.undoParams.isEmpty()) 076 state = (HashMap)currentFrame.undoParams.peek(); 077 078 if (state != null) 079 toolbar.setToolbarParams(state); 080 update(); 081 } 082 083 public boolean undoable() { 084 return !(currentFrame.undoList.isEmpty() && undoStack.isEmpty()); 085 } 086 087 public boolean redoable() { 088 return !(currentFrame.redoList.isEmpty() && redoStack.isEmpty()); 089 } 090 091 public void registerAction(Object action, int desc, boolean append) { 092 PhaseDetectorToolBar toolbar = Scene.getUIManager().getPhaseDetectorToolBar(); 093 HashMap state = toolbar.getToolbarParams(); 094 switch (desc) { 095 case singlePhase: 096 case pastedPhases: 097 currentFrame.undoList.push(action); 098 currentFrame.undoParams.push(state); 099 currentFrame.redoList.clear(); 100 break; 101 case triggeredPhases: 102 case detectedPhases: 103 case entitySetPhases: 104 if (!append) { 105 undoStack.push(currentFrame); 106 currentFrame.redoList.clear(); 107 currentFrame.redoParams.clear(); 108 currentFrame = new PhaseFrame(); 109 } else { // append 110 currentFrame.redoList.clear(); 111 currentFrame.redoParams.clear(); 112 } 113 currentFrame.undoParams.push(state); 114 currentFrame.undoList.push(action); 115 break; 116 default: 117 Scene.showErrorMessage("Internal error occurred when register an action to Undo/Redo"); 118 break; 119 } 120 redoStack.clear(); 121 Scene.getUIManager().getPhaseDetectorToolBar().enableButton(true); 122 } 123 124 public void reset() { 125 undoStack.clear(); 126 redoStack.clear(); 127 currentFrame = new PhaseFrame(); 128 panel.setPhases(null); 129 } 130 131 public void update() { 132 ArrayList phases = getCurrentFramePhases(); 133 panel.setPhases(phases); 134 panel.repaint(); 135 } 136 137 public ArrayList getCurrentFramePhases() { 138 HashSet tempPhases = new HashSet(); 139 ArrayList phases = new ArrayList(); 140 141 if (currentFrame.undoList.isEmpty()) return phases; 142 143 for (int i=0; i<currentFrame.undoList.size(); i++) { 144 Object action = currentFrame.undoList.get(i); 145 if (action instanceof ArrayList) { 146 ArrayList temp = (ArrayList)action; 147 for (int j=0; j<temp.size(); j++) { 148 if (!tempPhases.contains(temp.get(j))) 149 tempPhases.add(temp.get(j)); 150 } 151 } else { 152 int aPhase = ((Integer)action).intValue(); 153 if (aPhase < 0) {// a removed phase 154 if (tempPhases.contains(new Integer(-1*aPhase))) 155 tempPhases.remove(new Integer(-1*aPhase)); 156 } else { 157 if (!tempPhases.contains(action)) 158 tempPhases.add(action); 159 } 160 } 161 } 162 163 int list[] = new int[tempPhases.size()]; 164 Iterator it = tempPhases.iterator(); 165 int i=0; 166 while (it.hasNext()) { 167 list[i++] = ((Integer)it.next()).intValue(); 168 } 169 // sort phases 170 int j=1,temp; 171 boolean done=false; 172 while((j<list.length)&&(!done)) { 173 done=true; 174 for(i=0;i<list.length-j;i++){ 175 if(list[i]>list[i+1]){ 176 done=false; 177 temp=list[i]; 178 list[i]=list[i+1]; 179 list[i+1]=temp; 180 } 181 } 182 j++; 183 } 184 185 for (i=0; i<list.length; i++) { 186 phases.add(new Integer(list[i])); 187 } 188 189 return phases; 190 } 191 192 public void setPanel(AxesPanel panel) { 193 this.panel = panel; 194 } 195 196 public Object clone() { 197 PhaseUndoRedo o = null; 198 try { 199 o = (PhaseUndoRedo)super.clone(); 200 } catch (CloneNotSupportedException e) { 201 System.out.println(e.getStackTrace()); 202 return o; 203 } 204 205 o.undoStack = HelperFuncs.cloneStack(undoStack); 206 o.redoStack = HelperFuncs.cloneStack(redoStack); 207 o.currentFrame = (PhaseFrame)currentFrame.clone(); 208 return o; 209 } 210 }