001package jmri.jmrit.logixng.expressions;
002
003import java.beans.*;
004import java.util.*;
005
006import jmri.*;
007import jmri.jmrit.logixng.*;
008import jmri.jmrit.logixng.util.*;
009import jmri.jmrit.logixng.util.parser.*;
010
011/**
012 * This expression sets the state of a sensor.
013 *
014 * @author Daniel Bergqvist Copyright 2018
015 */
016public class ExpressionSensor extends AbstractDigitalExpression
017        implements PropertyChangeListener {
018
019    private final LogixNG_SelectNamedBean<Sensor> _selectNamedBean =
020            new LogixNG_SelectNamedBean<>(
021                    this, Sensor.class, InstanceManager.getDefault(SensorManager.class), this);
022
023    private Is_IsNot_Enum _is_IsNot = Is_IsNot_Enum.Is;
024
025    private final LogixNG_SelectEnum<SensorState> _selectEnum =
026            new LogixNG_SelectEnum<>(this, SensorState.values(), SensorState.Active, this);
027
028
029    public ExpressionSensor(String sys, String user)
030            throws BadUserNameException, BadSystemNameException {
031        super(sys, user);
032    }
033
034    @Override
035    public Base getDeepCopy(Map<String, String> systemNames, Map<String, String> userNames) throws ParserException {
036        DigitalExpressionManager manager = InstanceManager.getDefault(DigitalExpressionManager.class);
037        String sysName = systemNames.get(getSystemName());
038        String userName = userNames.get(getSystemName());
039        if (sysName == null) sysName = manager.getAutoSystemName();
040        ExpressionSensor copy = new ExpressionSensor(sysName, userName);
041        copy.setComment(getComment());
042        _selectNamedBean.copy(copy._selectNamedBean);
043        copy.set_Is_IsNot(_is_IsNot);
044        _selectEnum.copy(copy._selectEnum);
045        return manager.registerExpression(copy);
046    }
047
048    public LogixNG_SelectNamedBean<Sensor> getSelectNamedBean() {
049        return _selectNamedBean;
050    }
051
052    public void set_Is_IsNot(Is_IsNot_Enum is_IsNot) {
053        _is_IsNot = is_IsNot;
054    }
055
056    public Is_IsNot_Enum get_Is_IsNot() {
057        return _is_IsNot;
058    }
059
060    public LogixNG_SelectEnum<SensorState> getSelectEnum() {
061        return _selectEnum;
062    }
063
064    /** {@inheritDoc} */
065    @Override
066    public Category getCategory() {
067        return Category.ITEM;
068    }
069
070    /** {@inheritDoc} */
071    @Override
072    public boolean evaluate() throws JmriException {
073        Sensor sensor = _selectNamedBean.evaluateNamedBean(getConditionalNG());
074
075        if (sensor == null) return false;
076
077        SensorState checkSensorState = _selectEnum.evaluateEnum(getConditionalNG());
078        SensorState currentSensorState = SensorState.get(sensor.getKnownState());
079        if (_is_IsNot == Is_IsNot_Enum.Is) {
080            return currentSensorState == checkSensorState;
081        } else {
082            return currentSensorState != checkSensorState;
083        }
084    }
085
086    @Override
087    public FemaleSocket getChild(int index) throws IllegalArgumentException, UnsupportedOperationException {
088        throw new UnsupportedOperationException("Not supported.");
089    }
090
091    @Override
092    public int getChildCount() {
093        return 0;
094    }
095
096    @Override
097    public String getShortDescription(Locale locale) {
098        return Bundle.getMessage(locale, "Sensor_Short");
099    }
100
101    @Override
102    public String getLongDescription(Locale locale) {
103        String namedBean = _selectNamedBean.getDescription(locale);
104        String state = _selectEnum.getDescription(locale);
105
106        return Bundle.getMessage(locale, "Sensor_Long", namedBean, _is_IsNot.toString(), state);
107    }
108
109    /** {@inheritDoc} */
110    @Override
111    public void setup() {
112        // Do nothing
113    }
114
115    /** {@inheritDoc} */
116    @Override
117    public void registerListenersForThisClass() {
118        if (!_listenersAreRegistered) {
119            _selectNamedBean.addPropertyChangeListener("KnownState", this);
120            _selectNamedBean.registerListeners();
121            _listenersAreRegistered = true;
122        }
123    }
124
125    /** {@inheritDoc} */
126    @Override
127    public void unregisterListenersForThisClass() {
128        if (_listenersAreRegistered) {
129            _selectNamedBean.removePropertyChangeListener("KnownState", this);
130            _selectNamedBean.unregisterListeners();
131            _listenersAreRegistered = false;
132        }
133    }
134
135    /** {@inheritDoc} */
136    @Override
137    public void propertyChange(PropertyChangeEvent evt) {
138        getConditionalNG().execute();
139    }
140
141    /** {@inheritDoc} */
142    @Override
143    public void disposeMe() {
144    }
145
146
147    public enum SensorState {
148        Inactive(Sensor.INACTIVE, Bundle.getMessage("SensorStateInactive")),
149        Active(Sensor.ACTIVE, Bundle.getMessage("SensorStateActive")),
150        Other(-1, Bundle.getMessage("SensorOtherStatus"));
151
152        private final int _id;
153        private final String _text;
154
155        private SensorState(int id, String text) {
156            this._id = id;
157            this._text = text;
158        }
159
160        static public SensorState get(int id) {
161            switch (id) {
162                case Sensor.INACTIVE:
163                    return Inactive;
164
165                case Sensor.ACTIVE:
166                    return Active;
167
168                default:
169                    return Other;
170            }
171        }
172
173        public int getID() {
174            return _id;
175        }
176
177        @Override
178        public String toString() {
179            return _text;
180        }
181
182    }
183
184    /** {@inheritDoc} */
185    @Override
186    public void getUsageDetail(int level, NamedBean bean, List<NamedBeanUsageReport> report, NamedBean cdl) {
187        log.debug("getUsageReport :: ExpressionSensor: bean = {}, report = {}", cdl, report);
188        _selectNamedBean.getUsageDetail(level, bean, report, cdl, this, LogixNG_SelectNamedBean.Type.Expression);
189    }
190
191    private final static org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(ExpressionSensor.class);
192}