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), this);
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, this);
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 Category getCategory() {
074        return 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            _selectNamedBean.registerListeners();
139            _listenersAreRegistered = true;
140        }
141    }
142
143    /** {@inheritDoc} */
144    @Override
145    public void unregisterListenersForThisClass() {
146        if (_listenersAreRegistered) {
147            _selectNamedBean.removePropertyChangeListener(this);
148            _selectNamedBean.unregisterListeners();
149            _listenersAreRegistered = false;
150        }
151    }
152
153    /** {@inheritDoc} */
154    @Override
155    public void propertyChange(PropertyChangeEvent evt) {
156        getConditionalNG().execute();
157    }
158
159    /** {@inheritDoc} */
160    @Override
161    public void disposeMe() {
162    }
163
164    public enum TransitState {
165        Idle(Transit.IDLE, Bundle.getMessage("Transit_StateIdle")),
166        Assigned(Transit.ASSIGNED, Bundle.getMessage("Transit_StateAssigned"));
167
168        private final int _id;
169        private final String _text;
170
171        private TransitState(int id, String text) {
172            this._id = id;
173            this._text = text;
174        }
175
176        public int getID() {
177            return _id;
178        }
179
180        @Override
181        public String toString() {
182            return _text;
183        }
184    }
185
186    /** {@inheritDoc} */
187    @Override
188    public void getUsageDetail(int level, NamedBean bean, List<NamedBeanUsageReport> report, NamedBean cdl) {
189        log.debug("getUsageReport :: ExpressionTransit: bean = {}, report = {}", cdl, report);
190        _selectNamedBean.getUsageDetail(level, bean, report, cdl, this, LogixNG_SelectNamedBean.Type.Expression);
191    }
192
193    private final static org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(ExpressionTransit.class);
194
195}