001package jmri.jmrix.tmcc;
002
003import java.util.Locale;
004
005import javax.annotation.Nonnull;
006
007import jmri.*;
008import jmri.managers.AbstractTurnoutManager;
009
010import org.slf4j.Logger;
011import org.slf4j.LoggerFactory;
012
013/**
014 * Implement turnout manager for TMCC serial systems.
015 * <p>
016 * System names are "TTnnn", where T is the user configurable system prefix,
017 * nnn is the turnout number without padding.
018 *
019 * @author Bob Jacobsen Copyright (C) 2003, 2006
020 * with edits/additions by
021 * @author Timothy Jump Copyright (C) 2025
022 */
023
024public class SerialTurnoutManager extends AbstractTurnoutManager implements SerialListener {
025
026    public SerialTurnoutManager(TmccSystemConnectionMemo memo) {
027        super(memo);
028        memo.getTrafficController().addSerialListener(this);
029        log.debug("TMCC TurnoutManager prefix={}", getSystemPrefix());
030    }
031
032    /**
033     * {@inheritDoc}
034     */
035    @Override
036    @Nonnull
037    public TmccSystemConnectionMemo getMemo() {
038        return (TmccSystemConnectionMemo) memo;
039    }
040
041    /**
042     * {@inheritDoc}
043     */
044    @Nonnull
045    @Override
046    protected Turnout createNewTurnout(@Nonnull String systemName, String userName) throws IllegalArgumentException {
047        // validate the system name
048        String sName = validateSystemNameFormat(systemName);
049        // does this turnout already exist?
050        Turnout t = getBySystemName(sName);
051        if (t != null) {
052            log.debug("Turnout already exists");
053            return t;
054        }
055        // create the turnout
056        log.debug("new SerialTurnout with addr = {}", systemName.substring(getSystemPrefix().length() + 1));
057        int addr = Integer.parseInt(systemName.substring(getSystemPrefix().length() + 1));
058        t = new SerialTurnout(getSystemPrefix(), addr, getMemo());
059        t.setUserName(userName);
060        return t;
061    }
062
063    /**
064     * Listeners for messages from the command station.
065     */
066    @Override
067    public void message(SerialMessage m) {
068        log.debug("message received unexpectedly: {}", m.toString());
069    }
070
071    // Listen for status changes from TMCC system
072    @Override
073    public void reply(SerialReply r) {
074        // There isn't anything meaningful coming back at this time.
075        log.debug("reply received unexpectedly: {}", r.toString());
076    }
077
078    // Turnout address format is more than a simple number.
079    @Override
080    public boolean allowMultipleAdditions(@Nonnull String systemName) {
081        return true;
082    }
083
084    /**
085     * {@inheritDoc}
086     */
087    @Override
088    @Nonnull
089    public String validateSystemNameFormat(@Nonnull String name, @Nonnull Locale locale) {
090        return validateIntegerSystemNameFormat(name, 0, 119, locale);
091    }
092
093    /**
094     * {@inheritDoc}
095     */
096    @Override
097    public NameValidity validSystemNameFormat(@Nonnull String systemName) {
098        NameValidity validity = super.validSystemNameFormat(systemName);
099        if (validity == NameValidity.VALID) {
100            int num;
101            try {
102                num = Integer.parseInt(systemName.substring(getSystemNamePrefix().length()));
103                if (num < 0 || num > 119) {
104                    validity = NameValidity.INVALID;
105                }
106            } catch (NumberFormatException ex) {
107                validity = NameValidity.INVALID;
108            }
109        }
110        return validity;
111    }
112
113    /**
114     * {@inheritDoc}
115     */
116    @Override
117    public String getEntryToolTip() {
118        return Bundle.getMessage("AddOutputEntryToolTip");
119    }
120
121    private final static Logger log = LoggerFactory.getLogger(SerialTurnoutManager.class);
122
123}