package org.eclipse.ui.views.navigator;

/*
 * (c) Copyright IBM Corp. 2000, 2001.
 * All Rights Reserved.
 */
import org.eclipse.swt.widgets.*;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.*;
import org.eclipse.swt.layout.*;
import org.eclipse.swt.graphics.Image;
import org.eclipse.core.resources.*;
import org.eclipse.ui.dialogs.*;
import java.util.*;
import org.eclipse.ui.model.*;
import org.eclipse.ui.help.*;

/**
 * Shows a list of resources to the user with a text entry field
 * for a string pattern used to filter the list of resources.
 *
 */
/*package*/ class GotoResourceDialog extends SelectionDialog {
	Text pattern;
	Table resourceNames;
	Table folderNames;

	String patternString;
	IResource selection;
	
	StringMatcher stringMatcher;
	
	UpdateThread updateThread;
	ResourceDescriptor descriptors[];
	int descriptorsSize;

	WorkbenchLabelProvider labelProvider = new WorkbenchLabelProvider();

	static class ResourceDescriptor implements Comparable {
		String label;
		ArrayList resources = new ArrayList(1);
		public int compareTo(Object o) {
			return label.compareToIgnoreCase(((ResourceDescriptor)o).label);
		}
	}
	
	class UpdateThread extends Thread {
		boolean stop = false;
		public void run() {
			Display display = resourceNames.getDisplay();
			final boolean first[] = {true};
			for (int i = 0; i < descriptorsSize;i++) {
				if(i % 50 == 0) {
					try { Thread.sleep(10); } catch(InterruptedException e){}
				}
				if(stop || resourceNames.isDisposed()) return;
				final int index = i;
				if(match(descriptors[index].label)) {
					display.syncExec(new Runnable(){
						public void run() {
							if(stop || resourceNames.isDisposed()) return;
							createItem(index,first[0]);
							first[0]=false;
						}
					});
				}
			}
		}
	};
/**
 * Creates a new instance of the class.
 */
protected GotoResourceDialog(Shell parentShell,IResource resources[]) {
	super(parentShell);
	setTitle(ResourceNavigatorMessages.getString("Goto.title")); //$NON-NLS-1$
	setShellStyle(getShellStyle() | SWT.RESIZE);

	initDescriptors(resources);
}
public boolean close() {
	boolean r = super.close();
	labelProvider.dispose();
	return r;
}
/* (non-Javadoc)
 * Method declared in Window.
 */
protected void configureShell(Shell shell) {
	super.configureShell(shell);
	WorkbenchHelp.setHelp(shell, new Object[] {INavigatorHelpContextIds.GOTO_RESOURCE_DIALOG});
}
public void create() {
	super.create();
	pattern.setFocus();
}
/**
 * Creates the contents of this dialog, initializes the
 * listener and the update thread.
 */
protected Control createDialogArea(Composite parent) {
	
	Composite dialogArea = (Composite)super.createDialogArea(parent);

	Label l = new Label(dialogArea,SWT.NONE);
	l.setText(ResourceNavigatorMessages.getString("Goto.label")); //$NON-NLS-1$
	GridData data = new GridData(GridData.FILL_HORIZONTAL);
	l.setLayoutData(data);
	
	l = new Label(dialogArea,SWT.NONE);
	l.setText(ResourceNavigatorMessages.getString("Goto.pattern")); //$NON-NLS-1$
	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(ResourceNavigatorMessages.getString("Goto.matching")); //$NON-NLS-1$
	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 = 6 * resourceNames.getItemHeight();
	resourceNames.setLayoutData(data);
	
	l = new Label(dialogArea,SWT.NONE);
	l.setText(ResourceNavigatorMessages.getString("Goto.folders")); //$NON-NLS-1$
	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_HORIZONTAL);
	data = new GridData(GridData.FILL_BOTH);
	data.widthHint = 250;
	data.heightHint = 3 * folderNames.getItemHeight();
	folderNames.setLayoutData(data);

	startNewThread();
	
	pattern.addKeyListener(new KeyAdapter(){
		public void keyPressed(KeyEvent e) {
			textChanged();
		}
	});
			
	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();
		}
	});
	
	return dialogArea;
}
/**
 * Create a new table item.
 */
private void createItem(int index, boolean setSelection) {
	TableItem item = new TableItem(resourceNames, SWT.NONE);
	ResourceDescriptor desc = descriptors[index];
	item.setText(desc.label);
	item.setData(desc);
	item.setImage(getImage(desc));
	if (setSelection) {
		resourceNames.setSelection(0);
		updateFolders(desc);
	}
}
/**
 * Return a image for a resource.
 */
private Image getImage(ResourceDescriptor desc) {
	IResource r = (IResource)desc.resources.get(0);
	return labelProvider.getImage(r);
}
/**
 * Returns the IResource selected by the user or null if the
 * cancel was pressed.
 */
public IResource getSelection() {
	return selection;
}
/**
 * Creates a ResourceDescriptor for each IResource
 * sort them and remove the duplicated ones.
 */
private void initDescriptors(IResource resources[]) {
	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((next.label.equals(current.label)) && (nextResource.getType() == currentResource.getType())) {
			current.resources.add(next.resources.get(0));
		} else {
			descriptors[index + 1] = descriptors[i];
			index++;
			current = descriptors[index];
			currentResource = (IResource)current.resources.get(0);
		}
	}
	descriptorsSize = index + 1;
}
/**
 * Return true if the label matchs the choosen pattern.
 */
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.
 */
protected void okPressed() {
	TableItem items[] = folderNames.getSelection();
	if(items.length != 1)
		selection = null;
	else
		selection = (IResource)items[0].getData();
	super.okPressed();
}
/**
 * Start a new update thread.
 */
private void startNewThread() {
	updateThread = new UpdateThread();
	updateThread.start();
}
/**
 * The text in the pattern text entry has changed.
 * Create a new string matcher and start a new
 * update tread.
 */
private void textChanged() {
	String oldPattern = patternString;
	patternString = pattern.getText();
	if(!patternString.endsWith("*"))//$NON-NLS-1$
		patternString = patternString + "*";//$NON-NLS-1$
	if(patternString.equals(oldPattern))
		return;
	updateThread.stop = true;
	stringMatcher = new StringMatcher(patternString,true,false);
	resourceNames.removeAll();
	startNewThread();
}
/**
 * A new resource has been selected. Change the contents
 * of the folder names list.
 */
private void updateFolders(ResourceDescriptor desc) {
	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);
		IResource parent = r.getParent();
		String text;
		if (parent.getType() == IResource.ROOT) {
			// XXX: Get readable name for workspace root ("Workspace"), without duplicating language-specific string here.
			text = labelProvider.getText(parent);
		}
		else {
			text = parent.getFullPath().makeRelative().toString();
		}
		newItem.setText(text);
		newItem.setImage(labelProvider.getImage(r.getParent()));
		newItem.setData(r);
	}
	folderNames.setSelection(0);
}
}
