001package jmri.jmrix.acela;
002
003import java.util.Locale;
004import javax.annotation.Nonnull;
005import jmri.Turnout;
006import jmri.managers.AbstractTurnoutManager;
007import org.slf4j.Logger;
008import org.slf4j.LoggerFactory;
009
010/**
011 * Implement turnout manager for Acela systems.
012 * <p>
013 * System names are "ATnnn", where A is the user configurable system prefix,
014 * nnn is the bit number without padding.
015 *
016 * @author Dave Duchamp Copyright (C) 2004
017 * @author Bob Coleman Copyright (C) 2008 Based on CMRI serial example, modified
018 * to establish Acela support.
019 */
020public class AcelaTurnoutManager extends AbstractTurnoutManager {
021
022    public AcelaTurnoutManager(AcelaSystemConnectionMemo memo) {
023       super(memo);
024    }
025
026    /**
027     * {@inheritDoc}
028     */
029    @Override
030    @Nonnull
031    public AcelaSystemConnectionMemo getMemo() {
032        return (AcelaSystemConnectionMemo) memo;
033    }
034
035    /**
036     * Method to create a new Turnout based on the system name.
037     * <p>
038     * Assumes calling method has checked that a Turnout with this
039     * system name does not already exist.
040     * {@inheritDoc}
041     */
042    @Nonnull
043    @Override
044    protected Turnout createNewTurnout(@Nonnull String systemName, String userName) throws IllegalArgumentException {
045        Turnout trn = null;
046        // check if the output bit is available
047        int nAddress = AcelaAddress.getNodeAddressFromSystemName(systemName, getMemo());
048        if (nAddress == -1) {
049            throw new IllegalArgumentException("Cannot get Node Address from System Name " + systemName);
050        }
051        int bitNum = AcelaAddress.getBitFromSystemName(systemName, getSystemPrefix());
052        if (bitNum == -1) {
053            throw new IllegalArgumentException("Cannot get Bit Number from System Name " + systemName);
054        }
055
056        // Validate the systemName
057        if (AcelaAddress.validSystemNameFormat(systemName, 'T', getSystemPrefix()) == NameValidity.VALID) {
058            trn = new AcelaTurnout(systemName, userName, getMemo());
059            if (!AcelaAddress.validSystemNameConfig(systemName, 'T', getMemo())) {
060                log.warn("Turnout System Name does not refer to configured hardware: {}", systemName);
061            }
062        } else {
063            log.error("Invalid Turnout system Name format: {}", systemName);
064            throw new IllegalArgumentException("Invalid Turnout System Name format: " + systemName);
065        }
066        return trn;
067    }
068
069    /**
070     * {@inheritDoc}
071     * <p>
072     * Verifies system name has valid prefix and is an integer from
073     * {@value AcelaAddress#MINOUTPUTADDRESS} to
074     * {@value AcelaAddress#MAXOUTPUTADDRESS}.
075     */
076    @Override
077    @Nonnull
078    public String validateSystemNameFormat(@Nonnull String systemName, @Nonnull Locale locale) {
079        return super.validateIntegerSystemNameFormat(systemName,
080                AcelaAddress.MINOUTPUTADDRESS,
081                AcelaAddress.MAXOUTPUTADDRESS,
082                locale);
083    }
084
085    /**
086     * {@inheritDoc}
087     */
088    @Override
089    public NameValidity validSystemNameFormat(@Nonnull String systemName) {
090        return (AcelaAddress.validSystemNameFormat(systemName, 'T', getSystemPrefix()));
091    }
092
093    /**
094     * Public method to validate system name for configuration.
095     *
096     * @param systemName system name to validate
097     * @return 'true' if system name has a valid meaning in the current
098     * configuration, else return 'false'
099     */
100    public boolean validSystemNameConfig(@Nonnull String systemName) {
101        return (AcelaAddress.validSystemNameConfig(systemName, 'T', getMemo()));
102    }
103
104    /**
105     * Public method to convert system name to its alternate format.
106     *
107     * @param systemName system name to convert
108     * @return a normalized system name if system name is valid and has a valid
109     * alternate representation, else return ""
110     */
111    public String convertSystemNameToAlternate(String systemName) {
112        return (AcelaAddress.convertSystemNameToAlternate(systemName, getSystemPrefix()));
113    }
114
115    @Override
116    public boolean allowMultipleAdditions(@Nonnull String systemName) {
117        return true;
118    }
119
120    private final static Logger log = LoggerFactory.getLogger(AcelaTurnoutManager.class);
121
122}