001package jmri.jmrix.can.cbus;
002
003import java.beans.PropertyChangeEvent;
004import java.util.Locale;
005import javax.annotation.*;
006import jmri.*;
007import jmri.jmrix.can.CanSystemConnectionMemo;
008import jmri.managers.AbstractTurnoutManager;
009import org.slf4j.Logger;
010import org.slf4j.LoggerFactory;
011
012/**
013 * Implement TurnoutManager for CAN CBUS systems.
014 * <p>
015 * System names are "MT+n;-m", where M is the user configurable system prefix,
016 * n and m are the events (signed for on/off, separated by ;).
017 * <p>
018 * Turnouts must be explicitly created, they are not polled.
019 *
020 * @author Bob Jacobsen Copyright (C) 2008
021 * @since 2.3.1
022 */
023public class CbusTurnoutManager extends AbstractTurnoutManager {
024
025    /**
026     * Ctor using a given system connection memo
027     * @param memo System Connection
028     */
029    public CbusTurnoutManager(CanSystemConnectionMemo memo) {
030        super(memo);
031    }
032
033    /**
034     * {@inheritDoc}
035     */
036    @Nonnull
037    @Override
038    protected Turnout createNewTurnout(@Nonnull String systemName, String userName) throws IllegalArgumentException {
039        String addr = systemName.substring(getSystemPrefix().length() + 1);
040        // first, check validity
041        String newAddress;
042        try {
043            newAddress = CbusAddress.validateSysName(addr);
044        } catch (IllegalArgumentException e) {
045            log.error("Unable to create CbusTurnout, {}", e.getMessage());
046            throw e;
047        }
048        // OK, make
049        Turnout t = new CbusTurnout(getSystemPrefix(), newAddress, ((CanSystemConnectionMemo)getMemo()).getTrafficController());
050        t.setUserName(userName);
051        return t;
052    }
053
054    /**
055     * {@inheritDoc}
056     */
057    @Override
058    public boolean allowMultipleAdditions(@Nonnull String systemName) {
059        return true;
060    }
061
062    /**
063     * {@inheritDoc}
064     */
065    @Override
066    public String createSystemName(@Nonnull String curAddress, @Nonnull String prefix) {
067        // first, check validity
068        String newAddress;
069        try {
070            newAddress = CbusAddress.validateSysName(curAddress);
071         } catch (IllegalArgumentException e) {
072            newAddress = curAddress;
073        }
074        return prefix + typeLetter() + newAddress;
075    }
076
077    @Override
078    @Nonnull
079    @CheckReturnValue
080    public String getNextValidSystemName(@Nonnull NamedBean currentBean) throws JmriException {
081        if (!allowMultipleAdditions(currentBean.getSystemName())) throw new UnsupportedOperationException("Not supported");
082
083        String currentName = currentBean.getSystemName();
084        String suffix = Manager.getSystemSuffix(currentName);
085        String type = Manager.getTypeLetter(currentName);
086        String prefix = Manager.getSystemPrefix(currentName);
087
088        String nextName = CbusAddress.getIncrement(suffix);
089
090        if (nextName==null) {
091            throw new JmriException("No existing number found when incrementing " + currentName);
092        }
093        return prefix+type+nextName;
094
095    }
096
097    /**
098     * {@inheritDoc}
099     */
100    @Override
101    @Nonnull
102    public String validateSystemNameFormat(@Nonnull String name, @Nonnull Locale locale) {
103        validateSystemNamePrefix(name, locale);
104        try {
105            CbusAddress.validateSysName(name.substring(getSystemNamePrefix().length()));
106        } catch (IllegalArgumentException ex) {
107            throw new jmri.NamedBean.BadSystemNameException(locale, "InvalidSystemNameCustom", ex.getMessage());
108        }
109        return name;
110    }
111
112    /**
113     * {@inheritDoc}
114     */
115    @Override
116    public NameValidity validSystemNameFormat(@Nonnull String systemName) {
117        String addr;
118        try {
119            addr = systemName.substring(getSystemPrefix().length() + 1); // get only the address part
120        } catch (StringIndexOutOfBoundsException e){
121            return NameValidity.INVALID;
122        }
123        try {
124            CbusAddress.validateSysName(addr);
125        } catch (IllegalArgumentException e){
126            return NameValidity.INVALID;
127        }
128        return NameValidity.VALID;
129    }
130
131    /**
132     * {@inheritDoc}
133     */
134    @Override
135    public String getEntryToolTip() {
136        return Bundle.getMessage("AddOutputEntryToolTip");
137    }
138
139    @Override
140    public void propertyChange(PropertyChangeEvent e) {
141        super.propertyChange(e);
142        if (e.getPropertyName().equals("inverted")) {
143            firePropertyChange("beaninverted", null, null); //IN18N
144        }
145    }
146
147    private final static Logger log = LoggerFactory.getLogger(CbusTurnoutManager.class);
148
149}