001package jmri.jmrix.srcp;
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 * SRCP implementation of a ThrottleManager.
013 * <p>
014 * Based on early NCE code.
015 *
016 * @author Bob Jacobsen Copyright (C) 2001, 2005, 2008
017 * @author Modified by Kelly Loyd
018 */
019public class SRCPThrottleManager extends AbstractThrottleManager {
020
021    private int bus;
022
023    /**
024     * Constructor.
025     * @param memo system connection.
026     */
027    public SRCPThrottleManager(SRCPBusConnectionMemo memo) {
028        super(memo);
029        bus = memo.getBus();
030    }
031
032    @Override
033    public void requestThrottleSetup(LocoAddress address, boolean control) {
034        log.debug("new SRCPThrottle for {}", address);
035        // Notify ready to go (without waiting for OK?)
036        if (address instanceof DccLocoAddress) {
037           notifyThrottleKnown(new SRCPThrottle((SRCPBusConnectionMemo) adapterMemo, (DccLocoAddress) address), address);
038        } else { 
039          // we need to notify that the request failed, because the
040          // address is not a DccLocoAddress, but that notification also
041          // requires a DccLocoAddress.
042          throw new java.lang.IllegalArgumentException("Request for throttle for unsupported non-DCC address.");          
043        }
044    }
045
046    // KSL 20040409 - SRCP does not have a 'dispatch' function.
047    @Override
048    public boolean hasDispatchFunction() {
049        return false;
050    }
051
052    /**
053     * Address 100 and above is a long address
054     *
055     */
056    @Override
057    public boolean canBeLongAddress(int address) {
058        return isLongAddress(address);
059    }
060
061    /**
062     * Address 99 and below is a short address
063     *
064     */
065    @Override
066    public boolean canBeShortAddress(int address) {
067        return !isLongAddress(address);
068    }
069
070    /**
071     * Are there any ambiguous addresses (short vs long) on this system?
072     */
073    @Override
074    public boolean addressTypeUnique() {
075        return true;
076    }
077
078    /*
079     * Local method for deciding short/long address
080     */
081    static boolean isLongAddress(int num) {
082        return (num >= 100);
083    }
084
085    @Override
086    public EnumSet<SpeedStepMode> supportedSpeedModes() {
087        return EnumSet.of(SpeedStepMode.NMRA_DCC_128, SpeedStepMode.NMRA_DCC_28,
088            SpeedStepMode.NMRA_DCC_27, SpeedStepMode.NMRA_DCC_14);
089    }
090
091    @Override
092    public boolean disposeThrottle(jmri.DccThrottle t, jmri.ThrottleListener l) {
093        if (super.disposeThrottle(t, l)) {
094            // Form a message to release the loco
095            DccLocoAddress la = (DccLocoAddress) t.getLocoAddress();
096            String msg = "TERM " + bus + " GL "
097                    + (la.getNumber())
098                    + "\n";
099
100            // and send it
101            ((SRCPBusConnectionMemo) adapterMemo).getTrafficController().sendSRCPMessage(new SRCPMessage(msg), null);
102            return true;
103        }
104        return false;
105    }
106
107    private final static Logger log = LoggerFactory.getLogger(SRCPThrottleManager.class);
108
109}