/*******************************************************************************
 * Copyright (c) 2011 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.stem.loggers.imagewriter.logger.draw;

import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Composite;
import java.awt.Graphics2D;
import java.awt.Shape;
import java.awt.geom.AffineTransform;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.LinkedList;
import java.util.List;

import javax.imageio.ImageIO;

import org.eclipse.stem.core.graph.DynamicLabel;
import org.eclipse.stem.core.graph.DynamicNodeLabel;
import org.eclipse.stem.core.model.Decorator;
import org.eclipse.stem.loggers.imagewriter.ProjectedMapImageLogger;
import org.eclipse.stem.loggers.imagewriter.logger.PolygonHandler;
import org.eclipse.stem.loggers.imagewriter.logger.PolygonHandler.ProjectedPolygons;
import org.eclipse.stem.loggers.imagewriter.logger.projections.IMapProjection;
import org.eclipse.stem.ui.adapters.color.ColorProviderAdapter;
import org.eclipse.stem.ui.adapters.color.STEMColor;

public class MapDrawer 
{
	private static final float MAX_ALPHA_VALUE = 0.75f;
	
	private final ProjectedMapImageLogger logger;
	
	private BufferedImage img;
	private Graphics2D gc;
	private AffineTransform tx;
	
	private ColorProviderAdapter colorProvider;
	private Decorator decorator;
	
	private List<ProjectedPolygons> cachedProjectedPolygons = new LinkedList<ProjectedPolygons>();
	
	private IMapProjection projection;
	private Rectangle2D mapBounds;
	
	// Image Size Parameters
	private int imageWidth;
	private int imageHeight;
	
	// Projection parameters
	//private boolean useProjectionBounds = false;
	//private boolean forceAspectRatio = true;

	
	// Canvas color parameters
	private Color defaultBorderColor = Color.yellow;
	private Color defaultBackgroundColor = Color.black;
	
	private float borderTransparency = 0.25f;
	//private boolean useTransparentBackground = false;

	// Simulation color parameters
	//private boolean useLogScaling = true;
	private float gainFactor = 1.0f;
	
	private AlphaComposite borderCompositeAlpha;
	
	public MapDrawer(Decorator decorator, ProjectedMapImageLogger logger, IMapProjection projection)
	{
		this.projection = projection;
		this.logger = logger;
		this.decorator = decorator;
		
		init();
	}
	
	
	private void prepareShapes()
	{
		for (DynamicLabel label : decorator.getLabelsToUpdate()) {
			if (label instanceof DynamicNodeLabel) {
				ProjectedPolygons pp = PolygonHandler.getPolygonsForProjection(projection, (DynamicNodeLabel)label);
				if (pp != null) {
					cachedProjectedPolygons.add(pp);
				}
			}
		}
	}
	
	private Rectangle2D getBoundsForProjection()
	{
		return projection.getBounds();
	}
	
	private Rectangle2D getBoundsForPolygons()
	{
		Rectangle2D bounds = null;
		for (ProjectedPolygons pp : cachedProjectedPolygons) {
			Rectangle2D shapeBounds = pp.getBoundingBox();
			if (shapeBounds != null) {
				if (bounds == null) {
					bounds = shapeBounds;
				} else {
					bounds = bounds.createUnion(shapeBounds);
				}
			}
		}
		
		if (bounds == null) {
			return getBoundsForProjection();
		}
		
		return bounds;
	}
	
	private void init()
	{
		prepareShapes();

		// Get the boundaries for the map space
		if (logger.isFitToShapeBounds()) {
			// Otherwise, we want to fit the bounds to the bounding box of the
			// polygons to be drawn
			mapBounds = getBoundsForPolygons();
		} else {
			// If configured to show the "whole earth", then we want to 
			// get the projection boundaries from the map projection
			mapBounds = getBoundsForProjection();
		}
				
		imageWidth = logger.getWidth();
		imageHeight = logger.getHeight();

		// If configured to hold aspect, then re-calculate the image width/height based on the shortest
		// edge of the map projection boundaries
		if (logger.isForceAspectRatio()) {
			double aspect = Math.min(imageWidth / mapBounds.getWidth(), imageHeight / mapBounds.getHeight());
			imageWidth = (int)(mapBounds.getWidth() * aspect);
			imageHeight = (int)(mapBounds.getHeight() * aspect);
		}
		
		// Calculate the transform from map (projected geographic) coordinates to image coordinates
		tx = new AffineTransform();
		tx.scale(imageWidth / mapBounds.getWidth(), imageHeight / mapBounds.getHeight());
		tx.translate(-mapBounds.getX(), -mapBounds.getY());
		
		// Create the buffered image to back the drawing
		img = new BufferedImage(imageWidth,imageHeight, BufferedImage.TYPE_INT_ARGB);
		gc = img.createGraphics();

		// Set the border transparency level
		borderCompositeAlpha = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, borderTransparency);

		gainFactor = logger.getGain();
		if (gainFactor <= 0f) {
			gainFactor = 1.0f;
		}
		
		int borderTransparency = logger.getBorderTransparency();
		if (borderTransparency >= 0 && borderTransparency <= 1) {
			this.borderTransparency = (float)borderTransparency / 100.0f;
		}
		
		
		
		reset();
	}
	
	
	public void setColorProvider(ColorProviderAdapter cp)
	{
		this.colorProvider = cp;
	}
	
	public void reset()
	{
		 gc.setBackground(Color.white);
         gc.clearRect(0,0, img.getWidth(), img.getHeight());
		
		
//		gc.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1.0f));
//		gc.setBackground(Color.black);
//		gc.setPaint(Color.black);
//		gc.fillRect(0, 0, imageWidth,imageHeight);
	}
	

	public void save(File imagePath, String imageFormat)
	{
		try {
			ImageIO.write(img, imageFormat, imagePath);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	
	public void close()
	{
		img.flush();
		gc.dispose();
		gc = null;
		img = null;
	}
	

	private void drawBackground()
	{
		if (logger.isTransparentBackground()) {
			return;
		}
		
		Color backgroundColor;
		STEMColor backgroundColorStem = colorProvider.getBackgroundFillColor();
		if (backgroundColorStem != null) {
			backgroundColor = backgroundColorStem.toAWTColor();
		} else {
			backgroundColor = defaultBackgroundColor;
		}
		
		
		gc.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1.0f));
		gc.setBackground(backgroundColor);
		gc.setPaint(backgroundColor);
		gc.fillRect(0, 0, imageWidth,imageHeight);
		
	}
	
	private Color getBorderColor()
	{
		Color borderColor;
		STEMColor borderColorStem = colorProvider.getBorderColor();
		if (borderColorStem != null) {
			borderColor = borderColorStem.toAWTColor();
		} else {
			borderColor = defaultBorderColor;
		}
		
		return borderColor;
	}
	
	public void draw()
	{
		reset();
		Composite heldComposite = gc.getComposite();
		drawBackground();
		
		Color borderColor = getBorderColor();
		
		for (ProjectedPolygons node : cachedProjectedPolygons) {
			for (Shape polygon : node.polygons) {	
				
				Shape projectedShape = tx.createTransformedShape(polygon);
				colorProvider.setTarget(node.identifiable);
				STEMColor color = colorProvider.getColor(gainFactor, logger.isLogScaling());
				
				gc.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, color.getAlpha() * MAX_ALPHA_VALUE));
				gc.setColor(color.toAWTColor());
				gc.fill(projectedShape);
				
				gc.setComposite(borderCompositeAlpha);
				gc.setColor(borderColor);
				gc.draw(projectedShape);
			}
		}	
		
		gc.setComposite(heldComposite);
	}

	
}
