import java.util.Arrays;
import edu.princeton.cs.algs4.Queue;

// immutable "set" of objects of type T
// (ignore the "extends Comparable<T>"; it just is to be able to
// sort the arrays
public class MyCollectionSolved<T extends Comparable<T>> {

    // immutable array of objects
    private final T[] objects;
    
    public MyCollection(T[] original) {

        // create defensive copy using Arrays.copyOf(T[] original, int newLength)
        // https://docs.oracle.com/javase/7/docs/api/java/util/Arrays.html#copyOf(T[],%20int)
        this.objects = Arrays.copyOf(original, original.length);

        // sort the array
        Arrays.sort(this.objects);
    }

    // compare this collection to another object y
    public boolean equals(Object y) {
        
        // ***************************************************************

        // STANDARD EQUALS STUFF
        
        // optimization: more efficient when comparing object to itself
        if (y == this) return true;

        // check for null
        if (y == null) return false;

        // must make sure that the objects are of the same type
        if (y.getClass() != this.getClass()) return false;

        // once we made sure, we can cast the object to the type
        // 'MyCollection' so that we can access its instance variables
        MyCollection that = (MyCollection) y;

        // ***************************************************************

        // CODE THAT IS SPECIFIC TO MyCollection's EQUALITY TESTING
        
        // check length
        if (this.objects.length != that.objects.length) return false;

        // both arrays are sorted, so we just have to go through and compare both
        for (int i = 0; i < this.objects.length; i++) {
            if (!this.objects[i].equals(that.objects[i]))
                return false;
        }
        
        return true;   
    }


    public static void main(String[] args) {

        // two equal collections
        MyCollection c1 = new MyCollection( new Integer[] { 1, 5, 3, 2 } );
        MyCollection c2 = new MyCollection( new Integer[] { 5, 1, 2, 3 } );

        // smaller collection
        MyCollection c3 = new MyCollection( new Integer[] { 5, 1, 2 } );

        // null collection
        MyCollection c4 = null;

        // different collection
        MyCollection c5 = new MyCollection( new Integer[] { 5, 1, 4, 9 } );
        
        // could use assert here
        System.out.println("c1 == c2?: " +c1.equals(c2));
        System.out.println("c1 == c3?: " +c1.equals(c3));
        System.out.println("c1 == c4?: " +c1.equals(c4));
        System.out.println("c1 == c5?: " +c1.equals(c5));
        
    }
    
}