/*******************************************************************************
 * 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.tasklist;

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

import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IMarkerDelta;
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.runtime.CoreException;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.swt.widgets.Control;

/**
 * Task list content provider returns elements that should be
 * in the task list depending on the selection mode.
 * It goes directly to the marker manager and retreives
 * tasks and problems.
 */
class TaskListContentProvider implements IStructuredContentProvider,
        IResourceChangeListener {

    private static final int TASKS = 0;

    private static final int ERRORS = 1;

    private static final int WARNINGS = 2;

    private static final int INFOS = 3;

    private TaskList taskList;

    private TableViewer viewer;

    private IResource input;

    /* cached counts of tasks, errors, warnings and infos for the visible 
     * markers, maintained incrementally */
    private int[] visibleMarkerCounts = null;

    /* cached count of all markers in workspace matching supported root types 
     * (tasks & problems), maintained incrementally */
    private int totalMarkerCount = -1;

    /**
     * The constructor.
     */
    public TaskListContentProvider(TaskList taskList) {
        this.taskList = taskList;
        this.viewer = taskList.getTableViewer();
    }

    private boolean getFilterOnMarkerLimit() {
        return taskList.getFilter().getFilterOnMarkerLimit();
    }

    private int getMarkerLimit() {
        return taskList.getFilter().getMarkerLimit();
    }

    private boolean isMarkerLimitExceeded() {
        return taskList.isMarkerLimitExceeded();
    }

    private void setMarkerLimitExceeded(boolean markerLimitExceeded) {
        taskList.setMarkerLimitExceeded(markerLimitExceeded);
    }

    /**
     * Returns a one-line string containing a summary of the number
     * of visible tasks and problems.
     */
    public String getStatusSummaryVisible() {
        if (visibleMarkerCounts == null) {
            return ""; //$NON-NLS-1$
        }

        return TaskListMessages.format("TaskList.statusSummaryVisible", //$NON-NLS-1$
                new Object[] { new Integer(sum(visibleMarkerCounts)),
                        getStatusSummaryBreakdown(visibleMarkerCounts) });
    }

    /**
     * Returns a one-line string containing a summary of the number
     * of selected tasks and problems.
     * 
     * @param selection the current selection
     */
    public String getStatusSummarySelected(IStructuredSelection selection) {
        int[] selectedMarkerCounts = getMarkerCounts(selection.toList());
        return TaskListMessages.format("TaskList.statusSummarySelected", //$NON-NLS-1$
                new Object[] { new Integer(sum(selectedMarkerCounts)),
                        getStatusSummaryBreakdown(selectedMarkerCounts) });
    }

    /**
     * Returns a one-line string containing a summary of the number of 
     * given tasks, errors, warnings, and infos.
     */
    private String getStatusSummaryBreakdown(int[] counts) {
        return TaskListMessages.format("TaskList.statusSummaryBreakdown", //$NON-NLS-1$
                new Object[] { new Integer(counts[TASKS]),
                        new Integer(counts[ERRORS]),
                        new Integer(counts[WARNINGS]),
                        new Integer(counts[INFOS]) });
    }

    /**
     * Returns a one-line string containing a summary of the number items
     * being shown by the filter, for display in the title bar.
     */
    public String getTitleSummary() {
        if (visibleMarkerCounts == null) {
            return ""; //$NON-NLS-1$
        }

        int visibleMarkerCount = sum(visibleMarkerCounts);
        TasksFilter filter = (TasksFilter) taskList.getFilter();

        if (filter.isShowingAll()) {
            return TaskListMessages.format("TaskList.titleSummaryUnfiltered", //$NON-NLS-1$
                    new Object[] { new Integer(visibleMarkerCount) });
        } else {
            return TaskListMessages.format("TaskList.titleSummaryFiltered", //$NON-NLS-1$
                    new Object[] { new Integer(visibleMarkerCount),
                            new Integer(getTotalMarkerCount()) });
        }
    }

    /**
     * Returns the sum of the given counts.
     */
    private int sum(int[] counts) {
        int sum = 0;

        for (int i = 0, l = counts.length; i < l; ++i) {
            sum += counts[i];
        }

        return sum;
    }

    /**
     * Returns the count of all markers in the workspace which can be shown in 
     * the task list. This is computed once, then maintained incrementally by 
     * the delta processing.
     */
    private int getTotalMarkerCount() {
        if (totalMarkerCount == -1) {
            totalMarkerCount = 0;

            try {
                IResource root = taskList.getWorkspace().getRoot();
                IMarker[] markers = root.findMarkers(null, true,
                        IResource.DEPTH_INFINITE);

                for (int i = 0; i < markers.length; ++i) {
                    if (isRootType(markers[i])) {
                        ++totalMarkerCount;
                    }
                }
            } catch (CoreException e) {
                // shouldn't happen
            }
        }

        return totalMarkerCount;
    }

    /**
     * Returns whether the given marker is a subtype of one of the root types.
     */
    private boolean isRootType(IMarker marker) {
        String[] rootTypes = TasksFilter.ROOT_TYPES;

        for (int i = 0, l = rootTypes.length; i < l; ++i) {
            if (MarkerUtil.isMarkerType(marker, rootTypes[i])) {
                return true;
            }
        }

        return false;
    }

    /**
     * Returns the markers to show in the task list.
     */
    private IMarker[] getMarkers() throws CoreException {
        IResource[] resources = taskList.getResources();
        int l = resources.length;
        IResource resource;
        boolean bExists = false;

        for (int i = 0; i < l; i++) {
            resource = resources[i];

            if (resource != null && resource.exists()) {
                bExists = true;
                break;
            }
        }

        if (!bExists) {
            return new IMarker[0];
        }

        if (taskList.showOwnerProject()) {
            IResource[] projectResources = new IResource[l];
            IResource project;

            for (int i = 0; i < l; i++) {
                resource = resources[i];

                if (resource != null) {
                    project = resource.getProject();

                    if (project != null) {
                        projectResources[i] = project;
                    } else {
                        projectResources[i] = resource;
                    }
                }
            }

            resources = projectResources;
        }

        int depth = taskList.getResourceDepth();
        TasksFilter filter = taskList.getFilter();
        Set set = new HashSet();

        for (int i = 0; i < l; i++) {
            resource = resources[i];

            if (resource != null) {
                IMarker[] markers = resource.findMarkers(null, true, depth);

                for (int j = 0; j < markers.length; ++j) {
                    IMarker marker = markers[j];

                    if (filter.select(marker)) {
                        set.add(marker);
                    }
                }
            }
        }

        IMarker[] result = new IMarker[set.size()];
        set.toArray(result);
        return result;
    }

    /**
     * Returns the number of tasks, errors, warnings, infos
     * in the given markers.
     */
    private int[] getMarkerCounts(List markers) {
        int[] markerCounts = new int[4];
        Iterator iterator = markers.iterator();

        while (iterator.hasNext()) {
            IMarker marker = (IMarker) iterator.next();

            if (MarkerUtil.isMarkerType(marker, IMarker.PROBLEM)) {
                switch (MarkerUtil.getSeverity(marker)) {
                case IMarker.SEVERITY_ERROR:
                    ++markerCounts[ERRORS];
                    break;
                case IMarker.SEVERITY_WARNING:
                    ++markerCounts[WARNINGS];
                    break;
                case IMarker.SEVERITY_INFO:
                    ++markerCounts[INFOS];
                    break;
                }
            } else if (MarkerUtil.isMarkerType(marker, IMarker.TASK)) {
                ++markerCounts[TASKS];
            }
        }

        return markerCounts;
    }

    /**
     * Updates the marker counts for the given delta.
     * Assumptions:
     *   - the delta is either an addition or a removal
     *   - problem severities don't change
     */
    private void updateMarkerCounts(IMarkerDelta markerDelta, int difference) {
        if (visibleMarkerCounts == null)
            return;

        if (markerDelta.isSubtypeOf(IMarker.PROBLEM)) {
            int severity = markerDelta.getAttribute(IMarker.SEVERITY,
                    IMarker.SEVERITY_WARNING);

            switch (severity) {
            case IMarker.SEVERITY_ERROR:
                visibleMarkerCounts[ERRORS] += difference;
                break;
            case IMarker.SEVERITY_WARNING:
                visibleMarkerCounts[WARNINGS] += difference;
                break;
            case IMarker.SEVERITY_INFO:
                visibleMarkerCounts[INFOS] += difference;
                break;
            }
        } else if (markerDelta.isSubtypeOf(IMarker.TASK))
            visibleMarkerCounts[TASKS] += difference;
    }

    /**
     * Updates the viewer given the lists of added, removed, and changes 
     * markers. This is called inside an syncExec.
     */
    private void updateViewer(List additions, List removals, List changes) {

        // The widget may have been destroyed by the time this is run.  
        // Check for this and do nothing if so.
        Control ctrl = viewer.getControl();

        if (ctrl == null || ctrl.isDisposed()) {
            return;
        }

        //update the viewer based on the marker changes.
        //process removals before additions, to avoid multiple equal elements in 
        //the viewer
        if (removals.size() > 0) {

            // Cancel any open cell editor.  We assume that the one being edited 
            // is the one being removed.
            viewer.cancelEditing();
            viewer.remove(removals.toArray());
        }

        if (additions.size() > 0) {
            viewer.add(additions.toArray());
        }

        if (changes.size() > 0) {
            viewer.update(changes.toArray(), null);
        }
    }

    /**
     * The visual part that is using this content provider is about
     * to be disposed. Deallocate all allocated SWT resources.
     */
    public void dispose() {
        if (input != null) {
            input.getWorkspace().removeResourceChangeListener(this);
            input = null;
        }
    }

    public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
        if (this.input != null) {
            this.input.getWorkspace().removeResourceChangeListener(this);
        }

        this.input = (IResource) newInput;

        if (this.input != null) {
            this.input.getWorkspace().addResourceChangeListener(this,
                    IResourceChangeEvent.POST_CHANGE);
        }

        this.viewer = (TableViewer) viewer;
    }

    /**
     * Returns all the markers that should be shown for
     * the current settings.
     */
    public Object[] getElements(Object parent) {
        try {
            IMarker[] markers = getMarkers();
            this.visibleMarkerCounts = getMarkerCounts(Arrays.asList(markers));

            if (getFilterOnMarkerLimit() && markers.length > getMarkerLimit()) {
                if (!isMarkerLimitExceeded()) {
                    setMarkerLimitExceeded(true);

                    viewer.getControl().getDisplay().syncExec(new Runnable() {
                        public void run() {
                            viewer.refresh();
                        }
                    });
                }

                return new IMarker[0];
            } else {
                if (isMarkerLimitExceeded()) {
                    setMarkerLimitExceeded(false);

                    viewer.getControl().getDisplay().syncExec(new Runnable() {
                        public void run() {
                            viewer.refresh();
                        }
                    });
                }

                return markers;
            }
        } catch (CoreException e) {
            return new IMarker[0];
        }
    }

    /**
     * The workbench has changed.  Process the delta and issue updates to the 
     * viewer, inside the UI thread.
     *
     * @see IResourceChangeListener#resourceChanged
     */
    public void resourceChanged(final IResourceChangeEvent event) {
        /*
         * gather all marker changes from the delta. be sure to do this in the 
         * calling thread, as the delta is destroyed when this method returns
         */
        IMarkerDelta[] markerDeltas = event.findMarkerDeltas(null, true);

        if (markerDeltas == null)
            return;

        int oldTotal = totalMarkerCount;
        final List additions = new ArrayList();
        final List removals = new ArrayList();
        final List changes = new ArrayList();

        for (int i = 0; i < markerDeltas.length; i++) {
            IMarkerDelta markerDelta = markerDeltas[i];

            if (markerDelta == null)
                continue;

            int iKind = markerDelta.getKind();

            for (int j = 0; j < TasksFilter.ROOT_TYPES.length; j++) {
                if (markerDelta.isSubtypeOf(TasksFilter.ROOT_TYPES[j])) {

                    /* 
                     * Updates the total count of markers given the applicable 
                     * marker deltas. 
                     */
                    if (totalMarkerCount != -1) {
                        switch (iKind) {
                        case IResourceDelta.ADDED:
                            totalMarkerCount++;
                            break;
                        case IResourceDelta.REMOVED:
                            totalMarkerCount--;
                            break;
                        }
                    }

                    /*
                     * Partition the marker deltas into one of the three given 
                     * lists depending on
                     * the type of delta (add, remove, or change).
                     * The resulting lists contain the corresponding markers, 
                     * not the deltas.
                     * Deltas which are not under the current focus resource are 
                     * discarded.
                     * This also updates the marker counts.
                     */

                    IResource resource = markerDelta.getResource();

                    if (resource == null)
                        continue;

                    boolean affectedBy = taskList.checkResource(resource)
                            && taskList.getFilter().select(markerDelta);

                    if (affectedBy) {
                        IMarker marker = markerDelta.getMarker();

                        switch (iKind) {
                        case IResourceDelta.ADDED:
                            additions.add(marker);
                            updateMarkerCounts(markerDelta, +1);
                            break;
                        case IResourceDelta.REMOVED:
                            removals.add(marker);
                            updateMarkerCounts(markerDelta, -1);
                            break;
                        case IResourceDelta.CHANGED:
                            changes.add(marker);
                            /* 
                             * Assume attribute changes don't affect marker 
                             * counts. This is only true if problem severities 
                             * can't change. 
                             */
                            break;
                        }
                    }

                    break;
                }
            }
        }

        if (oldTotal == totalMarkerCount
                && additions.size() + removals.size() + changes.size() == 0) {
            // no changes to markers that we care about
            return;
        }

        /*
         * do the required viewer updates in the UI thread need to use syncExec; 
         * see 1G95PU8: ITPUI:WIN2000 - Changing task description flashes old 
         * description
         */
        viewer.getControl().getDisplay().syncExec(new Runnable() {
            public void run() {
                if (getFilterOnMarkerLimit()
                        && sum(visibleMarkerCounts) > getMarkerLimit()) {
                    if (!isMarkerLimitExceeded()) {
                        setMarkerLimitExceeded(true);
                        viewer.refresh();
                    }
                } else if (taskList.isMarkerLimitExceeded()) {
                    setMarkerLimitExceeded(false);
                    viewer.refresh();
                } else {
                    updateViewer(additions, removals, changes);
                }

                /* Update the task list's status message.
                 * XXX: Quick and dirty solution here.  
                 * Would be better to have a separate model for the tasks and
                 * have both the content provider and the task list register for 
                 * updates. XXX: Do this inside the syncExec, since we're 
                 * talking to status line widget.
                 */
                taskList.markersChanged();
            }
        });
    }
}