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