package org.eclipse.nebula.widgets.nattable.renderer.swt.graphics

import java.util.Map
import java.util.Stack
import org.eclipse.nebula.widgets.nattable.core.geometry.PixelRectangle
import org.eclipse.nebula.widgets.nattable.core.graphics.Color
import org.eclipse.nebula.widgets.nattable.core.graphics.GraphicsContext
import org.eclipse.swt.SWT
import org.eclipse.swt.graphics.GC
import org.eclipse.swt.graphics.Rectangle
import org.eclipse.swt.widgets.Composite

import static org.eclipse.nebula.widgets.nattable.renderer.swt.graphics.GraphicsPropertiesEnum.*

/**
 * Proxy implementation of {@link IGraphicsContext} to provide the drawing
 * capabilities by {@link GC} so the NatTable can be painted using this.
 * 
 * @author Dirk Fauth
 *
 */
class SWTGraphicsContext implements GraphicsContext {
	
	val Composite composite
	/**
	 * The SWT {@link GC} which is proxied by this implementation.
	 */
	val GC gc
	val stateStack = new Stack<Map<GraphicsPropertiesEnum, Object>>
	
	Map<GraphicsPropertiesEnum, Object> originalState = newHashMap
	double xOffset
	double yOffset
	int foregroundAlpha = 255
	int backgroundAlpha = 255
	
	/**
	 * Create a new proxy instance for the specified {@link GC}.
	 * @param gc The SWT {@link GC} which is proxied by this implementation.
	 */
	new(Composite composite, GC gc) {
		if (composite == null) throw new IllegalArgumentException("composite can not be null"); //$NON-NLS-1$
		if (gc == null) throw new IllegalArgumentException("gc can not be null"); //$NON-NLS-1$
		this.composite = composite
		this.gc = gc
	}
	
	def getSWTComposite() {
		composite
	}
	
	def getXOffset() { xOffset }
	def getYOffset() { yOffset }
	
	// GraphicsContext interface
	
	override pushState() {
		stateStack.push(originalState)
		originalState = newHashMap
	}
	
	override popState() {
		for (property : originalState.keySet) {
			val originalValue = originalState.get(property)
			switch (property) {
				case FOREGROUND_COLOR: gc.foreground = originalValue as org.eclipse.swt.graphics.Color
				case FOREGROUND_ALPHA: foregroundAlpha = originalValue as Integer
				case BACKGROUND_COLOR: gc.background = originalValue as org.eclipse.swt.graphics.Color
				case BACKGROUND_ALPHA: backgroundAlpha = originalValue as Integer
				case CLIP_BOUNDS: gc.clipping = originalValue as Rectangle
				case X_OFFSET: xOffset = originalValue as Double
				case Y_OFFSET: yOffset = originalValue as Double
			}
		}
		originalState = stateStack.pop
	}
	
	override translate(double deltaX, double deltaY) {
		originalState.put(X_OFFSET, xOffset)
		originalState.put(Y_OFFSET, yOffset)
		
		xOffset = xOffset + deltaX
		yOffset = yOffset + deltaY
	}
	
	override setForegroundColor(Color foregroundColor) {
		originalState.put(FOREGROUND_COLOR, gc.foreground)
		originalState.put(FOREGROUND_ALPHA, foregroundAlpha)
		
		gc.foreground = new org.eclipse.swt.graphics.Color(
			gc.device,
			foregroundColor.red,
			foregroundColor.green,
			foregroundColor.blue
		)
		foregroundAlpha = foregroundColor.alpha
	}
	
	override setBackgroundColor(Color backgroundColor) {
		originalState.put(BACKGROUND_COLOR, gc.background)
		originalState.put(BACKGROUND_ALPHA, backgroundAlpha)
		
		gc.background = new org.eclipse.swt.graphics.Color(
			gc.device,
			backgroundColor.red,
			backgroundColor.green,
			backgroundColor.blue
		)
		backgroundAlpha = backgroundColor.alpha
	}
	
	override getClipBounds() {
		new PixelRectangle((gc.clipping.x - xOffset), gc.clipping.y - yOffset, gc.clipping.width, gc.clipping.height)
	}
	
	override setClipBounds(PixelRectangle clipBounds) {
		originalState.put(CLIP_BOUNDS, gc.clipping)
		gc.clipping = new Rectangle((xOffset + clipBounds.x) as int, (yOffset + clipBounds.y) as int, clipBounds.width.intValue, clipBounds.height.intValue)
	}
	
	override drawLine(double x1, double y1, double x2, double y2) {
		gc.alpha = foregroundAlpha
		gc.drawLine((xOffset + x1) as int, (yOffset + y1) as int, (xOffset + x2) as int, (yOffset + y2) as int)
	}
	
	override drawRectangle(PixelRectangle rect) {
		gc.alpha = foregroundAlpha
		gc.drawRectangle((xOffset + rect.x) as int, (yOffset + rect.y) as int, rect.width.intValue, rect.height.intValue)
	}
	
	override fillRectangle(PixelRectangle rect) {
		gc.alpha = backgroundAlpha
		gc.fillRectangle((xOffset + rect.x) as int, (yOffset + rect.y) as int, rect.width.intValue, rect.height.intValue)
	}
	
	override clearRectangle(PixelRectangle rect) {
		fillRectangle(rect)
	}
	
	override drawText(String text, double x, double y) {
		gc.alpha = foregroundAlpha
		gc.drawText(text, (xOffset + x) as int, (yOffset + y) as int, SWT::DRAW_TRANSPARENT.bitwiseOr(SWT::DRAW_DELIMITER))
		
		//TODO draw underline and strikethrough in here instead of the TextPainter itself
	}
	
	override calculateTextWidth(String text) {
		gc.textExtent(text).x
	}
	
	override getFontHeight() {
		gc.fontMetrics.height
	}
	
}