001package jmri.jmrix.loconet;
002
003import jmri.DccLocoAddress;
004import jmri.LocoAddress;
005import jmri.jmrix.AbstractThrottleManager;
006import org.slf4j.Logger;
007import org.slf4j.LoggerFactory;
008
009/**
010 * LocoNet implementation of a ThrottleManager for the PR2.
011 * <p>
012 * Does direct "push" writes to the extended slot in the PR2.
013 * <p>
014 * The PR2 only allows a single locomotive address to be active, because it
015 * implements a single-slot command station.
016 *
017 * @see AbstractThrottleManager
018 * @author Bob Jacobsen Copyright (C) 2001, 2006
019 */
020public class LnPr2ThrottleManager extends AbstractThrottleManager {
021
022    /**
023     * Constructor, works via superclass.
024     * @param memo the LocoNetSystemConnectionMemo
025     */
026    public LnPr2ThrottleManager(LocoNetSystemConnectionMemo memo) {
027        super(memo);
028    }
029
030    /**
031     * PR2 allows only one throttle
032     * <p>
033     * {@inheritDoc}
034     */
035    @Override
036    protected boolean singleUse() {
037        return true;
038    }
039
040    /**
041     * Get a new Throttle object.
042     *
043     * This immediately invokes the callback with the a new throttle object.
044     */
045    @Override
046    public void requestThrottleSetup(LocoAddress address, boolean control) {
047        // The PR2 has only one slot, hence
048        // doesn't require an interaction with the command
049        // station to allocate slot, so immediately trigger the callback.
050        if (address instanceof DccLocoAddress) {
051            activeAddress = (DccLocoAddress) address;
052        } else {
053            log.error("cannot cast the passed address to DccLocoAddress.");
054        }
055        log.debug("new Pr2Throttle for {}", activeAddress);
056        notifyThrottleKnown(new Pr2Throttle((LocoNetSystemConnectionMemo) adapterMemo, activeAddress), activeAddress);
057    }
058
059    DccLocoAddress activeAddress = null;
060
061    /**
062     * PR2 does not have a Dispatch function
063     *
064     */
065    @Override
066    public boolean hasDispatchFunction() {
067        return false;
068    }
069
070    /**
071     * Address 128 and above is a long address
072     *
073     */
074    @Override
075    public boolean canBeLongAddress(int address) {
076        return isLongAddress(address);
077    }
078
079    /**
080     * Address 127 and below is a short address
081     *
082     */
083    @Override
084    public boolean canBeShortAddress(int address) {
085        return !isLongAddress(address);
086    }
087
088    /**
089     * Are there any ambiguous addresses (short vs long) on this system?
090     */
091    @Override
092    public boolean addressTypeUnique() {
093        return true;
094    }
095
096    /*
097     * Local method for deciding short/long address
098     */
099    static boolean isLongAddress(int num) {
100        return (num >= 128);
101    }
102
103    /**
104     * Make the active address available to the power manager, which needs it to
105     * turn on and off "neutral mode" in the locomotive
106     * @return a DccLocoAddress
107     */
108    public DccLocoAddress getActiveAddress() {
109        return activeAddress;
110    }
111
112    // initialize logging
113    private final static Logger log = LoggerFactory.getLogger(LnPr2ThrottleManager.class);
114}