package thisandthat;

/**
 * Immutable data type for US phone numbers.
 */
public final class PhoneNumber {
	
	/**
	 * area code (3 digits)
	 */
    private final int area;
    
    /**
     * exchange  (3 digits)
     */
    private final int exch;
    
    /**
     * extension (4 digits)
     */
    private final int ext;

    public PhoneNumber(int area, int exch, int ext) {
        this.area = area;
        this.exch = exch;
        this.ext  = ext;
    }
    
    public PhoneNumber(PhoneNumber number) {
        area = number.area;
        exch = number.exch;
        ext  = number.ext;
    }

    /**
     * how you're supposed to implement equals
     */
    public boolean equals(Object y) {
        if (y == this) { return true;  }
        if (y == null) { return false; }
        if (y.getClass() != this.getClass()) { return false; }
        PhoneNumber a = this;
        PhoneNumber b = (PhoneNumber) y;
        return (a.area == b.area) && (a.exch == b.exch) && (a.ext == b.ext);
    }

    /**
     * 0 for padding with leading 0s
     */
    public String toString() {
        return String.format("(%03d) %03d-%04d", area, exch, ext);
    }

    /**
     * satisfies the hashCode contract
     */
    public int hashCode() {
        return 10007 * (area + 1009 * exch) + ext;
    }

    public static void main(String[] args) {
        PhoneNumber a = new PhoneNumber(609, 258, 4455);
        PhoneNumber b = new PhoneNumber(609, 876, 5309);
        PhoneNumber c = new PhoneNumber(609, 003, 5309);
        PhoneNumber d = new PhoneNumber(215, 876, 5309);
        PhoneNumber e = new PhoneNumber(609, 876, 5309);
        PhoneNumber f = b;
        System.out.println("a = " + a);
        System.out.println("b = " + b);
        System.out.println("c = " + c);
        System.out.println("d = " + d);
        System.out.println("e = " + e);
        System.out.println("b == b:      " + (b == f));
        System.out.println("b == e:      " + (b == e));
        System.out.println("b.equals(b): " + (b.equals(b)));
        System.out.println("b.equals(e): " + (b.equals(e)));
    }
}
