/*******************************************************************************
 * Copyright (c) 2003, 2010 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.navigator.extensions;

import java.lang.ref.SoftReference;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
import java.util.WeakHashMap;

import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.SafeRunner;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.resource.ImageRegistry;
import org.eclipse.swt.graphics.Image;
import org.eclipse.ui.internal.navigator.NavigatorPlugin;
import org.eclipse.ui.internal.navigator.NavigatorSafeRunnable;
import org.eclipse.ui.internal.navigator.Policy;
import org.eclipse.ui.internal.navigator.VisibilityAssistant;
import org.eclipse.ui.internal.navigator.VisibilityAssistant.VisibilityListener;
import org.eclipse.ui.navigator.INavigatorContentDescriptor;
import org.eclipse.ui.navigator.OverridePolicy;
import org.eclipse.ui.plugin.AbstractUIPlugin;

/**
 * @since 3.2
 */
public class NavigatorContentDescriptorManager {

	private static final NavigatorContentDescriptorManager INSTANCE = new NavigatorContentDescriptorManager();

	private final Map firstClassDescriptorsMap = new HashMap();

	private final Map allDescriptors = new HashMap();

	private class EvaluationCache implements VisibilityListener {

		private final Map evaluations/* <Object, NavigatorContentDescriptor[]> */= new HashMap();
		private final Map evaluationsWithOverrides/*<Object, NavigatorContentDescriptor[]>*/ = new HashMap();

		EvaluationCache(VisibilityAssistant anAssistant) {
			anAssistant.addListener(this);
		}

		protected final NavigatorContentDescriptor[] getDescriptors(Object anElement) {
			return getDescriptors(anElement, true);
		}

		protected final void setDescriptors(Object anElement, NavigatorContentDescriptor[] theDescriptors) {
			setDescriptors(anElement, theDescriptors, true);
		}

		protected final NavigatorContentDescriptor[] getDescriptors(Object anElement, boolean toComputeOverrides) {

			if (anElement == null)
				return null;

			NavigatorContentDescriptor[] cachedDescriptors = null;
			if (toComputeOverrides) {
				SoftReference cache = (SoftReference) evaluations.get(anElement);
				if (cache != null && (cachedDescriptors = (NavigatorContentDescriptor[]) cache.get()) == null)
					evaluations.remove(anElement);
				return cachedDescriptors;
			}
			SoftReference cache = (SoftReference) evaluationsWithOverrides.get(anElement);
			if (cache != null && (cachedDescriptors = (NavigatorContentDescriptor[]) cache.get()) == null)
				evaluationsWithOverrides.remove(anElement);
			return cachedDescriptors;

		}

		protected final void setDescriptors(Object anElement, NavigatorContentDescriptor[] theDescriptors, boolean toComputeOverrides) {
			if (anElement != null) {
				if (toComputeOverrides)
					evaluations.put(new EvalutationReference(anElement), new SoftReference(theDescriptors));
				else
					evaluationsWithOverrides.put(new EvalutationReference(anElement), new SoftReference(theDescriptors));
			}
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see org.eclipse.ui.internal.navigator.VisibilityAssistant.VisibilityListener#onVisibilityOrActivationChange()
		 */
		public void onVisibilityOrActivationChange() {
			evaluations.clear();
			evaluationsWithOverrides.clear();
		}
	}

	/* Map of (VisibilityAssistant, EvaluationCache)-pairs */
	private final Map cachedTriggerPointEvaluations = new WeakHashMap();

	/* Map of (VisibilityAssistant, EvaluationCache)-pairs */
	private final Map cachedPossibleChildrenEvaluations = new WeakHashMap();

	private ImageRegistry imageRegistry;

	private final Set overridingDescriptors = new HashSet();

	private final Set saveablesProviderDescriptors = new HashSet();

	private final Set sortOnlyDescriptors = new HashSet();

	private final Set firstClassDescriptorsSet = new HashSet();

	/**
	 * @return the singleton instance of the manager
	 */
	public static NavigatorContentDescriptorManager getInstance() {
		return INSTANCE;
	}

	private NavigatorContentDescriptorManager() {
		new NavigatorContentDescriptorRegistry().readRegistry();
	}

	/**
	 * 
	 * @return Returns all content descriptor(s).
	 */
	public NavigatorContentDescriptor[] getAllContentDescriptors() {
		NavigatorContentDescriptor[] finalDescriptors = new NavigatorContentDescriptor[allDescriptors
				.size()];
		finalDescriptors = (NavigatorContentDescriptor[]) allDescriptors.values().toArray(finalDescriptors);
		Arrays.sort(finalDescriptors, ExtensionSequenceNumberComparator.INSTANCE);
		return finalDescriptors;
	}

	/**
	 * 
	 * @return Returns all content descriptors that provide saveables.
	 */
	public NavigatorContentDescriptor[] getContentDescriptorsWithSaveables() {
		NavigatorContentDescriptor[] finalDescriptors = new NavigatorContentDescriptor[saveablesProviderDescriptors
				.size()];
		saveablesProviderDescriptors.toArray(finalDescriptors);
		Arrays.sort(finalDescriptors, ExtensionSequenceNumberComparator.INSTANCE);
		return finalDescriptors;
	}

	/**
	 * 
	 * @return Returns all content descriptors that are sort only
	 */
	public NavigatorContentDescriptor[] getSortOnlyContentDescriptors() {
		NavigatorContentDescriptor[] finalDescriptors = new NavigatorContentDescriptor[sortOnlyDescriptors
				.size()];
		sortOnlyDescriptors.toArray(finalDescriptors);
		Arrays.sort(finalDescriptors, ExtensionSequenceNumberComparator.INSTANCE);
		return finalDescriptors;
	}


	/**
	 * 
	 * Returns all content descriptor(s) which enable for the given element.
	 * 
	 * @param anElement
	 *            the element to return the best content descriptor for
	 * 
	 * @param aVisibilityAssistant
	 *            The relevant viewer assistant; used to filter out unbound
	 *            content descriptors.
	 * @param considerOverrides 
	 * @return the best content descriptor for the given element.
	 */
	public Set findDescriptorsForTriggerPoint(Object anElement,
			VisibilityAssistant aVisibilityAssistant, boolean considerOverrides) {
		return findDescriptors(anElement, cachedTriggerPointEvaluations, aVisibilityAssistant, considerOverrides, !POSSIBLE_CHILD);
	}


	/**
	 * 
	 * Returns all content descriptor(s) which enable for the given element.
	 * 
	 * @param anElement
	 *            the element to return the best content descriptor for
	 * 
	 * @param aVisibilityAssistant
	 *            The relevant viewer assistant; used to filter out unbound
	 *            content descriptors.
	 * @param toComputeOverrides
	 * @return the best content descriptor for the given element.
	 */
	public Set findDescriptorsForPossibleChild(Object anElement,
			VisibilityAssistant aVisibilityAssistant, boolean toComputeOverrides) {
		return findDescriptors(anElement, cachedPossibleChildrenEvaluations, aVisibilityAssistant, toComputeOverrides, POSSIBLE_CHILD);
	}

	private static final boolean POSSIBLE_CHILD = true;
	

	private Set findDescriptors(Object anElement,
			Map cachedEvaluations, VisibilityAssistant aVisibilityAssistant, boolean considerOverrides, boolean possibleChild) {
		EvaluationCache cache = getEvaluationCache(
				cachedEvaluations, aVisibilityAssistant);

		Set descriptors = new TreeSet(ExtensionSequenceNumberComparator.INSTANCE);
		NavigatorContentDescriptor[] cachedDescriptors = null;
		if ((cachedDescriptors = cache.getDescriptors(anElement)) != null) {
			descriptors.addAll(Arrays.asList(cachedDescriptors));
		}

		if (considerOverrides) {
			addDescriptorsConsideringOverrides(anElement, firstClassDescriptorsSet, aVisibilityAssistant, descriptors, possibleChild);
			if (Policy.DEBUG_RESOLUTION) {
				System.out.println("Find descriptors for: " + Policy.getObjectString(anElement) + //$NON-NLS-1$
						": " + descriptors); //$NON-NLS-1$
			}
		} else {

			/* Find other ContentProviders which enable for this object */
			for (Iterator contentDescriptorsItr = firstClassDescriptorsSet.iterator(); contentDescriptorsItr.hasNext();) {
				NavigatorContentDescriptor descriptor = (NavigatorContentDescriptor) contentDescriptorsItr.next();

				if (aVisibilityAssistant.isActive(descriptor) && aVisibilityAssistant.isVisible(descriptor)
						&& (possibleChild ? descriptor.isPossibleChild(anElement) : descriptor.isTriggerPoint(anElement))) {
					descriptors.add(descriptor);
				}
			}
		}
		cache.setDescriptors(anElement, (NavigatorContentDescriptor[]) descriptors.toArray(new NavigatorContentDescriptor[descriptors.size()]));

		return descriptors;
	}

	private EvaluationCache getEvaluationCache(Map anEvaluationMap,
			VisibilityAssistant aVisibilityAssistant) {
		EvaluationCache c = (EvaluationCache) anEvaluationMap
				.get(aVisibilityAssistant);
		if (c == null) {
			anEvaluationMap.put(aVisibilityAssistant, c = new EvaluationCache(
					aVisibilityAssistant));
		}
		return c;

	}

	private boolean addDescriptorsConsideringOverrides(Object anElement,
			Set theChildDescriptors, VisibilityAssistant aVisibilityAssistant,
			Set theFoundDescriptors, boolean possibleChild) {
		int initialSize = theFoundDescriptors.size();

		NavigatorContentDescriptor descriptor;
		/* Find other ContentProviders which enable for this object */
		for (Iterator contentDescriptorsItr = theChildDescriptors.iterator(); contentDescriptorsItr
				.hasNext();) {
			descriptor = (NavigatorContentDescriptor) contentDescriptorsItr
					.next();

			boolean isApplicable = aVisibilityAssistant.isActive(descriptor)
					&& aVisibilityAssistant.isVisible(descriptor)
					&& (possibleChild ? descriptor.isPossibleChild(anElement) : descriptor.isTriggerPoint(anElement));

			if (descriptor.hasOverridingExtensions()) {

				boolean isOverridden;

				Set overridingDescriptors = new TreeSet(ExtensionSequenceNumberComparator.INSTANCE);
				isOverridden = addDescriptorsConsideringOverrides(anElement, descriptor.getOverriddingExtensions(),
						aVisibilityAssistant, overridingDescriptors, possibleChild);

				if (!isOverridden && isApplicable) {
					theFoundDescriptors.add(descriptor);
				} else if (isOverridden) {
					theFoundDescriptors.addAll(overridingDescriptors);
				}

			} else if (isApplicable) {
				theFoundDescriptors.add(descriptor);
			}

		}
		return initialSize < theFoundDescriptors.size();

	}

	/**
	 * Returns the navigator content descriptor with the given id.
	 * 
	 * @param id
	 *            The id of the content descriptor that should be returned
	 * @return The content descriptor of the given id
	 */
	public NavigatorContentDescriptor getContentDescriptor(String id) {
		return (NavigatorContentDescriptor) allDescriptors.get(id);
	}

	/**
	 * 
	 * @param descriptorId
	 *            The unique id of a particular descriptor
	 * @return The name (value of the 'name' attribute) of the given descriptor
	 */
	public String getText(String descriptorId) {
		INavigatorContentDescriptor descriptor = getContentDescriptor(descriptorId);
		if (descriptor != null) {
			return descriptor.getName();
		}
		return descriptorId;
	}

	/**
	 * 
	 * @param descriptorId
	 *            The unique id of a particular descriptor
	 * @return The image (corresponding to the value of the 'icon' attribute) of
	 *         the given descriptor
	 */
	public Image getImage(String descriptorId) {
		return retrieveAndStoreImage(descriptorId);
	}

	protected Image retrieveAndStoreImage(String descriptorId) {
		NavigatorContentDescriptor contentDescriptor = getContentDescriptor(descriptorId);

		Image image = null;
		if (contentDescriptor != null) {
			String icon = contentDescriptor.getIcon();
			if (icon != null) {
				image = getImageRegistry().get(icon);
				if (image == null || image.isDisposed()) {
					ImageDescriptor imageDescriptor = AbstractUIPlugin
							.imageDescriptorFromPlugin(contentDescriptor
							.getContribution().getPluginId(), icon);
					if (imageDescriptor != null) {
						image = imageDescriptor.createImage();
						if (image != null) {
							getImageRegistry().put(icon, image);
						}
					}
				}
			}
		}
		return image;
	}

	/**
	 * @param desc
	 */
	private void addNavigatorContentDescriptor(NavigatorContentDescriptor desc) {
		if (desc == null) {
			return;
		}
		synchronized (firstClassDescriptorsMap) {
			if (firstClassDescriptorsMap.containsKey(desc.getId())) {
				NavigatorPlugin
						.logError(
								0,
								"An extension already exists with id \"" + desc.getId() + "\".", null); //$NON-NLS-1$ //$NON-NLS-2$
			} else {
				if (desc.getSuppressedExtensionId() == null) {
					firstClassDescriptorsMap.put(desc.getId(), desc);
					firstClassDescriptorsSet.add(desc);
					if (Policy.DEBUG_EXTENSION_SETUP) {
						System.out.println("First class descriptor: " + desc); //$NON-NLS-1$
					}
				} else {
					overridingDescriptors.add(desc);
					if (Policy.DEBUG_EXTENSION_SETUP) {
						System.out.println("Overriding descriptor: " + desc); //$NON-NLS-1$
					}
				}
				allDescriptors.put(desc.getId(), desc);
				if (desc.hasSaveablesProvider()) {
					saveablesProviderDescriptors.add(desc);
					if (Policy.DEBUG_EXTENSION_SETUP) {
						System.out.println("Saveables provider descriptor: " + desc); //$NON-NLS-1$
					}
				}
				if (desc.isSortOnly()) {
					sortOnlyDescriptors.add(desc);
					if (Policy.DEBUG_EXTENSION_SETUP) {
						System.out.println("SortOnly descriptor: " + desc); //$NON-NLS-1$
					}
				}
			}
		}
	}

	/**
	 * 
	 */
	private void computeOverrides() {
		if (overridingDescriptors.size() > 0) {
			NavigatorContentDescriptor descriptor;
			NavigatorContentDescriptor overriddenDescriptor;
			for (Iterator overridingIterator = overridingDescriptors.iterator(); overridingIterator
					.hasNext();) {
				descriptor = (NavigatorContentDescriptor) overridingIterator
						.next();
				overriddenDescriptor = (NavigatorContentDescriptor) allDescriptors
						.get(descriptor.getSuppressedExtensionId());
				if (overriddenDescriptor != null) {

					if (Policy.DEBUG_EXTENSION_SETUP) {
						System.out.println(descriptor + " overrides: " + overriddenDescriptor); //$NON-NLS-1$
					}
					/*
					 * add the descriptor as an overriding extension for its
					 * suppressed extension
					 */
					overriddenDescriptor.getOverriddingExtensions().add(
							descriptor);
					descriptor.setOverriddenDescriptor(overriddenDescriptor);
					/*
					 * the always policy implies this is also a top-level
					 * extension
					 */
					if (descriptor.getOverridePolicy() == OverridePolicy.InvokeAlwaysRegardlessOfSuppressedExt) {
						if (Policy.DEBUG_EXTENSION_SETUP) {
							System.out.println(descriptor + " is first class"); //$NON-NLS-1$
						}
						firstClassDescriptorsMap.put(descriptor.getId(),
								descriptor);
						firstClassDescriptorsSet.add(descriptor);
					}

				} else {
					String message = 
							"Invalid suppressedExtensionId \"" //$NON-NLS-1$
									+ descriptor.getSuppressedExtensionId()
									+ "\" specified from \"" //$NON-NLS-1$
									+ descriptor.getId() + "\" in \"" + descriptor.getContribution() //$NON-NLS-1$
											.getPluginId()
									+ "\". No extension with matching id found."; //$NON-NLS-1$
					if (Policy.DEBUG_EXTENSION_SETUP) {
						System.out.println("Error: " + message); //$NON-NLS-1$
					}
					NavigatorPlugin.logError(0, message, null);
				}
			}
		}
	}
	
	private int findId(List list, String id) {
		for (int i = 0, len = list.size(); i < len; i++) {
			NavigatorContentDescriptor desc = (NavigatorContentDescriptor) list.get(i);
			if (desc.getId().equals(id))
				return i;
		}
		throw new RuntimeException("Can't find id: " + id); //$NON-NLS-1$
	}
	
	private void computeSequenceNumbers() {
		NavigatorContentDescriptor[] descs = getAllContentDescriptors();

		LinkedList list = new LinkedList();
		for (int i = 0; i < descs.length; i++) {
			list.add(descs[i]);
		}
		
		boolean changed = true;
		while (changed) {
			changed = false;
			for (int i = 0, len = list.size(); i < len; i++) {
				NavigatorContentDescriptor desc = (NavigatorContentDescriptor) list.get(i);
				if (desc.getAppearsBeforeId() != null) {
					int beforeInd = findId(list, desc.getAppearsBeforeId());
					if (beforeInd < i) {
						list.add(beforeInd, desc);
						list.remove(i + 1);
						changed = true;
					}
				}
			}
		}
		
		for (int i = 0, len = list.size(); i < len; i++) {
			NavigatorContentDescriptor desc = (NavigatorContentDescriptor) list.get(i);
			desc.setSequenceNumber(i);
			if (Policy.DEBUG_EXTENSION_SETUP) {
				System.out.println("Descriptors by sequence: " + desc); //$NON-NLS-1$
			}
		}
	}

	private ImageRegistry getImageRegistry() {
		if (imageRegistry == null) {
			imageRegistry = new ImageRegistry();
		}
		return imageRegistry;
	}

	private class NavigatorContentDescriptorRegistry extends
			NavigatorContentRegistryReader {

		/*
		 * (non-Javadoc)
		 * 
		 * @see org.eclipse.ui.internal.navigator.extensions.RegistryReader#readRegistry()
		 */
		public void readRegistry() {
			super.readRegistry();
			computeSequenceNumbers();
			computeOverrides();
		}

		protected boolean readElement(final IConfigurationElement anElement) {
			if (TAG_NAVIGATOR_CONTENT.equals(anElement.getName())) {
				SafeRunner.run(new NavigatorSafeRunnable(anElement) {
					public void run() throws Exception {
						addNavigatorContentDescriptor(new NavigatorContentDescriptor(anElement));
					}
				});
			}
			return super.readElement(anElement);
		}
	}

}
