001package jmri.jmrix.lenz.swing.li101;
002
003import java.awt.FlowLayout;
004import javax.swing.BoxLayout;
005import javax.swing.JButton;
006import javax.swing.JComboBox;
007import javax.swing.JLabel;
008import javax.swing.JPanel;
009import javax.swing.JToggleButton;
010import jmri.jmrix.lenz.XNetConstants;
011import jmri.jmrix.lenz.XNetListener;
012import jmri.jmrix.lenz.XNetMessage;
013import jmri.jmrix.lenz.XNetReply;
014import jmri.jmrix.lenz.XNetTrafficController;
015import org.slf4j.Logger;
016import org.slf4j.LoggerFactory;
017
018/**
019 * Frame displaying the LI101 configuration utility
020 * <p>
021 * This is a configuration utility for the LI101. It allows the user to set the
022 * XpressNet Address and the port speed used to communicate with the LI101.
023 *
024 * @author Paul Bender Copyright (C) 2003-2010
025 */
026public class LI101Frame extends jmri.util.JmriJFrame implements XNetListener {
027
028    protected XNetTrafficController tc;
029
030    public LI101Frame(jmri.jmrix.lenz.XNetSystemConnectionMemo memo) {
031        super(Bundle.getMessage("MenuItemLI101ConfigurationManager"));
032        tc = memo.getXNetTrafficController();
033        getContentPane().setLayout(new BoxLayout(getContentPane(), BoxLayout.Y_AXIS));
034
035        JPanel pane0 = new JPanel();
036        pane0.setLayout(new FlowLayout());
037        pane0.add(new JLabel(Bundle.getMessage("XNetAddressLabel")));
038        pane0.add(addrBox);
039        pane0.setAlignmentX(java.awt.Component.CENTER_ALIGNMENT);
040        getContentPane().add(pane0);
041
042        JPanel pane1 = new JPanel();
043        pane1.add(new JLabel(Bundle.getMessage("LI101SpeedSettingLabel")));
044        pane1.add(speedBox);
045        pane1.setAlignmentX(java.awt.Component.CENTER_ALIGNMENT);
046        getContentPane().add(pane1);
047
048        JPanel pane2 = new JPanel();
049        pane2.add(readSettingsButton);
050        pane2.add(writeSettingsButton);
051        pane2.add(resetButton);
052        resetButton.setToolTipText(Bundle.getMessage("ResetDefaultsToolTip"));
053        pane2.add(closeButton);
054        getContentPane().add(pane2);
055
056        // Initialize the comboBoxes
057        addrBox.setVisible(true);
058        addrBox.setToolTipText(Bundle.getMessage("XNetAddressToolTip"));
059        for (String validXNetAddress : validXNetAddresses) {
060            addrBox.addItem(validXNetAddress);
061        }
062        addrBox.setSelectedIndex(32);
063
064        speedBox.setVisible(true);
065        speedBox.setToolTipText(Bundle.getMessage("LI101SpeedSettingToolTip"));
066        for (String validSpeed : validSpeeds) {
067            speedBox.addItem(validSpeed);
068        }
069        speedBox.setSelectedIndex(4);
070
071        // and prep for display
072        pack();
073
074        status.setAlignmentX(java.awt.Component.CENTER_ALIGNMENT);
075        getContentPane().add(status);
076
077        // install read settings, write settings button handlers
078        readSettingsButton.addActionListener(a -> readLI101Settings());
079
080        writeSettingsButton.addActionListener(a -> writeLI101Settings());
081
082        // install close button handler
083        closeButton.addActionListener(a -> {
084            setVisible(false);
085            dispose();
086        });
087
088        // install reset button handler
089        resetButton.addActionListener(a -> resetLI101Settings());
090
091        // add status
092        getContentPane().add(status);
093
094        if (tc != null) {
095            tc.addXNetListener(~0, this);
096        } else {
097            log.warn("No XpressNet connection, so panel won't function");
098        }
099
100    }
101
102    boolean read = false;
103
104    final JComboBox<String> addrBox = new javax.swing.JComboBox<>();
105    final JComboBox<String> speedBox = new javax.swing.JComboBox<>();
106
107    final JLabel status = new JLabel("");
108
109    final JToggleButton readSettingsButton = new JToggleButton(Bundle.getMessage("LI101ReadButton"));
110    final JToggleButton writeSettingsButton = new JToggleButton(Bundle.getMessage("LI101WriteButton"));
111    final JButton closeButton = new JButton(Bundle.getMessage("ButtonClose"));
112    final JButton resetButton = new JButton(Bundle.getMessage("ButtonResetDefaults"));
113
114    protected final String[] validXNetAddresses = new String[]{"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10",
115            "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24", "25", "26", "27",
116            "28", "29", "30", "31", ""};
117
118    protected final String[] validSpeeds = new String[]{Bundle.getMessage("LIBaud19200"), Bundle.getMessage("Baud38400"),
119            Bundle.getMessage("Baud57600"), Bundle.getMessage("Baud115200"), ""};
120    protected int[] validSpeedValues = new int[]{19200, 38400, 57600, 115200};
121
122    /**
123     * Send new address/baud rate to LI101.
124     */
125    void writeLI101Settings() {
126        if (!(addrBox.getSelectedItem().equals(""))
127                && addrBox.getSelectedItem() != null) {
128            /* First, we take care of generating an address request */
129            XNetMessage msg = XNetMessage.getLIAddressRequestMsg(
130                    addrBox.getSelectedIndex());
131            //Then send to the controller
132            tc.sendXNetMessage(msg, this);
133        }
134        if (!(speedBox.getSelectedItem().equals(""))
135                && speedBox.getSelectedItem() != null) {
136            /* Now, we can send a baud rate request */
137            XNetMessage msg = XNetMessage.getLISpeedRequestMsg(speedBox.getSelectedIndex() + 1);
138            //Then send to the controller
139            tc.sendXNetMessage(msg, this);
140        }
141    }
142
143    /**
144     * Send Information request to LI101.
145     */
146    void readLI101Settings() {
147        /* First, we request setting an out of range address
148         to get the current value. */
149        XNetMessage msg = XNetMessage.getLIAddressRequestMsg(32);
150        //Then send to the controller
151        tc.sendXNetMessage(msg, this);
152
153        /* Next, we request setting an out of range speed request
154         to get the current value. */
155        XNetMessage msg2 = XNetMessage.getLISpeedRequestMsg(6);
156        //Then send to the controller
157        tc.sendXNetMessage(msg2, this);
158    }
159
160    /**
161     * Listen for responces from the LI101.
162     */
163    @Override
164    public void message(XNetReply l) {
165        // Check to see if this is an LI101 info request messgage, if it
166        //is, determine if it's the baud rate setting, or the address
167        //setting
168        if (l.getElement(0) == XNetConstants.LI101_REQUEST) {
169            if (l.getElement(1) == XNetConstants.LI101_REQUEST_ADDRESS) {
170                // The third element is the address
171                addrBox.setSelectedIndex(l.getElement(2));
172                status.setText("Address" + l.getElement(2) + "received from LI101");
173            } else if (l.getElement(1) == XNetConstants.LI101_REQUEST_BAUD) {
174                // The third element is the encoded Baud rate
175                speedBox.setSelectedIndex(l.getElement(2) - 1);
176                status.setText("Baud rate" + validSpeeds[l.getElement(2) - 1] + "received from LI101");
177            }
178        }
179    }
180
181    /**
182     * Listen for the messages to the LI101.
183     */
184    @Override
185    public void message(XNetMessage l) {
186    }
187
188    /**
189     * Handle a timeout notification.
190     */
191    @Override
192    public void notifyTimeout(XNetMessage msg) {
193        if (log.isDebugEnabled()) {
194            log.debug("Notified of timeout on message{}", msg.toString());
195        }
196    }
197
198    /**
199     * Reset this LI101.
200     * <p>
201     * For now, Reset just resets the screen to factory defaults, and does
202     * not send any information to the LI101F.  To do a reset, we need to
203     * send a BREAK signal for 200 milliseconds.
204     * Default values are 30 for the address, and 19,200 baud for the
205     * speed.
206     */
207    void resetLI101Settings() {
208        addrBox.setSelectedIndex(30);
209        speedBox.setSelectedIndex(0);
210    }
211
212    private static final Logger log = LoggerFactory.getLogger(LI101Frame.class);
213
214}