/*******************************************************************************
 * Copyright (c) 2000, 2010 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
 *******************************************************************************/
package org.eclipse.draw2d;

import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Control;

import org.eclipse.draw2d.geometry.Rectangle;
import org.eclipse.draw2d.rap.swt.SWT;

class BufferedGraphicsSource implements GraphicsSource {

	// UNSUPPORTED - bypass buffer handling since offscreen rendering is
	// not possible in RAP
	// private Image imageBuffer;
	private GC imageGC;
	private GC controlGC;
	private Control control;
	private Rectangle inUse;

	/**
	 * Constructs a new buffered graphics source using the given control.
	 * 
	 * @since 2.1
	 * @param c
	 *            the control
	 */
	public BufferedGraphicsSource(Control c) {
		control = c;
	}

	/**
	 * @see org.eclipse.draw2d.GraphicsSource#flushGraphics(org.eclipse.draw2d.geometry.Rectangle)
	 */
	public void flushGraphics(Rectangle region) {
		if (inUse.isEmpty())
			return;

		// UNSUPPORTED - Caret is not implemented in the RAP API
		// boolean restoreCaret = false;
		// Canvas canvas = null;
		// if (control instanceof Canvas) {
		// canvas = (Canvas) control;
		// Caret caret = canvas.getCaret();
		// if (caret != null)
		// restoreCaret = caret.isVisible();
		// if (restoreCaret)
		// caret.setVisible(false);
		// }
		/*
		 * The imageBuffer may be null if double-buffering was not successful.
		 */
		// UNSUPPORTED - bypass buffer handling since offscreen rendering is
		// not possible in RAP
		// if (imageBuffer != null) {
		// imageGC.dispose();
		// controlGC.drawImage(getImage(), 0, 0, inUse.width, inUse.height,
		// inUse.x, inUse.y, inUse.width, inUse.height);
		// imageBuffer.dispose();
		// imageBuffer = null;
		// imageGC = null;
		// }
		if (controlGC != null) {
			controlGC.dispose();
		}
		controlGC = null;

		// UNSUPPORTED - Caret is not implemented in the RAP API
		// if (restoreCaret)
		// canvas.getCaret().setVisible(true);
	}

	/**
	 * @see org.eclipse.draw2d.GraphicsSource#getGraphics(org.eclipse.draw2d.geometry.Rectangle)
	 */
	public Graphics getGraphics(Rectangle region) {
		if (control == null || control.isDisposed())
			return null;

		org.eclipse.swt.graphics.Point ptSWT = control.getSize();
		inUse = new Rectangle(0, 0, ptSWT.x, ptSWT.y);
		inUse.intersect(region);
		if (inUse.isEmpty())
			return null;

		/*
		 * Bugzilla 53632 - Attempts to create large images on some platforms
		 * will fail. When this happens, do not use double-buffering for
		 * painting.
		 */
		// UNSUPPORTED - bypass buffer creation since offscreen rendering is
		// not possible in RAP
		// try {
		// imageBuffer = new Image(null, inUse.width, inUse.height);
		// } catch (SWTError noMoreHandles) {
		// imageBuffer = null;
		// } catch (IllegalArgumentException tooBig) {
		// imageBuffer = null;
		// }

		controlGC = new GC(control, control.getStyle()
				& (SWT.RIGHT_TO_LEFT | SWT.LEFT_TO_RIGHT));
		Graphics graphics;
		// UNSUPPORTED - bypass buffer handling since offscreen rendering is
		// not possible in RAP
		// if (imageBuffer != null) {
		// imageGC = new GC(imageBuffer, control.getStyle()
		// & (SWT.RIGHT_TO_LEFT | SWT.LEFT_TO_RIGHT));
		// imageGC.setBackground(controlGC.getBackground());
		// imageGC.setForeground(controlGC.getForeground());
		// imageGC.setFont(controlGC.getFont());
		// imageGC.setLineStyle(controlGC.getLineStyle());
		// imageGC.setLineWidth(controlGC.getLineWidth());
		// imageGC.setXORMode(controlGC.getXORMode());
		// graphics = new SWTGraphics(imageGC);
		// graphics.translate(inUse.getLocation().negate());
		// } else {
		graphics = new SWTGraphics(controlGC);
		// }

		graphics.setClip(inUse);
		return graphics;
	}

	/**
	 * Returns the current image buffer or <code>null</code>.
	 * 
	 * @since 2.1
	 * @return the current image buffer
	 */
	protected Image getImage() {
		// UNSUPPORTED - bypass buffer handling since offscreen rendering is
		// not possible in RAP
		// return imageBuffer;
		return null;
	}

	/**
	 * Returns the current GC used on the buffer or <code>null</code>.
	 * 
	 * @since 2.1
	 * @return the GC for the image buffer
	 */
	protected GC getImageGC() {
		return imageGC;
	}

}
