/*******************************************************************************
 * Copyright (c) 2001, 2006 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.
	 */
	protected TabbedPropertyRegistryClassSectionFilter(ITypeMapper typeMapper) {
		super();
		this.typeMapper = typeMapper;
	}

	/**
	 * Verifies if the property section extension represented by sectionElement
	 * applies to the given input.
	 */
	protected 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);
		}
	}
}
