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