/***************************************************************************************************
 * 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
 * 		Sebastian Davids <sdavids@gmx.de> - bug 93374
 **************************************************************************************************/
package org.eclipse.help.ui.internal;

import java.net.URL;

import org.eclipse.core.runtime.Platform;
import org.eclipse.help.IContext;
import org.eclipse.help.IHelpResource;
import org.eclipse.help.browser.IBrowser;
import org.eclipse.help.internal.base.BaseHelpSystem;
import org.eclipse.help.internal.base.HelpBasePlugin;
import org.eclipse.help.internal.base.IHelpBaseConstants;
import org.eclipse.help.ui.internal.util.ErrorUtil;
import org.eclipse.help.ui.internal.util.FontUtils;
import org.eclipse.help.ui.internal.views.ContextHelpPart;
import org.eclipse.help.ui.internal.views.HelpTray;
import org.eclipse.help.ui.internal.views.HelpView;
import org.eclipse.help.ui.internal.views.ReusableHelpPart;
import org.eclipse.jface.dialogs.DialogTray;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.dialogs.TrayDialog;
import org.eclipse.osgi.service.environment.Constants;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IViewPart;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.browser.IWebBrowser;
import org.eclipse.ui.browser.IWorkbenchBrowserSupport;
import org.eclipse.ui.help.AbstractHelpUI;
import org.eclipse.ui.intro.IIntroManager;
import org.eclipse.ui.intro.IIntroPart;

/**
 * This class is an implementation of the Help UI. In is registered into the helpSupport extension
 * point, and is responsible for handling requests to display help. The methods on this class
 * interact with the actual UI component handling the display.
 * <p>
 * Most methods delegate most work to HelpDisplay class; only the UI specific ones implemented in
 * place.
 * </p>
 */
public class DefaultHelpUI extends AbstractHelpUI {

	private ContextHelpDialog f1Dialog = null;
	private static DefaultHelpUI instance;
	private static boolean openingHelpView = false;

	private static final String HELP_VIEW_ID = "org.eclipse.help.ui.HelpView"; //$NON-NLS-1$

	class ExternalWorkbenchBrowser implements IBrowser {

		public ExternalWorkbenchBrowser() {
		}

		private IWebBrowser getExternalBrowser() throws PartInitException {
			IWorkbenchBrowserSupport support = PlatformUI.getWorkbench().getBrowserSupport();
			return support.getExternalBrowser();
		}

		@Override
		public void close() {
		}

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

		@Override
		public void displayURL(String url) throws Exception {
			try {
				IWebBrowser browser = getExternalBrowser();
				if (browser != null) {
					browser.openURL(new URL(url));
				}
			} catch (PartInitException pie) {
				ErrorUtil.displayErrorDialog(pie.getLocalizedMessage());
			}
		}

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

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

		@Override
		public void setLocation(int x, int y) {
		}

		@Override
		public void setSize(int width, int height) {
		}
	}

	/**
	 * Constructor.
	 */
	public DefaultHelpUI() {
		super();
		instance = this;
		// register external browser. This will cause the help system
		// to use workbench external browser instead of its own.
		BaseHelpSystem.getInstance().setBrowserInstance(new ExternalWorkbenchBrowser());
	}

	public static DefaultHelpUI getInstance() {
		return instance;
	}

	/**
	 * Displays help.
	 */
	@Override
	public void displayHelp() {
		BaseHelpSystem.getHelpDisplay().displayHelp(useExternalBrowser(null));
	}

	/**
	 * Displays search.
	 */
	@Override
	public void displaySearch() {
		search(null);
	}

	/**
	 * Displays dynamic help.
	 */
	@Override
	public void displayDynamicHelp() {
		IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
		Shell activeShell = getActiveShell();
		if (window != null && isActiveShell(activeShell, window)) {
			setIntroStandby();

			IWorkbenchPage page = window.getActivePage();
			Control c = activeShell.getDisplay().getFocusControl();
			if (page != null) {
				IWorkbenchPart activePart = page.getActivePart();
				try {
					IViewPart part = page.showView(HELP_VIEW_ID, null, IWorkbenchPage.VIEW_ACTIVATE);
					if (part != null) {
						HelpView view = (HelpView) part;
						view.showDynamicHelp(activePart, c);
					}
				} catch (PartInitException e) {
				}
			} else {
				// check the dialog
				Object data = activeShell.getData();
				if (data instanceof TrayDialog) {
					IContext context = ContextHelpPart.findHelpContext(c);
					displayContextAsHelpTray(activeShell, context);
					return;
				}
				warnNoOpenPerspective(window);
			}
		}
	}

	/**
	 * Starts the search.
	 */
	@Override
	public void search(final String expression) {
		IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
		Shell activeShell = getActiveShell();
		if (window != null && isActiveShell(activeShell, window)) {
			setIntroStandby();

			IWorkbenchPage page = window.getActivePage();
			if (page != null) {
				boolean searchFromBrowser = Platform.getPreferencesService().getBoolean
				    (HelpBasePlugin.PLUGIN_ID, IHelpBaseConstants.P_KEY_SEARCH_FROM_BROWSER, false, null);
				if (searchFromBrowser) {
					String parameters = "tab=search"; //$NON-NLS-1$
					if (expression != null) {
						parameters += '&';
						parameters += expression;
					}
					BaseHelpSystem.getHelpDisplay().displayHelpResource(parameters, false);
				} else {
					try {
						IViewPart part = page.showView(HELP_VIEW_ID);
						if (part != null) {
							HelpView view = (HelpView) part;
							view.startSearch(expression);
						}
					} catch (PartInitException e) {
					}
				}
			} else {
				// check the dialog
				if (activeShell != null) {
					Object data = activeShell.getData();
					if (data instanceof TrayDialog) {
						displayContextAsHelpTray(activeShell, null);
						return;
					}
					else {
						// tried to summon help from a non-tray dialog
						// not supported
						return;
					}
				}
				warnNoOpenPerspective(window);
			}
		}
	}

	public static void showIndex() {
		HelpView helpView = getHelpView();
        if (helpView != null) {
		    helpView.showIndex();
        }
	}

	private static HelpView getHelpView() {
		HelpView view = null;
		IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
		Shell activeShell = getActiveShell();
		if (window != null && isActiveShell(activeShell, window)) {
			setIntroStandby();
			IWorkbenchPage page = window.getActivePage();
			if (page != null) {
				try {
					IViewPart part = page.showView(HELP_VIEW_ID);
					if (part != null) {
						view = (HelpView) part;
					}
				} catch (PartInitException e) {
				}
			}
		}
		return view;
	}

	private static void setIntroStandby() {
		IIntroManager introMng = PlatformUI.getWorkbench().getIntroManager();
		IIntroPart intro = introMng.getIntro();
		if (intro != null && !introMng.isIntroStandby(intro))
			introMng.setIntroStandby(intro, true);
	}

	private void warnNoOpenPerspective(IWorkbenchWindow window) {
		MessageDialog.openInformation(window.getShell(), Messages.DefaultHelpUI_wtitle,
				Messages.DefaultHelpUI_noPerspMessage);
	}

	/**
	 * Displays a help resource specified as a url.
	 * <ul>
	 * <li>a URL in a format that can be returned by
	 * {@link  org.eclipse.help.IHelpResource#getHref() IHelpResource.getHref()}
	 * <li>a URL query in the format format <em>key=value&amp;key=value ...</em> The valid keys
	 * are: "tab", "toc", "topic", "contextId". For example,
	 * <em>toc="/myplugin/mytoc.xml"&amp;topic="/myplugin/references/myclass.html"</em> is valid.
	 * </ul>
	 */
	@Override
	public void displayHelpResource(String href) {
		BaseHelpSystem.getHelpDisplay().displayHelpResource(href, useExternalBrowser(href));
	}

	/**
	 * Displays context-sensitive help for specified context
	 *
	 * @param context
	 *            the context to display
	 * @param x
	 *            int positioning information
	 * @param y
	 *            int positioning information
	 */
	@Override
	public void displayContext(IContext context, int x, int y) {
		displayContext(context, x, y, false);
	}

	void displayContext(IContext context, int x, int y, boolean noInfopop) {
		if (context == null)
			return;
		boolean winfopop = Platform.getPreferencesService().getBoolean
		        (HelpBasePlugin.PLUGIN_ID, IHelpBaseConstants.P_KEY_WINDOW_INFOPOP, false, null);
		boolean dinfopop = Platform.getPreferencesService().getBoolean
		        (HelpBasePlugin.PLUGIN_ID, IHelpBaseConstants.P_KEY_DIALOG_INFOPOP, false, null)  || FontUtils.isFontTooLargeForTray();

		IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
		Shell activeShell = getActiveShell();
		if (window != null && isActiveShell(activeShell, window)) {
			IWorkbenchPage page = window.getActivePage();
			if (page != null) {
				if (!noInfopop && winfopop) {
					Control c = window.getShell().getDisplay().getFocusControl();
					displayContextAsInfopop(context, x, y, c);
					return;
				}
				try {
					/*
					 * If the context help has no description text and exactly one
					 * topic, go straight to the topic and skip context help.
					 */
					String contextText = context.getText();
					IHelpResource[] topics = context.getRelatedTopics();
					boolean isSingleChoiceWithoutDescription = contextText == null && topics.length == 1;
					String openMode = Platform.getPreferencesService().getString
					    (HelpBasePlugin.PLUGIN_ID, IHelpBaseConstants.P_KEY_HELP_VIEW_OPEN_MODE, IHelpBaseConstants.P_IN_PLACE, null);
					if (isSingleChoiceWithoutDescription && IHelpBaseConstants.P_IN_EDITOR.equals(openMode)) {
						showInWorkbenchBrowser(topics[0].getHref(), true);
					} else if (isSingleChoiceWithoutDescription && IHelpBaseConstants.P_IN_BROWSER.equals(openMode)) {
						BaseHelpSystem.getHelpDisplay().displayHelpResource(topics[0].getHref(), true);
					} else {
						IWorkbenchPart activePart = page.getActivePart();
						Control c = window.getShell().getDisplay().getFocusControl();
						openingHelpView = true;
						IViewPart part = page.showView(HELP_VIEW_ID);
						openingHelpView = false;
						if (part != null) {
							HelpView view = (HelpView) part;
							if (isSingleChoiceWithoutDescription) {
								view.showHelp(topics[0].getHref());
							} else {
								view.displayContext(context, activePart, c);
							}
						}
					}
					return;
				} catch (PartInitException e) {
					// ignore the exception and let
					// the code default to the context
					// help dialog
				}
			}
		}
		// check the dialog
		if (HelpTray.isAppropriateFor(activeShell) && (!dinfopop || noInfopop)) {
			displayContextAsHelpTray(activeShell, context);
			return;
		}
		// we are here either as a fallback or because of the user preferences
		displayContextAsInfopop(context, x, y, null);
	}

	@Override
	public URL resolve(String href, boolean documentOnly) {
		return BaseHelpSystem.resolve(href, documentOnly);
	}

	public String unresolve(URL url) {
		return BaseHelpSystem.unresolve(url);
	}

	/*
	 * (non-Javadoc)
	 *
	 * @see org.eclipse.ui.help.AbstractHelpUI#resolve(java.lang.String, boolean)
	 */
	private static Shell getActiveShell() {
		Display display = PlatformUI.getWorkbench().getDisplay();
		return display.getActiveShell();
	}

	static boolean isActiveShell(Shell activeShell, IWorkbenchWindow window) {
		// Test if the active shell belongs to this window
		return activeShell != null && activeShell.equals(window.getShell());
	}

	private void displayContextAsInfopop(IContext context, int x, int y, Control c) {
		if (f1Dialog != null) {
			f1Dialog.close();
		}

		if (context != null) {
			/*
			 * If the context help has no description text and exactly one
			 * topic, go straight to the topic and skip context help.
			 */
			IHelpResource[] topics = context.getRelatedTopics();
			if (context.getText() == null && topics.length == 1) {
				try {
					PlatformUI.getWorkbench().getHelpSystem().displayHelpResource(topics[0].getHref());
				}
				catch (Exception e) {
					// should never happen
				}
			}
			else {
				f1Dialog = new ContextHelpDialog(context, x, y);
				f1Dialog.open();
			}
		}
	}

	private void displayContextAsHelpTray(Shell activeShell, IContext context) {
		Control controlInFocus = activeShell.getDisplay().getFocusControl();
		TrayDialog dialog = (TrayDialog)activeShell.getData();

		DialogTray tray = dialog.getTray();
		if (tray == null) {
			tray = new HelpTray();
			dialog.openTray(tray);
		}
		if (tray instanceof HelpTray) {
			ReusableHelpPart helpPart = ((HelpTray)tray).getHelpPart();
			if (context != null) {
				IHelpResource[] topics = context.getRelatedTopics();
				if (context.getText() == null && topics.length == 1) {
					helpPart.showURL(topics[0].getHref());
				}
				else {
					helpPart.showPage(IHelpUIConstants.HV_CONTEXT_HELP_PAGE);
					helpPart.update(null, context, null, controlInFocus, true);
				}
			}
			else {
				helpPart.showPage(IHelpUIConstants.HV_FSEARCH_PAGE, true);
			}
			helpPart.setFocus();
		}
		else {
			// someone else was occupying the tray; not supported
		}
	}

	/**
	 * Returns <code>true</code> if the context-sensitive help window is currently being
	 * displayed, <code>false</code> if not.
	 */
	@Override
	public boolean isContextHelpDisplayed() {
		if (f1Dialog == null) {
			return false;
		}
		return f1Dialog.isShowing();
	}

	private boolean useExternalBrowser(String url) {
		// On non Windows platforms, use external when modal window is displayed
		if (!Constants.OS_WIN32.equalsIgnoreCase(Platform.getOS())) {
			Display display = Display.getCurrent();
			if (display != null) {
				if (insideModalParent(display))
					return true;
			}
		}

		// Use external when no help frames are to be displayed, otherwise no
		// navigation buttons.
		if (url != null) {
			if (url.indexOf("?noframes=true") > 0 //$NON-NLS-1$
					|| url.indexOf("&noframes=true") > 0) { //$NON-NLS-1$
				return true;
			}
		}
		return false;
	}

	private boolean insideModalParent(Display display) {
		return isDisplayModal(display.getActiveShell());
	}

	public static boolean isDisplayModal(Shell activeShell) {
		while (activeShell != null) {
			if ((activeShell.getStyle() & (SWT.APPLICATION_MODAL | SWT.PRIMARY_MODAL | SWT.SYSTEM_MODAL)) > 0)
				return true;
			activeShell = (Shell) activeShell.getParent();
		}
		return false;
	}

	public static boolean showInWorkbenchBrowser(String url, boolean onlyInternal) {
		IWorkbenchBrowserSupport support = PlatformUI.getWorkbench().getBrowserSupport();
		if (!onlyInternal || support.isInternalWebBrowserAvailable()) {
			try {
				IWebBrowser browser = support
						.createBrowser(
								IWorkbenchBrowserSupport.AS_EDITOR
										| IWorkbenchBrowserSupport.NAVIGATION_BAR
										| IWorkbenchBrowserSupport.STATUS,
								"org.eclipse.help.ui", Messages.ReusableHelpPart_internalBrowserTitle, url); //$NON-NLS-1$
				browser.openURL(BaseHelpSystem.resolve(url, "/help/nftopic")); //$NON-NLS-1$
				return true;
			} catch (PartInitException e) {
				HelpUIPlugin.logError(
						Messages.ReusableHelpPart_internalWebBrowserError, e);
			}
		}
		return false;
	}

	/*
	 * Used to indicate to the HelpView that we are about to pass in a context
	 */

	public static boolean isOpeningHelpView() {
		return openingHelpView;
	}
}