/*******************************************************************************
 * Copyright (c) 2007, 2009 Oracle. All rights reserved.
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v1.0, which accompanies this distribution
 * and is available at http://www.eclipse.org/legal/epl-v10.html.
 * 
 * Contributors:
 *     Oracle - initial API and implementation
 ******************************************************************************/
package org.eclipse.jpt.utility.internal.model.value;

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

import org.eclipse.jpt.utility.internal.iterators.ReadOnlyListIterator;
import org.eclipse.jpt.utility.internal.model.AbstractModel;
import org.eclipse.jpt.utility.internal.model.ChangeSupport;
import org.eclipse.jpt.utility.internal.model.SingleAspectChangeSupport;
import org.eclipse.jpt.utility.model.event.CollectionAddEvent;
import org.eclipse.jpt.utility.model.event.CollectionChangeEvent;
import org.eclipse.jpt.utility.model.event.CollectionClearEvent;
import org.eclipse.jpt.utility.model.event.CollectionRemoveEvent;
import org.eclipse.jpt.utility.model.listener.ChangeListener;
import org.eclipse.jpt.utility.model.listener.CollectionChangeListener;
import org.eclipse.jpt.utility.model.listener.ListChangeListener;
import org.eclipse.jpt.utility.model.value.CollectionValueModel;
import org.eclipse.jpt.utility.model.value.ListValueModel;

/**
 * An adapter that allows us to make a CollectionValueModel behave like
 * a read-only ListValueModel, sorta.
 * 
 * To maintain a reasonably consistent appearance to client code, we
 * keep an internal list somewhat in synch with the wrapped collection.
 * 
 * NB: Since we only listen to the wrapped collection when we have
 * listeners ourselves and we can only stay in synch with the wrapped
 * collection while we are listening to it, results to various methods
 * (e.g. #size(), getItem(int)) will be unpredictable whenever
 * we do not have any listeners. This should not be too painful since,
 * most likely, client objects will also be listeners.
 */
public class CollectionListValueModelAdapter<E>
	extends AbstractModel
	implements ListValueModel<E>
{
	/** The wrapped collection value model. */
	protected final CollectionValueModel<? extends E> collectionHolder;

	/** A listener that forwards any events fired by the collection holder. */
	protected final CollectionChangeListener collectionChangeListener;

	/**
	 * Our internal list, which holds the same elements as
	 * the wrapped collection, but keeps them in order.
	 */
	// we declare this an ArrayList so we can use #clone() and #ensureCapacity(int)
	protected final ArrayList<E> list;


	// ********** constructors **********

	/**
	 * Wrap the specified CollectionValueModel.
	 */
	public CollectionListValueModelAdapter(CollectionValueModel<? extends E> collectionHolder) {
		super();
		if (collectionHolder == null) {
			throw new NullPointerException();
		}
		this.collectionHolder = collectionHolder;
		this.collectionChangeListener = this.buildCollectionChangeListener();
		this.list = new ArrayList<E>();
		// postpone building the list and listening to the underlying collection
		// until we have listeners ourselves...
	}


	// ********** initialization **********

	@Override
	protected ChangeSupport buildChangeSupport() {
		return new SingleAspectChangeSupport(this, ListChangeListener.class, LIST_VALUES);
	}

	/**
	 * The wrapped collection has changed, forward an equivalent
	 * list change event to our listeners.
	 */
	protected CollectionChangeListener buildCollectionChangeListener() {
		return new CollectionChangeListener() {
			public void itemsAdded(CollectionAddEvent event) {
				CollectionListValueModelAdapter.this.itemsAdded(event);
			}
			public void itemsRemoved(CollectionRemoveEvent event) {
				CollectionListValueModelAdapter.this.itemsRemoved(event);
			}
			public void collectionCleared(CollectionClearEvent event) {
				CollectionListValueModelAdapter.this.collectionCleared(event);
			}
			public void collectionChanged(CollectionChangeEvent event) {
				CollectionListValueModelAdapter.this.collectionChanged(event);
			}
			@Override
			public String toString() {
				return "collection change listener"; //$NON-NLS-1$
			}
		};
	}


	// ********** ListValueModel implementation **********

	public Iterator<E> iterator() {
		return this.listIterator();
	}

	public ListIterator<E> listIterator() {
		return new ReadOnlyListIterator<E>(this.list);
	}

	public E get(int index) {
		return this.list.get(index);
	}

	public int size() {
		return this.list.size();
	}

	public Object[] toArray() {
		return this.list.toArray();
	}


	// ********** extend change support **********

	/**
	 * Override to start listening to the collection holder if necessary.
	 */
	@Override
	public void addChangeListener(ChangeListener listener) {
		if (this.hasNoListeners()) {
			this.engageModel();
		}
		super.addChangeListener(listener);
	}

	/**
	 * Override to start listening to the collection holder if necessary.
	 */
	@Override
	public void addListChangeListener(String listName, ListChangeListener listener) {
		if (listName.equals(LIST_VALUES) && this.hasNoListeners()) {
			this.engageModel();
		}
		super.addListChangeListener(listName, listener);
	}

	/**
	 * Override to stop listening to the collection holder if appropriate.
	 */
	@Override
	public void removeChangeListener(ChangeListener listener) {
		super.removeChangeListener(listener);
		if (this.hasNoListeners()) {
			this.disengageModel();
		}
	}

	/**
	 * Override to stop listening to the collection holder if appropriate.
	 */
	@Override
	public void removeListChangeListener(String listName, ListChangeListener listener) {
		super.removeListChangeListener(listName, listener);
		if (listName.equals(LIST_VALUES) && this.hasNoListeners()) {
			this.disengageModel();
		}
	}


	// ********** queries **********

	protected boolean hasListeners() {
		return this.hasAnyListChangeListeners(LIST_VALUES);
	}

	protected boolean hasNoListeners() {
		return ! this.hasListeners();
	}

	/**
	 * Return the index of the specified item, using object
	 * identity instead of equality.
	 */
	protected int lastIdentityIndexOf(Object o) {
		return this.lastIdentityIndexOf(o, this.list.size());
	}
	
	/**
	 * Return the last index of the specified item, starting just before the
	 * the specified endpoint, and using object identity instead of equality.
	 */
	protected int lastIdentityIndexOf(Object o, int end) {
		for (int i = end; i-- > 0; ) {
			if (this.list.get(i) == o) {
				return i;
			}
		}
		return -1;
	}
	

	// ********** behavior **********

	protected void buildList() {
		Iterator<? extends E> stream = this.collectionHolder.iterator();
		// if the new collection is empty, do nothing
		if (stream.hasNext()) {
			this.list.ensureCapacity(this.collectionHolder.size());
			while (stream.hasNext()) {
				this.list.add(stream.next());
			}
			this.postBuildList();
		}
	}

	/**
	 * Allow subclasses to manipulate the internal list before
	 * sending out change notification.
	 */
	protected void postBuildList() {
		// the default is to do nothing...
	}

	protected void engageModel() {
		this.collectionHolder.addCollectionChangeListener(CollectionValueModel.VALUES, this.collectionChangeListener);
		// synch our list *after* we start listening to the collection holder,
		// since its value might change when a listener is added
		this.buildList();
	}

	protected void disengageModel() {
		this.collectionHolder.removeCollectionChangeListener(CollectionValueModel.VALUES, this.collectionChangeListener);
		// clear out the list when we are not listening to the collection holder
		this.list.clear();
	}

	protected void itemsAdded(CollectionAddEvent event) {
		this.addItemsToList(this.indexToAddItems(), this.getItems(event), this.list, LIST_VALUES);
	}
	
	protected int indexToAddItems() {
		return this.list.size();
	}

	// minimize scope of suppressed warnings
	@SuppressWarnings("unchecked")
	protected Iterable<E> getItems(CollectionAddEvent event) {
		return (Iterable<E>) event.getItems();
	}

	// minimize scope of suppressed warnings
	@SuppressWarnings("unchecked")
	protected Iterable<E> getItems(CollectionRemoveEvent event) {
		return (Iterable<E>) event.getItems();
	}

	protected void itemsRemoved(CollectionRemoveEvent event) {
		// we have to remove the items individually,
		// since they are probably not in sequence
		for (E item : this.getItems(event)) {
			this.removeItemFromList(this.lastIdentityIndexOf(item), this.list, LIST_VALUES);
		}
	}

	protected void collectionCleared(@SuppressWarnings("unused") CollectionClearEvent event) {
		this.clearList(this.list, LIST_VALUES);
	}
	
	/**
	 * synchronize our internal list with the wrapped collection
	 * and fire the appropriate events
	 */
	protected void collectionChanged(@SuppressWarnings("unused") CollectionChangeEvent event) {
		// put in empty check so we don't fire events unnecessarily
		if ( ! this.list.isEmpty()) {
			@SuppressWarnings("unchecked")
			ArrayList<E> removedItems = (ArrayList<E>) this.list.clone();
			this.list.clear();
			this.fireItemsRemoved(LIST_VALUES, 0, removedItems);
		}

		this.buildList();
		// put in empty check so we don't fire events unnecessarily
		if ( ! this.list.isEmpty()) {
			this.fireItemsAdded(LIST_VALUES, 0, this.list);
		}
	}

	@Override
	public void toString(StringBuilder sb) {
		sb.append(this.collectionHolder);
	}

}
