001package jmri.jmrix.lenz.swing.lz100;
002
003import javax.swing.BoxLayout;
004import javax.swing.JButton;
005import javax.swing.JLabel;
006import javax.swing.JPanel;
007import javax.swing.JRadioButton;
008import javax.swing.JToggleButton;
009import jmri.jmrix.lenz.XNetConstants;
010import jmri.jmrix.lenz.XNetListener;
011import jmri.jmrix.lenz.XNetMessage;
012import jmri.jmrix.lenz.XNetReply;
013import jmri.jmrix.lenz.XNetTrafficController;
014import org.slf4j.Logger;
015import org.slf4j.LoggerFactory;
016
017/**
018 * Internal Frame displaying the LZ100 configuration utility
019 *
020 * This is a configuration utility for the LZ100. It allows the user to set the
021 * statup mode (automatic or manual) and to reset the command station.
022 *
023 * @author Paul Bender Copyright (C) 2005-2010
024 */
025public class LZ100InternalFrame extends javax.swing.JInternalFrame implements XNetListener {
026
027    private boolean autoMode = false; // holds Auto/Manual Startup Mode.
028
029    private int resetMode = 0; // holds the reset mode;
030    static final private int IDLE = 0;
031    static final private int ONSENT = 1;
032    static final private int OFFSENT = 2;
033
034    private int sendCount = 0; // count the number of times the on/off 
035    // sequence for F4 has been sent during a reset
036
037    protected XNetTrafficController tc;
038
039    public LZ100InternalFrame(jmri.jmrix.lenz.XNetSystemConnectionMemo memo) {
040
041        tc = memo.getXNetTrafficController();
042
043        getContentPane().setLayout(new BoxLayout(getContentPane(), BoxLayout.Y_AXIS));
044
045        setTitle(Bundle.getMessage("CommandConfigTitle"));
046
047        JPanel pane4 = new JPanel();
048        pane4.add(new JLabel(Bundle.getMessage("LZ100StartMode")));
049
050        isAutoMode.setVisible(true);
051        // isAutoMode
052        isAutoMode.setToolTipText(Bundle.getMessage("LZ100AutoModeToolTip"));
053        pane4.add(isAutoMode);
054
055        isManualMode.setVisible(true);
056        // isManualMode
057        isManualMode.setToolTipText(Bundle.getMessage("LZ100ManualModeToolTip"));
058        pane4.add(isManualMode);
059
060        // amModeGetButton
061        amModeGetButton.setToolTipText(Bundle.getMessage("LZ100GetAMModeToolTip"));
062        pane4.add(amModeGetButton);
063
064        // amModeSetButton
065        amModeSetButton.setToolTipText(Bundle.getMessage("LZ100SetAMModeToolTip"));
066        pane4.add(amModeSetButton);
067        getContentPane().add(pane4);
068
069        JPanel pane3 = new JPanel();
070        pane3.add(new JLabel(Bundle.getMessage("LZ100OptionLabel")));
071
072        // resetCSButton
073        resetCSButton.setToolTipText(Bundle.getMessage("LZ100ResetToolTip"));
074        pane3.add(resetCSButton);
075        getContentPane().add(pane3);
076
077        // add status
078        status.setAlignmentX(java.awt.Component.CENTER_ALIGNMENT);
079        status.setVisible(true);
080        getContentPane().add(status);
081
082        // and prep for display
083        pack();
084
085        // install reset Command Station button handler
086        resetCSButton.addActionListener(a -> {
087            // ask user confirmation
088            if (javax.swing.JOptionPane.OK_OPTION == javax.swing.JOptionPane.showConfirmDialog(
089                    null, Bundle.getMessage("LZ100ConfirmResetDialog"),
090                            Bundle.getMessage("QuestionTitle"),
091                    javax.swing.JOptionPane.OK_CANCEL_OPTION,
092                    javax.swing.JOptionPane.WARNING_MESSAGE)) {
093                // indeed send reset commands
094                resetLZ100CS();
095            }
096        });
097
098        // install Auto/Manual mode retreive button handler.
099        amModeGetButton.addActionListener(a -> amModeGet());
100
101        // install Auto/Manual mode Save button handler.
102        amModeSetButton.addActionListener(a -> amModeSave());
103
104        // install Auto mode button handler.
105        isAutoMode.addActionListener(a -> autoModeAction());
106
107        // install Manual  mode button handler.
108        isManualMode.addActionListener(a -> manualModeAction());
109
110        // configure internal frame options
111        setClosable(false);     // don't let the user close this frame
112        setResizable(false);    // don't let the user resize this frame
113        setIconifiable(false);  // don't let the user minimize this frame
114        setMaximizable(false);  // don't let the user maximize this frame
115
116        // make the internal frame visible
117        this.setVisible(true);
118
119        // Check for XpressNet Connection, add listener if present,
120        //  warn if not.
121        if (tc != null) {
122            tc.addXNetListener(~0, this);
123        } else {
124            log.warn("No XpressNet connection, so panel won't function");
125        }
126    }
127
128    boolean read = false;
129
130    final JLabel status = new JLabel(" ");
131    final JButton resetCSButton = new JButton(Bundle.getMessage("LZ100Reset"));
132    final JRadioButton isAutoMode = new JRadioButton(Bundle.getMessage("Automatic"));
133    final JRadioButton isManualMode = new JRadioButton(Bundle.getMessage("Manual"));
134    final JToggleButton amModeGetButton = new JToggleButton(Bundle.getMessage("LZ100GetAMMode"));
135    final JToggleButton amModeSetButton = new JToggleButton(Bundle.getMessage("LZ100SetAMMode"));
136
137    /**
138     * Listen for responses from the LZ100.
139     */
140    @Override
141    synchronized public void message(XNetReply l) {
142        if (l.isOkMessage()) {
143            /* this was an "OK" message
144             We're only paying attention to it if we're 
145             resetting the command station 
146             */
147            if (status.getText().equals(Bundle.getMessage("LZ100StatusSetMode"))) {
148                status.setText(Bundle.getMessage("StatusOK"));
149            }
150            if (resetMode == OFFSENT) {
151                XNetMessage msgon = XNetMessage.getFunctionGroup1OpsMsg(0, false, false, false, false, true);
152                sendCount--;
153                resetMode = ONSENT;
154                tc.sendXNetMessage(msgon, this);
155            } else if (resetMode == ONSENT) {
156                XNetMessage msgoff = XNetMessage.getFunctionGroup1OpsMsg(0, false, false, false, false, false);
157                if (sendCount >= 0) {
158                    resetMode = OFFSENT;
159                } else {
160                    resetMode = IDLE;
161                    resetCSButton.setEnabled(true);
162                    status.setText(Bundle.getMessage("LZ100ResetFinished"));
163                }
164                tc.sendXNetMessage(msgoff, this);
165            }
166        } else if (l.getElement(0) == XNetConstants.CS_REQUEST_RESPONSE
167                && l.getElement(1) == XNetConstants.CS_STATUS_RESPONSE) {
168            int statusByte = l.getElement(2);
169            if ((statusByte & 0x04) == 0x04) {
170                isAutoMode.setSelected(true);
171                isManualMode.setSelected(false);
172                autoMode = true;
173                status.setText(Bundle.getMessage("StatusOK"));
174            } else {
175                isAutoMode.setSelected(false);
176                isManualMode.setSelected(true);
177                autoMode = false;
178                status.setText(Bundle.getMessage("StatusOK"));
179            }
180        }
181    }
182
183    /**
184     * Listen for the messages to the LI100/LI101.
185     */
186    @Override
187    synchronized public void message(XNetMessage l) {
188    }
189
190    /**
191     * Handle a timeout notification.
192     */
193    @Override
194    public void notifyTimeout(XNetMessage msg) {
195        log.debug("Notified of timeout on message {}", msg.toString());
196    }
197
198    /**
199     * Reset the command station to factory defaults.
200     */
201    synchronized void resetLZ100CS() {
202        resetCSButton.setEnabled(false);
203        status.setText(Bundle.getMessage("LZ100StatusReset"));
204        // the Command station is reset by sending F4 25 times for address 00
205        XNetMessage msgon = XNetMessage.getFunctionGroup1OpsMsg(0, false, false, false, true, false);
206        resetMode = ONSENT;
207        sendCount = 25;
208
209        tc.sendXNetMessage(msgon, this);
210    }
211
212    /**
213     * Get the current automatic/manual mode.
214     */
215    synchronized void amModeGet() {
216        XNetMessage msg = XNetMessage.getCSStatusRequestMessage();
217        tc.sendXNetMessage(msg, this);
218        amModeGetButton.setSelected(false);
219        status.setText(Bundle.getMessage("LZ100StatusRetrieveMode"));
220    }
221
222    /**
223     * Set the current automatic/manual mode.
224     */
225    synchronized void amModeSave() {
226        if (autoMode) {
227            log.debug("Auto Mode True");
228        } else {
229            log.debug("Auto Mode False");
230        }
231        XNetMessage msg = XNetMessage.getCSAutoStartMessage(autoMode);
232        tc.sendXNetMessage(msg, this);
233        amModeSetButton.setSelected(false);
234        status.setText(Bundle.getMessage("LZ100StatusSetMode"));
235    }
236
237    /**
238     * Toggle Auto Power-up Mode.
239     */
240    synchronized void autoModeAction() {
241        log.debug("Auto Mode Action Called");
242        isAutoMode.setSelected(true);
243        isManualMode.setSelected(false);
244        autoMode = true;
245    }
246
247    /**
248     * Toggle Manual Power-up Mode.
249     */
250    synchronized void manualModeAction() {
251        log.debug("Manual Mode Action Called");
252        isAutoMode.setSelected(false);
253        isManualMode.setSelected(true);
254        autoMode = false;
255    }
256
257    private static final Logger log = LoggerFactory.getLogger(LZ100InternalFrame.class);
258
259}