001package jmri.jmrit.logixng.util.swing;
002
003import java.awt.event.ActionEvent;
004import java.util.List;
005
006import javax.annotation.CheckForNull;
007import javax.annotation.Nonnull;
008import javax.swing.*;
009
010import jmri.*;
011import jmri.jmrit.logixng.*;
012import jmri.jmrit.logixng.swing.SwingConfiguratorInterface;
013import jmri.jmrit.logixng.util.LogixNG_SelectString;
014import jmri.jmrit.logixng.util.parser.ParserException;
015import jmri.util.FileUtil;
016import jmri.util.swing.BeanSelectPanel;
017import jmri.util.swing.JmriJFileChooser;
018
019/**
020 * Swing class for jmri.jmrit.logixng.util.LogixNG_SelectString.
021 *
022 * @author Daniel Bergqvist (C) 2022
023 */
024public class LogixNG_SelectStringSwing {
025
026    private final JDialog _dialog;
027    private final LogixNG_SelectTableSwing _selectTableSwing;
028
029    private JTabbedPane _tabbedPane;
030    private JTextField _valueTextField;
031    private JPanel _panelDirect;
032    private JPanel _panelReference;
033    private JPanel _panelMemory;
034    private JPanel _panelLocalVariable;
035    private JPanel _panelFormula;
036    private JPanel _panelTable;
037    private JTextField _referenceTextField;
038    private BeanSelectPanel<Memory> _memoryPanel;
039    private JTextField _localVariableTextField;
040    private JTextField _formulaTextField;
041
042
043    public LogixNG_SelectStringSwing(
044            @Nonnull JDialog dialog,
045            @Nonnull SwingConfiguratorInterface swi) {
046        _dialog = dialog;
047        _selectTableSwing = new LogixNG_SelectTableSwing(_dialog, swi);
048    }
049
050    public JPanel createPanel(@CheckForNull LogixNG_SelectString selectStr) {
051        _panelDirect = new javax.swing.JPanel();
052
053        _valueTextField = new JTextField(30);
054        _panelDirect.add(_valueTextField);
055
056        return internalCreatePanel(selectStr);
057    }
058
059    public JPanel createFilenamePanel(@CheckForNull LogixNG_SelectString selectStr, String path) {
060        _panelDirect = new javax.swing.JPanel();
061
062        JButton selectFileButton = new JButton("..."); // "File" replaced by ...
063        selectFileButton.setMaximumSize(selectFileButton.getPreferredSize());
064        selectFileButton.setToolTipText(Bundle.getMessage("FileButtonHint"));  // NOI18N
065        selectFileButton.addActionListener((ActionEvent e) -> {
066            JmriJFileChooser fileChooser = new JmriJFileChooser(path);
067            fileChooser.rescanCurrentDirectory();
068            int retVal = fileChooser.showOpenDialog(null);
069            // handle selection or cancel
070            if (retVal == JFileChooser.APPROVE_OPTION) {
071                // set selected file location
072                try {
073                    _valueTextField.setText(FileUtil.getPortableFilename(fileChooser.getSelectedFile().getCanonicalPath()));
074                } catch (java.io.IOException ex) {
075                    log.error("exception setting file location", ex);  // NOI18N
076                    _valueTextField.setText("");
077                }
078            }
079        });
080        _valueTextField = new JTextField(30);
081        _panelDirect.add(_valueTextField);
082        _panelDirect.add(selectFileButton);
083
084        return internalCreatePanel(selectStr);
085    }
086
087    private JPanel internalCreatePanel(@CheckForNull LogixNG_SelectString selectStr) {
088
089        JPanel panel = new JPanel();
090
091        _tabbedPane = new JTabbedPane();
092        _panelReference = new javax.swing.JPanel();
093        _panelMemory = new JPanel();
094        _panelLocalVariable = new javax.swing.JPanel();
095        _panelFormula = new javax.swing.JPanel();
096        if (selectStr != null) {
097            _panelTable = _selectTableSwing.createPanel(selectStr.getSelectTable());
098            if (selectStr.isOnlyDirectAddressingAllowed()) {
099                _tabbedPane.setEnabled(false);
100                _panelReference.setEnabled(false);
101                _panelMemory.setEnabled(false);
102                _panelLocalVariable.setEnabled(false);
103                _panelFormula.setEnabled(false);
104            }
105        } else {
106            _panelTable = _selectTableSwing.createPanel(null);
107        }
108
109        _memoryPanel = new BeanSelectPanel<>(InstanceManager.getDefault(MemoryManager.class), null);
110
111        _panelMemory.setLayout(new BoxLayout(_panelMemory, BoxLayout.Y_AXIS));
112        _panelMemory.add(_memoryPanel);
113
114        _tabbedPane.addTab(NamedBeanAddressing.Direct.toString(), _panelDirect);
115        _tabbedPane.addTab(NamedBeanAddressing.Reference.toString(), _panelReference);
116        _tabbedPane.addTab(NamedBeanAddressing.Memory.toString(), _panelMemory);
117        _tabbedPane.addTab(NamedBeanAddressing.LocalVariable.toString(), _panelLocalVariable);
118        _tabbedPane.addTab(NamedBeanAddressing.Formula.toString(), _panelFormula);
119        _tabbedPane.addTab(NamedBeanAddressing.Table.toString(), _panelTable);
120
121        _referenceTextField = new JTextField();
122        _referenceTextField.setColumns(30);
123        _panelReference.add(_referenceTextField);
124
125        _localVariableTextField = new JTextField();
126        _localVariableTextField.setColumns(30);
127        _panelLocalVariable.add(_localVariableTextField);
128
129        _formulaTextField = new JTextField();
130        _formulaTextField.setColumns(30);
131        _panelFormula.add(_formulaTextField);
132
133
134        if (selectStr != null) {
135            switch (selectStr.getAddressing()) {
136                case Direct: _tabbedPane.setSelectedComponent(_panelDirect); break;
137                case Reference: _tabbedPane.setSelectedComponent(_panelReference); break;
138                case Memory: _tabbedPane.setSelectedComponent(_panelMemory); break;
139                case LocalVariable: _tabbedPane.setSelectedComponent(_panelLocalVariable); break;
140                case Formula: _tabbedPane.setSelectedComponent(_panelFormula); break;
141                case Table: _tabbedPane.setSelectedComponent(_panelTable); break;
142                default: throw new IllegalArgumentException("invalid _addressing state: " + selectStr.getAddressing().name());
143            }
144            if (selectStr.getValue() != null) {
145                _valueTextField.setText(selectStr.getValue());
146            }
147            _referenceTextField.setText(selectStr.getReference());
148            _memoryPanel.setDefaultNamedBean(selectStr.getMemory());
149            _localVariableTextField.setText(selectStr.getLocalVariable());
150            _formulaTextField.setText(selectStr.getFormula());
151        }
152
153        panel.add(_tabbedPane);
154        return panel;
155    }
156
157    public boolean validate(
158            @Nonnull LogixNG_SelectString selectStr,
159            @Nonnull List<String> errorMessages) {
160        try {
161            if (_tabbedPane.getSelectedComponent() == _panelDirect) {
162                selectStr.setValue(_valueTextField.getText());
163            }
164            if (_tabbedPane.getSelectedComponent() == _panelReference) {
165                selectStr.setReference(_referenceTextField.getText());
166            }
167        } catch (IllegalArgumentException e) {
168            errorMessages.add(e.getMessage());
169            return false;
170        }
171
172        try {
173            selectStr.setFormula(_formulaTextField.getText());
174            if (_tabbedPane.getSelectedComponent() == _panelDirect) {
175                selectStr.setAddressing(NamedBeanAddressing.Direct);
176            } else if (_tabbedPane.getSelectedComponent() == _panelReference) {
177                selectStr.setAddressing(NamedBeanAddressing.Reference);
178            } else if (_tabbedPane.getSelectedComponent() == _panelMemory) {
179                selectStr.setAddressing(NamedBeanAddressing.Memory);
180            } else if (_tabbedPane.getSelectedComponent() == _panelLocalVariable) {
181                selectStr.setAddressing(NamedBeanAddressing.LocalVariable);
182            } else if (_tabbedPane.getSelectedComponent() == _panelFormula) {
183                selectStr.setAddressing(NamedBeanAddressing.Formula);
184            } else if (_tabbedPane.getSelectedComponent() == _panelTable) {
185                selectStr.setAddressing(NamedBeanAddressing.Table);
186            } else {
187                throw new IllegalArgumentException("_tabbedPane has unknown selection");
188            }
189        } catch (ParserException e) {
190            errorMessages.add("Cannot parse formula: " + e.getMessage());
191            return false;
192        }
193
194        _selectTableSwing.validate(selectStr.getSelectTable(), errorMessages);
195
196        return errorMessages.isEmpty();
197    }
198
199    public void setEnabled(boolean value) {
200        _tabbedPane.setEnabled(value);
201        _valueTextField.setEnabled(value);
202        _referenceTextField.setEnabled(value);
203        _localVariableTextField.setEnabled(value);
204        _formulaTextField.setEnabled(value);
205    }
206
207    public void updateObject(@Nonnull LogixNG_SelectString selectStr) {
208
209        if (_tabbedPane.getSelectedComponent() == _panelDirect) {
210            selectStr.setValue(_valueTextField.getText());
211        }
212
213        try {
214            if (_tabbedPane.getSelectedComponent() == _panelDirect) {
215                selectStr.setAddressing(NamedBeanAddressing.Direct);
216            } else if (_tabbedPane.getSelectedComponent() == _panelReference) {
217                selectStr.setAddressing(NamedBeanAddressing.Reference);
218                selectStr.setReference(_referenceTextField.getText());
219            } else if (_tabbedPane.getSelectedComponent() == _panelMemory) {
220                selectStr.setAddressing(NamedBeanAddressing.Memory);
221                selectStr.setMemory(_memoryPanel.getNamedBean());
222            } else if (_tabbedPane.getSelectedComponent() == _panelLocalVariable) {
223                selectStr.setAddressing(NamedBeanAddressing.LocalVariable);
224                selectStr.setLocalVariable(_localVariableTextField.getText());
225            } else if (_tabbedPane.getSelectedComponent() == _panelFormula) {
226                selectStr.setAddressing(NamedBeanAddressing.Formula);
227                selectStr.setFormula(_formulaTextField.getText());
228            } else if (_tabbedPane.getSelectedComponent() == _panelTable) {
229                selectStr.setAddressing(NamedBeanAddressing.Table);
230            } else {
231                throw new IllegalArgumentException("_tabbedPaneEnum has unknown selection");
232            }
233        } catch (ParserException e) {
234            throw new RuntimeException("ParserException: "+e.getMessage(), e);
235        }
236
237        _selectTableSwing.updateObject(selectStr.getSelectTable());
238    }
239
240    public void dispose() {
241        _selectTableSwing.dispose();
242    }
243
244    private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(LogixNG_SelectStringSwing.class);
245}