001package jmri.jmrix.lenz.messageformatters;
002
003import jmri.jmrix.Message;
004import jmri.jmrix.lenz.LenzCommandStation;
005import jmri.jmrix.lenz.XNetConstants;
006import jmri.jmrix.lenz.XNetMessage;
007import jmri.jmrix.lenz.XPressNetMessageFormatter;
008
009/**
010 * Formatter for XPressNet messages that set speed and direction in 27 speed step mode.
011 *
012 * @see XNetMessage
013 * @see XPressNetMessageFormatter
014 *
015 * @author Paul Bender Copyright (C) 2024
016 */
017
018public class XNet27SpeedStepModeSpeedAndDirectionFormatter implements XPressNetMessageFormatter {
019
020    private static final String FORWARD = "Forward";
021    private static final String REVERSE = "Reverse";
022    private static final String X_NET_MESSAGE_SET_SPEED = "XNetMessageSetSpeed";
023    private static final String X_NET_MESSAGE_SET_DIRECTION = "XNetMessageSetDirection";
024    private static final String SPEED_STEP_MODE_X = "SpeedStepModeX";
025
026    @Override
027    public boolean handlesMessage(Message m) {
028        return m instanceof XNetMessage &&
029                ((XNetMessage) m).getElement(0) == XNetConstants.LOCO_OPER_REQ &&
030                        ((XNetMessage) m).getElement(1) == XNetConstants.LOCO_SPEED_27;
031    }
032
033    @Override
034    public String formatMessage(Message m) {
035        if(!handlesMessage(m)) {
036            throw new IllegalArgumentException("Message not supported by this formatter");
037        }
038        int speed = (((m.getElement(4) & 0x10) >> 4) + ((m.getElement(4) & 0x0F) << 1));
039        if (speed >= 3) {
040            speed -= 3;
041        }
042        String direction;
043        if ((m.getElement(4) & 0x80) != 0) {
044            direction = " " + Bundle.getMessage(X_NET_MESSAGE_SET_DIRECTION, Bundle.getMessage(FORWARD));
045        } else {
046            direction = " " + Bundle.getMessage(X_NET_MESSAGE_SET_DIRECTION, Bundle.getMessage(REVERSE));
047        }
048        return "Mobile Decoder Operations Request: " + Bundle.getMessage(X_NET_MESSAGE_SET_SPEED,
049                   LenzCommandStation.calcLocoAddress(m.getElement(2), m.getElement(3)))
050                + " " + speed +direction
051                + " " + Bundle.getMessage(SPEED_STEP_MODE_X, 27) + ".";
052    }
053
054}