/*
 * Copyright Kilo project team, 2004. All rights reserved.
 */
package shared;

import java.awt.*;
import java.awt.image.*;
/**
 * Child class of Renderer for the generation of a MapImage for display by the Applet
 * 
 * @author Alaric [ajrn2]
 * @version 1.0
 */
public class RouteRenderer extends Renderer
{
	private Color defaultBG = Color.white;
	private Color defaultFG = new Color(255, 0, 0, 70);
	
	public MapImage render(Object o, Position origin, float scale)
	{	/* DO NOT USE THIS render NO BACKGROUND MAP */
		this.mapOrigin=origin;
		this.mapScale=scale;
		return null;
	}
	public RouteRenderer(Color bg, Color fg){
		this.bgColour=bg;
		this.fgColour=fg;
	}
	public RouteRenderer(){
		this.bgColour=defaultBG;
		this.fgColour=defaultFG;
	}
	
	/**
	 * A method to highlight a section of the instructions on the rendered map. Requires the use of all the RouteRendering functionality again and depends on method render(...). 
	 * 
	 * @param instructions an array of instructions to retrieve the data used for highlighting from
	 * @param indexIntoInstructions an int specifying which instruction should be highlighted
	 * @param r the Route object being rendered
	 * @param m the background MapImage object for the RouteRenderer to draw onto
	 * @return a MapImage with the section of instruction highlighted
	 */
	public MapImage highlightInstruction(Instruction[] instructions, int indexIntoInstructions, Route r, MapImage m){
		//highlights a section of the Route.
		
		// <glj20> fix bug where user clicks on empty instructions text box
		if (instructions == null)
			return null;
		// </glj20>
		
		Route preRoute = new Route();
		Route newRoute = new Route();
		Route postRoute = new Route();
		if((indexIntoInstructions==(instructions.length-1))||(indexIntoInstructions==0)){
			//System.out.println("Instruction index "+indexIntoInstructions);
			return render(r,m);
		}
		Instruction startInstruction = instructions[indexIntoInstructions];
		Instruction endInstruction = instructions[indexIntoInstructions+1];
		Position[] currentRoute = r.getPositions();
		int startRouteIndex = 0;
		for(int i = 0; i < currentRoute.length; i++){
			preRoute.add(currentRoute[i]);
			if((currentRoute[i].getX()==startInstruction.getPosition().getX())&&(currentRoute[i].getY()==startInstruction.getPosition().getY())){
				startRouteIndex = i;
				//System.out.println("Start route index="+i+" "+currentRoute[i].getX()+","+currentRoute[i].getY());
				break;
			}
		}
		int endRouteIndex = 0;
		//now traverse along Route adding them to newRoute
		for(int j = startRouteIndex; j < currentRoute.length; j++){
			newRoute.add(currentRoute[j]);
			if((currentRoute[j].getX()==endInstruction.getPosition().getX())&&(currentRoute[j].getY()==endInstruction.getPosition().getY())){
				//System.out.println("End route index="+j+" "+currentRoute[j].getX()+","+currentRoute[j].getY());
				endRouteIndex = j;
				break;
			}
		}
		
		for(int k = endRouteIndex; k < currentRoute.length; k++){
			postRoute.add(currentRoute[k]);
		}
		MapImage first = render(preRoute, m);
		this.fgColour=new Color(0,0,255,100);
		MapImage second = render(newRoute, first);
		this.fgColour=defaultFG;
		MapImage newMapImage = render(postRoute, second);
		return newMapImage;
		
	}
	/**
	 * Render function being defined from the abstract parent class, returns a MapImage object that encapsulates the BufferedImage object to be displayed
	 * 
	 * @author Alaric [ajrn2]
	 * @since 1.0
	 * @param o an object argument that is cast to a Route object, contains route information to be drawn
	 * @param image a background image to be drawn
	 * @return a MapImage object that contains the rendered image and scale and origin information about the map just drawn
	 */
	public MapImage render(Object o, MapImage image)
	{	
		//use image as a background image
		//derive the origin and scale from it.
		boolean drawBG = false;
		//check for being provided a background image
		if(image==null){
			this.mapOrigin= new Position(0,0);
			this.mapScale=4;
		}
		else{
			drawBG=true;
			this.mapOrigin=image.getOrigin();
			this.mapScale=image.getScale();
		}
		

		//otherwise continue
		BufferedImage drawnMap = new BufferedImage(MAPX, MAPY, BufferedImage.TYPE_INT_ARGB);
		this.graphics=drawnMap.createGraphics();
		if(image!=null&&image.getImage()!=null){
			this.addBG(image.getImage());
		}

		//cast the Route object
		Route route=(Route)o;
		if(route==null){
			//return a MapImage with just the background image
			return new MapImage(mapOrigin, mapScale, drawnMap);
		}
		//get an array of positions of roads to render
		Position[] listOfPositions = route.getPositions();
		for(int i=0; i < listOfPositions.length; i++){
			//iterate over the listOfPositions
			//System.out.println()
			//this.drawVertex(listOfPositions[i]);
			try{
				//System.out.println("NEWPOSITION FROM-("+listOfPositions[i].getX()+","+listOfPositions[i].getY()+") TO ("+listOfPositions[i+1].getX()+","+listOfPositions[i+1].getY()+")");
				this.drawVertex(listOfPositions[i]);
				this.drawRoad(listOfPositions[i],listOfPositions[i+1]);
			}
			catch(ArrayIndexOutOfBoundsException e){}//we don't care it's the last point
			finally{
				//System.out.println("\n");
			}
			
		}
		return new MapImage(mapOrigin, mapScale, drawnMap);
	}
	
}

