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.ExpressionLocalVariable;
014import jmri.jmrit.logixng.expressions.ExpressionLocalVariable.CompareTo;
015import jmri.jmrit.logixng.expressions.ExpressionLocalVariable.VariableOperation;
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 ExpressionLocalVariable object with a Swing JPanel.
024 *
025 * @author Daniel Bergqvist Copyright 2021
026 */
027public class ExpressionLocalVariableSwing extends AbstractDigitalExpressionSwing {
028
029    private LogixNG_SelectTableSwing selectTableSwing;
030    private JTextField _localVariableTextField;
031    private JComboBox<VariableOperation> _variableOperationComboBox;
032    private JComboBox<CompareType> _variableCompareTypeComboBox;
033    private JCheckBox _caseInsensitiveCheckBox;
034
035    private JTabbedPane _tabbedPane;
036
037    private JTabbedPane _tabbedPaneCompareTo;
038    private BeanSelectPanel<Memory> _compareToMemoryBeanPanel;
039    private JPanel _compareToConstant;
040    private JPanel _compareToMemory;
041    private JPanel _compareToLocalVariable;
042    private JPanel _compareToTable;
043    private JPanel _compareToRegEx;
044    private JTextField _compareToConstantTextField;
045    private JTextField _compareToLocalVariableTextField;
046    private JTextField _compareToRegExTextField;
047
048
049    private void enableDisableCompareTo() {
050        VariableOperation vo = _variableOperationComboBox.getItemAt(
051                        _variableOperationComboBox.getSelectedIndex());
052        boolean enable = vo.hasExtraValue();
053        _tabbedPaneCompareTo.setEnabled(enable);
054        ((JPanel)_tabbedPaneCompareTo.getSelectedComponent())
055                .getComponent(0).setEnabled(enable);
056
057        boolean regEx = (vo == VariableOperation.MatchRegex)
058                || (vo == VariableOperation.NotMatchRegex);
059        _tabbedPane.setEnabledAt(0, !regEx);
060        _tabbedPane.setEnabledAt(1, regEx);
061        _tabbedPane.setSelectedIndex(regEx ? 1 : 0);
062    }
063
064    @Override
065    protected void createPanel(@CheckForNull Base object, @Nonnull JPanel buttonPanel) {
066
067        ExpressionLocalVariable expression = (ExpressionLocalVariable)object;
068
069        selectTableSwing = new LogixNG_SelectTableSwing(getJDialog(), this);
070
071        panel = new JPanel();
072
073        _localVariableTextField = new JTextField(20);
074
075        JPanel operationAndCasePanel = new JPanel();
076        operationAndCasePanel.setLayout(new GridBagLayout());
077        GridBagConstraints constraint = new GridBagConstraints();
078        constraint.gridwidth = 2;
079        constraint.gridheight = 1;
080        constraint.gridx = 0;
081        constraint.gridy = 0;
082        constraint.anchor = GridBagConstraints.EAST;
083
084        _variableOperationComboBox = new JComboBox<>();
085        for (VariableOperation e : VariableOperation.values()) {
086            _variableOperationComboBox.addItem(e);
087        }
088        JComboBoxUtil.setupComboBoxMaxRows(_variableOperationComboBox);
089        operationAndCasePanel.add(_variableOperationComboBox, constraint);
090
091        _variableOperationComboBox.addActionListener((e) -> { enableDisableCompareTo(); });
092
093        constraint.gridy = 1;
094        operationAndCasePanel.add(javax.swing.Box.createVerticalStrut(8), constraint);
095
096        constraint.gridwidth = 1;
097        constraint.gridx = 0;
098        constraint.gridy = 2;
099        constraint.anchor = GridBagConstraints.EAST;
100        operationAndCasePanel.add(new JLabel(Bundle.getMessage("ExpressionLocalVariable_CompareType")+" "), constraint);
101
102        constraint.gridx = 1;
103        constraint.anchor = GridBagConstraints.WEST;
104        _variableCompareTypeComboBox = new JComboBox<>();
105        for (CompareType e : CompareType.values()) {
106            _variableCompareTypeComboBox.addItem(e);
107        }
108        JComboBoxUtil.setupComboBoxMaxRows(_variableCompareTypeComboBox);
109        operationAndCasePanel.add(_variableCompareTypeComboBox, constraint);
110
111        _variableCompareTypeComboBox.addActionListener((e) -> {
112            CompareType type = _variableCompareTypeComboBox.getItemAt(
113                    _variableCompareTypeComboBox.getSelectedIndex());
114            _caseInsensitiveCheckBox.setEnabled(type != CompareType.Number);
115        });
116
117        constraint.gridwidth = 2;
118        constraint.gridx = 0;
119        constraint.gridy = 3;
120        constraint.anchor = GridBagConstraints.WEST;
121        _caseInsensitiveCheckBox = new JCheckBox(Bundle.getMessage("ExpressionLocalVariable_CaseInsensitive"));
122        operationAndCasePanel.add(_caseInsensitiveCheckBox, constraint);
123
124        _tabbedPane = new JTabbedPane();
125
126        _tabbedPaneCompareTo = new JTabbedPane();
127        _tabbedPane.addTab("", _tabbedPaneCompareTo);
128
129        _compareToConstant = new JPanel();
130        _compareToMemory = new JPanel();
131        if (expression != null) {
132            _compareToTable = selectTableSwing.createPanel(expression.getSelectTable());
133        } else {
134            _compareToTable = selectTableSwing.createPanel(null);
135        }
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.getLocalVariable() != null) {
161                _localVariableTextField.setText(expression.getLocalVariable());
162            }
163            if (expression.getSelectMemoryNamedBean().getNamedBean() != null) {
164                _compareToMemoryBeanPanel.setDefaultNamedBean(expression.getSelectMemoryNamedBean().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());
173            }
174            _variableOperationComboBox.setSelectedItem(expression.getVariableOperation());
175            _variableCompareTypeComboBox.setSelectedItem(expression.getCompareType());
176            _caseInsensitiveCheckBox.setSelected(expression.getCaseInsensitive());
177            _compareToConstantTextField.setText(expression.getConstantValue());
178            _compareToLocalVariableTextField.setText(expression.getOtherLocalVariable());
179            _compareToRegExTextField.setText(expression.getRegEx());
180        }
181
182        JComponent[] components = new JComponent[]{
183            _localVariableTextField,
184            operationAndCasePanel,
185            _tabbedPane
186        };
187
188        List<JComponent> componentList = SwingConfiguratorInterface.parseMessage(
189                Bundle.getMessage("ExpressionLocalVariable_Components"), components);
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        ExpressionLocalVariable expression = new ExpressionLocalVariable("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        ExpressionLocalVariable expression = new ExpressionLocalVariable(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 ExpressionLocalVariable)) {
217            throw new IllegalArgumentException("object must be an ExpressionLocalVariable but is a: "+object.getClass().getName());
218        }
219        ExpressionLocalVariable expression = (ExpressionLocalVariable)object;
220
221        expression.setLocalVariable(_localVariableTextField.getText());
222        expression.setVariableOperation(_variableOperationComboBox.getItemAt(_variableOperationComboBox.getSelectedIndex()));
223        expression.setCompareType(_variableCompareTypeComboBox.getItemAt(_variableCompareTypeComboBox.getSelectedIndex()));
224        expression.setCaseInsensitive(_caseInsensitiveCheckBox.isSelected());
225
226
227        if (!_compareToMemoryBeanPanel.isEmpty()
228                && (_tabbedPane.getSelectedComponent() == _tabbedPaneCompareTo)
229                && (_tabbedPaneCompareTo.getSelectedComponent() == _compareToMemory)) {
230            Memory otherMemory = _compareToMemoryBeanPanel.getNamedBean();
231            if (otherMemory != null) {
232                NamedBeanHandle<Memory> handle
233                        = InstanceManager.getDefault(NamedBeanHandleManager.class)
234                                .getNamedBeanHandle(otherMemory.getDisplayName(), otherMemory);
235                expression.getSelectMemoryNamedBean().setNamedBean(handle);
236            } else {
237                expression.getSelectMemoryNamedBean().removeNamedBean();
238            }
239        } else {
240            expression.getSelectMemoryNamedBean().removeNamedBean();
241        }
242
243        if (_tabbedPane.getSelectedComponent() == _tabbedPaneCompareTo) {
244            if (_tabbedPaneCompareTo.getSelectedComponent() == _compareToConstant) {
245                expression.setCompareTo(CompareTo.Value);
246                expression.setConstantValue(_compareToConstantTextField.getText());
247            } else if (_tabbedPaneCompareTo.getSelectedComponent() == _compareToMemory) {
248                expression.setCompareTo(CompareTo.Memory);
249            } else if (_tabbedPaneCompareTo.getSelectedComponent() == _compareToTable) {
250                expression.setCompareTo(CompareTo.Table);
251            } else if (_tabbedPaneCompareTo.getSelectedComponent() == _compareToLocalVariable) {
252                expression.setCompareTo(CompareTo.LocalVariable);
253                expression.setOtherLocalVariable(_compareToLocalVariableTextField.getText());
254//            } else if (_tabbedPaneCompareTo.getSelectedComponent() == _compareToRegEx) {
255//                expression.setCompareTo(CompareTo.RegEx);
256//                expression.setRegEx(_compareToRegExTextField.getText());
257            } else {
258                throw new IllegalArgumentException("_tabbedPaneLight has unknown selection");
259            }
260        } else {
261            expression.setCompareTo(CompareTo.RegEx);
262            expression.setRegEx(_compareToRegExTextField.getText());
263        }
264
265
266        selectTableSwing.updateObject(expression.getSelectTable());
267    }
268
269    /** {@inheritDoc} */
270    @Override
271    public String toString() {
272        return Bundle.getMessage("LocalVariable_Short");
273    }
274
275    /** {@inheritDoc} */
276    @Override
277    public boolean canClose() {
278        return selectTableSwing.canClose();
279    }
280
281    @Override
282    public void dispose() {
283        selectTableSwing.dispose();
284    }
285
286
287//    private final static org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(ExpressionLocalVariableSwing.class);
288
289}