/*******************************************************************************
 * Copyright (c) 2006, 2007 IBM Corporation and others.
 * 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:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/

package org.eclipse.core.databinding.observable.set;

import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

import org.eclipse.core.databinding.observable.Diffs;
import org.eclipse.core.databinding.observable.Realm;
import org.eclipse.core.databinding.observable.map.IMapChangeListener;
import org.eclipse.core.databinding.observable.map.IObservableMap;
import org.eclipse.core.databinding.observable.map.MapChangeEvent;
import org.eclipse.core.databinding.observable.map.MapDiff;

/**
 * 
 * <p>
 * This class is thread safe. All state accessing methods must be invoked from
 * the {@link Realm#isCurrent() current realm}. Methods for adding and removing
 * listeners may be invoked from any thread.
 * </p>
 * 
 * @since 1.0
 * 
 */
public class MappedSet extends ObservableSet {

	private final IObservableMap wrappedMap;

	/*
	 * Map from values (range elements) to Integer ref counts
	 */
	private Map valueCounts = new HashMap();

	private ISetChangeListener domainListener = new ISetChangeListener() {
		public void handleSetChange(SetChangeEvent event) {
			Set additions = new HashSet();
			for (Iterator it = event.diff.getAdditions().iterator(); it.hasNext();) {
				Object added = it.next();
				Object mapValue = wrappedMap.get(added);
				if (handleAddition(mapValue)) {
					additions.add(mapValue);
				}
			}
			Set removals = new HashSet();
			for (Iterator it = event.diff.getRemovals().iterator(); it.hasNext();) {
				Object removed = it.next();
				Object mapValue = wrappedMap.get(removed);
				if (handleRemoval(mapValue)) {
					removals.add(mapValue);
				}
			}
			fireSetChange(Diffs.createSetDiff(additions, removals));
		}
	};

	private IMapChangeListener mapChangeListener = new IMapChangeListener() {
		public void handleMapChange(MapChangeEvent event) {
			MapDiff diff = event.diff;
			Set additions = new HashSet();
			Set removals = new HashSet();
			for (Iterator it = diff.getRemovedKeys().iterator(); it.hasNext();) {
				Object key = it.next();
				Object oldValue = diff.getOldValue(key);
				if (handleRemoval(oldValue)) {
					removals.add(oldValue);
				}
			}
			for (Iterator it = diff.getChangedKeys().iterator(); it.hasNext();) {
				Object key = it.next();
				Object oldValue = diff.getOldValue(key);
				Object newValue = diff.getNewValue(key);
				if (handleRemoval(oldValue)) {
					removals.add(oldValue);
				}
				if (handleAddition(newValue)) {
					additions.add(newValue);
				}
			}
			for (Iterator it = diff.getAddedKeys().iterator(); it.hasNext();) {
				Object key = it.next();
				Object newValue = diff.getNewValue(key);
				if (handleAddition(newValue)) {
					additions.add(newValue);
				}
			}
			fireSetChange(Diffs.createSetDiff(additions, removals));
		}
	};

	private IObservableSet input;

	/**
	 * @param input
	 * @param map
	 */
	public MappedSet(IObservableSet input, IObservableMap map) {
		super(input.getRealm(), Collections.EMPTY_SET, Object.class);
		setWrappedSet(valueCounts.keySet());
		this.wrappedMap = map;
		this.input = input;
		for (Iterator it = input.iterator(); it.hasNext();) {
			Object element = it.next();
			Object functionValue = wrappedMap.get(element);
			handleAddition(functionValue);
		}
		input.addSetChangeListener(domainListener);
		map.addMapChangeListener(mapChangeListener);
	}

	/**
	 * @param mapValue
	 * @return true if the given mapValue was an addition
	 */
	protected boolean handleAddition(Object mapValue) {
		Integer count = (Integer) valueCounts.get(mapValue);
		if (count == null) {
			valueCounts.put(mapValue, new Integer(1));
			return true;
		}
		valueCounts.put(mapValue, new Integer(count.intValue() + 1));
		return false;
	}

	/**
	 * @param mapValue
	 * @return true if the given mapValue has been removed
	 */
	protected boolean handleRemoval(Object mapValue) {
		Integer count = (Integer) valueCounts.get(mapValue);
		if (count.intValue() <= 1) {
			valueCounts.remove(mapValue);
			return true;
		}
		valueCounts.put(mapValue, new Integer(count.intValue() - 1));
		return false;
	}

	public synchronized void dispose() {
		wrappedMap.removeMapChangeListener(mapChangeListener);
		input.removeSetChangeListener(domainListener);
	}

}
