1 package org.catacomb.numeric.data;
2
3 import java.lang.reflect.Field;
4 import java.util.ArrayList;
5 import java.util.Collection;
6 import java.util.HashMap;
7
8 import org.catacomb.datalish.RunDataBlock;
9 import org.catacomb.datalish.SpriteStore;
10 import org.catacomb.interlish.content.BasicTouchTime;
11 import org.catacomb.interlish.structure.*;
12 import org.catacomb.report.E;
13
14
15
16 public class BlockStack implements Named, TreeNode, Parent {
17
18 ArrayList<RunDataBlock> items;
19
20 String name;
21
22 ArrayList<StackSlice> slices;
23 HashMap<String, StackSlice> sliceHM;
24
25
26 BasicTouchTime changeTime;
27
28 boolean doneInit;
29
30 TreeChangeReporter tcReporter;
31
32 NumDataStore store;
33
34
35 public BlockStack(NumDataStore p, String snm) {
36 name = snm;
37 store = p;
38 doneInit = false;
39 items = new ArrayList<RunDataBlock>();
40
41 slices = new ArrayList<StackSlice>();
42 sliceHM = new HashMap<String, StackSlice>();
43 changeTime = new BasicTouchTime();
44
45 }
46
47
48 public String getName() {
49 return name;
50 }
51
52
53 public String toString() {
54 return name;
55 }
56
57
58 public Object getParent() {
59 return store;
60 }
61
62
63 public BasicTouchTime getChangeTime() {
64 return changeTime;
65 }
66
67
68 public void addToStack(RunDataBlock str) {
69 if (!doneInit) {
70 initSlices(str);
71 doneInit = true;
72 }
73 items.add(str);
74 changeTime.now();
75 reportValueChange();
76 }
77
78
79
80 public void clear() {
81 items.clear();
82 for (StackSlice ss : sliceHM.values()) {
83 ss.clear();
84 }
85 changeTime.now();
86 }
87
88
89
90
91 private void initSlices(RunDataBlock proto) {
92 HashMap<String, Object> staticsHM = new HashMap<String, Object>();
93
94
95
96 for (Field f : proto.getClass().getFields()) {
97 String fnm = f.getName();
98
99 String unit = "";
100 String title = f.getName();
101
102 String[] arrayEltNames = null;
103
104
105 if ((f.getType().isArray() && f.getType().getComponentType().equals(String.class))
106 || (f.getType().equals(XYVectorSprite.class))
107 || (f.getType().equals(XYVectorScene.class))) {
108 try {
109 Object obj = f.get(proto);
110 if (obj != null) {
111 staticsHM.put(f.getName(), obj);
112 }
113 } catch (Exception ex) {
114
115 }
116
117 } else if (f.isAnnotationPresent(Quantity.class)) {
118 Quantity q = f.getAnnotation(Quantity.class);
119 unit = q.unit();
120 title = q.title();
121
122 } else if (f.isAnnotationPresent(QuantityDA.class)) {
123 QuantityDA qda = f.getAnnotation(QuantityDA.class);
124 unit = qda.unit();
125 title = qda.title();
126 String nameSet = qda.nameSet();
127
128 if (nameSet != null && nameSet.length() > 0) {
129 if (staticsHM.containsKey(qda.nameSet())) {
130 arrayEltNames = (String[])(staticsHM.get(nameSet));
131 } else {
132 E.warning("ref to names set " + nameSet + " - not found");
133 }
134 }
135
136 } else if (f.isAnnotationPresent(SpriteState.class)) {
137 SpriteState spr = f.getAnnotation(SpriteState.class);
138 title = spr.title();
139
140
141 } else if (f.isAnnotationPresent(MultiSprites.class)) {
142 MultiSprites spr = f.getAnnotation(MultiSprites.class);
143 title = spr.title();
144
145
146 } else {
147 E.warning("all fields in blocks should be annotated with a Quantity " + " annotation: "
148 + f.getName() + " in " + proto);
149
150
151 }
152
153
154 if (f.isAnnotationPresent(MultiSprites.class)) {
155 MultiSprites spr = f.getAnnotation(MultiSprites.class);
156 title = spr.title();
157 SpriteStore ss = store.getSpriteStore();
158
159 AnimSlice ans = new AnimSlice(this, fnm, f, title, ss);
160 sliceHM.put(fnm, ans);
161 slices.add(ans);
162
163
164
165 } else if (f.getType().equals(Double.TYPE)) {
166 DSlice sds = new DSlice(this, fnm, f, unit, title);
167 sliceHM.put(fnm, sds);
168 slices.add(sds);
169
170 } else if (f.getType().isArray()) {
171 Class<?> ctyp = f.getType().getComponentType();
172
173 if (ctyp.equals(String.class)) {
174
175
176 } else if (ctyp.equals(Double.TYPE)) {
177 DDSlice sdas = new DDSlice(this, fnm, f, unit, title, arrayEltNames);
178 sliceHM.put(fnm, sdas);
179 slices.add(sdas);
180
181 } else if (ctyp.equals(Integer.TYPE)) {
182 E.shortWarning(" missing code for int[] arrays");
183
184 } else if (ctyp.isArray()) {
185 E.shortWarning("missing code for array of arrays");
186
187
188 } else {
189 E.error("cant handle array of type " + ctyp);
190 }
191
192 } else if (f.getType().equals(XYVectorScene.class)) {
193
194
195 } else {
196 E.error("unrecognized class " + f + " " + f.getType());
197 }
198
199 }
200 reportNewFields();
201 }
202
203
204 public int getSize() {
205 return items.size();
206 }
207
208
209 public RunDataBlock getBlock(int i) {
210 return items.get(i);
211 }
212
213
214 private void reportNewFields() {
215
216 tcReporter.nodeAddedUnder(this, null);
217 }
218
219
220 private void reportValueChange() {
221
222 }
223
224
225 public void setTreeChangeReporter(TreeChangeReporter tcr) {
226 tcReporter = tcr;
227 }
228
229
230
231 public int getChildCount() {
232 return slices.size();
233 }
234
235
236 public Object getChild(int index) {
237 return slices.get(index);
238 }
239
240
241 public int getIndexOfChild(Object child) {
242 return slices.indexOf(child);
243 }
244
245
246 public boolean isLeaf() {
247 return false;
248 }
249
250
251 public boolean hasChild(String s) {
252 return sliceHM.containsKey(s);
253 }
254
255
256 public Object getChild(String s) {
257 return sliceHM.get(s);
258 }
259
260
261 public ArrayList<StackSlice> getSlices() {
262 return slices;
263 }
264
265
266 public NumVector getFirstArraySlice() {
267 NumVector ret = null;
268 for (StackSlice ss : slices) {
269 if (ss instanceof NumVector) {
270 ret = (NumVector)ss;
271 break;
272 }
273
274 }
275 return ret;
276 }
277
278
279 public Collection<? extends AnimSlice> getMovies() {
280 ArrayList<AnimSlice> msls = new ArrayList<AnimSlice>();
281 for (StackSlice sl : slices) {
282 if (sl instanceof AnimSlice) {
283 msls.add((AnimSlice)sl);
284 }
285 }
286 return msls;
287 }
288
289 }