package mycollection;

public class ArrayList implements List {

    // Instance variables
    private Object[] items;
    private int size;

    // Constructor
    public ArrayList() {
        clear();
    }

    // Returning the size of the list
    public int size() {
        return size;
    }

    // Cleaning up / Flushing the list
    public void clear() {
        size = 0;
        items = new Object[1];
    }

    // Checking whether the list is empty
    public boolean isEmpty() {
        return size == 0;
    }

    // Adding an element to the list
    public boolean add(Object x) {
        if (size >= items.length) {
            Object[] copy = new Object[items.length * 2];
            for (int i = 0; i < size; i++)
                copy[i] = items[i];
            items = copy;
        }
        items[size] = x;
        size++;
        return true;
    }

    // Returning the position of some element
    public int indexOf(Object x) {
        for (int i = 0; i < size; i++)
            if (items[i].equals(x))
                return i;
        return -1;
    }

    // Removing an element from the list
    public boolean remove(Object x) {
        int position = indexOf(x);
        if (position != -1) {
            for (int i = position; i < size - 1; i++)
                items[i] = items[i + 1];
            size--;
        }
        return position != -1;
    }

    // Finding out whether some element is in the list
    public boolean contains(Object x) {
        return indexOf(x) != -1;
    }

    // Transforming the list into an array of objects
    public Object[] toArray() {
        Object[] array = new Object[size];
        for (int i = 0; i < size; i++)
            array[i] = items[i];
        return array;
    }

    // Displaying the contents of the list
    public String toString() {
        String s = "[";
        for (int i = 0; i < size; i++) {
            s += items[i];
            if (i < size - 1)
                s += ", ";
        }
        return s + "]";
    }

    // Returning the element at position index
    public Object get(int index) {
        return items[index];
    }

    // Setting the "value" of the element at position index
    public Object set(int index, Object element) {
        Object item = items[index];
        items[index] = element;
        return item;
    }

    // Public iterator (for users of ArrayList)
    public Iterator iterator() {
        return new ArrayListIterator();
    }

    // Private implementation of ArrayList's iterator
    private class ArrayListIterator implements Iterator {
        private int current;

        ArrayListIterator() {
            current = 0;
        }

        public boolean hasNext() {
            return current < size;
        }

        public Object next() {
            return items[current++];
        }
    }
}
