001package jmri.jmrit.logix;
002
003import java.awt.BorderLayout;
004import java.awt.Font;
005
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 DccThrottle _throttle;
029    private float _currentThrottleValue = 0.0f;
030    private JLabel _scaleSpeed;
031
032    LearnSpeedPanel(Warrant w) {
033        _warrant = w;
034        initGUI();
035    }
036
037    private void initGUI() {
038        JPanel mainPanel = new JPanel();
039        this.setContentPane(mainPanel);
040        mainPanel.setLayout(new BorderLayout());
041        this.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
042
043        JPanel panel = new JPanel();
044        panel.setFont(new Font("", Font.PLAIN, 32));
045        panel.setLayout(new BoxLayout(panel, BoxLayout.X_AXIS));
046        panel.setOpaque(false);
047        OBlock blk = _warrant.getBlockAt(0);
048        String name;
049        if (blk != null) {
050            name = blk.getDisplayName();
051        } else {
052            name = _warrant.getDisplayName();
053        }
054        _scaleSpeed = new JLabel(Bundle.getMessage("TrainReady", _warrant.getTrainName(), name));
055        panel.add(_scaleSpeed);
056
057        mainPanel.add(panel, BorderLayout.CENTER);
058    }
059
060    public void notifyAddressThrottleFound(DccThrottle t) {
061        if (log.isDebugEnabled()) {
062            log.debug("control panel received new throttle");
063        }
064        _throttle = t;
065        _warrant.getSpeedUtil().setIsForward(_throttle.getIsForward());
066
067        _throttle.addPropertyChangeListener(this);
068        if (log.isDebugEnabled()) {
069            jmri.DccLocoAddress Address = (jmri.DccLocoAddress) _throttle.getLocoAddress();
070            log.debug("new address is {}", Address.toString());
071        }
072    }
073
074    /**
075     * update the state of this panel if direction or speed change
076     */
077    @Override
078    public void propertyChange(java.beans.PropertyChangeEvent e) {
079        if (e.getPropertyName().equals(Throttle.SPEEDSETTING)) {
080            _currentThrottleValue = ((Float) e.getNewValue()).floatValue();
081            _scaleSpeed.setText(setSpeed());
082        } else if (e.getPropertyName().equals(Throttle.ISFORWARD)) {
083            _warrant.getSpeedUtil().setIsForward((boolean) e.getNewValue());
084            _scaleSpeed.setText(setSpeed());
085        }
086        if (log.isDebugEnabled()) {
087            log.debug("Property change event received {} / {}", e.getPropertyName(), e.getNewValue());
088        }
089    }
090
091    /**
092     * @return a string for displaying speed if available
093     */
094    private String setSpeed() {
095        float trackSpeed = _warrant.getSpeedUtil().getTrackSpeed(_currentThrottleValue);
096        float speed = 0;
097        String units;
098        SignalSpeedMap speedMap = jmri.InstanceManager.getDefault(SignalSpeedMap.class);
099        switch (speedMap.getInterpretation()) {
100            case SignalSpeedMap.PERCENT_NORMAL:
101            case SignalSpeedMap.PERCENT_THROTTLE:
102                units = Bundle.getMessage("percentThrottle");
103                speed = _currentThrottleValue * 100;
104                break;
105            case SignalSpeedMap.SPEED_MPH:
106                units = Bundle.getMessage("speedMph");
107                speed = trackSpeed * speedMap.getLayoutScale() * 2.2369363f;
108                break;
109            case SignalSpeedMap.SPEED_KMPH:
110                units = Bundle.getMessage("speedKmph");
111                speed = trackSpeed * speedMap.getLayoutScale() * 3.6f;
112                break;
113            default:
114                units = "Error";
115                log.error("Unknown speed interpretation {}", speedMap.getInterpretation());
116        }
117        return Bundle.getMessage("atSpeed", 
118                Bundle.getMessage("speedmm", Math.round(trackSpeed*1000)),
119                Math.round(speed), units);
120    }
121
122    /**
123     * "Destructor"
124     */
125    public void destroy() {
126        if (_throttle != null) {
127            _throttle.removePropertyChangeListener(this);
128            if (log.isDebugEnabled()) {
129                jmri.DccLocoAddress Address = (jmri.DccLocoAddress) _throttle.getLocoAddress();
130                log.debug("Address {} destroyed", Address.toString());
131            }
132            _throttle = null;
133        }
134    }
135    
136
137    private static final Logger log = LoggerFactory.getLogger(LearnSpeedPanel.class);
138}