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