/*******************************************************************************
 * Copyright (c) 2000, 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;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.Platform;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.ui.actions.SimpleWildcardTester;
import org.eclipse.ui.internal.ActionExpression;
import org.eclipse.ui.internal.registry.IWorkbenchRegistryConstants;
import org.eclipse.ui.internal.util.Util;
import org.eclipse.ui.model.IWorkbenchAdapter;
import org.osgi.framework.Bundle;

/**
 * Determines the enablement status given a selection. This calculation is done
 * based on the definition of the <code>enablesFor</code> attribute,
 * <code>enablement</code> element, and the <code>selection</code> element
 * found in the <code>IConfigurationElement</code> provided.
 * <p>
 * This class can be instantiated by clients. It is not intended to be extended.
 * </p>
 * 
 * @since 1.0
 * 
 * Note: The dependency on org.eclipse.jface.text for ITextSelection must be
 * severed It may be possible to do with IActionFilter generic workbench
 * registers IActionFilter for "size" property against IStructuredSelection
 * workbench text registers IActionFilter for "size" property against
 * ITextSelection code here: sel.getAdapter(IActionFilter.class) As an interim
 * solution, use reflection to access selections implementing ITextSelection
 */
public final class SelectionEnabler {

	/* package */static class SelectionClass {
		public String className;

		public String nameFilter;

		public boolean recursive;
	}

	public static final int ANY_NUMBER = -2;

	/**
	 * The constant integer hash code value meaning the hash code has not yet
	 * been computed.
	 */
	private static final int HASH_CODE_NOT_COMPUTED = -1;

	/**
	 * A factor for computing the hash code for all schemes.
	 */
	private static final int HASH_FACTOR = 89;

	/**
	 * The seed for the hash code for all schemes.
	 */
	private static final int HASH_INITIAL = SelectionEnabler.class.getName()
			.hashCode();

	/**
	 * Cached value of <code>org.eclipse.jface.text.ITextSelection.class</code>;
	 * <code>null</code> if not initialized or not present.
	 */
	private static Class iTextSelectionClass = null;

	/**
	 * Hard-wired id of the JFace text plug-in (not on pre-req chain).
	 */
	private static final String JFACE_TEXT_PLUG_IN = "org.eclipse.jface.text"; //$NON-NLS-1$

	public static final int MULTIPLE = -5;

	public static final int NONE = -4;

	public static final int NONE_OR_ONE = -3;

	public static final int ONE_OR_MORE = -1;

	/**
	 * Hard-wired fully qualified name of the text selection class (not on
	 * pre-req chain).
	 */
	private static final String TEXT_SELECTION_CLASS = "org.eclipse.jface.text.ITextSelection"; //$NON-NLS-1$

	/**
	 * Indicates whether the JFace text plug-in is even around. Without the
	 * JFace text plug-in, text selections are moot.
	 */
	private static boolean textSelectionPossible = true;

	public static final int UNKNOWN = 0;

	/**
	 * Returns <code>ITextSelection.class</code> or <code>null</code> if the
	 * class is not available.
	 * 
	 * @return <code>ITextSelection.class</code> or <code>null</code> if
	 *         class not available
	 */
	private static Class getTextSelectionClass() {
		if (iTextSelectionClass != null) {
			// tried before and succeeded
			return iTextSelectionClass;
		}
		if (!textSelectionPossible) {
			// tried before and failed
			return null;
		}

		// JFace text plug-in is not on prereq chain of generic wb plug-in
		// hence: ITextSelection.class won't compile
		// and Class.forName("org.eclipse.jface.text.ITextSelection") won't find
		// it need to be trickier...
		Bundle bundle = Platform.getBundle(JFACE_TEXT_PLUG_IN);
		if (bundle == null || bundle.getState() == Bundle.UNINSTALLED) {
			// JFace text plug-in is not around, or has already
			// been removed, assume that it will never be around
			textSelectionPossible = false;
			return null;
		}

		// plug-in is around
		// it's not our job to activate the plug-in
		if (bundle.getState() == Bundle.INSTALLED) {
			// assume it might come alive later
			textSelectionPossible = true;
			return null;
		}

		try {
			Class c = bundle.loadClass(TEXT_SELECTION_CLASS);
			// remember for next time
			iTextSelectionClass = c;
			return iTextSelectionClass;
		} catch (ClassNotFoundException e) {
			// unable to load ITextSelection - sounds pretty serious
			// treat as if JFace text plug-in were unavailable
			textSelectionPossible = false;
			return null;
		}
	}

	/**
	 * Verifies that the given name matches the given wildcard filter. Returns
	 * true if it does.
	 * 
	 * @param name
	 * @param filter
	 * @return <code>true</code> if there is a match
	 */
	public static boolean verifyNameMatch(String name, String filter) {
		return SimpleWildcardTester.testWildcardIgnoreCase(filter, name);
	}

	private List classes = new ArrayList();

	private ActionExpression enablementExpression;

	/**
	 * The hash code for this object. This value is computed lazily, and marked
	 * as invalid when one of the values on which it is based changes.
	 */
	private transient int hashCode = HASH_CODE_NOT_COMPUTED;

	private int mode = UNKNOWN;

	/**
	 * Create a new instance of the receiver.
	 * 
	 * @param configElement
	 */
	public SelectionEnabler(IConfigurationElement configElement) {
		super();
		if (configElement == null) {
			throw new IllegalArgumentException();
		}
		parseClasses(configElement);
	}

	public final boolean equals(final Object object) {
		if (object instanceof SelectionEnabler) {
			final SelectionEnabler that = (SelectionEnabler) object;
			return Util.equals(this.classes, that.classes)
					&& Util.equals(this.enablementExpression,
							that.enablementExpression)
					&& Util.equals(this.mode, that.mode);
		}

		return false;
	}

	/**
	 * Computes the hash code for this object based on the id.
	 * 
	 * @return The hash code for this object.
	 */
	public final int hashCode() {
		if (hashCode == HASH_CODE_NOT_COMPUTED) {
			hashCode = HASH_INITIAL * HASH_FACTOR + Util.hashCode(classes);
			hashCode = hashCode * HASH_FACTOR
					+ Util.hashCode(enablementExpression);
			hashCode = hashCode * HASH_FACTOR + Util.hashCode(mode);
			if (hashCode == HASH_CODE_NOT_COMPUTED) {
				hashCode++;
			}
		}
		return hashCode;
	}

	/**
	 * Returns true if given structured selection matches the conditions
	 * specified in the registry for this action.
	 */
	private boolean isEnabledFor(ISelection sel) {
		Object obj = sel;
		int count = sel.isEmpty() ? 0 : 1;

		if (verifySelectionCount(count) == false) {
			return false;
		}

		// Compare selection to enablement expression.
		if (enablementExpression != null) {
			return enablementExpression.isEnabledFor(obj);
		}

		// Compare selection to class requirements.
		if (classes.isEmpty()) {
			return true;
		}
		if (obj instanceof IAdaptable) {
			IAdaptable element = (IAdaptable) obj;
			if (verifyElement(element) == false) {
				return false;
			}
		} else {
			return false;
		}

		return true;
	}

	/**
	 * Returns true if given text selection matches the conditions specified in
	 * the registry for this action.
	 */
	private boolean isEnabledFor(ISelection sel, int count) {
		if (verifySelectionCount(count) == false) {
			return false;
		}

		// Compare selection to enablement expression.
		if (enablementExpression != null) {
			return enablementExpression.isEnabledFor(sel);
		}

		// Compare selection to class requirements.
		if (classes.isEmpty()) {
			return true;
		}
		for (int i = 0; i < classes.size(); i++) {
			SelectionClass sc = (SelectionClass) classes.get(i);
			if (verifyClass(sel, sc.className)) {
				return true;
			}
		}
		return false;
	}

	/**
	 * Returns true if given structured selection matches the conditions
	 * specified in the registry for this action.
	 */
	private boolean isEnabledFor(IStructuredSelection ssel) {
		int count = ssel.size();

		if (verifySelectionCount(count) == false) {
			return false;
		}

		// Compare selection to enablement expression.
		if (enablementExpression != null) {
			return enablementExpression.isEnabledFor(ssel);
		}

		// Compare selection to class requirements.
		if (classes.isEmpty()) {
			return true;
		}
		for (Iterator elements = ssel.iterator(); elements.hasNext();) {
			Object obj = elements.next();
			if (obj instanceof IAdaptable) {
				IAdaptable element = (IAdaptable) obj;
				if (verifyElement(element) == false) {
					return false;
				}
			} else {
				return false;
			}
		}

		return true;
	}

	/**
	 * Check if the receiver is enabled for the given selection.
	 * 
	 * @param selection
	 * @return <code>true</code> if the given selection matches the conditions
	 *         specified in <code>IConfirgurationElement</code>.
	 */
	public boolean isEnabledForSelection(ISelection selection) {
		// Optimize it.
		if (mode == UNKNOWN) {
			return false;
		}

		// Handle undefined selections.
		if (selection == null) {
			selection = StructuredSelection.EMPTY;
		}

		// According to the dictionary, a selection is "one that
		// is selected", or "a collection of selected things".
		// In reflection of this, we deal with one or a collection.

		// special case: structured selections
		if (selection instanceof IStructuredSelection) {
			return isEnabledFor((IStructuredSelection) selection);
		}

		// special case: text selections
		// Code should read
		// if (selection instanceof ITextSelection) {
		// int count = ((ITextSelection) selection).getLength();
		// return isEnabledFor(selection, count);
		// }
		// use Java reflection to avoid dependence of org.eclipse.jface.text
		// which is in an optional part of the generic workbench
		Class tselClass = getTextSelectionClass();
		if (tselClass != null && tselClass.isInstance(selection)) {
			try {
				Method m = tselClass.getDeclaredMethod(
						"getLength", new Class[0]); //$NON-NLS-1$
				Object r = m.invoke(selection, new Object[0]);
				if (r instanceof Integer) {
					return isEnabledFor(selection, ((Integer) r).intValue());
				}
				// should not happen - but enable if it does
				return true;
			} catch (NoSuchMethodException e) {
				// should not happen - fall through if it does
			} catch (IllegalAccessException e) {
				// should not happen - fall through if it does
			} catch (InvocationTargetException e) {
				// should not happen - fall through if it does
			}
		}

		// all other cases
		return isEnabledFor(selection);
	}

	/**
	 * Parses registry element to extract mode and selection elements that will
	 * be used for verification.
	 */
	private void parseClasses(IConfigurationElement config) {
		// Get enables for.
		String enablesFor = config
				.getAttribute(IWorkbenchRegistryConstants.ATT_ENABLES_FOR);
		if (enablesFor == null) {
			enablesFor = "*"; //$NON-NLS-1$
		}
		if (enablesFor.equals("*")) { //$NON-NLS-1$
			mode = ANY_NUMBER;
		} else if (enablesFor.equals("?")) { //$NON-NLS-1$
			mode = NONE_OR_ONE;
		} else if (enablesFor.equals("!")) { //$NON-NLS-1$
			mode = NONE;
		} else if (enablesFor.equals("+")) { //$NON-NLS-1$
			mode = ONE_OR_MORE;
		} else if (enablesFor.equals("multiple") //$NON-NLS-1$
				|| enablesFor.equals("2+")) { //$NON-NLS-1$
			mode = MULTIPLE;
		} else {
			try {
				mode = Integer.parseInt(enablesFor);
			} catch (NumberFormatException e) {
				mode = UNKNOWN;
			}
		}

		// Get enablement block.
		IConfigurationElement[] children = config
				.getChildren(IWorkbenchRegistryConstants.TAG_ENABLEMENT);
		if (children.length > 0) {
			enablementExpression = new ActionExpression(children[0]);
			return;
		}

		// Get selection block.
		children = config
				.getChildren(IWorkbenchRegistryConstants.TAG_SELECTION);
		if (children.length > 0) {
			classes = new ArrayList();
			for (int i = 0; i < children.length; i++) {
				IConfigurationElement sel = children[i];
				String cname = sel
						.getAttribute(IWorkbenchRegistryConstants.ATT_CLASS);
				String name = sel
						.getAttribute(IWorkbenchRegistryConstants.ATT_NAME);
				SelectionClass sclass = new SelectionClass();
				sclass.className = cname;
				sclass.nameFilter = name;
				classes.add(sclass);
			}
		}
	}

	/**
	 * Verifies if the element is an instance of a class with a given class
	 * name. If direct match fails, implementing interfaces will be tested, then
	 * recursively all superclasses and their interfaces.
	 */
	private boolean verifyClass(Object element, String className) {
		Class eclass = element.getClass();
		Class clazz = eclass;
		boolean match = false;
		while (clazz != null) {
			// test the class itself
			if (clazz.getName().equals(className)) {
				match = true;
				break;
			}
			// test all the interfaces it implements
			Class[] interfaces = clazz.getInterfaces();
			for (int i = 0; i < interfaces.length; i++) {
				if (interfaces[i].getName().equals(className)) {
					match = true;
					break;
				}
			}
			if (match == true) {
				break;
			}
			// get the superclass
			clazz = clazz.getSuperclass();
		}
		return match;
	}

	/**
	 * Verifies if the given element matches one of the selection requirements.
	 * Element must at least pass the type test, and optionally wildcard name
	 * match.
	 */
	private boolean verifyElement(IAdaptable element) {
		if (classes.isEmpty()) {
			return true;
		}
		for (int i = 0; i < classes.size(); i++) {
			SelectionClass sc = (SelectionClass) classes.get(i);
			if (verifyClass(element, sc.className) == false) {
				continue;
			}
			if (sc.nameFilter == null) {
				return true;
			}
			IWorkbenchAdapter de = (IWorkbenchAdapter) Util.getAdapter(element, IWorkbenchAdapter.class);
			if ((de != null)
					&& verifyNameMatch(de.getLabel(element), sc.nameFilter)) {
				return true;
			}
		}
		return false;
	}

	/**
	 * Compare selection count with requirements.
	 */
	private boolean verifySelectionCount(int count) {
		if (count > 0 && mode == NONE) {
			return false;
		}
		if (count == 0 && mode == ONE_OR_MORE) {
			return false;
		}
		if (count > 1 && mode == NONE_OR_ONE) {
			return false;
		}
		if (count < 2 && mode == MULTIPLE) {
			return false;
		}
		if (mode > 0 && count != mode) {
			return false;
		}
		return true;
	}
}
