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.InstanceManager;
010import jmri.jmrit.logixng.*;
011import jmri.jmrit.logixng.expressions.Timer;
012import jmri.jmrit.logixng.swing.SwingConfiguratorInterface;
013import jmri.jmrit.logixng.util.TimerUnit;
014import jmri.jmrit.logixng.util.parser.ParserException;
015import jmri.util.swing.JComboBoxUtil;
016
017/**
018 * Configures an Timer object with a Swing JPanel.
019 *
020 * @author Daniel Bergqvist Copyright (C) 2021
021 */
022public class TimerSwing extends AbstractDigitalExpressionSwing {
023
024    private final JLabel _unitLabel = new JLabel(Bundle.getMessage("TimerSwing_Unit"));
025    private JComboBox<TimerUnit> _unitComboBox;
026
027    private JTabbedPane _tabbedPaneDelay;
028    private JFormattedTextField _timerDelay;
029    private JPanel _panelDelayDirect;
030    private JPanel _panelDelayReference;
031    private JPanel _panelDelayLocalVariable;
032    private JPanel _panelDelayFormula;
033    private JTextField _delayReferenceTextField;
034    private JTextField _delayLocalVariableTextField;
035    private JTextField _delayFormulaTextField;
036
037    @Override
038    protected void createPanel(@CheckForNull Base object, @Nonnull JPanel buttonPanel) {
039        if ((object != null) && !(object instanceof Timer)) {
040            throw new IllegalArgumentException("object must be an Timer but is a: "+object.getClass().getName());
041        }
042
043        Timer action = (Timer)object;
044
045        panel = new JPanel();
046        panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
047
048        _tabbedPaneDelay = new JTabbedPane();
049        _panelDelayDirect = new javax.swing.JPanel();
050        _panelDelayReference = new javax.swing.JPanel();
051        _panelDelayLocalVariable = new javax.swing.JPanel();
052        _panelDelayFormula = new javax.swing.JPanel();
053
054        _tabbedPaneDelay.addTab(NamedBeanAddressing.Direct.toString(), _panelDelayDirect);
055        _tabbedPaneDelay.addTab(NamedBeanAddressing.Reference.toString(), _panelDelayReference);
056        _tabbedPaneDelay.addTab(NamedBeanAddressing.LocalVariable.toString(), _panelDelayLocalVariable);
057        _tabbedPaneDelay.addTab(NamedBeanAddressing.Formula.toString(), _panelDelayFormula);
058
059        _timerDelay = new JFormattedTextField("0");
060        _timerDelay.setColumns(7);
061
062        _panelDelayDirect.add(_timerDelay);
063
064        _delayReferenceTextField = new JTextField();
065        _delayReferenceTextField.setColumns(30);
066        _panelDelayReference.add(_delayReferenceTextField);
067
068        _delayLocalVariableTextField = new JTextField();
069        _delayLocalVariableTextField.setColumns(30);
070        _panelDelayLocalVariable.add(_delayLocalVariableTextField);
071
072        _delayFormulaTextField = new JTextField();
073        _delayFormulaTextField.setColumns(30);
074        _panelDelayFormula.add(_delayFormulaTextField);
075
076
077        if (action != null) {
078            switch (action.getDelayAddressing()) {
079                case Direct: _tabbedPaneDelay.setSelectedComponent(_panelDelayDirect); break;
080                case Reference: _tabbedPaneDelay.setSelectedComponent(_panelDelayReference); break;
081                case LocalVariable: _tabbedPaneDelay.setSelectedComponent(_panelDelayLocalVariable); break;
082                case Formula: _tabbedPaneDelay.setSelectedComponent(_panelDelayFormula); break;
083                default: throw new IllegalArgumentException("invalid _addressing state: " + action.getDelayAddressing().name());
084            }
085            _timerDelay.setText(Integer.toString(action.getDelay()));
086            _delayReferenceTextField.setText(action.getDelayReference());
087            _delayLocalVariableTextField.setText(action.getDelayLocalVariable());
088            _delayFormulaTextField.setText(action.getDelayFormula());
089        }
090
091        JComponent[] components = new JComponent[]{
092            _tabbedPaneDelay};
093
094        List<JComponent> componentList = SwingConfiguratorInterface.parseMessage(
095                Bundle.getMessage("Timer_Components"), components);
096
097        JPanel delayPanel = new JPanel();
098        for (JComponent c : componentList) delayPanel.add(c);
099
100        panel.add(delayPanel);
101
102
103        JPanel unitPanel = new JPanel();
104        unitPanel.add(_unitLabel);
105
106        _unitComboBox = new JComboBox<>();
107        for (TimerUnit u : TimerUnit.values()) _unitComboBox.addItem(u);
108        JComboBoxUtil.setupComboBoxMaxRows(_unitComboBox);
109        if (action != null) _unitComboBox.setSelectedItem(action.getUnit());
110        unitPanel.add(_unitComboBox);
111
112        panel.add(unitPanel);
113    }
114
115    /** {@inheritDoc} */
116    @Override
117    public boolean validate(@Nonnull List<String> errorMessages) {
118        // Create a temporary action to test formula
119        Timer action = new Timer("IQDE1", null);
120
121        try {
122            if (_tabbedPaneDelay.getSelectedComponent() == _panelDelayReference) {
123                action.setDelayReference(_delayReferenceTextField.getText());
124            }
125        } catch (IllegalArgumentException e) {
126            errorMessages.add(e.getMessage());
127            return false;
128        }
129
130        try {
131            action.setDelayFormula(_delayFormulaTextField.getText());
132            if (_tabbedPaneDelay.getSelectedComponent() == _panelDelayDirect) {
133                action.setDelayAddressing(NamedBeanAddressing.Direct);
134            } else if (_tabbedPaneDelay.getSelectedComponent() == _panelDelayReference) {
135                action.setDelayAddressing(NamedBeanAddressing.Reference);
136            } else if (_tabbedPaneDelay.getSelectedComponent() == _panelDelayLocalVariable) {
137                action.setDelayAddressing(NamedBeanAddressing.LocalVariable);
138            } else if (_tabbedPaneDelay.getSelectedComponent() == _panelDelayFormula) {
139                action.setDelayAddressing(NamedBeanAddressing.Formula);
140            } else {
141                throw new IllegalArgumentException("_tabbedPane has unknown selection");
142            }
143        } catch (ParserException e) {
144            errorMessages.add("Cannot parse formula: " + e.getMessage());
145            return false;
146        }
147        return true;
148    }
149
150    /** {@inheritDoc} */
151    @Override
152    public MaleSocket createNewObject(@Nonnull String systemName, @CheckForNull String userName) {
153        Timer expression = new Timer(systemName, userName);
154        updateObject(expression);
155        return InstanceManager.getDefault(DigitalExpressionManager.class).registerExpression(expression);
156    }
157
158    /** {@inheritDoc} */
159    @Override
160    public void updateObject(@Nonnull Base object) {
161        if (!(object instanceof Timer)) {
162            throw new IllegalArgumentException("object must be an Timer but is a: "+object.getClass().getName());
163        }
164
165        Timer action = (Timer)object;
166
167        action.setUnit(_unitComboBox.getItemAt(_unitComboBox.getSelectedIndex()));
168
169        try {
170            if (_tabbedPaneDelay.getSelectedComponent() == _panelDelayDirect) {
171                action.setDelayAddressing(NamedBeanAddressing.Direct);
172                action.setDelay(Integer.parseInt(_timerDelay.getText()));
173            } else if (_tabbedPaneDelay.getSelectedComponent() == _panelDelayReference) {
174                action.setDelayAddressing(NamedBeanAddressing.Reference);
175                action.setDelayReference(_delayReferenceTextField.getText());
176            } else if (_tabbedPaneDelay.getSelectedComponent() == _panelDelayLocalVariable) {
177                action.setDelayAddressing(NamedBeanAddressing.LocalVariable);
178                action.setDelayLocalVariable(_delayLocalVariableTextField.getText());
179            } else if (_tabbedPaneDelay.getSelectedComponent() == _panelDelayFormula) {
180                action.setDelayAddressing(NamedBeanAddressing.Formula);
181                action.setDelayFormula(_delayFormulaTextField.getText());
182            } else {
183                throw new IllegalArgumentException("_tabbedPaneDelay has unknown selection");
184            }
185        } catch (ParserException e) {
186            throw new RuntimeException("ParserException: "+e.getMessage(), e);
187        }
188    }
189
190    /** {@inheritDoc} */
191    @Override
192    public String toString() {
193        return Bundle.getMessage("Timer_Short");
194    }
195
196    @Override
197    public void dispose() {
198    }
199
200}