001package jmri.jmrit.logix;
002
003import java.awt.Font;
004
005import javax.swing.Box;
006import javax.swing.BoxLayout;
007import javax.swing.JInternalFrame;
008import javax.swing.JLabel;
009import javax.swing.JPanel;
010import javax.swing.WindowConstants;
011
012import org.slf4j.Logger;
013import org.slf4j.LoggerFactory;
014
015import jmri.DccThrottle;
016import jmri.Throttle;
017import jmri.implementation.SignalSpeedMap;
018
019/**
020 * A JInternalFrame that contains a JSlider to control loco speed, and buttons
021 * for forward, reverse and STOP.
022 *
023 * @author Pete Cressman Copyright 2020
024 */
025public class LearnSpeedPanel extends JInternalFrame implements java.beans.PropertyChangeListener {
026
027    private Warrant _warrant;
028    private JLabel _scaleSpeed;
029    private JLabel _direction;
030
031    LearnSpeedPanel(Warrant w) {
032        _warrant = w;
033        initGUI();
034    }
035
036    private void initGUI() {
037        JPanel mainPanel = new JPanel();
038        this.setContentPane(mainPanel);
039        this.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
040
041        JPanel panel = new JPanel();
042        panel.setFont(new Font("", Font.PLAIN, 32));
043        panel.setLayout(new BoxLayout(panel, BoxLayout.X_AXIS));
044        panel.setOpaque(false);
045        OBlock blk = _warrant.getBlockAt(0);
046        String name;
047        if (blk != null) {
048            name = blk.getDisplayName();
049        } else {
050            name = _warrant.getDisplayName();
051        }
052        _direction = new JLabel(Bundle.getMessage("forward"));
053        panel.add(_direction);
054        panel.add(Box.createHorizontalStrut(WarrantRoute.STRUT_SIZE));
055        _scaleSpeed = new JLabel(Bundle.getMessage("TrainReady", _warrant.getTrainName(), name));
056        panel.add(_scaleSpeed);
057
058        mainPanel.add(panel);
059    }
060
061    public void notifyAddressThrottleFound(DccThrottle throttle) {
062        _warrant.getSpeedUtil().setThrottle(throttle);
063
064        throttle.addPropertyChangeListener(this);
065        _scaleSpeed.setText(setSpeed(throttle.getSpeedSetting()));
066        if (log.isDebugEnabled()) {
067            jmri.DccLocoAddress Address = (jmri.DccLocoAddress) throttle.getLocoAddress();
068            log.debug("new address is {}", Address.toString());
069        }
070        setSpeed(0);
071    }
072
073    /**
074     * update the state of this panel if direction or speed change
075     */
076    @Override
077    public void propertyChange(java.beans.PropertyChangeEvent e) {
078        if (e.getPropertyName().equals(Throttle.SPEEDSETTING)) {
079            _scaleSpeed.setText(setSpeed(((Float) e.getNewValue()).floatValue()));
080        } else if (e.getPropertyName().equals(Throttle.ISFORWARD)) {
081            String direction;
082            if ((Boolean)e.getNewValue()) {
083                direction = Bundle.getMessage("forward");
084            } else {
085                direction = Bundle.getMessage("reverse");
086            }
087            _direction.setText(direction);
088        }
089        if (log.isDebugEnabled()) {
090            log.debug("Property change event received {} / {}", e.getPropertyName(), e.getNewValue());
091        }
092    }
093
094    /**
095     * @return a string for displaying speed if available
096     */
097    private String setSpeed(float throttleValue) {
098        float trackSpeed = _warrant.getSpeedUtil().getTrackSpeed(throttleValue);
099        float speed = 0;
100        String units;
101        SignalSpeedMap speedMap = jmri.InstanceManager.getDefault(SignalSpeedMap.class);
102        switch (speedMap.getInterpretation()) {
103            case SignalSpeedMap.PERCENT_NORMAL:
104            case SignalSpeedMap.PERCENT_THROTTLE:
105                units = Bundle.getMessage("percentThrottle");
106                speed = throttleValue * 100;
107                break;
108            case SignalSpeedMap.SPEED_MPH:
109                units = Bundle.getMessage("speedMph");
110                speed = trackSpeed * speedMap.getLayoutScale() * 2.2369363f;
111                break;
112            case SignalSpeedMap.SPEED_KMPH:
113                units = Bundle.getMessage("speedKmph");
114                speed = trackSpeed * speedMap.getLayoutScale() * 3.6f;
115                break;
116            default:
117                units = "Error";
118                log.error("Unknown speed interpretation {}", speedMap.getInterpretation());
119        }
120        return Bundle.getMessage("atSpeed", 
121                Bundle.getMessage("speedmm", Math.round(trackSpeed*1000)),
122                Math.round(speed), units);
123    }
124
125    /**
126     * "Destructor"
127     */
128    public void destroy() {
129        DccThrottle throttle = _warrant.getSpeedUtil().getThrottle();
130        if (throttle != null) {
131            throttle.removePropertyChangeListener(this);
132            if (log.isDebugEnabled()) {
133                jmri.DccLocoAddress Address = (jmri.DccLocoAddress) throttle.getLocoAddress();
134                log.debug("Address {} destroyed", Address.toString());
135            }
136//            _throttle = null;
137        }
138    }
139    
140
141    private static final Logger log = LoggerFactory.getLogger(LearnSpeedPanel.class);
142}