package org.eclipse.equinox.internal.p2.ui.dialogs;

import java.util.ArrayList;
import java.util.Iterator;
import org.eclipse.core.runtime.*;
import org.eclipse.core.runtime.jobs.*;
import org.eclipse.equinox.internal.p2.ui.ProvUIMessages;
import org.eclipse.equinox.internal.provisional.p2.ui.ProvisioningOperationRunner;
import org.eclipse.equinox.internal.provisional.p2.ui.dialogs.IViewMenuProvider;
import org.eclipse.equinox.internal.provisional.p2.ui.query.QueriedElement;
import org.eclipse.equinox.internal.provisional.p2.ui.query.QueryableMetadataRepositoryManager;
import org.eclipse.equinox.internal.provisional.p2.ui.viewers.DeferredQueryContentListener;
import org.eclipse.equinox.internal.provisional.p2.ui.viewers.DeferredQueryContentProvider;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.dialogs.ControlEnableState;
import org.eclipse.jface.dialogs.PopupDialog;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.viewers.*;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.*;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.*;
import org.eclipse.ui.dialogs.FilteredTree;
import org.eclipse.ui.dialogs.PatternFilter;
import org.eclipse.ui.progress.WorkbenchJob;

/**
 * FilteredTree extension that creates a check box tree,
 * provides a hook for menu creation, and forces synchronous 
 * fetching of the tree when the first 
 * filtering is performed.
 * 
 * @since 3.4
 *
 */
public class DeferredFetchFilteredTree extends FilteredTree {
	private static final String WAIT_STRING = ProvUIMessages.DeferredFetchFilteredTree_RetrievingList;

	ToolBar toolBar;
	MenuManager menuManager;
	ToolItem viewMenuButton;
	Display display;
	PatternFilter patternFilter;
	IViewMenuProvider viewMenuProvider;
	DeferredQueryContentProvider contentProvider;
	boolean useCheckBoxTree = false;
	InputSchedulingRule filterRule;
	String savedFilterText;
	Job loadJob;
	WorkbenchJob filterJob;
	ControlEnableState enableState;
	Object viewerInput;
	ArrayList checkState = new ArrayList();

	class InputSchedulingRule implements ISchedulingRule {
		Object input;

		InputSchedulingRule(Object input) {
			this.input = input;
		}

		/* (non-Javadoc)
		 * @see org.eclipse.core.runtime.jobs.ISchedulingRule#contains(org.eclipse.core.runtime.jobs.ISchedulingRule)
		 */
		public boolean contains(ISchedulingRule rule) {
			return rule == this;
		}

		/* (non-Javadoc)
		 * @see org.eclipse.core.runtime.jobs.ISchedulingRule#isConflicting(org.eclipse.core.runtime.jobs.ISchedulingRule)
		 */
		public boolean isConflicting(ISchedulingRule rule) {
			if (rule instanceof InputSchedulingRule) {
				InputSchedulingRule other = (InputSchedulingRule) rule;
				if (input == null)
					return other.getInput() == null;
				return input.equals(other.getInput());
			}
			return false;
		}

		Object getInput() {
			return input;
		}
	}

	public DeferredFetchFilteredTree(Composite parent, int treeStyle, PatternFilter filter, final IViewMenuProvider viewMenuProvider, Display display, boolean useCheckBoxViewer) {
		super(parent);
		this.display = display;
		this.viewMenuProvider = viewMenuProvider;
		this.patternFilter = filter;
		this.useCheckBoxTree = useCheckBoxViewer;
		init(treeStyle, filter);
	}

	/*
	 * Overridden to see if filter controls were created.
	 * If they were not created, we need to create the view menu
	 * independently.  
	 * (non-Javadoc)
	 * @see org.eclipse.ui.dialogs.FilteredTree#createControl(org.eclipse.swt.widgets.Composite, int)
	 */
	protected void createControl(Composite composite, int treeStyle) {
		super.createControl(composite, treeStyle);
		if (!showFilterControls && viewMenuProvider != null) {
			createViewMenu(composite);
		}
	}

	protected TreeViewer doCreateTreeViewer(Composite composite, int style) {
		if (useCheckBoxTree) {
			final ContainerCheckedTreeViewer v = new ContainerCheckedTreeViewer(composite, style);
			v.addCheckStateListener(new ICheckStateListener() {
				public void checkStateChanged(CheckStateChangedEvent event) {
					// We use an additive check state cache so we need to remove
					// previously checked items if the user unchecked them.
					if (!event.getChecked() && checkState != null) {
						Iterator iter = checkState.iterator();
						ArrayList toRemove = new ArrayList(1);
						while (iter.hasNext()) {
							Object element = iter.next();
							if (v.getComparer().equals(element, event.getElement())) {
								toRemove.add(element);
								// Do not break out of the loop.  We may have duplicate equal
								// elements in the cache.  Since the cache is additive, we want
								// to be sure we've gotten everything.
							}
						}
						checkState.removeAll(toRemove);
					}

				}
			});
			return v;
		}
		return super.doCreateTreeViewer(composite, style);
	}

	protected Composite createFilterControls(Composite filterParent) {
		super.createFilterControls(filterParent);
		Object layout = filterParent.getLayout();
		if (layout instanceof GridLayout) {
			((GridLayout) layout).numColumns++;
		}
		if (viewMenuProvider != null)
			createViewMenu(filterParent);
		filterParent.addDisposeListener(new DisposeListener() {
			public void widgetDisposed(DisposeEvent e) {
				cancelLoadJob();
			}
		});
		return filterParent;
	}

	private void createViewMenu(Composite filterParent) {
		toolBar = new ToolBar(filterParent, SWT.FLAT);
		viewMenuButton = new ToolItem(toolBar, SWT.PUSH, 0);

		viewMenuButton.setImage(JFaceResources.getImage(PopupDialog.POPUP_IMG_MENU));
		viewMenuButton.setToolTipText(ProvUIMessages.AvailableIUGroup_ViewByToolTipText);
		viewMenuButton.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				showViewMenu();
			}
		});

		// See https://bugs.eclipse.org/bugs/show_bug.cgi?id=177183
		toolBar.addMouseListener(new MouseAdapter() {
			public void mouseDown(MouseEvent e) {
				showViewMenu();
			}
		});

	}

	void showViewMenu() {
		if (menuManager == null) {
			menuManager = new MenuManager();
			viewMenuProvider.fillViewMenu(menuManager);
		}
		Menu menu = menuManager.createContextMenu(getShell());
		Rectangle bounds = toolBar.getBounds();
		Point topLeft = new Point(bounds.x, bounds.y + bounds.height);
		topLeft = toolBar.getParent().toDisplay(topLeft);
		menu.setLocation(topLeft.x, topLeft.y);
		menu.setVisible(true);
	}

	public void contentProviderSet(final DeferredQueryContentProvider deferredProvider) {
		this.contentProvider = deferredProvider;
		deferredProvider.addListener(new DeferredQueryContentListener() {
			public void inputChanged(Viewer v, Object oldInput, Object newInput) {
				if (newInput == null)
					return;
				// Store the input because it's not reset in the viewer until
				// after this listener is run.
				viewerInput = newInput;

				// Reset the state for remembering check marks
				checkState = new ArrayList();
				// Cancel the load and filter jobs and null out the scheduling rule
				// so that a new one will be created on the new input when needed.
				filterRule = null;
				cancelLoadJob();
				cancelAndResetFilterJob();
				contentProvider.setSynchronous(false);

				if (showFilterControls && filterText != null && !filterText.isDisposed()) {
					// We cancelled the load and if it was in progress the filter
					// would have been disabled.  
					restoreAfterLoading(getInitialText());
				}
			}

		});
	}

	/*
	 * Overridden to hook a listener on the job and set the deferred content provider
	 * to synchronous mode before a filter is done.
	 * @see org.eclipse.ui.dialogs.FilteredTree#doCreateRefreshJob()
	 */
	protected WorkbenchJob doCreateRefreshJob() {
		// See bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=229735
		// Ideally we would not have to copy the filtering job, but this
		// gives us the most precise control over how and when to preserve
		// the check mark state.  We have modified the superclass job so
		// that everything is expanded rather than recursively expanding
		// the tree and checking for the stop time.  This simplifies the
		// restoration of the correct checkmarks.
		filterJob = new WorkbenchJob("Refresh Filter") {//$NON-NLS-1$
			public IStatus runInUIThread(IProgressMonitor monitor) {
				if (treeViewer.getControl().isDisposed()) {
					return Status.CANCEL_STATUS;
				}

				String text = getFilterString();
				if (text == null) {
					return Status.OK_STATUS;
				}

				if (monitor.isCanceled())
					return Status.CANCEL_STATUS;
				boolean initial = initialText != null && initialText.equals(text);
				if (initial) {
					patternFilter.setPattern(null);
				} else if (text != null) {
					patternFilter.setPattern(text);
				}

				Control redrawFalseControl = treeComposite != null ? treeComposite : treeViewer.getControl();
				try {
					// don't want the user to see updates that will be made to
					// the tree
					// we are setting redraw(false) on the composite to avoid
					// dancing scrollbar
					redrawFalseControl.setRedraw(false);
					treeViewer.getTree().setCursor(display.getSystemCursor(SWT.CURSOR_WAIT));
					rememberLeafCheckState();
					treeViewer.refresh(true);
					// The superclass did a recursive expand so it could be more responsive to subsequent
					// typing.  We are expanding all so that we know everything is realized when we go to
					// restore the check state afterward.
					treeViewer.expandAll();
					if (text.length() > 0 && !initial) {
						// enabled toolbar - there is text to clear
						// and the list is currently being filtered
						updateToolbar(true);
					} else {
						// disabled toolbar - there is no text to clear
						// and the list is currently not filtered
						updateToolbar(false);
					}
				} finally {
					// done updating the tree - set redraw back to true
					TreeItem[] items = getViewer().getTree().getItems();
					if (items.length > 0 && getViewer().getTree().getSelectionCount() == 0) {
						treeViewer.getTree().setTopItem(items[0]);
					}
					restoreLeafCheckState();
					redrawFalseControl.setRedraw(true);
					treeViewer.getTree().setCursor(null);
				}
				return Status.OK_STATUS;
			}
		};

		filterJob.addJobChangeListener(new JobChangeAdapter() {
			public void aboutToRun(final IJobChangeEvent event) {
				final boolean[] shouldLoad = new boolean[1];
				shouldLoad[0] = false;
				display.syncExec(new Runnable() {
					public void run() {
						if (filterText != null && !filterText.isDisposed()) {
							String text = getFilterString();
							// If we are about to filter and there is
							// actually filtering to do, force a load
							// of the input and set the content
							// provider to synchronous mode.  We want the
							// load job to complete before continuing with filtering.
							if (text == null || (initialText != null && initialText.equals(text)))
								return;
							if (!contentProvider.getSynchronous() && loadJob == null) {
								if (filterText != null && !filterText.isDisposed()) {
									disableWhileLoading();
									shouldLoad[0] = true;
								}
							}
						}
					}
				});
				if (shouldLoad[0]) {
					event.getJob().sleep();
					scheduleLoadJob();
				}

			}

			public void done(IJobChangeEvent event) {
				// To be safe, we always reset the scheduling
				// rule because the input may have changed since the last run.
				event.getJob().setRule(getFilterJobSchedulingRule());
			}
		});
		filterJob.setRule(getFilterJobSchedulingRule());
		return filterJob;
	}

	void disableWhileLoading() {
		// We already disabled.
		if (enableState != null)
			return;
		// TODO Knowledge of our client's parent structure is cheating
		// but for now our only usage is in one particular widget tree and
		// we want to disable at the right place.
		if (parent != null && !parent.isDisposed()) {
			enableState = ControlEnableState.disable(parent.getParent());
		}
		if (filterText != null && !filterText.isDisposed()) {
			filterText.setCursor(display.getSystemCursor(SWT.CURSOR_WAIT));
			getViewer().getTree().setCursor(display.getSystemCursor(SWT.CURSOR_WAIT));
			savedFilterText = filterText.getText();
			filterText.setText(WAIT_STRING);
		}

	}

	void restoreAfterLoading(String filterTextToRestore) {
		// If the filter text was previously disabled, reset the text to
		// the previous filter text.
		if (filterText != null && !filterText.isDisposed() && !filterText.isEnabled()) {
			filterText.setText(filterTextToRestore);
			filterText.setCursor(null);
			getViewer().getTree().setCursor(null);
			filterText.setSelection(filterTextToRestore.length(), filterTextToRestore.length());
		}
		// Now enable all of the controls
		if (enableState != null && parent != null && !parent.isDisposed()) {
			enableState.restore();
			enableState = null;
		}
		// Now set the focus back to the filter text
		if (filterText != null && !filterText.isDisposed())
			filterText.setFocus();
	}

	InputSchedulingRule getFilterJobSchedulingRule() {
		if (filterRule == null) {
			filterRule = new InputSchedulingRule(viewerInput);
		}
		return filterRule;
	}

	void scheduleLoadJob() {
		if (loadJob != null)
			return;
		loadJob = new Job(WAIT_STRING) {
			protected IStatus run(IProgressMonitor monitor) {
				if (this.getRule() instanceof InputSchedulingRule) {
					Object input = ((InputSchedulingRule) this.getRule()).getInput();
					if (input instanceof QueriedElement)
						if (((QueriedElement) input).getQueryable() instanceof QueryableMetadataRepositoryManager) {
							QueryableMetadataRepositoryManager q = (QueryableMetadataRepositoryManager) ((QueriedElement) input).getQueryable();
							q.loadAll(monitor);
							if (monitor.isCanceled())
								return Status.CANCEL_STATUS;
						}
				}
				return Status.OK_STATUS;
			}
		};
		loadJob.addJobChangeListener(new JobChangeAdapter() {
			public void done(IJobChangeEvent event) {
				if (event.getResult().isOK()) {
					contentProvider.setSynchronous(true);
					display.asyncExec(new Runnable() {
						public void run() {
							// We have just loaded all content.  Trigger a viewer expand.
							// This really only need be done before filtering, but it can
							// be slow the very first time, so we may as well do it while
							// the user is already waiting rather than after they expect
							// things to be responsive.
							if (getViewer() != null && !getViewer().getTree().isDisposed()) {
								getViewer().expandAll();
							}
							restoreAfterLoading(savedFilterText);
						}
					});
					if (filterJob != null)
						filterJob.wakeUp();
				}
				loadJob = null;
			}
		});
		loadJob.setSystem(true);
		loadJob.setUser(false);
		loadJob.setRule(getFilterJobSchedulingRule());
		// Telling the operation runner about it ensures that listeners know we are running
		// a provisioning-related job.
		ProvisioningOperationRunner.manageJob(loadJob);
		loadJob.schedule();
	}

	void cancelLoadJob() {
		if (loadJob != null) {
			loadJob.cancel();
			loadJob = null;
		}
	}

	void cancelAndResetFilterJob() {
		if (filterJob != null) {
			filterJob.cancel();
			// callers have likely reset the filtering rule.
			// We can't reset it here because we don't know that
			// the job actually stopped, so we do it in the
			// done() handler.
		}
	}

	protected void textChanged() {
		// Don't refilter if we are merely resetting the filter back
		// to what it was before loading repositories
		if (filterText.getText().trim().equals(WAIT_STRING))
			return;
		super.textChanged();
	}

	void rememberLeafCheckState() {
		if (!useCheckBoxTree)
			return;
		ContainerCheckedTreeViewer v = (ContainerCheckedTreeViewer) getViewer();
		Object[] checked = v.getCheckedElements();
		if (checkState == null)
			checkState = new ArrayList(checked.length);
		for (int i = 0; i < checked.length; i++)
			if (!v.getGrayed(checked[i]))
				checkState.add(checked[i]);
	}

	void restoreLeafCheckState() {
		if (!useCheckBoxTree)
			return;
		ContainerCheckedTreeViewer v = (ContainerCheckedTreeViewer) getViewer();
		if (v == null || v.getTree().isDisposed())
			return;
		if (checkState == null)
			return;

		v.setCheckedElements(new Object[0]);
		v.setGrayedElements(new Object[0]);
		// Now we are only going to set the check state of the leaf nodes
		// and rely on our container checked code to update the parents properly.
		Iterator iter = checkState.iterator();
		Object element = null;
		while (iter.hasNext()) {
			element = iter.next();
			if (!v.isExpandable(element)) {
				// setChecked does an internal expand
				v.setChecked(element, true);
			}
		}
		// We are only firing one event, knowing that this is enough for our listeners.
		if (element != null)
			v.fireCheckStateChanged(element, true);
	}
}