/*=============================================================================#
 # Copyright (c) 2009, 2021 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.rj.eclient.graphics;

import static org.eclipse.statet.ecommons.ui.actions.UIActions.ADDITIONS_GROUP_ID;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.eclipse.core.commands.AbstractHandler;
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.commands.IHandler2;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.resource.ImageRegistry;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.ui.IActionBars;
import org.eclipse.ui.menus.CommandContributionItemParameter;
import org.eclipse.ui.services.IServiceLocator;

import org.eclipse.statet.jcommons.collections.CopyOnWriteIdentityListSet;
import org.eclipse.statet.jcommons.collections.ImIdentityList;
import org.eclipse.statet.jcommons.status.ProgressMonitor;
import org.eclipse.statet.jcommons.status.Status;
import org.eclipse.statet.jcommons.status.StatusException;
import org.eclipse.statet.jcommons.ts.core.SystemRunnable;
import org.eclipse.statet.jcommons.ts.core.Tool;

import org.eclipse.statet.ecommons.ui.SharedUIResources;
import org.eclipse.statet.ecommons.ui.actions.HandlerCollection;
import org.eclipse.statet.ecommons.ui.actions.HandlerContributionItem;

import org.eclipse.statet.internal.rj.eclient.graphics.RGraphicsPlugin;
import org.eclipse.statet.rj.eclient.graphics.util.AbstractLocalLocator;
import org.eclipse.statet.rj.ts.core.AbstractRToolRunnable;
import org.eclipse.statet.rj.ts.core.RToolService;


/**
 * Actions for R graphics in an {@link RGraphicComposite}.
 */
public class RGraphicCompositeActionSet implements ERGraphic.ListenerLocatorExtension {
	
	
	public static final String POSITION_STATUSLINE_ITEM_ID= "position"; //$NON-NLS-1$
	
	public static final String CONTEXT_MENU_GROUP_ID= "context"; //$NON-NLS-1$
	public static final String SIZE_MENU_GROUP_ID= "size"; //$NON-NLS-1$
	
	private static final String LOCATOR_DONE_COMMAND_ID= ".locator.done"; //$NON-NLS-1$
	private static final String LOCATOR_CANCEL_COMMAND_ID= ".locator.cancel"; //$NON-NLS-1$
	private static final String RESIZE_FIT_COMMAND_ID= ".resize.fit"; //$NON-NLS-1$
	
	
	public static interface LocationListener {
		
		void loading();
		
		void located(double x, double y);
		
	}
	
	
	private class ResizeFitRHandler extends AbstractHandler {
		
		public ResizeFitRHandler() {
		}
		
		@Override
		public void setEnabled(final Object evaluationContext) {
			setBaseEnabled(RGraphicCompositeActionSet.this.graphic != null);
		}
		
		@Override
		public Object execute(final ExecutionEvent event) throws ExecutionException {
			if (RGraphicCompositeActionSet.this.graphic == null) {
				return null;
			}
			final double[] size= RGraphicCompositeActionSet.this.graphicComposite.getGraphicFitSize();
			final Status status= RGraphicCompositeActionSet.this.graphic.resize(size[0], size[1]);
			if (status == null || status.getSeverity() != Status.OK) {
				// TODO: Status message
				Display.getCurrent().beep();
			}
			return null;
		}
		
	}
	
	protected class StopLocatorHandler extends AbstractHandler {
		
		private final String type;
		
		public StopLocatorHandler(final String type) {
			this.type= type;
		}
		
		@Override
		public void setEnabled(final Object evaluationContext) {
			setBaseEnabled(RGraphicCompositeActionSet.this.graphic != null && RGraphicCompositeActionSet.this.graphic.isLocatorStarted()
					&& RGraphicCompositeActionSet.this.graphic.getLocatorStopTypes().contains(this.type) );
		}
		
		@Override
		public Object execute(final ExecutionEvent event) throws ExecutionException {
			if (RGraphicCompositeActionSet.this.graphic == null) {
				return null;
			}
			RGraphicCompositeActionSet.this.graphic.stopLocator(this.type);
			return null;
		}
		
	}
	
	private static abstract class ConversionRunnable extends AbstractRToolRunnable implements SystemRunnable {
		
		private final ERGraphic graphic;
		
		private boolean scheduled;
		
		private double[] todoSource;
		
		private double[] convertedSource;
		private double[] convertedTarget;
		
		
		public ConversionRunnable(final ERGraphic graphic) {
			super("r/rjgd/position", "Converting graphic coordinates"); //$NON-NLS-1$
			this.graphic= graphic;
		}
		
		
		public boolean schedule(final double[] source) {
			synchronized (this) {
				this.todoSource= source;
				if (this.scheduled) {
					return true;
				}
				final Status status= this.graphic.getRHandle().getQueue().addHot(this);
				if (status.getSeverity() == Status.OK) {
					this.scheduled= true;
					return true;
				}
				return false;
			}
		}
		
		public void cancel() {
			synchronized (this) {
				if (this.scheduled) {
					this.scheduled= false;
					this.todoSource= null;
					this.graphic.getRHandle().getQueue().removeHot(this);
				}
			}
		}
		
		
		@Override
		public boolean canRunIn(final Tool tool) {
			return (tool == this.graphic.getRHandle() && super.canRunIn(tool));
		}
		
		@Override
		public boolean changed(final int event, final Tool tool) {
			switch (event) {
			case MOVING_FROM:
				return false;
			case REMOVING_FROM:
			case BEING_ABANDONED:
			case FINISHING_ERROR:
			case FINISHING_CANCEL:
				synchronized (this) {
					this.scheduled= false;
					break;
				}
			case FINISHING_OK:
				converted(this.graphic, this.convertedSource, this.convertedTarget);
				break;
			}
			return true;
		}
		
		@Override
		protected void run(final RToolService service,
				final ProgressMonitor m) throws StatusException {
			double[] source= null;
			double[] target= null;
			while (true) {
				synchronized (this) {
					this.convertedSource= source;
					this.convertedTarget= target;
					
					source= this.todoSource;
					if (source == null) {
						this.scheduled= false;
						return;
					}
					this.todoSource= null;
				}
				target= this.graphic.convertGraphic2User(source, m);
			}
		}
		
		protected abstract void converted(ERGraphic graphic, double[] source, double[] target);
		
	}
	
	private class MouseLocationListener implements Listener {
		
		private double[] currentGraphic;
		private double[] currentTarget;
		
		
		@Override
		public void handleEvent(final Event event) {
			switch (event.type) {
			case SWT.MouseDown:
				if (event.button == 1) {
					final double[] request= this.currentGraphic= new double[] {
							RGraphicCompositeActionSet.this.graphicComposite.convertWidget2GraphicX(event.x),
							RGraphicCompositeActionSet.this.graphicComposite.convertWidget2GraphicY(event.y) };
					this.currentTarget= null;
					event.display.timerExec(1000, new Runnable() {
						@Override
						public void run() {
							if (MouseLocationListener.this.currentTarget == null && MouseLocationListener.this.currentGraphic == request
									&& !RGraphicCompositeActionSet.this.graphicComposite.isDisposed()) {
								notifyMouseLocationListeners(null);
							}
						}
					});
					if (RGraphicCompositeActionSet.this.mouseLocationRunnable == null) {
						RGraphicCompositeActionSet.this.mouseLocationRunnable= new ConversionRunnable(
								RGraphicCompositeActionSet.this.graphic) {
							@Override
							protected void converted(final ERGraphic graphic,
									final double[] source, final double[] target) {
								if (RGraphicCompositeActionSet.this.graphic == graphic) {
									RGraphicCompositeActionSet.this.display.asyncExec(new Runnable() {
										@Override
										public void run() {
											if (RGraphicCompositeActionSet.this.graphic == graphic
													&& source != null && target != null && MouseLocationListener.this.currentGraphic != null
													&& source[0] == MouseLocationListener.this.currentGraphic[0] && source[1] == MouseLocationListener.this.currentGraphic[1]) {
												MouseLocationListener.this.currentTarget= target;
												notifyMouseLocationListeners(target);
											}
										}
									});
								}
							}
						};
					}
					RGraphicCompositeActionSet.this.mouseLocationRunnable.schedule(this.currentGraphic);
				}
				break;
			}
		}
		
	}
	
	
	private final List<IActionBars> actionBars= new ArrayList<>(4);
	
	private ERGraphic graphic;
	private final RGraphicComposite graphicComposite;
	private final Display display;
	
	private HandlerCollection handlerCollection;
	
	private final CopyOnWriteIdentityListSet<LocationListener> mouseLocationListeners= new CopyOnWriteIdentityListSet<>();
	private MouseLocationListener mouseListenerListener;
	private ConversionRunnable mouseLocationRunnable;
	
	
	public RGraphicCompositeActionSet(final RGraphicComposite composite) {
		this.graphicComposite= composite;
		this.display= this.graphicComposite.getDisplay();
	}
	
	
	public void setGraphic(final ERGraphic graphic) {
		if (this.graphic != null) {
			this.graphic.removeListener(this);
			if (this.mouseLocationRunnable != null) {
				this.mouseLocationRunnable.cancel();
				this.mouseLocationRunnable= null;
			}
		}
		this.graphic= graphic;
		if (this.graphic != null) {
			this.graphic.addListener(this);
		}
		
		update();
	}
	
	public void initActions(final IServiceLocator serviceLocator) {
		this.handlerCollection= new HandlerCollection();
		this.handlerCollection.add(LOCATOR_DONE_COMMAND_ID,
				new StopLocatorHandler(ERGraphic.LOCATOR_DONE) );
		this.handlerCollection.add(LOCATOR_CANCEL_COMMAND_ID,
				new StopLocatorHandler(ERGraphic.LOCATOR_CANCEL) );
		this.handlerCollection.add(RESIZE_FIT_COMMAND_ID,
				new ResizeFitRHandler() );
	}
	
	public void contributeToActionsBars(final IServiceLocator serviceLocator,
			final IActionBars actionBars) {
		this.actionBars.add(actionBars);
		
		final IToolBarManager toolBar= actionBars.getToolBarManager();
		if (toolBar.find(CONTEXT_MENU_GROUP_ID) == null) {
			toolBar.insertBefore(ADDITIONS_GROUP_ID, new Separator(CONTEXT_MENU_GROUP_ID));
		}
		if (toolBar.find(SIZE_MENU_GROUP_ID) == null) {
			toolBar.insertBefore(ADDITIONS_GROUP_ID, new Separator(SIZE_MENU_GROUP_ID));
		}
		
		final ImageRegistry rGraphicsImageRegistry= RGraphicsPlugin.getInstance().getImageRegistry();
		
		toolBar.appendToGroup(CONTEXT_MENU_GROUP_ID, new HandlerContributionItem(new CommandContributionItemParameter(
				serviceLocator, null, HandlerContributionItem.NO_COMMAND_ID, null,
				rGraphicsImageRegistry.getDescriptor(RGraphicsPlugin.IMG_LOCTOOL_LOCATOR_DONE), null, null,
				"Stop Locator", null, null, HandlerContributionItem.STYLE_PUSH, null, true),
				this.handlerCollection.get(LOCATOR_DONE_COMMAND_ID) ));
		toolBar.appendToGroup(CONTEXT_MENU_GROUP_ID, new HandlerContributionItem(new CommandContributionItemParameter(
				serviceLocator, null, HandlerContributionItem.NO_COMMAND_ID, null,
				rGraphicsImageRegistry.getDescriptor(RGraphicsPlugin.IMG_LOCTOOL_LOCATOR_CANCEL), null, null,
				"Cancel Locator", null, null, HandlerContributionItem.STYLE_PUSH, null, true),
				this.handlerCollection.get(LOCATOR_CANCEL_COMMAND_ID) ));
	}
	
	protected void addTestLocator(final IServiceLocator serviceLocator, final IActionBars actionBars) {
		final IToolBarManager toolBar= actionBars.getToolBarManager();
		
		final IHandler2 handler= new AbstractHandler() {
			@Override
			public void setEnabled(final Object evaluationContext) {
				setBaseEnabled(RGraphicCompositeActionSet.this.graphic != null && !RGraphicCompositeActionSet.this.graphic.isLocatorStarted());
			}
			@Override
			public Object execute(final ExecutionEvent event) throws ExecutionException {
				if (RGraphicCompositeActionSet.this.graphic == null || RGraphicCompositeActionSet.this.graphic.isLocatorStarted()) {
					return null;
				}
				final AbstractLocalLocator locator= new AbstractLocalLocator(RGraphicCompositeActionSet.this.graphic) {
					@Override
					protected void finished(final List<double[]> graphic, final List<double[]> user) {
						final StringBuilder sb= new StringBuilder();
						for (int i= 0; i < user.size(); i++) {
							sb.append(Arrays.toString(user.get(i))).append("\n");
						}
						Display.getDefault().asyncExec(new Runnable() {
							@Override
							public void run() {
								MessageDialog.openInformation(null, "Locator Result",
										sb.toString());
							}
						});
					}
					@Override
					protected void canceled() {
					}
				};
				locator.start();
				return null;
			}
		};
		this.handlerCollection.add(".locator.startTest", handler);
		toolBar.appendToGroup(CONTEXT_MENU_GROUP_ID, new HandlerContributionItem(new CommandContributionItemParameter(
				serviceLocator, null, HandlerContributionItem.NO_COMMAND_ID, null,
				SharedUIResources.getImages().getDescriptor(SharedUIResources.LOCTOOL_SORT_SCORE_IMAGE_ID), null, null,
				"Test Locator", null, null, HandlerContributionItem.STYLE_PUSH, null, false),
				handler ));
	}
	
	protected void addSizeActions(final IServiceLocator serviceLocator, final IActionBars actionBars) {
		final IToolBarManager toolBar= actionBars.getToolBarManager();
		
		final ImageRegistry rGraphicsImageRegistry= RGraphicsPlugin.getInstance().getImageRegistry();
		
		toolBar.appendToGroup(SIZE_MENU_GROUP_ID, new HandlerContributionItem(new CommandContributionItemParameter(
				serviceLocator, null, HandlerContributionItem.NO_COMMAND_ID, null,
				rGraphicsImageRegistry.getDescriptor(RGraphicsPlugin.IMG_LOCTOOL_RESIZE_FIT_R), null, null,
				"Resize Fit in R", null, null, HandlerContributionItem.STYLE_PUSH, null, false ),
				this.handlerCollection.get(RESIZE_FIT_COMMAND_ID) ));
		
		update();
	}
	
	protected void update() {
		if (this.actionBars.isEmpty()) {
			return;
		}
		
		this.handlerCollection.update(null);
		
		for (final IActionBars actionBars : this.actionBars) {
			actionBars.getToolBarManager().update(true);
		}
	}
	
	
	@Override
	public void activated() {
	}
	
	@Override
	public void deactivated() {
	}
	
	@Override
	public void drawingStarted() {
	}
	
	@Override
	public void drawingStopped() {
	}
	
	@Override
	public void locatorStarted() {
		update();
	}
	
	@Override
	public void locatorStopped() {
		update();
	}
	
	
	public void addMouseClickLocationListener(final LocationListener listener) {
		this.mouseLocationListeners.add(listener);
		if (this.mouseListenerListener == null) {
			this.mouseListenerListener= new MouseLocationListener();
			final Control widget= this.graphicComposite.getGraphicWidget();
			widget.addListener(SWT.MouseDown, this.mouseListenerListener);
		}
	}
	
	public void removeMouseLocationListener(final LocationListener listener) {
		this.mouseLocationListeners.remove(listener);
	}
	
	private void notifyMouseLocationListeners(final double[] xy) {
		final ImIdentityList<LocationListener> listeners= this.mouseLocationListeners.toList();
		if (xy != null) {
			for (final LocationListener listener : listeners) {
				listener.located(xy[0], xy[1]);
			}
		}
		else {
			for (final LocationListener listener : listeners) {
				listener.loading();
			}
		}
	}
	
	
	public void dispose(final IActionBars actionBars) {
		this.actionBars.remove(actionBars);
	}
	
	public void dispose() {
		setGraphic(null);
	}
	
}
