package code;

import java.awt.Dimension;
import java.awt.Image;
import java.io.IOException;
import java.net.URL;
import java.net.URLEncoder;
import java.util.Date;

import javax.imageio.ImageIO;

import org.eclipse.emf.ecore.EObject;


public class StaticMap {
	private final String URLRoot="http://maps.googleapis.com/maps/api/staticmap";

	protected void onError(URL urlRequest, String status, Exception ex) {
		storageRequest(urlRequest.toString(), "Static maps request", "NO STATUS", ex);
	}

	protected void storeInfoRequest(URL urlRequest, String info, String status, Exception exception) {
		storageRequest(urlRequest.toString(), "Static maps request", "OK", exception);
	}

	//Stock request
	protected static String[][] stockRequest=new String[0][6];
	private static int numRequest=0;

	private void storageRequest(String urlRequest,String info,String status,
			Exception exception){
		Date date = new Date();
		numRequest+=1;
		stockRequest=(String[][])(this.resizeArray(stockRequest,numRequest));
		if(stockRequest[numRequest-1]==null){
			stockRequest[numRequest-1]=new String[6];
		}
		stockRequest[numRequest-1][0]=String.valueOf(numRequest);
		stockRequest[numRequest-1][1]=date.toString();
		stockRequest[numRequest-1][2]=status;
		stockRequest[numRequest-1][3]=urlRequest;
		stockRequest[numRequest-1][4]=info;
		if(exception==null){
			stockRequest[numRequest-1][5]="No exception";
		}else{
			stockRequest[numRequest-1][5]=exception.toString();
		}
	}


	/**
	 * Creates a static map according the parameters
	 * @param model model from which the map will be created
	 * @param zoom zoom of the map
	 * @param size size of the map
	 * @param scale number of pixels
	 * 
	 * @return Image containing the map
	 * @throws IOException
	 */
	public Image getStaticMap(EObject model,int zoom,Dimension size,int scale) throws IOException{
		String format = "png";
		String maptype = "roadmap";

		// map center 
		String cityName = model.eGet(model.eClass().getEStructuralFeature("name")).toString();
		String markers = null;
		String icon = null;
		
		for(EObject place : model.eContents()){	
			// types of places
			if(place.eClass().getName().equals("House")){
				icon = "color:orange|label:L|";
			}else if(place.eClass().getName().equals("Bank")){
				icon = "color:yellow|label:B|";
			}else if(place.eClass().getName().equals("University")){
				icon = "color:blue|label:U|";
			}else if(place.eClass().getName().equals("HealthFacility")){
				icon = "color:red|label:H|";
			}else if(place.eClass().getName().equals("Supermarket")){
				icon = "color:green|label:M|";
			}else if(place.eClass().getName().equals("Dormitory")){
				icon = "color:brown|label:D|";
			}else if(place.eClass().getName().equals("School")){
				icon = "color:purple|label:S|";
			}

			for(EObject addresse : place.eContents()){
				String number = (addresse.eGet(addresse.eClass().getEStructuralFeature("number"))).toString();
				for(EObject reference : addresse.eContents()){
					String referenceName = reference.eGet(reference.eClass().getEStructuralFeature("name")).toString();		
					String buildingAddress = null;
					if(reference.eClass().getName().equals("Street")){
						buildingAddress = cityName+"+"+number+"+rue+"+referenceName;
						String marker = "&markers=" + URLEncoder.encode(icon+buildingAddress, "utf-8");
						if(markers == null){
							markers = marker;
						}else{
							markers = markers + marker;
						}
					}else if(reference.eClass().getName().equals("Avenue")){
						buildingAddress = number+"+avenue+"+referenceName+"+"+cityName;
						String marker = "&markers=" + URLEncoder.encode(icon+buildingAddress, "utf-8");
						if(markers == null){
							markers = marker;
						}else{
							markers = markers + marker;
						}
					}

				}
			}
		}


		String prefix = URLRoot + 
				"?center="+ 
				URLEncoder.encode(cityName, "utf-8") + 
				"&zoom=" + zoom +
				"&size=" + size.width + "x" + size.height + 
				"&scale=" + scale +
				"&format=" + format + "&maptype=" + maptype;

		URL url=new URL(prefix + markers);
		try {
			Image imageReturn;
			imageReturn=ImageIO.read(url);
			storeInfoRequest(url,null,null,null);
			return imageReturn;
		} catch (Exception e) {
			onError(url, "NO STATUS", e);
			return null;
		}

	}


	/**
	 * Author: Christian d'Heureuse (from : www.source-code.biz, www.inventec.ch/chdh)
	 * Reallocates an array with a new size, and copies the contents
	 * of the old array to the new array.
	 * @param oldArray  the old array, to be reallocated.
	 * @param newSize   the new array size.
	 * @return          A new array with the same contents.
	 */
	protected Object resizeArray (Object oldArray, int newSize) {
		int oldSize = java.lang.reflect.Array.getLength(oldArray);
		Class elementType = oldArray.getClass().getComponentType();
		Object newArray = java.lang.reflect.Array.newInstance(
				elementType, newSize);
		int preserveLength = Math.min(oldSize, newSize);
		if (preserveLength > 0)
			System.arraycopy(oldArray, 0, newArray, 0, preserveLength);
		return newArray; 
	}
}
