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