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