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