1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package io.github.tonywasher.joceanus.moneywise.lethe.ui.controls;
18
19 import io.github.tonywasher.joceanus.oceanus.date.OceanusDateRange;
20 import io.github.tonywasher.joceanus.oceanus.event.OceanusEventManager;
21 import io.github.tonywasher.joceanus.oceanus.event.OceanusEventRegistrar;
22 import io.github.tonywasher.joceanus.oceanus.event.OceanusEventRegistrar.OceanusEventProvider;
23 import io.github.tonywasher.joceanus.metis.data.MetisDataDifference;
24 import io.github.tonywasher.joceanus.moneywise.data.basic.MoneyWiseBasicDataType;
25 import io.github.tonywasher.joceanus.moneywise.data.basic.MoneyWiseDepositCategory;
26 import io.github.tonywasher.joceanus.moneywise.data.statics.MoneyWiseDepositCategoryClass;
27 import io.github.tonywasher.joceanus.moneywise.lethe.data.analysis.data.MoneyWiseAnalysis;
28 import io.github.tonywasher.joceanus.moneywise.lethe.data.analysis.data.MoneyWiseAnalysisDepositBucket;
29 import io.github.tonywasher.joceanus.moneywise.lethe.data.analysis.data.MoneyWiseAnalysisDepositBucket.MoneyWiseAnalysisDepositBucketList;
30 import io.github.tonywasher.joceanus.moneywise.lethe.data.analysis.data.MoneyWiseAnalysisDepositCategoryBucket;
31 import io.github.tonywasher.joceanus.moneywise.lethe.data.analysis.data.MoneyWiseAnalysisDepositCategoryBucket.MoneyWiseAnalysisDepositCategoryBucketList;
32 import io.github.tonywasher.joceanus.moneywise.lethe.views.MoneyWiseAnalysisFilter;
33 import io.github.tonywasher.joceanus.moneywise.lethe.views.MoneyWiseAnalysisFilter.MoneyWiseAnalysisDepositFilter;
34 import io.github.tonywasher.joceanus.prometheus.views.PrometheusDataEvent;
35 import io.github.tonywasher.joceanus.tethys.api.base.TethysUIComponent;
36 import io.github.tonywasher.joceanus.tethys.api.base.TethysUIConstant;
37 import io.github.tonywasher.joceanus.tethys.api.base.TethysUIEvent;
38 import io.github.tonywasher.joceanus.tethys.api.button.TethysUIButtonFactory;
39 import io.github.tonywasher.joceanus.tethys.api.button.TethysUIScrollButtonManager;
40 import io.github.tonywasher.joceanus.tethys.api.control.TethysUIControlFactory;
41 import io.github.tonywasher.joceanus.tethys.api.control.TethysUILabel;
42 import io.github.tonywasher.joceanus.tethys.api.factory.TethysUIFactory;
43 import io.github.tonywasher.joceanus.tethys.api.menu.TethysUIScrollItem;
44 import io.github.tonywasher.joceanus.tethys.api.menu.TethysUIScrollMenu;
45 import io.github.tonywasher.joceanus.tethys.api.menu.TethysUIScrollSubMenu;
46 import io.github.tonywasher.joceanus.tethys.api.pane.TethysUIBoxPaneManager;
47
48 import java.util.HashMap;
49 import java.util.Iterator;
50 import java.util.Map;
51
52
53
54
55 public class MoneyWiseDepositAnalysisSelect
56 implements MoneyWiseAnalysisFilterSelection, OceanusEventProvider<PrometheusDataEvent> {
57
58
59
60 private static final String NLS_CATEGORY = MoneyWiseBasicDataType.DEPOSITCATEGORY.getItemName();
61
62
63
64
65 private static final String NLS_DEPOSIT = MoneyWiseBasicDataType.DEPOSIT.getItemName();
66
67
68
69
70 private final OceanusEventManager<PrometheusDataEvent> theEventManager;
71
72
73
74
75 private final TethysUIBoxPaneManager thePanel;
76
77
78
79
80 private final TethysUIScrollButtonManager<MoneyWiseAnalysisDepositBucket> theDepositButton;
81
82
83
84
85 private final TethysUIScrollButtonManager<MoneyWiseDepositCategory> theCatButton;
86
87
88
89
90 private final TethysUIScrollMenu<MoneyWiseDepositCategory> theCategoryMenu;
91
92
93
94
95 private final TethysUIScrollMenu<MoneyWiseAnalysisDepositBucket> theDepositMenu;
96
97
98
99
100 private MoneyWiseAnalysisDepositCategoryBucketList theCategories;
101
102
103
104
105 private MoneyWiseAnalysisDepositBucketList theDeposits;
106
107
108
109
110 private MoneyWiseDepositState theState;
111
112
113
114
115 private MoneyWiseDepositState theSavePoint;
116
117
118
119
120
121
122 protected MoneyWiseDepositAnalysisSelect(final TethysUIFactory<?> pFactory) {
123
124 final TethysUIButtonFactory<?> myButtons = pFactory.buttonFactory();
125 theDepositButton = myButtons.newScrollButton(MoneyWiseAnalysisDepositBucket.class);
126
127
128 theCatButton = myButtons.newScrollButton(MoneyWiseDepositCategory.class);
129
130
131 theEventManager = new OceanusEventManager<>();
132
133
134 final TethysUIControlFactory myControls = pFactory.controlFactory();
135 final TethysUILabel myCatLabel = myControls.newLabel(NLS_CATEGORY + TethysUIConstant.STR_COLON);
136 final TethysUILabel myDepLabel = myControls.newLabel(NLS_DEPOSIT + TethysUIConstant.STR_COLON);
137
138
139 thePanel = pFactory.paneFactory().newHBoxPane();
140 thePanel.addSpacer();
141 thePanel.addNode(myCatLabel);
142 thePanel.addNode(theCatButton);
143 thePanel.addStrut();
144 thePanel.addNode(myDepLabel);
145 thePanel.addNode(theDepositButton);
146
147
148 theState = new MoneyWiseDepositState();
149 theState.applyState();
150
151
152 theCategoryMenu = theCatButton.getMenu();
153 theDepositMenu = theDepositButton.getMenu();
154
155
156 OceanusEventRegistrar<TethysUIEvent> myRegistrar = theCatButton.getEventRegistrar();
157 myRegistrar.addEventListener(TethysUIEvent.NEWVALUE, e -> handleNewCategory());
158 theCatButton.setMenuConfigurator(e -> buildCategoryMenu());
159 myRegistrar = theDepositButton.getEventRegistrar();
160 myRegistrar.addEventListener(TethysUIEvent.NEWVALUE, e -> handleNewDeposit());
161 theDepositButton.setMenuConfigurator(e -> buildDepositMenu());
162 }
163
164 @Override
165 public TethysUIComponent getUnderlying() {
166 return thePanel;
167 }
168
169 @Override
170 public OceanusEventRegistrar<PrometheusDataEvent> getEventRegistrar() {
171 return theEventManager.getEventRegistrar();
172 }
173
174 @Override
175 public MoneyWiseAnalysisDepositFilter getFilter() {
176 return theState.getFilter();
177 }
178
179 @Override
180 public boolean isAvailable() {
181 return theDeposits != null
182 && !theDeposits.isEmpty();
183 }
184
185
186
187
188 protected void createSavePoint() {
189
190 theSavePoint = new MoneyWiseDepositState(theState);
191 }
192
193
194
195
196 protected void restoreSavePoint() {
197
198 theState = new MoneyWiseDepositState(theSavePoint);
199
200
201 theState.applyState();
202 }
203
204 @Override
205 public void setEnabled(final boolean bEnabled) {
206
207 final boolean dpAvailable = bEnabled && isAvailable();
208
209
210 theDepositButton.setEnabled(dpAvailable);
211 theCatButton.setEnabled(dpAvailable);
212 }
213
214
215
216
217
218
219 public void setAnalysis(final MoneyWiseAnalysis pAnalysis) {
220
221 theCategories = pAnalysis.getDepositCategories();
222 theDeposits = pAnalysis.getDeposits();
223
224
225 MoneyWiseAnalysisDepositBucket myDeposit = theState.getDeposit();
226
227
228 myDeposit = myDeposit != null
229 ? theDeposits.getMatchingDeposit(myDeposit.getAccount())
230 : theDeposits.getDefaultDeposit();
231
232
233 theState.setTheDeposit(myDeposit);
234 theState.setDateRange(pAnalysis.getDateRange());
235 theState.applyState();
236 }
237
238 @Override
239 public void setFilter(final MoneyWiseAnalysisFilter<?, ?> pFilter) {
240
241 if (pFilter instanceof MoneyWiseAnalysisDepositFilter) {
242
243 final MoneyWiseAnalysisDepositFilter myFilter = (MoneyWiseAnalysisDepositFilter) pFilter;
244
245
246 MoneyWiseAnalysisDepositBucket myDeposit = myFilter.getBucket();
247
248
249 myDeposit = theDeposits.getMatchingDeposit(myDeposit.getAccount());
250
251
252 theState.setTheDeposit(myDeposit);
253 theState.setDateRange(myFilter.getDateRange());
254 theState.applyState();
255 }
256 }
257
258
259
260
261
262
263
264 protected MoneyWiseAnalysisDepositBucket getDefaultDeposit(final MoneyWiseDepositCategory pCategory) {
265 return theDeposits.getDefaultDeposit(pCategory);
266 }
267
268
269
270
271 private void handleNewCategory() {
272
273 if (theState.setCategory(theCatButton.getValue())) {
274 theState.applyState();
275 theEventManager.fireEvent(PrometheusDataEvent.SELECTIONCHANGED);
276 }
277 }
278
279
280
281
282 private void handleNewDeposit() {
283
284 if (theState.setDeposit(theDepositButton.getValue())) {
285 theState.applyState();
286 theEventManager.fireEvent(PrometheusDataEvent.SELECTIONCHANGED);
287 }
288 }
289
290
291
292
293 private void buildCategoryMenu() {
294
295 theCategoryMenu.removeAllItems();
296
297
298 final Map<String, TethysUIScrollSubMenu<MoneyWiseDepositCategory>> myMap = new HashMap<>();
299
300
301 final MoneyWiseDepositCategory myCurrent = theState.getCategory();
302 TethysUIScrollItem<MoneyWiseDepositCategory> myActive = null;
303
304
305 final Iterator<MoneyWiseAnalysisDepositCategoryBucket> myIterator = theCategories.iterator();
306 while (myIterator.hasNext()) {
307 final MoneyWiseAnalysisDepositCategoryBucket myBucket = myIterator.next();
308
309
310 if (myBucket.getAccountCategory().isCategoryClass(MoneyWiseDepositCategoryClass.PARENT)) {
311 continue;
312 }
313
314
315 final MoneyWiseDepositCategory myParent = myBucket.getAccountCategory().getParentCategory();
316 final String myParentName = myParent.getName();
317 final TethysUIScrollSubMenu<MoneyWiseDepositCategory> myMenu = myMap.computeIfAbsent(myParentName, theCategoryMenu::addSubMenu);
318
319
320 final MoneyWiseDepositCategory myCategory = myBucket.getAccountCategory();
321 final TethysUIScrollItem<MoneyWiseDepositCategory> myItem = myMenu.getSubMenu().addItem(myCategory, myCategory.getSubCategory());
322
323
324 if (myCategory.equals(myCurrent)) {
325
326 myActive = myItem;
327 }
328 }
329
330
331 if (myActive != null) {
332 myActive.scrollToItem();
333 }
334 }
335
336
337
338
339 private void buildDepositMenu() {
340
341 theDepositMenu.removeAllItems();
342
343
344 final MoneyWiseDepositCategory myCategory = theState.getCategory();
345 final MoneyWiseAnalysisDepositBucket myDeposit = theState.getDeposit();
346
347
348 TethysUIScrollItem<MoneyWiseAnalysisDepositBucket> myActive = null;
349
350
351 final Iterator<MoneyWiseAnalysisDepositBucket> myIterator = theDeposits.iterator();
352 while (myIterator.hasNext()) {
353 final MoneyWiseAnalysisDepositBucket myBucket = myIterator.next();
354
355
356 if (!MetisDataDifference.isEqual(myCategory, myBucket.getCategory())) {
357 continue;
358 }
359
360
361 final TethysUIScrollItem<MoneyWiseAnalysisDepositBucket> myItem = theDepositMenu.addItem(myBucket);
362
363
364 if (myBucket.equals(myDeposit)) {
365
366 myActive = myItem;
367 }
368 }
369
370
371 if (myActive != null) {
372 myActive.scrollToItem();
373 }
374 }
375
376
377
378
379 private final class MoneyWiseDepositState {
380
381
382
383 private MoneyWiseDepositCategory theCategory;
384
385
386
387
388 private MoneyWiseAnalysisDepositBucket theDeposit;
389
390
391
392
393 private OceanusDateRange theDateRange;
394
395
396
397
398 private MoneyWiseAnalysisDepositFilter theFilter;
399
400
401
402
403 private MoneyWiseDepositState() {
404 }
405
406
407
408
409
410
411 private MoneyWiseDepositState(final MoneyWiseDepositState pState) {
412
413 theDeposit = pState.getDeposit();
414 theCategory = pState.getCategory();
415 theDateRange = pState.getDateRange();
416 theFilter = pState.getFilter();
417 }
418
419
420
421
422
423
424 private MoneyWiseAnalysisDepositBucket getDeposit() {
425 return theDeposit;
426 }
427
428
429
430
431
432
433 private MoneyWiseDepositCategory getCategory() {
434 return theCategory;
435 }
436
437
438
439
440
441
442 private OceanusDateRange getDateRange() {
443 return theDateRange;
444 }
445
446
447
448
449
450
451 private MoneyWiseAnalysisDepositFilter getFilter() {
452 return theFilter;
453 }
454
455
456
457
458
459
460
461 private boolean setDeposit(final MoneyWiseAnalysisDepositBucket pDeposit) {
462
463 if (!MetisDataDifference.isEqual(pDeposit, theDeposit)) {
464
465 setTheDeposit(pDeposit);
466 return true;
467 }
468 return false;
469 }
470
471
472
473
474
475
476 private void setTheDeposit(final MoneyWiseAnalysisDepositBucket pDeposit) {
477
478 final MoneyWiseDepositCategory myCategory = pDeposit == null
479 ? null
480 : pDeposit.getCategory();
481 setTheDeposit(myCategory, pDeposit);
482 }
483
484
485
486
487
488
489
490 private void setTheDeposit(final MoneyWiseDepositCategory pCategory,
491 final MoneyWiseAnalysisDepositBucket pDeposit) {
492
493 theDeposit = pDeposit;
494 theCategory = pCategory;
495
496
497 if (theDeposit != null) {
498 theFilter = new MoneyWiseAnalysisDepositFilter(theDeposit);
499 theFilter.setDateRange(theDateRange);
500 } else {
501 theFilter = null;
502 }
503 }
504
505
506
507
508
509
510
511 private boolean setCategory(final MoneyWiseDepositCategory pCategory) {
512
513 if (!MetisDataDifference.isEqual(pCategory, theCategory)) {
514 setTheDeposit(pCategory, getDefaultDeposit(pCategory));
515 return true;
516 }
517 return false;
518 }
519
520
521
522
523
524
525 private void setDateRange(final OceanusDateRange pRange) {
526
527 theDateRange = pRange;
528 if (theFilter != null) {
529 theFilter.setDateRange(theDateRange);
530 }
531 }
532
533
534
535
536 private void applyState() {
537
538 setEnabled(true);
539 theDepositButton.setValue(theDeposit);
540 theCatButton.setValue(theCategory);
541 }
542 }
543 }