package cs211.examples;

import java.util.Iterator;
import java.util.ListIterator;

public interface List<E> {

	/**
	 * Appends the specified element to the end of the list.
	 * 
	 * @param item the element to be added to the list
	 */
	public void add(E item);
	
	/**
	 * Appends the specified element at the specified position.
	 * 
	 * This does not replace any existing elements at this location. 
	 * This shifts any current element and all subsequent elements 
	 * one position to the right.
	 * 
	 * @param index index at which the specified element is to be inserted
	 * @param item the element to be inserted
	 * @throws IndexOutOfBoundsException if the index is out of range (index <0 || index >size())
	 */
	public void add(int index, E item);
	
	/**
	 * Empty all items from the list.
	 */
	public void clear();
	
	/**
	 * Returns {@code true} if this list contains the specified element.
	 * 
	 * More formally, returns {@code true} if and only if this list contains
	 * at least one element {@code e} such that {@code (item == null) ? e == null : item.equals(e)}.
	 * 
	 * @param item element whose presence in this list is being tested
	 * @return {@code true} if the list contains the specified item
	 */
	public boolean contains(E item);
	
	/**
	 * Returns the element at the specified position in this list
	 * 
	 * @param index index of the element to return
	 * @return the element at the specified position
	 * @throws IndexOutOfBoundsException if the index is out of range (index < 0 || index >= size())
	 */
	public E get(int index);
	
	/**
	 * Returns the index of the first occurrence of the specified element in this list, or -1 if this list does not contain the element.
	 * 
	 * More formally, returns the lowest index {@code i} such that {@code (o==null ? get(i)==null : o.equals(get(i)))},
	 *  or -1 if there is no such index.
	 *  
	 * @param item the element to search for
	 * @return the index of the first occurrence of the specified element in this list, or -1 if the list does not contain the element.
	 */
	public int indexOf(E item);
	
	/**
	 * Removes the element at the specified position in this list.
	 *  
	 * Shifts any subsequent elements to the left (subtracts one from their indices). 
	 * Returns the element that was removed from the list.
	 * 
	 * @param index the index of the element to be removed
	 * @return the element previously at the specified location
	 * @throws IndexOutOfBoundsException if the index is out of range {@code (index < 0 || index >= size())}
	 */
	public E remove(int index);
	
	/**
	 * Replaces the element at the specified position with the specified element.
	 * 
	 * @param index index of the element to replace
	 * @param item element to be stored at the specified position
	 * @throws IndexOutOfBoundsException if the index is out of the range {@code (index < 0 || index >= size())
	 */
	public void set(int i, E item);
	
	
	/**
	 * Returns the number of elements in this list.
	 * 
	 * @return the number of elements in the list
	 */
	public int size();
	
	/**
	 * Returns an iterator over the elements in this list in proper sequence.
	 * 
	 * @return an iterator over the elements in this list in proper sequence
	 */
	public Iterator<E> iterator();
	
	/**
	 * Returns a list iterator over the elements in this list in proper sequence.
	 * 
	 * @return a list iterator over the elements in this list in proper sequence
	 */
	public ListIterator<E> listIterator();
	
}