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