/*******************************************************************************
* Copyright (c)                                                                *
*           2005   Tristan Allwood,                                            *
*           2005   Daniel Burke,                                               *
*           2005   Marc Hull,                                                  *
*           2005   Ekaterina Itskova,                                          *
*           2005   Steve Zymler                                                *
*                                                                              *
* Permission is hereby granted, free of charge, to any person obtaining a      *
* copy of this software and associated documentation files (the                *
* "Software"), to deal in the Software without restriction, including          *
* without limitation the rights to use, copy, modify, merge, publish,          *
* distribute, sublicense, and/or sell copies of the Software, and to           *
* permit persons to whom the Software is furnished to do so, subject to        *
* the following conditions:                                                    *
*                                                                              *
* The above copyright notice and this permission notice shall be included      *
* in all copies or substantial portions of the Software.                       *
*                                                                              *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS      *
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF                   *
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.       *
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY         *
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,         *
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE            *
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                       *
*******************************************************************************/
/*
 * Created on 21-Nov-2004
 *
 */
package uk.ac.ic.doc.kevlar.publicUtil.collections;

import java.util.Collection;
import java.util.Iterator;

/**
 * @author Daniel Burke
 *
 */
public class NotifyingCollection<E> implements Collection<E> {
    

    Collection<E> backend;
    
    IUpdateListener<E> listener;
    
    public NotifyingCollection(Collection<E> backend, IUpdateListener<E> listener) {
        if(listener == null)
        {
            throw new IllegalArgumentException("Null listener not allowed");
        }
        
        if(backend == null)
        {
            throw new IllegalArgumentException("Null backend not allowed");
        }
        
        this.backend = backend;
        this.listener = listener;
    }

    public boolean add(E arg0) {
        boolean ret = backend.add(arg0);
        listener.updated(this);
        return ret;
    }
    
    public boolean addAll(Collection< ? extends E> arg0) {
        boolean ret = backend.addAll(arg0);
        listener.updated(this);
        return ret;
    }
    
    public void clear() {
        backend.clear();
        listener.updated(this);
    }
    
    public boolean contains(Object arg0) {
        boolean ret = backend.contains(arg0);
        return ret;
    }
    
    public boolean containsAll(Collection< ? > arg0) {
        boolean ret = backend.containsAll(arg0);
        return ret;
    }
    public boolean isEmpty() {
        boolean ret = backend.isEmpty();
        return ret;
    }
    
    private class NotifyingIterator<E> implements Iterator<E>
    {
        private Iterator<E> backend;
        
        public NotifyingIterator(Iterator<E> backend)
        {
            if(backend == null)
            {
                throw new IllegalArgumentException("Null backend not allowed");
            }
            this.backend = backend;
        }

        public boolean hasNext() {
            boolean ret = backend.hasNext();
            return ret;
        }

        public E next() {
            E ret = backend.next();
            return ret;
        }

        public void remove() {
            backend.remove();
            listener.updated(NotifyingCollection.this);
        }
        
    }
    
    public Iterator<E> iterator() {
        return new NotifyingIterator<E>(backend.iterator());
    }
    
    public boolean remove(Object arg0) {
        boolean ret = backend.remove(arg0);
        listener.updated(this);
        return ret;
    }
    public boolean removeAll(Collection< ? > arg0) {
        boolean ret = backend.removeAll(arg0);
        listener.updated(this);
        return ret;
    }
    public boolean retainAll(Collection< ? > arg0) {
        boolean ret = backend.retainAll(arg0);
        listener.updated(this);
        return ret;
    }
    
    public int size() {
        return backend.size();
    }
    
    public Object[] toArray() {
        return backend.toArray();
    }
    
    public <T> T[] toArray(T[] a) {
        return backend.toArray(a);
    }

}
