001package jmri.jmrit.beantable.signalmast;
002
003import java.awt.*;
004import java.text.DecimalFormat;
005import java.util.*;
006import java.util.List;
007
008import javax.swing.*;
009import javax.swing.border.TitledBorder;
010import javax.annotation.Nonnull;
011
012import jmri.*;
013import jmri.implementation.*;
014
015import org.openide.util.lookup.ServiceProvider;
016
017/**
018 * A pane for configuring VirtualSignalMast objects.
019 *
020 * @see jmri.jmrit.beantable.signalmast.SignalMastAddPane
021 * @author Bob Jacobsen Copyright (C) 2018
022 * @since 4.11.2
023 */
024public class VirtualSignalMastAddPane extends SignalMastAddPane {
025
026    public VirtualSignalMastAddPane() {
027        initPanel();
028    }
029    
030    final void initPanel() {
031        
032        setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
033        // lit/unlit controls
034        JPanel p = new JPanel();
035        p.setLayout(new BoxLayout(p, BoxLayout.X_AXIS));
036        p.add(new JLabel(Bundle.getMessage("AllowUnLitLabel") + ": "));
037        p.add(allowUnLit);
038        p.setAlignmentX(Component.LEFT_ALIGNMENT);
039        add(p);
040        
041        // disabled aspects controls
042        TitledBorder disableborder = BorderFactory.createTitledBorder(BorderFactory.createLineBorder(Color.black));
043        disableborder.setTitle(Bundle.getMessage("DisableAspectsLabel"));
044        JScrollPane disabledAspectsScroll = new JScrollPane(disabledAspectsPanel);
045        disabledAspectsScroll.setBorder(disableborder);
046        add(disabledAspectsScroll);
047    }
048
049    /** {@inheritDoc} */
050    @Override
051    @Nonnull public String getPaneName() {
052        return Bundle.getMessage("VirtualMast");
053    }
054
055    JCheckBox allowUnLit = new JCheckBox();
056
057    LinkedHashMap<String, JCheckBox> disabledAspects = new LinkedHashMap<>(NOTIONAL_ASPECT_COUNT);
058    JPanel disabledAspectsPanel = new JPanel();
059    
060    VirtualSignalMast currentMast = null;
061
062    /** {@inheritDoc} */
063    @Override
064    public void setAspectNames(@Nonnull SignalAppearanceMap map, @Nonnull SignalSystem sigSystem) {
065        Enumeration<String> aspects = map.getAspects();
066        // update immediately
067        disabledAspects = new LinkedHashMap<>(NOTIONAL_ASPECT_COUNT);
068        disabledAspectsPanel.removeAll();
069        while (aspects.hasMoreElements()) {
070            String aspect = aspects.nextElement();
071            JCheckBox disabled = new JCheckBox(aspect);
072            disabledAspects.put(aspect, disabled);
073        }
074
075        for (Map.Entry<String, JCheckBox> entry : disabledAspects.entrySet()) {
076            disabledAspectsPanel.add(entry.getValue());
077        }
078
079        disabledAspectsPanel.setLayout(new jmri.util.javaworld.GridLayout2(0, 1)); // 0 means enough
080
081        disabledAspectsPanel.revalidate();
082    }
083
084    /** {@inheritDoc} */
085    @Override
086    public boolean canHandleMast(@Nonnull SignalMast mast) {
087        return mast instanceof jmri.implementation.VirtualSignalMast;
088    }
089
090    /** {@inheritDoc} */
091    @Override
092    public void setMast(SignalMast mast) { 
093        log.trace("setMast {} start", mast);
094        if (mast == null) { 
095            currentMast = null; 
096            return; 
097        }
098        
099        if (! (mast instanceof jmri.implementation.VirtualSignalMast) ) {
100            log.error("mast was wrong type: {} {}", mast.getSystemName(), mast.getClass().getName());
101            return;
102        }
103
104        currentMast = (VirtualSignalMast) mast;
105        List<String> disabled = currentMast.getDisabledAspects();
106        if (disabled != null) {
107            for (String aspect : disabled) {
108                if (disabledAspects.containsKey(aspect)) {
109                    disabledAspects.get(aspect).setSelected(true);
110                }
111            }
112        }
113
114        allowUnLit.setSelected(currentMast.allowUnLit());
115
116        log.trace("setMast {} end", mast);
117    }
118
119    DecimalFormat paddedNumber = new DecimalFormat("0000");
120
121    /** {@inheritDoc} */
122    @Override
123    public boolean createMast(@Nonnull
124            String sigsysname, @Nonnull
125                    String mastname, @Nonnull
126                            String username) {
127        log.trace("createMast {} {} {} start with currentMast: {}", sigsysname, mastname, username, currentMast);
128        if (currentMast == null) {
129            // create a mast
130            String name = "IF$vsm:"
131                    + sigsysname
132                    + ":" + mastname.substring(11, mastname.length() - 4);
133            name += "($" + (paddedNumber.format(VirtualSignalMast.getLastRef() + 1)) + ")";
134            currentMast = new VirtualSignalMast(name);
135            if (!username.isEmpty()) {
136                currentMast.setUserName(username);
137            }
138            currentMast.setMastType(mastname.substring(11, mastname.length() - 4));
139            InstanceManager.getDefault(SignalMastManager.class).register(currentMast);
140        }
141
142        // load a new or existing mast
143        for (Map.Entry<String, JCheckBox> entry : disabledAspects.entrySet()) {
144            if (entry.getValue().isSelected()) {
145                currentMast.setAspectDisabled(entry.getKey());
146            } else {
147                currentMast.setAspectEnabled(entry.getKey());
148            }
149        }
150        currentMast.setAllowUnLit(allowUnLit.isSelected());
151        log.trace("createMast {} {} {} end", sigsysname, mastname, username);
152        return true;
153    }
154
155    @ServiceProvider(service = SignalMastAddPane.SignalMastAddPaneProvider.class)
156    static public class SignalMastAddPaneProvider extends SignalMastAddPane.SignalMastAddPaneProvider {
157        /** {@inheritDoc} */
158        @Override
159        @Nonnull public String getPaneName() {
160            return Bundle.getMessage("VirtualMast");
161        }
162        /** {@inheritDoc} */
163        @Override
164        @Nonnull public SignalMastAddPane getNewPane() {
165            return new VirtualSignalMastAddPane();
166        }
167    }
168    
169    private final static org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(VirtualSignalMastAddPane.class);
170
171}