001package jmri.jmrit.logixng.expressions.swing;
002
003import java.awt.Component;
004import java.util.List;
005
006import javax.annotation.CheckForNull;
007import javax.annotation.Nonnull;
008import javax.swing.*;
009
010import jmri.*;
011import jmri.jmrit.entryexit.DestinationPoints;
012import jmri.jmrit.entryexit.EntryExitPairs;
013import jmri.jmrit.logixng.*;
014import jmri.jmrit.logixng.expressions.ExpressionEntryExit;
015import jmri.jmrit.logixng.expressions.ExpressionEntryExit.EntryExitState;
016import jmri.jmrit.logixng.swing.SwingConfiguratorInterface;
017import jmri.jmrit.logixng.util.parser.ParserException;
018import jmri.jmrit.logixng.util.swing.LogixNG_SelectNamedBeanSwing;
019import jmri.util.swing.JComboBoxUtil;
020
021/**
022 * Configures an ExpressionEntryExit object with a Swing JPanel.
023 *
024 * @author Daniel Bergqvist Copyright 2021
025 */
026public class ExpressionEntryExitSwing extends AbstractDigitalExpressionSwing {
027
028    private LogixNG_SelectNamedBeanSwing<DestinationPoints> _selectNamedBeanSwing;
029
030    private JComboBox<Is_IsNot_Enum> _is_IsNot_ComboBox;
031
032    private JTabbedPane _tabbedPaneEntryExitState;
033    private JComboBox<EntryExitState> _stateComboBox;
034    private JPanel _panelEntryExitStateDirect;
035    private JPanel _panelEntryExitStateReference;
036    private JPanel _panelEntryExitStateLocalVariable;
037    private JPanel _panelEntryExitStateFormula;
038    private JTextField _entryExitStateReferenceTextField;
039    private JTextField _entryExitStateLocalVariableTextField;
040    private JTextField _entryExitStateFormulaTextField;
041
042
043    @Override
044    protected void createPanel(@CheckForNull Base object, @Nonnull JPanel buttonPanel) {
045        ExpressionEntryExit expression = (ExpressionEntryExit)object;
046
047        panel = new JPanel();
048
049        _selectNamedBeanSwing = new LogixNG_SelectNamedBeanSwing<>(
050                InstanceManager.getDefault(EntryExitPairs.class), getJDialog(), this);
051
052        JPanel _tabbedPaneNamedBean;
053        if (expression != null) {
054            _tabbedPaneNamedBean = _selectNamedBeanSwing.createPanel(expression.getSelectNamedBean());
055        } else {
056            _tabbedPaneNamedBean = _selectNamedBeanSwing.createPanel(null);
057        }
058
059
060        _is_IsNot_ComboBox = new JComboBox<>();
061        for (Is_IsNot_Enum e : Is_IsNot_Enum.values()) {
062            _is_IsNot_ComboBox.addItem(e);
063        }
064        JComboBoxUtil.setupComboBoxMaxRows(_is_IsNot_ComboBox);
065
066
067        _tabbedPaneEntryExitState = new JTabbedPane();
068        _panelEntryExitStateDirect = new javax.swing.JPanel();
069        _panelEntryExitStateReference = new javax.swing.JPanel();
070        _panelEntryExitStateLocalVariable = new javax.swing.JPanel();
071        _panelEntryExitStateFormula = new javax.swing.JPanel();
072
073        _tabbedPaneEntryExitState.addTab(NamedBeanAddressing.Direct.toString(), _panelEntryExitStateDirect);
074        _tabbedPaneEntryExitState.addTab(NamedBeanAddressing.Reference.toString(), _panelEntryExitStateReference);
075        _tabbedPaneEntryExitState.addTab(NamedBeanAddressing.LocalVariable.toString(), _panelEntryExitStateLocalVariable);
076        _tabbedPaneEntryExitState.addTab(NamedBeanAddressing.Formula.toString(), _panelEntryExitStateFormula);
077
078        _stateComboBox = new JComboBox<>();
079        for (EntryExitState e : EntryExitState.values()) {
080            _stateComboBox.addItem(e);
081        }
082        JComboBoxUtil.setupComboBoxMaxRows(_stateComboBox);
083
084        _stateComboBox.setRenderer(new ComboBoxRenderer<>(_stateComboBox.getRenderer()));
085
086        _panelEntryExitStateDirect.add(_stateComboBox);
087
088        _entryExitStateReferenceTextField = new JTextField();
089        _entryExitStateReferenceTextField.setColumns(30);
090        _panelEntryExitStateReference.add(_entryExitStateReferenceTextField);
091
092        _entryExitStateLocalVariableTextField = new JTextField();
093        _entryExitStateLocalVariableTextField.setColumns(30);
094        _panelEntryExitStateLocalVariable.add(_entryExitStateLocalVariableTextField);
095
096        _entryExitStateFormulaTextField = new JTextField();
097        _entryExitStateFormulaTextField.setColumns(30);
098        _panelEntryExitStateFormula.add(_entryExitStateFormulaTextField);
099
100
101        if (expression != null) {
102            _is_IsNot_ComboBox.setSelectedItem(expression.get_Is_IsNot());
103
104            switch (expression.getStateAddressing()) {
105                case Direct: _tabbedPaneEntryExitState.setSelectedComponent(_panelEntryExitStateDirect); break;
106                case Reference: _tabbedPaneEntryExitState.setSelectedComponent(_panelEntryExitStateReference); break;
107                case LocalVariable: _tabbedPaneEntryExitState.setSelectedComponent(_panelEntryExitStateLocalVariable); break;
108                case Formula: _tabbedPaneEntryExitState.setSelectedComponent(_panelEntryExitStateFormula); break;
109                default: throw new IllegalArgumentException("invalid _addressing state: " + expression.getStateAddressing().name());
110            }
111            _stateComboBox.setSelectedItem(expression.getBeanState());
112            _entryExitStateReferenceTextField.setText(expression.getStateReference());
113            _entryExitStateLocalVariableTextField.setText(expression.getStateLocalVariable());
114            _entryExitStateFormulaTextField.setText(expression.getStateFormula());
115        }
116
117        JComponent[] components = new JComponent[]{
118            _tabbedPaneNamedBean,
119            _is_IsNot_ComboBox,
120            _tabbedPaneEntryExitState};
121
122        List<JComponent> componentList = SwingConfiguratorInterface.parseMessage(
123                Bundle.getMessage("ExpressionEntryExit_Components"), components);
124
125        for (JComponent c : componentList) panel.add(c);
126    }
127
128    /** {@inheritDoc} */
129    @Override
130    public boolean validate(@Nonnull List<String> errorMessages) {
131        // Create a temporary expression to test formula
132        ExpressionEntryExit expression = new ExpressionEntryExit("IQDE1", null);
133
134        _selectNamedBeanSwing.validate(expression.getSelectNamedBean(), errorMessages);
135
136        try {
137            if (_tabbedPaneEntryExitState.getSelectedComponent() == _panelEntryExitStateReference) {
138                expression.setStateReference(_entryExitStateReferenceTextField.getText());
139            }
140        } catch (IllegalArgumentException e) {
141            errorMessages.add(e.getMessage());
142        }
143
144        return errorMessages.isEmpty();
145    }
146
147    /** {@inheritDoc} */
148    @Override
149    public String getAutoSystemName() {
150        return InstanceManager.getDefault(DigitalExpressionManager.class).getAutoSystemName();
151    }
152
153    /** {@inheritDoc} */
154    @Override
155    public MaleSocket createNewObject(@Nonnull String systemName, @CheckForNull String userName) {
156        ExpressionEntryExit expression = new ExpressionEntryExit(systemName, userName);
157        updateObject(expression);
158        return InstanceManager.getDefault(DigitalExpressionManager.class).registerExpression(expression);
159    }
160
161    /** {@inheritDoc} */
162    @Override
163    public void updateObject(@Nonnull Base object) {
164        if (! (object instanceof ExpressionEntryExit)) {
165            throw new IllegalArgumentException("object must be an ExpressionEntryExit but is a: "+object.getClass().getName());
166        }
167        ExpressionEntryExit expression = (ExpressionEntryExit)object;
168
169        _selectNamedBeanSwing.updateObject(expression.getSelectNamedBean());
170
171        try {
172            expression.set_Is_IsNot((Is_IsNot_Enum)_is_IsNot_ComboBox.getSelectedItem());
173
174            if (_tabbedPaneEntryExitState.getSelectedComponent() == _panelEntryExitStateDirect) {
175                expression.setStateAddressing(NamedBeanAddressing.Direct);
176                expression.setBeanState((EntryExitState)_stateComboBox.getSelectedItem());
177            } else if (_tabbedPaneEntryExitState.getSelectedComponent() == _panelEntryExitStateReference) {
178                expression.setStateAddressing(NamedBeanAddressing.Reference);
179                expression.setStateReference(_entryExitStateReferenceTextField.getText());
180            } else if (_tabbedPaneEntryExitState.getSelectedComponent() == _panelEntryExitStateLocalVariable) {
181                expression.setStateAddressing(NamedBeanAddressing.LocalVariable);
182                expression.setStateLocalVariable(_entryExitStateLocalVariableTextField.getText());
183            } else if (_tabbedPaneEntryExitState.getSelectedComponent() == _panelEntryExitStateFormula) {
184                expression.setStateAddressing(NamedBeanAddressing.Formula);
185                expression.setStateFormula(_entryExitStateFormulaTextField.getText());
186            } else {
187                throw new IllegalArgumentException("_tabbedPaneEntryExitState has unknown selection");
188            }
189        } catch (ParserException e) {
190            throw new RuntimeException("ParserException: "+e.getMessage(), e);
191        }
192    }
193
194    /** {@inheritDoc} */
195    @Override
196    public String toString() {
197        return Bundle.getMessage("EntryExit_Short");
198    }
199
200    @Override
201    public void dispose() {
202    }
203
204
205    private static class ComboBoxRenderer<E> extends JLabel implements ListCellRenderer<E> {
206
207        private final JSeparator _separator = new JSeparator(JSeparator.HORIZONTAL);
208        private final ListCellRenderer<E> _old;
209
210        private ComboBoxRenderer(ListCellRenderer<E> old) {
211            this._old = old;
212        }
213
214        @Override
215        public Component getListCellRendererComponent(JList<? extends E> list,
216                E value, int index, boolean isSelected, boolean cellHasFocus) {
217            if (Base.SEPARATOR.equals(value.toString())) {
218                return _separator;
219            } else {
220                return _old.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
221            }
222        }
223    }
224
225//    private final static org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(ExpressionEntryExitSwing.class);
226
227}