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

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;

import org.eclipse.core.runtime.IAdaptable;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceChangeEvent;
import org.eclipse.core.resources.IResourceChangeListener;
import org.eclipse.core.resources.IResourceDelta;
import org.eclipse.core.resources.ResourcesPlugin;

import org.eclipse.ui.IWorkingSet;
import org.eclipse.ui.IWorkingSetUpdater;

/**
 * A working set updater that updates resource working sets on resource deltas
 * 
 * @since 3.2
 */
public class ResourceWorkingSetUpdater implements IWorkingSetUpdater,
		IResourceChangeListener {

	/**
	 * Utility class used to help process incoming resource deltas.
	 */
	private static class WorkingSetDelta {
		private IWorkingSet fWorkingSet;

		private List fElements;

		private boolean fChanged;

		/**
		 * Create a new instance of this class.
		 * 
		 * @param workingSet
		 *            the working set to track.
		 */
		public WorkingSetDelta(IWorkingSet workingSet) {
			fWorkingSet = workingSet;
			fElements = new ArrayList(Arrays.asList(workingSet.getElements()));
		}

		/**
		 * Returns the index of this element in the list of known elements.
		 * 
		 * @param element
		 *            the element to search for
		 * @return the index, or -1 if unknown.
		 */
		public int indexOf(Object element) {
			return fElements.indexOf(element);
		}

		/**
		 * Add a new element to the list of known elements.
		 * 
		 * @param index
		 *            the index at which to place the element
		 * @param element
		 *            the element to set
		 */
		public void set(int index, Object element) {
			fElements.set(index, element);
			fChanged = true;
		}

		/**
		 * Remove an element from the list of known elements.
		 * 
		 * @param index
		 *            the index of the element to remove
		 */
		public void remove(int index) {
			if (fElements.remove(index) != null) {
				fChanged = true;
			}
		}

		/**
		 * Process the changes to this delta and update the working set if
		 * necessary.
		 */
		public void process() {
			if (fChanged) {
				fWorkingSet.setElements((IAdaptable[]) fElements
						.toArray(new IAdaptable[fElements.size()]));
			}
		}
	}

	private List fWorkingSets;

	/**
	 * Create a new instance of this updater.
	 */
	public ResourceWorkingSetUpdater() {
		fWorkingSets = new ArrayList();
		ResourcesPlugin.getWorkspace().addResourceChangeListener(this,
				IResourceChangeEvent.POST_CHANGE);
	}

	public void add(IWorkingSet workingSet) {
		checkElementExistence(workingSet);
		synchronized (fWorkingSets) {
			fWorkingSets.add(workingSet);
		}
	}

	public boolean remove(IWorkingSet workingSet) {
		boolean result;
		synchronized (fWorkingSets) {
			result = fWorkingSets.remove(workingSet);
		}

		return result;
	}

	public boolean contains(IWorkingSet workingSet) {
		synchronized (fWorkingSets) {
			return fWorkingSets.contains(workingSet);
		}
	}

	public void dispose() {
		synchronized (fWorkingSets) {
			fWorkingSets.clear();
		}
		ResourcesPlugin.getWorkspace().removeResourceChangeListener(this);
	}

	public void resourceChanged(IResourceChangeEvent event) {
		IResourceDelta delta = event.getDelta();
		if (delta == null)
			return;
		IWorkingSet[] workingSets;
		synchronized (fWorkingSets) {
			workingSets = (IWorkingSet[]) fWorkingSets
					.toArray(new IWorkingSet[fWorkingSets.size()]);
		}
		for (int w = 0; w < workingSets.length; w++) {
			WorkingSetDelta workingSetDelta = new WorkingSetDelta(
					workingSets[w]);
			processResourceDelta(workingSetDelta, delta);
			workingSetDelta.process();
		}
	}

	private void processResourceDelta(WorkingSetDelta result,
			IResourceDelta delta) {
		IResource resource = delta.getResource();
		int type = resource.getType();
		int index = result.indexOf(resource);
		int kind = delta.getKind();
		int flags = delta.getFlags();
		if (kind == IResourceDelta.CHANGED && type == IResource.PROJECT
				&& index != -1) {
			if ((flags & IResourceDelta.OPEN) != 0) {
				result.set(index, resource);
			}
		}
		if (index != -1 && kind == IResourceDelta.REMOVED) {
			if ((flags & IResourceDelta.MOVED_TO) != 0) {
				result.set(index, ResourcesPlugin.getWorkspace().getRoot()
						.findMember(delta.getMovedToPath()));
			} else {
				result.remove(index);
			}
		}

		// Don't dive into closed or opened projects
		if (projectGotClosedOrOpened(resource, kind, flags))
			return;

		IResourceDelta[] children = delta.getAffectedChildren();
		for (int i = 0; i < children.length; i++) {
			processResourceDelta(result, children[i]);
		}
	}

	private boolean projectGotClosedOrOpened(IResource resource, int kind,
			int flags) {
		return resource.getType() == IResource.PROJECT
				&& kind == IResourceDelta.CHANGED
				&& (flags & IResourceDelta.OPEN) != 0;
	}

	private void checkElementExistence(IWorkingSet workingSet) {
		List elements = new ArrayList(Arrays.asList(workingSet.getElements()));
		boolean changed = false;
		for (Iterator iter = elements.iterator(); iter.hasNext();) {
			IAdaptable element = (IAdaptable) iter.next();
			boolean remove = false;
			if (element instanceof IResource) {
				IResource resource = (IResource) element;
				IProject project = resource.getProject();
				remove = (project != null ? project.isOpen() : true)
						&& !resource.exists();
			}
			if (remove) {
				iter.remove();
				changed = true;
			}
		}
		if (changed) {
			workingSet.setElements((IAdaptable[]) elements
					.toArray(new IAdaptable[elements.size()]));
		}
	}
}
