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.InstanceManager;
010import jmri.NamedBeanHandle;
011import jmri.NamedBeanHandleManager;
012import jmri.Logix;
013import jmri.LogixManager;
014import jmri.jmrit.logixng.*;
015import jmri.jmrit.logixng.actions.EnableLogix;
016import jmri.jmrit.logixng.actions.EnableLogix.Operation;
017import jmri.jmrit.logixng.swing.SwingConfiguratorInterface;
018import jmri.jmrit.logixng.util.parser.ParserException;
019import jmri.util.swing.BeanSelectPanel;
020import jmri.util.swing.JComboBoxUtil;
021
022/**
023 * Configures an EnableLogix object with a Swing JPanel.
024 * 
025 * @author Daniel Bergqvist Copyright 2021
026 */
027public class EnableLogixSwing extends AbstractDigitalActionSwing {
028
029    private JTabbedPane _tabbedPaneLogix;
030    private BeanSelectPanel<Logix> logixBeanPanel;
031    private JPanel _panelLogixDirect;
032    private JPanel _panelLogixReference;
033    private JPanel _panelLogixLocalVariable;
034    private JPanel _panelLogixFormula;
035    private JTextField _logixReferenceTextField;
036    private JTextField _logixLocalVariableTextField;
037    private JTextField _logixFormulaTextField;
038    
039    private JTabbedPane _tabbedPaneOperation;
040    private JComboBox<Operation> _stateComboBox;
041    private JPanel _panelOperationDirect;
042    private JPanel _panelOperationReference;
043    private JPanel _panelOperationLocalVariable;
044    private JPanel _panelOperationFormula;
045    private JTextField _logixLockReferenceTextField;
046    private JTextField _logixLockLocalVariableTextField;
047    private JTextField _logixLockFormulaTextField;
048    
049    
050    @Override
051    protected void createPanel(@CheckForNull Base object, @Nonnull JPanel buttonPanel) {
052        EnableLogix action = (EnableLogix)object;
053        
054        panel = new JPanel();
055        
056        _tabbedPaneLogix = new JTabbedPane();
057        _panelLogixDirect = new javax.swing.JPanel();
058        _panelLogixReference = new javax.swing.JPanel();
059        _panelLogixLocalVariable = new javax.swing.JPanel();
060        _panelLogixFormula = new javax.swing.JPanel();
061        
062        _tabbedPaneLogix.addTab(NamedBeanAddressing.Direct.toString(), _panelLogixDirect);
063        _tabbedPaneLogix.addTab(NamedBeanAddressing.Reference.toString(), _panelLogixReference);
064        _tabbedPaneLogix.addTab(NamedBeanAddressing.LocalVariable.toString(), _panelLogixLocalVariable);
065        _tabbedPaneLogix.addTab(NamedBeanAddressing.Formula.toString(), _panelLogixFormula);
066        
067        logixBeanPanel = new BeanSelectPanel<>(InstanceManager.getDefault(LogixManager.class), null);
068        _panelLogixDirect.add(logixBeanPanel);
069        
070        _logixReferenceTextField = new JTextField();
071        _logixReferenceTextField.setColumns(30);
072        _panelLogixReference.add(_logixReferenceTextField);
073        
074        _logixLocalVariableTextField = new JTextField();
075        _logixLocalVariableTextField.setColumns(30);
076        _panelLogixLocalVariable.add(_logixLocalVariableTextField);
077        
078        _logixFormulaTextField = new JTextField();
079        _logixFormulaTextField.setColumns(30);
080        _panelLogixFormula.add(_logixFormulaTextField);
081        
082        
083        _tabbedPaneOperation = new JTabbedPane();
084        _panelOperationDirect = new javax.swing.JPanel();
085        _panelOperationReference = new javax.swing.JPanel();
086        _panelOperationLocalVariable = new javax.swing.JPanel();
087        _panelOperationFormula = new javax.swing.JPanel();
088        
089        _tabbedPaneOperation.addTab(NamedBeanAddressing.Direct.toString(), _panelOperationDirect);
090        _tabbedPaneOperation.addTab(NamedBeanAddressing.Reference.toString(), _panelOperationReference);
091        _tabbedPaneOperation.addTab(NamedBeanAddressing.LocalVariable.toString(), _panelOperationLocalVariable);
092        _tabbedPaneOperation.addTab(NamedBeanAddressing.Formula.toString(), _panelOperationFormula);
093        
094        _stateComboBox = new JComboBox<>();
095        for (Operation e : Operation.values()) {
096            _stateComboBox.addItem(e);
097        }
098        JComboBoxUtil.setupComboBoxMaxRows(_stateComboBox);
099        
100        _panelOperationDirect.add(_stateComboBox);
101        
102        _logixLockReferenceTextField = new JTextField();
103        _logixLockReferenceTextField.setColumns(30);
104        _panelOperationReference.add(_logixLockReferenceTextField);
105        
106        _logixLockLocalVariableTextField = new JTextField();
107        _logixLockLocalVariableTextField.setColumns(30);
108        _panelOperationLocalVariable.add(_logixLockLocalVariableTextField);
109        
110        _logixLockFormulaTextField = new JTextField();
111        _logixLockFormulaTextField.setColumns(30);
112        _panelOperationFormula.add(_logixLockFormulaTextField);
113        
114        
115        if (action != null) {
116            switch (action.getAddressing()) {
117                case Direct: _tabbedPaneLogix.setSelectedComponent(_panelLogixDirect); break;
118                case Reference: _tabbedPaneLogix.setSelectedComponent(_panelLogixReference); break;
119                case LocalVariable: _tabbedPaneLogix.setSelectedComponent(_panelLogixLocalVariable); break;
120                case Formula: _tabbedPaneLogix.setSelectedComponent(_panelLogixFormula); break;
121                default: throw new IllegalArgumentException("invalid _addressing state: " + action.getAddressing().name());
122            }
123            if (action.getLogix() != null) {
124                logixBeanPanel.setDefaultNamedBean(action.getLogix().getBean());
125            }
126            _logixReferenceTextField.setText(action.getReference());
127            _logixLocalVariableTextField.setText(action.getLocalVariable());
128            _logixFormulaTextField.setText(action.getFormula());
129            
130            switch (action.getOperationAddressing()) {
131                case Direct: _tabbedPaneOperation.setSelectedComponent(_panelOperationDirect); break;
132                case Reference: _tabbedPaneOperation.setSelectedComponent(_panelOperationReference); break;
133                case LocalVariable: _tabbedPaneOperation.setSelectedComponent(_panelOperationLocalVariable); break;
134                case Formula: _tabbedPaneOperation.setSelectedComponent(_panelOperationFormula); break;
135                default: throw new IllegalArgumentException("invalid _addressing state: " + action.getAddressing().name());
136            }
137            _stateComboBox.setSelectedItem(action.getOperationDirect());
138            _logixLockReferenceTextField.setText(action.getOperationReference());
139            _logixLockLocalVariableTextField.setText(action.getOperationLocalVariable());
140            _logixLockFormulaTextField.setText(action.getLockFormula());
141        }
142        
143        JComponent[] components = new JComponent[]{
144            _tabbedPaneLogix,
145            _tabbedPaneOperation};
146        
147        List<JComponent> componentList = SwingConfiguratorInterface.parseMessage(
148                Bundle.getMessage("EnableLogix_Components"), components);
149        
150        for (JComponent c : componentList) panel.add(c);
151    }
152    
153    /** {@inheritDoc} */
154    @Override
155    public boolean validate(@Nonnull List<String> errorMessages) {
156        // Create a temporary action to test formula
157        EnableLogix action = new EnableLogix("IQDA1", null);
158        
159        try {
160            if (_tabbedPaneLogix.getSelectedComponent() == _panelLogixReference) {
161                action.setReference(_logixReferenceTextField.getText());
162            }
163        } catch (IllegalArgumentException e) {
164            errorMessages.add(e.getMessage());
165            return false;
166        }
167        
168        try {
169            if (_tabbedPaneOperation.getSelectedComponent() == _panelOperationReference) {
170                action.setOperationReference(_logixLockReferenceTextField.getText());
171            }
172        } catch (IllegalArgumentException e) {
173            errorMessages.add(e.getMessage());
174            return false;
175        }
176        
177        try {
178            action.setFormula(_logixFormulaTextField.getText());
179            if (_tabbedPaneLogix.getSelectedComponent() == _panelLogixDirect) {
180                action.setAddressing(NamedBeanAddressing.Direct);
181            } else if (_tabbedPaneLogix.getSelectedComponent() == _panelLogixReference) {
182                action.setAddressing(NamedBeanAddressing.Reference);
183            } else if (_tabbedPaneLogix.getSelectedComponent() == _panelLogixLocalVariable) {
184                action.setAddressing(NamedBeanAddressing.LocalVariable);
185            } else if (_tabbedPaneLogix.getSelectedComponent() == _panelLogixFormula) {
186                action.setAddressing(NamedBeanAddressing.Formula);
187            } else {
188                throw new IllegalArgumentException("_tabbedPane has unknown selection");
189            }
190        } catch (ParserException e) {
191            errorMessages.add("Cannot parse formula: " + e.getMessage());
192        }
193        return true;
194    }
195    
196    /** {@inheritDoc} */
197    @Override
198    public MaleSocket createNewObject(@Nonnull String systemName, @CheckForNull String userName) {
199        EnableLogix action = new EnableLogix(systemName, userName);
200        updateObject(action);
201        return InstanceManager.getDefault(DigitalActionManager.class).registerAction(action);
202    }
203    
204    /** {@inheritDoc} */
205    @Override
206    public void updateObject(@Nonnull Base object) {
207        if (! (object instanceof EnableLogix)) {
208            throw new IllegalArgumentException("object must be an EnableLogix but is a: "+object.getClass().getName());
209        }
210        EnableLogix action = (EnableLogix)object;
211        if (_tabbedPaneLogix.getSelectedComponent() == _panelLogixDirect) {
212            Logix logix = logixBeanPanel.getNamedBean();
213            if (logix != null) {
214                NamedBeanHandle<Logix> handle
215                        = InstanceManager.getDefault(NamedBeanHandleManager.class)
216                                .getNamedBeanHandle(logix.getDisplayName(), logix);
217                action.setLogix(handle);
218            } else {
219                action.removeLogix();
220            }
221        } else {
222            action.removeLogix();
223        }
224        try {
225            if (_tabbedPaneLogix.getSelectedComponent() == _panelLogixDirect) {
226                action.setAddressing(NamedBeanAddressing.Direct);
227            } else if (_tabbedPaneLogix.getSelectedComponent() == _panelLogixReference) {
228                action.setAddressing(NamedBeanAddressing.Reference);
229                action.setReference(_logixReferenceTextField.getText());
230            } else if (_tabbedPaneLogix.getSelectedComponent() == _panelLogixLocalVariable) {
231                action.setAddressing(NamedBeanAddressing.LocalVariable);
232                action.setLocalVariable(_logixLocalVariableTextField.getText());
233            } else if (_tabbedPaneLogix.getSelectedComponent() == _panelLogixFormula) {
234                action.setAddressing(NamedBeanAddressing.Formula);
235                action.setFormula(_logixFormulaTextField.getText());
236            } else {
237                throw new IllegalArgumentException("_tabbedPaneLogix has unknown selection");
238            }
239            
240            if (_tabbedPaneOperation.getSelectedComponent() == _panelOperationDirect) {
241                action.setOperationAddressing(NamedBeanAddressing.Direct);
242                action.setOperationDirect(_stateComboBox.getItemAt(_stateComboBox.getSelectedIndex()));
243            } else if (_tabbedPaneOperation.getSelectedComponent() == _panelOperationReference) {
244                action.setOperationAddressing(NamedBeanAddressing.Reference);
245                action.setOperationReference(_logixLockReferenceTextField.getText());
246            } else if (_tabbedPaneOperation.getSelectedComponent() == _panelOperationLocalVariable) {
247                action.setOperationAddressing(NamedBeanAddressing.LocalVariable);
248                action.setOperationLocalVariable(_logixLockLocalVariableTextField.getText());
249            } else if (_tabbedPaneOperation.getSelectedComponent() == _panelOperationFormula) {
250                action.setOperationAddressing(NamedBeanAddressing.Formula);
251                action.setOperationFormula(_logixLockFormulaTextField.getText());
252            } else {
253                throw new IllegalArgumentException("_tabbedPaneLogix has unknown selection");
254            }
255        } catch (ParserException e) {
256            throw new RuntimeException("ParserException: "+e.getMessage(), e);
257        }
258    }
259    
260    /** {@inheritDoc} */
261    @Override
262    public String toString() {
263        return Bundle.getMessage("EnableLogix_Short");
264    }
265    
266    @Override
267    public void dispose() {
268        if (logixBeanPanel != null) {
269            logixBeanPanel.dispose();
270        }
271    }
272    
273    
274//    private final static org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(EnableLogixSwing.class);
275    
276}