001package jmri.jmrit.logixng.actions;
002
003import java.util.Locale;
004import java.util.Map;
005
006import jmri.InstanceManager;
007import jmri.JmriException;
008import jmri.jmrit.logixng.*;
009
010/**
011 * Executes an action depending on the parameter.
012 *
013 * @author Daniel Bergqvist Copyright 2019
014 */
015public class DigitalBooleanLogixAction extends AbstractDigitalBooleanAction
016        implements FemaleSocketListener {
017
018    /**
019     * The trigger of Action.
020     */
021    public enum When {
022        True(Bundle.getMessage("DigitalBooleanLogixAction_When_True")),
023        False(Bundle.getMessage("DigitalBooleanLogixAction_When_False")),
024        Either(Bundle.getMessage("DigitalBooleanLogixAction_When_Either"));
025
026        private final String _text;
027
028        private When(String text) {
029            this._text = text;
030        }
031
032        @Override
033        public String toString() {
034            return _text;
035        }
036    }
037
038    private String _socketSystemName;
039    private final FemaleDigitalActionSocket _socket;
040    When _when = When.Either;
041
042    public DigitalBooleanLogixAction(String sys, String user, When trigger) {
043        super(sys, user);
044        _socket = InstanceManager.getDefault(DigitalActionManager.class)
045                .createFemaleSocket(this, this, "A");
046        _when = trigger;
047    }
048
049    @Override
050    public Base getDeepCopy(Map<String, String> systemNames, Map<String, String> userNames) throws JmriException {
051        DigitalBooleanActionManager manager = InstanceManager.getDefault(DigitalBooleanActionManager.class);
052        String sysName = systemNames.get(getSystemName());
053        String userName = userNames.get(getSystemName());
054        if (sysName == null) sysName = manager.getAutoSystemName();
055        DigitalBooleanLogixAction copy = new DigitalBooleanLogixAction(sysName, userName, _when);
056        copy.setComment(getComment());
057        return manager.registerAction(copy).deepCopyChildren(this, systemNames, userNames);
058    }
059
060    /** {@inheritDoc} */
061    @Override
062    public Category getCategory() {
063        return Category.COMMON;
064    }
065
066    /** {@inheritDoc} */
067    @Override
068    public void execute(boolean value) throws JmriException {
069        if (_socket.isConnected()) {
070            switch (_when) {
071                case True:
072                    // Call execute() if true
073                    if (value) {
074                        _socket.execute();
075                    }
076                    break;
077                case False:
078                    // Call execute() if false
079                    if (!value) {
080                        _socket.execute();
081                    }
082                    break;
083                case Either:
084                    // Always call execute()
085                    _socket.execute();
086                    break;
087                default:
088                    throw new UnsupportedOperationException("_whichChange has unknown value: "+_when);
089            }
090        }
091    }
092
093    /**
094     * Get the type.
095     * @return the trigger
096     */
097    public When getTrigger() {
098        return _when;
099    }
100
101    /**
102     * Set the type.
103     * @param trigger the trigger
104     */
105    public void setTrigger(When trigger) {
106        _when = trigger;
107    }
108
109    @Override
110    public FemaleSocket getChild(int index) throws IllegalArgumentException, UnsupportedOperationException {
111        switch (index) {
112            case 0:
113                return _socket;
114
115            default:
116                throw new IllegalArgumentException(
117                        String.format("index has invalid value: %d", index));
118        }
119    }
120
121    @Override
122    public int getChildCount() {
123        return 1;
124    }
125
126    @Override
127    public void connected(FemaleSocket socket) {
128        if (socket == _socket) {
129            _socketSystemName = socket.getConnectedSocket().getSystemName();
130        } else {
131            throw new IllegalArgumentException("unkown socket");
132        }
133    }
134
135    @Override
136    public void disconnected(FemaleSocket socket) {
137        if (socket == _socket) {
138            _socketSystemName = null;
139        } else {
140            throw new IllegalArgumentException("unkown socket");
141        }
142    }
143
144    @Override
145    public String getShortDescription(Locale locale) {
146        return Bundle.getMessage(locale, "DigitalBooleanLogixAction_Short");
147    }
148
149    @Override
150    public String getLongDescription(Locale locale) {
151        return Bundle.getMessage(locale, "DigitalBooleanLogixAction_Long", _when.toString());
152    }
153
154    public FemaleDigitalActionSocket getSocket() {
155        return _socket;
156    }
157
158    public String getSocketSystemName() {
159        return _socketSystemName;
160    }
161
162    public void setActionSocketSystemName(String systemName) {
163        _socketSystemName = systemName;
164    }
165
166    /** {@inheritDoc} */
167    @Override
168    public void setup() {
169        try {
170            if ( !_socket.isConnected()
171                    || !_socket.getConnectedSocket().getSystemName()
172                            .equals(_socketSystemName)) {
173
174                String socketSystemName = _socketSystemName;
175                _socket.disconnect();
176                if (socketSystemName != null) {
177                    MaleSocket maleSocket =
178                            InstanceManager.getDefault(DigitalActionManager.class)
179                                    .getBySystemName(socketSystemName);
180                    _socket.disconnect();
181                    if (maleSocket != null) {
182                        _socket.connect(maleSocket);
183                        maleSocket.setup();
184                    } else {
185                        log.error("cannot load digital action {}", socketSystemName);
186                    }
187                }
188            } else {
189                _socket.getConnectedSocket().setup();
190            }
191        } catch (SocketAlreadyConnectedException ex) {
192            // This shouldn't happen and is a runtime error if it does.
193            throw new RuntimeException("socket is already connected");
194        }
195    }
196
197    /** {@inheritDoc} */
198    @Override
199    public void registerListenersForThisClass() {
200    }
201
202    /** {@inheritDoc} */
203    @Override
204    public void unregisterListenersForThisClass() {
205    }
206
207    /** {@inheritDoc} */
208    @Override
209    public void disposeMe() {
210    }
211
212    private final static org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(DigitalBooleanLogixAction.class);
213
214}