001package jmri.jmrix.lenz.hornbyelite;
002
003import javax.annotation.Nonnull;
004import jmri.Turnout;
005import jmri.jmrix.lenz.XNetAddress;
006import jmri.jmrix.lenz.XNetSystemConnectionMemo;
007import org.slf4j.Logger;
008import org.slf4j.LoggerFactory;
009
010/**
011 * Implement XNet turnout manager - Specific to Hornby Elite
012 * <p>
013 * System names are "XTnnn", where X is the user-configurable system prefix,
014 * nnn is the turnout number without padding.
015 *
016 * @author Paul Bender Copyright (C) 2008
017 */
018public class EliteXNetTurnoutManager extends jmri.jmrix.lenz.XNetTurnoutManager {
019
020    public EliteXNetTurnoutManager(XNetSystemConnectionMemo memo) {
021        super(memo);
022    }
023
024    // XNet-specific methods
025    
026    /**
027     * {@inheritDoc}
028     */
029    @Nonnull
030    @Override
031    protected Turnout createNewTurnout(@Nonnull String systemName, String userName) throws IllegalArgumentException {
032        // check if the output bit is available
033        int bitNum = XNetAddress.getBitFromSystemName(systemName, getSystemPrefix());
034        if (bitNum == -1) {
035            throw new IllegalArgumentException("Cannot get Bit from System Name " + systemName);
036        }
037        // create the new Turnout object
038        Turnout t = new EliteXNetTurnout(getSystemPrefix(), bitNum, tc);
039        t.setUserName(userName);
040        return t;
041    }
042
043    @Override
044    public boolean allowMultipleAdditions(@Nonnull String systemName) {
045        return true;
046    }
047
048    /**
049     * Listen for turnouts, creating them as needed
050     */
051    @Override
052    public void message(jmri.jmrix.lenz.XNetReply l) {
053        log.debug("received message: {}", l);
054        if (l.isFeedbackBroadcastMessage()) {
055            int numDataBytes = l.getElement(0) & 0x0f;
056            for (int i = 1; i < numDataBytes; i += 2) {
057                // parse message type
058                int addr = l.getTurnoutMsgAddr(i);    // Acc. Address 1 on 
059                // Hornby reads as 
060                // XpressNet address 2
061                // in the message.
062                if (addr >= 0) {
063                    log.debug("message has address: {}", addr);
064                    // reach here for switch command; make sure we know 
065                    // about this one
066                    String s = getSystemNamePrefix() +(addr - 1);
067                    forwardMessageToTurnout(s,l);
068                    if ((addr & 0x01) == 1) {
069                        // If the address we got was odd, we need to check to 
070                        // see if the even address should be added as well.
071                        int a2 = l.getElement(i + 1);
072                        if ((a2 & 0x0c) != 0) {
073                            // reach here for switch command; make sure we know 
074                            // about this one
075                            s = getSystemNamePrefix() + (addr);
076                            forwardMessageToTurnout(s,l);
077                        }
078                    }
079                }
080            }
081        }
082    }
083
084    private static final Logger log = LoggerFactory.getLogger(EliteXNetTurnoutManager.class);
085
086}