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