/*******************************************************************************
 * 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 
 * 		Cagatay Kavukcuoglu <cagatayk@acm.org> - Filter for markers in same project
 *******************************************************************************/

package org.eclipse.ui.views.tasklist;

import java.util.Arrays;
import java.util.HashSet;

import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IMarkerDelta;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IPath;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerFilter;
import org.eclipse.ui.IContainmentAdapter;
import org.eclipse.ui.IMemento;
import org.eclipse.ui.IWorkingSet;
import org.eclipse.ui.IWorkingSetManager;
import org.eclipse.ui.PlatformUI;

class TasksFilter extends ViewerFilter implements Cloneable {

    public static final String[] ROOT_TYPES = new String[] { IMarker.PROBLEM,
            IMarker.TASK };

    // Filter on resource constants
    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; // added by cagatayk@acm.org

    static final int ON_WORKING_SET = 4;

    // Description filter kind constants
    static final int FILTER_CONTAINS = 0;

    static final int FILTER_DOES_NOT_CONTAIN = 1;

    //final static int MINIMUM_MARKER_LIMIT = 10;
    final static int DEFAULT_MARKER_LIMIT = 2000;

    //final static int MAXIMUM_MARKER_LIMIT = 20000;

    String[] types;

    int onResource;

    IWorkingSet workingSet;

    boolean filterOnDescription;

    int descriptionFilterKind;

    String descriptionFilter;

    boolean filterOnSeverity;

    int severityFilter;

    boolean filterOnPriority;

    int priorityFilter;

    boolean filterOnCompletion;

    int completionFilter;

    private boolean filterOnMarkerLimit = true;

    private int markerLimit = DEFAULT_MARKER_LIMIT;

    private static final String TAG_ID = "id"; //$NON-NLS-1$

    private static final String TAG_TYPE = "type"; //$NON-NLS-1$

    private static final String TAG_ON_RESOURCE = "onResource"; //$NON-NLS-1$

    private static final String TAG_WORKING_SET = "workingSet"; //$NON-NLS-1$	

    private static final String TAG_FILTER_ON_DESCRIPTION = "filterOnDescription"; //$NON-NLS-1$

    private static final String TAG_DESCRIPTION_FILTER_KIND = "descriptionFilterKind"; //$NON-NLS-1$

    private static final String TAG_DESCRIPTION_FILTER = "descriptionFilter"; //$NON-NLS-1$

    private static final String TAG_FILTER_ON_SEVERITY = "filterOnSeverity"; //$NON-NLS-1$

    private static final String TAG_SEVERITY_FILTER = "severityFilter"; //$NON-NLS-1$

    private static final String TAG_FILTER_ON_PRIORITY = "filterOnPriority"; //$NON-NLS-1$

    private static final String TAG_PRIORITY_FILTER = "priorityFilter"; //$NON-NLS-1$

    private static final String TAG_FILTER_ON_COMPLETION = "filterOnCompletion"; //$NON-NLS-1$

    private static final String TAG_COMPLETION_FILTER = "completionFilter"; //$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$

    public TasksFilter() {
        reset();
    }

    boolean getFilterOnMarkerLimit() {
        return filterOnMarkerLimit;
    }

    void setFilterOnMarkerLimit(boolean filterOnMarkerLimit) {
        this.filterOnMarkerLimit = filterOnMarkerLimit;
    }

    int getMarkerLimit() {
        return markerLimit;
    }

    void setMarkerLimit(int markerLimit) {
        if (markerLimit < 1) {
            markerLimit = TasksFilter.DEFAULT_MARKER_LIMIT;
        }

        //if (markerLimit < TasksFilter.MINIMUM_MARKER_LIMIT) {
        //	markerLimit = TasksFilter.MINIMUM_MARKER_LIMIT;
        //} else if (markerLimit > TasksFilter.MAXIMUM_MARKER_LIMIT) {
        //	markerLimit = TasksFilter.MAXIMUM_MARKER_LIMIT;
        //} 

        this.markerLimit = markerLimit;
    }

    boolean checkDescription(String desc) {
        if (desc == null) { // be paranoid
            desc = ""; //$NON-NLS-1$
        }
        boolean contains = containsSubstring(desc, descriptionFilter);
        return descriptionFilterKind == FILTER_CONTAINS ? contains : !contains;
    }

    public Object clone() {
        try {
            return super.clone();
        } catch (CloneNotSupportedException e) {
            throw new Error(); // shouldn't happen
        }
    }

    boolean containsSubstring(String string, String substring) {
        int strLen = string.length();
        int subLen = substring.length();
        int len = strLen - subLen;
        for (int i = 0; i <= len; ++i) {
            if (string.regionMatches(true, i, substring, 0, subLen)) {
                return true;
            }
        }
        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;
    }

    public void reset() {
        types = ROOT_TYPES;
        onResource = ON_ANY_RESOURCE;
        filterOnDescription = false;
        descriptionFilter = ""; //$NON-NLS-1$
        filterOnSeverity = false;
        severityFilter = 0;
        filterOnPriority = false;
        priorityFilter = 0;
        filterOnCompletion = false;
        completionFilter = 0;
        filterOnMarkerLimit = true;
        markerLimit = DEFAULT_MARKER_LIMIT;
    }

    /**
     * @see IPersistable
     */
    public void restoreState(IMemento memento) {
        IMemento children[] = memento.getChildren(TAG_TYPE);
        types = new String[children.length];
        for (int i = 0; i < children.length; i++) {
            types[i] = children[i].getString(TAG_ID);
        }
        Integer ival = memento.getInteger(TAG_ON_RESOURCE);
        onResource = ival == null ? ON_ANY_RESOURCE : ival.intValue();
        restoreWorkingSet(memento.getString(TAG_WORKING_SET));
        ival = memento.getInteger(TAG_FILTER_ON_DESCRIPTION);
        filterOnDescription = ival != null && ival.intValue() == 1;
        ival = memento.getInteger(TAG_DESCRIPTION_FILTER_KIND);
        descriptionFilterKind = ival == null ? FILTER_CONTAINS : ival
                .intValue();
        descriptionFilter = memento.getString(TAG_DESCRIPTION_FILTER);
        if (descriptionFilter == null)
            descriptionFilter = ""; //$NON-NLS-1$
        ival = memento.getInteger(TAG_FILTER_ON_SEVERITY);
        filterOnSeverity = ival != null && ival.intValue() == 1;
        ival = memento.getInteger(TAG_SEVERITY_FILTER);
        severityFilter = ival == null ? 0 : ival.intValue();
        ival = memento.getInteger(TAG_FILTER_ON_PRIORITY);
        filterOnPriority = ival != null && ival.intValue() == 1;
        ival = memento.getInteger(TAG_PRIORITY_FILTER);
        priorityFilter = ival == null ? 0 : ival.intValue();
        ival = memento.getInteger(TAG_FILTER_ON_COMPLETION);
        filterOnCompletion = ival != null && ival.intValue() == 1;
        ival = memento.getInteger(TAG_COMPLETION_FILTER);
        completionFilter = ival == null ? 0 : ival.intValue();
        ival = memento.getInteger(TAG_FILTER_ON_MARKER_LIMIT);
        filterOnMarkerLimit = ival == null || ival.intValue() == 1;
        ival = memento.getInteger(TAG_MARKER_LIMIT);
        markerLimit = ival == null ? DEFAULT_MARKER_LIMIT : ival.intValue();
    }

    /**
     * Restores the saved working set, if any.
     * 
     * @param the saved working set name or null
     */
    private void restoreWorkingSet(String workingSetName) {
        if (workingSetName != null) {
            IWorkingSetManager workingSetManager = PlatformUI.getWorkbench()
                    .getWorkingSetManager();
            IWorkingSet workingSet = workingSetManager
                    .getWorkingSet(workingSetName);

            if (workingSet != null) {
                this.workingSet = workingSet;
            }
        }
    }

    /**
     * Saves the object state within a memento.
     *
     * @param memento a memento to receive the object state
     */
    public void saveState(IMemento memento) {
        for (int i = 0; i < types.length; i++) {
            memento.createChild(TAG_TYPE).putString(TAG_ID, types[i]);
        }
        memento.putInteger(TAG_ON_RESOURCE, onResource);
        if (workingSet != null) {
            memento.putString(TAG_WORKING_SET, workingSet.getName());
        }
        memento.putInteger(TAG_FILTER_ON_DESCRIPTION, filterOnDescription ? 1
                : 0);
        memento.putInteger(TAG_DESCRIPTION_FILTER_KIND, descriptionFilterKind);
        memento.putString(TAG_DESCRIPTION_FILTER, descriptionFilter);
        memento.putInteger(TAG_FILTER_ON_SEVERITY, filterOnSeverity ? 1 : 0);
        memento.putInteger(TAG_SEVERITY_FILTER, severityFilter);
        memento.putInteger(TAG_FILTER_ON_PRIORITY, filterOnPriority ? 1 : 0);
        memento.putInteger(TAG_PRIORITY_FILTER, priorityFilter);
        memento
                .putInteger(TAG_FILTER_ON_COMPLETION, filterOnCompletion ? 1
                        : 0);
        memento.putInteger(TAG_COMPLETION_FILTER, completionFilter);
        memento.putInteger(TAG_FILTER_ON_MARKER_LIMIT, filterOnMarkerLimit ? 1
                : 0);
        memento.putInteger(TAG_MARKER_LIMIT, markerLimit);
    }

    public boolean select(Viewer viewer, Object parentElement, Object element) {
        return select((IMarker) element);
    }

    public boolean select(IMarker marker) {
        // resource settings are handled by the content provider
        return selectByType(marker) && selectByAttributes(marker)
                && selectByWorkingSet(marker);
    }

    public boolean select(IMarkerDelta markerDelta) {
        // resource settings are handled by the content provider
        return selectByType(markerDelta) && selectByAttributes(markerDelta)
                && selectByWorkingSet(markerDelta);
    }

    private boolean selectByType(IMarker marker) {
        for (int i = 0; i < types.length; ++i) {
            if (MarkerUtil.isMarkerType(marker, types[i]))
                return true;
        }
        return false;
    }

    private boolean selectByType(IMarkerDelta markerDelta) {
        for (int i = 0; i < types.length; ++i) {
            if (markerDelta.isSubtypeOf(types[i]))
                return true;
        }
        return false;
    }

    /**
     * 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 selectByWorkingSet(IMarker marker) {
        if (workingSet == null || onResource != ON_WORKING_SET) {
            return true;
        }
        IResource resource = marker.getResource();
        if (resource != null) {
            return isEnclosed(resource);
        }
        return false;
    }

    /**
     * Returns whether the specified marker delta should be filter out 
     * or not.
     * 
     * @param markerDelta the marker delta to test
     * @return 
     * 	true=the marker delta should not be filtered out
     * 	false=the marker delta should be filtered out
     */
    private boolean selectByWorkingSet(IMarkerDelta markerDelta) {
        if (workingSet == null || onResource != ON_WORKING_SET) {
            return true;
        }
        IResource resource = markerDelta.getResource();
        if (resource != null) {
            return isEnclosed(resource);
        }
        return false;
    }

    /* 
     * WARNING: selectByAttributes(IMarker) and selectByAttributes(IMarkerDelta) must correspond.
     */

    private boolean selectByAttributes(IMarker marker) {

        // severity filter applies only to problems
        if (filterOnSeverity
                && MarkerUtil.isMarkerType(marker, IMarker.PROBLEM)) {
            int sev = MarkerUtil.getSeverity(marker);
            if ((severityFilter & (1 << sev)) == 0)
                return false;
        }

        // priority and completion filters apply only to tasks
        // avoid doing type check more than once
        if ((filterOnPriority || filterOnCompletion)
                && MarkerUtil.isMarkerType(marker, IMarker.TASK)) {
            if (filterOnPriority) {
                int pri = MarkerUtil.getPriority(marker);
                if ((priorityFilter & (1 << pri)) == 0)
                    return false;
            }
            if (filterOnCompletion) {
                boolean complete = MarkerUtil.isComplete(marker);
                if ((completionFilter & (complete ? 2 : 1)) == 0)
                    return false;
            }
        }

        // description applies to all markers
        if (filterOnDescription) {
            String desc = MarkerUtil.getMessage(marker);
            if (!checkDescription(desc))
                return false;
        }
        return true;
    }

    private boolean selectByAttributes(IMarkerDelta markerDelta) {

        // severity filter applies only to problems
        if (filterOnSeverity && markerDelta.isSubtypeOf(IMarker.PROBLEM)) {
            int sev = markerDelta.getAttribute(IMarker.SEVERITY,
                    IMarker.SEVERITY_WARNING);
            if ((severityFilter & (1 << sev)) == 0)
                return false;
        }

        // priority and completion filters apply only to tasks
        // avoid doing type check more than once
        if ((filterOnPriority || filterOnCompletion)
                && markerDelta.isSubtypeOf(IMarker.TASK)) {
            if (filterOnPriority) {
                int pri = markerDelta.getAttribute(IMarker.PRIORITY,
                        IMarker.PRIORITY_NORMAL);
                if ((priorityFilter & (1 << pri)) == 0)
                    return false;
            }
            if (filterOnCompletion) {
                boolean complete = markerDelta
                        .getAttribute(IMarker.DONE, false);
                if ((completionFilter & (complete ? 2 : 1)) == 0)
                    return false;
            }
        }

        // description applies to all markers
        if (filterOnDescription) {
            String desc = markerDelta.getAttribute(IMarker.MESSAGE, ""); //$NON-NLS-1$
            if (!checkDescription(desc))
                return false;
        }
        return true;
    }

    /**
     * Returns whether the filter is including all markers.
     *
     * @return <code>true</code> if the filter includes all markers, <code>false</code> if not
     */
    public boolean isShowingAll() {
        if (filterOnDescription || filterOnSeverity || filterOnPriority
                || filterOnCompletion) {
            return false;
        }
        if (onResource != ON_ANY_RESOURCE) {
            return false;
        }

        HashSet set = new HashSet(Arrays.asList(types));
        if (set.size() != ROOT_TYPES.length) {
            return false;
        }
        for (int i = 0; i < ROOT_TYPES.length; ++i) {
            if (!set.contains(ROOT_TYPES[i])) {
                return false;
            }
        }
        return true;
    }
}
