/*=============================================================================#
 # Copyright (c) 2006, 2022 Stephan Wahlbrink and others.
 # 
 # This program and the accompanying materials are made available under the
 # terms of the Eclipse Public License 2.0 which is available at
 # https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
 # which is available at https://www.apache.org/licenses/LICENSE-2.0.
 # 
 # SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
 # 
 # Contributors:
 #     Stephan Wahlbrink <sw@wahlbrink.eu> - initial API and implementation
 #=============================================================================*/

package org.eclipse.statet.ecommons.ui.util;

import static org.eclipse.statet.jcommons.lang.NullDefaultLocation.PARAMETER;

import java.util.function.Supplier;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PlatformUI;

import org.eclipse.statet.jcommons.lang.NonNullByDefault;
import org.eclipse.statet.jcommons.lang.Nullable;


/**
 * Access to UI resources from other threads.
 */
@NonNullByDefault
public class UIAccess {
	
	/**
	 * Returns the display for this workbench.
	 * 
	 * @return a display.
	 */
	public static Display getDisplay() {
		return PlatformUI.getWorkbench().getDisplay();
	}
	
	/**
	 * Searches a appropriate display.
	 * <p>
	 * Order for search: display of specified shell, display for the workbench.
	 * 
	 * @param shell optional shell
	 * @return display
	 */
	public static Display getDisplay(final @Nullable Shell shell) {
		Display display= null;
		if (shell != null) {
			display= shell.getDisplay();
		}
		if (display == null) {
			display= getDisplay();
		}
		return display;
	}
	
	public static @Nullable IWorkbenchWindow getActiveWorkbenchWindow(final boolean inUIThread) {
		if (inUIThread) {
			return PlatformUI.getWorkbench().getActiveWorkbenchWindow();
		}
		final Display display= getDisplay();
		if (display.getThread() == Thread.currentThread()) {
			return PlatformUI.getWorkbench().getActiveWorkbenchWindow();
		}
		return display.syncCall(() -> PlatformUI.getWorkbench().getActiveWorkbenchWindow());
	}
	
	public static @Nullable IWorkbenchPage getActiveWorkbenchPage(final boolean inUIThread) {
		final IWorkbenchWindow window= getActiveWorkbenchWindow(inUIThread);
		if (window != null) {
			return window.getActivePage();
		}
		return null;
	}
	
	public static @Nullable IWorkbenchPart getActiveWorkbenchPart(final boolean inUIThread) {
		final IWorkbenchWindow window= getActiveWorkbenchWindow(inUIThread);
		if (window != null) {
			final IWorkbenchPage activePage= window.getActivePage();
			if (activePage != null) {
				return activePage.getActivePart();
			}
		}
		return null;
	}
	
	public static @Nullable Shell getActiveWorkbenchShell(final boolean inUIThread) {
		final IWorkbenchWindow window= getActiveWorkbenchWindow(inUIThread);
		if (window != null) {
			return window.getShell();
		}
		return null;
	}
	
	
	public static interface CheckedRunnable {
		
		public void run() throws CoreException;
	}
	
	public static void checkedSyncExec(final CheckedRunnable runnable, final Display display)
			throws CoreException {
		final var catchRunnable= new Runnable() {
			
			private volatile @Nullable CoreException error;
			
			@Override
			public void run() {
				try {
					runnable.run();
				}
				catch (final CoreException e) {
					this.error= e;
				}
			}
			
		};
		display.syncExec(catchRunnable);
		final var error= catchRunnable.error;
		if (error != null) {
			throw error;
		}
	}
	
	public static void checkedSyncExec(final CheckedRunnable runnable)
			throws CoreException {
		checkedSyncExec(runnable, getDisplay());
	}
	
	@NonNullByDefault({ PARAMETER })
	public static <T> T syncExecGet(final Supplier<T> getter, final Display display) {
		return display.syncCall(getter::get);
	}
	
	@NonNullByDefault({ PARAMETER })
	public static <T> T syncExecGet(final Supplier<T> getter) {
		return syncExecGet(getter, getDisplay());
	}
	
	
	/**
	 * Tests is the control is not <code>null</code> and not disposed.
	 */
	public static final boolean isOkToUse(final @Nullable Control control) {
		return (control != null) && (Display.getCurrent() != null)
				&& !control.isDisposed();
	}
	
	/**
	 * Tests is the viewer is not <code>null</code> and its control is not
	 * disposed.
	 */
	public static final boolean isOkToUse(final @Nullable Viewer viewer) {
		return (viewer != null && isOkToUse(viewer.getControl()));
	}
	
	
	private UIAccess() {
	}
	
}
