001package jmri.jmrit.beantable.light;
002
003import java.awt.*;
004import java.awt.event.ActionEvent;
005import java.util.List;
006import java.util.*;
007
008import javax.annotation.Nonnull;
009import javax.swing.*;
010
011import jmri.*;
012import jmri.implementation.DefaultLightControl;
013import jmri.swing.NamedBeanComboBox;
014import jmri.util.swing.ComboBoxToolTipRenderer;
015import jmri.util.swing.JComboBoxUtil;
016
017/**
018 * Frame to add or edit a single Light Control.
019 * Code originally within LightTableAction.
020 *
021 * @author Dave Duchamp Copyright (C) 2004
022 * @author Egbert Broerse Copyright (C) 2017
023 * @author Steve Young Copyright (C) 2021
024 */
025public class AddEditSingleLightControlFrame extends jmri.util.JmriJFrame {
026
027    final LightControl lc;
028    private JComboBox<String> typeBox;
029
030    private final JLabel status1 = new JLabel();
031
032    private final NamedBeanComboBox<Sensor> sensor1Box = new NamedBeanComboBox<>( // Sensor (1 or only)
033            InstanceManager.sensorManagerInstance(), null, NamedBean.DisplayOptions.DISPLAYNAME);
034    private final NamedBeanComboBox<Sensor> sensor2Box = new NamedBeanComboBox<>( // Sensor 2
035            InstanceManager.sensorManagerInstance(), null, NamedBean.DisplayOptions.DISPLAYNAME);
036
037    private final JLabel f1Label = new JLabel(Bundle.getMessage("LightSensor", Bundle.getMessage("MakeLabel", ""))); // for 1 sensor
038    private final JLabel f1aLabel = new JLabel(Bundle.getMessage("LightSensor", Bundle.getMessage("MakeLabel", " 2"))); // for 2nd sensor
039
040    private final SpinnerNumberModel fastHourSpinnerModel1 = new SpinnerNumberModel(0, 0, 23, 1); // 0 - 23 h
041    private final JSpinner fastHourSpinner1 = new JSpinner(fastHourSpinnerModel1); // Fast Clock1 hours
042    private final SpinnerNumberModel fastMinuteSpinnerModel1 = new SpinnerNumberModel(0, 0, 59, 1); // 0 - 59 min
043    private final JSpinner fastMinuteSpinner1 = new JSpinner(fastMinuteSpinnerModel1); // Fast Clock1 minutes
044    private final JLabel clockSep1 = new JLabel(" : ");
045    private final JLabel clockSep2 = new JLabel(" : ");
046
047    private final SpinnerNumberModel fastHourSpinnerModel2 = new SpinnerNumberModel(0, 0, 23, 1); // 0 - 23 h
048    private final JSpinner fastHourSpinner2 = new JSpinner(fastHourSpinnerModel2); // Fast Clock2 hours
049    private final SpinnerNumberModel fastMinuteSpinnerModel2 = new SpinnerNumberModel(0, 0, 59, 1); // 0 - 59 min
050    private final JSpinner fastMinuteSpinner2 = new JSpinner(fastMinuteSpinnerModel2); // Fast Clock2 minutes
051
052    private final NamedBeanComboBox<Turnout> turnoutBox = new NamedBeanComboBox<>( // Turnout
053            InstanceManager.turnoutManagerInstance(), null, NamedBean.DisplayOptions.DISPLAYNAME);
054    private final NamedBeanComboBox<Sensor> sensorOnBox = new NamedBeanComboBox<>( // Timed ON
055            InstanceManager.sensorManagerInstance(), null, NamedBean.DisplayOptions.DISPLAYNAME);
056
057    private JComboBox<String> stateBox;
058    private ComboBoxToolTipRenderer stateBoxToolTipRenderer;
059
060    private final SpinnerNumberModel timedOnSpinnerModel = new SpinnerNumberModel(0, 0, 1000000, 1); // 0 - 1,000,000 msec
061    private final JSpinner timedOnSpinner = new JSpinner(timedOnSpinnerModel); // Timed ON
062
063    private JPanel sensorTwoPanel;
064
065    private final JLabel f2Label = new JLabel(Bundle.getMessage("LightSensorSense"));
066
067    private static final int SENSOR_ACTIVE_INDEX = 0;
068    private static final int SENSOR_INACTIVE_INDEX = 1;
069    private static final int TURNOUT_CLOSED_INDEX = 0;
070    private static final int TURNOUT_THROWN_INDEX = 1;
071
072    private JButton createControl;
073    private JButton updateControl;
074
075    final LightControlPane lcp;
076
077    /**
078     * Create a new Frame to Add or Edit a Light Control.
079     *
080     * @param pane Light Control Pane which instigated the action.
081     * @param ctrl If LightControl is null, is a Add Control Window.
082     *              If LightControl specified, is an Edit Control window.
083     */
084    public AddEditSingleLightControlFrame(@Nonnull LightControlPane pane, LightControl ctrl){
085        super(Bundle.getMessage("TitleAddLightControl"), false, true);
086        lc = ctrl;
087        lcp = pane;
088        init();
089    }
090
091    private void init(){
092
093        addHelpMenu("package.jmri.jmrit.beantable.LightAddEdit", true);
094
095        Container contentPane = getContentPane();
096        contentPane.setLayout(new BoxLayout(contentPane, BoxLayout.Y_AXIS));
097
098        JPanel mainContentPanel = new JPanel();
099        mainContentPanel.setLayout(new BoxLayout(mainContentPanel, BoxLayout.Y_AXIS));
100
101        JPanel controlTypePanel = new JPanel();
102        controlTypePanel.setLayout(new FlowLayout());
103        controlTypePanel.add(new JLabel(Bundle.getMessage("LightControlType")));
104        typeBox = new JComboBox<>(LightControlTableModel.controlTypes);
105        ComboBoxToolTipRenderer typeBoxToolTipRenderer = new ComboBoxToolTipRenderer();
106        typeBoxToolTipRenderer.setTooltips(LightControlTableModel.getControlTypeTips());
107        typeBox.setRenderer(typeBoxToolTipRenderer);
108
109        typeBox.addActionListener((ActionEvent e) -> setUpControlType(typeBox.getSelectedIndex()));
110        typeBox.setToolTipText(Bundle.getMessage("LightControlTypeHint"));
111
112        controlTypePanel.add(typeBox);
113
114        JPanel mainOptionsPanel = new JPanel();
115        mainOptionsPanel.setLayout(new FlowLayout());
116        mainOptionsPanel.add(f1Label);
117        mainOptionsPanel.add(sensor1Box);
118
119        // set up number formatting
120        JSpinner.NumberEditor ne1b = new JSpinner.NumberEditor(fastHourSpinner1, "00"); // 2 digits "01" format
121        fastHourSpinner1.setEditor(ne1b);
122        mainOptionsPanel.add(fastHourSpinner1);  // hours ON
123        mainOptionsPanel.add(clockSep1);
124        JSpinner.NumberEditor ne1b1 = new JSpinner.NumberEditor(fastMinuteSpinner1, "00"); // 2 digits "01" format
125        fastMinuteSpinner1.setEditor(ne1b1);
126        mainOptionsPanel.add(fastMinuteSpinner1); // minutes ON
127        mainOptionsPanel.add(turnoutBox);
128        mainOptionsPanel.add(sensorOnBox);
129
130        sensor1Box.setAllowNull(true);
131        sensor1Box.setToolTipText(Bundle.getMessage("LightSensorHint"));
132        JComboBoxUtil.setupComboBoxMaxRows(sensor1Box);
133
134        sensor2Box.setAllowNull(true);
135        sensor2Box.setToolTipText(Bundle.getMessage("LightTwoSensorHint"));
136        JComboBoxUtil.setupComboBoxMaxRows(sensor2Box);
137
138        fastHourSpinner1.setValue(0);  // reset needed
139        fastHourSpinner1.setVisible(false);
140        fastMinuteSpinner1.setValue(0); // reset needed
141        fastMinuteSpinner1.setVisible(false);
142
143        sensorOnBox.setAllowNull(true);
144        sensorOnBox.setVisible(false);
145        JComboBoxUtil.setupComboBoxMaxRows(sensorOnBox);
146        clockSep1.setVisible(false);
147
148        turnoutBox.setAllowNull(true);
149        turnoutBox.setVisible(false);
150        JComboBoxUtil.setupComboBoxMaxRows(turnoutBox);
151
152        sensorTwoPanel = new JPanel();
153        sensorTwoPanel.setLayout(new FlowLayout());
154        sensorTwoPanel.add(f1aLabel);
155        sensorTwoPanel.add(sensor2Box);
156
157        JPanel panel33 = new JPanel();
158        panel33.setLayout(new FlowLayout());
159
160
161        panel33.add(f2Label);
162
163        stateBox = new JComboBox<>(new String[]{
164            Bundle.getMessage("SensorStateActive"), Bundle.getMessage("SensorStateInactive")});
165        stateBox.setToolTipText(Bundle.getMessage("LightSensorSenseHint"));
166        stateBoxToolTipRenderer = new ComboBoxToolTipRenderer();
167        stateBox.setRenderer(stateBoxToolTipRenderer);
168        panel33.add(stateBox);
169
170        JSpinner.NumberEditor ne2a = new JSpinner.NumberEditor(fastHourSpinner2, "00"); // 2 digits "01" format
171        fastHourSpinner2.setEditor(ne2a);
172        panel33.add(fastHourSpinner2);  // hours OFF
173        panel33.add(clockSep2);
174
175        JSpinner.NumberEditor ne2a1 = new JSpinner.NumberEditor(fastMinuteSpinner2, "00"); // 2 digits "01" format
176        fastMinuteSpinner2.setEditor(ne2a1);
177        panel33.add(fastMinuteSpinner2); // minutes OFF
178        panel33.add(timedOnSpinner);
179
180        fastHourSpinner2.setValue(0);  // reset needed
181        fastHourSpinner2.setVisible(false);
182        fastMinuteSpinner2.setValue(0); // reset needed
183        fastMinuteSpinner2.setVisible(false);
184
185        timedOnSpinner.setValue(5000);  // reset needed, default to 5,000 ms
186        timedOnSpinner.setVisible(false);
187        clockSep2.setVisible(false);
188
189        mainContentPanel.add(controlTypePanel);
190        mainContentPanel.add(mainOptionsPanel);
191        mainContentPanel.add(sensorTwoPanel);
192        mainContentPanel.add(panel33);
193        mainContentPanel.setBorder(BorderFactory.createEtchedBorder());
194        contentPane.add(mainContentPanel);
195        contentPane.add(getButtonPanel());
196
197        JPanel statusPanel = new JPanel();
198        statusPanel.add(status1);
199        contentPane.add(statusPanel);
200
201        addWindowListener(new java.awt.event.WindowAdapter() {
202            @Override
203            public void windowClosing(java.awt.event.WindowEvent e) {
204                cancelControlPressed(null);
205            }
206        });
207
208        typeBox.setSelectedIndex(lcp.getLastSelectedControlIndex()); // force GUI status consistent
209
210        if (lc!=null){
211            setTitle(Bundle.getMessage("TitleEditLightControl"));
212            setFrameToControl(lc);
213        }
214
215    }
216
217    private JPanel getButtonPanel(){
218
219        JPanel buttonPanel = new JPanel();
220        buttonPanel.setLayout(new FlowLayout(FlowLayout.TRAILING));
221        JButton cancelControl = new JButton(Bundle.getMessage("ButtonCancel"));
222        buttonPanel.add(cancelControl);
223        cancelControl.addActionListener(this::cancelControlPressed);
224        cancelControl.setToolTipText(Bundle.getMessage("LightCancelButtonHint"));
225        createControl = new JButton(Bundle.getMessage("ButtonCreate"));
226        buttonPanel.add(createControl);
227        createControl.addActionListener(this::createControlPressed);
228        createControl.setToolTipText(Bundle.getMessage("LightCreateControlButtonHint"));
229        updateControl = new JButton(Bundle.getMessage("ButtonUpdate"));
230        buttonPanel.add(updateControl);
231        updateControl.addActionListener(this::updateControlPressed);
232        updateControl.setToolTipText(Bundle.getMessage("LightUpdateControlButtonHint"));
233
234        cancelControl.setVisible(true);
235        updateControl.setVisible(lc!=null);
236        createControl.setVisible(lc==null);
237
238        return buttonPanel;
239    }
240
241    /**
242     * Set the Control Information according to control type.
243     *
244     * @param ctype the control type
245     */
246    private void setUpControlType(int ctype) {
247        // set everything non-visible by default
248        clockSep1.setVisible(false);
249        clockSep2.setVisible(false);
250        fastHourSpinner1.setVisible(false);
251        fastHourSpinner2.setVisible(false);
252        fastMinuteSpinner1.setVisible(false);
253        fastMinuteSpinner2.setVisible(false);
254        f1aLabel.setVisible(false);
255        sensorOnBox.setVisible(false);
256        sensor1Box.setVisible(false);
257        sensor2Box.setVisible(false);
258        stateBox.setVisible(false);
259        timedOnSpinner.setVisible(false);
260        turnoutBox.setVisible(false);
261        sensorTwoPanel.setVisible(false);
262        typeBox.setSelectedIndex(ctype);
263        createControl.setEnabled(true);
264        updateControl.setEnabled(true);
265
266        lcp.setLastSelectedControlIndex(ctype);
267
268        List<String> stateTooltips;
269
270        switch (ctype) {
271            case Light.SENSOR_CONTROL:
272                // set up panel for sensor control
273                f1Label.setText(Bundle.getMessage("LightSensor", Bundle.getMessage("MakeLabel", ""))); // insert nothing before colon
274                sensor1Box.setToolTipText(Bundle.getMessage("LightSensorHint"));
275                f2Label.setText(Bundle.getMessage("LightSensorSense"));
276                stateBox.removeAllItems();
277                stateBox.addItem(Bundle.getMessage("SensorStateActive"));
278                stateBox.addItem(Bundle.getMessage("SensorStateInactive"));
279                stateTooltips = new ArrayList<>();
280                stateTooltips.add(Bundle.getMessage("LightSensorSenseActivTip"));
281                stateTooltips.add(Bundle.getMessage("LightSensorSenseInactivTip"));
282                stateBoxToolTipRenderer.setTooltips(stateTooltips);
283                stateBox.setToolTipText(Bundle.getMessage("LightSensorSenseHint"));
284                f2Label.setVisible(true);
285                sensor1Box.setVisible(true);
286                stateBox.setVisible(true);
287
288                break;
289            case Light.FAST_CLOCK_CONTROL:
290                // set up panel for fast clock control
291                f1Label.setText(Bundle.getMessage("LightScheduleOn"));
292                fastHourSpinner1.setToolTipText(Bundle.getMessage("LightScheduleHint"));
293                fastMinuteSpinner1.setToolTipText(Bundle.getMessage("LightScheduleHintMinutes"));
294                f2Label.setText(Bundle.getMessage("LightScheduleOff"));
295                fastHourSpinner2.setToolTipText(Bundle.getMessage("LightScheduleHint"));
296                fastMinuteSpinner2.setToolTipText(Bundle.getMessage("LightScheduleHintMinutes"));
297                clockSep1.setVisible(true);
298                clockSep2.setVisible(true);
299                fastHourSpinner1.setVisible(true);
300                fastHourSpinner2.setVisible(true);
301                fastMinuteSpinner1.setVisible(true);
302                fastMinuteSpinner2.setVisible(true);
303                f2Label.setVisible(true);
304
305                break;
306            case Light.TURNOUT_STATUS_CONTROL:
307                // set up panel for turnout status control
308                f1Label.setText(Bundle.getMessage("LightTurnout"));
309                turnoutBox.setToolTipText(Bundle.getMessage("LightTurnoutHint"));
310                f2Label.setText(Bundle.getMessage("LightTurnoutSense"));
311
312                stateBox.removeAllItems();
313                stateBox.addItem(InstanceManager.turnoutManagerInstance().getClosedText());
314                stateBox.addItem(InstanceManager.turnoutManagerInstance().getThrownText());
315                stateBox.setToolTipText(Bundle.getMessage("LightTurnoutSenseHint"));
316
317                stateTooltips = new ArrayList<>();
318                stateTooltips.add(Bundle.getMessage("LightConToClosedOrThrownTip",
319                        InstanceManager.turnoutManagerInstance().getClosedText(),
320                        InstanceManager.turnoutManagerInstance().getThrownText()));
321
322                stateTooltips.add(Bundle.getMessage("LightConToClosedOrThrownTip",
323                        InstanceManager.turnoutManagerInstance().getThrownText(),
324                        InstanceManager.turnoutManagerInstance().getClosedText()));
325                stateBoxToolTipRenderer.setTooltips(stateTooltips);
326
327
328                f2Label.setVisible(true);
329                turnoutBox.setVisible(true);
330                stateBox.setVisible(true);
331
332                break;
333            case Light.TIMED_ON_CONTROL:
334                // set up panel for sensor control
335                f1Label.setText(Bundle.getMessage("LightTimedSensor"));
336                sensorOnBox.setToolTipText(Bundle.getMessage("LightTimedSensorHint"));
337                f2Label.setText(Bundle.getMessage("LightTimedDurationOn"));
338                timedOnSpinner.setToolTipText(Bundle.getMessage("LightTimedDurationOnHint"));
339                f2Label.setVisible(true);
340                sensorOnBox.setVisible(true);
341                timedOnSpinner.setVisible(true);
342
343                break;
344            case Light.TWO_SENSOR_CONTROL:
345                // set up panel for two sensor control
346                sensorTwoPanel.setVisible(true);
347                f1Label.setText(Bundle.getMessage("LightSensor", " " + Bundle.getMessage("MakeLabel", "1"))); // for 2-sensor use, insert number "1" before colon
348                f1aLabel.setVisible(true);
349                sensor1Box.setToolTipText(Bundle.getMessage("LightSensorHint"));
350                f2Label.setText(Bundle.getMessage("LightSensorSense"));
351
352                stateBox.removeAllItems();
353                stateBox.addItem(Bundle.getMessage("SensorStateActive"));
354                stateBox.addItem(Bundle.getMessage("SensorStateInactive"));
355                stateBox.setToolTipText(Bundle.getMessage("LightSensorSenseHint"));
356
357                stateTooltips = new ArrayList<>();
358                stateTooltips.add(Bundle.getMessage("Light2SensorSenseActivTip"));
359                stateTooltips.add(Bundle.getMessage("Light2SensorSenseInactivTip"));
360                stateBoxToolTipRenderer.setTooltips(stateTooltips);
361
362                f2Label.setVisible(true);
363                sensor1Box.setVisible(true);
364                sensor2Box.setVisible(true);
365                sensor1Box.setToolTipText(Bundle.getMessage("LightTwoSensorHint"));
366                stateBox.setVisible(true);
367
368                break;
369            case Light.NO_CONTROL:
370                // set up panel for no control
371                f1Label.setText(Bundle.getMessage("LightNoneSelected"));
372                f2Label.setVisible(false);
373                createControl.setEnabled(false);
374                updateControl.setEnabled(false);
375                break;
376            default:
377                log.error("Unexpected control type in controlTypeChanged: {}", ctype);
378                break;
379        }
380        pack();
381        setVisible(true);
382    }
383
384    protected void cancelControlPressed(ActionEvent e) {
385        lcp.closeEditControlWindow();
386    }
387
388    private void commitEdits(){
389        try {
390            fastHourSpinner1.commitEdit();
391            fastHourSpinner2.commitEdit();
392            fastMinuteSpinner1.commitEdit();
393            fastMinuteSpinner2.commitEdit();
394            timedOnSpinner.commitEdit();
395        } catch (java.text.ParseException pe) {
396            // unlikely to be thrown as values set to original if incorrect on commitEdit()
397        }
398    }
399
400    protected void updateControlPressed(ActionEvent e) {
401        commitEdits();
402        LightControl newLc = new DefaultLightControl();
403        ArrayList<LightControl> withoutExistingLc = new ArrayList<>(lcp.getControlList());
404        withoutExistingLc.remove(lc);
405        if (setControlInformation(newLc,withoutExistingLc)) {
406            lcp.updateControlPressed(lc,newLc);
407            cancelControlPressed(e);
408        } else {
409            pack();
410            setVisible(true);
411        }
412    }
413
414    protected void createControlPressed(ActionEvent e) {
415        if (Objects.equals(typeBox.getSelectedItem(), LightControlTableModel.noControl)) {
416            return;
417        }
418
419        commitEdits();
420        LightControl newLc = new DefaultLightControl();
421        if (setControlInformation(newLc,lcp.getControlList())) {
422            lcp.addControlToTable(newLc);
423            cancelControlPressed(e);
424        } else {
425            pack();
426            setVisible(true);
427        }
428    }
429
430    private void notifyUser(String message, Color color){
431        status1.setText(message);
432        status1.setForeground(color);
433        jmri.util.ThreadingUtil.runOnGUIDelayed( ()->{
434            status1.setText(" ");
435        },5000);
436
437    }
438
439    /**
440     * Retrieve control information from pane and update Light Control.
441     *
442     * @param g LightControl to set to User Settings.
443     * @param currentList current Light Control List, used to check that Fast Clock Times are OK.
444     * @return 'true' if no errors or warnings
445     */
446    private boolean setControlInformation(LightControl g, List<LightControl> currentList) {
447        // Get control information
448        if (LightControlTableModel.sensorControl.equals(typeBox.getSelectedItem())) {
449            // Set type of control
450            g.setControlType(Light.SENSOR_CONTROL);
451            // Get sensor control information
452            String sensorName = sensor1Box.getSelectedItemDisplayName();
453            if (sensorName == null) {
454                // no sensor selected
455                g.setControlType(Light.NO_CONTROL);
456                notifyUser(Bundle.getMessage("LightWarn8"),Color.red);
457                return false;
458            }
459            int sState =  ( Bundle.getMessage("SensorStateInactive").equals(stateBox.getSelectedItem())
460                ? Sensor.INACTIVE : Sensor.ACTIVE);
461            g.setControlSensorName(sensorName);
462            g.setControlSensorSense(sState);
463        } else if (LightControlTableModel.fastClockControl.equals(typeBox.getSelectedItem())) {
464            // Set type of control
465            g.setControlType(Light.FAST_CLOCK_CONTROL);
466            // read and parse the hours and minutes in the 2 x 2 spinners
467            int onHour = (Integer) fastHourSpinner1.getValue();  // hours
468            int onMin = (Integer) fastMinuteSpinner1.getValue();  // minutes
469            int offHour = (Integer) fastHourSpinner2.getValue(); // hours
470            int offMin = (Integer) fastMinuteSpinner2.getValue(); // minutes
471
472            g.setFastClockControlSchedule(onHour, onMin, offHour, offMin);
473
474            if (g.onOffTimesFaulty()) {
475                notifyUser(Bundle.getMessage("LightWarn11"),Color.red);
476                return false;
477            }
478
479            if (g.areFollowerTimesFaulty(currentList)) {
480                notifyUser(Bundle.getMessage("LightWarn12"),Color.red);
481                return false;
482            }
483
484        } else if (LightControlTableModel.turnoutStatusControl.equals(typeBox.getSelectedItem())) {
485            // Set type of control
486            g.setControlType(Light.TURNOUT_STATUS_CONTROL);
487            // Get turnout control information
488            String turnoutName = turnoutBox.getSelectedItemSystemName();
489            if (turnoutName == null) {
490                // no turnout selected
491                g.setControlType(Light.NO_CONTROL);
492                notifyUser(Bundle.getMessage("LightWarn10"),Color.red);
493                return false;
494            }
495
496            // TODO : Remove Turnouts which are actually lights ( ???? )
497            // from the JComboBox list.
498
499            // IMPROVED TODO : Disable creation of Turnouts or Lights with matching
500            // hardware addresses ( except the L or T element ) at time of Bean creation
501
502            String testLightaddr = jmri.util.StringUtil.replaceLast(turnoutName, "T", "L");
503            Light testLight = InstanceManager.getDefault(LightManager.class).
504                getBySystemName(testLightaddr);
505            if (testLight != null) {
506                // Requested turnout bit is already assigned to a Light
507                notifyUser(Bundle.getMessage("LightWarn3") + " " + testLight.getDisplayName(),Color.red);
508                return false;
509            }
510
511            // Initialize the requested Turnout State
512            int tState = Turnout.CLOSED;
513            if (Objects.equals(stateBox.getSelectedItem(), InstanceManager.
514                    turnoutManagerInstance().getThrownText())) {
515                tState = Turnout.THROWN;
516            }
517            g.setControlTurnout(turnoutBox.getSelectedItemDisplayName());
518            g.setControlTurnoutState(tState);
519
520        } else if (LightControlTableModel.timedOnControl.equals(typeBox.getSelectedItem())) {
521            // Set type of control
522            g.setControlType(Light.TIMED_ON_CONTROL);
523            // Get trigger sensor control information
524            String triggerSensorName = sensorOnBox.getSelectedItemDisplayName();
525            if (triggerSensorName == null) {
526                // Trigger sensor not selected
527                g.setControlType(Light.NO_CONTROL);
528                notifyUser(Bundle.getMessage("LightWarn8"),Color.red);
529                return false;
530            }
531            g.setControlTimedOnSensorName(triggerSensorName);
532            int dur = (Integer) timedOnSpinner.getValue();
533            g.setTimedOnDuration(dur);
534        } else if (LightControlTableModel.twoSensorControl.equals(typeBox.getSelectedItem())) {
535            // Set type of control
536            g.setControlType(Light.TWO_SENSOR_CONTROL);
537            // Get sensor control information
538            String sensorName = sensor1Box.getSelectedItemDisplayName();
539            String sensor2Name = sensor2Box.getSelectedItemDisplayName();
540            if (sensorName == null || sensor2Name == null) {
541                // no sensor(s) selected
542                g.setControlType(Light.NO_CONTROL);
543                notifyUser(Bundle.getMessage("LightWarn8"),Color.red);
544                return false;
545            }
546            int sState = Sensor.ACTIVE;
547            if (Objects.equals(stateBox.getSelectedItem(), Bundle.getMessage("SensorStateInactive"))) {
548                sState = Sensor.INACTIVE;
549            }
550            g.setControlSensorName(sensorName);
551            g.setControlSensor2Name(sensor2Name);
552            g.setControlSensorSense(sState);
553        } else if (LightControlTableModel.noControl.equals(typeBox.getSelectedItem())) {
554            // Set type of control
555            g.setControlType(Light.NO_CONTROL);
556        } else {
557            log.error("Unexpected control type: {}", typeBox.getSelectedItem());
558        }
559        return (true);
560    }
561
562    private void setFrameToControl(LightControl lc){
563
564        int ctType = lc.getControlType();
565        switch (ctType) {
566            case Light.SENSOR_CONTROL:
567                setUpControlType(Light.SENSOR_CONTROL);
568                sensor1Box.setSelectedItemByName(lc.getControlSensorName());
569                stateBox.setSelectedIndex( (lc.getControlSensorSense() == Sensor.ACTIVE)? SENSOR_ACTIVE_INDEX : SENSOR_INACTIVE_INDEX);
570                break;
571            case Light.FAST_CLOCK_CONTROL:
572                setUpControlType(Light.FAST_CLOCK_CONTROL);
573                fastHourSpinner1.setValue(lc.getFastClockOnHour());
574                fastMinuteSpinner1.setValue(lc.getFastClockOnMin());
575                fastHourSpinner2.setValue(lc.getFastClockOffHour());
576                fastMinuteSpinner2.setValue(lc.getFastClockOffMin());
577                break;
578            case Light.TURNOUT_STATUS_CONTROL:
579                setUpControlType(Light.TURNOUT_STATUS_CONTROL);
580                turnoutBox.setSelectedItemByName(lc.getControlTurnoutName());
581                stateBox.setSelectedIndex( (lc.getControlTurnoutState() == Turnout.THROWN)? TURNOUT_THROWN_INDEX : TURNOUT_CLOSED_INDEX);
582                break;
583            case Light.TIMED_ON_CONTROL:
584                setUpControlType(Light.TIMED_ON_CONTROL);
585                sensorOnBox.setSelectedItemByName(lc.getControlTimedOnSensorName());
586                timedOnSpinner.setValue(lc.getTimedOnDuration());
587                break;
588            case Light.TWO_SENSOR_CONTROL:
589                setUpControlType(Light.TWO_SENSOR_CONTROL);
590                sensor1Box.setSelectedItemByName(lc.getControlSensorName());
591                sensor2Box.setSelectedItemByName(lc.getControlSensor2Name());
592                stateBox.setSelectedIndex( (lc.getControlSensorSense() == Sensor.ACTIVE)? SENSOR_ACTIVE_INDEX : SENSOR_INACTIVE_INDEX);
593                break;
594            case Light.NO_CONTROL:
595                setUpControlType(Light.NO_CONTROL);
596                break;
597            default:
598                log.error("Unhandled light control type: {}", ctType);
599                break;
600        }
601
602    }
603
604    private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(AddEditSingleLightControlFrame.class);
605
606}