001package jmri.jmrit.logixng.actions;
002
003import java.beans.PropertyChangeEvent;
004import java.beans.PropertyChangeListener;
005import java.util.*;
006
007import jmri.*;
008import jmri.jmrit.logixng.*;
009import jmri.jmrit.logixng.util.*;
010import jmri.jmrit.logixng.util.parser.*;
011import jmri.util.ThreadingUtil;
012
013/**
014 * This action sets the state of a sensor.
015 *
016 * @author Daniel Bergqvist Copyright 2018
017 */
018public class ActionSensor extends AbstractDigitalAction
019        implements PropertyChangeListener {
020
021    private final LogixNG_SelectNamedBean<Sensor> _selectNamedBean =
022            new LogixNG_SelectNamedBean<>(
023                    this, Sensor.class, InstanceManager.getDefault(SensorManager.class), this);
024
025    private final LogixNG_SelectEnum<SensorState> _selectEnum =
026            new LogixNG_SelectEnum<>(this, SensorState.values(), SensorState.Active, this);
027
028
029    public ActionSensor(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        DigitalActionManager manager = InstanceManager.getDefault(DigitalActionManager.class);
037        String sysName = systemNames.get(getSystemName());
038        String userName = userNames.get(getSystemName());
039        if (sysName == null) sysName = manager.getAutoSystemName();
040        ActionSensor copy = new ActionSensor(sysName, userName);
041        copy.setComment(getComment());
042        _selectNamedBean.copy(copy._selectNamedBean);
043        _selectEnum.copy(copy._selectEnum);
044        return manager.registerAction(copy);
045    }
046
047    public LogixNG_SelectNamedBean<Sensor> getSelectNamedBean() {
048        return _selectNamedBean;
049    }
050
051    public LogixNG_SelectEnum<SensorState> getSelectEnum() {
052        return _selectEnum;
053    }
054
055    /** {@inheritDoc} */
056    @Override
057    public Category getCategory() {
058        return Category.ITEM;
059    }
060
061    /** {@inheritDoc} */
062    @Override
063    public void execute() throws JmriException {
064        Sensor sensor = _selectNamedBean.evaluateNamedBean(getConditionalNG());
065
066        if (sensor == null) return;
067
068        SensorState state = _selectEnum.evaluateEnum(getConditionalNG());
069
070        ThreadingUtil.runOnLayoutWithJmriException(() -> {
071            if (state == SensorState.Toggle) {
072                if (sensor.getKnownState() == Sensor.INACTIVE) {
073                    sensor.setCommandedState(Sensor.ACTIVE);
074                } else {
075                    sensor.setCommandedState(Sensor.INACTIVE);
076                }
077            } else {
078                sensor.setCommandedState(state.getID());
079            }
080        });
081    }
082
083    @Override
084    public FemaleSocket getChild(int index) throws IllegalArgumentException, UnsupportedOperationException {
085        throw new UnsupportedOperationException("Not supported.");
086    }
087
088    @Override
089    public int getChildCount() {
090        return 0;
091    }
092
093    @Override
094    public String getShortDescription(Locale locale) {
095        return Bundle.getMessage(locale, "Sensor_Short");
096    }
097
098    @Override
099    public String getLongDescription(Locale locale) {
100        String namedBean = _selectNamedBean.getDescription(locale);
101        String state = _selectEnum.getDescription(locale);
102
103        return Bundle.getMessage(locale, "Sensor_Long", namedBean, state);
104    }
105
106    /** {@inheritDoc} */
107    @Override
108    public void setup() {
109        // Do nothing
110    }
111
112    /** {@inheritDoc} */
113    @Override
114    public void registerListenersForThisClass() {
115        _selectNamedBean.registerListeners();
116        _selectEnum.registerListeners();
117    }
118
119    /** {@inheritDoc} */
120    @Override
121    public void unregisterListenersForThisClass() {
122        _selectNamedBean.unregisterListeners();
123        _selectEnum.unregisterListeners();
124    }
125
126    /** {@inheritDoc} */
127    @Override
128    public void disposeMe() {
129    }
130
131
132    // This constant is only used internally in SensorState but must be outside
133    // the enum.
134    private static final int TOGGLE_ID = -1;
135
136
137    public enum SensorState {
138        Inactive(Sensor.INACTIVE, Bundle.getMessage("SensorStateInactive")),
139        Active(Sensor.ACTIVE, Bundle.getMessage("SensorStateActive")),
140        Toggle(TOGGLE_ID, Bundle.getMessage("SensorToggleStatus")),
141        Unknown(Sensor.UNKNOWN, Bundle.getMessage("BeanStateUnknown")),
142        Inconsistent(Sensor.INCONSISTENT, Bundle.getMessage("BeanStateInconsistent"));
143
144        private final int _id;
145        private final String _text;
146
147        private SensorState(int id, String text) {
148            this._id = id;
149            this._text = text;
150        }
151
152        static public SensorState get(int id) {
153            switch (id) {
154                case Sensor.UNKNOWN:
155                    return Unknown;
156
157                case Sensor.INCONSISTENT:
158                    return Inconsistent;
159
160                case Sensor.INACTIVE:
161                    return Inactive;
162
163                case Sensor.ACTIVE:
164                    return Active;
165
166                case TOGGLE_ID:
167                    return Toggle;
168
169                default:
170                    throw new IllegalArgumentException("invalid sensor state");
171            }
172        }
173
174        public int getID() {
175            return _id;
176        }
177
178        @Override
179        public String toString() {
180            return _text;
181        }
182
183    }
184
185    /** {@inheritDoc} */
186    @Override
187    public void getUsageDetail(int level, NamedBean bean, List<NamedBeanUsageReport> report, NamedBean cdl) {
188        _selectNamedBean.getUsageDetail(level, bean, report, cdl, this, LogixNG_SelectNamedBean.Type.Action);
189    }
190
191    /** {@inheritDoc} */
192    @Override
193    public void propertyChange(PropertyChangeEvent evt) {
194        getConditionalNG().execute();
195    }
196
197//    private final static org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(ActionSensor.class);
198}