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

import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.Callable;

import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.preferences.IPreferencesService;
import org.eclipse.swt.SWT;
import org.eclipse.swt.SWTException;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.ImageData;
import org.eclipse.swt.graphics.PaletteData;
import org.eclipse.swt.graphics.Path;
import org.eclipse.swt.widgets.Display;

import org.eclipse.statet.jcommons.collections.CopyOnWriteIdentityListSet;
import org.eclipse.statet.jcommons.collections.ImCollections;
import org.eclipse.statet.jcommons.lang.Nullable;
import org.eclipse.statet.jcommons.runtime.CommonsRuntime;
import org.eclipse.statet.jcommons.status.ErrorStatus;
import org.eclipse.statet.jcommons.status.InfoStatus;
import org.eclipse.statet.jcommons.status.ProgressMonitor;
import org.eclipse.statet.jcommons.status.Status;
import org.eclipse.statet.jcommons.status.StatusChangeListener;
import org.eclipse.statet.jcommons.status.StatusException;
import org.eclipse.statet.jcommons.status.Statuses;

import org.eclipse.statet.ecommons.ui.util.UIAccess;

import org.eclipse.statet.internal.rj.eclient.graphics.FontManager.FontFamily;
import org.eclipse.statet.rj.eclient.graphics.DefaultGCRenderer;
import org.eclipse.statet.rj.eclient.graphics.ERGraphic;
import org.eclipse.statet.rj.eclient.graphics.ERGraphicInstruction;
import org.eclipse.statet.rj.eclient.graphics.LocatorCallback;
import org.eclipse.statet.rj.eclient.graphics.RGraphics;
import org.eclipse.statet.rj.eclient.graphics.comclient.ToolRClientGraphicActions;
import org.eclipse.statet.rj.graphic.core.RGraphicInitialization;
import org.eclipse.statet.rj.graphic.core.RGraphicInstruction;
import org.eclipse.statet.rj.graphic.core.util.CachedMapping;
import org.eclipse.statet.rj.graphic.core.util.CharMapping;
import org.eclipse.statet.rj.graphic.core.util.Unicode2AdbSymbolMapping;
import org.eclipse.statet.rj.server.client.RClientGraphic;
import org.eclipse.statet.rj.server.client.RClientGraphicFactory;
import org.eclipse.statet.rj.services.RService;
import org.eclipse.statet.rj.services.RServiceControlExtension;
import org.eclipse.statet.rj.ts.core.RTool;


/**
 * R graphic implementation of this plug-in. Implements R side API ({@link RClientGraphic})
 * as well as client side API ({@link IERGraphic}, {@link org.eclipse.statet.rj.graphic.core.RGraphic}).
 */
public class EclipseRGraphic implements RClientGraphic, ERGraphic {
	
	
	private static final CharMapping ADBSYMBOL_MAPPING= new CachedMapping(
			new Unicode2AdbSymbolMapping() );
	
	private static final long MILLI_NANOS= 1000000L;
	
	private static final int DIRECT_RED_MASK=   0x0000FF00;
	private static final int DIRECT_GREEN_MASK= 0x00FF0000;
	private static final int DIRECT_BLUE_MASK=  0xFF000000;
	private static final PaletteData DIRECT_PALETTE= new PaletteData(
			DIRECT_RED_MASK, DIRECT_GREEN_MASK, DIRECT_BLUE_MASK );
	
	private static final LocatorCallback R_LOCATOR_CALLBACK= new LocatorCallback() {
		
		@Override
		public String getMessage() {
			return "→ Locate a point by mouse click (request from R)";
		}
		
		@Override
		public int located(final double x, final double y) {
			return NEXT;
		}
		
		@Override
		public void stopped(final String type) {
		}
		
	};
	
	
	private static void disposeElements(final ERGraphicInstruction[] instructions,
			final int beginIdx, final int endIdx) {
		try {
			for (int i= beginIdx; i < endIdx; i++) {
				switch (instructions[i].getInstructionType()) {
				case RGraphicInstruction.DRAW_RASTER: {
					final Image image= ((RasterElement) instructions[i]).swtImage;
					if (image != null && !image.isDisposed()) {
						image.dispose();
					}
					continue; }
				case RGraphicInstruction.DRAW_PATH: {
					final Path path= ((PathElement) instructions[i]).swtPath;
					if (path != null && !path.isDisposed()) {
						path.dispose();
					}
					continue; }
				default:
					continue;
				}
			}
		}
		catch (final SWTException e) {
			if (e.code != SWT.ERROR_DEVICE_DISPOSED) {
				CommonsRuntime.log(new ErrorStatus(RGraphics.BUNDLE_ID,
						"An error occurred when disposing SWT resources.",
						e ));
			}
		}
	}
	
	private static class DisposeRunnable implements Runnable {
		
		private final ERGraphicInstruction[] instructions;
		private final int size;
		
		private boolean delay;
		
		public DisposeRunnable(final ERGraphicInstruction[] instructions, final int size) {
			this.instructions= instructions;
			this.size= size;
		}
		
		@Override
		public void run() {
			if (this.delay) {
				this.delay= false;
				Display.getCurrent().timerExec(5000, this);
			}
			
			disposeElements(this.instructions, 0, this.size);
		}
		
	}
	
	
	private final int devId;
	
	private int canvasColor;
	
	private int drawingStopDelay= 33; // ms after stop
	private int drawingForceDelay= 333; // ms after last update
	
	private final EclipseRGraphicFactory manager;
	private boolean isRClosed;
	private boolean isLocalClosed;
	
	private final Object stateLock= new Object();
	private boolean isActive;
	private boolean isActiveNotified;
	private int mode= 1;
	private int modeNotified;
	private long drawingStoppedStamp;
	private long instructionsNotifiedStamp;
	private boolean stateNotificationDirectScheduled;
	private boolean stateNotificationDelayedScheduled;
	private final Runnable stateNotificationRunnable= new Runnable() {
		@Override
		public void run() {
			int type= 0;
			Runnable runnable= null;
			try {
				while (true) {
					boolean reset= false;
					List<ERGraphicInstruction> update= null;
					synchronized (EclipseRGraphic.this.stateLock) {
						if (type == 0
								&& !EclipseRGraphic.this.stateNotificationDirectScheduled
								&& EclipseRGraphic.this.stateNotificationDelayedScheduled) {
							EclipseRGraphic.this.stateNotificationDirectScheduled= true;
							EclipseRGraphic.this.stateNotificationDelayedScheduled= false;
						}
						if (EclipseRGraphic.this.isActive != EclipseRGraphic.this.isActiveNotified) {
							EclipseRGraphic.this.isActiveNotified= EclipseRGraphic.this.isActive;
							type= (EclipseRGraphic.this.isActive) ? 1 : 2;
						}
						else if ((EclipseRGraphic.this.mode == 1 || EclipseRGraphic.this.instructionsUpdateSize > 0)
								&& EclipseRGraphic.this.modeNotified != 1 ) {
							// start
							EclipseRGraphic.this.modeNotified= 1;
							type= 3;
						}
						else if (EclipseRGraphic.this.instructionsUpdateSize > 0) {
							// update
							final long stamp= System.nanoTime();
							int t= EclipseRGraphic.this.drawingForceDelay - (int) ((stamp - EclipseRGraphic.this.instructionsNotifiedStamp) / MILLI_NANOS);
							if (t > 10 && EclipseRGraphic.this.mode != 1) {
								t= Math.min(t, EclipseRGraphic.this.drawingStopDelay - (int) ((stamp - EclipseRGraphic.this.drawingStoppedStamp) / MILLI_NANOS));
							}
							if (t <= 10) {
								reset= (EclipseRGraphic.this.instructionsUpdateStart == 0);
								
								synchronized (EclipseRGraphic.this.instructionsLock) {
									if (reset && EclipseRGraphic.this.instructionsSize > 0) {
										runnable= new DisposeRunnable(EclipseRGraphic.this.instructions, EclipseRGraphic.this.instructionsSize);
									}
									EclipseRGraphic.this.instructions= EclipseRGraphic.this.instructionsUpdate;
									EclipseRGraphic.this.instructionsSize= EclipseRGraphic.this.instructionsUpdateStart + EclipseRGraphic.this.instructionsUpdateSize;
								}
								update= ImCollections.newList(EclipseRGraphic.this.instructionsUpdate)
										.subList(EclipseRGraphic.this.instructionsUpdateStart, EclipseRGraphic.this.instructionsUpdateStart + EclipseRGraphic.this.instructionsUpdateSize);
//								System.out.println("InstrUpdate: \treset= " + reset + " \tcount= " + update.size() + " \ttdiff= " + ((stamp - this.instructionsNotifiedStamp) / MILLI_NANOS));
								EclipseRGraphic.this.instructionsUpdateStart= EclipseRGraphic.this.instructionsSize;
								EclipseRGraphic.this.instructionsUpdateSize= 0;
								EclipseRGraphic.this.instructionsNotifiedStamp= stamp;
								type= 5;
							}
							else {
								if (!EclipseRGraphic.this.stateNotificationDelayedScheduled) {
									EclipseRGraphic.this.stateNotificationDelayedScheduled= true;
									EclipseRGraphic.this.display.timerExec(10 + Math.min(t, EclipseRGraphic.this.drawingStopDelay), this);
								}
								EclipseRGraphic.this.stateNotificationDirectScheduled= false;
								type= 0;
								return;
							}
						}
						else if (EclipseRGraphic.this.mode != 1 && EclipseRGraphic.this.modeNotified == 1 ) {
							// stop
							final long stamp= System.nanoTime();
							final int t= EclipseRGraphic.this.drawingStopDelay - (int) ((stamp - EclipseRGraphic.this.drawingStoppedStamp) / MILLI_NANOS);
							if (t <= 10) {
								EclipseRGraphic.this.modeNotified= 0;
								type= 4;
							}
							else {
								if (!EclipseRGraphic.this.stateNotificationDelayedScheduled) {
									EclipseRGraphic.this.stateNotificationDelayedScheduled= true;
									EclipseRGraphic.this.display.timerExec(10 + t, this);
								}
								EclipseRGraphic.this.stateNotificationDirectScheduled= false;
								type= 0;
								return;
							}
						}
						else {
							// done
							EclipseRGraphic.this.stateNotificationDirectScheduled= false;
							type= 0;
							return;
						}
					}
					
					
					switch (type) {
					case 1:
						for (final Listener listener : EclipseRGraphic.this.graphicListeners.toList()) {
							listener.activated();
						}
						break;
					case 2:
						for (final Listener listener : EclipseRGraphic.this.graphicListeners.toList()) {
							listener.deactivated();
						}
						break;
					case 3:
						for (final Listener listener : EclipseRGraphic.this.graphicListeners.toList()) {
							listener.drawingStarted();
						}
						break;
					case 4:
						for (final Listener listener : EclipseRGraphic.this.graphicListeners.toList()) {
							listener.drawingStopped();
						}
						break;
					case 5:
						for (final Listener listener : EclipseRGraphic.this.graphicListeners.toList()) {
							if (listener instanceof ListenerInstructionsExtension) {
								((ListenerInstructionsExtension) listener).instructionsChanged(reset, update);
							}
						}
//						System.out.println("InstrNotif: ns= " + (System.nanoTime() - this.instructionsNotifiedStamp));
						break;
					}
				}
			}
			finally {
				if (type != 0) {
					synchronized (EclipseRGraphic.this.stateLock) {
						EclipseRGraphic.this.stateNotificationDirectScheduled= false;
					}
				}
				if (runnable != null) {
					execInDisplay(runnable);
				}
			}
		}
	};
	
	
	private final int options;
	private final ToolRClientGraphicActions actions;
	private volatile double[] nextSize;
	private double[] size;
	
	private FontFamily currentFontFamily;
	private int currentFontSize;
	private int currentFontStyle;
	private int currentFontRFace;
	private CharMapping currentFontMapping;
	
	private String lastStringEnc;
	private double[] lastStringWidth;
	
	private final Display display;
	private boolean isDisposed;
	private final FontManager swtFontManager;
	private final ColorManager swtColorManager;
	
	private String serifFontName;
	private String sansFontName;
	private String monoFontName;
	private String symbolFontName;
	private CharMapping symbolFontMapping;
	
	/** List of newly added instructions */
	private ERGraphicInstruction[] instructionsNew= new ERGraphicInstruction[1]; // initial init
	/** Count of newly added instructions in {@link #instructionsNew} */
	private int instructionsNewSize;
	/** Current list of instructions, notified + not yet notified */
	private ERGraphicInstruction[] instructionsUpdate;
	/** Index of first not yet notified instruction in {@link #instructionsUpdate} */
	private int instructionsUpdateStart;
	/** Count of not yet notified instructions in {@link #instructionsUpdate} */
	private int instructionsUpdateSize;
	/** Lock for {@link #instructions} and {@link #instructionsSize} */
	private final Object instructionsLock= new Object();
	/** List of notified instructions */
	private ERGraphicInstruction[] instructions;
	/** Count of notified instructions in {@link #instructions} */
	private int instructionsSize;
	
	private final Object userExchangeLock= new Object();
	private String userExchangeRType;
	private RServiceControlExtension userExchangeRCallback;
	
	private volatile LocatorCallback locatorCallback; // != null => started
	private LocatorCallback locatorNotified;
	private Status locatorMessage;
	private Collection<String> locatorStopTypes= Collections.emptySet();
	private double[] locatorLocationValue; // only used for R
	private final Object locatorAnswerLock= new Object(); // pipe for answers
	
	private final CopyOnWriteIdentityListSet<ERGraphic.Listener> graphicListeners= new CopyOnWriteIdentityListSet<>();
	
	private Status message= Statuses.OK_STATUS;
	private final CopyOnWriteIdentityListSet<StatusChangeListener> messageListeners= new CopyOnWriteIdentityListSet<>();
	
	private boolean locatorNotificationDirectScheduled;
	private boolean locatorNotificationDeferredScheduled;
	private long locatorDeferredStamp;
	private final Runnable locatorNotificationRunnable= new Runnable() {
		@Override
		public void run() {
			int type= 0;
			try {
				while (true) {
					synchronized (EclipseRGraphic.this.userExchangeLock) {
						if (type == 0
								&& !EclipseRGraphic.this.locatorNotificationDirectScheduled
								&& EclipseRGraphic.this.locatorNotificationDeferredScheduled) {
							EclipseRGraphic.this.locatorNotificationDirectScheduled= true;
							EclipseRGraphic.this.locatorNotificationDeferredScheduled= false;
						}
						if (EclipseRGraphic.this.locatorCallback != null && EclipseRGraphic.this.locatorNotified == null
								&& EclipseRGraphic.this.locatorDeferredStamp == Long.MIN_VALUE) {
							EclipseRGraphic.this.locatorNotified= EclipseRGraphic.this.locatorCallback;
							type= 1;
						}
						else if (EclipseRGraphic.this.locatorNotified != null
								&& (EclipseRGraphic.this.locatorCallback != EclipseRGraphic.this.locatorNotified || EclipseRGraphic.this.locatorCallback == null) ){
							EclipseRGraphic.this.locatorNotified= null;
							type= 2;
						}
						else if (EclipseRGraphic.this.locatorDeferredStamp != Long.MIN_VALUE
								&& EclipseRGraphic.this.locatorCallback != null) {
							final int t= (int) ((EclipseRGraphic.this.locatorDeferredStamp - System.nanoTime()) / 1000000);
							if (t <= 10) {
								internalStopLocator(false);
								type= 3;
								continue;
							}
							else {
								if (!EclipseRGraphic.this.locatorNotificationDeferredScheduled) {
									EclipseRGraphic.this.locatorNotificationDeferredScheduled= true;
									EclipseRGraphic.this.display.timerExec(t + 10, this);
								}
								EclipseRGraphic.this.locatorNotificationDirectScheduled= false;
								type= 0;
								return;
							}
						}
						else {
							EclipseRGraphic.this.locatorNotificationDirectScheduled= false;
							type= 0;
							return;
						}
					}
					
					switch (type) {
					case 1:
						for (final Listener listener : EclipseRGraphic.this.graphicListeners.toList()) {
							if (listener instanceof ListenerLocatorExtension) {
								((ListenerLocatorExtension) listener).locatorStarted();
							}
						}
						break;
					case 2:
						for (final Listener listener : EclipseRGraphic.this.graphicListeners.toList()) {
							if (listener instanceof ListenerLocatorExtension) {	
								((ListenerLocatorExtension) listener).locatorStopped();
							}
						}
						break;
					}
					updateMessage();
				}
			}
			finally {
				if (type != 0) {
					synchronized (EclipseRGraphic.this.userExchangeLock) {
						EclipseRGraphic.this.locatorNotificationDirectScheduled= false;
					}
				}
			}
		}
	};
	
	
	public EclipseRGraphic(final int devId, final double w, final double h, final InitConfig config,
			final boolean active, final ToolRClientGraphicActions actions, final int options,
			final EclipseRGraphicFactory manager) {
		this.devId= devId;
		this.isActive= active;
		this.actions= actions;
		this.manager= manager;
		this.options= options;
		
		this.display= UIAccess.getDisplay();
		this.swtFontManager= manager.getFontManager(this.display);
//		this.swtFontManager= new FontManager(this.display); // -> dispose!
		this.swtColorManager= manager.getColorManager(this.display);
		
		this.size= this.nextSize= new double[] { w, h };
		initPanel(w, h, config);
	}
	
	
	@Override
	public String getLabel() {
		final StringBuilder sb= new StringBuilder();
		sb.append("Device ");
		sb.append(this.devId + 1);
		if (this.actions != null) {
			final String rLabel= this.actions.getRLabel();
			if (rLabel != null && rLabel.length() > 0) {
				sb.append(" │ ");
				sb.append(rLabel);
			}
		}
		final boolean locator= isLocatorStarted();
		if (this.isActive || locator) {
			sb.append(" \t<"); //$NON-NLS-1$
			if (this.isActive) {
				sb.append("active+"); //$NON-NLS-1$
			}
			if (locator) {
				sb.append("locator+"); //$NON-NLS-1$
			}
			sb.replace(sb.length()-1, sb.length(), ">"); //$NON-NLS-1$
		}
		return sb.toString();
	}
	
	private void add(final ERGraphicInstruction instr) {
		// adding is always in R thread
		if (this.instructionsNew == null) {
			this.instructionsNew= new ERGraphicInstruction[512];
		}
		else if (this.instructionsNewSize >= this.instructionsNew.length) {
			final ERGraphicInstruction[] newArray= new ERGraphicInstruction[this.instructionsNewSize + 512];
//			System.out.println("NewArray " + this.instructionsNewSize + " -> " + newArray.length);
			System.arraycopy(this.instructionsNew, 0, newArray, 0, this.instructionsNewSize);
			this.instructionsNew= newArray;
		}
		this.instructionsNew[this.instructionsNewSize]= instr;
		this.instructionsNewSize++;
	}
	
	protected void initPanel(final double w, final double h, final InitConfig config) {
		this.drawingStopDelay= 33;
		this.drawingForceDelay= 333;
		
		this.currentFontFamily= null;
		this.currentFontMapping= null;
		
		final IPreferencesService preferences= Platform.getPreferencesService();
		this.serifFontName= preferences.getString(RGraphics.FONTS_PREF_QUALIFIER, RGraphics.PREF_FONTS_SERIF_FONTNAME_KEY, "", null);
		this.sansFontName= preferences.getString(RGraphics.FONTS_PREF_QUALIFIER, RGraphics.PREF_FONTS_SANS_FONTNAME_KEY, "", null);
		this.monoFontName= preferences.getString(RGraphics.FONTS_PREF_QUALIFIER, RGraphics.PREF_FONTS_MONO_FONTNAME_KEY, "", null);
		if (preferences.getBoolean(RGraphics.FONTS_PREF_QUALIFIER, RGraphics.PREF_FONTS_SYMBOL_USE_KEY, true, null)) {
			this.symbolFontName= preferences.getString(RGraphics.FONTS_PREF_QUALIFIER, RGraphics.PREF_FONTS_SYMBOL_FONTNAME_KEY, "Symbol", null); //$NON-NLS-1$
			final String encoding= preferences.getString(RGraphics.FONTS_PREF_QUALIFIER, RGraphics.PREF_FONTS_SYMBOL_ENCODING_KEY, "AdobeSymbol", null); //$NON-NLS-1$
			if ("AdobeSymbol".equals(encoding)) { //$NON-NLS-1$
				this.symbolFontMapping= ADBSYMBOL_MAPPING;
			}
			else {
				this.symbolFontMapping= null;
			}
		}
		else {
			this.symbolFontName= null;
			this.symbolFontMapping= null;
		}
		this.canvasColor= (config.canvasColor & 0xffffff);
		
		add(new GraphicInitialization(w, h, this.canvasColor, this.swtColorManager.getColor(this.canvasColor)));
	}
	
	@Override
	public void reset(final double w, final double h, final InitConfig config) {
		synchronized (this.stateLock) {
			internalReset();
		}
		
		initPanel(w, h, config);
	}
	
	private void internalReset() {
		if (this.instructionsNew != null) {
			if (this.instructionsNewSize > 0) {
				disposeElements(this.instructionsNew, 0, this.instructionsNewSize);
			}
			this.instructionsNew= null;
			this.instructionsNewSize= 0;
		}
		if (this.instructionsUpdate != null) {
			if (this.instructionsUpdateSize > 0) {
				disposeElements(this.instructionsUpdate, this.instructionsUpdateStart, this.instructionsUpdateStart+this.instructionsUpdateSize);
			}
			this.instructionsUpdate= null;
			this.instructionsUpdateStart= 0;
			this.instructionsUpdateSize= 0;
		}
		this.drawingStoppedStamp= System.nanoTime();
		this.instructionsNotifiedStamp= this.drawingStoppedStamp - 1000 * MILLI_NANOS;
	}
	
	private void execInDisplay(final Runnable runnable) {
		try {
			this.display.asyncExec(runnable);
		}
		catch (final SWTException e) {
			if (e.code != SWT.ERROR_DEVICE_DISPOSED) {
				throw e;
			}
		}
	}
	
	@Override
	public int getDevId() {
		return this.devId;
	}
	
	@Override
	public void setActive(final boolean active) {
		if (this.isActive == active) {
			return;
		}
		synchronized (this.stateLock) {
			this.isActive= active;
			if (this.isDisposed) {
				return;
			}
			if (!this.stateNotificationDirectScheduled) {
				this.stateNotificationDirectScheduled= true;
				execInDisplay(this.stateNotificationRunnable);
			}
		}
	}
	
	@Override
	public boolean isActive() {
		return this.isActive;
	}
	
	@Override
	public void setMode(final int mode) {
		synchronized (this.stateLock) {
			if (this.mode == mode) {
				return;
			}
			if (mode != 1) {
				this.drawingStoppedStamp= System.nanoTime();
				flushNewInstructions();
			}
			this.mode= mode;
			if (this.isDisposed) {
				return;
			}
			if (mode == 1 && this.modeNotified != 1 // need start
					&& !this.stateNotificationDirectScheduled ) {
				this.stateNotificationDirectScheduled= true;
				execInDisplay(this.stateNotificationRunnable);
			}
			else if (mode != 1 // stop
					&& !(this.stateNotificationDirectScheduled || this.stateNotificationDelayedScheduled) ) {
				this.stateNotificationDirectScheduled= true;
				execInDisplay(this.stateNotificationRunnable);
			}
		}
	}
	
	private void flushNewInstructions() {
		if (this.instructionsNewSize > 0) {
			if (this.instructionsUpdate == null) {
				this.instructionsUpdate= this.instructionsNew;
				this.instructionsUpdateStart= 0;
				this.instructionsUpdateSize= this.instructionsNewSize;
				this.instructionsNew= null;
				this.instructionsNewSize= 0;
			}
			else {
				final int newSize= this.instructionsUpdateStart + this.instructionsUpdateSize + this.instructionsNewSize;
				if (newSize > this.instructionsUpdate.length) {
					final ERGraphicInstruction[] newArray= new ERGraphicInstruction[newSize + 512];
					System.arraycopy(this.instructionsUpdate, 0, newArray, 0, this.instructionsUpdateStart + this.instructionsUpdateSize);
					this.instructionsUpdate= newArray;
				}
				System.arraycopy(this.instructionsNew, 0, this.instructionsUpdate, this.instructionsUpdateStart + this.instructionsUpdateSize, this.instructionsNewSize);
				this.instructionsUpdateSize+= this.instructionsNewSize;
				this.instructionsNewSize= 0;
			}
		}
	}
	
	private List<ERGraphicInstruction> getCurrentInstructions() {
		synchronized (this.stateLock) {
			flushNewInstructions();
			return ImCollections.newList(this.instructionsUpdate).subList(0,
					this.instructionsSize + this.instructionsUpdateSize );
		}
	}
	
	@Override
	public double[] computeSize() {
		return this.size;
	}
	
	
	protected void printFont() {
		System.out.println(this.currentFontFamily.name + " " + this.currentFontStyle + " " + this.currentFontSize);
	}
	
	@Override
	public double[] computeFontMetric(final int ch) {
//		System.out.println("==\nTextMetrics: \"" + ((char) ch) + "\" (" + ch + ")"); printFont();
		return this.currentFontFamily.getCharMetrics(this.currentFontStyle, this.currentFontSize,
				(this.currentFontMapping != null) ? this.currentFontMapping.encode(ch) : ch );
	}
	
	@Override
	public double[] computeStringWidth(final String txt) {
//		System.out.println("==\nTextWidth: \"" + txt + "\""); printFont();
		return computeStringWidthEnc((this.currentFontMapping != null) ? this.currentFontMapping.encode(txt) : txt);
	}
	
	protected final double[] computeStringWidthEnc(final String text) {
		if (text.equals(this.lastStringEnc)) {
			return this.lastStringWidth;
		}
		
		final double[] answer= this.currentFontFamily.getStringWidth(this.currentFontStyle, this.currentFontSize, text);
		
		this.lastStringEnc= text;
		return (this.lastStringWidth= answer);
	}
	
	
	@Override
	public void addSetClip(final double x0, final double y0, final double x1, final double y1) {
		final ClipSetting instr= new ClipSetting(x0, y0, x1, y1);
		add(instr);
	}
	
	@Override
	public void addSetColor(final int color) {
		final ColorSetting instr= new ColorSetting(color,
				this.swtColorManager.getColor((color & 0xffffff)) );
		add(instr);
	}
	
	@Override
	public void addSetFill(final int color) {
		final FillSetting instr= new FillSetting(color,
				this.swtColorManager.getColor((color & 0xffffff)) );
		add(instr);
	}
	
	@Override
	public void addSetFont(String family, final int face, final float pointSize,
			final float lineHeight) {
//		System.out.println("==\nSetFont: \"" + family + "\" " + face + " " + pointSize);
		switch (face) {
		case 2:
		case 3:
		case 4:
			family= getFontName(family);
			this.currentFontStyle= face - 1;
			this.currentFontMapping= null;
			break;
		case 5:
			if (this.symbolFontName != null) {
				family= this.symbolFontName;
				this.currentFontStyle= 0;
				this.currentFontMapping= this.symbolFontMapping;
				break;
			}
			//$FALL-THROUGH$
		default:
			family= getFontName(family);
			this.currentFontStyle= 0;
			this.currentFontMapping= null;
			break;
		}
		this.currentFontFamily= this.swtFontManager.getFamily(family);
		this.currentFontRFace= face;
		this.currentFontSize= (int) (pointSize + 0.5);
		
		this.lastStringEnc= null;
		
		final FontSetting instr= new FontSetting(family, face, pointSize, lineHeight,
				this.currentFontFamily.getSWTFont(this.currentFontStyle, this.currentFontSize),
				this.currentFontFamily.getSWTFontProperties(this.currentFontStyle, this.currentFontSize) );
		add(instr);
	}
	
	private String getFontName(final String family) {
		if (family.length() == 0 || family.equals("sansserif")) {
			return this.sansFontName;
		}
		else if (family.equals("serif")) {
			return this.serifFontName;
		}
		else if (family.equals("mono")) {
			return this.monoFontName;
		}
		else {
			return family;
		}
	}
	
	@Override
	public void addSetLine(final int type, final float width,
			final byte cap, final byte join, final float joinMiterLimit) {
		final LineSetting instr= new LineSetting(type, width, cap, join, joinMiterLimit);
		add(instr);
	}
	
	@Override
	public void addDrawLine(final double x0, final double y0, final double x1, final double y1) {
		final LineElement instr= new LineElement(x0, y0, x1, y1);
		add(instr);
	}
	
	@Override
	public void addDrawRect(final double x0, final double y0, final double x1, final double y1) {
		final RectElement instr= new RectElement(x0, y0, x1, y1);
		add(instr);
	}
	
	@Override
	public void addDrawPolyline(final double[] x, final double[] y) {
		final PolylineElement instr= new PolylineElement(x, y);
		add(instr);
	}
	
	@Override
	public void addDrawPolygon(final double[] x, final double[] y) {
		final PolygonElement instr= new PolygonElement(x, y);
		add(instr);
	}
	
	@Override
	public void addDrawPath(final int[] n, final double[] x, final double[] y, final int winding) {
		final Path path= new Path(this.display);
		int k= 0, end= 0;
		for (int i= 0; i < n.length; i++) {
			end+= n[i];
			path.moveTo((float) Math.floor(x[k] + 0.5), (float) Math.floor(y[k++] + 0.5));
			while (k < end) {
				path.lineTo((float) Math.floor(x[k] + 0.5), (float) Math.floor(y[k++] + 0.5));
			}
			path.close();
		}
		final PathElement instr= new PathElement(n, x, y, winding, path);
		add(instr);
	}
	
	@Override
	public void addDrawCircle(final double x, final double y, final double r) {
		final CircleElement instr= new CircleElement(x, y, r);
		add(instr);
	}
	
	@Override
	public void addDrawText(final String txt,
			final double x, final double y, final double rDeg, final double hAdj) {
//		System.out.println("==\nDrawText: " + x + ", " + y + " " + hAdj + " \"" + txt + "\""); printFont();
		final String text= (this.currentFontMapping != null) ? this.currentFontMapping.encode(txt) : txt;
		final TextElement instr= new TextElement(text, x, y, rDeg, hAdj,
				(hAdj != 0) ? computeStringWidthEnc(text)[0] : 0);
		add(instr);
	}
	
	@Override
	public void addDrawRaster(final byte[] imgData, final boolean hasAlpha,
			final int imgWidth, final int imgHeight,
			final double x, final double y, final double w, final double h,
			final double rDeg, final boolean interpolate) {
		final ImageData imageData= new ImageData(imgWidth, imgHeight, 32, DIRECT_PALETTE, 4, imgData);
		if (hasAlpha) {
			final byte[] alpha= new byte[imgWidth*imgHeight];
			for (int i= 0; i < alpha.length; i++) {
				alpha[i]= imgData[i*4 + 3];
			}
			imageData.alphaData= alpha;
		}
		final Image swtImage= new Image(this.display, imageData);
		final RasterElement instr= new RasterElement(imgData, imgWidth, imgHeight, x, y, w, h,
				rDeg, interpolate, swtImage );
		add(instr);
	}
	
	@Override
	public byte[] capture(final int width, final int height) {
		ImageData imageData;
		{	Image image= null;
			GC gc= null;
			try {
				image= new Image(this.display, width, height);
				gc= new GC(image);
				final DefaultGCRenderer renderer= new DefaultGCRenderer();
				final List<ERGraphicInstruction> instructions= getCurrentInstructions();
				if (instructions.isEmpty()) {
					return null;
				}
				{	final RGraphicInitialization init= (RGraphicInitialization) instructions.get(0);
					double scale;
					if (width == (int) (init.width + 0.5)) {
						scale= 1.0;
					}
					else {
						scale= width / init.width;
					}
					renderer.clear(scale);
				}
				renderer.paint(gc, instructions);
				gc.dispose();
				gc= null;
				imageData= image.getImageData();
				image.dispose();
				image= null;
			}
			finally {
				if (gc != null && !gc.isDisposed()) {
					gc.dispose();
				}
				if (image != null && !image.isDisposed()) {
					image.dispose();
				}
			}
		}
		if (imageData == null || !imageData.palette.isDirect) {
			return null;
		}
		if (imageData.palette.redMask != DIRECT_RED_MASK
				|| imageData.palette.greenMask != DIRECT_GREEN_MASK
				|| imageData.palette.blueMask != DIRECT_BLUE_MASK
				|| imageData.scanlinePad != 4
				|| imageData.bytesPerLine != width * 4
				|| imageData.data.length != width * height * 4 ) {
			final byte[] data= (imageData.data.length == width * height * 4) ?
					imageData.data : new byte[width * height * 4];
			final int blueMask= imageData.palette.blueMask;
			final int blueShift= imageData.palette.blueShift;
			final int greenMask= imageData.palette.greenMask;
			final int greenShift= imageData.palette.greenShift;
			final int redMask= imageData.palette.redMask;
			final int redShift= imageData.palette.redShift;
			int i= 0;
			for (int y= 0; y < height; y++) {
				for (int x= 0; x < width; x++) {
					final int p= imageData.getPixel(x, y);
					data[i++]= (blueShift < 0) ?
							(byte) ((p & blueMask) >>> -blueShift) :
							(byte) ((p & blueMask) << blueShift);
					data[i++]= (greenShift < 0) ?
							(byte) ((p & greenMask) >>> -greenShift) :
							(byte) ((p & greenMask) << greenShift);
					data[i++]= (redShift < 0) ?
							(byte) ((p & redMask) >>> -redShift) :
							(byte) ((p & redMask) << redShift);
					data[i++]= (byte) 255;
				}
			}
			return data;
		}
		return imageData.data;
	}
	
	
	protected void waitRUserExchange(final String type,
			final RService r, final ProgressMonitor m,
			final Callable<Boolean> cancelListener) {
		final RServiceControlExtension rControl= (r instanceof RServiceControlExtension) ?
				(RServiceControlExtension) r : null;
		if (rControl != null && cancelListener != null) {
			rControl.addCancelHandler(cancelListener);
			rControl.getWaitLock().lock();
		}
		try {
			while (true) {
				synchronized (this.userExchangeLock) {
					if (this.userExchangeRType != type) {
						this.userExchangeRCallback= null;
						return;
					}
					if (this.isLocalClosed || this.isRClosed || m.isCanceled() ) {
						this.userExchangeRType= null;
						this.userExchangeRCallback= null;
						return;
					}
					this.userExchangeRCallback= rControl;
				}
				
				if (rControl != null) {
					rControl.waitingForUser(m);
				}
				else {
					try {
						Thread.sleep(50);
					}
					catch (final InterruptedException e) {
					}
				}
			}
		}
		finally {
			if (rControl != null && cancelListener != null) {
				rControl.getWaitLock().unlock();
				rControl.removeCancelHandler(cancelListener);
			}
		}
	}
	
	
	private void internalStartLocator(final LocatorCallback callback) {
		this.locatorCallback= callback;
		this.locatorMessage= new InfoStatus(RGraphics.BUNDLE_ID, callback.getMessage());
		this.locatorStopTypes= callback.getStopTypes();
		this.locatorDeferredStamp= Long.MIN_VALUE;
		
		if (this.display.isDisposed()) {
			return;
		}
		if (!this.locatorNotificationDirectScheduled) {
			execInDisplay(this.locatorNotificationRunnable);
		}
	}
	
	private void internalStopLocator(final boolean deferred) {
		if (deferred) {
			this.locatorDeferredStamp= System.nanoTime() + 500 * MILLI_NANOS;
			if (this.display.isDisposed()) {
				return;
			}
			if (!(this.locatorNotificationDirectScheduled || this.locatorNotificationDeferredScheduled)) {
				this.locatorNotificationDirectScheduled= true;
				execInDisplay(this.locatorNotificationRunnable);
			}
			return;
		}
		
		this.locatorCallback= null;
		this.locatorMessage= null;
		this.locatorStopTypes= Collections.emptySet();
		this.locatorDeferredStamp= Long.MIN_VALUE;
		
		if (this.display.isDisposed()) {
			return;
		}
		if (!this.locatorNotificationDirectScheduled) {
			this.locatorNotificationDirectScheduled= true;
			execInDisplay(this.locatorNotificationRunnable);
		}
	}
	
	@Override
	public double[] runRLocator(final RService r, final ProgressMonitor m) {
		synchronized (this.userExchangeLock) {
			if (this.locatorCallback != null && this.locatorCallback != R_LOCATOR_CALLBACK) {
				return null;
			}
			this.userExchangeRType= "locator";
			internalStartLocator(R_LOCATOR_CALLBACK);
			
			this.locatorLocationValue= null;
		}
		waitRUserExchange("locator", r, m, new Callable<Boolean>() {
			@Override
			public Boolean call() {
				return Boolean.valueOf(answerLocator(null, null, true));
			}
		});
		final double[] value;
		synchronized (this.userExchangeLock) {
			value= this.locatorLocationValue;
			if (this.userExchangeRType == "locator") {
				this.userExchangeRType= null;
			}
			// avoid flickering as well as stale locators
			internalStopLocator(value != null);
		}
		return value;
	}
	
	@Override
	public Status startLocalLocator(final LocatorCallback callback) {
		if (callback == null) {
			throw new NullPointerException("callback"); //$NON-NLS-1$
		}
		synchronized (this.userExchangeLock) {
			if (this.locatorCallback != null && this.locatorCallback != callback) {
				return new ErrorStatus(RGraphics.BUNDLE_ID, "Another locator is already started.");
			}
			internalStartLocator(callback);
		}
		return Statuses.OK_STATUS;
	}
	
	@Override
	public boolean isLocatorStarted() {
		return (this.locatorCallback != null);
	}
	
	@Override
	public Collection<String> getLocatorStopTypes() {
		return this.locatorStopTypes;
	}
	
	@Override
	public void returnLocator(final double x, final double y) {
		answerLocator(null, new double[] { x, y }, false);
	}
	
	@Override
	public void stopLocator(final String type) {
		answerLocator(type, null, false);
	}
	
	private boolean answerLocator(final String type, final double[] xy,
			final boolean onlyR) {
		synchronized (this.locatorAnswerLock) {
			RServiceControlExtension rControl= null;
			LocatorCallback callback;
			synchronized (this.userExchangeLock) {
				if (this.locatorCallback == null || this.locatorDeferredStamp != Long.MIN_VALUE) {
					return false;
				}
				if (this.locatorCallback == R_LOCATOR_CALLBACK) {
					if (this.userExchangeRType == "locator") { //$NON-NLS-1$
						this.userExchangeRType= null;
						rControl= this.userExchangeRCallback;
					}
					else {
						return false;
					}
				}
				else if (onlyR) {
					return false;
				}
				if (xy == null && type != null && !this.locatorStopTypes.contains(type)) {
					return false;
				}
				this.locatorLocationValue= xy;
				callback= this.locatorCallback;
			}
			
			final int code;
			if (callback == R_LOCATOR_CALLBACK) {
				if (xy != null) {
					code= -1;
				}
				else {
					code= LocatorCallback.STOP;
				}
				if (rControl != null) {
					rControl.getWaitLock().lock();
					try {
						rControl.resume();
					}
					finally {
						rControl.getWaitLock().unlock();
					}
				}
			}
			else {
				if (xy != null) {
					code= callback.located(xy[0], xy[1]);
				}
				else {
					code= LocatorCallback.STOP;
					callback.stopped(type);
				}
			}
			synchronized (this.userExchangeLock) {
				if (code == LocatorCallback.NEXT) {
					internalStartLocator(callback);
				}
				else {
					internalStopLocator((code == -1));
				}
			}
			return true;
		}
	}
	
	
	public void closeFromR() {
		this.isRClosed= true;
		if (this.isLocalClosed
				|| (this.options & RClientGraphicFactory.R_CLOSE_OFF) == 0) {
			dispose();
		}
		answerLocator(null, null, true);
		setActive(false);
	}
	
	protected void dispose() {
		this.graphicListeners.clear();
		Runnable runnable= null;
		synchronized (this.stateLock) {
			if (!this.isDisposed) {
				this.isDisposed= true;
				internalReset();
				synchronized (this.instructionsLock) {
					if (this.instructionsSize > 0) {
						runnable= new DisposeRunnable(this.instructions, this.instructionsSize);
					}
					this.instructionsSize= 0;
					this.instructions= null;
				}
			}
		}
		if (runnable != null) {
			execInDisplay(runnable);
		}
	}
	
	
	@Override
	public List<ERGraphicInstruction> getInstructions() {
		synchronized (this.instructionsLock) {
			return (this.instructionsSize > 0) ?
					ImCollections.newList(this.instructions).subList(0, this.instructionsSize) :
					ImCollections.<ERGraphicInstruction>emptyList();
		}
	}
	
	@Override
	public @Nullable RTool getRHandle() {
		if (this.actions != null) {
			return this.actions.getRHandle();
		}
		return null;
	}
	
	@Override
	public Status resize(final double w, final double h) {
		if (this.actions != null) {
			this.nextSize= new double[] { w, h };
			return this.actions.resizeGraphic(this.devId, new Runnable() {
				@Override
				public void run() {
					EclipseRGraphic.this.size= EclipseRGraphic.this.nextSize;
				}
			});
		}
		return null;
	}
	
	@Override
	public Status close() {
		if (this.isRClosed) {
			this.isLocalClosed= true;
			dispose();
		}
		if (this.actions != null) {
			answerLocator(null, null, false);
			return this.actions.closeGraphic(this.devId);
		}
		else {
			this.isLocalClosed= true;
			answerLocator(null, null, false);
			this.manager.close(this);
			dispose();
		}
		return null;
	}
	
	@Override
	public void addListener(final Listener listener) {
		this.graphicListeners.add(listener);
	}
	
	@Override
	public void removeListener(final Listener listener) {
		this.graphicListeners.remove(listener);
	}
	
	protected void updateMessage() {
		Status message;
		if (this.locatorMessage != null) {
			message= this.locatorMessage;
		}
		else {
			message= Statuses.OK_STATUS;
		}
		if (!this.message.equals(message)) {
			this.message= message;
			for (final StatusChangeListener listener : this.messageListeners.toList()) {
				listener.onStatusChanged(message);
			}
		}
	}
	
	@Override
	public Status getMessage() {
		return this.message;
	}
	
	@Override
	public void addMessageListener(final StatusChangeListener listener) {
		this.messageListeners.add(listener);
	}
	
	@Override
	public void removeMessageListener(final StatusChangeListener listener) {
		this.messageListeners.remove(listener);
	}
	
	
	protected void preAction() throws StatusException {
		if (this.actions == null || this.actions.getRHandle() == null) {
			throw new UnsupportedOperationException();
		}
		if (this.isRClosed) {
			throw new StatusException(new ErrorStatus(RGraphics.BUNDLE_ID,
					"The R graphic device is already closed." ));
		}
	}
	
	@Override
	public void copy(final String toDev, final String toDevFile, final String toDevArgs,
			final ProgressMonitor m) throws StatusException {
		preAction();
		this.actions.copy(this.devId, toDev, toDevFile, toDevArgs, m);
	}
	
	@Override
	public double[] convertGraphic2User(final double[] xy,
			final ProgressMonitor m) throws StatusException {
		preAction();
		return this.actions.convertGraphic2User(this.devId, xy, m);
	}
	
	@Override
	public double[] convertUser2Graphic(final double[] xy,
			final ProgressMonitor m) throws StatusException {
		preAction();
		return this.actions.convertUser2Graphic(this.devId, xy, m);
	}
	
}
