001package jmri.jmrit.logixng.expressions.swing;
002
003import java.awt.GridBagConstraints;
004import java.awt.GridBagLayout;
005import java.util.List;
006
007import javax.annotation.CheckForNull;
008import javax.annotation.Nonnull;
009import javax.swing.*;
010
011import jmri.*;
012import jmri.jmrit.logixng.*;
013import jmri.jmrit.logixng.expressions.ExpressionMemory;
014import jmri.jmrit.logixng.expressions.ExpressionMemory.CompareTo;
015import jmri.jmrit.logixng.expressions.ExpressionMemory.MemoryOperation;
016import jmri.jmrit.logixng.swing.SwingConfiguratorInterface;
017import jmri.jmrit.logixng.util.swing.LogixNG_SelectTableSwing;
018import jmri.util.CompareUtil.CompareType;
019import jmri.util.swing.BeanSelectPanel;
020import jmri.util.swing.JComboBoxUtil;
021
022/**
023 * Configures an ExpressionMemory object with a Swing JPanel.
024 *
025 * @author Daniel Bergqvist Copyright 2021
026 */
027public class ExpressionMemorySwing extends AbstractDigitalExpressionSwing {
028
029    private LogixNG_SelectTableSwing selectTableSwing;
030
031    private BeanSelectPanel<Memory> _memoryBeanPanel;
032    private JComboBox<MemoryOperation> _memoryOperationComboBox;
033    private JComboBox<CompareType> _variableCompareTypeComboBox;
034    private JCheckBox _caseInsensitiveCheckBox;
035
036    private JTabbedPane _tabbedPane;
037
038    private JTabbedPane _tabbedPaneCompareTo;
039    private BeanSelectPanel<Memory> _compareToMemoryBeanPanel;
040    private JPanel _compareToConstant;
041    private JPanel _compareToMemory;
042    private JPanel _compareToLocalVariable;
043    private JPanel _compareToTable;
044    private JPanel _compareToRegEx;
045    private JTextField _compareToConstantTextField;
046    private JTextField _compareToLocalVariableTextField;
047    private JTextField _compareToRegExTextField;
048
049
050
051    private void enableDisableCompareTo() {
052        MemoryOperation mo = _memoryOperationComboBox.getItemAt(
053                        _memoryOperationComboBox.getSelectedIndex());
054        boolean enable = mo.hasExtraValue();
055        _tabbedPaneCompareTo.setEnabled(enable);
056        ((JPanel)_tabbedPaneCompareTo.getSelectedComponent())
057                .getComponent(0).setEnabled(enable);
058
059        boolean regEx = (mo == MemoryOperation.MatchRegex)
060                || (mo == MemoryOperation.NotMatchRegex);
061        _tabbedPane.setEnabledAt(0, !regEx);
062        _tabbedPane.setEnabledAt(1, regEx);
063        _tabbedPane.setSelectedIndex(regEx ? 1 : 0);
064    }
065
066    @Override
067    protected void createPanel(@CheckForNull Base object, @Nonnull JPanel buttonPanel) {
068        ExpressionMemory expression = (ExpressionMemory)object;
069
070        selectTableSwing = new LogixNG_SelectTableSwing(getJDialog(), this);
071
072        panel = new JPanel();
073
074        _memoryBeanPanel = new BeanSelectPanel<>(InstanceManager.getDefault(MemoryManager.class), null);
075
076        JPanel operationAndCasePanel = new JPanel();
077        operationAndCasePanel.setLayout(new GridBagLayout());
078        GridBagConstraints constraint = new GridBagConstraints();
079        constraint.gridwidth = 2;
080        constraint.gridheight = 1;
081        constraint.gridx = 0;
082        constraint.gridy = 0;
083        constraint.anchor = GridBagConstraints.EAST;
084
085        _memoryOperationComboBox = new JComboBox<>();
086        for (MemoryOperation e : MemoryOperation.values()) {
087            _memoryOperationComboBox.addItem(e);
088        }
089        JComboBoxUtil.setupComboBoxMaxRows(_memoryOperationComboBox);
090        operationAndCasePanel.add(_memoryOperationComboBox, constraint);
091
092        _memoryOperationComboBox.addActionListener((e) -> { enableDisableCompareTo(); });
093
094        constraint.gridy = 1;
095        operationAndCasePanel.add(javax.swing.Box.createVerticalStrut(8), constraint);
096
097        constraint.gridwidth = 1;
098        constraint.gridx = 0;
099        constraint.gridy = 2;
100        constraint.anchor = GridBagConstraints.EAST;
101        operationAndCasePanel.add(new JLabel(Bundle.getMessage("ExpressionMemory_CompareType")+" "), constraint);
102
103        constraint.gridx = 1;
104        constraint.anchor = GridBagConstraints.WEST;
105        _variableCompareTypeComboBox = new JComboBox<>();
106        for (CompareType e : CompareType.values()) {
107            _variableCompareTypeComboBox.addItem(e);
108        }
109        JComboBoxUtil.setupComboBoxMaxRows(_variableCompareTypeComboBox);
110        operationAndCasePanel.add(_variableCompareTypeComboBox, constraint);
111
112        _variableCompareTypeComboBox.addActionListener((e) -> {
113            CompareType type = _variableCompareTypeComboBox.getItemAt(
114                    _variableCompareTypeComboBox.getSelectedIndex());
115            _caseInsensitiveCheckBox.setEnabled(type != CompareType.Number);
116        });
117
118        constraint.gridwidth = 2;
119        constraint.gridx = 0;
120        constraint.gridy = 3;
121        constraint.anchor = GridBagConstraints.WEST;
122        _caseInsensitiveCheckBox = new JCheckBox(Bundle.getMessage("ExpressionMemory_CaseInsensitive"));    // NOI18N
123        operationAndCasePanel.add(_caseInsensitiveCheckBox, constraint);
124
125        _tabbedPane = new JTabbedPane();
126
127        _tabbedPaneCompareTo = new JTabbedPane();
128        _tabbedPane.addTab("", _tabbedPaneCompareTo);
129
130        _compareToConstant = new JPanel();
131        _compareToMemory = new JPanel();
132        if (expression != null) {
133            _compareToTable = selectTableSwing.createPanel(expression.getSelectTable());
134        } else {
135            _compareToTable = selectTableSwing.createPanel(null);
136        }        _compareToLocalVariable = new JPanel();
137        _compareToRegEx = new JPanel();
138
139        _tabbedPaneCompareTo.addTab(CompareTo.Value.toString(), _compareToConstant);
140        _tabbedPaneCompareTo.addTab(CompareTo.Memory.toString(), _compareToMemory);
141        _tabbedPaneCompareTo.addTab(CompareTo.LocalVariable.toString(), _compareToLocalVariable);
142        _tabbedPaneCompareTo.addTab(CompareTo.Table.toString(), _compareToTable);
143
144        _tabbedPane.addTab(CompareTo.RegEx.toString(), _compareToRegEx);
145
146        _compareToConstantTextField = new JTextField(30);
147        _compareToConstant.add(_compareToConstantTextField);
148
149        _compareToMemoryBeanPanel = new BeanSelectPanel<>(InstanceManager.getDefault(MemoryManager.class), null);
150        _compareToMemory.add(_compareToMemoryBeanPanel);
151
152        _compareToLocalVariableTextField = new JTextField(30);
153        _compareToLocalVariable.add(_compareToLocalVariableTextField);
154
155        _compareToRegExTextField = new JTextField(30);
156        _compareToRegEx.add(_compareToRegExTextField);
157
158
159        if (expression != null) {
160            if (expression.getSelectNamedBean().getNamedBean() != null) {
161                _memoryBeanPanel.setDefaultNamedBean(expression.getSelectNamedBean().getNamedBean().getBean());
162            }
163            if (expression.getSelectOtherMemoryNamedBean().getNamedBean() != null) {
164                _compareToMemoryBeanPanel.setDefaultNamedBean(expression.getSelectOtherMemoryNamedBean().getNamedBean().getBean());
165            }
166            switch (expression.getCompareTo()) {
167                case RegEx:
168                case Value: _tabbedPaneCompareTo.setSelectedComponent(_compareToConstant); break;
169                case Memory: _tabbedPaneCompareTo.setSelectedComponent(_compareToMemory); break;
170                case Table: _tabbedPaneCompareTo.setSelectedComponent(_compareToTable); break;
171                case LocalVariable: _tabbedPaneCompareTo.setSelectedComponent(_compareToLocalVariable); break;
172                default: throw new IllegalArgumentException("invalid _addressing state: " + expression.getCompareTo().name());  // NOI18N
173            }
174            _memoryOperationComboBox.setSelectedItem(expression.getMemoryOperation());
175            _variableCompareTypeComboBox.setSelectedItem(expression.getCompareType());
176            _caseInsensitiveCheckBox.setSelected(expression.getCaseInsensitive());
177            _compareToConstantTextField.setText(expression.getConstantValue());
178            _compareToLocalVariableTextField.setText(expression.getLocalVariable());
179            _compareToRegExTextField.setText(expression.getRegEx());
180        }
181
182        JComponent[] components = new JComponent[]{
183            _memoryBeanPanel,
184            operationAndCasePanel,
185            _tabbedPane
186        };
187
188        List<JComponent> componentList = SwingConfiguratorInterface.parseMessage(
189                Bundle.getMessage("ExpressionMemory_Components"), components);  // NOI18N
190
191        for (JComponent c : componentList) panel.add(c);
192
193        enableDisableCompareTo();
194    }
195
196    /** {@inheritDoc} */
197    @Override
198    public boolean validate(@Nonnull List<String> errorMessages) {
199        // Create a temporary action to test formula
200        ExpressionMemory expression = new ExpressionMemory("IQDE1", null);
201
202        return selectTableSwing.validate(expression.getSelectTable(), errorMessages);
203    }
204
205    /** {@inheritDoc} */
206    @Override
207    public MaleSocket createNewObject(@Nonnull String systemName, @CheckForNull String userName) {
208        ExpressionMemory expression = new ExpressionMemory(systemName, userName);
209        updateObject(expression);
210        return InstanceManager.getDefault(DigitalExpressionManager.class).registerExpression(expression);
211    }
212
213    /** {@inheritDoc} */
214    @Override
215    public void updateObject(@Nonnull Base object) {
216        if (! (object instanceof ExpressionMemory)) {
217            throw new IllegalArgumentException("object must be an ExpressionMemory but is a: "+object.getClass().getName());
218        }
219        ExpressionMemory expression = (ExpressionMemory)object;
220        Memory memory = _memoryBeanPanel.getNamedBean();
221        if (memory != null) {
222            NamedBeanHandle<Memory> handle
223                    = InstanceManager.getDefault(NamedBeanHandleManager.class)
224                            .getNamedBeanHandle(memory.getDisplayName(), memory);
225            expression.getSelectNamedBean().setNamedBean(handle);
226        } else {
227            expression.getSelectNamedBean().removeNamedBean();
228        }
229        expression.setMemoryOperation(_memoryOperationComboBox.getItemAt(_memoryOperationComboBox.getSelectedIndex()));
230        expression.setCompareType(_variableCompareTypeComboBox.getItemAt(_variableCompareTypeComboBox.getSelectedIndex()));
231        expression.setCaseInsensitive(_caseInsensitiveCheckBox.isSelected());
232
233
234        if (!_compareToMemoryBeanPanel.isEmpty()
235                && (_tabbedPane.getSelectedComponent() == _tabbedPaneCompareTo)
236                && (_tabbedPaneCompareTo.getSelectedComponent() == _compareToMemory)) {
237            Memory otherMemory = _compareToMemoryBeanPanel.getNamedBean();
238            if (otherMemory != null) {
239                NamedBeanHandle<Memory> handle
240                        = InstanceManager.getDefault(NamedBeanHandleManager.class)
241                                .getNamedBeanHandle(otherMemory.getDisplayName(), otherMemory);
242                expression.getSelectOtherMemoryNamedBean().setNamedBean(handle);
243            } else {
244                expression.getSelectOtherMemoryNamedBean().removeNamedBean();
245            }
246        } else {
247            expression.getSelectOtherMemoryNamedBean().removeNamedBean();
248        }
249
250        if (_tabbedPane.getSelectedComponent() == _tabbedPaneCompareTo) {
251            if (_tabbedPaneCompareTo.getSelectedComponent() == _compareToConstant) {
252                expression.setCompareTo(CompareTo.Value);
253                expression.setConstantValue(_compareToConstantTextField.getText());
254            } else if (_tabbedPaneCompareTo.getSelectedComponent() == _compareToMemory) {
255                expression.setCompareTo(CompareTo.Memory);
256            } else if (_tabbedPaneCompareTo.getSelectedComponent() == _compareToTable) {
257                expression.setCompareTo(CompareTo.Table);
258            } else if (_tabbedPaneCompareTo.getSelectedComponent() == _compareToLocalVariable) {
259                expression.setCompareTo(CompareTo.LocalVariable);
260                expression.setLocalVariable(_compareToLocalVariableTextField.getText());
261//            } else if (_tabbedPaneCompareTo.getSelectedComponent() == _compareToRegEx) {
262//                expression.setCompareTo(CompareTo.RegEx);
263//                expression.setRegEx(_compareToRegExTextField.getText());
264            } else {
265                throw new IllegalArgumentException("_tabbedPaneLight has unknown selection");
266            }
267        } else {
268            expression.setCompareTo(CompareTo.RegEx);
269            expression.setRegEx(_compareToRegExTextField.getText());
270        }
271
272        selectTableSwing.updateObject(expression.getSelectTable());
273    }
274
275    /** {@inheritDoc} */
276    @Override
277    public String toString() {
278        return Bundle.getMessage("Memory_Short");
279    }
280
281    /** {@inheritDoc} */
282    @Override
283    public boolean canClose() {
284        return selectTableSwing.canClose();
285    }
286
287    @Override
288    public void dispose() {
289        selectTableSwing.dispose();
290    }
291
292
293//    private final static org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(ExpressionMemorySwing.class);
294
295}