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