/*******************************************************************************
 * Copyright (c) 2018 Remain Software
 * 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:
 *     wim.jongman@remainsoftware.com - initial API and implementation
 *******************************************************************************/
package org.eclipse.tips.ui.internal;

import java.io.IOException;
import java.net.URL;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
import java.util.function.Function;

import org.eclipse.core.runtime.FileLocator;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.swt.SWT;
import org.eclipse.swt.browser.Browser;
import org.eclipse.swt.browser.BrowserFunction;
import org.eclipse.swt.custom.StackLayout;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.MenuItem;
import org.eclipse.swt.widgets.ToolBar;
import org.eclipse.swt.widgets.ToolItem;
import org.eclipse.tips.core.IHtmlTip;
import org.eclipse.tips.core.IUrlTip;
import org.eclipse.tips.core.Tip;
import org.eclipse.tips.core.TipAction;
import org.eclipse.tips.core.TipImage;
import org.eclipse.tips.core.TipProvider;
import org.eclipse.tips.core.internal.LogUtil;
import org.eclipse.tips.core.internal.TipManager;
import org.eclipse.tips.ui.IBrowserFunctionProvider;
import org.eclipse.tips.ui.ISwtTip;
import org.eclipse.tips.ui.internal.util.ImageUtil;
import org.eclipse.tips.ui.internal.util.ResourceManager;

@SuppressWarnings("restriction")
public class TipComposite extends Composite implements ProviderSelectionListener {
	private static final String EMPTY = ""; //$NON-NLS-1$
	private static final int READ_TIMER = 2000;
	private TipProvider fProvider;
	private Browser fBrowser;
	private Slider fSlider;
	private TipManager fTipManager;
	private Tip fCurrentTip;
	private Button fUnreadOnly;
	private Button fPreviousTipButton;
	private Composite fSWTComposite;
	private Composite fBrowserComposite;
	private StackLayout fContentStack;
	private Button fMultiActionMenuButton;
	private Composite fNavigationBar;
	private StackLayout fActionStack;
	private Composite fEmptyActionComposite;
	private Composite fSingleActionComposite;
	private Composite fMultiActionComposite;
	private Button fSingleActionButton;
	private Button fMultiActionButton;
	private Composite fContentComposite;
	private List<Image> fActionImages = new ArrayList<>();
	private List<BrowserFunction> fBrowserFunctions = new ArrayList<>();
	private Menu fActionMenu;
	private ToolBar ftoolBar;
	private ToolItem fStartupItem;

	/**
	 * Constructor.
	 *
	 * @param parent the parent
	 * @param style  the style
	 */
	public TipComposite(Composite parent, int style) {
		super(parent, style);
		GridLayout gridLayout_1 = new GridLayout(1, false);
		gridLayout_1.marginWidth = 2;
		gridLayout_1.marginHeight = 2;
		setLayout(gridLayout_1);

		fContentComposite = new Composite(this, SWT.NONE);
		fContentStack = new StackLayout();
		fContentComposite.setLayout(fContentStack);
		GridData gd_gridComposite = new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1);
		gd_gridComposite.widthHint = 600;
		gd_gridComposite.heightHint = 400;
		fContentComposite.setLayoutData(gd_gridComposite);

		fBrowserComposite = new Composite(fContentComposite, SWT.NONE);
		fBrowserComposite.setLayout(new FillLayout(SWT.HORIZONTAL));

		fBrowser = new Browser(fBrowserComposite, SWT.NONE);
		fBrowser.setJavascriptEnabled(true);

		fSWTComposite = new Composite(fContentComposite, SWT.NONE);
		fSWTComposite.setLayout(new FillLayout(SWT.HORIZONTAL));

		fNavigationBar = new Composite(this, SWT.NONE);
		fNavigationBar.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
		GridLayout gl_NavigationBar = new GridLayout(2, false);
		gl_NavigationBar.horizontalSpacing = 0;
		gl_NavigationBar.marginHeight = 0;
		gl_NavigationBar.verticalSpacing = 0;
		gl_NavigationBar.marginWidth = 0;
		fNavigationBar.setLayout(gl_NavigationBar);

		Composite preferenceBar = new Composite(fNavigationBar, SWT.NONE);
		FillLayout fl_composite_3 = new FillLayout(SWT.HORIZONTAL);
		fl_composite_3.marginWidth = 5;
		fl_composite_3.spacing = 5;
		preferenceBar.setLayout(fl_composite_3);

		final Menu menu = new Menu(getShell(), SWT.POP_UP);
		menu.addListener(SWT.Show, event -> startupMenuAboutToShow(menu));

		ftoolBar = new ToolBar(preferenceBar, SWT.FLAT | SWT.RIGHT);

		fStartupItem = new ToolItem(ftoolBar, SWT.DROP_DOWN);
		fStartupItem.setText(Messages.TipComposite_13);
		fStartupItem.addListener(SWT.Selection, event -> {
			showStartupOptions(menu);
		});

		fUnreadOnly = new Button(preferenceBar, SWT.CHECK);
		fUnreadOnly.setText(Messages.TipComposite_2);
		fUnreadOnly.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				fTipManager.setServeReadTips(!fUnreadOnly.getSelection());
				fPreviousTipButton.setEnabled(fTipManager.mustServeReadTips());
				fSlider.load();
				getNextTip();
			}
		});

		Composite buttonBar = new Composite(fNavigationBar, SWT.NONE);
		buttonBar.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, true, false, 1, 1));
		GridLayout gl_buttonBar = new GridLayout(4, true);
		gl_buttonBar.marginHeight = 0;
		buttonBar.setLayout(gl_buttonBar);

		Composite actionComposite = new Composite(buttonBar, SWT.NONE);
		fActionStack = new StackLayout();
		actionComposite.setLayout(fActionStack);
		actionComposite.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));

		fSingleActionComposite = new Composite(actionComposite, SWT.NONE);
		GridLayout gl_SingleActionComposite = new GridLayout(1, false);
		gl_SingleActionComposite.marginWidth = 0;
		fSingleActionComposite.setLayout(gl_SingleActionComposite);

		fSingleActionButton = new Button(fSingleActionComposite, SWT.NONE);
		fSingleActionButton.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
		fSingleActionButton.setText(Messages.TipComposite_3);
		fSingleActionButton.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				runTipAction(fCurrentTip.getActions().get(0));
			}
		});

		fMultiActionComposite = new Composite(actionComposite, SWT.NONE);
		GridLayout gl_MultiActionComposite = new GridLayout(2, false);
		gl_MultiActionComposite.marginWidth = 0;
		gl_MultiActionComposite.verticalSpacing = 0;
		gl_MultiActionComposite.horizontalSpacing = 0;
		fMultiActionComposite.setLayout(gl_MultiActionComposite);

		fMultiActionButton = new Button(fMultiActionComposite, SWT.NONE);
		fMultiActionButton.setText(Messages.TipComposite_4);
		fMultiActionButton.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				runTipAction(fCurrentTip.getActions().get(0));
			}
		});

		fMultiActionMenuButton = new Button(fMultiActionComposite, SWT.NONE);
		fMultiActionMenuButton.setImage(ResourceManager.getPluginImage("org.eclipse.tips.ui", "icons/popup_menu.png")); //$NON-NLS-1$ //$NON-NLS-2$
		fMultiActionMenuButton.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				showActionMenu();
			}
		});

		fEmptyActionComposite = new Composite(actionComposite, SWT.NONE);
		fEmptyActionComposite.setLayout(new FillLayout(SWT.HORIZONTAL));

		fPreviousTipButton = new Button(buttonBar, SWT.NONE);
		fPreviousTipButton.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
		fPreviousTipButton.setText(Messages.TipComposite_7);
		fPreviousTipButton.addSelectionListener(new SelectionAdapter() {

			@Override
			public void widgetSelected(SelectionEvent e) {
				getPreviousTip();
			}
		});
		fPreviousTipButton.setEnabled(false);

		Button btnNextTip = new Button(buttonBar, SWT.NONE);
		btnNextTip.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
		btnNextTip.setText(Messages.TipComposite_8);
		btnNextTip.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				getNextTip();
			}
		});

		Button btnClose = new Button(buttonBar, SWT.NONE);
		btnClose.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				getParent().dispose();
			}
		});
		btnClose.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
		btnClose.setText(Messages.TipComposite_9);

		Label label_1 = new Label(this, SWT.SEPARATOR | SWT.HORIZONTAL);
		label_1.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));

		fSlider = new Slider(this, SWT.NONE);
		GridLayout gridLayout = (GridLayout) fSlider.getLayout();
		gridLayout.verticalSpacing = 0;
		gridLayout.marginWidth = 0;
		gridLayout.horizontalSpacing = 0;
		fSlider.setLayoutData(new GridData(SWT.FILL, SWT.BOTTOM, false, false, 1, 1));
		fContentStack.topControl = fBrowserComposite;
		fSlider.addTipProviderListener(this);

		loadWaitingScript();
	}

	private void showStartupOptions(final Menu menu) {
		Rectangle rect = fStartupItem.getBounds();
		Point pt = new Point(rect.x, rect.y + rect.height);
		pt = ftoolBar.toDisplay(pt);
		menu.setLocation(pt.x, pt.y);
		menu.setVisible(true);
	}

	private Image getStartupItemImage(int startup) {
		switch (startup) {
		case 1:
			return ResourceManager.getPluginImage("org.eclipse.tips.ui", "icons/lightbulb.png"); //$NON-NLS-1$ //$NON-NLS-2$
		case 2:
			return ResourceManager.getPluginImage("org.eclipse.tips.ui", "icons/stop.png"); //$NON-NLS-1$ //$NON-NLS-2$
		default:
			return ResourceManager.getPluginImage("org.eclipse.tips.ui", "icons/run_exc.png"); //$NON-NLS-1$ //$NON-NLS-2$
		}
	}

	private void startupMenuAboutToShow(final Menu menu) {
		Arrays.asList(menu.getItems()).forEach(item -> item.dispose());

		MenuItem item0 = new MenuItem(menu, SWT.CHECK);
		item0.setText(Messages.TipComposite_1);
		item0.setSelection(fTipManager.getStartupBehavior() == TipManager.START_DIALOG);
		item0.addListener(SWT.Selection, event -> fTipManager.setStartupBehavior(TipManager.START_DIALOG));
		item0.setImage(getStartupItemImage(TipManager.START_DIALOG));

		MenuItem item1 = new MenuItem(menu, SWT.CHECK);
		item1.setText(Messages.TipComposite_5);
		item1.setSelection(fTipManager.getStartupBehavior() == TipManager.START_BACKGROUND);
		item1.addListener(SWT.Selection, event -> fTipManager.setStartupBehavior(TipManager.START_BACKGROUND));
		item1.setImage(getStartupItemImage(TipManager.START_BACKGROUND));

		MenuItem item2 = new MenuItem(menu, SWT.CHECK);
		item2.setText(Messages.TipComposite_6);
		item2.setSelection(fTipManager.getStartupBehavior() == TipManager.START_DISABLE);
		item2.addListener(SWT.Selection, event -> fTipManager.setStartupBehavior(TipManager.START_DISABLE));
		item2.setImage(getStartupItemImage(TipManager.START_DISABLE));
	}

	private void showActionMenu() {
		Rectangle rect = fMultiActionButton.getBounds();
		Point pt = new Point(rect.x - 1, rect.y + rect.height);
		pt = fMultiActionButton.toDisplay(pt);
		fActionMenu.setLocation(pt.x, pt.y);
		fActionMenu.setVisible(true);
	}

	private void runTipAction(TipAction tipAction) {
		Job job = new Job(MessageFormat.format(Messages.TipComposite_10, tipAction.getTooltip())) {
			@Override
			protected IStatus run(IProgressMonitor monitor) {
				try {
					tipAction.getRunner().run();
				} catch (Exception e) {
					IStatus status = LogUtil.error(getClass(), e);
					fTipManager.log(status);
					return status;
				}
				return Status.OK_STATUS;
			}
		};
		job.setUser(true);
		job.schedule();
	}

	/**
	 * Sets the selected provider.
	 *
	 * @param provider the {@link TipProvider}
	 */
	public void setProvider(TipProvider provider) {
		fProvider = provider;
		fSlider.setTipProvider(provider);
		getCurrentTip();
	}

	/**
	 * Schedules a TimerTask that is executed after {@value #READ_TIMER}
	 * milliseconds after which the tip is marked as read.
	 */
	private void hitTimer() {
		Tip timerTip = fCurrentTip;
		Timer timer = new Timer(Messages.TipComposite_11);
		timer.schedule(new TimerTask() {
			@Override
			public void run() {
				if (timerTip == fCurrentTip) {
					fTipManager.setAsRead(timerTip);
					fSlider.updateButtons();
				}
				timer.cancel();
			}
		}, READ_TIMER);
	}

	private void getPreviousTip() {
		processTip(fProvider.getPreviousTip());
	}

	private void getNextTip() {
		if (fProvider.getTips().isEmpty() && !fTipManager.getProviders().isEmpty()) {
			fProvider.getNextTip(); // advance current tip
			for (TipProvider provider : fTipManager.getProviders()) {
				if (!provider.getTips().isEmpty()) {
					setProvider(provider);
					break;
				}
			}
		}
		processTip(fProvider.getNextTip());
	}

	private void getCurrentTip() {
		processTip(fProvider.getCurrentTip());
	}

	private void processTip(Tip tip) {
		fCurrentTip = tip;
		hitTimer();
		enableActionButtons(tip);
		prepareForHTML();
		loadContent(tip);
	}

	private void loadContent(Tip tip) {
		disposeBrowserFunctions();
		if (tip instanceof ISwtTip) {
			loadContentSWT(tip);
		} else if (tip instanceof IHtmlTip) {
			loadContentHtml((IHtmlTip) tip);
			applyBrowserFunctions(tip);
		} else if (tip instanceof IUrlTip) {
			loadContentUrl((IUrlTip) tip);
			applyBrowserFunctions(tip);
		} else {
			fTipManager.log(LogUtil.error(getClass(), Messages.TipComposite_12 + tip));
		}

		fContentComposite.requestLayout();
	}

	private void applyBrowserFunctions(Tip tip) {
		if (tip instanceof IBrowserFunctionProvider) {
			((IBrowserFunctionProvider) tip).getBrowserFunctions()
					.forEach((name, function) -> fBrowserFunctions.add(createBrowserFunction(name, function)));
		}
	}

	private BrowserFunction createBrowserFunction(String functionName, Function<Object[], Object> function) {
		return new BrowserFunction(getBrowser(), functionName) {
			@Override
			public Object function(Object[] arguments) {
				return function.apply(arguments);
			}
		};
	}

	private void loadContentHtml(IHtmlTip tip) {
		fBrowser.setText(getHTML(tip).trim());
	}

	private void loadContentUrl(IUrlTip tip) {
		try {
			String url = FileLocator.resolve(new URL(tip.getURL())).toString();
			fBrowser.setUrl(url);
		} catch (IOException e) {
			fTipManager.log(LogUtil.error(getClass(), e));
		}
	}

	private void loadContentSWT(Tip tip) {
		for (Control control : fSWTComposite.getChildren()) {
			control.dispose();
		}
		fContentStack.topControl = fSWTComposite;
		((ISwtTip) tip).createControl(fSWTComposite);
		fSWTComposite.requestLayout();
	}

	private void prepareForHTML() {
		fContentStack.topControl = fBrowserComposite;
		loadTimeOutScript();

		fBrowserComposite.requestLayout();
	}

	private void disposeBrowserFunctions() {
		fBrowserFunctions.forEach(BrowserFunction::dispose);
		fBrowserFunctions.clear();
	}

	/**
	 * Sets content in the browser that displays a message after 1500ms if the Tip
	 * could not load fast enough.
	 */
	private void loadTimeOutScript() {
		fBrowser.setText(getLoadingScript(500));
		while (!isDisposed()) {
			if (!getDisplay().readAndDispatch()) {
				break;
			}
		}
	}

	/**
	 * Sets content in the browser that displays a message after 1500ms if tips
	 * could not be loaded.
	 */
	private void loadWaitingScript() {
		fBrowser.setText(getWaitingScript(1500));
		while (!isDisposed()) {
			if (!getDisplay().readAndDispatch()) {
				break;
			}
		}
	}

	/**
	 * Get the timeout script in case the tips are not loading.
	 *
	 * @param timeout the timeout in milliseconds
	 * @return the script
	 */
	private static String getWaitingScript(int timeout) {
		return "<style>div{height: 90vh;display: flex;justify-content: center;align-items: center;}</style>" //$NON-NLS-1$
				+ "<div id=\"txt\"></div>" //$NON-NLS-1$
				+ "<script>var wss=function(){document.getElementById(\"txt\").innerHTML=\"" //$NON-NLS-1$
				+ Messages.TipComposite_14 //
				+ "\"};window.setTimeout(wss," //$NON-NLS-1$
				+ timeout //
				+ ");</script>"; //$NON-NLS-1$
	}

	private void enableActionButtons(Tip tip) {
		disposeActionImages();
		if (tip.getActions().isEmpty()) {
			fActionStack.topControl = fEmptyActionComposite;
		} else if (tip.getActions().size() == 1) {
			TipAction action = tip.getActions().get(0);
			fActionStack.topControl = fSingleActionComposite;
			fSingleActionButton.setImage(getActionImage(action.getTipImage()));
			fSingleActionButton.setText(action.getText());
			fSingleActionButton.setToolTipText(action.getTooltip());
		} else {
			TipAction action = tip.getActions().get(0);
			fActionStack.topControl = fMultiActionComposite;
			fMultiActionButton.setImage(getActionImage(tip.getActions().get(0).getTipImage()));
			fMultiActionButton.setText(action.getText());
			fMultiActionButton.setToolTipText(action.getTooltip());
			loadActionMenu(tip);
		}
		fEmptyActionComposite.getParent().requestLayout();
		fNavigationBar.requestLayout();
	}

	private void disposeActionImages() {
		fActionImages.forEach(img -> img.dispose());
	}

	private void loadActionMenu(Tip pTip) {
		if (fActionMenu != null) {
			fActionMenu.dispose();
		}
		fActionMenu = new Menu(fContentComposite.getShell(), SWT.POP_UP);
		pTip.getActions().subList(1, pTip.getActions().size()).forEach(action -> {
			MenuItem item = new MenuItem(fActionMenu, SWT.PUSH);
			item.setText(action.getText());
			item.setToolTipText(action.getTooltip());
			item.setText(action.getText());
			item.setImage(getActionImage(action.getTipImage()));
			item.addListener(SWT.Selection, e -> runTipAction(action));
		});
	}

	private Image getActionImage(TipImage tipImage) {
		if (tipImage == null) {
			return null;
		}
		try {
			Image image = new Image(getDisplay(), ImageUtil.decodeToImage(tipImage.getBase64Image()));
			if (image != null) {
				fActionImages.add(image);
				return image;
			}
		} catch (IOException e) {
			fTipManager.log(LogUtil.error(getClass(), e));
		}
		return null;
	}

	/**
	 * Get the timeout script in case a tip takes time to load.
	 *
	 * @param timeout the timeout in milliseconds
	 * @return the script
	 */
	private static String getLoadingScript(int timeout) {
		return "<style>div{position:fixed;top:50%;left:40%}</style>" //$NON-NLS-1$
				+ "<div id=\"txt\"></div>" //$NON-NLS-1$
				+ "<script>var wss=function(){document.getElementById(\"txt\").innerHTML=\"" //$NON-NLS-1$
				+ Messages.TipComposite_0 //
				+ "\"};window.setTimeout(wss," //$NON-NLS-1$
				+ timeout //
				+ ");</script>"; //$NON-NLS-1$
	}

	private String getHTML(IHtmlTip tip) {
		String encodedImage = encodeImage(tip);
		return tip.getHTML() + encodedImage;
	}

	private String encodeImage(IHtmlTip tip) {
		TipImage image = tip.getImage();
		if (image == null) {
			return EMPTY;
		}
		return encodeImageFromBase64(image);
	}

	private String encodeImageFromBase64(TipImage image) {
		int width = fBrowser.getClientArea().width;
		int height = Math.min(fBrowser.getClientArea().height / 2, (2 * (width / 3)));
		String attributes = image.getIMGAttributes(width, height).trim();
		String encoded = EMPTY + "<center> <img " // //$NON-NLS-1$
				+ attributes //
				+ " src=\"" // //$NON-NLS-1$
				+ image.getBase64Image() //
				+ "\"></center><br/>"; //$NON-NLS-1$
		return encoded;
	}

	@Override
	protected void checkSubclass() {
	}

	/**
	 * @return the {@link Browser} widget
	 */
	public Browser getBrowser() {
		return fBrowser;
	}

	/**
	 * @return the {@link Slider} widget
	 */
	public Slider getSlider() {
		return fSlider;
	}

	@Override
	public void selected(TipProvider provider) {
		setProvider(provider);
	}

	/**
	 * Sets the {@link TipManager}
	 *
	 * @param tipManager the {@link TipManager} that opened the dialog.
	 */
	public void setTipManager(TipManager tipManager) {
		fTipManager = tipManager;

		getDisplay().syncExec(() -> {
			fSlider.setTipManager(fTipManager);
			fUnreadOnly.setSelection(!fTipManager.mustServeReadTips());
			fPreviousTipButton.setEnabled(fTipManager.mustServeReadTips());
		});
	}

	@Override
	public void dispose() {
		disposeActionImages();
		super.dispose();
	}
}