001package jmri.jmrix.bachrus.speedmatcher.basic;
002
003import jmri.jmrix.bachrus.Speed;
004import jmri.jmrix.bachrus.speedmatcher.SpeedMatcher;
005
006/**
007 * Abstract class defining the basic operations of a Basic speed matcher (sets a
008 * minimum speed at speed step 1, a maximum at speed step 28, and some number of
009 * points in between). All basic speed matcher implementations must extend this
010 * class.
011 *
012 * @author Todd Wegter Copyright (C) 2024
013 */
014public abstract class BasicSpeedMatcher extends SpeedMatcher {
015
016    //<editor-fold defaultstate="collapsed" desc="Instance Variables">
017    protected float targetStartSpeedKPH;
018    protected float targetTopSpeedKPH;
019    //</editor-fold>
020
021    /**
022     * Constructs the abstract BasicSpeedMatcher at the core of any Basic Speed
023     * Matcher
024     *
025     * @param config BasicSpeedMatcherConfig
026     */
027    public BasicSpeedMatcher(BasicSpeedMatcherConfig config) {
028        super(config);
029
030        if (config.speedUnit == Speed.Unit.MPH) {
031            this.targetStartSpeedKPH = Speed.mphToKph(config.targetStartSpeed);
032            this.targetTopSpeedKPH = Speed.mphToKph(config.targetTopSpeed);
033        } else {
034            this.targetStartSpeedKPH = config.targetStartSpeed;
035            this.targetTopSpeedKPH = config.targetTopSpeed;
036        }
037    }
038
039    //<editor-fold defaultstate="collapsed" desc="Protected APIs">
040    /**
041     * Validates the speed matcher's configuration
042     *
043     * @return true if the configuration is valid, false otherwise
044     */
045    @Override
046    protected boolean validate() {
047        if (dccLocoAddress.getNumber() <= 0) {
048            statusLabel.setText(Bundle.getMessage("StatInvalidDCCAddress"));
049            return false;
050        }
051
052        if (targetStartSpeedKPH < 1) {
053            statusLabel.setText(Bundle.getMessage("StatInvalidStartSpeed"));
054            return false;
055        }
056
057        if (targetTopSpeedKPH <= targetStartSpeedKPH) {
058            statusLabel.setText(Bundle.getMessage("StatInvalidTopSpeed"));
059            return false;
060        }
061
062        return true;
063    }
064
065    /**
066     * Gets the desired speed for a given speed step
067     *
068     * @param speedStep the SpeedTableStep to get the speed for
069     * @param minSpeed  minimum speed in KPH (at speed step 1)
070     * @param maxSpeed  maximum speed in KPH (at speed step 28)
071     * @return the speed for the given speed step in KPH
072     */
073    protected float getSpeedForSpeedStep(SpeedTableStep speedStep, float minSpeed, float maxSpeed) {
074        return minSpeed + (((maxSpeed - minSpeed) / 27) * (speedStep.getSpeedStep() - 1));
075    }
076    //</editor-fold>
077}