001package jmri.implementation;
002
003import java.beans.PropertyChangeEvent;
004import java.beans.PropertyChangeListener;
005import javax.annotation.Nonnull;
006import jmri.NamedBeanHandle;
007import jmri.SignalMast;
008import org.slf4j.Logger;
009import org.slf4j.LoggerFactory;
010
011public class SignalMastRepeater {
012
013    public final static int BOTHWAY = 0x00;
014    public final static int MASTERTOSLAVE = 0x01;
015    public final static int SLAVETOMASTER = 0x02;
016
017    protected jmri.NamedBeanHandleManager nbhm = jmri.InstanceManager.getDefault(jmri.NamedBeanHandleManager.class);
018
019    protected NamedBeanHandle<SignalMast> _master;
020    protected NamedBeanHandle<SignalMast> _slave;
021    boolean _enabled = true;
022    int _direction = BOTHWAY;
023
024    public SignalMastRepeater(@Nonnull SignalMast master, @Nonnull SignalMast slave) {
025        _master = nbhm.getNamedBeanHandle(master.getDisplayName(), master);
026        _slave = nbhm.getNamedBeanHandle(slave.getDisplayName(), slave);
027    }
028
029    public SignalMastRepeater(@Nonnull String master, @Nonnull String slave) {
030        SignalMast masterMast = jmri.InstanceManager.getDefault(jmri.SignalMastManager.class).getSignalMast(master);
031        if (masterMast == null) throw new IllegalArgumentException("master mast must exist, \""+master+"\" doesn't");
032        _master = nbhm.getNamedBeanHandle(master, masterMast);
033        SignalMast slaveMast = jmri.InstanceManager.getDefault(jmri.SignalMastManager.class).getSignalMast(slave);
034        if (slaveMast == null) throw new IllegalArgumentException("slave mast must exist, \""+slave+"\" doesn't");
035        _slave = nbhm.getNamedBeanHandle(slave, slaveMast);
036    }
037
038    @Nonnull 
039    public SignalMast getMasterMast() {
040        return _master.getBean();
041    }
042
043    @Nonnull 
044    public SignalMast getSlaveMast() {
045        return _slave.getBean();
046    }
047
048    @Nonnull 
049    public String getMasterMastName() {
050        return _master.getName();
051    }
052
053    @Nonnull 
054    public String getSlaveMastName() {
055        return _slave.getName();
056    }
057
058    public int getDirection() {
059        return _direction;
060    }
061
062    public void setDirection(int dir) {
063        if (dir == _direction) {
064            return;
065        }
066        _direction = dir;
067        getMasterMast().removePropertyChangeListener(mastListener);
068        getSlaveMast().removePropertyChangeListener(mastListener);
069        initialise();
070    }
071
072    public void setEnabled(boolean en) {
073        if (_enabled == en) {
074            return;
075        }
076        _enabled = en;
077        getMasterMast().removePropertyChangeListener(mastListener);
078        getSlaveMast().removePropertyChangeListener(mastListener);
079        initialise();
080    }
081
082    public boolean getEnabled() {
083        return _enabled;
084    }
085
086    public void initialise() {
087        if (disposed) {
088            log.error("Trying to initialise a repeater that has already been disposed");
089        }
090        if (!_enabled) {
091            return;
092        }
093        getMasterMast().removePropertyChangeListener(mastListener);
094        getSlaveMast().removePropertyChangeListener(mastListener);
095        switch (_direction) {
096            case MASTERTOSLAVE:
097                getMasterMast().addPropertyChangeListener(mastListener);
098                updateStatus(getMasterMast(), getSlaveMast());
099                break;
100            case SLAVETOMASTER:
101                getSlaveMast().addPropertyChangeListener(mastListener);
102                updateStatus(getSlaveMast(), getMasterMast());
103                break;
104            default:
105                getMasterMast().addPropertyChangeListener(mastListener);
106                getSlaveMast().addPropertyChangeListener(mastListener);
107                updateStatus(getMasterMast(), getSlaveMast());
108        }
109    }
110
111    PropertyChangeListener mastListener = new PropertyChangeListener() {
112        @Override
113        public void propertyChange(PropertyChangeEvent e) {
114            if (disposed) {
115                return;
116            }
117            if (e.getSource() == getMasterMast()) {
118                updateStatus(getMasterMast(), getSlaveMast());
119            } else {
120                updateStatus(getSlaveMast(), getMasterMast());
121            }
122        }
123    };
124
125    void updateStatus(@Nonnull SignalMast mastFrom, @Nonnull SignalMast mastTo) {
126        if (log.isDebugEnabled()) {
127            log.debug("Updating from mast {}:{} to mast {}", mastFrom.getDisplayName(), mastFrom.getAspect(), mastTo.getDisplayName());
128        }
129        if (mastFrom.getAspect() != null) {
130            mastTo.setAspect(mastFrom.getAspect());
131        }
132    }
133
134    boolean disposed = false;
135
136    public void dispose() {
137        disposed = true;
138        getMasterMast().removePropertyChangeListener(mastListener);
139        getSlaveMast().removePropertyChangeListener(mastListener);
140        _master = null;
141        _slave = null;
142    }
143
144    private final static Logger log = LoggerFactory.getLogger(SignalMastRepeater.class);
145
146}