/*******************************************************************************
 * Copyright (c) 2000, 2016 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
 *******************************************************************************/
package org.eclipse.help.ui.internal;

import org.eclipse.core.runtime.Platform;
import org.eclipse.help.IContext;
import org.eclipse.help.IContext2;
import org.eclipse.help.IHelpResource;
import org.eclipse.help.UAContentFilter;
import org.eclipse.help.internal.base.BaseHelpSystem;
import org.eclipse.help.internal.base.HelpEvaluationContext;
import org.eclipse.help.ui.internal.views.HelpTray;
import org.eclipse.osgi.service.environment.Constants;
import org.eclipse.swt.SWT;
import org.eclipse.swt.accessibility.ACC;
import org.eclipse.swt.accessibility.Accessible;
import org.eclipse.swt.accessibility.AccessibleAdapter;
import org.eclipse.swt.accessibility.AccessibleControlAdapter;
import org.eclipse.swt.accessibility.AccessibleControlEvent;
import org.eclipse.swt.accessibility.AccessibleEvent;
import org.eclipse.swt.custom.BusyIndicator;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.events.ControlAdapter;
import org.eclipse.swt.events.ControlEvent;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
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.ui.IWorkbenchWindow;
import org.eclipse.ui.PlatformUI;

/**
 * ContextHelpDialog
 */
public class ContextHelpDialog {
	//private static ImageRegistry imgRegistry = null;

	private Color backgroundColour = null;

	private IContext context;

	private Color foregroundColour = null;

	private Color linkColour = null;

	private static HyperlinkHandler linkManager = new HyperlinkHandler();

	protected Shell parentShell;

	protected Shell shell;

	protected String infopopText;

	/**
	 * Listener for hyperlink selection.
	 */
	class LinkListener extends HyperlinkAdapter {
		IHelpResource topic;

		public LinkListener(IHelpResource topic) {
			this.topic = topic;
		}

		@Override
		public void linkActivated(Control c) {
			launchLinks(topic);
		}

	}

	/**
	 * Constructor:
	 *
	 * @param context
	 *            an array of String or an array of IContext
	 * @param x
	 *            the x mouse location in the current display
	 * @param y
	 *            the y mouse location in the current display
	 */
	ContextHelpDialog(IContext context, int x, int y) {
		this.context = context;
		Display display = Display.getCurrent();
		if (display == null) {
			return;
		}
		backgroundColour = display.getSystemColor(SWT.COLOR_INFO_BACKGROUND);
		foregroundColour = display.getSystemColor(SWT.COLOR_INFO_FOREGROUND);
		linkColour = display.getSystemColor(SWT.COLOR_BLUE);
		parentShell = PlatformUI.getWorkbench().getModalDialogShellProvider().getShell();

		if (parentShell != null) {
			boolean isModal = 0 < (parentShell.getStyle() & (SWT.APPLICATION_MODAL
					| SWT.PRIMARY_MODAL | SWT.SYSTEM_MODAL));
			if (HelpUIPlugin.DEBUG_INFOPOP) {
				System.out
						.println("ContextHelpDialog.ContextHelpDialog(): ParentShell: " //$NON-NLS-1$
								+ parentShell.toString() + " is " //$NON-NLS-1$
								+ (isModal ? "modal" : "modeless")); //$NON-NLS-1$ //$NON-NLS-2$
			}
		}

		shell = new Shell(parentShell, SWT.NONE);
		if (HelpUIPlugin.DEBUG_INFOPOP) {
			System.out
					.println("ContextHelpDialog.ContextHelpDialog(): Shell is:" //$NON-NLS-1$
							+ shell.toString());
		}
		PlatformUI.getWorkbench().getHelpSystem().setHelp(shell, IHelpUIConstants.F1_SHELL);

		shell.addListener(SWT.Deactivate, e -> {
			if (HelpUIPlugin.DEBUG_INFOPOP) {
				System.out.println("ContextHelpDialog shell deactivate listener: SWT.Deactivate called. "); //$NON-NLS-1$
			}
			close();
		});

		shell.addTraverseListener(e -> {
			if (e.detail == SWT.TRAVERSE_ESCAPE) {
				if (HelpUIPlugin.DEBUG_INFOPOP) {
					System.out.println(
							"ContextHelpDialog: shell traverse listener: SWT.TRAVERSE_ESCAPE called. "); //$NON-NLS-1$
				}
				e.doit = true;
			}
		});

		shell.addControlListener(new ControlAdapter() {

			@Override
			public void controlMoved(ControlEvent e) {
				if (HelpUIPlugin.DEBUG_INFOPOP) {
					System.out
							.println("ContextHelpDialog: shell control adapter called."); //$NON-NLS-1$
				}
				Rectangle clientArea = shell.getClientArea();
				shell.redraw(clientArea.x, clientArea.y, clientArea.width,
						clientArea.height, true);
				shell.update();
			}
		});
		if (HelpUIPlugin.DEBUG_INFOPOP) {
			System.out
					.println("ContextHelpDialog.ContextHelpDialog(): Focus owner is: " //$NON-NLS-1$
							+ Display.getCurrent().getFocusControl().toString());
		}
		linkManager
				.setHyperlinkUnderlineMode(HyperlinkHandler.UNDERLINE_ALWAYS);
		createContents(shell);
		shell.pack();
		// Correct x and y of the shell if it not contained within the screen
		int width = shell.getBounds().width;
		int height = shell.getBounds().height;

		Rectangle screen = display.getClientArea();
		// check lower boundaries
		x = x >= screen.x ? x : screen.x;
		y = y >= screen.y ? y : screen.y;
		// check upper boundaries
		x = x + width <= screen.width ? x : screen.width - width;
		y = y + height <= screen.height ? y : screen.height - height;
		shell.setLocation(x, y);

		initAccessible(shell);
	}

	public synchronized void close() {
		try {
			if (HelpUIPlugin.DEBUG_INFOPOP) {
				System.out.println("ContextHelpDialog.close()"); //$NON-NLS-1$
			}
			if (shell != null) {
				shell.close();
				if (!shell.isDisposed())
					shell.dispose();
				shell = null;
			}
		} catch (Throwable ex) {
		}
	}

	protected Control createContents(Composite contents) {
		initAccessible(contents);
		contents.setBackground(backgroundColour);
		GridLayout layout = new GridLayout();
		layout.marginHeight = 5;
		layout.marginWidth = 5;
		contents.setLayout(layout);
		contents.setLayoutData(new GridData(GridData.FILL_BOTH));
		// create the dialog area and button bar
		createInfoArea(contents);
		Control c = createLinksArea(contents);
		if (c != null) {
			// links exist, make them the only focusable controls
			contents.setTabList(new Control[] { c });
		}
		return contents;
	}

	private Control createInfoArea(Composite parent) {
		// Create the text field.
		String styledText = null;
		if (context instanceof IContext2) {
			styledText = ((IContext2) context).getStyledText();
		}
		if (styledText == null && context.getText() != null) {
			styledText = context.getText();
		    styledText= styledText.replaceAll("<b>","<@#\\$b>"); //$NON-NLS-1$ //$NON-NLS-2$
		    styledText= styledText.replaceAll("</b>", "</@#\\$b>"); //$NON-NLS-1$ //$NON-NLS-2$
		}
		if (styledText == null) { // no description found in context objects.
			styledText = Messages.ContextHelpPart_noDescription;
		}
		Description text = new Description(parent, SWT.MULTI | SWT.READ_ONLY);
		text.addTraverseListener(e -> {
			if (e.detail == SWT.TRAVERSE_ESCAPE) {
				if (HelpUIPlugin.DEBUG_INFOPOP) {
					System.out.println(
							"ContextHelpDialog text TraverseListener.handleEvent(): SWT.TRAVERSE_ESCAPE."); //$NON-NLS-1$
				}
				e.doit = true;
			}
		});

		text.getCaret().setVisible(false);
		text.setBackground(backgroundColour);
		text.setForeground(foregroundColour);
		text.setFont(parent.getFont());
		int linkWidth = getLinksWidth(text);
		StyledLineWrapper content = new StyledLineWrapper(styledText, text,
				linkWidth + 70);
		text.setContent(content);
		text.setStyleRanges(content.getStyles());

		infopopText = text.getText();
		initAccessible(text);

		return text;
	}

	/**
	 * Measures the longest label of related links
	 *
	 * @param text
	 * @return
	 */
	private int getLinksWidth(Description text) {
		int linkWidth = 0;
		IHelpResource relatedTopics[] = context.getRelatedTopics();
		if (relatedTopics != null) {
			GC gc = new GC(text);
			for (int i = 0; i < relatedTopics.length; i++) {
				linkWidth = Math.max(linkWidth, gc.textExtent(relatedTopics[i]
						.getLabel()).x);
			}
			gc.dispose();
		}
		return linkWidth;
	}

	private Control createLink(Composite parent, IHelpResource topic) {
		Label image = new Label(parent, SWT.NONE);
		image.setImage(getImage());
		image.setBackground(backgroundColour);
		GridData data = new GridData();
		data.horizontalAlignment = GridData.HORIZONTAL_ALIGN_BEGINNING;
		data.verticalAlignment = GridData.VERTICAL_ALIGN_BEGINNING;
		//data.horizontalIndent = 4;
		image.setLayoutData(data);
		HyperlinkLabel link = new HyperlinkLabel(parent, SWT.NONE);
		link.setText(topic.getLabel());
		link.setBackground(backgroundColour);
		link.setForeground(linkColour);
		link.setFont(parent.getFont());
		linkManager.registerHyperlink(link, new LinkListener(topic));
		return link;
	}

	private Control createLinksArea(Composite parent) {
		IHelpResource[] relatedTopics = context.getRelatedTopics();
		if (relatedTopics == null)
			return null;
		// Create control
		Composite composite = new Composite(parent, SWT.NONE);
		initAccessible(composite);

		composite.setBackground(backgroundColour);
		GridLayout layout = new GridLayout();
		layout.marginHeight = 2;
		layout.marginWidth = 0;
		layout.verticalSpacing = 3;
		layout.horizontalSpacing = 2;
		layout.numColumns = 2;
		composite.setLayout(layout);
		composite.setFont(parent.getFont());
		GridData data = new GridData(GridData.FILL_BOTH
				| GridData.HORIZONTAL_ALIGN_BEGINNING
				| GridData.VERTICAL_ALIGN_CENTER);
		composite.setLayoutData(data);
		// Create separator.
		Label label = new Label(composite, SWT.SEPARATOR | SWT.HORIZONTAL);
		label.setBackground(backgroundColour);
		label.setForeground(foregroundColour);
		data = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING
				| GridData.VERTICAL_ALIGN_BEGINNING | GridData.FILL_HORIZONTAL);
		data.horizontalSpan = 2;
		label.setLayoutData(data);
		// Create related links
		for (int i = 0; i < relatedTopics.length; i++) {
			if (!UAContentFilter.isFiltered(relatedTopics[i], HelpEvaluationContext.getContext())) {
				createLink(composite, relatedTopics[i]);
			}
		}

		// create dynamic help link if current context allows dynamic help
		IWorkbenchWindow wbWindow = HelpUIPlugin.getDefault().getWorkbench().getActiveWorkbenchWindow();
		if (DefaultHelpUI.isActiveShell(parentShell, wbWindow) || HelpTray.isAppropriateFor(parentShell)) {
			// Create separator.
			label = new Label(composite, SWT.SEPARATOR | SWT.HORIZONTAL);
			label.setBackground(backgroundColour);
			label.setForeground(foregroundColour);
			data = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING
					| GridData.VERTICAL_ALIGN_BEGINNING | GridData.FILL_HORIZONTAL);
			data.horizontalSpan = 2;
			label.setLayoutData(data);

			// create link to the dynamic help
			createDynamicHelpLink(composite);
		}

		return composite;
	}

	private Control createDynamicHelpLink(Composite parent) {
		Label image = new Label(parent, SWT.NONE);
		Image img = HelpUIResources.getImage(IHelpUIConstants.IMAGE_DHELP);
		image.setImage(img);
		image.setBackground(backgroundColour);
		GridData data = new GridData();
		data.horizontalAlignment = GridData.HORIZONTAL_ALIGN_BEGINNING;
		data.verticalAlignment = GridData.VERTICAL_ALIGN_BEGINNING;
		//data.horizontalIndent = 4;
		image.setLayoutData(data);
		HyperlinkLabel link = new HyperlinkLabel(parent, SWT.NONE);
		link.setText(Messages.ContextHelpDialog_showInDynamicHelp);
		link.setBackground(backgroundColour);
		link.setForeground(linkColour);
		link.setFont(parent.getFont());
		linkManager.registerHyperlink(link, new HyperlinkAdapter() {

			@Override
			public void linkActivated(Control label) {
				openDynamicHelp();
			}
		});
		return link;
	}

	/**
	 * Called when related link has been chosen Opens help viewer with list of
	 * all related topics
	 */
	protected void launchLinks(IHelpResource selectedTopic) {
		close();
		if (HelpUIPlugin.DEBUG_INFOPOP) {
			System.out.println("ContextHelpDialog.launchLinks(): closed shell"); //$NON-NLS-1$
		}
		BaseHelpSystem.getHelpDisplay().displayHelp(
				context,
				selectedTopic,
				DefaultHelpUI.isDisplayModal(parentShell)
				&& !Constants.OS_WIN32.equalsIgnoreCase(Platform
								.getOS()));
	}

	private void openDynamicHelp() {
		BusyIndicator.showWhile(shell.getDisplay(), () -> {
			close();
			DefaultHelpUI.getInstance().displayContext(context, 0, 0, true);
		});
	}

	public synchronized void open() {
		try {
			shell.open();
			if (HelpUIPlugin.DEBUG_INFOPOP) {
				System.out
						.println("ContextHelpDialog.open(): Focus owner after open is: " //$NON-NLS-1$
								+ Display.getCurrent().getFocusControl()
										.toString());
			}
		} catch (Throwable e) {
			HelpUIPlugin
					.logError(
							"An error occurred when opening context-sensitive help pop-up.", //$NON-NLS-1$
							e);
		}
	}

	private Image getImage() {
		return HelpUIResources.getImage(IHelpUIConstants.IMAGE_FILE_F1TOPIC);
	}

	public boolean isShowing() {
		return (shell != null && !shell.isDisposed() && shell.isVisible());
	}

	private void initAccessible(final Control control) {
		Accessible accessible = control.getAccessible();
		accessible.addAccessibleListener(new AccessibleAdapter() {

			@Override
			public void getName(AccessibleEvent e) {
				e.result = infopopText;
			}

			@Override
			public void getHelp(AccessibleEvent e) {
				e.result = control.getToolTipText();
			}
		});

		accessible.addAccessibleControlListener(new AccessibleControlAdapter() {

			@Override
			public void getChildAtPoint(AccessibleControlEvent e) {
				Point pt = control.toControl(new Point(e.x, e.y));
				e.childID = (control.getBounds().contains(pt)) ? ACC.CHILDID_MULTIPLE
						: ACC.CHILDID_NONE;
			}

			@Override
			public void getLocation(AccessibleControlEvent e) {
				Rectangle location = control.getBounds();
				Point pt = control.toDisplay(new Point(location.x, location.y));
				e.x = pt.x;
				e.y = pt.y;
				e.width = location.width;
				e.height = location.height;
			}

			@Override
			public void getChildCount(AccessibleControlEvent e) {
				e.detail = 1;
			}

			@Override
			public void getRole(AccessibleControlEvent e) {
				e.detail = ACC.ROLE_LABEL;
			}

			@Override
			public void getState(AccessibleControlEvent e) {
				e.detail = ACC.STATE_READONLY;
			}
		});
	}

	public class Description extends StyledText {
		/**
		 * @param parent
		 * @param style
		 */
		public Description(Composite parent, int style) {
			super(parent, style);
		}

		@Override
		public boolean setFocus() {
			return false;
		}

		@Override
		public boolean isFocusControl() {
			return false;
		}
	}

}
