001package jmri.jmrit.logixng.actions;
002
003import java.beans.PropertyChangeEvent;
004import java.beans.PropertyChangeListener;
005import java.util.*;
006
007import jmri.*;
008import jmri.jmrit.entryexit.DestinationPoints;
009import jmri.jmrit.logixng.*;
010import jmri.jmrit.logixng.util.*;
011import jmri.jmrit.logixng.util.parser.*;
012import jmri.util.ThreadingUtil;
013
014/**
015 * This action triggers a entryExit.
016 * <p>
017 * This action has the Operation enum, similar to EnableLogix and other actions,
018 * despite that's not needed since this action only has one option. But it's
019 * here in case someone wants to add more options later.
020 *
021 * @author Daniel Bergqvist Copyright 2021
022 */
023public class ActionEntryExit extends AbstractDigitalAction
024        implements PropertyChangeListener {
025
026    private final LogixNG_SelectNamedBean<DestinationPoints> _selectNamedBean =
027            new LogixNG_SelectNamedBean<>(
028                    this, DestinationPoints.class, InstanceManager.getDefault(jmri.jmrit.entryexit.EntryExitPairs.class), this);
029
030    private final LogixNG_SelectEnum<Operation> _selectEnum =
031            new LogixNG_SelectEnum<>(this, Operation.values(), Operation.SetNXPairEnabled, this);
032
033
034    public ActionEntryExit(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        DigitalActionManager manager = InstanceManager.getDefault(DigitalActionManager.class);
042        String sysName = systemNames.get(getSystemName());
043        String userName = userNames.get(getSystemName());
044        if (sysName == null) sysName = manager.getAutoSystemName();
045        ActionEntryExit copy = new ActionEntryExit(sysName, userName);
046        copy.setComment(getComment());
047        _selectNamedBean.copy(copy._selectNamedBean);
048        _selectEnum.copy(copy._selectEnum);
049        return manager.registerAction(copy);
050    }
051
052    public LogixNG_SelectNamedBean<DestinationPoints> getSelectNamedBean() {
053        return _selectNamedBean;
054    }
055
056    public LogixNG_SelectEnum<Operation> getSelectEnum() {
057        return _selectEnum;
058    }
059
060    /** {@inheritDoc} */
061    @Override
062    public Category getCategory() {
063        return Category.ITEM;
064    }
065
066    /** {@inheritDoc} */
067    @Override
068    public void execute() throws JmriException {
069        DestinationPoints entryExit = _selectNamedBean.evaluateNamedBean(getConditionalNG());
070
071        if (entryExit == null) return;
072
073        Operation oper = _selectEnum.evaluateEnum(getConditionalNG());
074
075        // Variables used in lambda must be effectively final
076        Operation theOper = oper;
077
078        ThreadingUtil.runOnLayoutWithJmriException(() -> {
079            switch (theOper) {
080                case SetNXPairEnabled:
081                    entryExit.setEnabled(true);
082                    break;
083                case SetNXPairDisabled:
084                    entryExit.setEnabled(false);
085                    break;
086                case SetNXPairSegment:
087                    jmri.InstanceManager.getDefault(jmri.jmrit.entryexit.EntryExitPairs.class).
088                            setSingleSegmentRoute(entryExit.getSystemName());
089                    break;
090                case SetNXPairInactive:
091                    if (entryExit.isActive()) {
092                        jmri.InstanceManager.getDefault(jmri.jmrit.entryexit.EntryExitPairs.class).
093                                setSingleSegmentRoute(entryExit.getSystemName());
094                    }
095                    break;
096                case SetNXPairActive:
097                    if (!entryExit.isActive()) {
098                        jmri.InstanceManager.getDefault(jmri.jmrit.entryexit.EntryExitPairs.class).
099                                setSingleSegmentRoute(entryExit.getSystemName());
100                    }
101                    break;
102                case SetNXPairReversed:
103                    if (entryExit.isUniDirection()) {
104                        throw new IllegalArgumentException("\"" + entryExit.getDisplayName() +
105                                "\" is not enabled for reversed activation (Both Way)");
106                    }
107
108                    if (!entryExit.isActive()) {
109                        jmri.InstanceManager.getDefault(jmri.jmrit.entryexit.EntryExitPairs.class).
110                                setReversedRoute(entryExit.getSystemName());
111                    }
112                    break;
113                default:
114                    throw new IllegalArgumentException("invalid oper state: " + theOper.name());
115            }
116        });
117    }
118
119    @Override
120    public FemaleSocket getChild(int index) throws IllegalArgumentException, UnsupportedOperationException {
121        throw new UnsupportedOperationException("Not supported.");
122    }
123
124    @Override
125    public int getChildCount() {
126        return 0;
127    }
128
129    @Override
130    public String getShortDescription(Locale locale) {
131        return Bundle.getMessage(locale, "ActionEntryExit_Short");
132    }
133
134    @Override
135    public String getLongDescription(Locale locale) {
136        String namedBean = _selectNamedBean.getDescription(locale);
137        String state = _selectEnum.getDescription(locale);
138
139        return Bundle.getMessage(locale, "ActionEntryExit_Long", namedBean, state);
140    }
141
142    /** {@inheritDoc} */
143    @Override
144    public void setup() {
145        getSelectNamedBean().setup();
146    }
147
148    /** {@inheritDoc} */
149    @Override
150    public void registerListenersForThisClass() {
151        _selectNamedBean.registerListeners();
152        _selectEnum.registerListeners();
153    }
154
155    /** {@inheritDoc} */
156    @Override
157    public void unregisterListenersForThisClass() {
158        _selectNamedBean.unregisterListeners();
159        _selectEnum.unregisterListeners();
160    }
161
162    /** {@inheritDoc} */
163    @Override
164    public void disposeMe() {
165    }
166
167
168    public enum Operation {
169        SetNXPairEnabled(Bundle.getMessage("ActionEntryExit_SetNXPairEnabled")),
170        SetNXPairDisabled(Bundle.getMessage("ActionEntryExit_SetNXPairDisabled")),
171        SetNXPairSegment(Bundle.getMessage("ActionEntryExit_SetNXPairSegment")),
172        Separator1(Base.SEPARATOR),
173        SetNXPairInactive(Bundle.getMessage("ActionEntryExit_SetNXPairInactive")),
174        SetNXPairActive(Bundle.getMessage("ActionEntryExit_SetNXPairActive")),
175        SetNXPairReversed(Bundle.getMessage("ActionEntryExit_SetNXPairReversed"));
176
177        private final String _text;
178
179        private Operation(String text) {
180            this._text = text;
181        }
182
183        @Override
184        public String toString() {
185            return _text;
186        }
187
188    }
189
190    /** {@inheritDoc} */
191    @Override
192    public void getUsageDetail(int level, NamedBean bean, List<NamedBeanUsageReport> report, NamedBean cdl) {
193        _selectNamedBean.getUsageDetail(level, bean, report, cdl, this, LogixNG_SelectNamedBean.Type.Action);
194    }
195
196    /** {@inheritDoc} */
197    @Override
198    public void propertyChange(PropertyChangeEvent evt) {
199        getConditionalNG().execute();
200    }
201
202//    private final static org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(ActionEntryExit.class);
203
204}