/******************************************************************************
 * Copyright (c) 2000, 2009 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *    IBM Corporation - initial API and implementation
 *    Mariot Chauvin <mariot.chauvin@obeo.fr> - patch 244297
 ****************************************************************************/
package org.eclipse.gmf.runtime.draw2d.ui.internal.graphics;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.eclipse.core.runtime.IStatus;
import org.eclipse.draw2d.FigureUtilities;
import org.eclipse.draw2d.Graphics;
import org.eclipse.draw2d.geometry.Dimension;
import org.eclipse.draw2d.geometry.Point;
import org.eclipse.draw2d.geometry.PointList;
import org.eclipse.draw2d.geometry.Rectangle;
import org.eclipse.gmf.runtime.common.core.util.Log;
import org.eclipse.gmf.runtime.draw2d.ui.graphics.GCUtilities;
import org.eclipse.gmf.runtime.draw2d.ui.internal.Draw2dPlugin;
import org.eclipse.jface.window.Window;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.FontData;
import org.eclipse.swt.graphics.FontMetrics;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.LineAttributes;
import org.eclipse.swt.graphics.Path;
import org.eclipse.swt.graphics.PathData;
import org.eclipse.swt.graphics.Pattern;
import org.eclipse.swt.graphics.TextLayout;
import org.eclipse.swt.graphics.TextStyle;
import org.eclipse.swt.widgets.Display;


/**
 * @canBeSeenBy %partners
 *  
 * Subclass of Graphics that uses resource manager for its font cache and 
 * scales graphics/fonts by a specified scale factor
 *
 * <p>
 * Code taken from Eclipse reference bugzilla #77403
 * See also bugzilla #111454
 * See also bugzilla #230056 setLineWidth in ScaledGraphics does not support the 
 * zoom factor.
 */
/**
 * A Graphics object able to scale all operations based on the current scale factor.
 */
public class ScaledGraphics
	extends Graphics {

	private static class FontHeightCache {
		Font font;
		int height;
	}
	
	static class FontKey {
		Font font;
		int height;
		protected FontKey() { }
		protected FontKey(Font font, int height) {
			this.font = font;
			this.height = height;
		}
		
		public boolean equals(Object obj) {
			return (((FontKey)obj).font.equals(font) 
					&& ((FontKey)obj).height == height);
		}
	
		public int hashCode() {
			return font.hashCode() ^ height;
		}
	
		protected void setValues(Font font, int height) {
			this.font = font;
			this.height = height;
		}
	}
	
	/**
	 * The internal state of the scaled graphics.
	 */
	protected static class State {
		private double appliedX;
		private double appliedY;
		private Font font;
		private float lineWidth;
		private double zoom; 
	
		/**
		 * Constructs a new, uninitialized State object.
		 */
		protected State() {	}
		
		/**
		 * Constructs a new State object and initializes the properties based on the given 
		 * values.
		 * 
		 * @param zoom the zoom factor
		 * @param x the x offset
		 * @param y the y offset
		 * @param font the font
		 * @param lineWidth the line width
		 */
		protected State(double zoom, double x, double y, Font font, int lineWidth) {
			this(zoom, x, y, font, (float)lineWidth);
		}
	
		/**
		 * Constructs a new State object and initializes the properties based on the given 
		 * values.
		 * 
		 * @param zoom the zoom factor
		 * @param x the x offset
		 * @param y the y offset
		 * @param font the font
		 * @param lineWidth the line width
		 * 
		 * @since 3.5
		 */
		protected State(double zoom, double x, double y, Font font, float lineWidth) {
			this.zoom = zoom;
			this.appliedX = x;
			this.appliedY = y;
			this.font = font;
			this.lineWidth = lineWidth;
		}
		
		/**
		 * Sets all the properties of the state object.
		 * @param zoom the zoom factor
		 * @param x the x offset
		 * @param y the y offset
		 * @param font the font
		 * @param lineWidth the line width
		 */
		protected void setValues(double zoom, double x, double y, 
				Font font, int lineWidth) {
			setValues(zoom, x, y, font, (float)lineWidth);
		}
	
		/**
		 * Sets all the properties of the state object.
		 * @param zoom the zoom factor
		 * @param x the x offset
		 * @param y the y offset
		 * @param font the font
		 * @param lineWidth the line width
		 * 
		 * @since 3.5
		 */
		protected void setValues(double zoom, double x, double y, 
				Font font, float lineWidth) {
			this.zoom = zoom;
			this.appliedX = x;
			this.appliedY = y;
			this.font = font;
			this.lineWidth = lineWidth;
		}
	}
	
	static private boolean advancedGraphicsWarningLogged = false;
	
	private static int[][] intArrayCache = new int[8][];
	private final Rectangle tempRECT = new Rectangle();
	
	static {
		for (int i = 0; i < intArrayCache.length; i++) {
			intArrayCache[i] = new int[i + 1];
		}
	}
	
	private boolean allowText = true;
	//private static final Point PT = new Point();
	//private Map fontCache = new HashMap();
	private Map<Font, FontData> fontDataCache = new HashMap<Font, FontData>();
	private FontKey fontKey = new FontKey();
	private double fractionalX;
	private double fractionalY;
	private Graphics graphics;
	private FontHeightCache localCache = new FontHeightCache();
	private Font localFont;
	private float localLineWidth;
	private List<State> stack = new ArrayList<State>();
	private int stackPointer = 0;
	private FontHeightCache targetCache = new FontHeightCache();
	
	double zoom = 1.0;

	/**
	 * Constructs a new ScaledGraphics based on the given Graphics object.
	 * @param g the base graphics object
	 */
	public ScaledGraphics(Graphics g) {
		graphics = g;
		localFont = g.getFont();
		localLineWidth = g.getLineWidthFloat();
	}
	
	/** @see Graphics#clipRect(Rectangle) */
	public void clipRect(Rectangle r) {
		graphics.clipRect(zoomClipRect(r));
	}
	
	Font createFont(FontData data) {
		return new Font(Display.getCurrent(), data);
	}
	
	/**
	 * Scales given path by zoom factor
	 * 
	 * @param path
	 *            Path to be scaled
	 * @return Scaled path
	 * @since 1.2	 
	 */
	private Path createScaledPath(Path path) {
		PathData p = path.getPathData();
		for (int i = 0; i < p.points.length; i += 2) {
			p.points[i] = (float) (p.points[i] * zoom + fractionalX);
			p.points[i + 1] = (float) (p.points[i + 1] * zoom + fractionalY);
		}
		Path scaledPath = new Path(path.getDevice());
		int index = 0;
		for (int i = 0; i < p.types.length; i++) {
			byte type = p.types[i];
			switch (type) {
				case SWT.PATH_MOVE_TO:
					scaledPath.moveTo(p.points[index], p.points[index + 1]);
					index += 2;
					break;
				case SWT.PATH_LINE_TO:
					scaledPath.lineTo(p.points[index], p.points[index + 1]);
					index += 2;
					break;
				case SWT.PATH_CUBIC_TO:
					scaledPath.cubicTo(p.points[index], p.points[index + 1],
							p.points[index + 2], p.points[index + 3],
							p.points[index + 4], p.points[index + 5]);
					index += 6;
					break;
				case SWT.PATH_QUAD_TO:
					scaledPath.quadTo(p.points[index], p.points[index + 1],
							p.points[index + 2], p.points[index + 3]);
					index += 4;
					break;
				case SWT.PATH_CLOSE:
					scaledPath.close();
					break;
			}
		}
		return scaledPath;
	}
	
	/** @see Graphics#dispose() */
	public void dispose() {
		//Remove all states from the stack
		while (stackPointer > 0) {
			popState();
		}
		
		//	 Resource manager handles fonts 
	}
	
	/** @see Graphics#drawArc(int, int, int, int, int, int) */
	public void drawArc(int x, int y, int w, int h, int offset, int sweep) {
		Rectangle z = zoomRect(x, y, w, h);
		if (z.isEmpty() || sweep == 0)
			return;
		graphics.drawArc(z, offset, sweep);
	}
	
	/** @see Graphics#drawFocus(int, int, int, int) */
	public void drawFocus(int x, int y, int w, int h) {
		graphics.drawFocus(zoomRect(x, y, w, h));
	}
	
	/** @see Graphics#drawImage(Image, int, int) */
	public void drawImage(Image srcImage, int x, int y) {
		org.eclipse.swt.graphics.Rectangle size = srcImage.getBounds();
	    Dimension sizeLPDim = new Dimension(size.width, size.height);
	    if (graphics instanceof MapModeGraphics) {
	        ((MapModeGraphics)graphics).getMapMode().DPtoLP(sizeLPDim);
	    }
	    
	    Rectangle z = new Rectangle((int)(Math.floor((x * zoom + fractionalX))), 
	        (int)(Math.floor((y * zoom + fractionalY))),
	        (int)(Math.floor((sizeLPDim.width * zoom + fractionalX))), 
	        (int)(Math.floor((sizeLPDim.height * zoom + fractionalY))));
	    
		graphics.drawImage(srcImage, 0, 0, size.width, size.height,
			z.x, z.y, z.width, z.height);
	}
	
	/** @see Graphics#drawImage(Image, int, int, int, int, int, int, int, int) */
	public void drawImage(Image srcImage, int sx, int sy, int sw, int sh,
											int tx, int ty, int tw, int th) {
		//"t" == target rectangle, "s" = source
				 
		Rectangle t = zoomRect(tx, ty, tw, th);
		if (!t.isEmpty())
			graphics.drawImage(srcImage, sx, sy, sw, sh, t.x, t.y, t.width, t.height);
	}
	
	/** @see Graphics#drawLine(int, int, int, int) */
	public void drawLine(int x1, int y1, int x2, int y2) {
		graphics.drawLine(
			(int)(Math.floor((x1 * zoom + fractionalX))),
			(int)(Math.floor((y1 * zoom + fractionalY))),
			(int)(Math.floor((x2 * zoom + fractionalX))),
			(int)(Math.floor((y2 * zoom + fractionalY))));
	}
	
	/** @see Graphics#drawOval(int, int, int, int) */
	public void drawOval(int x, int y, int w, int h) {
		graphics.drawOval(zoomRect(x, y, w, h));
	}
	
	/** @see Graphics#drawPath(Path) */
	public void drawPath(Path path) {
		Path scaledPath = createScaledPath(path);
		try {
			graphics.drawPath(scaledPath);
		} finally {
			scaledPath.dispose();
		}
	}
	
	/** @see Graphics#drawPoint(int, int) */
	public void drawPoint(int x, int y) {
		graphics.drawPoint((int)Math.floor(x * zoom + fractionalX),
				(int)Math.floor(y * zoom + fractionalY));
	}
	
	/**
	 * @see Graphics#drawPolygon(int[])
	 */
	public void drawPolygon(int[] points) {
		graphics.drawPolygon(zoomPointList(points));
	}
	
	/** @see Graphics#drawPolygon(PointList) */
	public void drawPolygon(PointList points) {
		graphics.drawPolygon(zoomPointList(points.toIntArray()));
	}
	
	/**
	 * @see Graphics#drawPolyline(int[])
	 */
	public void drawPolyline(int[] points) {
		graphics.drawPolyline(zoomPointList(points));
	}
	
	/** @see Graphics#drawPolyline(PointList) */
	public void drawPolyline(PointList points) {
		graphics.drawPolyline(zoomPointList(points.toIntArray()));
	}
	
	/** @see Graphics#drawRectangle(int, int, int, int) */
	public void drawRectangle(int x, int y, int w, int h) {
		graphics.drawRectangle(zoomRect(x, y, w, h));
	}
	
	/** @see Graphics#drawRoundRectangle(Rectangle, int, int) */
	public void drawRoundRectangle(Rectangle r, int arcWidth, int arcHeight) {
		graphics.drawRoundRectangle(zoomRect(r.x, r.y, r.width, r.height),
			(int)(arcWidth * zoom),
			(int)(arcHeight * zoom));
	}
	
	/** @see Graphics#drawString(String, int, int) */
	public void drawString(String s, int x, int y) {
		if (allowText)
			graphics.drawString(s, zoomTextPoint(x, y));
	}
	
	/** @see Graphics#drawText(String, int, int) */
	public void drawText(String s, int x, int y) {
		if (allowText)
			graphics.drawText(s, zoomTextPoint(x, y));
	}
	
	/**
	 * @see Graphics#drawText(String, int, int, int)
	 */
	public void drawText(String s, int x, int y, int style) {
		if (allowText)
			graphics.drawText(s, zoomTextPoint(x, y), style);
	}
	
	/**
	 * @see Graphics#drawTextLayout(TextLayout, int, int, int, int, Color, Color)
	 */
	public void drawTextLayout(TextLayout layout, int x, int y, int selectionStart,
			int selectionEnd, Color selectionForeground, Color selectionBackground) {
		TextLayout scaled = zoomTextLayout(layout);
		graphics.drawTextLayout(scaled,
				(int)Math.floor(x * zoom + fractionalX),
				(int)Math.floor(y * zoom + fractionalY),
				selectionStart, selectionEnd, selectionBackground, selectionForeground);
		scaled.dispose();
	}
	
	/** @see Graphics#fillArc(int, int, int, int, int, int) */
	public void fillArc(int x, int y, int w, int h, int offset, int sweep) {
		Rectangle z = zoomFillRect(x, y, w, h);
		if (z.isEmpty() || sweep == 0)
			return;
		graphics.fillArc(z, offset, sweep);
	}
	
	/** @see Graphics#fillGradient(int, int, int, int, boolean) */
	public void fillGradient(int x, int y, int w, int h, boolean vertical) {
		graphics.fillGradient(zoomFillRect(x, y, w, h), vertical);
	}
	
	/** @see Graphics#fillOval(int, int, int, int) */
	public void fillOval(int x, int y, int w, int h) {
		graphics.fillOval(zoomFillRect(x, y, w, h));
	}
	
	/** @see Graphics#fillPath(Path) */
	public void fillPath(Path path) {
		Path scaledPath = createScaledPath(path);
		try {
			graphics.fillPath(scaledPath);
		} finally {
			scaledPath.dispose();
		}
	}	
		
	/**
	 * @see Graphics#fillPolygon(int[])
	 */
	public void fillPolygon(int[] points) {
		graphics.fillPolygon(zoomPointList(points));
	}
	
	/** @see Graphics#fillPolygon(PointList) */
	public void fillPolygon(PointList points) {
		graphics.fillPolygon(zoomPointList(points.toIntArray()));
	}
	
	/** @see Graphics#fillRectangle(int, int, int, int) */
	public void fillRectangle(int x, int y, int w, int h) {
		graphics.fillRectangle(zoomFillRect(x, y, w, h));
	}
	
	/** @see Graphics#fillRoundRectangle(Rectangle, int, int) */
	public void fillRoundRectangle(Rectangle r, int arcWidth, int arcHeight) {
		graphics.fillRoundRectangle(zoomFillRect(r.x, r.y, r.width, r.height),
			(int)(arcWidth * zoom),
			(int)(arcHeight * zoom));
	}
	
	/** @see Graphics#fillString(String, int, int) */
	public void fillString(String s, int x, int y) {
		if (allowText)
			graphics.fillString(s, zoomTextPoint(x, y));
	}
	
	/** @see Graphics#fillText(String, int, int) */
	public void fillText(String s, int x, int y) {
		if (allowText)
			graphics.fillText(s, zoomTextPoint(x, y));
	}
	
	/**
	 * @see Graphics#getAbsoluteScale()
	 */
	public double getAbsoluteScale() {
		return zoom * graphics.getAbsoluteScale();
	}
	
	/**
	 * @see Graphics#getAlpha()
	 */
	public int getAlpha() {
		return graphics.getAlpha();
	}
	
	/**
	 * @see Graphics#getAntialias()
	 */
	public int getAntialias() {
		return graphics.getAntialias();
	}
	
	/** @see Graphics#getBackgroundColor() */
	public Color getBackgroundColor() {
		return graphics.getBackgroundColor();
	}
	
	Font getCachedFont(FontKey key) {
		FontData data = key.font.getFontData()[0];		
		data.setHeight(key.height);
		return FontRegistry.getInstance().getFont(Display.getCurrent(), data);
	}
	
	/**
	 * Allows clients to reset the font cache utilized by the ScaledGraphics in
	 * order to avoid caching more objects then necessary.
	 */
	static public void resetFontCache() {
		FontRegistry.getInstance().clearFontCache();
	}
	
	FontData getCachedFontData(Font f) {
		FontData data = fontDataCache.get(f);
		if (data == null) {
			data = getLocalFont().getFontData()[0];
			fontDataCache.put(f, data);
		}
		return data;
	}
	
	/** @see Graphics#getClip(Rectangle) */
	public Rectangle getClip(Rectangle rect) {
		graphics.getClip(rect);
		int x = (int)(rect.x / zoom);
		int y = (int)(rect.y / zoom);
		/*
		 * If the clip rectangle is queried, perform an inverse zoom, and take the ceiling of
		 * the resulting double. This is necessary because forward scaling essentially performs
		 * a floor() function. Without this, figures will think that they don't need to paint
		 * when actually they do.
		 */
		rect.width = (int)Math.ceil(rect.right() / zoom) - x;
		rect.height = (int)Math.ceil(rect.bottom() / zoom) - y;
		rect.x = x;
		rect.y = y;
		return rect;
	}
	
	/**
	 * @see Graphics#getAdvanced()
	 */
	public boolean getAdvanced() {
		return graphics.getAdvanced();
	}

	/**
	 * @see Graphics#getFillRule()
	 */
	public int getFillRule() {
		return graphics.getFillRule();
	}
	
	/** @see Graphics#getFont() */
	public Font getFont() {
		return getLocalFont();
	}
	
	/** @see Graphics#getFontMetrics() */
	public FontMetrics getFontMetrics() {
		return FigureUtilities.getFontMetrics(localFont);
	}
	
	/** @see Graphics#getForegroundColor() */
	public Color getForegroundColor() {
		return graphics.getForegroundColor();
	}
	
	/**
	 * @see Graphics#getInterpolation()
	 */
	public int getInterpolation() {
		return graphics.getInterpolation();
	}

	/**
	 * @see Graphics#getLineCap()
	 */
	public int getLineCap() {
		return graphics.getLineCap();
	}
	
	/**
	 * @see Graphics#getLineJoin()
	 */
	public int getLineJoin() {
		return graphics.getLineJoin();
	}
	
	/** @see Graphics#getLineStyle() */
	public int getLineStyle() {
		return graphics.getLineStyle();
	}
	
	/** @see Graphics#getLineMiterLimit() */
	public float getLineMiterLimit() {
		return graphics.getLineMiterLimit();
	}
	
	/** @see Graphics#getLineWidth() */
	public int getLineWidth() {
		return (int)getLineWidthFloat();
	}
	
	/** @see Graphics#getLineWidthFloat() */
	public float getLineWidthFloat() {
		return getLocalLineWidth();
	}
	
	/** @see Graphics#getLineAttributes() */
	public LineAttributes getLineAttributes() {
		LineAttributes a = graphics.getLineAttributes();
		a.width = getLocalLineWidth();
		return a;
	}

	private Font getLocalFont() {
		return localFont;
	}
	
	private float getLocalLineWidth() {
		return localLineWidth;
	}
	
	/**
	 * @see Graphics#getTextAntialias()
	 */
	public int getTextAntialias() {
		return graphics.getTextAntialias();
	}
	
	/** @see Graphics#getXORMode() */
	public boolean getXORMode() {
		return graphics.getXORMode();
	}
	
	/** @see Graphics#popState() */
	public void popState() {
		graphics.popState();
		stackPointer--;
		restoreLocalState(stack.get(stackPointer));
	}
	
	/** @see Graphics#pushState() */
	public void pushState() {
		State s;
		if (stack.size() > stackPointer) {
			s = stack.get(stackPointer);
			s.setValues(zoom, fractionalX, fractionalY, getLocalFont(), localLineWidth);
		} else {
			stack.add(new State(zoom, fractionalX, fractionalY, getLocalFont(), 
									localLineWidth));
		}
		stackPointer++;
	
		graphics.pushState();
	}
	
	private void restoreLocalState(State state) {
		this.fractionalX = state.appliedX;
		this.fractionalY = state.appliedY;
		setScale(state.zoom);
		setLocalFont(state.font);
		setLocalLineWidth(state.lineWidth);
	}
	
	/** @see Graphics#restoreState() */
	public void restoreState() {
		graphics.restoreState();
		restoreLocalState(stack.get(stackPointer - 1));
	}
	
	/** @see Graphics#scale(double) */
	public void scale(double amount) {
		setScale(zoom * amount);
	}
	
	/** @see Graphics#setAdvanced(boolean) */
	public void setAdvanced(boolean advanced) {
		graphics.setAdvanced(advanced);
	}

	/**
	 * This method requires advanced graphics support. A check should be made to
	 * ensure advanced graphics is supported in the user's environment before
	 * calling this method. See {@link GCUtilities#supportsAdvancedGraphics()}.
	 * 
	 * @see Graphics#setAlpha(int)
	 */
	public void setAlpha(int alpha) {
	    if (!GCUtilities.supportsAdvancedGraphics()) { 
	        logAdvancedGraphicsWarning();
	        return;
	    }
		graphics.setAlpha(alpha);
	}
	
	/**
	 * This method requires advanced graphics support. A check should be made to
	 * ensure advanced graphics is supported in the user's environment before
	 * calling this method. See {@link GCUtilities#supportsAdvancedGraphics()}.
	 * 
	 * @see Graphics#setAntialias(int)
	 */
	public void setAntialias(int value) {
	    if (!GCUtilities.supportsAdvancedGraphics()) { 
	        logAdvancedGraphicsWarning();
	        return;
	    }
		graphics.setAntialias(value);
	}
	
	/** @see Graphics#setBackgroundColor(Color) */
	public void setBackgroundColor(Color rgb) {
		graphics.setBackgroundColor(rgb);
	}

	/** @see Graphics#setClip(Path) */
	public void setClip(Path path) {
		Path scaledPath = createScaledPath(path);
		try {
			graphics.setClip(scaledPath);
		} finally {
			scaledPath.dispose();
		}
	}
	
	public void clipPath(Path path) {
		Path scaledPath = createScaledPath(path);
		try {
			graphics.clipPath(scaledPath);
		} finally {
			scaledPath.dispose();
		}
	}
		
	/** @see Graphics#setBackgroundPattern(Pattern) */
	public void setBackgroundPattern(Pattern pattern) {
		graphics.setBackgroundPattern(pattern);  
	}
	
	/** @see Graphics#setClip(Rectangle) */
	public void setClip(Rectangle r) {
		graphics.setClip(zoomClipRect(r));
	}
	
	/**
	 * @see Graphics#setFillRule(int)
	 */
	public void setFillRule(int rule) {
		graphics.setFillRule(rule);
	}
	
	/** @see Graphics#setFont(Font) */
	public void setFont(Font f) {
		setLocalFont(f);
	}
	
	/** @see Graphics#setForegroundColor(Color) */
	public void setForegroundColor(Color rgb) {
		graphics.setForegroundColor(rgb);
	}
	
	/** @see Graphics#setForegroundPattern(Pattern) */
	public void setForegroundPattern(Pattern pattern) {
		graphics.setForegroundPattern(pattern);
	}
	
	/**
	 * This method requires advanced graphics support. A check should be made to
	 * ensure advanced graphics is supported in the user's environment before
	 * calling this method. See {@link GCUtilities#supportsAdvancedGraphics()}.
	 * 
	 * @see org.eclipse.draw2d.Graphics#setInterpolation(int)
	 */
	public void setInterpolation(int interpolation) {
	    if (!GCUtilities.supportsAdvancedGraphics()) { 
	        logAdvancedGraphicsWarning();
	        return;
	    }
		graphics.setInterpolation(interpolation);
	}
	
	/**
	 * @see Graphics#setLineCap(int)
	 */
	public void setLineCap(int cap) {
		graphics.setLineCap(cap);
	}
	
	/**
	 * @see Graphics#setLineDash(int[])
	 */
	public void setLineDash(int[] dash) {
		graphics.setLineDash(dash);
	}
	
	/**
	 * @see Graphics#setLineJoin(int)
	 */
	public void setLineJoin(int join) {
		graphics.setLineJoin(join);
	}
	
	/** @see Graphics#setLineStyle(int) */
	public void setLineStyle(int style) {
		graphics.setLineStyle(style);
	}
	
	/** @see Graphics#setLineMiterLimit(float) */
	public void setLineMiterLimit(float value) {
		graphics.setLineMiterLimit(value);
	}

	/** @see Graphics#setLineWidth(int) */
	public void setLineWidth(int width) {
		setLineWidthFloat(width);
	}
	
	/** @see Graphics#setLineWidthFloat(float) */
	public void setLineWidthFloat(float width) {
		setLocalLineWidth(width);
	}
	
	/** @see Graphics#setLineAttributes(LineAttributes) */
	public void setLineAttributes(LineAttributes attributes) {
		graphics.setLineAttributes(attributes);
		setLocalLineWidth(attributes.width);
	}
	
	private void setLocalFont(Font f) {
		localFont = f;
		graphics.setFont(zoomFont(f));
	}
	
	private void setLocalLineWidth(float width) {
		localLineWidth = width;
		graphics.setLineWidthFloat(zoomLineWidth(width));
	}
	
	void setScale(double value) {
		if (zoom != value) {
			this.zoom = value;
			graphics.setFont(zoomFont(getLocalFont()));
			graphics.setLineWidthFloat(zoomLineWidth(localLineWidth));
		}
	}
	
	/**
	 * This method requires advanced graphics support. A check should be made to
	 * ensure advanced graphics is supported in the user's environment before
	 * calling this method. See {@link GCUtilities#supportsAdvancedGraphics()}.
	 * 
	 * @see Graphics#setTextAntialias(int)
	 */
	public void setTextAntialias(int value) {
	    if (!GCUtilities.supportsAdvancedGraphics()) { 
	        logAdvancedGraphicsWarning();
	        return;
	    }
		graphics.setTextAntialias(value);
	}	
	
	/** @see Graphics#setXORMode(boolean) */
	public void setXORMode(boolean b) {
		graphics.setXORMode(b);
	}
	
	/** @see Graphics#translate(int, int) */
	public void translate(int dx, int dy) {
		// fractionalX/Y is the fractional part left over from previous 
		// translates that gets lost in the integer approximation.
		double dxFloat = dx * zoom + fractionalX;
		double dyFloat = dy * zoom + fractionalY;
		fractionalX = dxFloat - Math.floor(dxFloat);
		fractionalY = dyFloat - Math.floor(dyFloat);
		graphics.translate((int)Math.floor(dxFloat), (int)Math.floor(dyFloat));
	}
	
	/** @see Graphics#translate(float, float) */
	public void translate(float dx, float dy) {
		double dxFloat = dx * zoom + fractionalX;
		double dyFloat = dy * zoom + fractionalY;
		fractionalX = dxFloat - Math.floor(dxFloat);
		fractionalY = dyFloat - Math.floor(dyFloat);
		graphics.translate((int)Math.floor(dxFloat), (int)Math.floor(dyFloat));
	}
	
	private Rectangle zoomClipRect(Rectangle r) {
		tempRECT.x = (int)(Math.floor(r.x * zoom + fractionalX));
		tempRECT.y = (int)(Math.floor(r.y * zoom + fractionalY));
		tempRECT.width = (int)(Math.ceil(((r.x + r.width) * zoom + fractionalX))) - tempRECT.x;
		tempRECT.height = (int)(Math.ceil(((r.y + r.height) * zoom + fractionalY))) - tempRECT.y;
		return tempRECT;
	}
	
	private Rectangle zoomFillRect(int x, int y, int w, int h) {
		tempRECT.x = (int)(Math.floor((x * zoom + fractionalX)));
		tempRECT.y = (int)(Math.floor((y * zoom + fractionalY)));
		tempRECT.width = (int)(Math.floor(((x + w - 1) * zoom + fractionalX))) - tempRECT.x + 1;
		tempRECT.height = (int)(Math.floor(((y + h - 1) * zoom + fractionalY))) - tempRECT.y + 1;
		return tempRECT;
	}
	
	Font zoomFont(Font f) {
		if (f == null) {
			f = Display.getCurrent().getSystemFont();
		}
		FontData data = getCachedFontData(f);
		int zoomedFontHeight = zoomFontHeight(data.getHeight());
		allowText = zoomedFontHeight > 0;
		fontKey.setValues(f, zoomedFontHeight);
		return getCachedFont(fontKey);
	}
	
	int zoomFontHeight(int height) {
		return (int)(zoom * height);
	}
	
	float zoomLineWidth(float w) {
		/*
		 * We introduced line width zoom in GMF 2.1.
		 * Unfortunately GMF 2.0 clients used HiMetric map mode and called
		 * setLineWidth(1) rather than setLineWidth(getMapMode().LPtoDP(1)).
		 * This small piece of code detects this case and simply returns the
		 * line width.
		 */
		if (zoom < 0.04 && w <= 5) {
			return w;
		}
		/*
		 * We interestingly add 0.1 to eliminate rounding errors with HiMetric
		 * map mode. This has no effect with identity/pixel map mode.
		 */
		return (float)((zoom * w) + 0.1);
	}
	
	private int[] zoomPointList(int[] points) {
		int[] scaled = null;
	
		// Look in cache for a integer array with the same length as 'points'
		for (int i = 0; i < intArrayCache.length; i++) {
			if (intArrayCache[i].length == points.length) {
				scaled = intArrayCache[i];
				
				// Move this integer array up one notch in the array
				if (i != 0) {
					int[] temp = intArrayCache[i - 1];
					intArrayCache[i - 1] = scaled;
					intArrayCache[i] = temp;	
				}
			}
		}
		
		// If no match is found, take the one that is last and resize it.
		if (scaled == null) {
			intArrayCache[intArrayCache.length - 1] = new int[points.length];
			scaled = intArrayCache[intArrayCache.length - 1];
		}
		
		// Scale the points
		for (int i = 0; (i + 1) < points.length; i += 2) {
			scaled[i] = (int)(Math.floor((points[i] * zoom + fractionalX)));
			scaled[i + 1] = (int)(Math.floor((points[i + 1] * zoom + fractionalY)));
		}
		return scaled;
	}	
	
	protected Rectangle zoomRect(int x, int y, int w, int h) {
		tempRECT.x = (int)(Math.floor(x * zoom + fractionalX));
		tempRECT.y = (int)(Math.floor(y * zoom + fractionalY));
		tempRECT.width = (int)(Math.floor(((x + w) * zoom + fractionalX))) - tempRECT.x;
		tempRECT.height = (int)(Math.floor(((y + h) * zoom + fractionalY))) - tempRECT.y;
		return tempRECT;
	}
	
	private TextLayout zoomTextLayout(TextLayout layout) {
		TextLayout zoomed = new TextLayout(Display.getCurrent());
		zoomed.setText(layout.getText());
		
		int zoomWidth = -1;
		
		if (layout.getWidth() != -1)
			zoomWidth = ((int)(layout.getWidth() * zoom));
			
		if (zoomWidth < -1 || zoomWidth == 0)
			return null;
		
		zoomed.setFont(zoomFont(layout.getFont()));
		zoomed.setAlignment(layout.getAlignment());
		zoomed.setAscent(layout.getAscent());
		zoomed.setDescent(layout.getDescent());
		zoomed.setOrientation(layout.getOrientation());
		zoomed.setSegments(layout.getSegments());
		zoomed.setSpacing(layout.getSpacing());
		zoomed.setTabs(layout.getTabs());
		
		zoomed.setWidth(zoomWidth);
		int length = layout.getText().length();
		if (length > 0) {
			int start = 0, offset = 1;
			TextStyle style = null, lastStyle = layout.getStyle(0);
			for (; offset <= length; offset++) {
				if (offset != length
						&& (style = layout.getStyle(offset)) == lastStyle)
					continue;
				int end = offset - 1;
				
				if (lastStyle != null) {
					TextStyle zoomedStyle = new TextStyle(zoomFont(lastStyle.font),
							lastStyle.foreground, lastStyle.background);
	                zoomedStyle.metrics = lastStyle.metrics;
	                zoomedStyle.rise = lastStyle.rise;
	                zoomedStyle.strikeout = lastStyle.strikeout;
	                zoomedStyle.underline = lastStyle.underline;
					zoomed.setStyle(zoomedStyle, start, end);
				}
				lastStyle = style;
				start = offset;
			}
		}
		return zoomed;
	}
	
	Point zoomTextPoint(int x, int y) {
		if (localCache.font != localFont) {
			//Font is different, re-calculate its height
			FontMetrics metric = FigureUtilities.getFontMetrics(localFont); 
			localCache.height = metric.getHeight() - metric.getDescent();
			localCache.font = localFont;
		}
		if (targetCache.font != graphics.getFont()) {
			FontMetrics metric = graphics.getFontMetrics();
			targetCache.font = graphics.getFont();
			targetCache.height = metric.getHeight() - metric.getDescent();
		}
		return new Point(((int)(Math.floor((x * zoom) + fractionalX))),
							(int)(Math.floor((y + localCache.height - 1) * zoom 
												- targetCache.height + 1 + fractionalY)));
	}
	
	protected Graphics getGraphics() {
		return graphics;
	}
	
	/**
	 * Logs a warning once if advanced graphics support is not available.
	 */
	private void logAdvancedGraphicsWarning() {
	    if (!advancedGraphicsWarningLogged) {
	        if (Window.getDefaultOrientation() == SWT.RIGHT_TO_LEFT) {
	            Log
	                .warning(
	                    Draw2dPlugin.getInstance(),
	                    IStatus.WARNING,
	                    "Advanced graphics support is not available in right-to-left mode.  Diagrams might not look as nice as they could in right-to-left mode."); //$NON-NLS-1$
	        } else {
	            Log
	                .warning(
	                    Draw2dPlugin.getInstance(),
	                    IStatus.WARNING,
	                    "Unable to load advanced graphics library.  Diagrams might not look as nice as they could with an advanced graphics library installed (e.g. Cairo or GDI+)"); //$NON-NLS-1$
	        }
	        advancedGraphicsWarningLogged = true;
	    }
	}
}
