001package jmri.jmrit.logixng.actions.swing;
002
003import java.util.List;
004
005import javax.annotation.CheckForNull;
006import javax.annotation.Nonnull;
007import javax.swing.*;
008
009import jmri.*;
010import jmri.jmrit.logixng.*;
011import jmri.jmrit.logixng.actions.ActionLocalVariable;
012import jmri.jmrit.logixng.actions.ActionLocalVariable.ConstantType;
013import jmri.jmrit.logixng.actions.ActionLocalVariable.VariableOperation;
014import jmri.jmrit.logixng.swing.SwingConfiguratorInterface;
015import jmri.jmrit.logixng.util.parser.ParserException;
016import jmri.jmrit.logixng.util.swing.LogixNG_SelectTableSwing;
017import jmri.util.swing.BeanSelectPanel;
018import jmri.util.swing.JComboBoxUtil;
019
020/**
021 * Configures an ActionLocalVariable object with a Swing JPanel.
022 *
023 * @author Daniel Bergqvist Copyright 2021
024 */
025public class ActionLocalVariableSwing extends AbstractDigitalActionSwing {
026
027    private LogixNG_SelectTableSwing selectTableSwing;
028
029    private JTextField _localVariableTextField;
030
031    private JTabbedPane _tabbedPaneVariableOperation;
032    private BeanSelectPanel<Memory> _copyMemoryBeanPanel;
033    private JCheckBox _listenOnMemory;
034    private BeanSelectPanel<Block> _copyBlockBeanPanel;
035    private JCheckBox _listenOnBlock;
036    private BeanSelectPanel<Reporter> _copyReporterBeanPanel;
037    private JCheckBox _listenOnReporter;
038    private JPanel _setToNull;
039    private JPanel _setToConstant;
040    private JPanel _copyMemory;
041    private JPanel _copyBlock;
042    private JPanel _copyReporter;
043    private JPanel _copyVariable;
044    private JPanel _copyReference;
045    private JPanel _calculateFormula;
046    private JPanel _copyTableCell;
047    private JComboBox<ConstantType> _setToConstantTypeComboBox;
048    private JTextField _setToConstantTextField;
049    private JTextField _copyLocalVariableTextField;
050    private JTextField _copyReferenceTextField;
051    private JTextField _calculateFormulaTextField;
052
053
054    @Override
055    protected void createPanel(@CheckForNull Base object, @Nonnull JPanel buttonPanel) {
056        ActionLocalVariable action = (ActionLocalVariable)object;
057
058        selectTableSwing = new LogixNG_SelectTableSwing(getJDialog(), this);
059
060        panel = new JPanel();
061
062        _localVariableTextField = new JTextField(20);
063
064        _tabbedPaneVariableOperation = new JTabbedPane();
065
066        _setToNull = new JPanel();
067        _setToConstant = new JPanel();
068        _setToConstant.setLayout(new BoxLayout(_setToConstant, BoxLayout.Y_AXIS));
069        _copyMemory = new JPanel();
070        _copyBlock = new JPanel();
071        _copyReporter = new JPanel();
072        if (action != null) {
073            _copyTableCell = selectTableSwing.createPanel(action.getSelectTable());
074        } else {
075            _copyTableCell = selectTableSwing.createPanel(null);
076        }
077        _copyVariable = new JPanel();
078        _copyReference = new JPanel();
079        _calculateFormula = new JPanel();
080
081
082        _tabbedPaneVariableOperation.addTab(VariableOperation.SetToNull.toString(), _setToNull);
083        _tabbedPaneVariableOperation.addTab(VariableOperation.SetToString.toString(), _setToConstant);
084        _tabbedPaneVariableOperation.addTab(VariableOperation.CopyMemoryToVariable.toString(), _copyMemory);
085        _tabbedPaneVariableOperation.addTab(VariableOperation.CopyBlockToVariable.toString(), _copyBlock);
086        _tabbedPaneVariableOperation.addTab(VariableOperation.CopyReporterToVariable.toString(), _copyReporter);
087        _tabbedPaneVariableOperation.addTab(VariableOperation.CopyVariableToVariable.toString(), _copyVariable);
088        _tabbedPaneVariableOperation.addTab(VariableOperation.CopyReferenceToVariable.toString(), _copyReference);
089        _tabbedPaneVariableOperation.addTab(VariableOperation.CopyTableCellToVariable.toString(), _copyTableCell);
090        _tabbedPaneVariableOperation.addTab(VariableOperation.CalculateFormula.toString(), _calculateFormula);
091
092        _setToNull.add(new JLabel("Null"));     // No I18N
093
094        JPanel _setToConstantTypeInnerPanel = new JPanel();
095        _setToConstantTypeComboBox = new JComboBox<>();
096        for (ConstantType value : ConstantType.values()) {
097            _setToConstantTypeComboBox.addItem(value);
098        }
099        JComboBoxUtil.setupComboBoxMaxRows(_setToConstantTypeComboBox);
100        _setToConstantTypeInnerPanel.add(new JLabel(Bundle.getMessage("ActionLocalVariable_ConstantType")));
101        _setToConstantTypeInnerPanel.add(_setToConstantTypeComboBox);
102        _setToConstant.add(_setToConstantTypeInnerPanel);
103
104        JPanel _setToConstantTextFieldInnerPanel = new JPanel();
105        _setToConstantTextField = new JTextField(30);
106        _setToConstantTextFieldInnerPanel.add(_setToConstantTextField);
107        _setToConstant.add(_setToConstantTextFieldInnerPanel);
108
109        _copyMemoryBeanPanel = new BeanSelectPanel<>(InstanceManager.getDefault(MemoryManager.class), null);
110        _listenOnMemory = new JCheckBox(Bundle.getMessage("ActionLocalVariable_ListenOnMemory"));
111        _copyMemory.add(_copyMemoryBeanPanel);
112        _copyMemory.add(_listenOnMemory);
113
114        _copyBlockBeanPanel = new BeanSelectPanel<>(InstanceManager.getDefault(BlockManager.class), null);
115        _listenOnBlock = new JCheckBox(Bundle.getMessage("ActionLocalVariable_ListenOnBlock"));
116        _copyBlock.add(_copyBlockBeanPanel);
117        _copyBlock.add(_listenOnBlock);
118
119        _copyReporterBeanPanel = new BeanSelectPanel<>(InstanceManager.getDefault(ReporterManager.class), null);
120        _listenOnReporter = new JCheckBox(Bundle.getMessage("ActionLocalVariable_ListenOnReporter"));
121        _copyReporter.add(_copyReporterBeanPanel);
122        _copyReporter.add(_listenOnReporter);
123
124        _copyLocalVariableTextField = new JTextField(30);
125        _copyVariable.add(_copyLocalVariableTextField);
126
127        _copyReferenceTextField = new JTextField(30);
128        _copyReference.add(_copyReferenceTextField);
129
130        _calculateFormulaTextField = new JTextField(30);
131        _calculateFormula.add(_calculateFormulaTextField);
132
133
134        if (action != null) {
135            if (action.getLocalVariable() != null) {
136                _localVariableTextField.setText(action.getLocalVariable());
137            }
138            if (action.getSelectMemoryNamedBean().getNamedBean() != null) {
139                _copyMemoryBeanPanel.setDefaultNamedBean(action.getSelectMemoryNamedBean().getNamedBean().getBean());
140            }
141            if (action.getSelectBlockNamedBean().getNamedBean() != null) {
142                _copyBlockBeanPanel.setDefaultNamedBean(action.getSelectBlockNamedBean().getNamedBean().getBean());
143            }
144            if (action.getSelectReporterNamedBean().getNamedBean() != null) {
145                _copyReporterBeanPanel.setDefaultNamedBean(action.getSelectReporterNamedBean().getNamedBean().getBean());
146            }
147            switch (action.getVariableOperation()) {
148                case SetToNull: _tabbedPaneVariableOperation.setSelectedComponent(_setToNull); break;
149                case SetToString: _tabbedPaneVariableOperation.setSelectedComponent(_setToConstant); break;
150                case CopyMemoryToVariable: _tabbedPaneVariableOperation.setSelectedComponent(_copyMemory); break;
151                case CopyTableCellToVariable: _tabbedPaneVariableOperation.setSelectedComponent(_copyTableCell); break;
152                case CopyBlockToVariable: _tabbedPaneVariableOperation.setSelectedComponent(_copyBlock); break;
153                case CopyReporterToVariable: _tabbedPaneVariableOperation.setSelectedComponent(_copyReporter); break;
154                case CopyVariableToVariable: _tabbedPaneVariableOperation.setSelectedComponent(_copyVariable); break;
155                case CopyReferenceToVariable: _tabbedPaneVariableOperation.setSelectedComponent(_copyReference); break;
156                case CalculateFormula: _tabbedPaneVariableOperation.setSelectedComponent(_calculateFormula); break;
157                default: throw new IllegalArgumentException("invalid _addressing state: " + action.getVariableOperation().name());
158            }
159            _setToConstantTypeComboBox.setSelectedItem(action.getConstantType());
160            _setToConstantTextField.setText(action.getConstantValue());
161            _copyLocalVariableTextField.setText(action.getOtherLocalVariable());
162            _copyReferenceTextField.setText(action.getReference());
163            _calculateFormulaTextField.setText(action.getFormula());
164
165            _listenOnMemory.setSelected(action.getListenToMemory());
166            _listenOnBlock.setSelected(action.getListenToBlock());
167            _listenOnReporter.setSelected(action.getListenToReporter());
168        }
169
170        JComponent[] components = new JComponent[]{
171            _localVariableTextField,
172            _tabbedPaneVariableOperation
173        };
174
175        List<JComponent> componentList = SwingConfiguratorInterface.parseMessage(
176                Bundle.getMessage("ActionLocalVariable_Components"), components);
177
178        for (JComponent c : componentList) panel.add(c);
179    }
180
181    /** {@inheritDoc} */
182    @Override
183    public boolean validate(@Nonnull List<String> errorMessages) {
184        ActionLocalVariable action = new ActionLocalVariable("IQDA1", null);
185
186        try {
187            action.setVariableOperation(VariableOperation.CalculateFormula);
188            action.setFormula(_calculateFormulaTextField.getText());
189        } catch (ParserException e) {
190            errorMessages.add(e.getMessage());
191        }
192
193        // If using the Memory tab, validate the memory variable selection.
194        if (_tabbedPaneVariableOperation.getSelectedComponent() == _copyMemory) {
195            if (_copyMemoryBeanPanel.getNamedBean() == null) {
196                errorMessages.add(Bundle.getMessage("ActionLocalVariable_CopyErrorMemory"));
197            }
198        }
199
200         // If using the Block tab, validate the block variable selection.
201        if (_tabbedPaneVariableOperation.getSelectedComponent() == _copyBlock) {
202            if (_copyBlockBeanPanel.getNamedBean() == null) {
203                errorMessages.add(Bundle.getMessage("ActionLocalVariable_CopyErrorBlock"));
204            }
205        }
206
207         // If using the Reporter tab, validate the reporter variable selection.
208        if (_tabbedPaneVariableOperation.getSelectedComponent() == _copyReporter) {
209            if (_copyReporterBeanPanel.getNamedBean() == null) {
210                errorMessages.add(Bundle.getMessage("ActionLocalVariable_CopyErrorReporter"));
211            }
212        }
213
214        selectTableSwing.validate(action.getSelectTable(), errorMessages);
215
216        return errorMessages.isEmpty();
217    }
218
219    /** {@inheritDoc} */
220    @Override
221    public MaleSocket createNewObject(@Nonnull String systemName, @CheckForNull String userName) {
222        ActionLocalVariable action = new ActionLocalVariable(systemName, userName);
223        updateObject(action);
224        return InstanceManager.getDefault(DigitalActionManager.class).registerAction(action);
225    }
226
227    /** {@inheritDoc} */
228    @Override
229    public void updateObject(@Nonnull Base object) {
230        if (! (object instanceof ActionLocalVariable)) {
231            throw new IllegalArgumentException("object must be an ActionLocalVariable but is a: "+object.getClass().getName());
232        }
233        ActionLocalVariable action = (ActionLocalVariable)object;
234
235        action.setLocalVariable(_localVariableTextField.getText());
236
237
238        if (!_copyMemoryBeanPanel.isEmpty()
239                && (_tabbedPaneVariableOperation.getSelectedComponent() == _copyMemory)) {
240            Memory memory = _copyMemoryBeanPanel.getNamedBean();
241            if (memory != null) {
242                NamedBeanHandle<Memory> handle
243                        = InstanceManager.getDefault(NamedBeanHandleManager.class)
244                                .getNamedBeanHandle(memory.getDisplayName(), memory);
245                action.getSelectMemoryNamedBean().setNamedBean(handle);
246            }
247        }
248
249        if (!_copyBlockBeanPanel.isEmpty()
250                && (_tabbedPaneVariableOperation.getSelectedComponent() == _copyBlock)) {
251            Block block = _copyBlockBeanPanel.getNamedBean();
252            if (block != null) {
253                NamedBeanHandle<Block> handle
254                        = InstanceManager.getDefault(NamedBeanHandleManager.class)
255                                .getNamedBeanHandle(block.getDisplayName(), block);
256                action.getSelectBlockNamedBean().setNamedBean(handle);
257            }
258        }
259
260        if (!_copyReporterBeanPanel.isEmpty()
261                && (_tabbedPaneVariableOperation.getSelectedComponent() == _copyReporter)) {
262            Reporter reporter = _copyReporterBeanPanel.getNamedBean();
263            if (reporter != null) {
264                NamedBeanHandle<Reporter> handle
265                        = InstanceManager.getDefault(NamedBeanHandleManager.class)
266                                .getNamedBeanHandle(reporter.getDisplayName(), reporter);
267                action.getSelectReporterNamedBean().setNamedBean(handle);
268            }
269        }
270
271        try {
272            if (_tabbedPaneVariableOperation.getSelectedComponent() == _setToNull) {
273                action.setVariableOperation(VariableOperation.SetToNull);
274            } else if (_tabbedPaneVariableOperation.getSelectedComponent() == _setToConstant) {
275                action.setVariableOperation(VariableOperation.SetToString);
276                action.setConstantType(_setToConstantTypeComboBox.getItemAt(
277                        _setToConstantTypeComboBox.getSelectedIndex()));
278                action.setConstantValue(_setToConstantTextField.getText());
279            } else if (_tabbedPaneVariableOperation.getSelectedComponent() == _copyMemory) {
280                action.setVariableOperation(VariableOperation.CopyMemoryToVariable);
281            } else if (_tabbedPaneVariableOperation.getSelectedComponent() == _copyBlock) {
282                action.setVariableOperation(VariableOperation.CopyBlockToVariable);
283            } else if (_tabbedPaneVariableOperation.getSelectedComponent() == _copyReporter) {
284                action.setVariableOperation(VariableOperation.CopyReporterToVariable);
285            } else if (_tabbedPaneVariableOperation.getSelectedComponent() == _copyTableCell) {
286                action.setVariableOperation(VariableOperation.CopyTableCellToVariable);
287            } else if (_tabbedPaneVariableOperation.getSelectedComponent() == _copyVariable) {
288                action.setVariableOperation(VariableOperation.CopyVariableToVariable);
289                action.setOtherLocalVariable(_copyLocalVariableTextField.getText());
290            } else if (_tabbedPaneVariableOperation.getSelectedComponent() == _copyReference) {
291                action.setVariableOperation(VariableOperation.CopyReferenceToVariable);
292                action.setReference(_copyReferenceTextField.getText());
293            } else if (_tabbedPaneVariableOperation.getSelectedComponent() == _calculateFormula) {
294                action.setVariableOperation(VariableOperation.CalculateFormula);
295                action.setFormula(_calculateFormulaTextField.getText());
296            } else {
297                throw new IllegalArgumentException("_tabbedPaneVariableOperation has unknown selection");
298            }
299        } catch (ParserException e) {
300            throw new RuntimeException("ParserException: "+e.getMessage(), e);
301        }
302
303        selectTableSwing.updateObject(action.getSelectTable());
304
305        action.setListenToMemory(_listenOnMemory.isSelected());
306        action.setListenToBlock(_listenOnBlock.isSelected());
307        action.setListenToReporter(_listenOnReporter.isSelected());
308    }
309
310    /** {@inheritDoc} */
311    @Override
312    public String toString() {
313        return Bundle.getMessage("ActionLocalVariable_Short");
314    }
315
316    /** {@inheritDoc} */
317    @Override
318    public boolean canClose() {
319        return selectTableSwing.canClose();
320    }
321
322    @Override
323    public void dispose() {
324        selectTableSwing.dispose();
325    }
326
327//    private final static org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(ActionLocalVariableSwing.class);
328
329}