/*******************************************************************************
 * Copyright (c) 2005 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.commands;

import org.eclipse.core.commands.common.HandleObject;
import org.eclipse.core.commands.common.NotDefinedException;
import org.eclipse.core.internal.commands.util.Util;

/**
 * <p>
 * Provides information about the type of a command parameter. Clients can use a
 * parameter type to check if an object matches the type of the parameter with
 * {@link #isCompatible(Object)} and can get an
 * {@link AbstractParameterValueConverter} to convert between objects matching
 * the parameter type and strings that encode the object's identity.
 * </p>
 * <p>
 * A command parameter is not required to declare a type. To determine if a
 * given parameter has a type, check if an {@link IParameter} implements
 * {@link ITypedParameter} and if so, use
 * {@link ITypedParameter#getParameterType()} like this:
 * </p>
 * 
 * <pre>
 *                   IParameter parameter = // ... get IParameter from Command
 *                   if (parameter instanceof ITypedParameter) {
 *                     ParameterType type = ((ITypedParameter)parameter).getParameterType();
 *                     if (type != null) {
 *                       // this parameter has a ParameterType
 *                     }
 *                   }
 * </pre>
 * 
 * @see IParameter
 * @see ITypedParameter#getParameterType()
 * @since 3.2
 */
public final class ParameterType extends HandleObject implements Comparable {

	/**
	 * TODO: this was copied from
	 * org.eclipse.core.internal.expressions.Expressions is there a better place
	 * to reference this?
	 * 
	 * @param element
	 *            The element to test; may be <code>null</code>.
	 * @param type
	 *            The type against which we are testing;may be <code>null</code>.
	 * @return <code>true</code> if the <code>element</code> is an instance
	 *         of <code>type</code>; <code>false</code> otherwise.
	 */
	private static final boolean isInstanceOf(final Object element,
			final String type) {
		// null isn't an instanceof of anything.
		if (element == null)
			return false;
		return isSubtype(element.getClass(), type);
	}

	/**
	 * TODO: this was copied from
	 * org.eclipse.core.internal.expressions.Expressions is there a better place
	 * to reference this?
	 * 
	 * @param clazz
	 *            The class to match; may be <code>null</code>.
	 * @param type
	 *            The type against which we are testing;may be <code>null</code>.
	 * @return <code>true</code> if the <code>element</code> is an instance
	 *         of <code>type</code>; <code>false</code> otherwise.
	 */
	private static final boolean isSubtype(final Class clazz, final String type) {
		if (clazz.getName().equals(type))
			return true;
		final Class superClass = clazz.getSuperclass();
		if (superClass != null && isSubtype(superClass, type))
			return true;
		final Class[] interfaces = clazz.getInterfaces();
		for (int i = 0; i < interfaces.length; i++) {
			if (isSubtype(interfaces[i], type))
				return true;
		}
		return false;
	}

	/**
	 * An {@link AbstractParameterValueConverter} for converting parameter
	 * values between objects and strings. This may be <code>null</code>.
	 */
	private transient AbstractParameterValueConverter parameterTypeConverter;

	/**
	 * A string specifying the object type of this parameter type. This will be
	 * <code>null</code> when the parameter type is undefined but never null
	 * when it is defined.
	 */
	private transient String type = null;

	/**
	 * Constructs a new instance based on the given identifier. When a parameter
	 * type is first constructed, it is undefined. Parameter types should only
	 * be constructed by the {@link CommandManager} to ensure that the
	 * identifier remains unique.
	 * 
	 * @param id
	 *            The identifier for this type. This value must not be
	 *            <code>null</code>, and must be unique amongst all parameter
	 *            types.
	 */
	ParameterType(final String id) {
		super(id);
	}

	/**
	 * Adds a listener to this parameter type that will be notified when its
	 * state changes.
	 * 
	 * @param listener
	 *            The listener to be added; must not be <code>null</code>.
	 */
	public final void addListener(final IParameterTypeListener listener) {
		addListenerObject(listener);
	}

	/**
	 * Compares this parameter type with another object by comparing each of the
	 * non-transient attributes.
	 * 
	 * @param object
	 *            The object with which to compare; must be an instance of
	 *            {@link ParameterType}.
	 * @return A negative integer, zero or a positive integer, if the object is
	 *         greater than, equal to or less than this parameter type.
	 */
	public final int compareTo(final Object object) {
		final ParameterType castedObject = (ParameterType) object;
		int compareTo = Util.compare(defined, castedObject.defined);
		if (compareTo == 0) {
			compareTo = Util.compare(id, castedObject.id);
		}
		return compareTo;
	}

	/**
	 * <p>
	 * Defines this parameter type, setting the defined property to
	 * <code>true</code>.
	 * </p>
	 * <p>
	 * Notification is sent to all listeners that something has changed.
	 * </p>
	 * 
	 * @param type
	 *            a string identifying the Java object type for this parameter
	 *            type; <code>null</code> is interpreted as
	 *            <code>"java.lang.Object"</code>
	 * @param parameterTypeConverter
	 *            an {@link AbstractParameterValueConverter} to perform
	 *            string/object conversions for parameter values; may be
	 *            <code>null</code>
	 */
	public final void define(final String type,
			final AbstractParameterValueConverter parameterTypeConverter) {

		final boolean definedChanged = !this.defined;
		this.defined = true;

		this.type = (type == null) ? Object.class.getName() : type;
		this.parameterTypeConverter = parameterTypeConverter;

		fireParameterTypeChanged(new ParameterTypeEvent(this, definedChanged));
	}

	/**
	 * Notifies all listeners that this parameter type has changed. This sends
	 * the given event to all of the listeners, if any.
	 * 
	 * @param event
	 *            The event to send to the listeners; must not be
	 *            <code>null</code>.
	 */
	private final void fireParameterTypeChanged(final ParameterTypeEvent event) {
		if (event == null) {
			throw new NullPointerException(
					"Cannot send a null event to listeners."); //$NON-NLS-1$
		}

		if (!isListenerAttached()) {
			return;
		}

		final Object[] listeners = getListeners();
		for (int i = 0; i < listeners.length; i++) {
			final IParameterTypeListener listener = (IParameterTypeListener) listeners[i];
			listener.parameterTypeChanged(event);
		}
	}

	/**
	 * Returns the value converter associated with this parameter, if any.
	 * 
	 * @return The parameter value converter, or <code>null</code> if there is
	 *         no value converter for this parameter.
	 * @throws NotDefinedException
	 *             if the parameter type is not currently defined
	 */
	public final AbstractParameterValueConverter getValueConverter()
			throws NotDefinedException {
		if (!isDefined()) {
			throw new NotDefinedException(
					"Cannot use getValueConverter() with an undefined ParameterType"); //$NON-NLS-1$
		}

		return parameterTypeConverter;
	}

	/**
	 * Returns whether the provided value is compatible with this parameter
	 * type. An object is compatible with a parameter type if the object is an
	 * instance of the class defined as the parameter's type class.
	 * 
	 * @param value
	 *            an object to check for compatibility with this parameter type;
	 *            may be <code>null</code>.
	 * @return <code>true</code> if the value is compatible with this type,
	 *         <code>false</code> otherwise
	 * @throws NotDefinedException
	 *             if the parameter type is not currently defined
	 */
	public boolean isCompatible(Object value) throws NotDefinedException {
		if (!isDefined()) {
			throw new NotDefinedException(
					"Cannot use isCompatible() with an undefined ParameterType"); //$NON-NLS-1$
		}
		return isInstanceOf(value, type);
	}

	/**
	 * Unregisters listener for changes to properties of this parameter type.
	 * 
	 * @param listener
	 *            the instance to unregister. Must not be <code>null</code>.
	 *            If an attempt is made to unregister an instance which is not
	 *            already registered with this instance, no operation is
	 *            performed.
	 */
	public final void removeListener(final IParameterTypeListener listener) {
		removeListenerObject(listener);
	}

	/**
	 * The string representation of this parameter type. For debugging purposes
	 * only. This string should not be shown to an end user.
	 * 
	 * @return The string representation; never <code>null</code>.
	 */
	public final String toString() {
		if (string == null) {
			final StringBuffer stringBuffer = new StringBuffer();
			stringBuffer.append("ParameterType("); //$NON-NLS-1$
			stringBuffer.append(id);
			stringBuffer.append(',');
			stringBuffer.append(defined);
			stringBuffer.append(')');
			string = stringBuffer.toString();
		}
		return string;
	}

	/**
	 * Makes this parameter type become undefined. Notification is sent to all
	 * listeners.
	 */
	public final void undefine() {
		string = null;

		final boolean definedChanged = defined;
		defined = false;

		type = null;
		parameterTypeConverter = null;

		fireParameterTypeChanged(new ParameterTypeEvent(this, definedChanged));
	}

}
