001package jmri.jmrix.can.cbus.logixng;
002
003import java.beans.PropertyChangeEvent;
004import java.beans.PropertyChangeListener;
005import java.util.Locale;
006import java.util.Map;
007
008import jmri.*;
009import jmri.jmrit.logixng.*;
010import jmri.jmrit.logixng.actions.AbstractDigitalAction;
011import jmri.jmrit.logixng.util.LogixNG_SelectEnum;
012import jmri.jmrit.logixng.util.LogixNG_SelectInteger;
013import jmri.jmrit.logixng.util.parser.ParserException;
014import jmri.jmrix.can.CanSystemConnectionMemo;
015import jmri.jmrix.can.cbus.CbusEvent;
016import jmri.util.ThreadingUtil;
017
018/**
019 * This action sends a Cbus event.
020 *
021 * @author Daniel Bergqvist Copyright 2025
022 */
023public class SendMergCbusEvent extends AbstractDigitalAction
024        implements PropertyChangeListener {
025
026    private final LogixNG_SelectInteger _selectNodeNumber =
027            new LogixNG_SelectInteger(
028                    this, this);
029
030    private final LogixNG_SelectInteger _selectEventNumber =
031            new LogixNG_SelectInteger(
032                    this, this);
033
034    private final LogixNG_SelectEnum<CbusEventType> _selectEventType =
035            new LogixNG_SelectEnum<>(this, CbusEventType.values(), CbusEventType.Off, this);
036
037    private CanSystemConnectionMemo _memo;
038
039
040    public SendMergCbusEvent(String sys, String user, CanSystemConnectionMemo memo)
041            throws BadUserNameException, BadSystemNameException {
042        super(sys, user);
043        _memo = memo;
044    }
045
046    @Override
047    public Base getDeepCopy(Map<String, String> systemNames, Map<String, String> userNames) throws ParserException {
048        DigitalActionManager manager = InstanceManager.getDefault(DigitalActionManager.class);
049        String sysName = systemNames.get(getSystemName());
050        String userName = userNames.get(getSystemName());
051        if (sysName == null) sysName = manager.getAutoSystemName();
052        SendMergCbusEvent copy = new SendMergCbusEvent(sysName, userName, _memo);
053        copy.setComment(getComment());
054        _selectNodeNumber.copy(copy._selectNodeNumber);
055        _selectEventNumber.copy(copy._selectEventNumber);
056        _selectEventType.copy(copy._selectEventType);
057
058        return manager.registerAction(copy);
059    }
060
061    public void setMemo(CanSystemConnectionMemo memo) {
062        assertListenersAreNotRegistered(log, "setMemo");
063        _memo = memo;
064    }
065
066    public CanSystemConnectionMemo getMemo() {
067        return _memo;
068    }
069
070    public LogixNG_SelectInteger getSelectNodeNumber() {
071        return _selectNodeNumber;
072    }
073
074    public LogixNG_SelectInteger getSelectEventNumber() {
075        return _selectEventNumber;
076    }
077
078    public LogixNG_SelectEnum<CbusEventType> getSelectEventType() {
079        return _selectEventType;
080    }
081
082    /** {@inheritDoc} */
083    @Override
084    public Category getCategory() {
085        return CategoryMergCbus.CBUS;
086    }
087
088    /** {@inheritDoc} */
089    @Override
090    public void execute() throws JmriException {
091        ConditionalNG conditionalNG = getConditionalNG();
092        int nodeNumber = _selectNodeNumber.evaluateValue(conditionalNG);
093        int eventNumber = _selectEventNumber.evaluateValue(conditionalNG);
094        CbusEventType state = _selectEventType.evaluateEnum(getConditionalNG());
095
096        ThreadingUtil.runOnLayoutWithJmriException(() -> {
097            CbusEvent event = new CbusEvent(_memo,nodeNumber,eventNumber);
098            state._command.action(event);
099        });
100    }
101
102    @Override
103    public FemaleSocket getChild(int index) throws IllegalArgumentException, UnsupportedOperationException {
104        throw new UnsupportedOperationException("Not supported.");
105    }
106
107    @Override
108    public int getChildCount() {
109        return 0;
110    }
111
112    @Override
113    public String getShortDescription(Locale locale) {
114        return Bundle.getMessage(locale, "SendCbusEvent_Short");
115    }
116
117    @Override
118    public String getLongDescription(Locale locale) {
119        String nodeNumber = _selectNodeNumber.getDescription(locale);
120        String eventNumber = _selectEventNumber.getDescription(locale);
121        String eventType = _selectEventType.getDescription(locale);
122
123        return Bundle.getMessage(locale, "SendCbusEvent_Long", eventNumber, eventType, nodeNumber,
124                _memo != null ? _memo.getUserName() : Bundle.getMessage("MemoNotSet"));
125    }
126
127    /** {@inheritDoc} */
128    @Override
129    public void setup() {
130        // Do nothing
131    }
132
133    /** {@inheritDoc} */
134    @Override
135    public void registerListenersForThisClass() {
136        _selectNodeNumber.registerListeners();
137        _selectEventType.registerListeners();
138    }
139
140    /** {@inheritDoc} */
141    @Override
142    public void unregisterListenersForThisClass() {
143        _selectNodeNumber.unregisterListeners();
144        _selectEventType.unregisterListeners();
145    }
146
147    /** {@inheritDoc} */
148    @Override
149    public void propertyChange(PropertyChangeEvent evt) {
150        getConditionalNG().execute();
151    }
152
153    /** {@inheritDoc} */
154    @Override
155    public void disposeMe() {
156    }
157
158
159    public enum CbusEventType {
160        Off((e)-> {e.sendOff();}, Bundle.getMessage("SendCbusEvent_EventType_Off")),
161        On((e)-> {e.sendOn();}, Bundle.getMessage("SendCbusEvent_EventType_On")),
162        Request((e)-> {e.sendRequest();}, Bundle.getMessage("SendCbusEvent_EventType_Request"));
163
164        private interface EventCommand {
165            void action(CbusEvent event);
166        }
167
168        private final EventCommand _command;
169        private final String _text;
170
171        private CbusEventType(EventCommand command, String text) {
172            this._command = command;
173            this._text = text;
174        }
175
176        @Override
177        public String toString() {
178            return _text;
179        }
180
181    }
182
183    private final static org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(SendMergCbusEvent.class);
184
185}