001package jmri.jmrit.logixng.expressions.swing;
002
003import java.util.List;
004import java.util.SortedSet;
005
006import javax.annotation.CheckForNull;
007import javax.annotation.Nonnull;
008import javax.swing.*;
009
010import jmri.*;
011import jmri.jmrit.logixng.*;
012import jmri.jmrit.logixng.expressions.ExpressionReporter;
013import jmri.jmrit.logixng.expressions.ExpressionReporter.CompareTo;
014import jmri.jmrit.logixng.expressions.ExpressionReporter.ReporterOperation;
015import jmri.jmrit.logixng.expressions.ExpressionReporter.ReporterValue;
016import jmri.jmrit.logixng.swing.SwingConfiguratorInterface;
017import jmri.util.swing.BeanSelectPanel;
018import jmri.util.swing.JComboBoxUtil;
019
020/**
021 * Configures an ExpressionReporter object with a Swing JPanel.
022 *
023 * @author Daniel Bergqvist Copyright 2021
024 * @author Dave Sand Copyright 2021
025 */
026public class ExpressionReporterSwing extends AbstractDigitalExpressionSwing {
027
028    private BeanSelectPanel<Reporter> _reporterBeanPanel;
029    private JComboBox<ReporterValue> _reporterValueComboBox;
030    private JComboBox<ReporterOperation> _reporterOperationComboBox;
031    private JCheckBox _caseInsensitiveCheckBox;
032
033    private JTabbedPane _tabbedPane;
034
035    private JTabbedPane _tabbedPaneCompareTo;
036    private BeanSelectPanel<Memory> _compareToMemoryBeanPanel;
037    private JPanel _reporterValuePanel;
038    private JPanel _compareToConstant;
039    private JPanel _compareToMemory;
040    private JPanel _compareToLocalVariable;
041    private JPanel _compareToRegEx;
042    private JTextField _compareToConstantTextField;
043    private JTextField _compareToLocalVariableTextField;
044    private JTextField _compareToRegExTextField;
045
046
047    private void enableDisableCompareTo() {
048        ReporterOperation mo = _reporterOperationComboBox.getItemAt(
049                        _reporterOperationComboBox.getSelectedIndex());
050        boolean enable = mo.hasExtraValue();
051        _tabbedPaneCompareTo.setEnabled(enable);
052        ((JPanel)_tabbedPaneCompareTo.getSelectedComponent())
053                .getComponent(0).setEnabled(enable);
054
055        boolean regEx = (mo == ReporterOperation.MatchRegex)
056                || (mo == ReporterOperation.NotMatchRegex);
057        _tabbedPane.setEnabledAt(0, !regEx);
058        _tabbedPane.setEnabledAt(1, regEx);
059        _tabbedPane.setSelectedIndex(regEx ? 1 : 0);
060    }
061
062    @Override
063    protected void createPanel(@CheckForNull Base object, @Nonnull JPanel buttonPanel) {
064        ExpressionReporter expression = (ExpressionReporter)object;
065
066        panel = new JPanel();
067
068        _reporterBeanPanel = new BeanSelectPanel<>(InstanceManager.getDefault(ReporterManager.class), null);
069
070        _reporterValuePanel = new JPanel();
071        _reporterValueComboBox = new JComboBox<>();
072        for (ReporterValue e : ReporterValue.values()) {
073            _reporterValueComboBox.addItem(e);
074        }
075        JComboBoxUtil.setupComboBoxMaxRows(_reporterValueComboBox);
076        _reporterValuePanel.add(_reporterValueComboBox);
077
078        JPanel operationAndCasePanel = new JPanel();
079        operationAndCasePanel.setLayout(new BoxLayout(operationAndCasePanel, BoxLayout.Y_AXIS));
080
081        _reporterOperationComboBox = new JComboBox<>();
082        for (ReporterOperation e : ReporterOperation.values()) {
083            _reporterOperationComboBox.addItem(e);
084        }
085        JComboBoxUtil.setupComboBoxMaxRows(_reporterOperationComboBox);
086        if (expression == null) {
087            _reporterOperationComboBox.setSelectedItem(ReporterOperation.Equal);
088        }
089        operationAndCasePanel.add(_reporterOperationComboBox);
090
091        _reporterOperationComboBox.addActionListener((e) -> { enableDisableCompareTo(); });
092
093        _caseInsensitiveCheckBox = new JCheckBox(Bundle.getMessage("ExpressionReporter_CaseInsensitive"));
094        operationAndCasePanel.add(_caseInsensitiveCheckBox);
095
096        _tabbedPane = new JTabbedPane();
097
098        _tabbedPaneCompareTo = new JTabbedPane();
099        _tabbedPane.addTab("", _tabbedPaneCompareTo);
100
101        _compareToConstant = new JPanel();
102        _compareToMemory = new JPanel();
103        _compareToLocalVariable = new JPanel();
104        _compareToRegEx = new JPanel();
105
106        _tabbedPaneCompareTo.addTab(CompareTo.Value.toString(), _compareToConstant);
107        _tabbedPaneCompareTo.addTab(CompareTo.Memory.toString(), _compareToMemory);
108        _tabbedPaneCompareTo.addTab(CompareTo.LocalVariable.toString(), _compareToLocalVariable);
109
110        _tabbedPane.addTab(CompareTo.RegEx.toString(), _compareToRegEx);
111
112        _compareToConstantTextField = new JTextField(30);
113        _compareToConstant.add(_compareToConstantTextField);
114
115        _compareToMemoryBeanPanel = new BeanSelectPanel<>(InstanceManager.getDefault(MemoryManager.class), null);
116        _compareToMemory.add(_compareToMemoryBeanPanel);
117
118        _compareToLocalVariableTextField = new JTextField(30);
119        _compareToLocalVariable.add(_compareToLocalVariableTextField);
120
121        _compareToRegExTextField = new JTextField(30);
122        _compareToRegEx.add(_compareToRegExTextField);
123
124
125        if (expression != null) {
126            if (expression.getSelectNamedBean().getNamedBean() != null) {
127                _reporterBeanPanel.setDefaultNamedBean(expression.getSelectNamedBean().getNamedBean().getBean());
128            }
129            if (expression.getSelectMemoryNamedBean().getNamedBean() != null) {
130                _compareToMemoryBeanPanel.setDefaultNamedBean(expression.getSelectMemoryNamedBean().getNamedBean().getBean());
131            }
132            switch (expression.getCompareTo()) {
133                case RegEx:
134                case Value: _tabbedPaneCompareTo.setSelectedComponent(_compareToConstant); break;
135                case Memory: _tabbedPaneCompareTo.setSelectedComponent(_compareToMemory); break;
136                case LocalVariable: _tabbedPaneCompareTo.setSelectedComponent(_compareToLocalVariable); break;
137                default: throw new IllegalArgumentException("invalid _addressing state: " + expression.getCompareTo().name());
138            }
139            _reporterValueComboBox.setSelectedItem(expression.getReporterValue());
140            _reporterOperationComboBox.setSelectedItem(expression.getReporterOperation());
141            _caseInsensitiveCheckBox.setSelected(expression.getCaseInsensitive());
142            _compareToConstantTextField.setText(expression.getConstantValue());
143            _compareToLocalVariableTextField.setText(expression.getLocalVariable());
144            _compareToRegExTextField.setText(expression.getRegEx());
145        }
146
147        JComponent[] components = new JComponent[]{
148            _reporterBeanPanel,
149            _reporterValuePanel,
150            operationAndCasePanel,
151            _tabbedPane
152        };
153
154        List<JComponent> componentList = SwingConfiguratorInterface.parseMessage(
155                Bundle.getMessage("ExpressionReporter_Components"), components);
156
157        for (JComponent c : componentList) panel.add(c);
158
159        enableDisableCompareTo();
160    }
161
162    /** {@inheritDoc} */
163    @Override
164    public boolean validate(@Nonnull List<String> errorMessages) {
165        if (_reporterBeanPanel.getNamedBean() == null) {
166            errorMessages.add(Bundle.getMessage("Reporter_No_Reporter"));
167        }
168        return errorMessages.isEmpty();
169    }
170
171    /** {@inheritDoc} */
172    @Override
173    public MaleSocket createNewObject(@Nonnull String systemName, @CheckForNull String userName) {
174        ExpressionReporter expression = new ExpressionReporter(systemName, userName);
175        updateObject(expression);
176        return InstanceManager.getDefault(DigitalExpressionManager.class).registerExpression(expression);
177    }
178
179    /** {@inheritDoc} */
180    @Override
181    public void updateObject(@Nonnull Base object) {
182        if (! (object instanceof ExpressionReporter)) {
183            throw new IllegalArgumentException("object must be an ExpressionReporter but is a: "+object.getClass().getName());
184        }
185        ExpressionReporter expression = (ExpressionReporter)object;
186        Reporter reporter = _reporterBeanPanel.getNamedBean();
187
188        if (reporter != null) {
189            NamedBeanHandle<Reporter> handle
190                    = InstanceManager.getDefault(NamedBeanHandleManager.class)
191                            .getNamedBeanHandle(reporter.getDisplayName(), reporter);
192            expression.getSelectNamedBean().setNamedBean(handle);
193        } else {
194            expression.getSelectNamedBean().removeNamedBean();
195        }
196
197        expression.setReporterValue(_reporterValueComboBox.getItemAt(_reporterValueComboBox.getSelectedIndex()));
198        expression.setReporterOperation(_reporterOperationComboBox.getItemAt(_reporterOperationComboBox.getSelectedIndex()));
199        expression.setCaseInsensitive(_caseInsensitiveCheckBox.isSelected());
200
201
202        if (!_compareToMemoryBeanPanel.isEmpty()
203                && (_tabbedPane.getSelectedComponent() == _tabbedPaneCompareTo)
204                && (_tabbedPaneCompareTo.getSelectedComponent() == _compareToMemory)) {
205            Memory memory = _compareToMemoryBeanPanel.getNamedBean();
206            if (memory != null) {
207                NamedBeanHandle<Memory> handle
208                        = InstanceManager.getDefault(NamedBeanHandleManager.class)
209                                .getNamedBeanHandle(memory.getDisplayName(), memory);
210                expression.getSelectMemoryNamedBean().setNamedBean(handle);
211            } else {
212                expression.getSelectMemoryNamedBean().removeNamedBean();
213            }
214        } else {
215            expression.getSelectMemoryNamedBean().removeNamedBean();
216        }
217
218        if (_tabbedPane.getSelectedComponent() == _tabbedPaneCompareTo) {
219            if (_tabbedPaneCompareTo.getSelectedComponent() == _compareToConstant) {
220                expression.setCompareTo(CompareTo.Value);
221                expression.setConstantValue(_compareToConstantTextField.getText());
222            } else if (_tabbedPaneCompareTo.getSelectedComponent() == _compareToMemory) {
223                expression.setCompareTo(CompareTo.Memory);
224            } else if (_tabbedPaneCompareTo.getSelectedComponent() == _compareToLocalVariable) {
225                expression.setCompareTo(CompareTo.LocalVariable);
226                expression.setLocalVariable(_compareToLocalVariableTextField.getText());
227//            } else if (_tabbedPaneCompareTo.getSelectedComponent() == _compareToRegEx) {
228//                expression.setCompareTo(CompareTo.RegEx);
229//                expression.setRegEx(_compareToRegExTextField.getText());
230            } else {
231                throw new IllegalArgumentException("_tabbedPaneLight has unknown selection");
232            }
233        } else {
234            expression.setCompareTo(CompareTo.RegEx);
235            expression.setRegEx(_compareToRegExTextField.getText());
236        }
237    }
238
239    /** {@inheritDoc} */
240    @Override
241    public String toString() {
242        return Bundle.getMessage("Reporter_Short");
243    }
244
245    @Override
246    public void setDefaultValues() {
247        if (_reporterBeanPanel.getNamedBean() == null) {
248            SortedSet<Reporter> set = InstanceManager.getDefault(ReporterManager.class).getNamedBeanSet();
249            if (!set.isEmpty()) {
250                Reporter r = set.first();
251                _reporterBeanPanel.setDefaultNamedBean(r);
252            } else {
253                log.error("Reporter manager has no reporters. Can't set default values");
254            }
255        }
256    }
257
258    @Override
259    public void dispose() {
260    }
261
262
263    private final static org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(ExpressionReporterSwing.class);
264
265}