001package jmri.jmrix.ecos;
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 * EcosDCC implementation of a ThrottleManager.
013 * <p>
014 * Based on early NCE code.
015 *
016 * @author Bob Jacobsen Copyright (C) 2001, 2005
017 * @author Modified by Kevin Dickerson
018 */
019public class EcosDccThrottleManager extends AbstractThrottleManager implements EcosListener {
020
021    /**
022     * Constructor.
023     * @param memo system connection.
024     */
025    public EcosDccThrottleManager(EcosSystemConnectionMemo memo) {
026        super(memo);
027    }
028
029    @Override
030    public void reply(EcosReply m) {
031        //We are not sending commands from here yet!
032    }
033
034    @Override
035    public void message(EcosMessage m) {
036        // messages are ignored
037    }
038
039    @Override
040    public void requestThrottleSetup(LocoAddress address, boolean control) {
041        /*Here we do not set notifythrottle, we simply create a new ecos throttle.
042         The ecos throttle in turn will notify the throttle manager of a successful or
043         unsuccessful throttle connection. */
044        if ( address instanceof DccLocoAddress ) {
045            log.debug("new EcosDccThrottle for {}", address);
046            new EcosDccThrottle((DccLocoAddress) address, (EcosSystemConnectionMemo) adapterMemo, control);
047        }
048        else {
049            log.error("{} is not an DccLocoAddress",address);
050            failedThrottleRequest(address, "LocoAddress " +address+ " is not a DccLocoAddress");
051        }
052    }
053
054    @Override
055    public boolean hasDispatchFunction() {
056        return false;
057    }
058
059    /**
060     * Address 100 and above is a long address
061     */
062    @Override
063    public boolean canBeLongAddress(int address) {
064        return isLongAddress(address);
065    }
066
067    /**
068     * Address 99 and below is a short address
069     */
070    @Override
071    public boolean canBeShortAddress(int address) {
072        return !isLongAddress(address);
073    }
074
075    /**
076     * Are there any ambiguous addresses (short vs. long) on this system?
077     */
078    @Override
079    public boolean addressTypeUnique() {
080        return false;
081    }
082
083    @Override
084    public String[] getAddressTypes() {
085        return new String[]{
086            LocoAddress.Protocol.DCC.getPeopleName(),
087            LocoAddress.Protocol.MFX.getPeopleName(),
088            LocoAddress.Protocol.MOTOROLA.getPeopleName(),
089            LocoAddress.Protocol.SELECTRIX.getPeopleName(),
090            LocoAddress.Protocol.LGB.getPeopleName()};
091    }
092
093    @Override
094    public LocoAddress.Protocol[] getAddressProtocolTypes() {
095        return new LocoAddress.Protocol[]{
096            LocoAddress.Protocol.DCC,
097            LocoAddress.Protocol.MFX,
098            LocoAddress.Protocol.MOTOROLA,
099            LocoAddress.Protocol.SELECTRIX,
100            LocoAddress.Protocol.LGB};
101    }
102
103
104    /*
105     * Decide whether given a long address or not.
106     */
107    static boolean isLongAddress(int num) {
108        return (num >= 127);
109    }
110
111    @Override
112    public EnumSet<SpeedStepMode> supportedSpeedModes() {
113        return EnumSet.of(SpeedStepMode.NMRA_DCC_128, SpeedStepMode.NMRA_DCC_28, SpeedStepMode.NMRA_DCC_14);
114    }
115
116    public void throttleSetup(EcosDccThrottle throttle, LocoAddress address, boolean result) {
117        /* this is called by the ecosdccthrottle, to inform the manager if it has successfully gained
118         control of a loco, when setting up the throttle.*/
119        if (result) {
120            log.debug("Ecos Throttle has control over loco {}", address);
121            notifyThrottleKnown(throttle, address);
122        } else {
123            log.debug("Ecos Throttle has NO control over loco {}", address);
124            failedThrottleRequest(address, "Loco is alredy in use by anoher throttle " + address);
125        }
126    }
127
128    @Override
129    public boolean disposeThrottle(jmri.DccThrottle t, jmri.ThrottleListener l) {
130        if (super.disposeThrottle(t, l)) {
131            if ( t instanceof EcosDccThrottle ) {
132                EcosDccThrottle lnt = (EcosDccThrottle) t;
133                lnt.throttleDispose();
134                return true;
135            }
136            else {
137                log.error("{} is not an EcosDccThrottle",t);
138            }
139        }
140        return false;
141    }
142
143    private final static Logger log = LoggerFactory.getLogger(EcosDccThrottleManager.class);
144
145}