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.MoneyWiseCashCategory;
26 import io.github.tonywasher.joceanus.moneywise.data.statics.MoneyWiseCashCategoryClass;
27 import io.github.tonywasher.joceanus.moneywise.lethe.data.analysis.data.MoneyWiseAnalysis;
28 import io.github.tonywasher.joceanus.moneywise.lethe.data.analysis.data.MoneyWiseAnalysisCashBucket;
29 import io.github.tonywasher.joceanus.moneywise.lethe.data.analysis.data.MoneyWiseAnalysisCashBucket.MoneyWiseAnalysisCashBucketList;
30 import io.github.tonywasher.joceanus.moneywise.lethe.data.analysis.data.MoneyWiseAnalysisCashCategoryBucket;
31 import io.github.tonywasher.joceanus.moneywise.lethe.data.analysis.data.MoneyWiseAnalysisCashCategoryBucket.MoneyWiseAnalysisCashCategoryBucketList;
32 import io.github.tonywasher.joceanus.moneywise.lethe.views.MoneyWiseAnalysisFilter;
33 import io.github.tonywasher.joceanus.moneywise.lethe.views.MoneyWiseAnalysisFilter.MoneyWiseAnalysisCashFilter;
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 MoneyWiseCashAnalysisSelect
56 implements MoneyWiseAnalysisFilterSelection, OceanusEventProvider<PrometheusDataEvent> {
57
58
59
60 private static final String NLS_CATEGORY = MoneyWiseBasicDataType.CASHCATEGORY.getItemName();
61
62
63
64
65 private static final String NLS_CASH = MoneyWiseBasicDataType.CASH.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<MoneyWiseAnalysisCashBucket> theCashButton;
81
82
83
84
85 private final TethysUIScrollButtonManager<MoneyWiseCashCategory> theCatButton;
86
87
88
89
90 private final TethysUIScrollMenu<MoneyWiseCashCategory> theCategoryMenu;
91
92
93
94
95 private final TethysUIScrollMenu<MoneyWiseAnalysisCashBucket> theCashMenu;
96
97
98
99
100 private MoneyWiseAnalysisCashCategoryBucketList theCategories;
101
102
103
104
105 private MoneyWiseAnalysisCashBucketList theCash;
106
107
108
109
110 private MoneyWiseCashState theState;
111
112
113
114
115 private MoneyWiseCashState theSavePoint;
116
117
118
119
120
121
122 protected MoneyWiseCashAnalysisSelect(final TethysUIFactory<?> pFactory) {
123
124 final TethysUIButtonFactory<?> myButtons = pFactory.buttonFactory();
125 theCashButton = myButtons.newScrollButton(MoneyWiseAnalysisCashBucket.class);
126
127
128 theCatButton = myButtons.newScrollButton(MoneyWiseCashCategory.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 myCshLabel = myControls.newLabel(NLS_CASH + 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(myCshLabel);
145 thePanel.addNode(theCashButton);
146
147
148 theState = new MoneyWiseCashState();
149 theState.applyState();
150
151
152 theCategoryMenu = theCatButton.getMenu();
153 theCashMenu = theCashButton.getMenu();
154
155
156 OceanusEventRegistrar<TethysUIEvent> myRegistrar = theCatButton.getEventRegistrar();
157 myRegistrar.addEventListener(TethysUIEvent.NEWVALUE, e -> handleNewCategory());
158 theCatButton.setMenuConfigurator(e -> buildCategoryMenu());
159 myRegistrar = theCashButton.getEventRegistrar();
160 myRegistrar.addEventListener(TethysUIEvent.NEWVALUE, e -> handleNewCash());
161 theCashButton.setMenuConfigurator(e -> buildCashMenu());
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 MoneyWiseAnalysisCashFilter getFilter() {
176 return theState.getFilter();
177 }
178
179 @Override
180 public boolean isAvailable() {
181 return theCash != null
182 && !theCash.isEmpty();
183 }
184
185
186
187
188 protected void createSavePoint() {
189
190 theSavePoint = new MoneyWiseCashState(theState);
191 }
192
193
194
195
196 protected void restoreSavePoint() {
197
198 theState = new MoneyWiseCashState(theSavePoint);
199
200
201 theState.applyState();
202 }
203
204 @Override
205 public void setEnabled(final boolean bEnabled) {
206
207 final boolean csAvailable = bEnabled && isAvailable();
208
209
210 theCashButton.setEnabled(csAvailable);
211 theCatButton.setEnabled(csAvailable);
212 }
213
214 @Override
215 public void setVisible(final boolean pVisible) {
216 thePanel.setVisible(pVisible);
217 }
218
219
220
221
222
223
224 public void setAnalysis(final MoneyWiseAnalysis pAnalysis) {
225
226 theCategories = pAnalysis.getCashCategories();
227 theCash = pAnalysis.getCash();
228
229
230 MoneyWiseAnalysisCashBucket myCash = theState.getCash();
231
232
233 myCash = myCash != null
234 ? theCash.getMatchingCash(myCash.getAccount())
235 : theCash.getDefaultCash();
236
237
238 theState.setTheCash(myCash);
239 theState.setDateRange(pAnalysis.getDateRange());
240 theState.applyState();
241 }
242
243 @Override
244 public void setFilter(final MoneyWiseAnalysisFilter<?, ?> pFilter) {
245
246 if (pFilter instanceof MoneyWiseAnalysisCashFilter) {
247
248 final MoneyWiseAnalysisCashFilter myFilter = (MoneyWiseAnalysisCashFilter) pFilter;
249
250
251 MoneyWiseAnalysisCashBucket myCash = myFilter.getBucket();
252
253
254 myCash = theCash.getMatchingCash(myCash.getAccount());
255
256
257 theState.setTheCash(myCash);
258 theState.setDateRange(myFilter.getDateRange());
259 theState.applyState();
260 }
261 }
262
263
264
265
266
267
268
269 protected MoneyWiseAnalysisCashBucket getDefaultCash(final MoneyWiseCashCategory pCategory) {
270 return theCash.getDefaultCash(pCategory);
271 }
272
273
274
275
276 private void handleNewCategory() {
277
278 if (theState.setCategory(theCatButton.getValue())) {
279 theState.applyState();
280 theEventManager.fireEvent(PrometheusDataEvent.SELECTIONCHANGED);
281 }
282 }
283
284
285
286
287 private void handleNewCash() {
288
289 if (theState.setCash(theCashButton.getValue())) {
290 theState.applyState();
291 theEventManager.fireEvent(PrometheusDataEvent.SELECTIONCHANGED);
292 }
293 }
294
295
296
297
298 private void buildCategoryMenu() {
299
300 theCategoryMenu.removeAllItems();
301
302
303 final Map<String, TethysUIScrollSubMenu<MoneyWiseCashCategory>> myMap = new HashMap<>();
304
305
306 final MoneyWiseCashCategory myCurrent = theState.getCategory();
307 TethysUIScrollItem<MoneyWiseCashCategory> myActive = null;
308
309
310 final Iterator<MoneyWiseAnalysisCashCategoryBucket> myIterator = theCategories.iterator();
311 while (myIterator.hasNext()) {
312 final MoneyWiseAnalysisCashCategoryBucket myBucket = myIterator.next();
313
314
315 if (myBucket.getAccountCategory().isCategoryClass(MoneyWiseCashCategoryClass.PARENT)) {
316 continue;
317 }
318
319
320 final MoneyWiseCashCategory myParent = myBucket.getAccountCategory().getParentCategory();
321 final String myParentName = myParent.getName();
322 final TethysUIScrollSubMenu<MoneyWiseCashCategory> myMenu = myMap.computeIfAbsent(myParentName, theCategoryMenu::addSubMenu);
323
324
325 final MoneyWiseCashCategory myCategory = myBucket.getAccountCategory();
326 final TethysUIScrollItem<MoneyWiseCashCategory> myItem = myMenu.getSubMenu().addItem(myCategory, myCategory.getSubCategory());
327
328
329 if (myCategory.equals(myCurrent)) {
330
331 myActive = myItem;
332 }
333 }
334
335
336 if (myActive != null) {
337 myActive.scrollToItem();
338 }
339 }
340
341
342
343
344 private void buildCashMenu() {
345
346 theCashMenu.removeAllItems();
347
348
349 final MoneyWiseCashCategory myCategory = theState.getCategory();
350 final MoneyWiseAnalysisCashBucket myCash = theState.getCash();
351
352
353 TethysUIScrollItem<MoneyWiseAnalysisCashBucket> myActive = null;
354
355
356 final Iterator<MoneyWiseAnalysisCashBucket> myIterator = theCash.iterator();
357 while (myIterator.hasNext()) {
358 final MoneyWiseAnalysisCashBucket myBucket = myIterator.next();
359
360
361 if (!MetisDataDifference.isEqual(myCategory, myBucket.getCategory())) {
362 continue;
363 }
364
365
366 final TethysUIScrollItem<MoneyWiseAnalysisCashBucket> myItem = theCashMenu.addItem(myBucket);
367
368
369 if (myBucket.equals(myCash)) {
370
371 myActive = myItem;
372 }
373 }
374
375
376 if (myActive != null) {
377 myActive.scrollToItem();
378 }
379 }
380
381
382
383
384 private final class MoneyWiseCashState {
385
386
387
388 private MoneyWiseCashCategory theCategory;
389
390
391
392
393 private MoneyWiseAnalysisCashBucket theCash;
394
395
396
397
398 private OceanusDateRange theDateRange;
399
400
401
402
403 private MoneyWiseAnalysisCashFilter theFilter;
404
405
406
407
408 private MoneyWiseCashState() {
409 }
410
411
412
413
414
415
416 private MoneyWiseCashState(final MoneyWiseCashState pState) {
417
418 theCash = pState.getCash();
419 theCategory = pState.getCategory();
420 theDateRange = pState.getDateRange();
421 theFilter = pState.getFilter();
422 }
423
424
425
426
427
428
429 private MoneyWiseAnalysisCashBucket getCash() {
430 return theCash;
431 }
432
433
434
435
436
437
438 private MoneyWiseCashCategory getCategory() {
439 return theCategory;
440 }
441
442
443
444
445
446
447 private OceanusDateRange getDateRange() {
448 return theDateRange;
449 }
450
451
452
453
454
455
456 private MoneyWiseAnalysisCashFilter getFilter() {
457 return theFilter;
458 }
459
460
461
462
463
464
465
466 private boolean setCash(final MoneyWiseAnalysisCashBucket pCash) {
467
468 if (!MetisDataDifference.isEqual(pCash, theCash)) {
469
470 setTheCash(pCash);
471 return true;
472 }
473 return false;
474 }
475
476
477
478
479
480
481 private void setTheCash(final MoneyWiseAnalysisCashBucket pCash) {
482
483 final MoneyWiseCashCategory myCategory = pCash == null
484 ? null
485 : pCash.getCategory();
486 setTheCash(myCategory, pCash);
487 }
488
489
490
491
492
493
494
495 private void setTheCash(final MoneyWiseCashCategory pCategory,
496 final MoneyWiseAnalysisCashBucket pCash) {
497
498 theCash = pCash;
499 theCategory = pCategory;
500
501
502 if (theCash != null) {
503 theFilter = new MoneyWiseAnalysisCashFilter(theCash);
504 theFilter.setDateRange(theDateRange);
505 } else {
506 theFilter = null;
507 }
508 }
509
510
511
512
513
514
515
516 private boolean setCategory(final MoneyWiseCashCategory pCategory) {
517
518 if (!MetisDataDifference.isEqual(pCategory, theCategory)) {
519 setTheCash(pCategory, getDefaultCash(pCategory));
520 return true;
521 }
522 return false;
523 }
524
525
526
527
528
529
530 private void setDateRange(final OceanusDateRange pRange) {
531
532 theDateRange = pRange;
533 if (theFilter != null) {
534 theFilter.setDateRange(theDateRange);
535 }
536 }
537
538
539
540
541 private void applyState() {
542
543 setEnabled(true);
544 theCashButton.setValue(theCash);
545 theCatButton.setValue(theCategory);
546 }
547 }
548 }