package ch.epfl.isochrone.tiledmap;

import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.geom.Ellipse2D;
import java.awt.image.BufferedImage;

import ch.epfl.isochrone.geo.PointOSM;
import ch.epfl.isochrone.timetable.FastestPathTree;
import ch.epfl.isochrone.timetable.Stop;

/**
 * Classe servant un fournisseur de tuile isochrone
 * 
 * @author Charles Thiebaut (238935)
 * @author Arnaud Delamare (234841)
 * 
 */
public final class IsochroneTileProvider implements TileProvider {
	private FastestPathTree tree; 
	private ColorTable colorTable;
	private double speed;
	
	/**
	 * 
	 * @param tree
	 *        L'arbre des trajets
	 * @param colorTable
	 *        La table des couleurs pour les différentes tranches
	 * @param speed
	 *        La vitesse de marche à pied
	 */
	public IsochroneTileProvider(FastestPathTree tree, ColorTable colorTable, double speed)
	{
		this.tree = tree; 
		this.colorTable = colorTable; 
		this.speed = speed; 
	}
	
	/**
	 * Retourne la Tile aux coordonnées demandées, en créant des disques de différentes couleurs selon le temps d'arrivée aux différents arrêts
	 *
     * 
     * @param zoom
     *        Le zoom de la Tile
     *        
     * @param x
     *        La position x de la Tile
     *        
     * @param y
     *        La position y de la Tile
     */
    @Override
    public Tile tileAt(int zoom, int x, int y) {
       
        double pixelLengthX = new PointOSM(zoom, x * 256, y * 256).toWGS84().distanceTo(new PointOSM(zoom, x * 256 + 1, y * 256).toWGS84());  // la largeur d'un pixel en m
        double pixelLengthY = new PointOSM(zoom, x * 256, y * 256).toWGS84().distanceTo(new PointOSM(zoom, x * 256, y * 256 + 1).toWGS84());
        
        BufferedImage image =
                new BufferedImage(256, 256, BufferedImage.TYPE_INT_ARGB);
        Graphics2D g = image.createGraphics();

        g.setColor(colorTable.sliceColor(colorTable.numberOfSlice()));
        g.fillRect(0, 0, image.getWidth(), image.getHeight());
        g.setRenderingHint (RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        
        int cornerX = new PointOSM(zoom, x * 256, y * 256).roundedX();
        int cornerY = new PointOSM(zoom, x * 256, y * 256).roundedY();
        
        for(int i=colorTable.numberOfSlice(); i>=1; i--)
        {
            for (Stop s : tree.stops())
            {
                int t = colorTable.sliceLength()*i - tree.arrivalTime(s) + tree.startingTime();
                if (t>0)
                {
                    double r1 = speed*t/pixelLengthX;
                    double r2 = speed*t/pixelLengthY;
                    
                    g.setColor(colorTable.sliceColor(i-1));
                    g.fill(new Ellipse2D.Double(s.position().toOSM(zoom).x()-cornerX-r1, s.position().toOSM(zoom).y()-cornerY-r2, r1*2, r2*2));
                }
            }
        }
    	

        return new Tile(x, y, zoom, image);
    }

}
