001package jmri.jmrit.beantable.beanedit;
002
003import java.awt.event.ActionEvent;
004
005import javax.swing.*;
006
007import jmri.*;
008import jmri.NamedBean.DisplayOptions;
009import jmri.implementation.SignalSpeedMap;
010import jmri.jmrit.beantable.block.BlockCurvatureJComboBox;
011import jmri.jmrit.beantable.oblock.TableFrames;
012import jmri.jmrit.logix.OBlock;
013import jmri.jmrit.logix.OBlockManager;
014import jmri.swing.NamedBeanComboBox;
015import jmri.util.swing.JComboBoxUtil;
016
017/**
018 * Provides a tabbed beanedit panel for an OBlock object.
019 *
020 * @author Kevin Dickerson Copyright (C) 2011
021 * @author Egbert Broerse Copyright (C) 2020
022 */
023public class OBlockEditAction extends BeanEditAction<OBlock> {
024
025    static final java.util.Vector<String> speedList = new java.util.Vector<>();
026    private String tabName = Bundle.getMessage("BeanNameOBlock");
027    NamedBeanComboBox<Reporter> reporterComboBox;
028    JCheckBox useCurrent = new JCheckBox();
029    TableFrames.BlockPathJPanel blockPathPanel;
030    NamedBeanComboBox<Sensor> sensorComboBox;
031    NamedBeanComboBox<Sensor> errorSensorComboBox;
032
033    public OBlockEditAction(ActionEvent ae) {
034        super();
035        if (ae != null) {
036            tabName = ae.getActionCommand();
037        }
038    }
039
040    @Override
041    public String helpTarget() {
042        return "package.jmri.jmrit.beantable.OBlockTable";
043    } // NOI18N
044
045    public void setTablePanel(TableFrames.BlockPathJPanel panel){
046        blockPathPanel = panel;
047    }
048
049    @Override
050    protected void initPanels() {
051        super.initPanels();
052        sensor();
053        paths();
054        physicalDetails();
055    }
056
057    @Override
058    public OBlock getByUserName(String name) {
059        return InstanceManager.getDefault(OBlockManager.class).getByUserName(name);
060    }
061
062    BeanItemPanel sensor() {
063        BeanItemPanel basic = new BeanItemPanel();
064        basic.setName(Bundle.getMessage("BeanNameSensors"));
065
066        sensorComboBox = new NamedBeanComboBox<>(InstanceManager.sensorManagerInstance(), bean.getSensor(), DisplayOptions.DISPLAYNAME);
067        sensorComboBox.setAllowNull(true);
068        JComboBoxUtil.setupComboBoxMaxRows(sensorComboBox);
069        basic.addItem(new BeanEditItem(sensorComboBox, Bundle.getMessage("BeanNameSensor"), Bundle.getMessage("OBlockAssignSensorText")));
070
071        errorSensorComboBox = new NamedBeanComboBox<>(InstanceManager.sensorManagerInstance(), bean.getErrorSensor(), DisplayOptions.DISPLAYNAME);
072        errorSensorComboBox.setAllowNull(true);
073        JComboBoxUtil.setupComboBoxMaxRows(errorSensorComboBox);
074        basic.addItem(new BeanEditItem(errorSensorComboBox, Bundle.getMessage("ErrorSensorCol"), Bundle.getMessage("BlockAssignErrorSensorText")));
075
076        final SensorDebounceEditAction debounce = new SensorDebounceEditAction();
077        debounce.sensorDebounce(basic);
078
079        sensorComboBox.addActionListener(e -> {
080            debounce.setBean(sensorComboBox.getSelectedItem());
081            debounce.resetDebounceItems(e);
082        });
083        basic.setSaveItem(new AbstractAction() {
084            @Override
085            public void actionPerformed(ActionEvent e) {
086                if (sensorComboBox.getSelectedItem() == null) {
087                    bean.setSensor(null);
088                } else {
089                    bean.setSensor(sensorComboBox.getSelectedItem().getDisplayName());
090                }
091                if (errorSensorComboBox.getSelectedItem() == null) {
092                    bean.setErrorSensor(null);
093                } else {
094                    bean.setErrorSensor(errorSensorComboBox.getSelectedItem().getDisplayName());
095                }
096            }
097        });
098        basic.setResetItem(new AbstractAction() {
099            @Override
100            public void actionPerformed(ActionEvent e) {
101                //From basic details
102                sensorComboBox.setSelectedItem(bean.getSensor());
103                errorSensorComboBox.setSelectedItem(bean.getErrorSensor());
104                debounce.setBean(bean.getSensor());
105                debounce.resetDebounceItems(e);
106            }
107        });
108
109        bei.add(basic);
110        return basic;
111    }
112
113    BeanItemPanel paths() {
114        BeanItemPanel paths = new BeanItemPanel();
115        String name = Bundle.getMessage("TitlePaths");
116        paths.setName(name);
117
118        paths.addItem(new BeanEditItem(blockPathPanel, Bundle.getMessage("PathTableLabel", bean.getDisplayName()), null));
119        // includes Add Path button
120
121        paths.setResetItem(new AbstractAction() {
122            @Override
123            public void actionPerformed(ActionEvent e) {
124                //clear the table?
125            }
126        });
127
128        bei.add(paths);
129        if (InstanceManager.getNullableDefault(OBlockManager.class) == null) {
130            setEnabled(false);
131        }
132        if (name.equals(tabName)) {
133            setSelectedComponent(paths);
134        }
135        return paths;
136    }
137
138//    BeanItemPanel reporterDetails() { not used for OBlocks/not valid XML
139
140    JSpinner lengthSpinner = new JSpinner(); // 2 digit decimal format field, initialized later as instance
141    private final BlockCurvatureJComboBox curvatureField = new BlockCurvatureJComboBox();
142    JCheckBox permissiveField = new JCheckBox();
143    JComboBox<String> speedField;
144
145    JRadioButton inch = new JRadioButton(Bundle.getMessage("LengthInches"));
146    JRadioButton cm = new JRadioButton(Bundle.getMessage("LengthCentimeters"));
147
148    String defaultBlockSpeedText;
149
150    BeanItemPanel physicalDetails() {
151        defaultBlockSpeedText = (Bundle.getMessage("UseGlobal", "Global") + " " + InstanceManager.getDefault(BlockManager.class).getDefaultSpeed());
152        speedList.add(defaultBlockSpeedText);
153        java.util.Vector<String> _speedMap = InstanceManager.getDefault(SignalSpeedMap.class).getValidSpeedNames();
154        for (String s : _speedMap) {
155            if (!speedList.contains(s)) {
156                speedList.add(s);
157            }
158        }
159        BeanItemPanel basic = new BeanItemPanel();
160        basic.setName(Bundle.getMessage("BlockPhysicalProperties"));
161
162        basic.addItem(new BeanEditItem(null, null, Bundle.getMessage("OBlockPropertiesText")));
163        lengthSpinner.setModel(
164            new SpinnerNumberModel(0f, 0f, 1000f, 0.01f));
165        lengthSpinner.setEditor(new JSpinner.NumberEditor(lengthSpinner, "###0.00"));
166        lengthSpinner.setPreferredSize(new JTextField(8).getPreferredSize());
167        lengthSpinner.setValue(0f); // reset from possible previous use
168        basic.addItem(new BeanEditItem(lengthSpinner, Bundle.getMessage("BlockLengthColName"), Bundle.getMessage("OBlockLengthText")));
169
170        ButtonGroup rg = new ButtonGroup();
171        rg.add(inch);
172        rg.add(cm);
173
174        JPanel p = new JPanel();
175        p.add(inch);
176        p.add(cm);
177        p.setLayout(new BoxLayout(p, BoxLayout.Y_AXIS));
178        inch.setSelected(true);
179
180        inch.addActionListener(e -> {
181            cm.setSelected(!inch.isSelected());
182            updateLength();
183        });
184        cm.addActionListener(e -> {
185            inch.setSelected(!cm.isSelected());
186            updateLength();
187        });
188
189        speedField = new JComboBox<>(speedList);
190        JComboBoxUtil.setupComboBoxMaxRows(speedField);
191        basic.addItem(new BeanEditItem(p, Bundle.getMessage("BlockLengthUnits"), Bundle.getMessage("BlockLengthUnitsText")));
192        basic.addItem(new BeanEditItem(curvatureField, Bundle.getMessage("BlockCurveColName"), ""));
193        basic.addItem(new BeanEditItem(speedField, Bundle.getMessage("BlockSpeedColName"), Bundle.getMessage("BlockMaxSpeedText")));
194        basic.addItem(new BeanEditItem(permissiveField, Bundle.getMessage("BlockPermColName"), Bundle.getMessage("BlockPermissiveText")));
195
196        permissiveField.setSelected(bean.getPermissiveWorking());
197
198        basic.setSaveItem(new AbstractAction() {
199            @Override
200            public void actionPerformed(ActionEvent e) {
201                bean.setCurvature(curvatureField.getCurvature());
202
203                String speed = (String) speedField.getSelectedItem();
204                try {
205                    bean.setBlockSpeed(speed);
206                } catch (JmriException ex) {
207                    jmri.util.swing.JmriJOptionPane.showMessageDialog(f, ex.getMessage() + "\n" + speed);
208                    return;
209                }
210                if (speed != null && !speedList.contains(speed) && !speed.contains("Global")) {
211                    speedList.add(speed);
212                }
213                float len = (Float) lengthSpinner.getValue();
214                bean.setLength( inch.isSelected() ? (len * 25.4f) : (len * 10.0f) );
215                bean.setPermissiveWorking(permissiveField.isSelected());
216            }
217        });
218        basic.setResetItem(new AbstractAction() {
219            @Override
220            public void actionPerformed(ActionEvent e) {
221                lengthSpinner.setValue(bean.getLengthMm());
222
223                curvatureField.setCurvature(bean.getCurvature());
224
225                String speed = bean.getBlockSpeed();
226                if (!speedList.contains(speed)) {
227                    speedList.add(speed);
228                }
229
230                speedField.setEditable(true);
231                speedField.setSelectedItem(speed);
232                updateLength();
233                permissiveField.setSelected(bean.getPermissiveWorking());
234            }
235        });
236        bei.add(basic);
237        return basic;
238    }
239
240    private void updateLength() {
241        lengthSpinner.setValue(inch.isSelected() ? bean.getLengthIn() : bean.getLengthCm());
242    }
243
244    // private final static Logger log = LoggerFactory.getLogger(OBlockEditAction.class);
245
246}