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

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

import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.VerifyKeyListener;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.KeyListener;
import org.eclipse.swt.events.VerifyEvent;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;

import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.Platform;

import org.eclipse.jface.fieldassist.ControlDecoration;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.viewers.ILabelProviderListener;
import org.eclipse.jface.viewers.LabelProviderChangedEvent;

import org.eclipse.jface.text.IEventConsumer;


/**
 * An <code>AbstractControlContentAssistSubjectAdapter</code> delegates assistance requests from a
 * {@linkplain org.eclipse.jface.text.contentassist.ContentAssistant content assistant}
 * to a <code>Control</code>.
 *
 * A visual feedback can be configured via {@link #setContentAssistCueProvider(ILabelProvider)}.
 *
 * @since 3.0
 * @deprecated As of 3.2, replaced by Platform UI's field assist support
 */
@Deprecated
public abstract class AbstractControlContentAssistSubjectAdapter implements IContentAssistSubjectControl {

	protected static final boolean DEBUG= "true".equalsIgnoreCase(Platform.getDebugOption("org.eclipse.jface.text/debug/ContentAssistSubjectAdapters"));  //$NON-NLS-1$//$NON-NLS-2$

	/**
	 * VerifyKeyListeners for the control.
	 */
	private List<VerifyKeyListener> fVerifyKeyListeners;
	/**
	 * KeyListeners for the control.
	 */
	private Set<KeyListener> fKeyListeners;
	/**
	 * The Listener installed on the control which passes events to
	 * {@link #fVerifyKeyListeners fVerifyKeyListeners} and {@link #fKeyListeners}.
	 */
	private Listener fControlListener;
	/**
	 * The cue label provider, or <code>null</code> iff none.
	 * @since 3.3
	 */
	private ILabelProvider fCueLabelProvider;
	/**
	 * The control decoration, or <code>null</code> iff fCueLabelProvider is null.
	 * @since 3.3
	 */
	private ControlDecoration fControlDecoration;
	/**
	 * The default cue image, or <code>null</code> if not cached yet.
	 * @since 3.3
	 */
	private Image fCachedDefaultCueImage;

	/**
	 * Creates a new {@link AbstractControlContentAssistSubjectAdapter}.
	 */
	public AbstractControlContentAssistSubjectAdapter() {
		fVerifyKeyListeners= new ArrayList<>(1);
		fKeyListeners= new HashSet<>(1);
	}

	@Override
	public abstract Control getControl();

	@Override
	public void addKeyListener(KeyListener keyListener) {
		fKeyListeners.add(keyListener);

		if (DEBUG)
			System.out.println("AbstractControlContentAssistSubjectAdapter#addKeyListener()"); //$NON-NLS-1$

		installControlListener();
	}

	@Override
	public void removeKeyListener(KeyListener keyListener) {
		boolean deleted= fKeyListeners.remove(keyListener);

		if (DEBUG) {
			if (!deleted)
				System.out.println("removeKeyListener -> wasn't here"); //$NON-NLS-1$
			System.out.println("AbstractControlContentAssistSubjectAdapter#removeKeyListener() -> " + fKeyListeners.size()); //$NON-NLS-1$
		}

		uninstallControlListener();
	}

	@Override
	public boolean supportsVerifyKeyListener() {
		return true;
	}

	@Override
	public boolean appendVerifyKeyListener(final VerifyKeyListener verifyKeyListener) {
		fVerifyKeyListeners.add(verifyKeyListener);

		if (DEBUG)
			System.out.println("AbstractControlContentAssistSubjectAdapter#appendVerifyKeyListener() -> " + fVerifyKeyListeners.size()); //$NON-NLS-1$

		installControlListener();
		return true;
	}

	@Override
	public boolean prependVerifyKeyListener(final VerifyKeyListener verifyKeyListener) {
		fVerifyKeyListeners.add(0, verifyKeyListener);

		if (DEBUG)
			System.out.println("AbstractControlContentAssistSubjectAdapter#prependVerifyKeyListener() -> " + fVerifyKeyListeners.size()); //$NON-NLS-1$

		installControlListener();
		return true;
	}

	@Override
	public void removeVerifyKeyListener(VerifyKeyListener verifyKeyListener) {
		fVerifyKeyListeners.remove(verifyKeyListener);

		if (DEBUG)
			System.out.println("AbstractControlContentAssistSubjectAdapter#removeVerifyKeyListener() -> " + fVerifyKeyListeners.size()); //$NON-NLS-1$

		uninstallControlListener();
	}

	@Override
	public void setEventConsumer(IEventConsumer eventConsumer) {
		// this is not supported
		if (DEBUG)
			System.out.println("AbstractControlContentAssistSubjectAdapter#setEventConsumer()"); //$NON-NLS-1$
	}

	@Override
	public String getLineDelimiter() {
		return System.lineSeparator();
	}

	/**
	 * Installs <code>fControlListener</code>, which handles VerifyEvents and KeyEvents by
	 * passing them to {@link #fVerifyKeyListeners} and {@link #fKeyListeners}.
	 */
	private void installControlListener() {
		if (DEBUG)
			System.out.println("AbstractControlContentAssistSubjectAdapter#installControlListener() -> k: " + fKeyListeners.size() + ", v: " + fVerifyKeyListeners.size()); //$NON-NLS-1$ //$NON-NLS-2$

		if (fControlListener != null)
			return;

		fControlListener= new Listener() {
			@Override
			public void handleEvent(Event e) {
				if (! getControl().isFocusControl())
					return; //SWT.TRAVERSE_MNEMONIC events can also come in to inactive widgets
				VerifyEvent verifyEvent= new VerifyEvent(e);
				KeyEvent keyEvent= new KeyEvent(e);
				switch (e.type) {
					case SWT.Traverse :

						if (DEBUG)
							dump("before traverse", e, verifyEvent); //$NON-NLS-1$

						verifyEvent.doit= true;
						for (VerifyKeyListener verifyKeyListener : fVerifyKeyListeners) {
							verifyKeyListener.verifyKey(verifyEvent);
							if (! verifyEvent.doit) {
								e.detail= SWT.TRAVERSE_NONE;
								e.doit= true;
								if (DEBUG)
									dump("traverse eaten by verify", e, verifyEvent); //$NON-NLS-1$
								return;
							}

							if (DEBUG)
								dump("traverse OK", e, verifyEvent); //$NON-NLS-1$
						}
						break;

					case SWT.KeyDown:
						for (VerifyKeyListener verifyKeyListener : fVerifyKeyListeners) {
							verifyKeyListener.verifyKey(verifyEvent);
							if (! verifyEvent.doit) {
								e.doit= verifyEvent.doit;
								if (DEBUG)
									dump("keyDown eaten by verify", e, verifyEvent); //$NON-NLS-1$
								return;
							}
						}

						if (DEBUG)
							dump("keyDown OK", e, verifyEvent); //$NON-NLS-1$

						for (KeyListener keyListener : fKeyListeners) {
							keyListener.keyPressed(keyEvent);
						}
						break;

					default :
						Assert.isTrue(false);
				}
			}

			/**
			 * Dump the given events to "standard" output.
			 *
			 * @param who who dump's
			 * @param e the event
			 * @param ve the verify event
			 */
			private void dump(String who, Event e, VerifyEvent ve) {
				StringBuilder sb= new StringBuilder("--- [AbstractControlContentAssistSubjectAdapter]\n"); //$NON-NLS-1$
				sb.append(who);
				sb.append(" - e: keyCode="+e.keyCode+hex(e.keyCode)); //$NON-NLS-1$
				sb.append("; character="+e.character+hex(e.character)); //$NON-NLS-1$
				sb.append("; stateMask="+e.stateMask+hex(e.stateMask)); //$NON-NLS-1$
				sb.append("; doit="+e.doit); //$NON-NLS-1$
				sb.append("; detail="+e.detail+hex(e.detail)); //$NON-NLS-1$
				sb.append("; widget="+e.widget); //$NON-NLS-1$
				sb.append("\n"); //$NON-NLS-1$
				sb.append("  verifyEvent keyCode="+e.keyCode+hex(e.keyCode)); //$NON-NLS-1$
				sb.append("; character="+e.character+hex(e.character)); //$NON-NLS-1$
				sb.append("; stateMask="+e.stateMask+hex(e.stateMask)); //$NON-NLS-1$
				sb.append("; doit="+ve.doit); //$NON-NLS-1$
				sb.append("; widget="+e.widget); //$NON-NLS-1$
				System.out.println(sb);
			}

			private String hex(int i) {
				return "[0x" + Integer.toHexString(i) + ']'; //$NON-NLS-1$
			}
		};
		getControl().addListener(SWT.Traverse, fControlListener);
		getControl().addListener(SWT.KeyDown, fControlListener);

		if (DEBUG)
			System.out.println("AbstractControlContentAssistSubjectAdapter#installControlListener() - installed"); //$NON-NLS-1$
	}

	/**
	 * Uninstalls <code>fControlListener</code> iff there are no <code>KeyListener</code>s and no
	 * <code>VerifyKeyListener</code>s registered.
	 * Otherwise does nothing.
	 */
	private void uninstallControlListener() {
		if (fControlListener == null || fKeyListeners.size() + fVerifyKeyListeners.size() != 0) {

			if (DEBUG)
				System.out.println("AbstractControlContentAssistSubjectAdapter#uninstallControlListener() -> k: " + fKeyListeners.size() + ", v: " + fVerifyKeyListeners.size()); //$NON-NLS-1$ //$NON-NLS-2$

			return;
		}
		getControl().removeListener(SWT.Traverse, fControlListener);
		getControl().removeListener(SWT.KeyDown, fControlListener);
		fControlListener= null;

		if (DEBUG)
			System.out.println("AbstractControlContentAssistSubjectAdapter#uninstallControlListener() - done"); //$NON-NLS-1$
	}

	/**
	 * Sets the visual feedback provider for content assist.
	 * The given {@link ILabelProvider} methods are called with
	 * {@link #getControl()} as argument.
	 *
	 * <ul>
	 *   <li><code>getImage(Object)</code> provides the visual cue image.
	 *     The image can maximally be 5 pixels wide and 8 pixels high.
	 *     If <code>getImage(Object)</code> returns <code>null</code>, a default image is used.
	 *   </li>
	 *   <li><code>getText(Object)</code> provides the hover info text.
	 *     It is shown when hovering over the cue image or the adapted {@link Control}.
	 *     No info text is shown if <code>getText(Object)</code> returns <code>null</code>.
	 *   </li>
	 * </ul>
	 * <p>
	 * The given {@link ILabelProvider} becomes owned by the {@link AbstractControlContentAssistSubjectAdapter},
	 * i.e. it gets disposed when the adapted {@link Control} is disposed
	 * or when another {@link ILabelProvider} is set.
	 * </p>
	 *
	 * @param labelProvider a {@link ILabelProvider}, or <code>null</code>
	 * 	if no visual feedback should be shown
	 */
	public void setContentAssistCueProvider(final ILabelProvider labelProvider) {
		if (fCueLabelProvider != null) {
			fCueLabelProvider.dispose();
		}

		fCueLabelProvider= labelProvider;

		if (labelProvider == null) {
			if (fControlDecoration != null) {
				fControlDecoration.dispose();
				fControlDecoration= null;
			}

		} else {
			if (fControlDecoration == null) {
				fControlDecoration= new ControlDecoration(getControl(), (SWT.TOP | SWT.LEFT));
				getControl().addDisposeListener(e -> {
					if (fCueLabelProvider != null) {
						fCueLabelProvider.dispose();
						fCueLabelProvider= null;
					}
					if (fControlDecoration != null) {
						fControlDecoration.dispose();
						fControlDecoration= null;
					}
					if (fCachedDefaultCueImage != null) {
						fCachedDefaultCueImage.dispose();
						fCachedDefaultCueImage= null;
					}
				});
				fControlDecoration.setShowHover(true);
				fControlDecoration.setShowOnlyOnFocus(true);
			}

			ILabelProviderListener listener= event -> {
				fControlDecoration.setDescriptionText(labelProvider.getText(getControl()));
				Image image= labelProvider.getImage(getControl());
				if (image == null)
					image= getDefaultCueImage();
				fControlDecoration.setImage(image);
			};
			labelProvider.addListener(listener);
			//initialize control decoration:
			listener.labelProviderChanged(new LabelProviderChangedEvent(labelProvider));
		}
	}

	/**
	 * Returns the default cue image.
	 *
	 * @return the default cue image
	 * @since 3.3
	 */
	private Image getDefaultCueImage() {
		if (fCachedDefaultCueImage == null) {
			ImageDescriptor cueID= ImageDescriptor.createFromFile(AbstractControlContentAssistSubjectAdapter.class, "images/content_assist_cue.png"); //$NON-NLS-1$
			fCachedDefaultCueImage= cueID.createImage(getControl().getDisplay());
		}
		return fCachedDefaultCueImage;
	}
}
