001package jmri.jmrix.roco.z21;
002
003import javax.annotation.Nonnull;
004import jmri.Turnout;
005import jmri.jmrix.lenz.XNetReply;
006import jmri.jmrix.lenz.XNetSystemConnectionMemo;
007import jmri.jmrix.lenz.XNetTurnoutManager;
008import org.slf4j.Logger;
009import org.slf4j.LoggerFactory;
010
011/**
012 * Implement z21 turnout manager.
013 * <p>
014 * System names are "XTnnn", where X is the user-configurable system prefix,
015 * nnn is the turnout number without padding.
016 *
017 * @author Paul Bender Copyright (C) 2016 
018 */
019public class Z21XNetTurnoutManager extends XNetTurnoutManager {
020
021    public Z21XNetTurnoutManager(XNetSystemConnectionMemo memo) {
022        super(memo);
023    }
024
025    // XNet-specific methods
026    
027    /**
028     * {@inheritDoc}
029     */
030    @Nonnull
031    @Override
032    protected Turnout createNewTurnout(@Nonnull String systemName, String userName) throws IllegalArgumentException {
033        int addr;
034        try {
035            addr = Integer.parseInt(systemName.substring(getSystemPrefix().length() + 1));
036        } catch (NumberFormatException e) {
037            throw new IllegalArgumentException("Failed to convert systemName '"+systemName+"' to a numeric Turnout address");
038        }
039        Turnout t = new Z21XNetTurnout(getSystemPrefix(), addr, tc);
040        t.setUserName(userName);
041        return t;
042    }
043
044    @Override
045    public boolean allowMultipleAdditions(@Nonnull String systemName) {
046        return true;
047    }
048
049    // listen for turnouts, creating them as needed
050    @Override
051    public void message(XNetReply l) {
052        log.debug("received message: {}", l);
053        if (l.getElement(0)==Z21Constants.LAN_X_TURNOUT_INFO) {
054          // bytes 2 and 3 are the address.
055          int address = (l.getElement(1) << 8) + l.getElement(2);
056          // the address sent byte the Z21 is one less than what JMRI's 
057          // XpressNet code (and lenz systems) expect.
058          address = address + 1; 
059          log.debug("message has address: {}", address);
060          // make sure we know about this turnout.
061          String s = getSystemNamePrefix() + address;
062          forwardMessageToTurnout(s,l);
063        } else {
064          super.message(l); // let the XpressNetTurnoutManager code
065                            // handle any other replies.
066        }
067    }
068
069    @Override
070    protected void forwardMessageToTurnout(String s, XNetReply l){
071        Z21XNetTurnout t = (Z21XNetTurnout) getBySystemName(s);
072        if ( null == t ) {
073           // need to create a new one, and send the message on 
074           // to the newly created object.
075           ((Z21XNetTurnout) provideTurnout(s)).initMessageZ21(l);
076        } else {
077           // The turnout exists, forward this message to the 
078           // turnout
079           t.message(l);
080        }
081    }
082    
083    /**
084     * {@inheritDoc}
085     */
086    @Override
087    @Nonnull
088    public String validateSystemNameFormat(@Nonnull String systemName, @Nonnull java.util.Locale locale) {
089        return this.validateSystemNameFormatOnlyNumeric(systemName, locale);
090    }
091
092    private static final Logger log = LoggerFactory.getLogger(Z21XNetTurnoutManager.class);
093
094}