1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package io.github.tonywasher.joceanus.moneywise.atlas.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.atlas.data.analysis.buckets.MoneyWiseXAnalysis;
25 import io.github.tonywasher.joceanus.moneywise.atlas.data.analysis.buckets.MoneyWiseXAnalysisDepositBucket;
26 import io.github.tonywasher.joceanus.moneywise.atlas.data.analysis.buckets.MoneyWiseXAnalysisDepositBucket.MoneyWiseXAnalysisDepositBucketList;
27 import io.github.tonywasher.joceanus.moneywise.atlas.data.analysis.buckets.MoneyWiseXAnalysisDepositCategoryBucket;
28 import io.github.tonywasher.joceanus.moneywise.atlas.data.analysis.buckets.MoneyWiseXAnalysisDepositCategoryBucket.MoneyWiseXAnalysisDepositCategoryBucketList;
29 import io.github.tonywasher.joceanus.moneywise.atlas.views.MoneyWiseXAnalysisFilter;
30 import io.github.tonywasher.joceanus.moneywise.atlas.views.MoneyWiseXAnalysisFilter.MoneyWiseXAnalysisDepositFilter;
31 import io.github.tonywasher.joceanus.moneywise.data.basic.MoneyWiseBasicDataType;
32 import io.github.tonywasher.joceanus.moneywise.data.basic.MoneyWiseDepositCategory;
33 import io.github.tonywasher.joceanus.moneywise.data.statics.MoneyWiseDepositCategoryClass;
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 MoneyWiseXDepositAnalysisSelect
56 implements MoneyWiseXAnalysisFilterSelection, 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<MoneyWiseXAnalysisDepositBucket> 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<MoneyWiseXAnalysisDepositBucket> theDepositMenu;
96
97
98
99
100 private MoneyWiseXAnalysisDepositCategoryBucketList theCategories;
101
102
103
104
105 private MoneyWiseXAnalysisDepositBucketList 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 MoneyWiseXDepositAnalysisSelect(final TethysUIFactory<?> pFactory) {
123
124 final TethysUIButtonFactory<?> myButtons = pFactory.buttonFactory();
125 theDepositButton = myButtons.newScrollButton(MoneyWiseXAnalysisDepositBucket.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 MoneyWiseXAnalysisDepositFilter 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 MoneyWiseXAnalysis pAnalysis) {
220
221 theCategories = pAnalysis.getDepositCategories();
222 theDeposits = pAnalysis.getDeposits();
223
224
225 MoneyWiseXAnalysisDepositBucket 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 MoneyWiseXAnalysisFilter<?, ?> pFilter) {
240
241 if (pFilter instanceof MoneyWiseXAnalysisDepositFilter myFilter) {
242
243 MoneyWiseXAnalysisDepositBucket myDeposit = myFilter.getBucket();
244
245
246 myDeposit = theDeposits.getMatchingDeposit(myDeposit.getAccount());
247
248
249 theState.setTheDeposit(myDeposit);
250 theState.setDateRange(myFilter.getDateRange());
251 theState.applyState();
252 }
253 }
254
255
256
257
258
259
260
261 protected MoneyWiseXAnalysisDepositBucket getDefaultDeposit(final MoneyWiseDepositCategory pCategory) {
262 return theDeposits.getDefaultDeposit(pCategory);
263 }
264
265
266
267
268 private void handleNewCategory() {
269
270 if (theState.setCategory(theCatButton.getValue())) {
271 theState.applyState();
272 theEventManager.fireEvent(PrometheusDataEvent.SELECTIONCHANGED);
273 }
274 }
275
276
277
278
279 private void handleNewDeposit() {
280
281 if (theState.setDeposit(theDepositButton.getValue())) {
282 theState.applyState();
283 theEventManager.fireEvent(PrometheusDataEvent.SELECTIONCHANGED);
284 }
285 }
286
287
288
289
290 private void buildCategoryMenu() {
291
292 theCategoryMenu.removeAllItems();
293
294
295 final Map<String, TethysUIScrollSubMenu<MoneyWiseDepositCategory>> myMap = new HashMap<>();
296
297
298 final MoneyWiseDepositCategory myCurrent = theState.getCategory();
299 TethysUIScrollItem<MoneyWiseDepositCategory> myActive = null;
300
301
302 final Iterator<MoneyWiseXAnalysisDepositCategoryBucket> myIterator = theCategories.iterator();
303 while (myIterator.hasNext()) {
304 final MoneyWiseXAnalysisDepositCategoryBucket myBucket = myIterator.next();
305
306
307 if (myBucket.getAccountCategory().isCategoryClass(MoneyWiseDepositCategoryClass.PARENT)) {
308 continue;
309 }
310
311
312 final MoneyWiseDepositCategory myParent = myBucket.getAccountCategory().getParentCategory();
313 final String myParentName = myParent.getName();
314 final TethysUIScrollSubMenu<MoneyWiseDepositCategory> myMenu = myMap.computeIfAbsent(myParentName, theCategoryMenu::addSubMenu);
315
316
317 final MoneyWiseDepositCategory myCategory = myBucket.getAccountCategory();
318 final TethysUIScrollItem<MoneyWiseDepositCategory> myItem = myMenu.getSubMenu().addItem(myCategory, myCategory.getSubCategory());
319
320
321 if (myCategory.equals(myCurrent)) {
322
323 myActive = myItem;
324 }
325 }
326
327
328 if (myActive != null) {
329 myActive.scrollToItem();
330 }
331 }
332
333
334
335
336 private void buildDepositMenu() {
337
338 theDepositMenu.removeAllItems();
339
340
341 final MoneyWiseDepositCategory myCategory = theState.getCategory();
342 final MoneyWiseXAnalysisDepositBucket myDeposit = theState.getDeposit();
343
344
345 TethysUIScrollItem<MoneyWiseXAnalysisDepositBucket> myActive = null;
346
347
348 final Iterator<MoneyWiseXAnalysisDepositBucket> myIterator = theDeposits.iterator();
349 while (myIterator.hasNext()) {
350 final MoneyWiseXAnalysisDepositBucket myBucket = myIterator.next();
351
352
353 if (!MetisDataDifference.isEqual(myCategory, myBucket.getCategory())) {
354 continue;
355 }
356
357
358 final TethysUIScrollItem<MoneyWiseXAnalysisDepositBucket> myItem = theDepositMenu.addItem(myBucket);
359
360
361 if (myBucket.equals(myDeposit)) {
362
363 myActive = myItem;
364 }
365 }
366
367
368 if (myActive != null) {
369 myActive.scrollToItem();
370 }
371 }
372
373
374
375
376 private final class MoneyWiseDepositState {
377
378
379
380 private MoneyWiseDepositCategory theCategory;
381
382
383
384
385 private MoneyWiseXAnalysisDepositBucket theDeposit;
386
387
388
389
390 private OceanusDateRange theDateRange;
391
392
393
394
395 private MoneyWiseXAnalysisDepositFilter theFilter;
396
397
398
399
400 private MoneyWiseDepositState() {
401 }
402
403
404
405
406
407
408 private MoneyWiseDepositState(final MoneyWiseDepositState pState) {
409
410 theDeposit = pState.getDeposit();
411 theCategory = pState.getCategory();
412 theDateRange = pState.getDateRange();
413 theFilter = pState.getFilter();
414 }
415
416
417
418
419
420
421 private MoneyWiseXAnalysisDepositBucket getDeposit() {
422 return theDeposit;
423 }
424
425
426
427
428
429
430 private MoneyWiseDepositCategory getCategory() {
431 return theCategory;
432 }
433
434
435
436
437
438
439 private OceanusDateRange getDateRange() {
440 return theDateRange;
441 }
442
443
444
445
446
447
448 private MoneyWiseXAnalysisDepositFilter getFilter() {
449 return theFilter;
450 }
451
452
453
454
455
456
457
458 private boolean setDeposit(final MoneyWiseXAnalysisDepositBucket pDeposit) {
459
460 if (!MetisDataDifference.isEqual(pDeposit, theDeposit)) {
461
462 setTheDeposit(pDeposit);
463 return true;
464 }
465 return false;
466 }
467
468
469
470
471
472
473 private void setTheDeposit(final MoneyWiseXAnalysisDepositBucket pDeposit) {
474
475 final MoneyWiseDepositCategory myCategory = pDeposit == null
476 ? null
477 : pDeposit.getCategory();
478 setTheDeposit(myCategory, pDeposit);
479 }
480
481
482
483
484
485
486
487 private void setTheDeposit(final MoneyWiseDepositCategory pCategory,
488 final MoneyWiseXAnalysisDepositBucket pDeposit) {
489
490 theDeposit = pDeposit;
491 theCategory = pCategory;
492
493
494 if (theDeposit != null) {
495 theFilter = new MoneyWiseXAnalysisDepositFilter(theDeposit);
496 theFilter.setDateRange(theDateRange);
497 } else {
498 theFilter = null;
499 }
500 }
501
502
503
504
505
506
507
508 private boolean setCategory(final MoneyWiseDepositCategory pCategory) {
509
510 if (!MetisDataDifference.isEqual(pCategory, theCategory)) {
511 setTheDeposit(pCategory, getDefaultDeposit(pCategory));
512 return true;
513 }
514 return false;
515 }
516
517
518
519
520
521
522 private void setDateRange(final OceanusDateRange pRange) {
523
524 theDateRange = pRange;
525 if (theFilter != null) {
526 theFilter.setDateRange(theDateRange);
527 }
528 }
529
530
531
532
533 private void applyState() {
534
535 setEnabled(true);
536 theDepositButton.setValue(theDeposit);
537 theCatButton.setValue(theCategory);
538 }
539 }
540 }