001package jmri.jmrix.bidib;
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 BiDiB
011 * systems
012 *
013 * @see jmri.GlobalProgrammerManager
014 * @author Bob Jacobsen Copyright (C) 2002, 2016
015 * @author Eckart Meyer Copyright (C) 2019
016 */
017public class BiDiBProgrammerManager extends DefaultProgrammerManager {
018
019    BiDiBTrafficController tc;
020    BiDiBSystemConnectionMemo memo;
021
022    public BiDiBProgrammerManager(@Nonnull BiDiBSystemConnectionMemo memo) {
023        super(
024                checkGlobalProgrammerAvailable(memo.getBiDiBTrafficController())
025                ? new BiDiBProgrammer(memo.getBiDiBTrafficController())
026                : null,
027                memo);
028        this.tc = memo.getBiDiBTrafficController();
029        this.memo = memo;
030        log.trace("BiDiBProgrammerManager({}) with {}", memo,
031                checkGlobalProgrammerAvailable(memo.getBiDiBTrafficController()));
032        Objects.requireNonNull(memo, "require BiDiBSystemConnectionMemo");
033    }
034
035    /**
036     * {@inheritDoc}
037     *
038     * @return true if selected BiDiB hardware and connection type support Ops
039     *         Mode
040     */
041    @Override
042    public boolean isAddressedModePossible() {
043//        Objects.requireNonNull(tc, "require BiDiBTrafficController");
044        Objects.requireNonNull(memo, "require BiDiBSystemConnectionMemo");
045
046        return (tc.getFirstCommandStationNode() != null);
047    }
048
049    /**
050     * {@inheritDoc}
051     *
052     * @return true if selected BiDiB hardware and connection type support Service
053     *         Mode
054     */
055    @Override
056    public boolean isGlobalProgrammerAvailable() {
057        Objects.requireNonNull(tc, "require BiDiBTrafficController");
058        return checkGlobalProgrammerAvailable(tc);
059    }
060
061    // this centralizes the isGlobalProgrammerAvailable logic.  It
062    // has to be static so it can be called during the construction of
063    // an object of this class
064    static private boolean checkGlobalProgrammerAvailable(@Nonnull BiDiBTrafficController tc) {
065        return (tc.getCurrentGlobalProgrammerNode() != null);
066    }
067
068    /**
069     * {@inheritDoc}
070     */
071    @Override
072    public Programmer getGlobalProgrammer() {
073        if (!isGlobalProgrammerAvailable()) {
074            return null;
075        }
076        return super.getGlobalProgrammer();
077    }
078
079    /**
080     * {@inheritDoc}
081     */
082    @Override
083    public AddressedProgrammer getAddressedProgrammer(boolean pLongAddress, int pAddress) {
084        return new BiDiBOpsModeProgrammer(pAddress, tc);
085    }
086
087    /**
088     * {@inheritDoc}
089     */
090    @Override
091    public AddressedProgrammer reserveAddressedProgrammer(boolean pLongAddress, int pAddress) {
092        return null; //what is this??
093    }
094
095    /**
096     * {@inheritDoc}
097     */
098    @Override
099    public void releaseGlobalProgrammer(@Nonnull Programmer p) {
100        log.debug("release global programmer: {}", p);
101    }
102
103    /**
104     * {@inheritDoc}
105     */
106    @Override
107    public void releaseAddressedProgrammer(@Nonnull AddressedProgrammer p) {
108        log.debug("release addressed programmer: {}", p);
109    }
110
111    private final static org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(BiDiBProgrammerManager.class);
112}