/*******************************************************************************
 * Copyright (c) 2000, 2003 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials 
 * are made available under the terms of the Common Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/cpl-v10.html
 * 
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/

package org.eclipse.ui.views.markers.internal;

import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;

import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IPath;
import org.eclipse.jface.dialogs.IDialogSettings;
import org.eclipse.ui.IContainmentAdapter;
import org.eclipse.ui.IWorkingSet;
import org.eclipse.ui.PlatformUI;

class MarkerFilter implements IFilter {
	
	private static final String TAG_DIALOG_SECTION = "filter"; //$NON-NLS-1$
	private static final String TAG_ENABLED = "enabled"; //$NON-NLS-1$
	private static final String TAG_FILTER_ON_MARKER_LIMIT = "filterOnMarkerLimit"; //$NON-NLS-1$
	private static final String TAG_MARKER_LIMIT = "markerLimit"; //$NON-NLS-1$
	private static final String TAG_ON_RESOURCE = "onResource"; //$NON-NLS-1$
	private static final String TAG_SELECTED_TYPES = "selectedType"; //$NON-NLS-1$
	private static final String TAG_WORKING_SET = "workingSet"; //$NON-NLS-1$
	private static final String TAG_TYPES_DELIMITER = ":"; //$NON-NLS-1$
	
	static final int ON_ANY_RESOURCE = 0;
	static final int ON_SELECTED_RESOURCE_ONLY = 1;
	static final int ON_SELECTED_RESOURCE_AND_CHILDREN = 2;
	static final int ON_ANY_RESOURCE_OF_SAME_PROJECT = 3;
	static final int ON_WORKING_SET = 4;

	static final int DEFAULT_MARKER_LIMIT = 2000;
	static final boolean DEFAULT_FILTER_ON_MARKER_LIMIT = true;
	static final int DEFAULT_ON_RESOURCE = ON_ANY_RESOURCE;
	static final boolean DEFAULT_ACTIVATION_STATUS = true;

	protected List rootTypes = new ArrayList();
	protected List selectedTypes = new ArrayList();
	protected IWorkingSet workingSet;
	protected int onResource;
	protected boolean filterOnMarkerLimit;
	protected boolean enabled;
	protected int markerLimit;
	
	private MarkerTypesModel typesModel;
	
	private IResource[] focusResource;
	
	MarkerFilter(String[] rootTypes) {
		typesModel = new MarkerTypesModel();
		
		for (int i = 0; i < rootTypes.length; i++) {
			MarkerType type = typesModel.getType(rootTypes[i]);
			
			if (!this.rootTypes.contains(type))
				this.rootTypes.add(type);
		}
	}
	
	private void addAllSubTypes() {
		for (int i = 0; i < rootTypes.size(); i++) {
			MarkerType rootType = (MarkerType) rootTypes.get(i);
			addAllSubTypes(rootType);
		}
	}
	
	private void addAllSubTypes(MarkerType type) {
		if (type == null)
			return;
	
		if (!selectedTypes.contains(type))
			selectedTypes.add(type);
	
		MarkerType[] subTypes = type.getSubtypes();
		
		for (int i = 0; i < subTypes.length; i++)
			addAllSubTypes(subTypes[i]);
	} 
	
	public Object[] filter(Object[] elements) {
		if (elements == null)	
			return new Object[0];
			
		List filteredElements = new ArrayList();
		
		for (int i = 0; i < elements.length; i++) {
			Object element = elements[i];
			
			if (select(element))
				filteredElements.add(element); 
		}
		
		return filteredElements.toArray();
	}

	public boolean select(Object item) {
		if (!isEnabled()) {
			return true;
		}
		
		if (!(item instanceof IMarker))
			return false;

		IMarker marker = (IMarker) item;
		return selectByType(marker) && selectBySelection(marker);
	}
	
	private boolean selectByType(IMarker marker) {
		String type;

		try {
			type = marker.getType();
		}
		catch (CoreException e) {
			return false;
		}
		
		return selectedTypes.contains(typesModel.getType(type));
	}
	
	/**
	 * Returns whether the specified marker should be filter out or not.
	 * 
	 * @param marker the marker to test
	 * @return 
	 * 	true=the marker should not be filtered out
	 * 	false=the marker should be filtered out
	 */
	private boolean selectBySelection(IMarker marker) {
		if (onResource == ON_ANY_RESOURCE || marker == null)
			return true;
	
		if (focusResource == null)
			return true;
	
		IResource resource = marker.getResource();
		
		if (onResource == ON_WORKING_SET) {
			if (workingSet == null)
				return true;
				
			if (resource != null) 
				return isEnclosed(resource);
			
		} else if (onResource == ON_ANY_RESOURCE_OF_SAME_PROJECT) {
			IProject project = resource.getProject();
			
			for (int i = 0; i < focusResource.length; i++) {
				IProject selectedProject = focusResource[i].getProject();
			
				if (project.equals(selectedProject))
					return true;
			}
		} else if (onResource == ON_SELECTED_RESOURCE_ONLY) {
			for (int i = 0; i < focusResource.length; i++) {
				if (resource.equals(focusResource[i]))
					return true;
			}
		} else if (onResource == ON_SELECTED_RESOURCE_AND_CHILDREN) {
			for (int i = 0; i < focusResource.length; i++) {
				IResource parentResource = resource;
				
				while (parentResource != null) {
					if (parentResource.equals(focusResource[i]))
						return true;
				
					parentResource = parentResource.getParent();
				}
			}
		}
		
		return false;
	}

	/**
	 * Returns if the given resource is enclosed by a working set element.
	 * The IContainmentAdapter of each working set element is used for the
	 * containment test. If there is no IContainmentAdapter for a working 
	 * set element, a simple resource based test is used. 
	 * 
	 * @param element resource to test for enclosure by a working set
	 * 	element 
	 * @return true if element is enclosed by a working set element and 
	 * 	false otherwise. 
	 */
	private boolean isEnclosed(IResource element) {
		IPath elementPath = element.getFullPath();
		IAdaptable[] workingSetElements = workingSet.getElements();
		
		if (elementPath.isEmpty() || elementPath.isRoot())
			return false;
		
		for (int i = 0; i < workingSetElements.length; i++) {
			IAdaptable workingSetElement = workingSetElements[i];
			IContainmentAdapter containmentAdapter = (IContainmentAdapter) workingSetElement.getAdapter(IContainmentAdapter.class);
			
			// if there is no IContainmentAdapter defined for the working  
			// set element type fall back to using resource based  
			// containment check 
			if (containmentAdapter != null) {
				if (containmentAdapter.contains(workingSetElement, element, IContainmentAdapter.CHECK_CONTEXT | IContainmentAdapter.CHECK_IF_CHILD | IContainmentAdapter.CHECK_IF_DESCENDANT))
					return true;
			} else if (isEnclosedResource(element, elementPath, workingSetElement)) {
				return true;
			}		
		}
		
		return false;
	}

	/**
	 * Returns if the given resource is enclosed by a working set element.
	 * A resource is enclosed if it is either a parent of a working set 
	 * element, a child of a working set element or a working set element
	 * itself.
	 * Simple path comparison is used. This is only guaranteed to return
	 * correct results for resource working set elements. 
	 * 
	 * @param element resource to test for enclosure by a working set
	 * 	element
	 * @param elementPath full, absolute path of the element to test 
	 * @return true if element is enclosed by a working set element and 
	 * 	false otherwise. 
	 */
	private boolean isEnclosedResource(IResource element, IPath elementPath, IAdaptable workingSetElement) {
		IResource workingSetResource = null;
		
		if (workingSetElement.equals(element))
			return true;
			
		if (workingSetElement instanceof IResource)
			workingSetResource = (IResource) workingSetElement;
		else
			workingSetResource = (IResource) workingSetElement.getAdapter(IResource.class);
	
		if (workingSetResource != null) {
			IPath resourcePath = workingSetResource.getFullPath();
	
			if (resourcePath.isPrefixOf(elementPath))
				return true;
		}
	
		return false;
	}

	/**
	 * @return the defined limit on the number of markers to be displayed.
	 */
	int getMarkerLimit() {
		return markerLimit;
	}

	/**
	 * Sets the limit on the number of markers to be displayed.
	 * 
	 * @param the new limit
	 */
	void setMarkerLimit(int markerLimit) {
		this.markerLimit = markerLimit;
	}

	/**
	 * @return <ul>
	 * <li><code>MarkerFilter.ON_ANY_RESOURCE</code> if showing items associated with any resource.</li>
	 * <li><code>MarkerFilter.ON_SELECTED_RESOURCE_ONLY</code> if showing items associated with
	 * the selected resource within the workbench.</li>
	 * <li><code>MarkerFilter.ON_SELECTED_RESOURCE_AND_CHILDREN</code> if showing items associated with
	 * the selected resource within the workbench and its children.</li>
	 * <li><code>MarkerFilter.ON_ANY_RESOURCE_OF_SAME_PROJECT</code> if showing items in the same project
	 * as the selected resource within the workbench.</li>
	 * <li><code>MarkerFilter.ON_WORKING_SET</code> if showing items in some working set.</li>
	 * </ul>
	 */
	int getOnResource() {
		return onResource;
	}

	/**
	 * Sets the type of filtering by selection.
	 * 
	 * @param onResource must be one of:
	 * <ul>
	 * <li><code>MarkerFilter.ON_ANY_RESOURCE</code></li>
	 * <li><code>MarkerFilter.ON_SELECTED_RESOURCE_ONLY</code></li>
	 * <li><code>MarkerFilter.ON_SELECTED_RESOURCE_AND_CHILDREN</code></li>
	 * <li><code>MarkerFilter.ON_ANY_RESOURCE_OF_SAME_PROJECT</code></li>
	 * <li><code>MarkerFilter.ON_WORKING_SET</code></li>
	 * </ul>
	 */
	void setOnResource(int onResource) {
		if (onResource >= ON_ANY_RESOURCE && onResource <= ON_WORKING_SET)
			this.onResource = onResource;
	}

	/**
	 * @return the selected resource(s) withing the workbench.
	 */
	IResource[] getFocusResource() {
		return focusResource;
	}

	/**
	 * Sets the focused resources.
	 */
	void setFocusResource(IResource[] resources) {
		focusResource = resources;
	}

	/**
	 * @return
	 * <ul>
	 * <li><code>true</code> if the filter is enabled.</li>
	 * <li><code>false</code> if the filter is not enabled.</li>
	 * </ul>
	 */
	boolean isEnabled() {
		return enabled;
	}

	/**
	 * @return
	 * <ul>
	 * <li><code>true</code> if filtering by marker limit is enabled.</li>
	 * <li><code>false</code> if filtering by marker limit is not enabled.</li>
	 * </ul>
	 */
	boolean getFilterOnMarkerLimit() {
		return filterOnMarkerLimit;
	}

	/**
	 * @return the root marker types.
	 */
	List getRootTypes() {
		return rootTypes;
	}

	/**
	 * @return the selected marker types to be displayed.
	 */
	List getSelectedTypes() {
		return selectedTypes;
	}

	/**
	 * @return the current working set or <code>null</code> if no working set is defined.
	 */
	IWorkingSet getWorkingSet() {
		return workingSet;
	}

	/**
	 * Sets the enablement state of the filter.
	 */
	void setEnabled(boolean enabled) {
		this.enabled = enabled;
	}

	/**
	 * Sets the enablement state of filtering by marker limit.
	 */
	void setFilterOnMarkerLimit(boolean filterOnMarkerLimit) {
		this.filterOnMarkerLimit = filterOnMarkerLimit;
	}

	/**
	 * Sets the selected marker types to be displayed. The List <b>MUST ONLY</b> contain 
	 * <code>MarkerType</code> objects.
	 */
	void setSelectedTypes(List selectedTypes) {
		this.selectedTypes = selectedTypes;
	}

	/**
	 * Sets the current working set.
	 */
	void setWorkingSet(IWorkingSet workingSet) {
		this.workingSet = workingSet;
	}
	
	void resetState() {
		enabled = DEFAULT_ACTIVATION_STATUS;
		filterOnMarkerLimit = DEFAULT_FILTER_ON_MARKER_LIMIT;
		markerLimit = DEFAULT_MARKER_LIMIT;
		onResource = DEFAULT_ON_RESOURCE;
		selectedTypes.clear();
		addAllSubTypes();
		workingSet = null;
	}
	
	public void restoreState(IDialogSettings dialogSettings) {
		resetState();		
		IDialogSettings settings = dialogSettings.getSection(TAG_DIALOG_SECTION);
		
		if (settings != null) {
			String setting = settings.get(TAG_ENABLED);

			if (setting != null)
				enabled = Boolean.valueOf(setting).booleanValue();

			setting = settings.get(TAG_FILTER_ON_MARKER_LIMIT);
			
			if (setting != null)
				filterOnMarkerLimit = Boolean.valueOf(setting).booleanValue();
				
			setting = settings.get(TAG_MARKER_LIMIT);

			if (setting != null)
				try {
					markerLimit = Integer.parseInt(setting);		
				}
				catch (NumberFormatException eNumberFormat) {
				}

			setting = settings.get(TAG_ON_RESOURCE);

			if (setting != null)
				try {
					onResource = Integer.parseInt(setting);		
				}
				catch (NumberFormatException eNumberFormat) {
				}

			setting = settings.get(TAG_SELECTED_TYPES);
			
			if (setting != null) {
				selectedTypes.clear();
				StringTokenizer stringTokenizer = new StringTokenizer(setting);
				
				while (stringTokenizer.hasMoreTokens()) {				
					MarkerType markerType = typesModel.getType(stringTokenizer.nextToken(TAG_TYPES_DELIMITER));
					
					if (markerType != null && !selectedTypes.contains(markerType))
						selectedTypes.add(markerType);
				}
			}

			setting = settings.get(TAG_WORKING_SET);

			if (setting != null)
				workingSet = PlatformUI.getWorkbench().getWorkingSetManager().getWorkingSet(setting);					
		}		
	}
	
	public void saveState(IDialogSettings dialogSettings) {		
		if (dialogSettings != null) {
			IDialogSettings settings = dialogSettings.getSection(TAG_DIALOG_SECTION);

			if (settings == null)
				settings = dialogSettings.addNewSection(TAG_DIALOG_SECTION);

			settings.put(TAG_ENABLED, enabled);
			settings.put(TAG_FILTER_ON_MARKER_LIMIT, filterOnMarkerLimit);
			settings.put(TAG_MARKER_LIMIT, markerLimit);
			settings.put(TAG_ON_RESOURCE, onResource);

			String markerTypeIds = ""; //$NON-NLS-1$
		
			for (int i = 0; i < selectedTypes.size(); i++) {
				MarkerType markerType = (MarkerType) selectedTypes.get(i);
				markerTypeIds += markerType.getId() + TAG_TYPES_DELIMITER;
			}
		
			settings.put(TAG_SELECTED_TYPES, markerTypeIds);
		
			if (workingSet != null)
				settings.put(TAG_WORKING_SET, workingSet.getName());
		}
	}
}
