001package jmri;
002
003/**
004 * Encapsulate information for a DCC Locomotive Decoder Address.
005 *
006 * In particular, this handles the "short" (standard) vs "extended" (long)
007 * address selection.
008 *
009 * An address must be one of these, hence short vs long is encoded as a boolean.
010 *
011 * Once created, the number and long/short status cannot be changed.
012 *
013 * @author Bob Jacobsen Copyright (C) 2005
014 */
015@javax.annotation.concurrent.Immutable
016public class DccLocoAddress implements LocoAddress {
017
018    public DccLocoAddress(int number, boolean isLong) {
019        this.number = number;
020        if (isLong) {
021            protocol = LocoAddress.Protocol.DCC_LONG;
022        } else {
023            protocol = LocoAddress.Protocol.DCC_SHORT;
024        }
025    }
026
027    public DccLocoAddress(int number, LocoAddress.Protocol protocol) {
028        this.number = number;
029        this.protocol = protocol;
030    }
031
032    public DccLocoAddress(DccLocoAddress l) {
033        this.number = l.number;
034        this.protocol = l.protocol;
035    }
036
037    @Override
038    public boolean equals(Object a) {
039        if (a != null && a.getClass().equals(this.getClass())) {
040            try {
041                DccLocoAddress other = (DccLocoAddress) a;
042                if (this.number != other.number) {
043                    return false;
044                }
045                if (this.protocol != other.protocol) {
046                    return false;
047                }
048                return true;
049            } catch (RuntimeException e) {
050                return false;
051            }
052        }
053        return false;
054    }
055
056    @Override
057    public int hashCode() {
058        switch (protocol) {
059            case DCC_LONG:
060                return (int) (20000 + number & 0xFFFFFFFF);
061            case SELECTRIX:
062                return (int) (30000 + number & 0xFFFFFFFF);
063            case MOTOROLA:
064                return (int) (40000 + number & 0xFFFFFFFF);
065            case MFX:
066                return (int) (50000 + number & 0xFFFFFFFF);
067            case M4:
068                return (int) (60000 + number & 0xFFFFFFFF);
069            case OPENLCB:
070                return (int) (70000 + number & 0xFFFFFFFF);
071            case LGB:
072                return (int) (80000 + number & 0xFFFFFFFF);
073            case DCC_SHORT:
074            default:
075                return (int) (number & 0xFFFFFFFF);
076        }
077    }
078
079    @Override
080    public String toString() {
081        switch (protocol) {
082            case DCC_SHORT:
083                return "" + number + "(S)";
084            case DCC_LONG:
085                return "" + number + "(L)";
086            case SELECTRIX:
087                return "" + number + "(SX)";
088            case MOTOROLA:
089                return "" + number + "(MM)";
090            case M4:
091                return "" + number + "(M4)";
092            case MFX:
093                return "" + number + "(MFX)";
094            case OPENLCB:
095                return "" + number + "(OpenLCB)";
096            case LGB:
097                return "" + number + "(LGB)";
098            default:
099                return "" + number + "(D)";
100        }
101    }
102
103    public boolean isLongAddress() {
104        if (protocol == LocoAddress.Protocol.DCC_SHORT) {
105            return false;
106        }
107        return true;
108    }
109
110    @Override
111    public LocoAddress.Protocol getProtocol() {
112        return protocol;
113    }
114
115    @Override
116    public int getNumber() {
117        return (int) number;
118    }
119    final protected long number;
120    final protected LocoAddress.Protocol protocol;
121}