/*******************************************************************************
 * 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 
 * 	Sebastian Davids <sdavids@gmx.de> - Fix for bug 19346 - Dialog font
 * 		should be activated and used by other components.
 *******************************************************************************/
package org.eclipse.ui.dialogs;

import java.text.Collator;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;

import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceProxy;
import org.eclipse.core.resources.IResourceProxyVisitor;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.IDialogSettings;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.BusyIndicator;
import org.eclipse.swt.events.KeyAdapter;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.internal.ide.IDEWorkbenchMessages;
import org.eclipse.ui.internal.ide.IDEWorkbenchPlugin;
import org.eclipse.ui.internal.ide.StringMatcher;
import org.eclipse.ui.model.WorkbenchLabelProvider;

/**
 * Shows a list of resources to the user with a text entry field
 * for a string pattern used to filter the list of resources.
 * <p>
 * 
 * @since 2.1
 */
public class ResourceListSelectionDialog extends SelectionDialog {
	
	private static final String DIALOG_SETTINGS_SECTION = "ResourceListSelectionDialogSettings"; //$NON-NLS-1$
    
    Text pattern;

    Table resourceNames;

    Table folderNames;

    String patternString;

    IContainer container;

    int typeMask;

    static Collator collator = Collator.getInstance();

    boolean gatherResourcesDynamically = true;

    StringMatcher stringMatcher;

    UpdateFilterThread updateFilterThread;

    UpdateGatherThread updateGatherThread;

    ResourceDescriptor[] descriptors;

    int descriptorsSize;

    WorkbenchLabelProvider labelProvider = new WorkbenchLabelProvider();
    
    boolean okEnabled = false;

    private boolean showDerived = false;

    private Button showDerivedButton;

    private boolean allowUserToToggleDerived;
    
    static class ResourceDescriptor implements Comparable {
        String label;

        ArrayList resources = new ArrayList();

        boolean resourcesSorted = true;

        public int compareTo(Object o) {
            return collator.compare(label, ((ResourceDescriptor) o).label);
        }
    }

    class UpdateFilterThread extends Thread {
        boolean stop = false;

        int firstMatch = 0;

        int lastMatch = descriptorsSize - 1;

        public void run() {
            Display display = resourceNames.getDisplay();
            final int itemIndex[] = { 0 };
            final int itemCount[] = { 0 };
            //Keep track of if the widget got disposed 
            //so that we can abort if required
            final boolean[] disposed = { false };
            display.syncExec(new Runnable() {
                public void run() {
                    //Be sure the widget still exists
                    if (resourceNames.isDisposed()) {
                        disposed[0] = true;
                        return;
                    }
                    itemCount[0] = resourceNames.getItemCount();
                }
            });

            if (disposed[0])
                return;

            int last;
            if ((patternString.indexOf('?') == -1)
                    && (patternString.endsWith("*")) && //$NON-NLS-1$
                    (patternString.indexOf('*') == patternString.length() - 1)) {
                // Use a binary search to get first and last match when the pattern
                // string ends with "*" and has no other embedded special characters.  
                // For this case, we can be smarter about getting the first and last 
                // match since the items are in sorted order.
                firstMatch = getFirstMatch();
                if (firstMatch == -1) {
                    firstMatch = 0;
                    lastMatch = -1;
                } else {
                    lastMatch = getLastMatch();
                }
                last = lastMatch;
                for (int i = firstMatch; i <= lastMatch; i++) {
                    if (i % 50 == 0) {
                        try {
                            Thread.sleep(10);
                        } catch (InterruptedException e) {
                            // ignore
                        }
                    }
                    if (stop || resourceNames.isDisposed()) {
                        disposed[0] = true;
                        return;
                    }
                    final int index = i;
                    display.syncExec(new Runnable() {
                        public void run() {
                            if (stop || resourceNames.isDisposed())
                                return;
                            updateItem(index, itemIndex[0], itemCount[0]);
                            itemIndex[0]++;
                        }
                    });
                }
            } else {
                last = lastMatch;
                boolean setFirstMatch = true;
                for (int i = firstMatch; i <= lastMatch; i++) {
                    if (i % 50 == 0) {
                        try {
                            Thread.sleep(10);
                        } catch (InterruptedException e) {
                            // ignore
                        }
                    }
                    if (stop || resourceNames.isDisposed()) {
                        disposed[0] = true;
                        return;
                    }
                    final int index = i;
                    if (match(descriptors[index].label)) {
                        if (setFirstMatch) {
                            setFirstMatch = false;
                            firstMatch = index;
                        }
                        last = index;
                        display.syncExec(new Runnable() {
                            public void run() {
                                if (stop || resourceNames.isDisposed())
                                    return;
                                updateItem(index, itemIndex[0], itemCount[0]);
                                itemIndex[0]++;
                            }
                        });
                    }
                }
            }

            if (disposed[0])
                return;

            lastMatch = last;
            display.syncExec(new Runnable() {
                public void run() {
                    if (resourceNames.isDisposed())
                        return;
                    itemCount[0] = resourceNames.getItemCount();
                    if (itemIndex[0] < itemCount[0]) {
                        resourceNames.setRedraw(false);
                        resourceNames.remove(itemIndex[0], itemCount[0] - 1);
                        resourceNames.setRedraw(true);
                    }
                    // If no resources, remove remaining folder entries
                    if (resourceNames.getItemCount() == 0) {
                        folderNames.removeAll();
                        updateOKState(false);
                    }
                }
            });
        }
    }

    class UpdateGatherThread extends Thread {
        boolean stop = false;

        int lastMatch = -1;

        int firstMatch = 0;

        boolean refilter = false;

        public void run() {
            Display display = resourceNames.getDisplay();
            final int itemIndex[] = { 0 };
            final int itemCount[] = { 0 };
            //Keep track of if the widget got disposed 
            //so that we can abort if required
            final boolean[] disposed = { false };
            display.syncExec(new Runnable() {
                public void run() {
                    //Be sure the widget still exists
                    if (resourceNames.isDisposed()) {
                        disposed[0] = true;
                        return;
                    }
                    itemCount[0] = resourceNames.getItemCount();
                }
            });

            if (disposed[0]) {
                return;
            }

            if (!refilter) {
                for (int i = 0; i <= lastMatch; i++) {
                    if (i % 50 == 0) {
                        try {
                            Thread.sleep(10);
                        } catch (InterruptedException e) {
                            // ignore
                        }
                    }
                    if (stop || resourceNames.isDisposed()) {
                        disposed[0] = true;
                        return;
                    }
                    final int index = i;
                    display.syncExec(new Runnable() {
                        public void run() {
                            if (stop || resourceNames.isDisposed())
                                return;
                            updateItem(index, itemIndex[0], itemCount[0]);
                            itemIndex[0]++;
                        }
                    });
                }
            } else {
                // we're filtering the previous list
                for (int i = firstMatch; i <= lastMatch; i++) {
                    if (i % 50 == 0) {
                        try {
                            Thread.sleep(10);
                        } catch (InterruptedException e) {
                            // ignore
                        }
                    }
                    if (stop || resourceNames.isDisposed()) {
                        disposed[0] = true;
                        return;
                    }
                    final int index = i;
                    if (match(descriptors[index].label)) {
                        display.syncExec(new Runnable() {
                            public void run() {
                                if (stop || resourceNames.isDisposed())
                                    return;
                                updateItem(index, itemIndex[0], itemCount[0]);
                                itemIndex[0]++;
                            }
                        });
                    }
                }
            }

            if (disposed[0]) {
                return;
            }

            display.syncExec(new Runnable() {
                public void run() {
                    if (resourceNames.isDisposed()) {
                        return;
                    }
                    itemCount[0] = resourceNames.getItemCount();
                    if (itemIndex[0] < itemCount[0]) {
                        resourceNames.setRedraw(false);
                        resourceNames.remove(itemIndex[0], itemCount[0] - 1);
                        resourceNames.setRedraw(true);
                    }
                    // If no resources, remove remaining folder entries
                    if (resourceNames.getItemCount() == 0) {
                        folderNames.removeAll();
                        updateOKState(false);
                    }
                }
            });
        }
    }

    /**
     * Creates a new instance of the class.
     * 
     * @param parentShell shell to parent the dialog on
     * @param resources resources to display in the dialog
     */
    public ResourceListSelectionDialog(Shell parentShell, IResource[] resources) {
        super(parentShell);
        setShellStyle(getShellStyle() | SWT.RESIZE);
        gatherResourcesDynamically = false;
        initDescriptors(resources);
    }

    /**
     * Creates a new instance of the class.  When this constructor is used to
     * create the dialog, resources will be gathered dynamically as the pattern
     * string is specified.  Only resources of the given types that match the 
     * pattern string will be listed.  To further filter the matching resources,
     * @see #select(IResource)
     * 
     * @param parentShell shell to parent the dialog on
     * @param container container to get resources from
     * @param typeMask mask containing IResource types to be considered
     */
    public ResourceListSelectionDialog(Shell parentShell, IContainer container,
            int typeMask) {
        super(parentShell);
        this.container = container;
        this.typeMask = typeMask;
        setShellStyle(getShellStyle() | SWT.RESIZE);
    }

    /**
     * Adjust the pattern string for matching.
     */
    protected String adjustPattern() {
        String text = pattern.getText().trim();
        if (text.endsWith("<")) { //$NON-NLS-1$
            // the < character indicates an exact match search
            return text.substring(0, text.length() - 1);
        }
        if (!text.equals("") && !text.endsWith("*")) { //$NON-NLS-1$ //$NON-NLS-2$
        	return text + "*"; //$NON-NLS-1$
        }
        return text;
    }

    /**
     * @see org.eclipse.jface.dialogs.Dialog#cancelPressed()
     */
    protected void cancelPressed() {
        setResult(null);
        super.cancelPressed();
    }

    /**
     * @see org.eclipse.jface.window.Window#close()
     */
    public boolean close() {
        boolean result = super.close();
        labelProvider.dispose();
        return result;
    }

    /**
     * @see org.eclipse.jface.window.Window#create()
     */
    public void create() {
        super.create();
        pattern.setFocus();
        getButton(IDialogConstants.OK_ID).setEnabled(okEnabled);
    }

    /**
     * Creates the contents of this dialog, initializes the
     * listener and the update thread.
     * 
     * @param parent parent to create the dialog widgets in
     */
    protected Control createDialogArea(Composite parent) {

        Composite dialogArea = (Composite) super.createDialogArea(parent);
        Label l = new Label(dialogArea, SWT.NONE);
        l.setText(IDEWorkbenchMessages.ResourceSelectionDialog_label);
        GridData data = new GridData(GridData.FILL_HORIZONTAL);
        l.setLayoutData(data);

        pattern = new Text(dialogArea, SWT.SINGLE | SWT.BORDER);
        pattern.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
        l = new Label(dialogArea, SWT.NONE);
        l.setText(IDEWorkbenchMessages.ResourceSelectionDialog_matching);
        data = new GridData(GridData.FILL_HORIZONTAL);
        l.setLayoutData(data);
        resourceNames = new Table(dialogArea, SWT.SINGLE | SWT.BORDER
                | SWT.V_SCROLL);
        data = new GridData(GridData.FILL_BOTH);
        data.heightHint = 12 * resourceNames.getItemHeight();
        resourceNames.setLayoutData(data);

        l = new Label(dialogArea, SWT.NONE);
        l.setText(IDEWorkbenchMessages.ResourceSelectionDialog_folders);
        data = new GridData(GridData.FILL_HORIZONTAL);
        l.setLayoutData(data);

        folderNames = new Table(dialogArea, SWT.SINGLE | SWT.BORDER
                | SWT.V_SCROLL | SWT.H_SCROLL);
        data = new GridData(GridData.FILL_BOTH);
        data.widthHint = 300;
        data.heightHint = 4 * folderNames.getItemHeight();
        folderNames.setLayoutData(data);

        if (gatherResourcesDynamically) {
            updateGatherThread = new UpdateGatherThread();
        } else {
            updateFilterThread = new UpdateFilterThread();
        }

        pattern.addKeyListener(new KeyAdapter() {
            public void keyReleased(KeyEvent e) {
                if (e.keyCode == SWT.ARROW_DOWN)
                    resourceNames.setFocus();
            }
        });

        pattern.addModifyListener(new ModifyListener() {
            public void modifyText(ModifyEvent e) {
                refresh(false);
            }
        });

        resourceNames.addSelectionListener(new SelectionAdapter() {
            public void widgetSelected(SelectionEvent e) {
                updateFolders((ResourceDescriptor) e.item.getData());
            }

            public void widgetDefaultSelected(SelectionEvent e) {
                okPressed();
            }
        });

        folderNames.addSelectionListener(new SelectionAdapter() {
            public void widgetDefaultSelected(SelectionEvent e) {
                okPressed();
            }
        });

        if (getAllowUserToToggleDerived()) {
            showDerivedButton = new Button(dialogArea, SWT.CHECK);
            showDerivedButton.setText(IDEWorkbenchMessages.ResourceSelectionDialog_showDerived);
            showDerivedButton.addSelectionListener(new SelectionAdapter() {
                public void widgetSelected(SelectionEvent e) {
                    setShowDerived(showDerivedButton.getSelection());
                    refresh(true);
                }
            });
            showDerivedButton.setSelection(getShowDerived());
        }
            
        applyDialogFont(dialogArea);
        return dialogArea;
    }

    /**
     * Returns whether to include a "Show derived resources" checkbox in the dialog.
     * The default is <code>false</code>.
     * 
     * @return <code>true</code> to include the checkbox, <code>false</code> to omit
     * @since 3.1
     */
    public boolean getAllowUserToToggleDerived() {
        return allowUserToToggleDerived;
    }

    /**
     * Sets whether to include a "Show derived resources" checkbox in the dialog.
     * 
     * @param allow <code>true</code> to include the checkbox, <code>false</code> to omit
     * @since 3.1
     */
    public void setAllowUserToToggleDerived(boolean allow) {
        allowUserToToggleDerived = allow;
    }
    
    /**
     */
    private void filterResources(boolean force) {
        String oldPattern = force ? null : patternString;
        patternString = adjustPattern();
        if (!force && patternString.equals(oldPattern))
            return;

        updateFilterThread.stop = true;
        stringMatcher = new StringMatcher(patternString, true, false);
        UpdateFilterThread oldThread = updateFilterThread;
        updateFilterThread = new UpdateFilterThread();
        if (patternString.equals("")) { //$NON-NLS-1$
            updateFilterThread.firstMatch = 0;
            updateFilterThread.lastMatch = -1;
            updateFilterThread.start();
            return;
        }

        if (oldPattern != null && (oldPattern.length() != 0)
                && oldPattern.endsWith("*") && patternString.endsWith("*")) { //$NON-NLS-1$ //$NON-NLS-2$
            int matchLength = oldPattern.length() - 1;
            if (patternString.regionMatches(0, oldPattern, 0, matchLength)) {
                // filter the previous list of items, this is done when the 
                // new pattern is a derivative of the old pattern
                updateFilterThread.firstMatch = oldThread.firstMatch;
                updateFilterThread.lastMatch = oldThread.lastMatch;
                updateFilterThread.start();
                return;
            }
        }

        // filter the entire list
        updateFilterThread.firstMatch = 0;
        updateFilterThread.lastMatch = descriptorsSize - 1;
        updateFilterThread.start();
    }

    /**
     * Use a binary search to get the first match for the patternString.
     * This method assumes the patternString does not contain any '?' 
     * characters and that it contains only one '*' character at the end
     * of the string.
     */
    private int getFirstMatch() {
        int high = descriptorsSize;
        int low = -1;
        boolean match = false;
        ResourceDescriptor desc = new ResourceDescriptor();
        desc.label = patternString.substring(0, patternString.length() - 1);
        while (high - low > 1) {
            int index = (high + low) / 2;
            String label = descriptors[index].label;
            if (match(label)) {
                high = index;
                match = true;
            } else {
                int compare = descriptors[index].compareTo(desc);
                if (compare == -1) {
                    low = index;
                } else {
                    high = index;
                }
            }
        }
        if (match)
            return high;
        return -1;
    }

    /**
     */
    private void gatherResources(boolean force) {
        String oldPattern = force ? null : patternString;
        patternString = adjustPattern();
        if (!force && patternString.equals(oldPattern))
            return;

        updateGatherThread.stop = true;
        updateGatherThread = new UpdateGatherThread();

        if (patternString.equals("")) { //$NON-NLS-1$
            updateGatherThread.start();
            return;
        }
        stringMatcher = new StringMatcher(patternString, true, false);

        if (oldPattern != null && (oldPattern.length() != 0)
                && oldPattern.endsWith("*") && patternString.endsWith("*")) { //$NON-NLS-1$ //$NON-NLS-2$
            // see if the new pattern is a derivative of the old pattern
            int matchLength = oldPattern.length() - 1;
            if (patternString.regionMatches(0, oldPattern, 0, matchLength)) {
                updateGatherThread.refilter = true;
                updateGatherThread.firstMatch = 0;
                updateGatherThread.lastMatch = descriptorsSize - 1;
                updateGatherThread.start();
                return;
            }
        }

        final ArrayList resources = new ArrayList();
        BusyIndicator.showWhile(getShell().getDisplay(), new Runnable() {
            public void run() {
                getMatchingResources(resources);
                IResource resourcesArray[] = new IResource[resources.size()];
                resources.toArray(resourcesArray);
                initDescriptors(resourcesArray);
            }
        });

        updateGatherThread.firstMatch = 0;
        updateGatherThread.lastMatch = descriptorsSize - 1;
        updateGatherThread.start();
    }

    /**
     * Return an image for a resource descriptor.
     * 
     * @param desc resource descriptor to return image for
     * @return an image for a resource descriptor.
     */
    private Image getImage(ResourceDescriptor desc) {
        IResource r = (IResource) desc.resources.get(0);
        return labelProvider.getImage(r);
    }

    /**
     * Use a binary search to get the last match for the patternString.
     * This method assumes the patternString does not contain any '?' 
     * characters and that it contains only one '*' character at the end
     * of the string.
     */
    private int getLastMatch() {
        int high = descriptorsSize;
        int low = -1;
        boolean match = false;
        ResourceDescriptor desc = new ResourceDescriptor();
        desc.label = patternString.substring(0, patternString.length() - 1);
        while (high - low > 1) {
            int index = (high + low) / 2;
            String label = descriptors[index].label;
            if (match(label)) {
                low = index;
                match = true;
            } else {
                int compare = descriptors[index].compareTo(desc);
                if (compare == -1) {
                    low = index;
                } else {
                    high = index;
                }
            }
        }
        if (match)
            return low;
        return -1;
    }

    /**
     * Gather the resources of the specified type that match the current
     * pattern string.  Gather the resources using the proxy visitor since
     * this is quicker than getting the entire resource.
     * 
     * @param resources resources that match
     */
    private void getMatchingResources(final ArrayList resources) {
        try {
            container.accept(new IResourceProxyVisitor() {
                public boolean visit(IResourceProxy proxy) {
                    // optionally exclude derived resources (bugs 38085 and 81333)
                    if (!getShowDerived() && proxy.isDerived()) {
                        return false;
                    }
                    int type = proxy.getType();
                    if ((typeMask & type) != 0) {
                        if (match(proxy.getName())) {
                            IResource res = proxy.requestResource();
                            if (select(res)) {
                                resources.add(res);
                                return true;
                            }
                            return false;
                        }
                    }
                    if (type == IResource.FILE)
                        return false;
                    return true;
                }
            }, IResource.NONE);
        } catch (CoreException e) {
            // ignore
        }
    }

    private Image getParentImage(IResource resource) {
        IResource parent = resource.getParent();
        return labelProvider.getImage(parent);
    }

    private String getParentLabel(IResource resource) {
        IResource parent = resource.getParent();
        String text;
        if (parent.getType() == IResource.ROOT) {
            // Get readable name for workspace root ("Workspace"), without duplicating language-specific string here.
            text = labelProvider.getText(parent);
        } else {
            text = parent.getFullPath().makeRelative().toString();
        }
        if(text == null)
        	return ""; //$NON-NLS-1$
        return text;
    }

    /**
     * Returns whether derived resources should be shown in the list.
     * The default is <code>false</code>.
     * 
     * @return <code>true</code> to show derived resources, <code>false</code> to hide them
     * @since 3.1
     */
    protected boolean getShowDerived() {
       return showDerived ; 
    }

    /**
     * Sets whether derived resources should be shown in the list.
     * 
     * @param show <code>true</code> to show derived resources, <code>false</code> to hide them
     * @since 3.1
     */
    protected void setShowDerived(boolean show) {
        showDerived  = show;
    }

    /**
     * Creates a ResourceDescriptor for each IResource,
     * sorts them and removes the duplicated ones.
     * 
     * @param resources resources to create resource descriptors for
     */
    private void initDescriptors(final IResource resources[]) {
        BusyIndicator.showWhile(null, new Runnable() {
            public void run() {
                descriptors = new ResourceDescriptor[resources.length];
                for (int i = 0; i < resources.length; i++) {
                    IResource r = resources[i];
                    ResourceDescriptor d = new ResourceDescriptor();
                    //TDB: Should use the label provider and compare performance.
                    d.label = r.getName();
                    d.resources.add(r);
                    descriptors[i] = d;
                }
                Arrays.sort(descriptors);
                descriptorsSize = descriptors.length;

                //Merge the resource descriptor with the same label and type.
                int index = 0;
                if (descriptorsSize < 2)
                    return;
                ResourceDescriptor current = descriptors[index];
                IResource currentResource = (IResource) current.resources
                        .get(0);
                for (int i = 1; i < descriptorsSize; i++) {
                    ResourceDescriptor next = descriptors[i];
                    IResource nextResource = (IResource) next.resources.get(0);
                    if (nextResource.getType() == currentResource.getType()
                            && next.label.equals(current.label)) {
                        current.resources.add(nextResource);
                        // If we are merging resources with the same name, into a single descriptor,
                        // then we must mark the descriptor unsorted so that we will sort the folder
                        // names.  
                        // See https://bugs.eclipse.org/bugs/show_bug.cgi?id=76496
                        current.resourcesSorted = false;
                    } else {
                        if (current.resources.size() > 1) {
                            current.resourcesSorted = false;
                        }
                        descriptors[index + 1] = descriptors[i];
                        index++;
                        current = descriptors[index];
                        currentResource = (IResource) current.resources.get(0);
                    }
                }
                descriptorsSize = index + 1;
            }
        });
    }

    /**
     * Returns true if the label matches the chosen pattern.
     * 
     * @param label label to match with the current pattern
     * @return true if the label matches the chosen pattern. 
     * 	false otherwise.
     */
    private boolean match(String label) {
        if ((patternString == null)
                || (patternString.equals("")) || (patternString.equals("*")))//$NON-NLS-2$//$NON-NLS-1$
            return true;
        return stringMatcher.match(label);
    }

    /**
     * The user has selected a resource and the dialog is closing.
     * Set the selected resource as the dialog result.
     */
    protected void okPressed() {
        TableItem items[] = folderNames.getSelection();
        if (items.length == 1) {
            ArrayList result = new ArrayList();
            result.add(items[0].getData());
            setResult(result);
        }
        super.okPressed();
    }

    /**
     * Use this method to further filter resources.  As resources are gathered,
     * if a resource matches the current pattern string, this method will be called.
     * If this method answers false, the resource will not be included in the list
     * of matches and the resource's children will NOT be considered for matching.
     */
    protected boolean select(IResource resource) {
        return true;
    }

    /**
     * Refreshes the filtered list of resources.
     * Called when the text in the pattern text entry has changed.
     * 
     * @param force if <code>true</code> a refresh is forced, if <code>false</code> a refresh only
     *   occurs if the pattern has changed
     * 
     * @since 3.1
     */
    protected void refresh(boolean force) {
        if (gatherResourcesDynamically) {
            gatherResources(force);
        } else {
            filterResources(force);
        }
    }

    /**
     * A new resource has been selected. Change the contents
     * of the folder names list.
     * 
     * @desc resource descriptor of the selected resource
     */
    private void updateFolders(final ResourceDescriptor desc) {
        BusyIndicator.showWhile(getShell().getDisplay(), new Runnable() {
            public void run() {
                if (!desc.resourcesSorted) {
                    // sort the folder names
                    Collections.sort(desc.resources, new Comparator() {
                        public int compare(Object o1, Object o2) {
                            String s1 = getParentLabel((IResource) o1);
                            String s2 = getParentLabel((IResource) o2);
                            return collator.compare(s1, s2);
                        }
                    });
                    desc.resourcesSorted = true;
                }
                folderNames.removeAll();
                for (int i = 0; i < desc.resources.size(); i++) {
                    TableItem newItem = new TableItem(folderNames, SWT.NONE);
                    IResource r = (IResource) desc.resources.get(i);
                    newItem.setText(getParentLabel(r));
                    newItem.setImage(getParentImage(r));
                    newItem.setData(r);
                }
                folderNames.setSelection(0);
            }
        });
    }

    /**
     * Update the specified item with the new info from the resource 
     * descriptor.
     * Create a new table item if there is no item. 
     * 
     * @param index index of the resource descriptor
     * @param itemPos position of the existing item to update
     * @param itemCount number of items in the resources table widget
     */
    private void updateItem(int index, int itemPos, int itemCount) {
        ResourceDescriptor desc = descriptors[index];
        TableItem item;
        if (itemPos < itemCount) {
            item = resourceNames.getItem(itemPos);
            if (item.getData() != desc) {
                item.setText(desc.label);
                item.setData(desc);
                item.setImage(getImage(desc));
                if (itemPos == 0) {
                    resourceNames.setSelection(0);
                    updateFolders(desc);
                }
            }
        } else {
            item = new TableItem(resourceNames, SWT.NONE);
            item.setText(desc.label);
            item.setData(desc);
            item.setImage(getImage(desc));
            if (itemPos == 0) {
                resourceNames.setSelection(0);
                updateFolders(desc);
            }
        }
        updateOKState(true);
    }
    
    /**
     * Update the enabled state of the OK button.  To be called when
     * the resource list is updated.
     * @param state the new enabled state of the button
     */
    protected void updateOKState(boolean state) {
    	Button okButton = getButton(IDialogConstants.OK_ID);
    	if(okButton != null && !okButton.isDisposed() && state != okEnabled) {
    		okButton.setEnabled(state);
    		okEnabled = state;
    	}
    }
    
	
	/* (non-Javadoc)
     * @see org.eclipse.jface.window.Dialog#getDialogBoundsSettings()
     * 
     * @since 3.2
     */
	protected IDialogSettings getDialogBoundsSettings() {
        IDialogSettings settings = IDEWorkbenchPlugin.getDefault().getDialogSettings();
        IDialogSettings section = settings.getSection(DIALOG_SETTINGS_SECTION);
        if (section == null) {
            section = settings.addNewSection(DIALOG_SETTINGS_SECTION);
        } 
        return section;
	}
}
    
