/*******************************************************************************
 * Copyright (c) 2000, 2018 IBM Corporation and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.jface.internal.text.link.contentassist;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.eclipse.swt.SWT;
import org.eclipse.swt.SWTError;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.custom.VerifyKeyListener;
import org.eclipse.swt.events.ControlEvent;
import org.eclipse.swt.events.ControlListener;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.events.FocusListener;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseListener;
import org.eclipse.swt.events.VerifyEvent;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Widget;

import org.eclipse.core.runtime.Assert;

import org.eclipse.jface.util.OpenStrategy;

import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.DefaultInformationControl;
import org.eclipse.jface.text.IEventConsumer;
import org.eclipse.jface.text.IInformationControlCreator;
import org.eclipse.jface.text.ITextViewer;
import org.eclipse.jface.text.ITextViewerExtension;
import org.eclipse.jface.text.IViewportListener;
import org.eclipse.jface.text.IWidgetTokenKeeper;
import org.eclipse.jface.text.IWidgetTokenKeeperExtension;
import org.eclipse.jface.text.IWidgetTokenOwner;
import org.eclipse.jface.text.IWidgetTokenOwnerExtension;
import org.eclipse.jface.text.TextUtilities;
import org.eclipse.jface.text.contentassist.CompletionProposal;
import org.eclipse.jface.text.contentassist.ICompletionProposal;
import org.eclipse.jface.text.contentassist.ICompletionProposalExtension6;
import org.eclipse.jface.text.contentassist.IContentAssistProcessor;
import org.eclipse.jface.text.contentassist.IContentAssistant;
import org.eclipse.jface.text.contentassist.IContentAssistantExtension;
import org.eclipse.jface.text.contentassist.IContextInformation;
import org.eclipse.jface.text.contentassist.IContextInformationPresenter;
import org.eclipse.jface.text.contentassist.IContextInformationValidator;


/**
 * A custom implementation of the <code>IContentAssistant</code> interface.
 * This implementation is used by the linked mode UI. This is internal and subject
 * to change without notice.
 */
public class ContentAssistant2 implements IContentAssistant, IContentAssistantExtension, IWidgetTokenKeeper, IWidgetTokenKeeperExtension {

	/**
	 * A generic closer class used to monitor various
	 * interface events in order to determine whether
	 * content-assist should be terminated and all
	 * associated windows closed.
	 */
	class Closer implements ControlListener, MouseListener, FocusListener, DisposeListener, IViewportListener {

		/** The shell on which we add listeners. */
		private Shell fShell;
		private long fViewportListenerStartTime;

		/**
		 * Installs this closer on it's viewer's text widget.
		 */
		protected void install() {
			Control w= fViewer.getTextWidget();
			if (Helper2.okToUse(w)) {

				Shell shell= w.getShell();
				fShell= shell;
				shell.addControlListener(this);

				w.addMouseListener(this);
				w.addFocusListener(this);

				/*
				 * 1GGYYWK: ITPJUI:ALL - Dismissing editor with code assist up causes lots of Internal Errors
				 */
				w.addDisposeListener(this);
			}

			fViewer.addViewportListener(this);
			fViewportListenerStartTime= System.currentTimeMillis() + 500;
		}

		/**
		 * Uninstalls this closer from the viewer's text widget.
		 */
		protected void uninstall() {
			Shell shell= fShell;
			fShell= null;
			if (Helper2.okToUse(shell))
				shell.removeControlListener(this);

			Control w= fViewer.getTextWidget();
			if (Helper2.okToUse(w)) {

				w.removeMouseListener(this);
				w.removeFocusListener(this);

				/*
				 * 1GGYYWK: ITPJUI:ALL - Dismissing editor with code assist up causes lots of Internal Errors
				 */
				w.removeDisposeListener(this);
			}

			fViewer.removeViewportListener(this);
		}

		@Override
		public void controlResized(ControlEvent e) {
			hide();
		}

		@Override
		public void controlMoved(ControlEvent e) {
			hide();
		}

		@Override
		public void mouseDown(MouseEvent e) {
			hide();
		}

		@Override
		public void mouseUp(MouseEvent e) {
		}

		@Override
		public void mouseDoubleClick(MouseEvent e) {
			hide();
		}

		@Override
		public void focusGained(FocusEvent e) {
		}

		@Override
		public void focusLost(FocusEvent e) {
			if (fViewer != null) {
				Control control= fViewer.getTextWidget();
				if (control != null) {
					Display d= control.getDisplay();
					if (d != null) {
						d.asyncExec(() -> {
							if (!hasFocus())
								hide();
						});
					}
				}
			}
		}

		/*
		 * @seeDisposeListener#widgetDisposed(DisposeEvent)
		 */
		@Override
		public void widgetDisposed(DisposeEvent e) {
			/*
			 * 1GGYYWK: ITPJUI:ALL - Dismissing editor with code assist up causes lots of Internal Errors
			 */
			hide();
		}

		@Override
		public void viewportChanged(int topIndex) {
			if (System.currentTimeMillis() > fViewportListenerStartTime)
				hide();
		}
	}

	/**
	 * An implementation of <code>IContentAssistListener</code>, this class is
	 * used to monitor key events in support of automatic activation
	 * of the content assistant. If enabled, the implementation utilizes a
	 * thread to watch for input characters matching the activation
	 * characters specified by the content assist processor, and if
	 * detected, will wait the indicated delay interval before
	 * activating the content assistant.
	 */
	class AutoAssistListener implements VerifyKeyListener, Runnable {

		private Thread fThread;
		private boolean fIsReset= false;
		private Object fMutex= new Object();
		private int fShowStyle;

		private final static int SHOW_PROPOSALS= 1;
		private final static int SHOW_CONTEXT_INFO= 2;

		protected AutoAssistListener() {
		}

		protected void start(int showStyle) {
			fShowStyle= showStyle;
			fThread= new Thread(this, ContentAssistMessages.getString("ContentAssistant.assist_delay_timer_name")); //$NON-NLS-1$
			fThread.start();
		}

		@Override
		public void run() {
			try {
				while (true) {
					synchronized (fMutex) {
						if (fAutoActivationDelay != 0)
							fMutex.wait(fAutoActivationDelay);
						if (fIsReset) {
							fIsReset= false;
							continue;
						}
					}
					showAssist(fShowStyle);
					break;
				}
			} catch (InterruptedException e) {
			}
			fThread= null;
		}

		protected void reset(int showStyle) {
			synchronized (fMutex) {
				fShowStyle= showStyle;
				fIsReset= true;
				fMutex.notifyAll();
			}
		}

		protected void stop() {
			Thread threadToStop= fThread;
			if (threadToStop != null)
				threadToStop.interrupt();
		}

		private boolean contains(char[] characters, char character) {
			if (characters != null) {
				for (char c : characters) {
					if (character == c) {
						return true;
					}
				}
			}
			return false;
		}

		@Override
		public void verifyKey(VerifyEvent e) {
			// Only act on typed characters and ignore modifier-only events
			if (e.character == 0 && (e.keyCode & SWT.KEYCODE_BIT) == 0)
				return;

			if (e.character != 0 && (e.stateMask == SWT.ALT))
				return;

			int showStyle;
			int pos= fViewer.getSelectedRange().x;
			char[] activation= getCompletionProposalAutoActivationCharacters(fViewer, pos);

			if (contains(activation, e.character) && !fProposalPopup.isActive())
				showStyle= SHOW_PROPOSALS;
			else {
				activation= getContextInformationAutoActivationCharacters(fViewer, pos);
				if (contains(activation, e.character) && !fContextInfoPopup.isActive())
					showStyle= SHOW_CONTEXT_INFO;
				else {
					if (fThread != null && fThread.isAlive())
						stop();
					return;
				}
			}

			if (fThread != null && fThread.isAlive())
				reset(showStyle);
			else
				start(showStyle);
		}

		protected void showAssist(final int showStyle) {
			Control control= fViewer.getTextWidget();
			Display d= control.getDisplay();
			if (d != null) {
				try {
					d.syncExec(() -> {
						if (showStyle == SHOW_PROPOSALS)
							fProposalPopup.showProposals(true);
						else if (showStyle == SHOW_CONTEXT_INFO)
							fContextInfoPopup.showContextProposals(true);
					});
				} catch (SWTError e) {
				}
			}
		}
	}

	/**
	 * The layout manager layouts the various
	 * windows associated with the content assistant based on the
	 * settings of the content assistant.
	 */
	class LayoutManager implements Listener {

		// Presentation types.
		/** proposal selector */
		public final static int LAYOUT_PROPOSAL_SELECTOR= 0;
		/** context selector */
		public final static int LAYOUT_CONTEXT_SELECTOR= 1;
		/** context info */
		public final static int LAYOUT_CONTEXT_INFO_POPUP= 2;

		int fContextType= LAYOUT_CONTEXT_SELECTOR;
		Shell[] fShells= new Shell[3];
		Object[] fPopups= new Object[3];

		protected void add(Object popup, Shell shell, int type, int offset) {
			Assert.isNotNull(popup);
			Assert.isTrue(shell != null && !shell.isDisposed());
			checkType(type);

			if (fShells[type] != shell) {
				if (fShells[type] != null)
					fShells[type].removeListener(SWT.Dispose, this);
				shell.addListener(SWT.Dispose, this);
				fShells[type]= shell;
			}

			fPopups[type]= popup;
			if (type == LAYOUT_CONTEXT_SELECTOR || type == LAYOUT_CONTEXT_INFO_POPUP)
				fContextType= type;

			layout(type, offset);
			adjustListeners(type);
		}

		protected void checkType(int type) {
			Assert.isTrue(type == LAYOUT_PROPOSAL_SELECTOR ||
				type == LAYOUT_CONTEXT_SELECTOR || type == LAYOUT_CONTEXT_INFO_POPUP);
		}

		@Override
		public void handleEvent(Event event) {
			Widget source= event.widget;
			source.removeListener(SWT.Dispose, this);

			int type= getShellType(source);
			checkType(type);
			fShells[type]= null;

			switch (type) {
				case LAYOUT_PROPOSAL_SELECTOR:
					if (fContextType == LAYOUT_CONTEXT_SELECTOR &&
							Helper2.okToUse(fShells[LAYOUT_CONTEXT_SELECTOR])) {
						// Restore event notification to the tip popup.
						addContentAssistListener((IContentAssistListener2) fPopups[LAYOUT_CONTEXT_SELECTOR], CONTEXT_SELECTOR);
					}
					break;

				case LAYOUT_CONTEXT_SELECTOR:
					if (Helper2.okToUse(fShells[LAYOUT_PROPOSAL_SELECTOR])) {
						if (fProposalPopupOrientation == PROPOSAL_STACKED)
							layout(LAYOUT_PROPOSAL_SELECTOR, getSelectionOffset());
						// Restore event notification to the proposal popup.
						addContentAssistListener((IContentAssistListener2) fPopups[LAYOUT_PROPOSAL_SELECTOR], PROPOSAL_SELECTOR);
					}
					fContextType= LAYOUT_CONTEXT_INFO_POPUP;
					break;

				case LAYOUT_CONTEXT_INFO_POPUP:
					if (Helper2.okToUse(fShells[LAYOUT_PROPOSAL_SELECTOR])) {
						if (fContextInfoPopupOrientation == CONTEXT_INFO_BELOW)
							layout(LAYOUT_PROPOSAL_SELECTOR, getSelectionOffset());
					}
					fContextType= LAYOUT_CONTEXT_SELECTOR;
					break;
			}
		}

		protected int getShellType(Widget shell) {
			for (int i=0; i<fShells.length; i++) {
				if (fShells[i] == shell)
					return i;
			}
			return -1;
		}

		protected void layout(int type, int offset) {
			switch (type) {
				case LAYOUT_PROPOSAL_SELECTOR:
					layoutProposalSelector(offset);
					break;
				case LAYOUT_CONTEXT_SELECTOR:
					layoutContextSelector(offset);
					break;
				case LAYOUT_CONTEXT_INFO_POPUP:
					layoutContextInfoPopup(offset);
					break;
			}
		}

		protected void layoutProposalSelector(int offset) {
			if (fContextType == LAYOUT_CONTEXT_INFO_POPUP &&
					fContextInfoPopupOrientation == CONTEXT_INFO_BELOW &&
					Helper2.okToUse(fShells[LAYOUT_CONTEXT_INFO_POPUP])) {
				// Stack proposal selector beneath the tip box.
				Shell shell= fShells[LAYOUT_PROPOSAL_SELECTOR];
				Shell parent= fShells[LAYOUT_CONTEXT_INFO_POPUP];
				shell.setLocation(getStackedLocation(shell, parent));
			} else if (fContextType != LAYOUT_CONTEXT_SELECTOR ||
						!Helper2.okToUse(fShells[LAYOUT_CONTEXT_SELECTOR])) {
				// There are no other presentations to be concerned with,
				// so place the proposal selector beneath the cursor line.
				Shell shell= fShells[LAYOUT_PROPOSAL_SELECTOR];
				shell.setLocation(getBelowLocation(shell, offset));
			} else {
				switch (fProposalPopupOrientation) {
					case PROPOSAL_REMOVE: {
						// Remove the tip selector and place the
						// proposal selector beneath the cursor line.
						fShells[LAYOUT_CONTEXT_SELECTOR].dispose();
						Shell shell= fShells[LAYOUT_PROPOSAL_SELECTOR];
						shell.setLocation(getBelowLocation(shell, offset));
						break;
					}
					case PROPOSAL_OVERLAY: {
						// Overlay the tip selector with the proposal selector.
						Shell shell= fShells[LAYOUT_PROPOSAL_SELECTOR];
						shell.setLocation(getBelowLocation(shell, offset));
						break;
					}
					case PROPOSAL_STACKED: {
						// Stack the proposal selector beneath the tip selector.
						Shell shell= fShells[LAYOUT_PROPOSAL_SELECTOR];
						Shell parent= fShells[LAYOUT_CONTEXT_SELECTOR];
						shell.setLocation(getStackedLocation(shell, parent));
						break;
					}
				}
			}
		}

		protected void layoutContextSelector(int offset) {
			// Always place the context selector beneath the cursor line.
			Shell shell= fShells[LAYOUT_CONTEXT_SELECTOR];
			shell.setLocation(getBelowLocation(shell, offset));

			if (Helper2.okToUse(fShells[LAYOUT_PROPOSAL_SELECTOR])) {
				switch (fProposalPopupOrientation) {
					case PROPOSAL_REMOVE:
						// Remove the proposal selector.
						fShells[LAYOUT_PROPOSAL_SELECTOR].dispose();
						break;

					case PROPOSAL_OVERLAY:
						// The proposal selector has been overlaid by the tip selector.
						break;

					case PROPOSAL_STACKED: {
						// Stack the proposal selector beneath the tip selector.
						shell= fShells[LAYOUT_PROPOSAL_SELECTOR];
						Shell parent= fShells[LAYOUT_CONTEXT_SELECTOR];
						shell.setLocation(getStackedLocation(shell, parent));
						break;
					}
				}
			}
		}

		protected void layoutContextInfoPopup(int offset) {
			switch (fContextInfoPopupOrientation) {
				case CONTEXT_INFO_ABOVE: {
					// Place the popup above the cursor line.
					Shell shell= fShells[LAYOUT_CONTEXT_INFO_POPUP];
					shell.setLocation(getAboveLocation(shell, offset));
					break;
				}
				case CONTEXT_INFO_BELOW: {
					// Place the popup beneath the cursor line.
					Shell parent= fShells[LAYOUT_CONTEXT_INFO_POPUP];
					parent.setLocation(getBelowLocation(parent, offset));
					if (Helper2.okToUse(fShells[LAYOUT_PROPOSAL_SELECTOR])) {
						// Stack the proposal selector beneath the context info popup.
						Shell shell= fShells[LAYOUT_PROPOSAL_SELECTOR];
						shell.setLocation(getStackedLocation(shell, parent));
					}
					break;
				}
			}
		}

		protected void shiftHorizontalLocation(Point location, Rectangle shellBounds, Rectangle displayBounds) {
			if (location.x + shellBounds.width > displayBounds.width)
				location.x= displayBounds.width - shellBounds.width;

			if (location.x < displayBounds.x)
				location.x= displayBounds.x;
		}

		protected void shiftVerticalLocation(Point location, Rectangle shellBounds, Rectangle displayBounds) {
			if (location.y + shellBounds.height > displayBounds.height)
				location.y= displayBounds.height - shellBounds.height;

			if (location.y < displayBounds.y)
				location.y= displayBounds.y;
		}

		protected Point getAboveLocation(Shell shell, int offset) {
			StyledText text= fViewer.getTextWidget();
			Point location= text.getLocationAtOffset(offset);
			location= text.toDisplay(location);

			Rectangle shellBounds= shell.getBounds();
			Rectangle displayBounds= shell.getDisplay().getClientArea();

			location.y=location.y - shellBounds.height;

			shiftHorizontalLocation(location, shellBounds, displayBounds);
			shiftVerticalLocation(location, shellBounds, displayBounds);

			return location;
		}

		protected Point getBelowLocation(Shell shell, int offset) {
			StyledText text= fViewer.getTextWidget();
			Point location= text.getLocationAtOffset(offset);
			if (location.x < 0) location.x= 0;
			if (location.y < 0) location.y= 0;
			location= text.toDisplay(location);

			Rectangle shellBounds= shell.getBounds();
			Rectangle displayBounds= shell.getDisplay().getClientArea();

			location.y= location.y + text.getLineHeight(offset);
			shiftHorizontalLocation(location, shellBounds, displayBounds);
			shiftVerticalLocation(location, shellBounds, displayBounds);

			return location;
		}

		protected Point getStackedLocation(Shell shell, Shell parent) {
			Point p= parent.getLocation();
			Point size= parent.getSize();
			p.x += size.x / 4;
			p.y += size.y;

			p= parent.toDisplay(p);

			Rectangle shellBounds= shell.getBounds();
			Rectangle displayBounds= shell.getDisplay().getClientArea();
			shiftHorizontalLocation(p, shellBounds, displayBounds);
			shiftVerticalLocation(p, shellBounds, displayBounds);

			return p;
		}

		protected void adjustListeners(int type) {
			switch (type) {
				case LAYOUT_PROPOSAL_SELECTOR:
					if (fContextType == LAYOUT_CONTEXT_SELECTOR &&
							Helper2.okToUse(fShells[LAYOUT_CONTEXT_SELECTOR]))
						// Disable event notification to the tip selector.
						removeContentAssistListener((IContentAssistListener2) fPopups[LAYOUT_CONTEXT_SELECTOR], CONTEXT_SELECTOR);
					break;
				case LAYOUT_CONTEXT_SELECTOR:
					if (Helper2.okToUse(fShells[LAYOUT_PROPOSAL_SELECTOR]))
						// Disable event notification to the proposal selector.
						removeContentAssistListener((IContentAssistListener2) fPopups[LAYOUT_PROPOSAL_SELECTOR], PROPOSAL_SELECTOR);
					break;
				case LAYOUT_CONTEXT_INFO_POPUP:
					break;
			}
		}
	}

	/**
	 * Internal key listener and event consumer.
	 */
	class InternalListener implements VerifyKeyListener, IEventConsumer {

		/**
		 * Verifies key events by notifying the registered listeners.
		 * Each listener is allowed to indicate that the event has been
		 * handled and should not be further processed.
		 *
		 * @param e the verify event
		 * @see VerifyKeyListener#verifyKey(org.eclipse.swt.events.VerifyEvent)
		 */
		@Override
		public void verifyKey(VerifyEvent e) {
			IContentAssistListener2[] listeners= fListeners.clone();
			for (int i= 0; i < listeners.length; i++) {
				if (listeners[i] != null) {
					if (!listeners[i].verifyKey(e) || !e.doit)
						return;
				}
			}
		}

		/*
		 * @see IEventConsumer#processEvent
		 */
		@Override
		public void processEvent(VerifyEvent event) {

			installKeyListener();

			IContentAssistListener2[] listeners= fListeners.clone();
			for (IContentAssistListener2 listener : listeners) {
				if (listener != null) {
					listener.processEvent(event);
					if (!event.doit)
						return;
				}
			}
		}
	}


	// Content-Assist Listener types
	final static int CONTEXT_SELECTOR= 0;
	final static int PROPOSAL_SELECTOR= 1;
	final static int CONTEXT_INFO_POPUP= 2;

	/**
	 * The popup priority: &gt; info pop-ups, &lt; standard content assist.
	 * Default value: <code>10</code>.
	 *
	 * @since 3.0
	 */
	public static final int WIDGET_PRIORITY= 10;


	private static final int DEFAULT_AUTO_ACTIVATION_DELAY= 500;

	private IInformationControlCreator fInformationControlCreator;
	private int fAutoActivationDelay= DEFAULT_AUTO_ACTIVATION_DELAY;
	private boolean fIsAutoActivated= false;
	private boolean fIsAutoInserting= false;
	private int fProposalPopupOrientation= PROPOSAL_OVERLAY;
	private int fContextInfoPopupOrientation= CONTEXT_INFO_ABOVE;
	private Map<String, IContentAssistProcessor> fProcessors;
	private String fPartitioning;

	private Color fContextInfoPopupBackground;
	private Color fContextInfoPopupForeground;
	private Color fContextSelectorBackground;
	private Color fContextSelectorForeground;

	private ITextViewer fViewer;
	private String fLastErrorMessage;

	private Closer fCloser;
	private LayoutManager fLayoutManager;
	private AutoAssistListener fAutoAssistListener;
	private InternalListener fInternalListener;
	private CompletionProposalPopup2 fProposalPopup;
	private ContextInformationPopup2 fContextInfoPopup;

	private boolean fKeyListenerHooked= false;
	private IContentAssistListener2[] fListeners= new IContentAssistListener2[4];
	private int fCompletionPosition;
	private String[] fProposalStrings;
	private ICompletionProposal[] fProposals;
	private final List<IProposalListener> fProposalListeners= new ArrayList<>();

	/**
	 * Tells whether colored label support is enabled.
	 * @since 3.4
	 */
	private boolean fIsColoredLabelsSupportEnabled= false;


	/**
	 * Creates a new content assistant. The content assistant is not automatically activated,
	 * overlays the completion proposals with context information list if necessary, and
	 * shows the context information above the location at which it was activated. If auto
	 * activation will be enabled, without further configuration steps, this content assistant
	 * is activated after a 500 ms delay. It uses the default partitioning.
	 */
	public ContentAssistant2() {
		setContextInformationPopupOrientation(CONTEXT_INFO_ABOVE);
		setInformationControlCreator(getInformationControlCreator());

//		JavaTextTools textTools= JavaPlugin.getDefault().getJavaTextTools();
//		IColorManager manager= textTools.getColorManager();
//
//		IPreferenceStore store=  JavaPlugin.getDefault().getPreferenceStore();
//
//		Color c= getColor(store, PreferenceConstants.CODEASSIST_PROPOSALS_FOREGROUND, manager);
//		setProposalSelectorForeground(c);
//
//		c= getColor(store, PreferenceConstants.CODEASSIST_PROPOSALS_BACKGROUND, manager);
//		setProposalSelectorBackground(c);
	}

	/**
	 * Creates an <code>IInformationControlCreator</code> to be used to display context information.
	 *
	 * @return an <code>IInformationControlCreator</code> to be used to display context information
	 */
	private IInformationControlCreator getInformationControlCreator() {
		return parent -> new DefaultInformationControl(parent, false);
	}

	/**
	 * Sets the document partitioning this content assistant is using.
	 *
	 * @param partitioning the document partitioning for this content assistant
	 */
	public void setDocumentPartitioning(String partitioning) {
		Assert.isNotNull(partitioning);
		fPartitioning= partitioning;
	}

	@Override
	public String getDocumentPartitioning() {
		return fPartitioning;
	}

	/**
	 * Registers a given content assist processor for a particular content type.
	 * If there is already a processor registered for this type, the new processor
	 * is registered instead of the old one.
	 *
	 * @param processor the content assist processor to register, or <code>null</code> to remove an existing one
	 * @param contentType the content type under which to register
	 */
	 public void setContentAssistProcessor(IContentAssistProcessor processor, String contentType) {

		Assert.isNotNull(contentType);

		if (fProcessors == null)
			fProcessors= new HashMap<>();

		if (processor == null)
			fProcessors.remove(contentType);
		else
			fProcessors.put(contentType, processor);
	}

	/*
	 * @see IContentAssistant#getContentAssistProcessor
	 */
	@Override
	public IContentAssistProcessor getContentAssistProcessor(String contentType) {
		if (fProcessors == null)
			return null;

		return fProcessors.get(contentType);
	}

	/**
	 * Enables the content assistant's auto activation mode.
	 *
	 * @param enabled indicates whether auto activation is enabled or not
	 */
	public void enableAutoActivation(boolean enabled) {
		fIsAutoActivated= enabled;
		manageAutoActivation(fIsAutoActivated);
	}

	/**
	 * Enables the content assistant's auto insertion mode. If enabled,
	 * the content assistant inserts a proposal automatically if it is
	 * the only proposal. In the case of ambiguities, the user must
	 * make the choice.
	 *
	 * @param enabled indicates whether auto insertion is enabled or not
	 * @since 2.0
	 */
	public void enableAutoInsert(boolean enabled) {
		fIsAutoInserting= enabled;
	}

	/**
	 * Returns whether this content assistant is in the auto insertion
	 * mode or not.
	 *
	 * @return <code>true</code> if in auto insertion mode
	 * @since 2.0
	 */
	boolean isAutoInserting() {
		return fIsAutoInserting;
	}

	/**
	 * Installs and uninstall the listeners needed for auto activation.
	 *
	 * @param start <code>true</code> if listeners must be installed, <code>false</code> if they
	 *            must be removed
	 * @since 2.0
	 */
	private void manageAutoActivation(boolean start) {
		if (start) {

			if (fViewer != null && fAutoAssistListener == null) {
				fAutoAssistListener= new AutoAssistListener();
				if (fViewer instanceof ITextViewerExtension) {
					ITextViewerExtension extension= (ITextViewerExtension) fViewer;
					extension.appendVerifyKeyListener(fAutoAssistListener);
				} else {
					StyledText textWidget= fViewer.getTextWidget();
					if (Helper2.okToUse(textWidget))
						textWidget.addVerifyKeyListener(fAutoAssistListener);
				}
			}

		} else if (fAutoAssistListener != null) {

			if (fViewer instanceof ITextViewerExtension) {
				ITextViewerExtension extension= (ITextViewerExtension) fViewer;
				extension.removeVerifyKeyListener(fAutoAssistListener);
			} else {
				StyledText textWidget= fViewer.getTextWidget();
				if (Helper2.okToUse(textWidget))
					textWidget.removeVerifyKeyListener(fAutoAssistListener);
			}

			fAutoAssistListener= null;
		}
	}

	/**
	 * Sets the delay after which the content assistant is automatically invoked
	 * if the cursor is behind an auto activation character.
	 *
	 * @param delay the auto activation delay
	 */
	public void setAutoActivationDelay(int delay) {
		fAutoActivationDelay= delay;
	}

	/**
	 * Sets the proposal pop-ups' orientation.
	 * The following values may be used:
	 * <ul>
	 *   <li>PROPOSAL_OVERLAY<p>
	 *     proposal popup windows should overlay each other
	 *   </li>
	 *   <li>PROPOSAL_REMOVE<p>
	 *     any currently shown proposal popup should be closed
	 *   </li>
	 *   <li>PROPOSAL_STACKED<p>
	 *     proposal popup windows should be vertical stacked, with no overlap,
	 *     beneath the line containing the current cursor location
	 *   </li>
	 * </ul>
	 *
	 * @param orientation the popup's orientation
	 */
	public void setProposalPopupOrientation(int orientation) {
		fProposalPopupOrientation= orientation;
	}

	/**
	 * Sets the context information popup's orientation.
	 * The following values may be used:
	 * <ul>
	 *   <li>CONTEXT_ABOVE<p>
	 *     context information popup should always appear above the line containing
	 *     the current cursor location
	 *   </li>
	 *   <li>CONTEXT_BELOW<p>
	 *     context information popup should always appear below the line containing
	 *     the current cursor location
	 *   </li>
	 * </ul>
	 *
	 * @param orientation the popup's orientation
	 */
	public void setContextInformationPopupOrientation(int orientation) {
		fContextInfoPopupOrientation= orientation;
	}

	/**
	 * Sets the context information popup's background color.
	 *
	 * @param background the background color
	 */
	public void setContextInformationPopupBackground(Color background) {
		fContextInfoPopupBackground= background;
	}

	/**
	 * Returns the background of the context information popup.
	 *
	 * @return the background of the context information popup
	 * @since 2.0
	 */
	Color getContextInformationPopupBackground() {
		return fContextInfoPopupBackground;
	}

	/**
	 * Sets the context information popup's foreground color.
	 *
	 * @param foreground the foreground color
	 * @since 2.0
	 */
	public void setContextInformationPopupForeground(Color foreground) {
		fContextInfoPopupForeground= foreground;
	}

	/**
	 * Returns the foreground of the context information popup.
	 *
	 * @return the foreground of the context information popup
	 * @since 2.0
	 */
	Color getContextInformationPopupForeground() {
		return fContextInfoPopupForeground;
	}

	/**
	 * Sets the context selector's background color.
	 *
	 * @param background the background color
	 * @since 2.0
	 */
	public void setContextSelectorBackground(Color background) {
		fContextSelectorBackground= background;
	}

	/**
	 * Returns the background of the context selector.
	 *
	 * @return the background of the context selector
	 * @since 2.0
	 */
	Color getContextSelectorBackground() {
		return fContextSelectorBackground;
	}

	/**
	 * Sets the context selector's foreground color.
	 *
	 * @param foreground the foreground color
	 * @since 2.0
	 */
	public void setContextSelectorForeground(Color foreground) {
		fContextSelectorForeground= foreground;
	}

	/**
	 * Returns the foreground of the context selector.
	 *
	 * @return the foreground of the context selector
	 * @since 2.0
	 */
	Color getContextSelectorForeground() {
		return fContextSelectorForeground;
	}

	/**
	 * Sets the information control creator for the additional information control.
	 *
	 * @param creator the information control creator for the additional information control
	 * @since 2.0
	 */
	public void setInformationControlCreator(IInformationControlCreator creator) {
		fInformationControlCreator= creator;
	}

	/*
	 * @see IContentAssist#install
	 */
	@Override
	public void install(ITextViewer textViewer) {
		Assert.isNotNull(textViewer);

		fViewer= textViewer;

		fLayoutManager= new LayoutManager();
		fInternalListener= new InternalListener();

		AdditionalInfoController2 controller= null;
		if (fInformationControlCreator != null)
			controller= new AdditionalInfoController2(fInformationControlCreator, OpenStrategy.getPostSelectionDelay());

		fContextInfoPopup= new ContextInformationPopup2(this, fViewer);
		fProposalPopup= new CompletionProposalPopup2(this, fViewer, controller);

		manageAutoActivation(fIsAutoActivated);
	}

	/*
	 * @see IContentAssist#uninstall
	 */
	@Override
	public void uninstall() {

		if (fProposalPopup != null)
			fProposalPopup.hide();

		if (fContextInfoPopup != null)
			fContextInfoPopup.hide();

		manageAutoActivation(false);

		if (fCloser != null) {
			fCloser.uninstall();
			fCloser= null;
		}

		fViewer= null;
	}

	/**
	 * Adds the given shell of the specified type to the layout.
	 * Valid types are defined by <code>LayoutManager</code>.
	 *
	 * @param popup a content assist popup
	 * @param shell the shell of the content-assist popup
	 * @param type the type of popup
	 * @param visibleOffset the offset at which to layout the popup relative to the offset of the viewer's visible region
	 * @since 2.0
	 */
	void addToLayout(Object popup, Shell shell, int type, int visibleOffset) {
		fLayoutManager.add(popup, shell, type, visibleOffset);
	}

	/**
	 * Layouts the registered popup of the given type relative to the
	 * given offset. The offset is relative to the offset of the viewer's visible region.
	 * Valid types are defined by <code>LayoutManager</code>.
	 *
	 * @param type the type of popup to layout
	 * @param visibleOffset the offset at which to layout relative to the offset of the viewer's visible region
	 * @since 2.0
	 */
	void layout(int type, int visibleOffset) {
		fLayoutManager.layout(type, visibleOffset);
	}

	/**
	 * Notifies the controller that a popup has lost focus.
	 *
	 * @param e the focus event
	 */
	void popupFocusLost(FocusEvent e) {
		fCloser.focusLost(e);
	}

	/**
	 * Returns the offset of the selection relative to the offset of the visible region.
	 *
	 * @return the offset of the selection relative to the offset of the visible region
	 * @since 2.0
	 */
	int getSelectionOffset() {
		StyledText text= fViewer.getTextWidget();
		return text.getSelectionRange().x;
	}

	/**
	 * Returns whether the widget token could be acquired.
	 * The following are valid listener types:
	 * <ul>
	 *   <li>AUTO_ASSIST
	 *   <li>CONTEXT_SELECTOR
	 *   <li>PROPOSAL_SELECTOR
	 *   <li>CONTEXT_INFO_POPUP
	 * <ul>
	 * @param type the listener type for which to acquire
	 * @return <code>true</code> if the widget token could be acquired
	 * @since 2.0
	 */
	private boolean acquireWidgetToken(int type) {
		switch (type) {
			case CONTEXT_SELECTOR:
			case PROPOSAL_SELECTOR:
				if (fViewer instanceof IWidgetTokenOwner) {
					IWidgetTokenOwner owner= (IWidgetTokenOwner) fViewer;
					return owner.requestWidgetToken(this);
				} else if (fViewer instanceof IWidgetTokenOwnerExtension)  {
					IWidgetTokenOwnerExtension extension= (IWidgetTokenOwnerExtension) fViewer;
					return extension.requestWidgetToken(this, WIDGET_PRIORITY);
				}
		}
		return true;
	}

	/**
	 * Registers a content assist listener.
	 * The following are valid listener types:
	 * <ul>
	 *   <li>AUTO_ASSIST
	 *   <li>CONTEXT_SELECTOR
	 *   <li>PROPOSAL_SELECTOR
	 *   <li>CONTEXT_INFO_POPUP
	 * <ul>
	 * Returns whether the listener could be added successfully. A listener
	 * can not be added if the widget token could not be acquired.
	 *
	 * @param listener the listener to register
	 * @param type the type of listener
	 * @return <code>true</code> if the listener could be added
	 */
	boolean addContentAssistListener(IContentAssistListener2 listener, int type) {

		if (acquireWidgetToken(type)) {

			fListeners[type]= listener;

			if (getNumberOfListeners() == 1) {
				fCloser= new Closer();
				fCloser.install();
				fViewer.setEventConsumer(fInternalListener);
				installKeyListener();
			}
			return true;
		}

		return false;
	}

	/**
	 * Installs a key listener on the text viewer's widget.
	 */
	private void installKeyListener() {
		if (!fKeyListenerHooked) {
			StyledText text= fViewer.getTextWidget();
			if (Helper2.okToUse(text)) {

				if (fViewer instanceof ITextViewerExtension) {
					ITextViewerExtension e= (ITextViewerExtension) fViewer;
					e.prependVerifyKeyListener(fInternalListener);
				} else {
					text.addVerifyKeyListener(fInternalListener);
				}

				fKeyListenerHooked= true;
			}
		}
	}

	/**
	 * Releases the previously acquired widget token if the token
	 * is no longer necessary.
	 * The following are valid listener types:
	 * <ul>
	 *   <li>AUTO_ASSIST
	 *   <li>CONTEXT_SELECTOR
	 *   <li>PROPOSAL_SELECTOR
	 *   <li>CONTEXT_INFO_POPUP
	 * <ul>
	 *
	 * @param type the listener type
	 * @since 2.0
	 */
	private void releaseWidgetToken(int type) {
		if (fListeners[CONTEXT_SELECTOR] == null && fListeners[PROPOSAL_SELECTOR] == null) {
			if (fViewer instanceof IWidgetTokenOwner) {
				IWidgetTokenOwner owner= (IWidgetTokenOwner) fViewer;
				owner.releaseWidgetToken(this);
			}
		}
	}

	/**
	 * Unregisters a content assist listener.
	 *
	 * @param listener the listener to unregister
	 * @param type the type of listener
	 *
	 * @see #addContentAssistListener
	 */
	void removeContentAssistListener(IContentAssistListener2 listener, int type) {
		fListeners[type]= null;

		if (getNumberOfListeners() == 0) {

			if (fCloser != null) {
				fCloser.uninstall();
				fCloser= null;
			}

			uninstallKeyListener();
			fViewer.setEventConsumer(null);
		}

		releaseWidgetToken(type);
	}

	/**
	 * Uninstall the key listener from the text viewer's widget.
	 */
	private void uninstallKeyListener() {
		if (fKeyListenerHooked) {
			StyledText text= fViewer.getTextWidget();
			if (Helper2.okToUse(text)) {

				if (fViewer instanceof ITextViewerExtension) {
					ITextViewerExtension e= (ITextViewerExtension) fViewer;
					e.removeVerifyKeyListener(fInternalListener);
				} else {
					text.removeVerifyKeyListener(fInternalListener);
				}

				fKeyListenerHooked= false;
			}
		}
	}

	/**
	 * Returns the number of listeners.
	 *
	 * @return the number of listeners
	 * @since 2.0
	 */
	private int getNumberOfListeners() {
		int count= 0;
		for (int i= 0; i <= CONTEXT_INFO_POPUP; i++) {
			if (fListeners[i] != null)
				++ count;
		}
		return count;
	}

	/*
	 * @see IContentAssist#showPossibleCompletions
	 */
	@Override
	public String showPossibleCompletions() {
		return fProposalPopup.showProposals(false);
	}

	/**
	 * Hides the proposal popup.
	 */
	public void hidePossibleCompletions() {
		if (fProposalPopup != null)
			fProposalPopup.hide();
	}

	/**
	 * Hides any open pop-ups.
	 */
	protected void hide() {
		if (fProposalPopup != null)
			fProposalPopup.hide();
		if (fContextInfoPopup != null)
			fContextInfoPopup.hide();
	}

	/**
	 * Callback to signal this content assistant that the presentation of the possible completions has been stopped.
	 * @since 2.1
	 */
	protected void possibleCompletionsClosed() {
	}

	/*
	 * @see IContentAssist#showContextInformation
	 */
	@Override
	public String showContextInformation() {
		return fContextInfoPopup.showContextProposals(false);
	}


	/**
	 * Callback to signal this content assistant that the presentation of the context information has been stopped.
	 * @since 2.1
	 */
	protected void contextInformationClosed() {
	}

	/**
	 * Requests that the specified context information to be shown.
	 *
	 * @param contextInformation the context information to be shown
	 * @param position the position to which the context information refers to
	 * @since 2.0
	 */
	void showContextInformation(IContextInformation contextInformation, int position) {
		fContextInfoPopup.showContextInformation(contextInformation, position);
	}

	/**
	 * Returns the current content assist error message.
	 *
	 * @return an error message or <code>null</code> if no error has occurred
	 */
	String getErrorMessage() {
		return fLastErrorMessage;
	}

	/**
	 * Returns the content assist processor for the content
	 * type of the specified document position.
	 *
	 * @param viewer the text viewer
	 * @param offset a offset within the document
	 * @return a content-assist processor or <code>null</code> if none exists
	 */
	private IContentAssistProcessor getProcessor(ITextViewer viewer, int offset) {
		try {
			String type= TextUtilities.getContentType(viewer.getDocument(), getDocumentPartitioning(), offset, true);
			return getContentAssistProcessor(type);
		} catch (BadLocationException x) {
		}
		return null;
	}

	/**
	 * Returns an array of completion proposals computed based on
	 * the specified document position. The position is used to
	 * determine the appropriate content assist processor to invoke.
	 *
	 * @param viewer the viewer for which to compute the proposals
	 * @param position a document position
	 * @return an array of completion proposals
	 *
	 * @see IContentAssistProcessor#computeCompletionProposals
	 */
	ICompletionProposal[] computeCompletionProposals(ITextViewer viewer, int position) {
		if (fProposals != null) {
			return fProposals;
		} else if (fProposalStrings != null) {
			ICompletionProposal[] result= new ICompletionProposal[fProposalStrings.length];
			for (int i= 0; i < fProposalStrings.length; i++) {
				result[i]= new CompletionProposal(fProposalStrings[i], position, fProposalStrings[i].length(), fProposalStrings[i].length());
			}
			return result;
		} else return null;
	}

	/**
	 * Returns an array of context information objects computed based
	 * on the specified document position. The position is used to determine
	 * the appropriate content assist processor to invoke.
	 *
	 * @param viewer the viewer for which to compute the context information
	 * @param position a document position
	 * @return an array of context information objects
	 *
	 * @see IContentAssistProcessor#computeContextInformation
	 */
	IContextInformation[] computeContextInformation(ITextViewer viewer, int position) {
		fLastErrorMessage= null;

		IContextInformation[] result= null;

		IContentAssistProcessor p= getProcessor(viewer, position);
		if (p != null) {
			result= p.computeContextInformation(viewer, position);
			fLastErrorMessage= p.getErrorMessage();
		}

		return result;
	}

	/**
	 * Returns the context information validator that should be used to
	 * determine when the currently displayed context information should
	 * be dismissed. The position is used to determine the appropriate
	 * content assist processor to invoke.
	 *
	 * @param textViewer the text viewer
	 * @param offset a document offset
	 * @return an validator
	 *
	 * @see IContentAssistProcessor#getContextInformationValidator
	 */
	IContextInformationValidator getContextInformationValidator(ITextViewer textViewer, int offset) {
		IContentAssistProcessor p= getProcessor(textViewer, offset);
		return p != null ? p.getContextInformationValidator() : null;
	}

	/**
	 * Returns the context information presenter that should be used to
	 * display context information. The position is used to determine the appropriate
	 * content assist processor to invoke.
	 *
	 * @param textViewer the text viewer
	 * @param offset a document offset
	 * @return a presenter
	 * @since 2.0
	 */
	IContextInformationPresenter getContextInformationPresenter(ITextViewer textViewer, int offset) {
		IContextInformationValidator validator= getContextInformationValidator(textViewer, offset);
		if (validator instanceof IContextInformationPresenter)
			return (IContextInformationPresenter) validator;
		return null;
	}

	/**
	 * Returns the characters which when typed by the user should automatically
	 * initiate proposing completions. The position is used to determine the
	 * appropriate content assist processor to invoke.
	 *
	 * @param textViewer the text viewer
	 * @param offset a document offset
	 * @return the auto activation characters
	 *
	 * @see IContentAssistProcessor#getCompletionProposalAutoActivationCharacters
	 */
	private char[] getCompletionProposalAutoActivationCharacters(ITextViewer textViewer, int offset) {
		IContentAssistProcessor p= getProcessor(textViewer, offset);
		return p != null ? p.getCompletionProposalAutoActivationCharacters() : null;
	}

	/**
	 * Returns the characters which when typed by the user should automatically
	 * initiate the presentation of context information. The position is used
	 * to determine the appropriate content assist processor to invoke.
	 *
	 * @param textViewer the text viewer
	 * @param offset a document offset
	 * @return the auto activation characters
	 *
	 * @see IContentAssistProcessor#getContextInformationAutoActivationCharacters
	 */
	private char[] getContextInformationAutoActivationCharacters(ITextViewer textViewer, int offset) {
		IContentAssistProcessor p= getProcessor(textViewer, offset);
		return p != null ? p.getContextInformationAutoActivationCharacters() : null;
	}

	@Override
	public boolean requestWidgetToken(IWidgetTokenOwner owner) {
		hidePossibleCompletions();
		return true;
	}

	/**
	 * @param completionPosition the completion position
	 */
	public void setCompletionPosition(int completionPosition) {
		fCompletionPosition= completionPosition;
	}

	/**
	 * @return the completion position
	 */
	public int getCompletionPosition() {
		return fCompletionPosition;
	}

	/**
	 * @param proposals the proposals
	 */
	public void setCompletions(String[] proposals) {
		fProposalStrings= proposals;
	}

	/**
	 * @param proposals the proposals
	 */
	public void setCompletions(ICompletionProposal[] proposals) {
		fProposals= proposals;
	}

	@Override
	public boolean requestWidgetToken(IWidgetTokenOwner owner, int priority) {
		if (priority > WIDGET_PRIORITY) {
			hidePossibleCompletions();
			return true;
		}
		return false;
	}

	@Override
	public boolean setFocus(IWidgetTokenOwner owner) {
		if (fProposalPopup != null) {
			fProposalPopup.setFocus();
			return fProposalPopup.hasFocus();
		}
		return false;
	}

	/**
	 * Returns whether any popups controlled by the receiver have the input focus.
	 *
	 * @return <code>true</code> if any of the managed popups have the focus, <code>false</code> otherwise
	 */
	public boolean hasFocus() {
		return (fProposalPopup != null && fProposalPopup.hasFocus())
				|| (fContextInfoPopup != null && fContextInfoPopup.hasFocus());
	}

	@Override
	public String completePrefix() {
		return null;
	}

	/**
	 * @param proposal the proposal
	 */
	public void fireProposalChosen(ICompletionProposal proposal) {
		List<IProposalListener> list= new ArrayList<>(fProposalListeners);
		for (IProposalListener listener : list) {
			listener.proposalChosen(proposal);
		}

	}

	/**
	 * @param listener the proposal listener
	 */
	public void removeProposalListener(IProposalListener listener) {
		fProposalListeners.remove(listener);
	}

	/**
	 * @param listener the proposal listener
	 */
	public void addProposalListener(IProposalListener listener) {
		fProposalListeners.add(listener);
	}

	/**
	 * Tells whether the support for colored labels is enabled.
	 *
	 * @return <code>true</code> if the support for colored labels is enabled, <code>false</code> otherwise
	 * @since 3.4
	 */
	boolean isColoredLabelsSupportEnabled() {
		return fIsColoredLabelsSupportEnabled;
	}

	/**
	 * Enables the support for colored labels in the proposal popup.
	 * <p>Completion proposals can implement {@link ICompletionProposalExtension6}
	 * to provide colored proposal labels.</p>
	 *
	 * @param isEnabled if <code>true</code> the support for colored labels is enabled in the proposal popup
	 * @since 3.4
	 */
	public void enableColoredLabels(boolean isEnabled) {
		fIsColoredLabelsSupportEnabled= isEnabled;
	}
}

