/*=============================================================================#
 # 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 ERGraphic}, {@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);
	}
	
}
