/*******************************************************************************
 * Copyright (c) 2001, 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.ui.internal.views.properties.tabbed.view;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.eclipse.jface.viewers.IFilter;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.ui.views.properties.tabbed.ISectionDescriptor;
import org.eclipse.ui.views.properties.tabbed.ITypeMapper;

/**
 * Provides a section filtering mechanism where the selection is an
 * IStructuredSelection and filtering is based on class.
 * 
 * @author Anthony Hunter
 */
public class TabbedPropertyRegistryClassSectionFilter {

	private ITypeMapper typeMapper = null;

	/**
	 * Constructor for TabbedPropertyRegistryClassSectionFilter
	 * 
	 * @param typeMapper
	 *            the type mapper.
	 */
	public TabbedPropertyRegistryClassSectionFilter(ITypeMapper typeMapper) {
		super();
		this.typeMapper = typeMapper;
	}

	/**
	 * Verifies if the property section extension represented by sectionElement
	 * applies to the given input.
	 * @param descriptor the section descriptor.
	 * @param selection the selection.
	 * @return <code>true</code> if this section applies to the current
	 *         selection.
	 */
	public boolean appliesToSelection(ISectionDescriptor descriptor,
			ISelection selection) {

		if (selection instanceof IStructuredSelection &&
				selection.isEmpty() == false) {

			if (descriptor.getEnablesFor() != ISectionDescriptor.ENABLES_FOR_ANY &&
					((IStructuredSelection) selection).size() != descriptor
							.getEnablesFor()) {
				/**
				 * enablesFor does not match the size of the selection, do not
				 * display section.
				 */
				return false;
			}

			IFilter filter = descriptor.getFilter();

			if (filter != null) {
				for (Iterator i = ((IStructuredSelection) selection).iterator(); i
						.hasNext();) {
					Object object = i.next();

					if (filter != null && filter.select(object) == false) {
						/**
						 * filter fails so section does not apply to the
						 * selection, do not display section.
						 */
						return false;
					}
				}
				/**
				 * filter passes for all objects in the selection.
				 */
				return true;
			}

			Set effectiveTypes = new HashSet();

			for (Iterator i = ((IStructuredSelection) selection).iterator(); i
					.hasNext();) {

				Object object = i.next();

				Class remapType = object.getClass();
				if (typeMapper != null) {
					remapType = typeMapper.mapType(object);
				}

				if (effectiveTypes.add(remapType)) {

					// the effective types of the selection
					if (appliesToEffectiveType(descriptor, remapType) == false) {
						return false;
					}
				}
			}
		}

		return true;
	}

	private boolean appliesToEffectiveType(ISectionDescriptor descriptor,
			Class inputClass) {

		ArrayList classTypes = getClassTypes(inputClass);

		List sectionInputTypes = descriptor.getInputTypes();
		for (Iterator j = sectionInputTypes.iterator(); j.hasNext();) {
			String type = (String) j.next();
			if (classTypes.contains(type)) {
				// found a match
				return true;
			}
		}

		return false;
	}

	/**
	 * Returns the classes and interfaces the given target class
	 * extends/implements.
	 */
	protected ArrayList getClassTypes(Class target) {
		ArrayList result = new ArrayList();
		// add classes
		List classes = computeClassOrder(target);
		for (Iterator i = classes.iterator(); i.hasNext();) {
			result.add(((Class) i.next()).getName());
		}
		// add interfaces
		result.addAll(computeInterfaceOrder(classes));
		return result;
	}

	private List computeClassOrder(Class target) {
		List result = new ArrayList(4);
		Class clazz = target;
		while (clazz != null) {
			result.add(clazz);
			clazz = clazz.getSuperclass();
		}
		return result;
	}

	private List computeInterfaceOrder(List classes) {
		List result = new ArrayList(4);
		Map seen = new HashMap(4);
		for (Iterator iter = classes.iterator(); iter.hasNext();) {
			Class[] interfaces = ((Class) iter.next()).getInterfaces();
			internalComputeInterfaceOrder(interfaces, result, seen);
		}
		return result;
	}

	private void internalComputeInterfaceOrder(Class[] interfaces, List result,
			Map seen) {
		List newInterfaces = new ArrayList(seen.size());
		for (int i = 0; i < interfaces.length; i++) {
			Class interfac = interfaces[i];
			if (seen.get(interfac) == null) {
				result.add(interfac.getName());
				seen.put(interfac, interfac);
				newInterfaces.add(interfac);
			}
		}
		for (Iterator iter = newInterfaces.iterator(); iter.hasNext();) {
			internalComputeInterfaceOrder(
					((Class) iter.next()).getInterfaces(), result, seen);
		}
	}
}
