001package jmri.jmrit.logixng.actions.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.actions.ForEach;
012import jmri.jmrit.logixng.actions.CommonManager;
013import jmri.jmrit.logixng.actions.ForEach.UserSpecifiedSource;
014import jmri.jmrit.logixng.util.parser.ParserException;
015import jmri.jmrit.logixng.util.swing.LogixNG_SelectNamedBeanSwing;
016import jmri.jmrit.logixng.util.swing.LogixNG_SelectStringSwing;
017import jmri.util.swing.JComboBoxUtil;
018
019/**
020 * Configures an ForEach object with a Swing JPanel.
021 *
022 * @author Daniel Bergqvist Copyright 2021
023 */
024public class ForEachSwing extends AbstractDigitalActionSwing {
025
026    private LogixNG_SelectStringSwing _selectVariableSwing;
027    private LogixNG_SelectNamedBeanSwing<Memory> _selectMemorySwing;
028
029    private JTabbedPane _commonOrUserSpecifiedPane;
030    private JPanel _commonPanel;
031    private JComboBox<CommonManager> _commonManagersComboBox;
032
033    private JTabbedPane _tabbedPaneUserSpecifiedSource;
034    JPanel _tabbedPaneMemoryBean;
035    JPanel _tabbedPaneVariable;
036    private JPanel _calculateFormula;
037    private JTextField _calculateFormulaTextField;
038
039    private JTextField _localVariable;
040
041    @Override
042    protected void createPanel(@CheckForNull Base object, @Nonnull JPanel buttonPanel) {
043        if ((object != null) && !(object instanceof ForEach)) {
044            throw new IllegalArgumentException("object must be an ForEach but is a: "+object.getClass().getName());
045        }
046
047        ForEach action = (ForEach)object;
048
049        _selectVariableSwing = new LogixNG_SelectStringSwing(getJDialog(), this);
050
051        _selectMemorySwing = new LogixNG_SelectNamedBeanSwing<>(
052                InstanceManager.getDefault(MemoryManager.class), getJDialog(), this);
053
054        panel = new JPanel();
055        panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
056
057        if (action != null) {
058            _tabbedPaneMemoryBean = _selectMemorySwing.createPanel(action.getSelectMemoryNamedBean());
059            _tabbedPaneVariable = _selectVariableSwing.createPanel(action.getSelectVariable());
060        } else {
061            _tabbedPaneMemoryBean = _selectMemorySwing.createPanel(null);
062            _tabbedPaneVariable = _selectVariableSwing.createPanel(null);
063        }
064
065        _commonOrUserSpecifiedPane = new JTabbedPane();
066
067        _commonPanel = new JPanel();
068        _commonOrUserSpecifiedPane.addTab(Bundle.getMessage("ForEachSwing_Common"), _commonPanel);
069        _commonManagersComboBox = new JComboBox<>();
070        for (CommonManager commonManager : CommonManager.values()) {
071            _commonManagersComboBox.addItem(commonManager);
072        }
073        JComboBoxUtil.setupComboBoxMaxRows(_commonManagersComboBox);
074
075        _commonPanel.add(_commonManagersComboBox);
076
077
078        _tabbedPaneUserSpecifiedSource = new JTabbedPane();
079        _commonOrUserSpecifiedPane.addTab(Bundle.getMessage("ForEachSwing_UserSpecified"), _tabbedPaneUserSpecifiedSource);
080
081        _calculateFormula = new JPanel();
082
083        _tabbedPaneUserSpecifiedSource.addTab(UserSpecifiedSource.Memory.toString(), _tabbedPaneMemoryBean);
084        _tabbedPaneUserSpecifiedSource.addTab(UserSpecifiedSource.Variable.toString(), _tabbedPaneVariable);
085        _tabbedPaneUserSpecifiedSource.addTab(UserSpecifiedSource.Formula.toString(), _calculateFormula);
086
087        _calculateFormulaTextField = new JTextField(30);
088        _calculateFormula.add(_calculateFormulaTextField);
089
090        JPanel localVariablePanel = new JPanel();
091        localVariablePanel.add(new JLabel(Bundle.getMessage("ForEachSwing_LocalVariable")));
092        _localVariable = new JTextField(20);
093        localVariablePanel.add(_localVariable);
094        panel.add(localVariablePanel);
095
096
097        if (action != null) {
098            if (!action.isUseCommonSource()) {
099                _commonOrUserSpecifiedPane.setSelectedComponent(_tabbedPaneUserSpecifiedSource);
100            }
101            _commonManagersComboBox.setSelectedItem(action.getCommonManager());
102
103            switch (action.getUserSpecifiedSource()) {
104                case Memory: _tabbedPaneUserSpecifiedSource.setSelectedComponent(_tabbedPaneMemoryBean); break;
105                case Variable: _tabbedPaneUserSpecifiedSource.setSelectedComponent(_tabbedPaneVariable); break;
106                case Formula: _tabbedPaneUserSpecifiedSource.setSelectedComponent(_calculateFormula); break;
107                default: throw new IllegalArgumentException("invalid _addressing state: " + action.getUserSpecifiedSource().name());
108            }
109            _calculateFormulaTextField.setText(action.getFormula());
110
111            _localVariable.setText(action.getLocalVariableName());
112        }
113
114
115        panel.add(_commonOrUserSpecifiedPane);
116        panel.add(localVariablePanel);
117    }
118
119    /** {@inheritDoc} */
120    @Override
121    public boolean validate(@Nonnull List<String> errorMessages) {
122        // Create a temporary action to test formula
123        ForEach action = new ForEach("IQDA1", null);
124
125        if (_commonOrUserSpecifiedPane.getSelectedComponent() == _tabbedPaneUserSpecifiedSource) {
126            // If using the Memory tab, validate the memory variable selection.
127            if (_tabbedPaneUserSpecifiedSource.getSelectedComponent() == _tabbedPaneMemoryBean) {
128                _selectMemorySwing.validate(action.getSelectMemoryNamedBean(), errorMessages);
129            }
130
131            // If using the Variable tab, validate the memory variable selection.
132            if (_tabbedPaneUserSpecifiedSource.getSelectedComponent() == _tabbedPaneVariable) {
133                _selectVariableSwing.validate(action.getSelectVariable(), errorMessages);
134            }
135
136            if (_tabbedPaneUserSpecifiedSource.getSelectedComponent() == _calculateFormula) {
137                try {
138                    action.setUserSpecifiedSource(UserSpecifiedSource.Formula);
139                    action.setFormula(_calculateFormulaTextField.getText());
140                } catch (ParserException e) {
141                    errorMessages.add(e.getMessage());
142                }
143            }
144        }
145
146        return errorMessages.isEmpty();
147    }
148
149    /** {@inheritDoc} */
150    @Override
151    public MaleSocket createNewObject(@Nonnull String systemName, @CheckForNull String userName) {
152        ForEach action = new ForEach(systemName, userName);
153        updateObject(action);
154        return InstanceManager.getDefault(DigitalActionManager.class).registerAction(action);
155    }
156
157    /** {@inheritDoc} */
158    @Override
159    public void updateObject(@Nonnull Base object) {
160        if (!(object instanceof ForEach)) {
161            throw new IllegalArgumentException("object must be an ForEach but is a: "+object.getClass().getName());
162        }
163
164        ForEach action = (ForEach)object;
165
166        try {
167            if (_commonOrUserSpecifiedPane.getSelectedComponent() == _commonPanel) {
168
169                action.setUseCommonSource(true);
170                action.setCommonManager(_commonManagersComboBox.getItemAt(
171                        _commonManagersComboBox.getSelectedIndex()));
172
173            } else if (_commonOrUserSpecifiedPane.getSelectedComponent() == _tabbedPaneUserSpecifiedSource) {
174
175                action.setUseCommonSource(false);
176
177                try {
178                    if (_tabbedPaneUserSpecifiedSource.getSelectedComponent() == _tabbedPaneMemoryBean) {
179                        action.setUserSpecifiedSource(UserSpecifiedSource.Memory);
180                        _selectMemorySwing.updateObject(action.getSelectMemoryNamedBean());
181                    } else if (_tabbedPaneUserSpecifiedSource.getSelectedComponent() == _tabbedPaneVariable) {
182                        action.setUserSpecifiedSource(UserSpecifiedSource.Variable);
183                        _selectVariableSwing.updateObject(action.getSelectVariable());
184                    } else if (_tabbedPaneUserSpecifiedSource.getSelectedComponent() == _calculateFormula) {
185                        action.setUserSpecifiedSource(UserSpecifiedSource.Formula);
186                        action.setFormula(_calculateFormulaTextField.getText());
187                    } else {
188                        throw new IllegalArgumentException("_tabbedPaneUserSpecifiedSource has unknown selection");
189                    }
190                } catch (ParserException e) {
191                    throw new RuntimeException("ParserException: "+e.getMessage(), e);
192                }
193
194            } else {
195                throw new IllegalArgumentException("_tabbedPaneUserSpecifiedSource has unknown selection");
196            }
197        } catch (ParserException e) {
198            throw new RuntimeException("ParserException: "+e.getMessage(), e);
199        }
200
201        action.setLocalVariableName(_localVariable.getText());
202    }
203
204    /** {@inheritDoc} */
205    @Override
206    public String toString() {
207        return Bundle.getMessage("ForEach_Short");
208    }
209
210    @Override
211    public void dispose() {
212    }
213
214//    private final static org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(ForEachSwing.class);
215
216}