001package jmri.jmrix.sprog;
002
003import java.util.EnumSet;
004import jmri.DccLocoAddress;
005import jmri.LocoAddress;
006import jmri.SpeedStepMode;
007import jmri.jmrix.AbstractThrottleManager;
008import org.slf4j.Logger;
009import org.slf4j.LoggerFactory;
010
011/**
012 * SPROG implementation of a ThrottleManager.
013 * <p>
014 * Updated by Andrew Crosland February 2012 to enable 28 step speed packets
015 *
016 * @author Bob Jacobsen Copyright (C) 2001
017 */
018public class SprogThrottleManager extends AbstractThrottleManager {
019
020    /**
021     * Constructor.
022     * @param memo system connection.
023     */
024    public SprogThrottleManager(SprogSystemConnectionMemo memo) {
025        super(memo);
026    }
027
028    boolean throttleInUse = false;
029
030    void release() {
031        throttleInUse = false;
032    }
033
034    @Override
035    public void requestThrottleSetup(LocoAddress a, boolean control) {
036        
037        if (!(a instanceof DccLocoAddress)) {
038            log.error("{} is not a DccLocoAddress",a);
039            failedThrottleRequest(a, "LocoAddress " +a+ " is not a DccLocoAddress");
040            return;
041        }
042        
043        // The SPROG protocol doesn't require an interaction with the command
044        // station for this, so set the address and immediately trigger the callback
045        // if a throttle is not in use.
046            DccLocoAddress address = (DccLocoAddress) a;
047        if (!throttleInUse) {
048            throttleInUse = true;
049            log.debug("new SprogThrottle for {}", address);
050            String addr = "" + address.getNumber() + ( address.isLongAddress() ? " 0" : "");
051            SprogMessage m = new SprogMessage(2 + addr.length());
052            int i = 0;
053            m.setElement(i++, 'A');
054            m.setElement(i++, ' ');
055            for (int j = 0; j < addr.length(); j++) {
056                m.setElement(i++, addr.charAt(j));
057            }
058            ((SprogSystemConnectionMemo) adapterMemo).getSprogTrafficController().sendSprogMessage(m, null);
059            notifyThrottleKnown(new SprogThrottle((SprogSystemConnectionMemo) adapterMemo, address), address);
060        } else {
061            failedThrottleRequest(address, "Only one Throttle can be in use at anyone time with the Sprog.");
062            //javax.swing.JOptionPane.showMessageDialog(null, "Only one Throttle can be in use at anyone time with the Sprog.", "Sprog Throttle", javax.swing.JOptionPane.WARNING_MESSAGE);
063            log.warn("Single SPROG Throttle already in use");
064        }
065    }
066
067    /**
068     * What speed modes are supported by this system? Value should be one of
069     * possible modes specified by the DccThrottle interface.
070     */
071    @Override
072    public EnumSet<SpeedStepMode> supportedSpeedModes() {
073        return EnumSet.of(SpeedStepMode.NMRA_DCC_128, SpeedStepMode.NMRA_DCC_28);
074    }
075
076    /**
077     * Addresses 0-10239 can be long.
078     */
079    @Override
080    public boolean canBeLongAddress(int address) {
081        return ((address >= 0) && (address <= 10239));
082    }
083
084    /**
085     * The short addresses 1-127 are available.
086     */
087    @Override
088    public boolean canBeShortAddress(int address) {
089        return ((address >= 1) && (address <= 127));
090    }
091
092    /**
093     * Are there any ambiguous addresses (short vs long) on this system?
094     */
095    @Override
096    public boolean addressTypeUnique() {
097        return false;
098    }
099
100    @Override
101    public boolean disposeThrottle(jmri.DccThrottle t, jmri.ThrottleListener l) {
102        if (super.disposeThrottle(t, l)) {
103            throttleInUse = false;
104            return true;
105        }
106        return false;
107    }
108
109    private final static Logger log = LoggerFactory.getLogger(SprogThrottleManager.class);
110
111}