001package jmri.jmrix.cmri.serial;
002
003import java.util.Locale;
004import javax.annotation.Nonnull;
005import jmri.Light;
006import jmri.jmrix.cmri.CMRISystemConnectionMemo;
007import jmri.managers.AbstractLightManager;
008import org.slf4j.Logger;
009import org.slf4j.LoggerFactory;
010
011/**
012 * Implement LightManager for CMRI serial systems.
013 * <p>
014 * System names are "CLnnn", where C is the user-configurable system prefix,
015 * nnn is the bit number without padding.
016 * <p>
017 * Based in part on SerialTurnoutManager.java
018 *
019 * @author Dave Duchamp Copyright (C) 2004
020 */
021public class SerialLightManager extends AbstractLightManager {
022
023    public SerialLightManager(CMRISystemConnectionMemo memo) {
024        super(memo);
025    }
026
027    /**
028     * {@inheritDoc}
029     */
030    @Override
031    @Nonnull
032    public CMRISystemConnectionMemo getMemo() {
033        return (CMRISystemConnectionMemo) memo;
034    }
035
036    /**
037     * Create a new Light based on the system name and optional user name.
038     * <p>
039     * Assumes calling method has checked that a Light with this system
040     * name does not already exist.
041     *
042     * @throws IllegalArgumentException if the
043     * system name is not in a valid format or if the system name does not
044     * correspond to a configured C/MRI digital output bit.
045     * @return New Light.
046     */
047    @Override
048    @Nonnull
049    protected Light createNewLight(@Nonnull String systemName, String userName) throws IllegalArgumentException {
050        Light lgt = null;
051        // check if the output bit is available
052        int nAddress;
053        nAddress = getMemo().getNodeAddressFromSystemName(systemName);
054        if (nAddress == -1) {
055            throw new IllegalArgumentException("Invalid Node Address from System Name: " + systemName);
056        }
057        int bitNum = getMemo().getBitFromSystemName(systemName);
058        if (bitNum == 0) {
059            throw new IllegalArgumentException("Invalid Bit from System Name: " + systemName);
060        }
061        String conflict;
062        conflict = getMemo().isOutputBitFree(nAddress, bitNum);
063        if (!conflict.isEmpty()) {
064            log.error("Assignment conflict with {}.  Light not created.", conflict);
065            throw new IllegalArgumentException(Bundle.getMessage("ErrorAssignDialog", bitNum, conflict));
066        }
067        // Validate the systemName
068        if (getMemo().validSystemNameFormat(systemName, 'L') == NameValidity.VALID) {
069            lgt = new SerialLight(systemName, userName,getMemo());
070            if (!getMemo().validSystemNameConfig(systemName, 'L',getMemo().getTrafficController())) {
071                log.warn("Light system Name does not refer to configured hardware: {}", systemName);
072            }
073        } else {
074            log.error("Invalid Light system Name format: {}", systemName);
075            throw new IllegalArgumentException("Invalid Light system Name format: " + systemName);
076        }
077        return lgt;
078    }
079
080    /**
081     * {@inheritDoc}
082     */
083    @Override
084    @Nonnull
085    public String validateSystemNameFormat(@Nonnull String systemName, @Nonnull Locale locale) {
086        return getMemo().validateSystemNameFormat(super.validateSystemNameFormat(systemName, locale), typeLetter(), locale);
087    }
088    
089    /**
090     * {@inheritDoc}
091     */
092    @Override
093    public NameValidity validSystemNameFormat(@Nonnull String systemName) {
094        return getMemo().validSystemNameFormat(systemName, typeLetter());
095    }
096
097    /**
098     * Public method to validate system name for configuration.
099     *
100     * @return 'true' if system name has a valid meaning in current configuration,
101     * else return 'false'
102     */
103    @Override
104    public boolean validSystemNameConfig(@Nonnull String systemName) {
105        return getMemo().validSystemNameConfig(systemName, 'L',getMemo().getTrafficController());
106    }
107
108    /**
109     * Public method to convert system name to its alternate format
110     *
111     * @return a normalized system name if system name is valid and has a valid
112     * alternate representation, else returns ""
113     */
114    @Override
115    @Nonnull
116    public String convertSystemNameToAlternate(@Nonnull String systemName) {
117        return getMemo().convertSystemNameToAlternate(systemName);
118    }
119
120    /**
121     * {@inheritDoc}
122     */
123    @Override
124    public String getEntryToolTip() {
125        return Bundle.getMessage("AddOutputEntryToolTip");
126    }
127
128    @Override
129    public boolean allowMultipleAdditions(@Nonnull String systemName) {
130        return true;
131    }
132
133    private final static Logger log = LoggerFactory.getLogger(SerialLightManager.class);
134
135}