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.MoneyWiseXAnalysisPortfolioBucket;
26 import io.github.tonywasher.joceanus.moneywise.atlas.data.analysis.buckets.MoneyWiseXAnalysisPortfolioBucket.MoneyWiseXAnalysisPortfolioBucketList;
27 import io.github.tonywasher.joceanus.moneywise.atlas.data.analysis.buckets.MoneyWiseXAnalysisSecurityBucket;
28 import io.github.tonywasher.joceanus.moneywise.atlas.views.MoneyWiseXAnalysisFilter;
29 import io.github.tonywasher.joceanus.moneywise.atlas.views.MoneyWiseXAnalysisFilter.MoneyWiseXAnalysisSecurityFilter;
30 import io.github.tonywasher.joceanus.moneywise.data.basic.MoneyWiseBasicDataType;
31 import io.github.tonywasher.joceanus.prometheus.views.PrometheusDataEvent;
32 import io.github.tonywasher.joceanus.tethys.api.base.TethysUIComponent;
33 import io.github.tonywasher.joceanus.tethys.api.base.TethysUIConstant;
34 import io.github.tonywasher.joceanus.tethys.api.base.TethysUIEvent;
35 import io.github.tonywasher.joceanus.tethys.api.button.TethysUIButtonFactory;
36 import io.github.tonywasher.joceanus.tethys.api.button.TethysUIScrollButtonManager;
37 import io.github.tonywasher.joceanus.tethys.api.control.TethysUIControlFactory;
38 import io.github.tonywasher.joceanus.tethys.api.control.TethysUILabel;
39 import io.github.tonywasher.joceanus.tethys.api.factory.TethysUIFactory;
40 import io.github.tonywasher.joceanus.tethys.api.menu.TethysUIScrollItem;
41 import io.github.tonywasher.joceanus.tethys.api.menu.TethysUIScrollMenu;
42 import io.github.tonywasher.joceanus.tethys.api.pane.TethysUIBoxPaneManager;
43
44 import java.util.Iterator;
45
46
47
48
49 public class MoneyWiseXSecurityAnalysisSelect
50 implements MoneyWiseXAnalysisFilterSelection, OceanusEventProvider<PrometheusDataEvent> {
51
52
53
54 private static final String NLS_PORTFOLIO = MoneyWiseBasicDataType.PORTFOLIO.getItemName();
55
56
57
58
59 private static final String NLS_SECURITY = MoneyWiseBasicDataType.SECURITY.getItemName();
60
61
62
63
64 private final OceanusEventManager<PrometheusDataEvent> theEventManager;
65
66
67
68
69 private final TethysUIBoxPaneManager thePanel;
70
71
72
73
74 private final TethysUIScrollButtonManager<MoneyWiseXAnalysisSecurityBucket> theSecButton;
75
76
77
78
79 private final TethysUIScrollButtonManager<MoneyWiseXAnalysisPortfolioBucket> thePortButton;
80
81
82
83
84 private final TethysUIScrollMenu<MoneyWiseXAnalysisPortfolioBucket> thePortfolioMenu;
85
86
87
88
89 private final TethysUIScrollMenu<MoneyWiseXAnalysisSecurityBucket> theSecurityMenu;
90
91
92
93
94 private MoneyWiseXAnalysisPortfolioBucketList thePortfolios;
95
96
97
98
99 private MoneyWiseSecurityState theState;
100
101
102
103
104 private MoneyWiseSecurityState theSavePoint;
105
106
107
108
109
110
111 protected MoneyWiseXSecurityAnalysisSelect(final TethysUIFactory<?> pFactory) {
112
113 final TethysUIButtonFactory<?> myButtons = pFactory.buttonFactory();
114 theSecButton = myButtons.newScrollButton(MoneyWiseXAnalysisSecurityBucket.class);
115
116
117 thePortButton = myButtons.newScrollButton(MoneyWiseXAnalysisPortfolioBucket.class);
118
119
120 theEventManager = new OceanusEventManager<>();
121
122
123 final TethysUIControlFactory myControls = pFactory.controlFactory();
124 final TethysUILabel myPortLabel = myControls.newLabel(NLS_PORTFOLIO + TethysUIConstant.STR_COLON);
125 final TethysUILabel mySecLabel = myControls.newLabel(NLS_SECURITY + TethysUIConstant.STR_COLON);
126
127
128 thePanel = pFactory.paneFactory().newHBoxPane();
129 thePanel.addSpacer();
130 thePanel.addNode(myPortLabel);
131 thePanel.addNode(thePortButton);
132 thePanel.addStrut();
133 thePanel.addNode(mySecLabel);
134 thePanel.addNode(theSecButton);
135
136
137 theState = new MoneyWiseSecurityState();
138 theState.applyState();
139
140
141 thePortfolioMenu = thePortButton.getMenu();
142 theSecurityMenu = theSecButton.getMenu();
143
144
145 OceanusEventRegistrar<TethysUIEvent> myRegistrar = thePortButton.getEventRegistrar();
146 myRegistrar.addEventListener(TethysUIEvent.NEWVALUE, e -> handleNewPortfolio());
147 thePortButton.setMenuConfigurator(e -> buildPortfolioMenu());
148 myRegistrar = theSecButton.getEventRegistrar();
149 myRegistrar.addEventListener(TethysUIEvent.NEWVALUE, e -> handleNewSecurity());
150 theSecButton.setMenuConfigurator(e -> buildSecurityMenu());
151 }
152
153 @Override
154 public TethysUIComponent getUnderlying() {
155 return thePanel;
156 }
157
158 @Override
159 public OceanusEventRegistrar<PrometheusDataEvent> getEventRegistrar() {
160 return theEventManager.getEventRegistrar();
161 }
162
163 @Override
164 public MoneyWiseXAnalysisSecurityFilter getFilter() {
165 return theState.getFilter();
166 }
167
168 @Override
169 public boolean isAvailable() {
170 return thePortfolios != null
171 && !thePortfolios.isEmpty();
172 }
173
174
175
176
177 public void createSavePoint() {
178
179 theSavePoint = new MoneyWiseSecurityState(theState);
180 }
181
182
183
184
185 public void restoreSavePoint() {
186
187 theState = new MoneyWiseSecurityState(theSavePoint);
188
189
190 theState.applyState();
191 }
192
193 @Override
194 public void setEnabled(final boolean bEnabled) {
195
196 final boolean secAvailable = bEnabled && isAvailable();
197
198
199 theSecButton.setEnabled(secAvailable);
200 thePortButton.setEnabled(secAvailable);
201 }
202
203 @Override
204 public void setVisible(final boolean pVisible) {
205 thePanel.setVisible(pVisible);
206 }
207
208
209
210
211
212
213 public void setAnalysis(final MoneyWiseXAnalysis pAnalysis) {
214
215 thePortfolios = pAnalysis.getPortfolios();
216
217
218 MoneyWiseXAnalysisSecurityBucket mySecurity = theState.getSecurity();
219
220
221 mySecurity = mySecurity != null
222 ? thePortfolios.getMatchingSecurityHolding(mySecurity.getSecurityHolding())
223 : thePortfolios.getDefaultSecurityHolding();
224 final MoneyWiseXAnalysisPortfolioBucket myPortfolio = mySecurity != null
225 ? thePortfolios.getMatchingPortfolio(mySecurity.getPortfolio())
226 : thePortfolios.getDefaultPortfolio();
227
228
229 theState.setTheSecurity(myPortfolio, mySecurity);
230 theState.setDateRange(pAnalysis.getDateRange());
231 theState.applyState();
232 }
233
234 @Override
235 public void setFilter(final MoneyWiseXAnalysisFilter<?, ?> pFilter) {
236
237 if (pFilter instanceof MoneyWiseXAnalysisSecurityFilter myFilter) {
238
239 MoneyWiseXAnalysisSecurityBucket mySecurity = myFilter.getBucket();
240
241
242 mySecurity = thePortfolios.getMatchingSecurityHolding(mySecurity.getSecurityHolding());
243
244
245 final MoneyWiseXAnalysisPortfolioBucket myPortfolio = thePortfolios.getMatchingPortfolio(mySecurity.getPortfolio());
246
247
248 theState.setTheSecurity(myPortfolio, mySecurity);
249 theState.setDateRange(myFilter.getDateRange());
250 theState.applyState();
251 }
252 }
253
254
255
256
257 private void handleNewPortfolio() {
258
259 if (theState.setPortfolio(thePortButton.getValue())) {
260 theState.applyState();
261 theEventManager.fireEvent(PrometheusDataEvent.SELECTIONCHANGED);
262 }
263 }
264
265
266
267
268 private void handleNewSecurity() {
269
270 if (theState.setSecurity(theSecButton.getValue())) {
271 theState.applyState();
272 theEventManager.fireEvent(PrometheusDataEvent.SELECTIONCHANGED);
273 }
274 }
275
276
277
278
279 private void buildPortfolioMenu() {
280
281 thePortfolioMenu.removeAllItems();
282
283
284 TethysUIScrollItem<MoneyWiseXAnalysisPortfolioBucket> myActive = null;
285 final MoneyWiseXAnalysisPortfolioBucket myCurr = theState.getPortfolio();
286
287
288 final Iterator<MoneyWiseXAnalysisPortfolioBucket> myIterator = thePortfolios.iterator();
289 while (myIterator.hasNext()) {
290 final MoneyWiseXAnalysisPortfolioBucket myBucket = myIterator.next();
291
292
293 final TethysUIScrollItem<MoneyWiseXAnalysisPortfolioBucket> myItem = thePortfolioMenu.addItem(myBucket);
294
295
296 if (myBucket.equals(myCurr)) {
297
298 myActive = myItem;
299 }
300 }
301
302
303 if (myActive != null) {
304 myActive.scrollToItem();
305 }
306 }
307
308
309
310
311 private void buildSecurityMenu() {
312
313 theSecurityMenu.removeAllItems();
314
315
316 final MoneyWiseXAnalysisPortfolioBucket myPortfolio = theState.getPortfolio();
317 final MoneyWiseXAnalysisSecurityBucket myCurr = theState.getSecurity();
318 TethysUIScrollItem<MoneyWiseXAnalysisSecurityBucket> myActive = null;
319
320
321 final Iterator<MoneyWiseXAnalysisSecurityBucket> myIterator = myPortfolio.securityIterator();
322 while (myIterator.hasNext()) {
323 final MoneyWiseXAnalysisSecurityBucket myBucket = myIterator.next();
324
325
326 final TethysUIScrollItem<MoneyWiseXAnalysisSecurityBucket> myItem = theSecurityMenu.addItem(myBucket, myBucket.getSecurityName());
327
328
329 if (myBucket.equals(myCurr)) {
330
331 myActive = myItem;
332 }
333 }
334
335
336 if (myActive != null) {
337 myActive.scrollToItem();
338 }
339 }
340
341
342
343
344 private final class MoneyWiseSecurityState {
345
346
347
348 private MoneyWiseXAnalysisPortfolioBucket thePortfolio;
349
350
351
352
353 private MoneyWiseXAnalysisSecurityBucket theSecurity;
354
355
356
357
358 private OceanusDateRange theDateRange;
359
360
361
362
363 private MoneyWiseXAnalysisSecurityFilter theFilter;
364
365
366
367
368 private MoneyWiseSecurityState() {
369 }
370
371
372
373
374
375
376 private MoneyWiseSecurityState(final MoneyWiseSecurityState pState) {
377
378 theSecurity = pState.getSecurity();
379 thePortfolio = pState.getPortfolio();
380 theDateRange = pState.getDateRange();
381 theFilter = pState.getFilter();
382 }
383
384
385
386
387
388
389 private MoneyWiseXAnalysisSecurityBucket getSecurity() {
390 return theSecurity;
391 }
392
393
394
395
396
397
398 private MoneyWiseXAnalysisPortfolioBucket getPortfolio() {
399 return thePortfolio;
400 }
401
402
403
404
405
406
407 private OceanusDateRange getDateRange() {
408 return theDateRange;
409 }
410
411
412
413
414
415
416 private MoneyWiseXAnalysisSecurityFilter getFilter() {
417 return theFilter;
418 }
419
420
421
422
423
424
425
426 private boolean setSecurity(final MoneyWiseXAnalysisSecurityBucket pSecurity) {
427
428 if (!MetisDataDifference.isEqual(pSecurity, theSecurity)) {
429
430 setTheSecurity(thePortfolio, pSecurity);
431 return true;
432 }
433 return false;
434 }
435
436
437
438
439
440
441
442 private void setTheSecurity(final MoneyWiseXAnalysisPortfolioBucket pPortfolio,
443 final MoneyWiseXAnalysisSecurityBucket pSecurity) {
444
445 thePortfolio = pPortfolio;
446 theSecurity = pSecurity;
447 if (theSecurity != null) {
448 theFilter = new MoneyWiseXAnalysisSecurityFilter(theSecurity);
449 theFilter.setDateRange(theDateRange);
450 } else {
451 theFilter = null;
452 }
453 }
454
455
456
457
458
459
460
461 private boolean setPortfolio(final MoneyWiseXAnalysisPortfolioBucket pPortfolio) {
462
463 if (!MetisDataDifference.isEqual(pPortfolio, thePortfolio)) {
464 setTheSecurity(pPortfolio, getFirstSecurity(pPortfolio));
465 return true;
466 }
467 return false;
468 }
469
470
471
472
473
474
475
476 private MoneyWiseXAnalysisSecurityBucket getFirstSecurity(final MoneyWiseXAnalysisPortfolioBucket pPortfolio) {
477
478 final Iterator<MoneyWiseXAnalysisSecurityBucket> myIterator = pPortfolio.securityIterator();
479 return myIterator.hasNext()
480 ? myIterator.next()
481 : null;
482 }
483
484
485
486
487
488
489 private void setDateRange(final OceanusDateRange pRange) {
490
491 theDateRange = pRange;
492 if (theFilter != null) {
493 theFilter.setDateRange(theDateRange);
494 }
495 }
496
497
498
499
500 private void applyState() {
501
502 setEnabled(true);
503 theSecButton.setValue(theSecurity, theSecurity == null
504 ? null
505 : theSecurity.getSecurityName());
506 thePortButton.setValue(thePortfolio);
507 }
508 }
509 }