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