001package jmri.jmrit.etcs.dmi.swing;
002
003import java.beans.PropertyChangeListener;
004
005import jmri.util.TimerUtil;
006
007import org.apiguardian.api.API;
008
009/**
010 * Class to provide a Timer to ensure all flashing DMI Icons flash in unison.
011 * @author Steve Young Copyright (C) 2024
012 */
013@API(status=API.Status.EXPERIMENTAL)
014public class DmiFlashTimer {
015
016    private final DmiPanel panel;
017
018    private static final String PROP_CHANGE_SLOW_FLASH = "SlowFlash";
019    private static final String PROP_CHANGE_FAST_FLASH = "FastFlash";
020
021    private boolean fastFlashOn = false;
022    private boolean slowFlashOn = false;
023    private boolean disposed = false;
024
025    private java.util.TimerTask flashTimer;
026
027    protected DmiFlashTimer(DmiPanel mainPanel) {
028        panel = mainPanel;
029    }
030
031    protected void addFlashListener( PropertyChangeListener pcl, boolean fast ) {
032        log.debug("add pcl {}", pcl);
033        panel.addPropertyChangeListener(
034            ( fast ? PROP_CHANGE_FAST_FLASH : PROP_CHANGE_SLOW_FLASH), pcl);
035        ensureRunning();
036    }
037
038    protected void removeFlashListener ( PropertyChangeListener pcl, boolean fast ) {
039        
040        log.debug("remove pcl {} num listeners {}", pcl, 
041                    panel.getPropertyChangeListeners(PROP_CHANGE_FAST_FLASH).length +
042            panel.getPropertyChangeListeners(PROP_CHANGE_SLOW_FLASH).length
043                    
044                    );
045        
046        panel.removePropertyChangeListener(( fast ? PROP_CHANGE_FAST_FLASH : PROP_CHANGE_SLOW_FLASH), pcl);
047        
048        
049        log.debug("remove pcl {} num listeners {}", pcl, 
050                    panel.getPropertyChangeListeners(PROP_CHANGE_FAST_FLASH).length +
051            panel.getPropertyChangeListeners(PROP_CHANGE_SLOW_FLASH).length
052                    
053                    );
054        
055        if ( panel.getPropertyChangeListeners(PROP_CHANGE_FAST_FLASH).length +
056            panel.getPropertyChangeListeners(PROP_CHANGE_SLOW_FLASH).length == 0 ) {
057            dispose();
058        }
059        
060    }
061
062    private void ensureRunning(){
063        log.debug("ensureRunning");
064        disposed = false;
065        if (flashTimer==null) {
066            flashTimer = new java.util.TimerTask(){
067                @Override
068                public void run() {
069                    if ( !disposed ) {
070                        triggerFastFlash();
071                        TimerUtil.scheduleOnGUIThread(flashTimer, 250);
072                    }
073                }
074            };
075            TimerUtil.scheduleOnGUIThread(flashTimer, 250);
076        }
077    }
078
079    private void triggerFastFlash(){
080        fastFlashOn = !fastFlashOn;
081        log.debug("fast flash {}", fastFlashOn );
082        panel.firePropertyChange(PROP_CHANGE_FAST_FLASH, !fastFlashOn, fastFlashOn);
083        if (!fastFlashOn) {
084            triggerSlowFlash();
085        }
086    }
087
088    private void triggerSlowFlash(){
089        slowFlashOn = !slowFlashOn;
090        log.debug("slow flash {}", slowFlashOn );
091        panel.firePropertyChange(PROP_CHANGE_SLOW_FLASH, !slowFlashOn, slowFlashOn);
092    }
093
094    protected void dispose(){
095        log.debug("dispose");
096        disposed = true;
097        if ( flashTimer != null ) {
098            flashTimer.cancel();
099            flashTimer = null;
100        }
101    }
102
103    private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(DmiFlashTimer.class);
104
105}