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        this.isConsist = false;
026    }
027
028    public DccLocoAddress(int number, LocoAddress.Protocol protocol) {
029        this.number = number;
030        this.protocol = protocol;
031        this.isConsist = false;
032    }
033
034    public DccLocoAddress(int number, LocoAddress.Protocol protocol, boolean isConsist) {
035        this.number = number;
036        this.protocol = protocol;
037        this.isConsist = isConsist;
038    }
039
040    public DccLocoAddress(DccLocoAddress l) {
041        this.number = l.number;
042        this.protocol = l.protocol;
043        this.isConsist = false;
044    }
045    
046    @Override
047    public boolean isConsistAddress () {
048        return isConsist;
049    }
050    
051    @Override
052    public boolean equals(Object a) {
053        if (a != null && a.getClass().equals(this.getClass())) {
054            try {
055                DccLocoAddress other = (DccLocoAddress) a;
056                if (this.number != other.number) {
057                    return false;
058                }
059                if (this.protocol != other.protocol) {
060                    return false;
061                }
062                return true;
063            } catch (RuntimeException e) {
064                return false;
065            }
066        }
067        return false;
068    }
069
070    @Override
071    public int hashCode() {
072        switch (protocol) {
073            case DCC_LONG:
074                return (int) (20000 + number & 0xFFFFFFFF);
075            case SELECTRIX:
076                return (int) (30000 + number & 0xFFFFFFFF);
077            case MOTOROLA:
078                return (int) (40000 + number & 0xFFFFFFFF);
079            case MFX:
080                return (int) (50000 + number & 0xFFFFFFFF);
081            case M4:
082                return (int) (60000 + number & 0xFFFFFFFF);
083            case OPENLCB:
084                return (int) (70000 + number & 0xFFFFFFFF);
085            case LGB:
086                return (int) (80000 + number & 0xFFFFFFFF);
087            case DCC_SHORT:
088            default:
089                return (int) (number & 0xFFFFFFFF);
090        }
091    }
092
093    @Override
094    public String toString() {
095        switch (protocol) {
096            case DCC_SHORT:
097                return "" + number + "(S)";
098            case DCC_LONG:
099                return "" + number + "(L)";
100            case SELECTRIX:
101                return "" + number + "(SX)";
102            case MOTOROLA:
103                return "" + number + "(MM)";
104            case M4:
105                return "" + number + "(M4)";
106            case MFX:
107                return "" + number + "(MFX)";
108            case OPENLCB:
109                return "" + number + "(OpenLCB)";
110            case LGB:
111                return "" + number + "(LGB)";
112            default:
113                return "" + number + "(D)";
114        }
115    }
116
117    public boolean isLongAddress() {
118        if (protocol == LocoAddress.Protocol.DCC_SHORT) {
119            return false;
120        }
121        return true;
122    }
123
124    @Override
125    public LocoAddress.Protocol getProtocol() {
126        return protocol;
127    }
128
129    @Override
130    public int getNumber() {
131        return (int) number;
132    }
133    protected final long number;
134    protected final LocoAddress.Protocol protocol;
135    final boolean isConsist;
136
137}