/*******************************************************************************
 * 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.Collection;
import java.util.IdentityHashMap;
import java.util.Iterator;
import java.util.List;

import org.eclipse.jpt.utility.internal.CollectionTools;
import org.eclipse.jpt.utility.internal.NullList;
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.model.event.CollectionAddEvent;
import org.eclipse.jpt.utility.model.event.CollectionChangeEvent;
import org.eclipse.jpt.utility.model.event.CollectionRemoveEvent;
import org.eclipse.jpt.utility.model.listener.CollectionChangeListener;
import org.eclipse.jpt.utility.model.value.CollectionValueModel;
import org.eclipse.jpt.utility.model.value.ListValueModel;

/**
 * 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 component CVMs by the transformer
 * - component CVMs - the component collection value models that are combined
 *    by this composite collection value model
 * - items - the items held by the component CVMs
 */
public class CompositeCollectionValueModel<E1, E2>
	extends CollectionValueModelWrapper<E1>
	implements CollectionValueModel<E2>
{
	/**
	 * This is the (optional) user-supplied object that transforms
	 * the items in the wrapped collection to collection value models.
	 */
	private final Transformer<E1, CollectionValueModel<E2>> 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<E1, CollectionValueModel<E2>> componentCVMs;

	/**
	 * Cache of the collections corresponding to the component
	 * collection value models above; keyed by the component
	 * collection value models.
	 * Use ArrayLists so we can use ArrayList-specific methods
	 * (e.g. #clone() and #ensureCapacity()).
	 */
	private final IdentityHashMap<CollectionValueModel<E2>, ArrayList<E2>> collections;

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

	/** 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
	 *     - the wrapped collection value model already contains other
	 *       collection value models or
	 *     - you want to override the <code>transform(E1)</code> method
	 *       instead of building a <code>Transformer</code>
	 */
	public CompositeCollectionValueModel(CollectionValueModel<? extends E1> collectionHolder) {
		this(collectionHolder, Transformer.Null.<E1, CollectionValueModel<E2>>instance());
	}

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

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

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

	/**
	 * Construct a collection value model with the specified, unchanging, wrapped
	 * collection. Use this constructor if
	 *     - the wrapped collection already contains collection
	 *       value models or
	 *     - you want to override the <code>transform(E1)</code> method
	 *       instead of building a <code>Transformer</code>
	 */
	public CompositeCollectionValueModel(Collection<? extends E1> collection) {
		this(new StaticCollectionValueModel<E1>(collection));
	}

	/**
	 * Construct a collection value model with the specified, unchanging, wrapped
	 * collection and transformer.
	 */
	public CompositeCollectionValueModel(Collection<? extends E1> collection, Transformer<E1, CollectionValueModel<E2>> transformer) {
		this(new StaticCollectionValueModel<E1>(collection), transformer);
	}


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

	protected CollectionChangeListener buildComponentListener() {
		return new CollectionChangeListener() {
			public void itemsAdded(CollectionAddEvent event) {
				CompositeCollectionValueModel.this.componentItemsAdded(event);
			}		
			public void itemsRemoved(CollectionRemoveEvent event) {
				CompositeCollectionValueModel.this.componentItemsRemoved(event);
			}
			public void collectionCleared(CollectionChangeEvent event) {
				CompositeCollectionValueModel.this.componentCollectionCleared(event);
			}
			public void collectionChanged(CollectionChangeEvent event) {
				CompositeCollectionValueModel.this.componentCollectionChanged(event);
			}
			@Override
			public String toString() {
				return "component listener"; //$NON-NLS-1$
			}
		};
	}


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

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

	protected Iterator<Iterator<E2>> buildCollectionsIterators() {
		return new TransformationIterator<ArrayList<E2>, Iterator<E2>>(this.collections.values().iterator()) {
			@Override
			protected Iterator<E2> transform(ArrayList<E2> 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
		this.addAllComponentSources();
	}

	/**
	 * Transform all the sources to collection value models
	 * and add their items to our cache, with no event notification.
	 */
	protected void addAllComponentSources() {
		for (E1 source : this.collectionHolder) {
			this.addComponentSource(source, NullList.<E2>instance());
		}
	}

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

	/**
	 * Some component sources were added;
	 * add their corresponding items to our cache.
	 */
	@Override
	protected void itemsAdded(CollectionAddEvent event) {
		ArrayList<E2> addedItems = new ArrayList<E2>();
		for (E1 item : this.getAddedItems(event)) {
			this.addComponentSource(item, addedItems);
		}
		this.fireItemsAdded(VALUES, addedItems);
	}

	/**
	 * Transform the specified source to a collection value model
	 * and add its items to our cache and the "collecting parameter".
	 */
	protected void addComponentSource(E1 source, List<E2> addedItems) {
		CollectionValueModel<E2> componentCVM = this.transform(source);
		if (this.componentCVMs.put(source, componentCVM) != null) {
			throw new IllegalStateException("duplicate component: " + source); //$NON-NLS-1$
		}
		componentCVM.addCollectionChangeListener(VALUES, this.componentCVMListener);
		ArrayList<E2> componentCollection = new ArrayList<E2>(componentCVM.size());
		if (this.collections.put(componentCVM, componentCollection) != null) {
			throw new IllegalStateException("duplicate collection: " + source); //$NON-NLS-1$
		}
		this.addComponentItems(componentCVM, componentCollection);
		addedItems.addAll(componentCollection);
	}

	/**
	 * Add the items in the specified component CVM to the specified component
	 * collection.
	 */
	protected void addComponentItems(CollectionValueModel<E2> componentCVM, ArrayList<E2> componentCollection) {
		int itemsSize = componentCVM.size();
		this.size += itemsSize;
		componentCollection.ensureCapacity(componentCollection.size() + itemsSize);
		CollectionTools.addAll(componentCollection, componentCVM);
	}

	/**
	 * Some component sources were removed;
	 * remove their corresponding items from our cache.
	 */
	@Override
	protected void itemsRemoved(CollectionRemoveEvent event) {
		ArrayList<E2> removedItems = new ArrayList<E2>();
		for (E1 item : this.getRemovedItems(event)) {
			this.removeComponentSource(item, removedItems);
		}
		this.fireItemsRemoved(VALUES, removedItems);
	}

	/**
	 * Remove the items corresponding to the specified source
	 * from our cache.
	 */
	protected void removeComponentSource(E1 source, List<E2> removedItems) {
		CollectionValueModel<E2> componentCVM = this.componentCVMs.remove(source);
		if (componentCVM == null) {
			throw new IllegalStateException("missing component: " + source); //$NON-NLS-1$
		}
		componentCVM.removeCollectionChangeListener(VALUES, this.componentCVMListener);
		ArrayList<E2> componentCollection = this.collections.remove(componentCVM);
		if (componentCollection == null) {
			throw new IllegalStateException("missing collection: " + source); //$NON-NLS-1$
		}
		removedItems.addAll(componentCollection);
		this.removeComponentItems(componentCollection);
	}

	/**
	 * Update our size and collection cache.
	 */
	protected void removeComponentItems(ArrayList<E2> componentCollection) {
		this.size -= componentCollection.size();
		componentCollection.clear();
	}

	/**
	 * The component sources cleared;
	 * clear our cache.
	 */
	@Override
	protected void collectionCleared(CollectionChangeEvent event) {
		this.removeAllComponentSources();
		this.fireCollectionCleared(VALUES);
	}

	protected void removeAllComponentSources() {
		// copy the keys so we don't eat our own tail
		ArrayList<E1> copy = new ArrayList<E1>(this.componentCVMs.keySet());
		for (E1 source : copy) {
			this.removeComponentSource(source, NullList.<E2>instance());
		}
	}

	/**
	 * The component sources changed;
	 * rebuild our cache.
	 */
	@Override
	protected void collectionChanged(CollectionChangeEvent event) {
		this.removeAllComponentSources();
		this.addAllComponentSources();
		this.fireCollectionChanged(VALUES);
	}


	// ********** internal methods **********

	/**
	 * 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<E2> transform(E1 value) {
		return this.transformer.transform(value);
	}

	/**
	 * One of the component collections had items added;
	 * synchronize our caches.
	 */
	protected void componentItemsAdded(CollectionAddEvent event) {
		int itemsSize = event.getAddedItemsSize();
		this.size += itemsSize;

		ArrayList<E2> componentCollection = this.collections.get(this.componentCVM(event));
		componentCollection.ensureCapacity(componentCollection.size() + itemsSize);

		this.addItemsToCollection(this.getAddedComponentItems(event), componentCollection, VALUES);
	}

	/**
	 * One of the component collections had items removed;
	 * synchronize our caches.
	 */
	protected void componentItemsRemoved(CollectionRemoveEvent event) {
		this.size -= event.getRemovedItemsSize();
		ArrayList<E2> componentCollection = this.collections.get(this.componentCVM(event));
		this.removeItemsFromCollection(this.getRemovedComponentItems(event), componentCollection, VALUES);
	}

	/**
	 * One of the component collections was cleared;
	 * synchronize our caches by clearing out the appropriate
	 * collection.
	 */
	protected void componentCollectionCleared(CollectionChangeEvent event) {
		ArrayList<E2> componentCollection = this.collections.get(this.componentCVM(event));
		ArrayList<E2> removedItems = new ArrayList<E2>(componentCollection);
		this.removeComponentItems(componentCollection);
		this.fireItemsRemoved(VALUES, removedItems);
	}

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

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

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

	// minimize scope of suppressed warnings
	@SuppressWarnings("unchecked")
	protected CollectionValueModel<E2> componentCVM(CollectionChangeEvent event) {
		return (CollectionValueModel<E2>) event.getSource();
	}

}
