001package jmri.jmrix;
002
003import java.awt.Color;
004import java.awt.GridBagConstraints;
005import java.awt.Insets;
006import java.util.Map;
007import javax.swing.JComboBox;
008import javax.swing.JComponent;
009import javax.swing.JPanel;
010import org.slf4j.Logger;
011import org.slf4j.LoggerFactory;
012
013/**
014 * Abstract base class for common implementation of the Stream Port
015 * ConnectionConfig
016 *
017 * @author Kevin Dickerson Copyright (C) 2001, 2003
018 */
019abstract public class AbstractStreamConnectionConfig extends AbstractConnectionConfig implements StreamConnectionConfig {
020
021    /**
022     * Create a connection configuration with a preexisting adapter. This is
023     * used principally when loading a configuration that defines this
024     * connection.
025     *
026     * @param p the adapter to create a connection configuration for
027     */
028    public AbstractStreamConnectionConfig(jmri.jmrix.AbstractStreamPortController p) {
029        super();
030        adapter = p;
031    }
032
033    /**
034     * Ctor for a functional object with no preexisting adapter. Expect that the
035     * subclass setInstance() will fill the adapter member.
036     */
037    public AbstractStreamConnectionConfig() {
038        adapter = null;
039    }
040
041    @Override
042    public jmri.jmrix.AbstractStreamPortController getAdapter() {
043        return adapter;
044    }
045
046    protected boolean init = false;
047
048    /**
049     * {@inheritDoc}
050     */
051    @Override
052    protected void checkInitDone() {
053        log.debug("init called for {}", name());
054        if (init) {
055            return;
056        }
057        addNameEntryCheckers(adapter);
058        init = true;
059    }
060
061    @Override
062    public void updateAdapter() {
063        for (Map.Entry<String, Option> entry : options.entrySet()) {
064            adapter.setOptionState(entry.getKey(), entry.getValue().getItem());
065        }
066
067        if (!adapter.getSystemConnectionMemo().setSystemPrefix(systemPrefixField.getText())) {
068            systemPrefixField.setText(adapter.getSystemConnectionMemo().getSystemPrefix());
069            connectionNameField.setText(adapter.getSystemConnectionMemo().getUserName());
070        }
071    }
072
073    protected jmri.jmrix.AbstractStreamPortController adapter;
074
075    /**
076     * {@inheritDoc}
077     * <p>
078     * This implementation always returns the localized value for "none".
079     *
080     * @return the localized value for "none"
081     */
082    @Override
083    public String getInfo() {
084        return Bundle.getMessage("none");
085    }
086
087    /**
088     * {@inheritDoc}
089     */
090    @Override
091    public void loadDetails(final JPanel details) {
092        _details = details;
093        setInstance();
094        if (!init) {
095            String[] optionsAvailable = adapter.getOptions();
096            options.clear();
097            for (String i : optionsAvailable) {
098                JComboBox<String> opt = new JComboBox<>(adapter.getOptionChoices(i));
099                opt.setSelectedItem(adapter.getOptionState(i));
100                // check that it worked
101                if (!adapter.getOptionState(i).equals(opt.getSelectedItem())) {
102                    // no, set 1st option choice
103                    opt.setSelectedIndex(0);
104                    // log before setting new value to show old value
105                    log.warn("Loading found invalid value for option {}, found \"{}\", setting to \"{}\"", i, adapter.getOptionState(i), opt.getSelectedItem());
106                    adapter.setOptionState(i, (String) opt.getSelectedItem());
107                }
108                options.put(i, new Option(adapter.getOptionDisplayName(i), opt, adapter.isOptionAdvanced(i)));
109            }
110        }
111
112        if (adapter.getSystemConnectionMemo() != null) {
113            systemPrefixField.setText(adapter.getSystemConnectionMemo().getSystemPrefix());
114            connectionNameField.setText(adapter.getSystemConnectionMemo().getUserName());
115        }
116        NUMOPTIONS = NUMOPTIONS + options.size();
117
118        showAdvanced.setFont(showAdvanced.getFont().deriveFont(9f));
119        showAdvanced.setForeground(Color.blue);
120        showAdvanced.addItemListener(e -> showAdvancedItems());
121        showAdvancedItems();
122        init = false;  // need to reload action listeners
123        checkInitDone();
124    }
125
126    @Override
127    @edu.umd.cs.findbugs.annotations.SuppressFBWarnings(value = "BC_UNCONFIRMED_CAST_OF_RETURN_VALUE",
128        justification = "Type is checked before casting")
129    protected void showAdvancedItems() {
130        _details.removeAll();
131        cL.anchor = GridBagConstraints.WEST;
132        cL.insets = new Insets(2, 5, 0, 5);
133        cR.insets = new Insets(2, 0, 0, 5);
134        cR.anchor = GridBagConstraints.WEST;
135        cR.gridx = 1;
136        cL.gridx = 0;
137        _details.setLayout(gbLayout);
138        int i = 0;
139
140        boolean incAdvancedOptions = false;
141        for (Map.Entry<String, Option> entry : options.entrySet()) {
142            if (entry.getValue().isAdvanced()) {
143                incAdvancedOptions = true;
144                break;
145            }
146        }
147
148        i = addStandardDetails(adapter, incAdvancedOptions, i);
149
150        if (showAdvanced.isSelected()) {
151            for (Map.Entry<String, Option> entry : options.entrySet()) {
152                if (entry.getValue().isAdvanced()) {
153                    cR.gridy = i;
154                    cL.gridy = i;
155                    gbLayout.setConstraints(entry.getValue().getLabel(), cL);
156                    gbLayout.setConstraints(entry.getValue().getComponent(), cR);
157                    _details.add(entry.getValue().getLabel());
158                    _details.add(entry.getValue().getComponent());
159                    i++;
160                }
161            }
162        }
163        cL.gridwidth = 2;
164        for (JComponent item : additionalItems) {
165            cL.gridy = i;
166            gbLayout.setConstraints(item, cL);
167            _details.add(item);
168            i++;
169        }
170        cL.gridwidth = 1;
171        if (_details.getParent() != null && _details.getParent() instanceof javax.swing.JViewport) {
172            javax.swing.JViewport vp = (javax.swing.JViewport) _details.getParent();
173            vp.revalidate();
174            vp.repaint();
175        }
176    }
177
178    @Override
179    public String getManufacturer() {
180        return adapter.getManufacturer();
181    }
182
183    @Override
184    public void setManufacturer(String manufacturer) {
185        setInstance();
186        adapter.setManufacturer(manufacturer);
187    }
188
189    @Override
190    public String getConnectionName() {
191        if (adapter.getSystemConnectionMemo() != null) {
192            return adapter.getSystemConnectionMemo().getUserName();
193        } else {
194            return null;
195        }
196    }
197
198    @Override
199    public boolean getDisabled() {
200        if (adapter == null) {
201            return true;
202        }
203        return adapter.getDisabled();
204    }
205
206    @Override
207    public void setDisabled(boolean disabled) {
208        adapter.setDisabled(disabled);
209    }
210
211    @Override
212    public void dispose() {
213        super.dispose();
214        if (adapter != null) {
215            adapter.dispose();
216            adapter = null;
217        }
218    }
219
220    private final static Logger log = LoggerFactory.getLogger(AbstractStreamConnectionConfig.class);
221
222}