/*=============================================================================#
 # Copyright (c) 2009, 2020 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.internal.rj.example.rcpdemo.views;

import static org.eclipse.statet.rj.eclient.graphics.RGraphicCompositeActionSet.CONTEXT_MENU_GROUP_ID;
import static org.eclipse.statet.rj.eclient.graphics.RGraphicCompositeActionSet.SIZE_MENU_GROUP_ID;

import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Point;
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.Label;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.IActionBars;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.part.ViewPart;
import org.eclipse.ui.services.IServiceLocator;

import org.eclipse.statet.jcommons.status.ProgressMonitor;
import org.eclipse.statet.jcommons.status.StatusException;
import org.eclipse.statet.jcommons.ts.core.ToolRunnable;

import org.eclipse.statet.internal.rj.example.rcpdemo.Activator;
import org.eclipse.statet.rj.eclient.graphics.ERGraphic;
import org.eclipse.statet.rj.eclient.graphics.RGraphicComposite;
import org.eclipse.statet.rj.eclient.graphics.RGraphicCompositeActionSet;
import org.eclipse.statet.rj.graphic.core.RGraphic;
import org.eclipse.statet.rj.services.RGraphicCreator;
import org.eclipse.statet.rj.ts.core.AbstractRToolRunnable;
import org.eclipse.statet.rj.ts.core.RToolService;


/** 
 * View for R plots using RJ graphic device (rj.gd) and SWT rendering.
 * 
 * Note: All field access occur in display thread.
 */
public class GraphDemoView extends ViewPart {
	
	
	public static final String VIEW_ID= "org.eclipse.statet.rj.example.rcpdemo.views.GraphDemo";
	
	
	private Text commandControl;
	
	private RGraphicComposite imageControl;
	
	private ERGraphic currentPlot;
	
	private RGraphicCompositeActionSet actionSet;
	
	
	public GraphDemoView() {
	}
	
	
	@Override
	public void createPartControl(final Composite parent) {
		final Composite composite= new Composite(parent, SWT.NONE);
		composite.setLayout(new GridLayout(3, false));
		
		final Label label= new Label(composite, SWT.LEFT);
		label.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false));
		label.setText("Graphic &command:");
		
		this.commandControl= new Text(composite, SWT.BORDER);
		this.commandControl.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
		
		final Button button= new Button(composite, SWT.PUSH);
		button.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false));
		button.setText("Run");
		button.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(final SelectionEvent e) {
				run();
			}
		});
		
		this.commandControl.setText("hist(rnorm(1e+07))");
		
		this.imageControl= new RGraphicComposite(composite, null);
		this.imageControl.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 3, 1));
		
		initActions(getViewSite());
		contributeToActionsBars(getViewSite(), getViewSite().getActionBars());
	}
	
	protected void initActions(final IServiceLocator serviceLocator) {
		this.actionSet= new RGraphicCompositeActionSet(this.imageControl) {
			@Override
			public void contributeToActionsBars(final IServiceLocator serviceLocator, final IActionBars actionBars) {
				super.contributeToActionsBars(serviceLocator, actionBars);
				
				addSizeActions(serviceLocator, actionBars);
				addTestLocator(serviceLocator, actionBars);
			}
		};
		this.actionSet.initActions(serviceLocator);
	}
	
	protected void contributeToActionsBars(final IServiceLocator serviceLocator,
			final IActionBars actionBars) {
		final IToolBarManager toolBar= actionBars.getToolBarManager();
		toolBar.add(new Separator("additions"));
		toolBar.insertBefore("additions", new Separator(CONTEXT_MENU_GROUP_ID));
		toolBar.insertBefore("additions", new Separator(SIZE_MENU_GROUP_ID));
		
		this.actionSet.contributeToActionsBars(serviceLocator, actionBars);
	}
	
	protected void setGraphic(final ERGraphic graphic) {
		this.imageControl.setGraphic(graphic);
		this.actionSet.setGraphic(graphic);
		
		if (this.currentPlot != null) {
			this.currentPlot.close();
			this.currentPlot= null;
		}
		this.currentPlot= graphic;
	}
	
	@Override
	public void dispose() {
		super.dispose();
		if (this.currentPlot != null) {
			this.currentPlot.close();
			this.currentPlot= null;
		}
	}
	
	@Override
	public void setFocus() {
		this.commandControl.setFocus();
	}
	
	private void run() {
		final Point size= this.imageControl.getSize();
		final String command= this.commandControl.getText();
		final ToolRunnable job= new AbstractRToolRunnable("r/demo/graphic", "Graphic Demo") {
			@Override
			protected void run(final RToolService r, final ProgressMonitor m) throws StatusException {
				m.beginTask("Creating graphic in R...", 100);
				
				final RGraphicCreator rGraphicCreator= r.createRGraphicCreator(0);
				rGraphicCreator.setSize(size.x, size.y);
				final RGraphic plot= rGraphicCreator.create(command, m);
				
				m.addWorked(90);
				
				if (plot instanceof ERGraphic) {
					final ERGraphic erPlot= (ERGraphic) plot;
					PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {
						@Override
						public void run() {
							if (GraphDemoView.this.imageControl.isDisposed()) {
								erPlot.close();
								return;
							}
							setGraphic(erPlot);
						}
					});
				}
				return;
			}
		};
		Activator.getInstance().getRServiManager().scheduleDemo(job);
	}
	
}
