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.lethe.data.analysis.data.MoneyWiseAnalysis;
26 import io.github.tonywasher.joceanus.moneywise.lethe.data.analysis.data.MoneyWiseAnalysisPortfolioBucket;
27 import io.github.tonywasher.joceanus.moneywise.lethe.data.analysis.data.MoneyWiseAnalysisPortfolioBucket.MoneyWiseAnalysisPortfolioBucketList;
28 import io.github.tonywasher.joceanus.moneywise.lethe.data.analysis.data.MoneyWiseAnalysisSecurityBucket;
29 import io.github.tonywasher.joceanus.moneywise.lethe.views.MoneyWiseAnalysisFilter;
30 import io.github.tonywasher.joceanus.moneywise.lethe.views.MoneyWiseAnalysisFilter.MoneyWiseAnalysisSecurityFilter;
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 MoneyWiseSecurityAnalysisSelect
50 implements MoneyWiseAnalysisFilterSelection, 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<MoneyWiseAnalysisSecurityBucket> theSecButton;
75
76
77
78
79 private final TethysUIScrollButtonManager<MoneyWiseAnalysisPortfolioBucket> thePortButton;
80
81
82
83
84 private final TethysUIScrollMenu<MoneyWiseAnalysisPortfolioBucket> thePortfolioMenu;
85
86
87
88
89 private final TethysUIScrollMenu<MoneyWiseAnalysisSecurityBucket> theSecurityMenu;
90
91
92
93
94 private MoneyWiseAnalysisPortfolioBucketList 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 MoneyWiseSecurityAnalysisSelect(final TethysUIFactory<?> pFactory) {
112
113 final TethysUIButtonFactory<?> myButtons = pFactory.buttonFactory();
114 theSecButton = myButtons.newScrollButton(MoneyWiseAnalysisSecurityBucket.class);
115
116
117 thePortButton = myButtons.newScrollButton(MoneyWiseAnalysisPortfolioBucket.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 MoneyWiseAnalysisSecurityFilter 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 MoneyWiseAnalysis pAnalysis) {
214
215 thePortfolios = pAnalysis.getPortfolios();
216
217
218 MoneyWiseAnalysisSecurityBucket mySecurity = theState.getSecurity();
219
220
221 mySecurity = mySecurity != null
222 ? thePortfolios.getMatchingSecurityHolding(mySecurity.getSecurityHolding())
223 : thePortfolios.getDefaultSecurityHolding();
224 final MoneyWiseAnalysisPortfolioBucket 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 MoneyWiseAnalysisFilter<?, ?> pFilter) {
236
237 if (pFilter instanceof MoneyWiseAnalysisSecurityFilter) {
238
239 final MoneyWiseAnalysisSecurityFilter myFilter = (MoneyWiseAnalysisSecurityFilter) pFilter;
240
241
242 MoneyWiseAnalysisSecurityBucket mySecurity = myFilter.getBucket();
243
244
245 mySecurity = thePortfolios.getMatchingSecurityHolding(mySecurity.getSecurityHolding());
246
247
248 final MoneyWiseAnalysisPortfolioBucket myPortfolio = thePortfolios.getMatchingPortfolio(mySecurity.getPortfolio());
249
250
251 theState.setTheSecurity(myPortfolio, mySecurity);
252 theState.setDateRange(myFilter.getDateRange());
253 theState.applyState();
254 }
255 }
256
257
258
259
260 private void handleNewPortfolio() {
261
262 if (theState.setPortfolio(thePortButton.getValue())) {
263 theState.applyState();
264 theEventManager.fireEvent(PrometheusDataEvent.SELECTIONCHANGED);
265 }
266 }
267
268
269
270
271 private void handleNewSecurity() {
272
273 if (theState.setSecurity(theSecButton.getValue())) {
274 theState.applyState();
275 theEventManager.fireEvent(PrometheusDataEvent.SELECTIONCHANGED);
276 }
277 }
278
279
280
281
282 private void buildPortfolioMenu() {
283
284 thePortfolioMenu.removeAllItems();
285
286
287 TethysUIScrollItem<MoneyWiseAnalysisPortfolioBucket> myActive = null;
288 final MoneyWiseAnalysisPortfolioBucket myCurr = theState.getPortfolio();
289
290
291 final Iterator<MoneyWiseAnalysisPortfolioBucket> myIterator = thePortfolios.iterator();
292 while (myIterator.hasNext()) {
293 final MoneyWiseAnalysisPortfolioBucket myBucket = myIterator.next();
294
295
296 final TethysUIScrollItem<MoneyWiseAnalysisPortfolioBucket> myItem = thePortfolioMenu.addItem(myBucket);
297
298
299 if (myBucket.equals(myCurr)) {
300
301 myActive = myItem;
302 }
303 }
304
305
306 if (myActive != null) {
307 myActive.scrollToItem();
308 }
309 }
310
311
312
313
314 private void buildSecurityMenu() {
315
316 theSecurityMenu.removeAllItems();
317
318
319 final MoneyWiseAnalysisPortfolioBucket myPortfolio = theState.getPortfolio();
320 final MoneyWiseAnalysisSecurityBucket myCurr = theState.getSecurity();
321 TethysUIScrollItem<MoneyWiseAnalysisSecurityBucket> myActive = null;
322
323
324 final Iterator<MoneyWiseAnalysisSecurityBucket> myIterator = myPortfolio.securityIterator();
325 while (myIterator.hasNext()) {
326 final MoneyWiseAnalysisSecurityBucket myBucket = myIterator.next();
327
328
329 final TethysUIScrollItem<MoneyWiseAnalysisSecurityBucket> myItem = theSecurityMenu.addItem(myBucket, myBucket.getSecurityName());
330
331
332 if (myBucket.equals(myCurr)) {
333
334 myActive = myItem;
335 }
336 }
337
338
339 if (myActive != null) {
340 myActive.scrollToItem();
341 }
342 }
343
344
345
346
347 private final class MoneyWiseSecurityState {
348
349
350
351 private MoneyWiseAnalysisPortfolioBucket thePortfolio;
352
353
354
355
356 private MoneyWiseAnalysisSecurityBucket theSecurity;
357
358
359
360
361 private OceanusDateRange theDateRange;
362
363
364
365
366 private MoneyWiseAnalysisSecurityFilter theFilter;
367
368
369
370
371 private MoneyWiseSecurityState() {
372 }
373
374
375
376
377
378
379 private MoneyWiseSecurityState(final MoneyWiseSecurityState pState) {
380
381 theSecurity = pState.getSecurity();
382 thePortfolio = pState.getPortfolio();
383 theDateRange = pState.getDateRange();
384 theFilter = pState.getFilter();
385 }
386
387
388
389
390
391
392 private MoneyWiseAnalysisSecurityBucket getSecurity() {
393 return theSecurity;
394 }
395
396
397
398
399
400
401 private MoneyWiseAnalysisPortfolioBucket getPortfolio() {
402 return thePortfolio;
403 }
404
405
406
407
408
409
410 private OceanusDateRange getDateRange() {
411 return theDateRange;
412 }
413
414
415
416
417
418
419 private MoneyWiseAnalysisSecurityFilter getFilter() {
420 return theFilter;
421 }
422
423
424
425
426
427
428
429 private boolean setSecurity(final MoneyWiseAnalysisSecurityBucket pSecurity) {
430
431 if (!MetisDataDifference.isEqual(pSecurity, theSecurity)) {
432
433 setTheSecurity(thePortfolio, pSecurity);
434 return true;
435 }
436 return false;
437 }
438
439
440
441
442
443
444
445 private void setTheSecurity(final MoneyWiseAnalysisPortfolioBucket pPortfolio,
446 final MoneyWiseAnalysisSecurityBucket pSecurity) {
447
448 thePortfolio = pPortfolio;
449 theSecurity = pSecurity;
450 if (theSecurity != null) {
451 theFilter = new MoneyWiseAnalysisSecurityFilter(theSecurity);
452 theFilter.setDateRange(theDateRange);
453 } else {
454 theFilter = null;
455 }
456 }
457
458
459
460
461
462
463
464 private boolean setPortfolio(final MoneyWiseAnalysisPortfolioBucket pPortfolio) {
465
466 if (!MetisDataDifference.isEqual(pPortfolio, thePortfolio)) {
467 setTheSecurity(pPortfolio, getFirstSecurity(pPortfolio));
468 return true;
469 }
470 return false;
471 }
472
473
474
475
476
477
478
479 private MoneyWiseAnalysisSecurityBucket getFirstSecurity(final MoneyWiseAnalysisPortfolioBucket pPortfolio) {
480
481 final Iterator<MoneyWiseAnalysisSecurityBucket> myIterator = pPortfolio.securityIterator();
482 return myIterator.hasNext()
483 ? myIterator.next()
484 : null;
485 }
486
487
488
489
490
491
492 private void setDateRange(final OceanusDateRange pRange) {
493
494 theDateRange = pRange;
495 if (theFilter != null) {
496 theFilter.setDateRange(theDateRange);
497 }
498 }
499
500
501
502
503 private void applyState() {
504
505 setEnabled(true);
506 theSecButton.setValue(theSecurity, theSecurity == null
507 ? null
508 : theSecurity.getSecurityName());
509 thePortButton.setValue(thePortfolio);
510 }
511 }
512 }