/*******************************************************************************
 * Copyright (c) 2007, 2008 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.IdentityHashMap;
import java.util.Iterator;

import org.eclipse.jpt.utility.internal.Transformer;
import org.eclipse.jpt.utility.internal.iterators.CompositeIterator;
import org.eclipse.jpt.utility.internal.iterators.TransformationIterator;
import org.eclipse.jpt.utility.internal.model.event.CollectionChangeEvent;
import org.eclipse.jpt.utility.internal.model.listener.CollectionChangeListener;

/**
 * A <code>CompositeCollectionValueModel</code> wraps another
 * <code>CollectionValueModel</code> and uses a <code>Transformer</code>
 * to convert each item in the wrapped collection to yet another
 * <code>CollectionValueModel</code>. This composite collection contains
 * the combined items from all these component collections.
 * 
 * NB: The wrapped collection must be an "identity set" that does not
 * contain the same item twice or this class will throw an exception.
 * 
 * Terminology:
 * - sources - the items in the wrapped collection value model; these
 * 	are converted into components by the transformer
 * - components - the component collection value models that are combined
 * 	by this composite collection value model
 */
public class CompositeCollectionValueModel<T, E>
	extends CollectionValueModelWrapper<T>
	implements CollectionValueModel<E>
{
	/**
	 * This is the (optional) user-supplied object that transforms
	 * the items in the wrapped collection to collection value models.
	 */
	private final Transformer<T, CollectionValueModel<E>> transformer;

	/**
	 * Cache of the component collection value models that
	 * were generated by the transformer; keyed by the item
	 * in the wrapped collection that was passed to the transformer.
	 */
	private final IdentityHashMap<T, CollectionValueModel<E>> components;

	/**
	 * Cache of the collections corresponding to the component
	 * collection value models above; keyed by the component
	 * collection value models.
	 */
	private final IdentityHashMap<CollectionValueModel<E>, ArrayList<E>> collections;

	/** Listener that listens to all the component collection value models. */
	private final CollectionChangeListener componentListener;

	/** Cache the size of the composite collection. */
	private int size;


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

	/**
	 * Construct a collection value model with the specified wrapped
	 * collection value model. Use this constructor if you want to override the
	 * <code>transform(Object)</code> method instead of building a
	 * <code>Transformer</code>.
	 */
	public CompositeCollectionValueModel(CollectionValueModel<? extends T> collectionHolder) {
		this(collectionHolder, Transformer.Disabled.<T, CollectionValueModel<E>>instance());
	}

	/**
	 * Construct a collection value model with the specified wrapped
	 * collection value model and transformer.
	 */
	public CompositeCollectionValueModel(CollectionValueModel<? extends T> collectionHolder, Transformer<T, CollectionValueModel<E>> transformer) {
		super(collectionHolder);
		this.transformer = transformer;
		this.components = new IdentityHashMap<T, CollectionValueModel<E>>();
		this.collections = new IdentityHashMap<CollectionValueModel<E>, ArrayList<E>>();
		this.componentListener = this.buildComponentListener();
		this.size = 0;
	}

	/**
	 * Construct a collection value model with the specified wrapped
	 * list value model. Use this constructor if you want to override the
	 * <code>transform(Object)</code> method instead of building a
	 * <code>Transformer</code>.
	 */
	public CompositeCollectionValueModel(ListValueModel<? extends T> listHolder) {
		this(new ListCollectionValueModelAdapter<T>(listHolder));
	}

	/**
	 * Construct a collection value model with the specified wrapped
	 * list value model and transformer.
	 */
	public CompositeCollectionValueModel(ListValueModel<? extends T> listHolder, Transformer<T, CollectionValueModel<E>> transformer) {
		this(new ListCollectionValueModelAdapter<T>(listHolder), transformer);
	}


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

	protected CollectionChangeListener buildComponentListener() {
		return new CollectionChangeListener() {
			public void itemsAdded(CollectionChangeEvent e) {
				CompositeCollectionValueModel.this.componentItemsAdded(e);
			}		
			public void itemsRemoved(CollectionChangeEvent e) {
				CompositeCollectionValueModel.this.componentItemsRemoved(e);
			}
			public void collectionCleared(CollectionChangeEvent e) {
				CompositeCollectionValueModel.this.componentCollectionCleared(e);
			}
			public void collectionChanged(CollectionChangeEvent e) {
				CompositeCollectionValueModel.this.componentCollectionChanged(e);
			}
			@Override
			public String toString() {
				return "component listener";
			}
		};
	}


	// ********** CollectionValueModel implementation **********

	public Iterator<E> iterator() {
		return new CompositeIterator<E>(this.buildCollectionsIterators());
	}

	protected Iterator<Iterator<E>> buildCollectionsIterators() {
		return new TransformationIterator<ArrayList<E>, Iterator<E>>(this.collections.values().iterator()) {
			@Override
			protected Iterator<E> transform(ArrayList<E> next) {
				return next.iterator();
			}
		};
	}

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


	// ********** CollectionValueModelWrapper overrides/implementation **********

	@Override
	protected void engageModel() {
		super.engageModel();
		// synch our cache *after* we start listening to the wrapped collection,
		// since its value might change when a listener is added;
		// the following will trigger the firing of a number of unnecessary events
		// (since we don't have any listeners yet),
		// but it reduces the amount of duplicate code
		this.addComponentSources(this.collectionHolder.iterator());
	}

	@Override
	protected void disengageModel() {
		super.disengageModel();
		// stop listening to the components...
		for (CollectionValueModel<E> cvm : this.components.values()) {
			cvm.removeCollectionChangeListener(CollectionValueModel.VALUES, this.componentListener);
		}
		// ...and clear the cache
		this.components.clear();
		this.collections.clear();
		this.size = 0;
	}

	/**
	 * Some component sources were added;
	 * add their corresponding items to our cache.
	 */
	@Override
	protected void itemsAdded(CollectionChangeEvent e) {
		this.addComponentSources(this.items(e));
	}

	/**
	 * Transform the specified sources to collection value models
	 * and add their items to our cache.
	 */
	protected void addComponentSources(Iterator<? extends T> sources) {
		while (sources.hasNext()) {
			this.addComponentSource(sources.next());
		}
	}

	/**
	 * Transform the specified source to a collection value model
	 * and add its items to our cache.
	 */
	protected void addComponentSource(T source) {
		CollectionValueModel<E> component = this.transform(source);
		if (this.components.put(source, component) != null) {
			throw new IllegalStateException("duplicate component: " + source);
		}
		component.addCollectionChangeListener(CollectionValueModel.VALUES, this.componentListener);
		ArrayList<E> componentCollection = new ArrayList<E>(component.size());
		if (this.collections.put(component, componentCollection) != null) {
			throw new IllegalStateException("duplicate collection: " + source);
		}
		this.addComponentItems(component, componentCollection);
	}

	/**
	 * Some component sources were removed;
	 * remove their corresponding items from our cache.
	 */
	@Override
	protected void itemsRemoved(CollectionChangeEvent e) {
		this.removeComponentSources(this.items(e));
	}

	/**
	 * Remove the items corresponding to the specified sources
	 * from our cache.
	 */
	protected void removeComponentSources(Iterator<T> sources) {
		while (sources.hasNext()) {
			this.removeComponentSource(sources.next());
		}
	}

	/**
	 * Remove the items corresponding to the specified source
	 * from our cache.
	 */
	protected void removeComponentSource(T source) {
		CollectionValueModel<E> component = this.components.remove(source);
		if (component == null) {
			throw new IllegalStateException("missing component: " + source);
		}
		component.removeCollectionChangeListener(CollectionValueModel.VALUES, this.componentListener);
		ArrayList<E> componentCollection = this.collections.remove(component);
		if (componentCollection == null) {
			throw new IllegalStateException("missing collection: " + source);
		}
		this.clearComponentItems(componentCollection);
	}

	/**
	 * The component sources cleared;
	 * clear our cache.
	 */
	@Override
	protected void collectionCleared(CollectionChangeEvent e) {
		// copy the keys so we don't eat our own tail
		this.removeComponentSources(new ArrayList<T>(this.components.keySet()).iterator());
	}

	/**
	 * The component sources changed;
	 * rebuild our cache.
	 */
	@Override
	protected void collectionChanged(CollectionChangeEvent e) {
		// copy the keys so we don't eat our own tail
		this.removeComponentSources(new ArrayList<T>(this.components.keySet()).iterator());
		this.addComponentSources(this.collectionHolder.iterator());
	}


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

	/**
	 * Return the cached collection for the specified component model.
	 * Cast to ArrayList so we can use ArrayList-specific methods
	 * (e.g. #clone() and #ensureCapacity()).
	 */
	protected ArrayList<E> componentCollection(CollectionValueModel<E> collectionValueModel) {
		return this.collections.get(collectionValueModel);
	}


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

	/**
	 * Transform the specified object into a collection value model.
	 * <p>
	 * This method can be overridden by a subclass as an
	 * alternative to building a <code>Transformer</code>.
	 */
	protected CollectionValueModel<E> transform(T value) {
		return this.transformer.transform(value);
	}

	/**
	 * One of the component collections had items added;
	 * synchronize our caches.
	 */
	protected void componentItemsAdded(CollectionChangeEvent e) {
		this.addComponentItems(this.componentItems(e), e.itemsSize(), this.componentCVM(e));
	}

	/**
	 * Update our cache.
	 */
	protected void addComponentItems(Iterator<E> items, int itemsSize, CollectionValueModel<E> cvm) {
		this.addComponentItems(items, itemsSize, this.componentCollection(cvm));
	}

	/**
	 * Update our cache.
	 */
	protected void addComponentItems(CollectionValueModel<E> itemsHolder, ArrayList<E> componentCollection) {
		this.addComponentItems(itemsHolder.iterator(), itemsHolder.size(), componentCollection);
	}

	/**
	 * Update our size and collection cache.
	 */
	protected void addComponentItems(Iterator<E> items, int itemsSize, ArrayList<E> componentCollection) {
		this.size += itemsSize;
		componentCollection.ensureCapacity(componentCollection.size() + itemsSize);
		this.addItemsToCollection(items, componentCollection, CollectionValueModel.VALUES);
	}

	/**
	 * One of the component collections had items removed;
	 * synchronize our caches.
	 */
	protected void componentItemsRemoved(CollectionChangeEvent e) {
		this.removeComponentItems(this.componentItems(e), e.itemsSize(), this.componentCVM(e));
	}

	/**
	 * Update our size and collection cache.
	 */
	protected void removeComponentItems(Iterator<E> items, int itemsSize, CollectionValueModel<E> cvm) {
		this.removeComponentItems(items, itemsSize, this.componentCollection(cvm));
	}

	/**
	 * Update our size and collection cache.
	 */
	protected void clearComponentItems(ArrayList<E> items) {
		// clone the collection so we don't eat our own tail
		@SuppressWarnings("unchecked") ArrayList<E> clone = (ArrayList<E>) items.clone();
		this.removeComponentItems(clone.iterator(), items.size(), items);
	}

	/**
	 * Update our size and collection cache.
	 */
	protected void removeComponentItems(Iterator<E> items, int itemsSize, ArrayList<E> componentCollection) {
		this.size -= itemsSize;
		this.removeItemsFromCollection(items, componentCollection, CollectionValueModel.VALUES);
	}

	/**
	 * One of the component collections was cleared;
	 * synchronize our caches by clearing out the appropriate
	 * collection.
	 */
	protected void componentCollectionCleared(CollectionChangeEvent e) {
		ArrayList<E> items = this.componentCollection(this.componentCVM(e));
		this.clearComponentItems(items);
	}

	/**
	 * One of the component collections changed;
	 * synchronize our caches by clearing out the appropriate
	 * collection and then rebuilding it.
	 */
	protected void componentCollectionChanged(CollectionChangeEvent e) {
		CollectionValueModel<E> componentCVM = this.componentCVM(e);
		ArrayList<E> items = this.componentCollection(componentCVM);
		this.clearComponentItems(items);
		this.addComponentItems(componentCVM, items);
	}

	// minimize suppressed warnings
	@SuppressWarnings("unchecked")
	protected Iterator<E> componentItems(CollectionChangeEvent e) {
		return (Iterator<E>) e.items();
	}

	// minimize suppressed warnings
	@SuppressWarnings("unchecked")
	protected CollectionValueModel<E> componentCVM(CollectionChangeEvent e) {
		return (CollectionValueModel<E>) e.getSource();
	}

}
