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