001package jmri.jmrix.nce;
002
003import java.util.Objects;
004import javax.annotation.Nonnull;
005import jmri.AddressedProgrammer;
006import jmri.Programmer;
007import jmri.managers.DefaultProgrammerManager;
008
009/**
010 * Extend DefaultProgrammerManager to provide ops mode programmers for NCE
011 * systems.
012 *
013 * @see jmri.GlobalProgrammerManager
014 * @author Bob Jacobsen Copyright (C) 2002, 2016
015 * @author Ken Cameron Copyright (C) 2013
016 */
017public class NceProgrammerManager extends DefaultProgrammerManager {
018
019    NceTrafficController tc;
020    NceSystemConnectionMemo memo;
021
022    public NceProgrammerManager(@Nonnull NceSystemConnectionMemo memo) {
023        super(
024                checkGlobalProgrammerAvailable(memo.getNceTrafficController())
025                ? new NceProgrammer(memo.getNceTrafficController())
026                : null,
027                memo);
028        this.tc = memo.getNceTrafficController();
029        this.memo = memo;
030        log.trace("NceProgrammerManager({}) with {}", memo,
031                checkGlobalProgrammerAvailable(memo.getNceTrafficController()));
032        Objects.requireNonNull(memo, "require NceSystemConnectionMemo");
033    }
034
035    /**
036     * {@inheritDoc}
037     *
038     * @return true if selected NCE hardware and connection type support Ops
039     *         Mode
040     */
041    @Override
042    public boolean isAddressedModePossible() {
043        Objects.requireNonNull(tc, "require NceTrafficController");
044        Objects.requireNonNull(memo, "require NceSystemConnectionMemo");
045
046        switch (memo.getNceUsbSystem()) {
047            case NceTrafficController.USB_SYSTEM_POWERPRO:
048                log.trace("isAddressedModePossible returns false");
049                return false;
050            default:
051                log.trace("isAddressedModePossible returns true");
052                return true;
053        }
054    }
055
056    /**
057     * {@inheritDoc}
058     *
059     * @return true if selected NCE hardware and connection type support Service
060     *         Mode
061     */
062    @Override
063    public boolean isGlobalProgrammerAvailable() {
064        Objects.requireNonNull(tc, "require NceTrafficController");
065        return checkGlobalProgrammerAvailable(tc);
066    }
067
068    // this centralizes the isGlobalProgrammerAvailable logic.  It
069    // has to be static so it can be called during the construction of
070    // an object of this class
071    static private boolean checkGlobalProgrammerAvailable(@Nonnull NceTrafficController tc) {
072        switch (tc.getUsbSystem()) {
073            case NceTrafficController.USB_SYSTEM_NONE: // Serial or Simulator
074            case NceTrafficController.USB_SYSTEM_POWERCAB:
075            case NceTrafficController.USB_SYSTEM_TWIN:
076                log.trace("checkGlobalProgrammerAvailable returns true");
077                return true;
078            default:
079                log.trace("checkGlobalProgrammerAvailable returns false");
080                return false;
081        }
082    }
083
084    /**
085     * {@inheritDoc}
086     * <p>
087     * Note: The NCE service mode programmer might exist, but not be able to
088     * function. Not a great situation, but there it is. We therefore check
089     * before returning it.
090     */
091    @Override
092    public Programmer getGlobalProgrammer() {
093        if (!isGlobalProgrammerAvailable()) {
094            return null;
095        }
096        return super.getGlobalProgrammer();
097    }
098
099    /**
100     * {@inheritDoc}
101     */
102    @Override
103    public AddressedProgrammer getAddressedProgrammer(boolean pLongAddress, int pAddress) {
104        return new NceOpsModeProgrammer(tc, pAddress, pLongAddress);
105    }
106
107    /**
108     * {@inheritDoc}
109     */
110    @Override
111    public AddressedProgrammer reserveAddressedProgrammer(boolean pLongAddress, int pAddress) {
112        return null;
113    }
114
115    private final static org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(NceProgrammerManager.class);
116
117}