001package jmri.jmrit.logixng.expressions.swing;
002
003import java.util.List;
004
005import javax.annotation.CheckForNull;
006import javax.annotation.Nonnull;
007import javax.swing.*;
008
009import jmri.*;
010import jmri.jmrit.logixng.*;
011import jmri.jmrit.logixng.expressions.ExpressionDispatcher;
012import jmri.jmrit.logixng.expressions.ExpressionDispatcher.DispatcherState;
013import jmri.jmrit.logixng.swing.SwingConfiguratorInterface;
014import jmri.jmrit.logixng.util.DispatcherActiveTrainManager;
015import jmri.jmrit.logixng.util.parser.ParserException;
016import jmri.jmrit.logixng.util.swing.LogixNG_SelectEnumSwing;
017import jmri.util.swing.JComboBoxUtil;
018
019/**
020 * Configures an ExpressionDispatcher object with a Swing JPanel.
021 *
022 * @author Daniel Bergqvist Copyright 2021
023 */
024public class ExpressionDispatcherSwing extends AbstractDigitalExpressionSwing {
025
026    private LogixNG_SelectEnumSwing<DispatcherState> _selectEnumSwing;
027
028    private JTabbedPane _tabbedPaneDispatcher;
029    private JPanel _panelDispatcherDirect;
030    private JPanel _panelDispatcherReference;
031    private JPanel _panelDispatcherLocalVariable;
032    private JPanel _panelDispatcherFormula;
033
034    private JComboBox<String> _fileNamesComboBox;
035    private JTextField _dispatcherReferenceTextField;
036    private JTextField _dispatcherLocalVariableTextField;
037    private JTextField _dispatcherFormulaTextField;
038
039    private JComboBox<Is_IsNot_Enum> _is_IsNot_ComboBox;
040
041
042    @Override
043    protected void createPanel(@CheckForNull Base object, @Nonnull JPanel buttonPanel) {
044        ExpressionDispatcher expression = (ExpressionDispatcher)object;
045
046        _selectEnumSwing = new LogixNG_SelectEnumSwing<>(getJDialog(), this);
047
048
049        JPanel _tabbedPaneEnum;
050
051        if (expression != null) {
052//            _tabbedPaneNamedBean = _selectNamedBeanSwing.createPanel(expression.getSelectNamedBean());
053            _tabbedPaneEnum = _selectEnumSwing.createPanel(expression.getSelectEnum(), DispatcherState.values());
054        } else {
055//            _tabbedPaneNamedBean = _selectNamedBeanSwing.createPanel(null);
056            _tabbedPaneEnum = _selectEnumSwing.createPanel(null, DispatcherState.values());
057        }
058
059
060
061        panel = new JPanel();
062
063        _tabbedPaneDispatcher = new JTabbedPane();
064        _panelDispatcherDirect = new javax.swing.JPanel();
065        _panelDispatcherReference = new javax.swing.JPanel();
066        _panelDispatcherLocalVariable = new javax.swing.JPanel();
067        _panelDispatcherFormula = new javax.swing.JPanel();
068
069        _tabbedPaneDispatcher.addTab(NamedBeanAddressing.Direct.toString(), _panelDispatcherDirect);
070        _tabbedPaneDispatcher.addTab(NamedBeanAddressing.Reference.toString(), _panelDispatcherReference);
071        _tabbedPaneDispatcher.addTab(NamedBeanAddressing.LocalVariable.toString(), _panelDispatcherLocalVariable);
072        _tabbedPaneDispatcher.addTab(NamedBeanAddressing.Formula.toString(), _panelDispatcherFormula);
073
074        _fileNamesComboBox = new JComboBox<>();
075        InstanceManager.getDefault(DispatcherActiveTrainManager.class).getTrainInfoFileNames().forEach(name -> {
076            _fileNamesComboBox.addItem(name);
077        });
078        JComboBoxUtil.setupComboBoxMaxRows(_fileNamesComboBox);
079        _panelDispatcherDirect.add(_fileNamesComboBox);
080
081        _dispatcherReferenceTextField = new JTextField();
082        _dispatcherReferenceTextField.setColumns(30);
083        _panelDispatcherReference.add(_dispatcherReferenceTextField);
084
085        _dispatcherLocalVariableTextField = new JTextField();
086        _dispatcherLocalVariableTextField.setColumns(30);
087        _panelDispatcherLocalVariable.add(_dispatcherLocalVariableTextField);
088
089        _dispatcherFormulaTextField = new JTextField();
090        _dispatcherFormulaTextField.setColumns(30);
091        _panelDispatcherFormula.add(_dispatcherFormulaTextField);
092
093
094        _is_IsNot_ComboBox = new JComboBox<>();
095        for (Is_IsNot_Enum e : Is_IsNot_Enum.values()) {
096            _is_IsNot_ComboBox.addItem(e);
097        }
098        JComboBoxUtil.setupComboBoxMaxRows(_is_IsNot_ComboBox);
099
100
101
102        if (expression != null) {
103            switch (expression.getAddressing()) {
104                case Direct: _tabbedPaneDispatcher.setSelectedComponent(_panelDispatcherDirect); break;
105                case Reference: _tabbedPaneDispatcher.setSelectedComponent(_panelDispatcherReference); break;
106                case LocalVariable: _tabbedPaneDispatcher.setSelectedComponent(_panelDispatcherLocalVariable); break;
107                case Formula: _tabbedPaneDispatcher.setSelectedComponent(_panelDispatcherFormula); break;
108                default: throw new IllegalArgumentException("invalid _addressing state: " + expression.getAddressing().name());
109            }
110
111            _fileNamesComboBox.setSelectedItem(expression.getTrainInfoFileName());
112            _dispatcherReferenceTextField.setText(expression.getReference());
113            _dispatcherLocalVariableTextField.setText(expression.getLocalVariable());
114            _dispatcherFormulaTextField.setText(expression.getFormula());
115
116            _is_IsNot_ComboBox.setSelectedItem(expression.get_Is_IsNot());
117        }
118
119        JComponent[] components = new JComponent[]{
120            _tabbedPaneDispatcher,
121            _is_IsNot_ComboBox,
122            _tabbedPaneEnum};
123
124        List<JComponent> componentList = SwingConfiguratorInterface.parseMessage(
125                Bundle.getMessage("ExpressionDispatcher_Components"), components);
126
127        for (JComponent c : componentList) panel.add(c);
128    }
129
130    /** {@inheritDoc} */
131    @Override
132    public boolean validate(@Nonnull List<String> errorMessages) {
133        if (_selectEnumSwing.getAddressing() == NamedBeanAddressing.Direct) {
134            DispatcherState state = _selectEnumSwing.getEnum();
135            if (state.getType().equals("Separator")) {
136                errorMessages.add(Bundle.getMessage("Dispatcher_No_Status_Selected"));
137            }
138        }
139
140        // Create a temporary expression to test formula
141        ExpressionDispatcher expression = new ExpressionDispatcher("IQDE1", null);
142
143        try {
144            if (_tabbedPaneDispatcher.getSelectedComponent() == _panelDispatcherReference) {
145                expression.setReference(_dispatcherReferenceTextField.getText());
146            }
147        } catch (IllegalArgumentException e) {
148            errorMessages.add(e.getMessage());
149            return false;
150        }
151
152        _selectEnumSwing.validate(expression.getSelectEnum(), errorMessages);
153
154        try {
155            expression.setFormula(_dispatcherFormulaTextField.getText());
156            if (_tabbedPaneDispatcher.getSelectedComponent() == _panelDispatcherDirect) {
157                expression.setAddressing(NamedBeanAddressing.Direct);
158            } else if (_tabbedPaneDispatcher.getSelectedComponent() == _panelDispatcherReference) {
159                expression.setAddressing(NamedBeanAddressing.Reference);
160            } else if (_tabbedPaneDispatcher.getSelectedComponent() == _panelDispatcherLocalVariable) {
161                expression.setAddressing(NamedBeanAddressing.LocalVariable);
162            } else if (_tabbedPaneDispatcher.getSelectedComponent() == _panelDispatcherFormula) {
163                expression.setAddressing(NamedBeanAddressing.Formula);
164            } else {
165                throw new IllegalArgumentException("_tabbedPane has unknown selection");
166            }
167        } catch (ParserException e) {
168            errorMessages.add("Cannot parse formula: " + e.getMessage());
169        }
170
171        return errorMessages.isEmpty();
172    }
173
174    /** {@inheritDoc} */
175    @Override
176    public String getAutoSystemName() {
177        return InstanceManager.getDefault(DigitalExpressionManager.class).getAutoSystemName();
178    }
179
180    /** {@inheritDoc} */
181    @Override
182    public MaleSocket createNewObject(@Nonnull String systemName, @CheckForNull String userName) {
183        ExpressionDispatcher expression = new ExpressionDispatcher(systemName, userName);
184        updateObject(expression);
185        return InstanceManager.getDefault(DigitalExpressionManager.class).registerExpression(expression);
186    }
187
188    /** {@inheritDoc} */
189    @Override
190    public void updateObject(@Nonnull Base object) {
191        if (! (object instanceof ExpressionDispatcher)) {
192            throw new IllegalArgumentException("object must be an ExpressionDispatcher but is a: " + object.getClass().getName());
193        }
194        ExpressionDispatcher expression = (ExpressionDispatcher)object;
195
196        try {
197            if (_tabbedPaneDispatcher.getSelectedComponent() == _panelDispatcherDirect) {
198                expression.setAddressing(NamedBeanAddressing.Direct);
199                expression.setTrainInfoFileName((String) _fileNamesComboBox.getSelectedItem());
200            } else if (_tabbedPaneDispatcher.getSelectedComponent() == _panelDispatcherReference) {
201                expression.setAddressing(NamedBeanAddressing.Reference);
202                expression.setReference(_dispatcherReferenceTextField.getText());
203            } else if (_tabbedPaneDispatcher.getSelectedComponent() == _panelDispatcherLocalVariable) {
204                expression.setAddressing(NamedBeanAddressing.LocalVariable);
205                expression.setLocalVariable(_dispatcherLocalVariableTextField.getText());
206            } else if (_tabbedPaneDispatcher.getSelectedComponent() == _panelDispatcherFormula) {
207                expression.setAddressing(NamedBeanAddressing.Formula);
208                expression.setFormula(_dispatcherFormulaTextField.getText());
209            } else {
210                throw new IllegalArgumentException("_tabbedPaneDispatcher has unknown selection");
211            }
212
213            expression.set_Is_IsNot((Is_IsNot_Enum)_is_IsNot_ComboBox.getSelectedItem());
214
215            _selectEnumSwing.updateObject(expression.getSelectEnum());
216        } catch (ParserException e) {
217            throw new RuntimeException("ParserException: " + e.getMessage(), e);
218        }
219    }
220
221    /** {@inheritDoc} */
222    @Override
223    public String toString() {
224        return Bundle.getMessage("Dispatcher_Short");
225    }
226
227    @Override
228    public void dispose() {
229        _selectEnumSwing.dispose();
230    }
231
232    @Override
233    public void setDefaultValues() {
234        _selectEnumSwing.setEnum(DispatcherState.Manual);
235    }
236
237//    private final static org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(ExpressionDispatcherSwing.class);
238
239}