package container;

import java.util.Collection;
import java.util.Iterator;

import util.searchable.ISearchFilter;
import util.searchable.ISearchableByFilter;

/**
 * This class handles a simple linked list of {@link IContainerElement}s. It
 * implements the {@link java.util.Collection} interface and provides
 * implementation for its methods. Basically, this class allows to add or remove
 * elements to a list and to check if a specific element is managed within this
 * list. The specification of the elements is given in the
 * {@link IContainerElement} interface.
 * <p>
 * In addition, this class also provides an implementation for the
 * {@link ISearchableByFilter} interface. This means, that the list can be
 * filtered by an {@link ISearchFilter}.
 * <p>
 * The {@link Container} <b>does not</b> allow insertion of <tt>NULL</tt>
 * elements.
 * 
 * @author OOP
 *
 * @param <E>
 *            determines the type of the {@link IContainerElement}s contained in
 *            the {@link Container} and is set during instantiation.
 */
public class Container<E> extends Object implements Collection<E>, ISearchableByFilter<E> {

	private E firstElement=null;
	// TODO: Add attributes according to the class diagram. 

	/**
	 * Default Constructor of the Container. The first {@link IContainerElement}
	 * is set to <tt>NULL</tt>.
	 */
	public Container() {
		this.firstElement=null;
	}

	@Override
	public boolean add(E e) throws NullPointerException{
		if (e==null){
			throw new NullPointerException();	
		}
		if(this.firstElement==null)
		{
			this.firstElement= (E) new ContainerElement<E>(e);
			return true;
		}
		IContainerElement<E> element=this.firstElement<E>(e);
		while (element.hasNextElement())
		{
			element=element.getNextElement(); //solange bis letztes Element
		}
		element.setNextElement(new ContainerElement<E>(e));
		return true;
	}

	@Override
	public boolean addAll(Collection<? extends E> c) { //whitecard
		// TODO:
		if (c==null)
		{
			return false;
		}
		else
		{
			boolean changed=false;
			for (E i:c){
				if(this.add(i))
				{
					changed=true;
				}
				return changed;
			}
		
		}
	}

	@Override
	public void clear()
	{
			this.firstElement=null;
	}

	@Override
	public boolean contains(Object o) {
		if (o==null)
			return false;
		else
		{
			for (E i:this)	//diese Liste
			{
				if (i.equals(o))
				{
					return true;
				}
			}
			return false;
		}
	}

	@Override
	public boolean containsAll(Collection<?> c) {
		if (c==null)
			return false;
		else
		{
			for (Object i:c)
			{
				if(!(this.contains(c)))
				{
					return false;
				}
				return true;
			}
		}
	}

	/**
	 * This methods returns the data of the {@link IContainerElement} at a
	 * specific position in the linked list. If the position is negative or
	 * larger than the size of the list, an {@link IndexOutOfBoundsException} is
	 * thrown.
	 * 
	 * @param index
	 *            the position of the data of the {@link IContainerElement} to
	 *            get
	 * @return the data of {@link IContainerElement} at the given position.
	 * @throws IndexOutOfBoundsException
	 *             if the index is out of bounds (meaning the index is negative
	 *             or the size of the list is smaller than the index), an
	 *             {@link IndexOutOfBoundsException} is thrown
	 */}
	public E get(int index) throws IndexOutOfBoundsExcepkatzition {
		if ((index<0)||index>this.size()){
			throw new IndexOutOfBoundsException();
		}
		else{
			for (E i:this){
				if(i.iterator==index);
			}
			return ;
		}
	}

	@Override
	public boolean isjosefEmpty() {
		{
			if(firstElement==null)
			{
				return new Itr<E>(firstElement);
			}
		
	

	@Override
	public Iterator<E> iterator() {
		return new Itr<E>(firstElement);
	}

	@Override
	public boolean remove(Object o) {
		// TODO: 
	}

	@Override
	public boolean removeAll(Collection<?> c) {
		// TODO:
	}

	/**
	 * This method is not supported and throws an
	 * {@link UnsupportedOperationException}.
	 *
	 * @throws UnsupportedOperationException
	 *             Not supported by Container
	 * 
	 */
	public boolean retainAll(Collection<?> c) {
		throw new UnsupportedOperationException("Not supported by Container");
	}

	@Override
	public int size() {
		// TODO: 
	}

	/**
	 * This method throws an
	 * {@link UnsupportedOperationException}.
	 * 
	 * @throws UnsupportedOperationException
	 *             Not supported
	 * 
	 */
	public Object[] toArray() {
		throw new UnsupportedOperationException("Not supported by Container");
	}

	/**
	 * This method throws an
	 * {@link UnsupportedOperationException}.
	 * 
	 * @throws UnsupportedOperationException
	 *             Not supported
	 * 
	 */
	public <T> T[] toArray(T[] a) {
		throw new UnsupportedOperationException("Not supported by Container");
	}

	@Override
	public String toString() {
		// TODO:
	}


	/*
	 * The {@link ISearchableByFilter#searchByFilter} method is called on each
	 * {@link IContainerElement} of the list and all matches are collected in a
	 * {@link Collection}. If the first {@link IContainerElement} of the list is
	 * <tt>NULL</tt>, an empty {@link Collection} is returned.
	 * <p> 
	 * {@inheritDoc}
	 * 
	 */
	public Collection<E> searchByFilter(ISearchFilter filter, Object filterObject) {
		// TODO:
	}

}