package org.eclipse.stem.ui.ge;
/*******************************************************************************
 * Copyright (c) 2006 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
 *******************************************************************************/ 
import java.io.File;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.eclipse.core.runtime.Preferences;
import org.eclipse.emf.common.notify.Notifier;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.edit.provider.ItemPropertyDescriptor;
import org.eclipse.stem.core.common.DublinCore;
import org.eclipse.stem.core.graph.Graph;
import org.eclipse.stem.core.graph.Node;
import org.eclipse.stem.core.graph.NodeLabel;
import org.eclipse.stem.core.model.Decorator;
import org.eclipse.stem.core.model.Model;
import org.eclipse.stem.core.scenario.Scenario;
import org.eclipse.stem.core.sequencer.Sequencer;
import org.eclipse.stem.definitions.adapters.relativevalue.RelativeValueProvider;
import org.eclipse.stem.definitions.adapters.relativevalue.RelativeValueProviderAdapter;
import org.eclipse.stem.definitions.adapters.relativevalue.RelativeValueProviderAdapterFactory;
import org.eclipse.stem.definitions.adapters.spatial.geo.LatLong;
import org.eclipse.stem.definitions.adapters.spatial.geo.LatLongProvider;
import org.eclipse.stem.definitions.adapters.spatial.geo.LatLongProviderAdapter;
import org.eclipse.stem.definitions.adapters.spatial.geo.LatLongProviderAdapterFactory;
import org.eclipse.stem.definitions.adapters.spatial.geo.PlatformLatLongDataProvider;
import org.eclipse.stem.definitions.adapters.spatial.geo.LatLong.Segment;
import org.eclipse.stem.definitions.nodes.impl.RegionImpl;
import org.eclipse.stem.data.geography.GeographicNames;
import org.eclipse.stem.jobs.preferences.PreferenceConstants;
import org.eclipse.stem.jobs.simulation.ISimulation;
import org.eclipse.stem.jobs.simulation.ISimulationListener;
import org.eclipse.stem.jobs.simulation.ISimulationManagerListener;
import org.eclipse.stem.jobs.simulation.SimulationEvent;
import org.eclipse.stem.jobs.simulation.SimulationManager;
import org.eclipse.stem.jobs.simulation.SimulationManagerEvent;
import org.eclipse.stem.jobs.simulation.SimulationState;
import org.eclipse.stem.ui.ge.kml.KmlDisplaySelection;
import org.eclipse.stem.ui.ge.kml.StemKml;
import org.eclipse.stem.ui.ge.views.GEPreferencePage;
import org.eclipse.stem.ui.ge.views.GEView;
import org.eclipse.stem.ui.views.geographic.map.GeographicSelectionElements;



/**
 * This is the STEM half of the interface between 
 * STEM and GoogleEarth.
 * 
 * It listens for Simulations to be added or deleted and maintains a 
 * list of simulations.  When a simulation becomes active it then 
 * listens for Simulation events.   
 * <p>
 * When a simulation cycle completes, we are notified and 
 * it will take the STEM data and call StemKml to convert 
 * it to KML and either log it to a set of files for later display 
 * or send it directly to GoogleEarth.
 * <p>
 * The overall process flow is the following:
 * <pre>
 *   <b>simulationsChanged:</b> Notified when a new Simulation is added
 *   or removed.  If added then setActive() is called to add it to 
 *   the list of Simulations being handled.
 *   
 *   <b>simulationChanged:</b> Notified when a cycle ends. It calls 
 *   the processCycle method.
 *   
 *   <b>processCycle</b>Main process when a processing cycle ends.
 *     
 *     <b>buildMap()</b> called on 1st cycle to build a map of  
 *     GEData instances that contains the geographic description 
 *     of each county/areaid
 *     
 *     It then uses the PreferencePage option to decide how to 
 *     comunicate with GoogleEarth.  
 *     
 *      <b>storeSEIR()</b> This updates the GEData instances with the 
 *      relative disease statistics.
 *      
 *      <b>generateKML()</b> This sends all the information to the 
 *      GEJob instance where a KML file for this cydle is written.
 *      
 * </pre>
 *    
 */

public class GEInterface 
           implements ISimulationListener, ISimulationManagerListener{
		
	 /**
     * template for the KML filename written on the 
     * Nth cycle for type T
     */
    private static final String controlTemplate = "control_&N_&T.kml";
    
    
	/**
	 * List of active simulations keyed by Name
	 * 
	 * The list is updated by SimulationManager events
	 * that add or remove simulations.
	 */
	private Map<String,GESimEntry> activeSimulations = null;
	
	
	/**
	 * map of geographic data keyed by area id
	 */
	private Map<String, GEData> stemMap = null;
	
	/**
	 * GEView handles all the gui ui for us
	 */
	private GEView geView = null;
	
	/**
	 * This will contain the simulation id when that simulation 
	 * is sending its KML to GoogleEarth.  When it is filled
	 * in any subsequent requests to log and view will only do logging.
	 * It is cleared when the simulation is removed.
	 */
	private String activeView = null;
	
	/**
	 * when set to a node name then the displayMap method
	 * will only display that node.
	 */
	private String displayNode = null;
	/**
	 * Cycle being processed.
	 */
	//private int cycle = 0;
	/**
	 * This map is used to collect nodes that have been 
	 * displayed by previous requests so that this can 
	 * be an accumulative display.  
	 */
	private Map<String,GEData> stemMapNode = null;
	/**
	 * default Aspect to be displayed for simulations.
	 * Set by GEView context menu to override 
	 * the defaultAspect specified in Aspect.properties
	 */
	private Aspect defaultAspect = null;
	
	/** 
	 * place to store an error message so the caller can get it.
	 */
	private String errorMessage = null;
	/**
	 * when user requests a manual display of map
	 * set this true 
	 */
	private boolean manualRequest = false;
	
	/**
	 * Reference to the display module that 
	 * displays the info based on a selection by
	 * the mapview view 
	 */
	private final KmlDisplaySelection displaySelection = 
		new KmlDisplaySelection();
	/**
	 * remember if we have isssued a displayArea cmd
	 * so we can clean it up.
	 */
	private boolean didDisplayArea = false;
	/**
	 * 
	 * Constructor. 
	 * 
	 * - setup to listen for SimulationManager events
	 * - check if existing simulations.
	 * @param geView  GUI class that is invoking us.
	 */
	public GEInterface(GEView geView) {
		
		GELog.debug(this,"constructor: ");
		
		this.geView = geView;
		Aspect.setup();
		activeSimulations = new HashMap<String,GESimEntry>(1);
		
		
		
	}

	/**
	 * called by GEView to do any initialization 
	 * after we have setup the GUI environment
	 *
	 * It will startup the servlet web server if possible
	 * 
	 * @return true if initialization is successful
	 * 
	 */
    public boolean init() {
    	boolean ok = true;
    	boolean okKML = true;
    	SimulationManager simulationManager = SimulationManager.getManager();
		simulationManager.addSimulationManagerListener(this);
		List<ISimulation>list = simulationManager.getActiveSimulations();
		boolean autolog = GEPreferencePage.isAutoLogging();
		for (ISimulation sim: list) {
			String name = getSimulationId(sim);
		    GELog.debug(this,"simulationAdded: "+name+" "+sim);			
			setActive(sim,autolog);			
		}
    	// check for valid web server
		String url = StemKml.initWebServer();
		GELog.debug(this,"Web server URL: "+url);
		if (url == null ) {
			setErrorMessage("Unable to access WebServer");
			ok = false;
		} else {
			okKML = StemKml.verifyGE();			
			// handle undefined KML
			if (! okKML) {	
				setErrorMessage("GoogleEarth KML files are not defined");
				
			}
		}
		if (!ok || !okKML) {
			// check if preferences will work with no web 
			// server or no KNL file definition
			ok = checkPreferences(url,okKML);
			if (!ok) {
				GELog.debug(getErrorMessage());
			}
		}
		
		return ok;
		
	}

    /**
     * verify (and change) the preferences based on the 
     * environment.  
     * 
     * If a webserver is not available or if googleearth 
     * has not been installed then it will limit the 
     * communication methods to not use a webserve or 
     * not try to launch the kml file.
     * 
     * @param url URL for web server or null
     * @param okGE false if googleEarth not installed
     * @return false if not OK and changes had to be made
     */
    private boolean checkPreferences(String url,boolean okGE) {
    	boolean result = false;
    	int method = GEPreferencePage.getMethod();
    	int newMethod = -1;
		switch (method) {				
			case GEPreferencePage.M_LOG_ONLY:
				// this method alway works
				result = true;
		        break;
			case GEPreferencePage.M_LOG_SERVLET:
				// this method will not work if no server
				result = false; 
				
				if ( url == null && okGE) {
					newMethod = GEPreferencePage.M_AUTO_LAUNCH;
					errorMessage = "No WebServer: Changed to directly launch KML";
					
				} else {
					newMethod = GEPreferencePage.M_LOG_ONLY;
					errorMessage = "KML is not recognized, Changed to only Log files";
				}					
				
		        break;
			case GEPreferencePage.M_ASYNC_SERVLET:
//				 this method will not work if no server
								
				if ( url == null && okGE) {
					newMethod = GEPreferencePage.M_AUTO_LAUNCH;
					errorMessage = "No WebServer: Changed to directly launch KML";
					
				} else {
					newMethod = GEPreferencePage.M_LOG_ONLY;
					errorMessage = "KML is not recognized, Changed to only Log files";
				}					
				
		        break;
			case GEPreferencePage.M_AUTO_LAUNCH:
                 //	 this method will not work if KML is unknown
				  if (! okGE) {
					  newMethod = GEPreferencePage.M_LOG_ONLY;
						errorMessage = "KML is not recognized, Changed to only Log files";
				  }
		  		break;	
			case GEPreferencePage.M_MANUAL_DISPLAY:
				// this method is always OK
				break;

		    default:
		        	
		}
		if (newMethod != -1) {
			GEPreferencePage.setMethod(newMethod);
			result = false;  // tell about change
		}
    	return result;
    }
	/**
	 * We get here because we are listening for SimulationsChanged 
	 * events from the Simulation Manager and one occured. 
	 * We will check for a Simulation being removed and if so check if 
	 * it is one of our active simulation and if so remove it.
	 * If a simulation is being added, it will be added to the list of
	 * active simulations.
	 * 	 
	 */
	public void simulationsChanged(SimulationManagerEvent event) {
		GELog.debug(this.getClass(), "simulationsChanged: ");
		// GELog.memory();
		if (event.getSimulationsRemoved().length > 0) {
			for (ISimulation sim : event.getSimulationsRemoved()) {

				String id = getSimulationId(sim);
				GELog.debug(this.getClass(), "simulationRemoved: " + id + " "
						+ sim);

				GESimEntry existing = activeSimulations.get(id);
				if (existing != null) {
					boolean active = isActiveView(sim);
					setActive(sim, false);
					activeSimulations.remove(id);
					if (active) {
						stopGE();
					}
					GELog.debug(this, "Active simulation removed: " + id);
				}
			}
		} else if (event.getSimulationsAdded().length > 0) {
			boolean autolog = GEPreferencePage.isAutoLogging();
			for (ISimulation sim : event.getSimulationsAdded()) {
				String name = getSimulationId(sim);
				GELog.debug(this, "simulationAdded: " + name + " " + sim);
				GESimEntry existing = activeSimulations.get(name);
				if (existing == null) {
					boolean ok = setActive(sim, autolog);
					if (!ok) {
						if (!autolog) {
							geView.showMessage(errorMessage);
						} 
					}
				}

			}
		}
	} // simulationsChanged
    
	/**
	 * Called by GEView.dispose()
	 * 
	 * 
	 */
	public void dispose() {
		SimulationManager simulationManager = SimulationManager.getManager();
		List<ISimulation> list =simulationManager.getActiveSimulations();
		for (ISimulation sim:list) {
			sim.removeSimulationListener(this);
		}
		simulationManager.removeListener(this);
		if (activeView != null) {
			// GE is talking to us
			stopGE();
			// wait a bit before we continue 
			// because this will kill the webserver 
			// that GoogleEarth is talking to.
			try {
				Thread.sleep(5000);
			} catch (Exception e) {
				// ignore
			}
		}
	}
    /**
	 * Listener for events that happen in a specific Simulation.
	 * 
	 * <code>
	 * This gets called for the following event states
	 *    SimulationState: RUNNING
	 *                     COMPLETED_CYCLE
	 *                     PAUSED  
	 * We are interested in Completed_Cycle 
	 * 
	 * @param event
	 *            the event that records what happened to the manager.
	 */
	
	public void simulationChanged(SimulationEvent event) {
		
		
		try {
			ISimulation simulation = event.getSimulation();
			SimulationState state = event.getSimulationState();
			String id = getSimulationId(simulation);
			GESimEntry existing = activeSimulations.get(id);
            Sequencer seq = simulation.getScenario().getSequencer();
			          
            
			if (state == SimulationState.COMPLETED_CYCLE) {				
				if (existing == null ) {
					GELog.debug(this,"Simulation "+id+" not active for GE.");
					return;
				}
				//existing.cycle++;
				int cycle = seq.getCycle();
				GELog.debug(this,id+" State="+state+" cycle="+cycle); 
				processCycle(simulation,state);
				geView.refresh();
			} else {
				GELog.debug(this,id+" State="+state); 
			}

		} catch (Exception e) {
			GELog.error("simulationChanged: Failure ", e);
		}
	}
	
	/**
	 * Handle the simulation event that just occured
	 * This is where the real processing starts.
	 * If we haven't already, we build a map of the 
	 * geographical information.
	 * Then determine if we want to do anything on this cycle and 
	 * determine how we want to comunicate with GE.  
	 * Next we run thru the scenario nodes and pick up
	 * the current disease state for each node.  
	 * Finally all of the information is sent to a 
	 * background method that builds the KML file that is
	 * sent to GoogleEarth.   
	 *  
	 * @param simulation that event is for
	 * @param state  Current state being processed
	 * 
	 */
	private void processCycle(ISimulation simulation, SimulationState state ) {
		
		String kmlfn = null;		
		boolean doit = false;
		int nth = GEPreferencePage.getWhichCycle();
		
		
			
		String id = getSimulationId(simulation);
		GESimEntry existing = activeSimulations.get(id);
		if (existing == null) {
			GELog.debug(this,"Simulation "+id+" not active for GE.");
			return;
		}
		
		
		int method = existing.getMethod();
		String entryFolder = existing.getLogFolder();
		Scenario scenario = simulation.getScenario();
		Sequencer seq = scenario.getSequencer();
//		 get cycle from simulation
		int cycle = seq.getCycle();
		if (GELog.memoryCheck(0.8) ) {
			GELog.debug(this,"Process for cycle "+
					cycle+" skipped. Memory low");
			return;
		}		
		//if we haven't yet, then build geo map
		if ((stemMap = existing.getStemMap()) == null ) {
			if (! GELog.memoryCheck(0.8) ) {
				stemMap = buildMap(simulation);
			}
			if (stemMap == null) {
				GELog.debug(this.getClass(),"Unable to build stemMap");
				return;
			}
			doit = true;
			existing.setStemMap(stemMap);			
		}
		
		StemKml stemKml = existing.getStemKml();
		if (stemKml == null) {
			stemKml = new StemKml();
			existing.setStemKml(stemKml);			
			stemKml.init();
		}
	    // if ManualDisplay and no user request
		if (method == GEPreferencePage.M_MANUAL_DISPLAY &&
				! manualRequest ) {
			return;
		}
        
		if (cycle == 0 || nth == 1 ) {
			doit = true;
		} else if (nth > 1 && cycle%nth == 0 ) {
			doit = true;
		}

		// Get aspect that we want view of
		Aspect aspect = getAspectToDisplay(simulation);
		if (manualRequest) 
			doit = true;
		// decide how we want to process it
		if (doit) {	
			try {				
				boolean launch = false;	
				boolean rename = false;
				switch (method) {				
					case GEPreferencePage.M_LOG_ONLY:
						// log the file but no launch or netlink						
						if (entryFolder != null) {
							kmlfn = StemKml.getControlFN(entryFolder,
									controlTemplate,aspect, cycle);
						} else {
							doit = false;
						}
				        break;
					case GEPreferencePage.M_LOG_SERVLET:
						// log file and launch a netlink to display
						if ( manualRequest ) {
							doit = true;							
							if (activeView == null) {									
								launch = true;
								kmlfn = StemKml.getControlFile();
							} else {
								kmlfn = StemKml.getControlFN(entryFolder,
										controlTemplate,aspect, cycle);	
							}
						} else if (! id.equals(activeView)) { 
							doit = false;
							GELog.debug(this,"Unable to display id "+id);
						} else if (entryFolder != null) {
							kmlfn = StemKml.getControlFN(entryFolder,
									controlTemplate,aspect, cycle);							
						} else {
							doit = false;
							GELog.debug(this,"Unable to display. Invalid folder");
						}
				        break;
					case GEPreferencePage.M_ASYNC_SERVLET:						

						if ( manualRequest ) {
							if (activeView != null) {
								doit = false;
								GELog.debug(this,"Unable to do manual display");
							} else {
								launch = true;
								kmlfn = StemKml.getControlFile();
							}
						} else {
							if (! id.equals(activeView)) { 						
							   doit = false;
							   GELog.debug(this,"Not an active Simulation id: "+id+" activeView: "+
									   activeView);
							} else {
								kmlfn = StemKml.getControlFile();
								rename = true;
							}
						}
				        break;
					case GEPreferencePage.M_AUTO_LAUNCH:
				  		// build control.kml and launch it
						launch = true;
						kmlfn = StemKml.getControlFile();
						if ( ! manualRequest && (! id.equals(activeView)) ) {							
							doit = false;
							GELog.debug(this,"Invalid. id: "+id+
									          " activeView: "+activeView);
						} 
				  		break;	
					case GEPreferencePage.M_MANUAL_DISPLAY:
						if (manualRequest) {
							GELog.debug(this,"Do manual display");
							launch = true;
							kmlfn = StemKml.getControlFile();
							doit = true;
							
						} else {
							doit = false;
						}
						break;
	
				    default:
				        	
				}
				manualRequest = false;
				if (doit) {
					//	 store the current SEIR data into GEData
					storeAspects(simulation, stemMap);
					
					// generate the KML file
					GELog.debug(this.getClass(),"GenerateKML for id: "+
							id + " aspect "+aspect.toString());
				
					generateKML(kmlfn, stemKml,stemMap, aspect, cycle,launch,rename);
					
					
				}
			} catch (Exception e) {				
				GELog.error("processCycle(): Failure creating KML ",e);
				activeSimulations.remove(id);
			}
		}
		
		//GELog.debug(this.getClass(),"Done. cycle="+cycle);
	}
	
	
	/**
	 *  called by GEView to display the current map for 
	 *  a specific admin area.
	 * 
	 * @param adminFile  File that contains desired data
	 * @param search   String that is matched against area id
	 * @param clear    If true then clear the existing map
	 * @return  true if able to display map or false if could not.
	 */	
	public boolean displayArea( String adminFile,String search, boolean clear) {
		displayNode = search;
		didDisplayArea = true;
		errorMessage = null;
		boolean result = true;
		try {
            if (clear) 
            	stemMapNode = null;
            
			GELog.debug(this,"displayMap() "+adminFile+" search: "+search);
			if (adminFile == null) {				
				errorMessage = "AdminFile argument is null";
				GELog.debug(this,errorMessage);
				return false;
			}
			String fn = StemKml.getDisplayAreaFile();
			
			StemKml stemKml = new StemKml();				
			stemKml.init();				
			// this will create GEData instances with LatLong data
            // The LatLong comes from file rather than simulation
			Map<String,GEData> stemMap = buildMap(adminFile,search);
            if (stemMap.size() == 0) {
            	errorMessage = "Search argument "+search+
            	       " did not match any admin area name.";
            	return false;
            }
			if (stemMapNode == null) {
				stemMapNode = stemMap;
			} else {
				stemMapNode.putAll(stemMap);
			}

//			 Get aspect that we want view of
			Aspect aspect = Aspect.getAspect("S");  
			// generate the KML file	
			boolean rename = false;
            int cycle = 0;
			boolean launch = true;				
			generateKML(fn,stemKml,stemMapNode, aspect,
					cycle,launch,rename);

		} catch (RuntimeException e) {
			result = false;
			GELog.error("DisplayArea failure", e);
		}

		displayNode = null;
		return result;
	}
	/**
	 *  called by GEView to display the specified area
	 *  when a Selection event is received from mapview
	 * 
	 * @param region The Identifiable describing the admin area that 
	 *               was selected.
	 * @param gse  reference to the data about the selection
	 * 
	 * @return  true if able to display map or false if could not.
	 */	
	public boolean displaySelection( RegionImpl region,GeographicSelectionElements gse) {
        didDisplayArea = true;
		errorMessage = null;
		boolean result = true;
		try {           
			
			String fn = StemKml.getDisplayAreaFile();
			
			StemKml stemKml = new StemKml();				
			stemKml.init();				
			
			Map<String,GEData> stemMap = buildSelectionMap(region,gse);
            if (stemMap == null | stemMap.size() == 0) {
            	
            	return false;
            }
			if (stemMapNode == null) {
				stemMapNode = stemMap;
			} else {
				//stemMapNode.putAll(stemMap);
				stemMapNode = stemMap; // clear???
			}

//			 Aspect not used
			Aspect aspect = null;  
			// generate the KML file
			displaySelection.generatePolygons(fn, stemMapNode,aspect);

//			 launch the file for GoogleEarth			  
			StemKml.launch(fn);
			GELog.debug(this,"GoogleEarth Map  submitted");
            
		} catch (RuntimeException e) {
			result = false;
			GELog.error("DisplayArea failure", e);
		}

		displayNode = null;
		return result;
	}
	/**
	 *  called by GEView to display the current map 
	 * This version sets a switch to cause 
	 * a display on the next cycle if simulation or
	 * now if paused. 
	 * 
	 * 
	 * @param simulation The currently selected Simulation
	 * @return  true if able to display map or false if could not.
	 */
	public boolean displayMap(ISimulation simulation) {
		boolean result = true;
		SimulationState state =   simulation.getSimulationState();
		GELog.debug(this,"DisplayMap request");
		manualRequest = true;
		if (state != SimulationState.RUNNING) {	
			// process it if not running.
			processCycle(simulation,simulation.getSimulationState());
		}
	    // if it was running it will do it at end of cycle
		return result;
	}
	

	/**
	 *  called by GEView to display the KML files on GE
	 *  via the Servlet API
	 *  
	 * @param folder 
	 * @return  true if able to display map or false if could not.
	 */
	public boolean runGE(String folder) {
		boolean result = true;
		GELog.debug(this,"GoogleEarth run request");
		if (activeView == null) {	
	        
	        activeView = "runGE";
	        
	        StemKml.setWaitForKML(false);
	        StemKml.launchNetworkLink(folder, null);
		} else {
			errorMessage = "GoogleEarth is busy";
			GELog.debug(this,errorMessage);
			result = false;
			
		}
		return result;
	}
	/**
	 *  called by GEView to start the GoogleEarth 
	 *  application if not already started
	 * 
	 * 
	 * 
	 * @return  true if able to display map or false if could not.
	 */
	public boolean startGE() {
		boolean result = true;	
		GELog.debug(this,"GoogleEarth Start request");
	    StemKml.launchGE();
		
		return result;
	}
	/**
	 *  called by GEView when the GoogleEarth 
	 *  application is being restarted.
	 * 
	 * 
	 * 
	 * @return  true if able to reset or false if could not.
	 */
	public boolean restartGE() {
		boolean result = true;	
		GELog.debug(this,"GoogleEarth Restart request");
	    StemKml.launchGE();
	    int method = 0;
		
		// TODO 
	    // reestablish the communication environment.
	    // If a networklink was active, reestablish it.
	    if (activeView != null)  {
	    	GESimEntry existing = activeSimulations.get(activeView);
			if (existing != null) {
				method = existing.getMethod();
				ISimulation sim = existing.getSimulation();
				if (sim.getSimulationState() == SimulationState.RUNNING){
					errorMessage = 
						"Simulation should be paused while restarting GoogleEarth";
					return false;
						
				}
				String folder = existing.getLogFolder();
			    if (method == GEPreferencePage.M_ASYNC_SERVLET ||
			    	method == GEPreferencePage.M_LOG_SERVLET)	{        
			    	StemKml.launchNetworkLink(folder, null);
			    }
	        }
		}
		return result;
	}
	/**
	 *  called by GEView to stop the current
	 *  display the KML files on GE
	 *  via the Servlet API
	 * 
	 * 
	 * @return  true 
	 */
	public boolean stopGE() {
		boolean result = true;	
		GELog.debug(this,"GoogleEarth Stop request");
		//StemKml.launchGE();
		if (didDisplayArea) {
			StemKml.clearDisplayArea();
		}
		activeView = null;
		// for some reason it appears that sometimes 
		// it takes to writing of an empty control file
		// to stop the current NetworkLink so do it again
		StemKml.launchGE();
		return result;
	}
	/**
	 * Schedule the background job that will build the .kml file 
	 * that will be sent to GoogleEarth 
	 * 
	 * @param fn       Fully qualified Filename where we write the kml
	 * @param stemKml  Object containing info about where and
	 *                 how to generate the KML.
	 * @param stemMap  Map of Polygons with SEIR data and PopDensity
	 * 
	 * @param aspect   SEIR Type to be displayed
	 * @param cycle    current cycle number
	 * @param launch   true if file should be sent to GoogleEarth
	 * @param rename   true if file should be written then renamed
	 * @return reference to the file containing the KML
	 */	
	
	private StemKml generateKML(String fn,StemKml stemKml, Map<String,GEData> stemMap,
			Aspect aspect,long cycle,boolean launch,boolean rename) {	
		try {
			GEJob job = new GEJob("Generate KML");
			job.generateKML(fn,stemKml, stemMap, aspect, cycle,launch,rename);
			
		} catch (Exception e) {			
			e.printStackTrace();
		}
		return stemKml;
	}
	
	
	/**
	 * obtain the current aspect values and store them in the 
	 * GEData instance
	 * 
	 * @param sim
	 * @param stemMap
	 */
	
	private void storeAspects(ISimulation sim,Map<String,GEData> stemMap) {
		
		Scenario scenario = sim.getScenario();		
		//		 We get the decorators from the scenario ...			
		Graph g = scenario.getCanonicalGraph();
		Decorator[] decorators = (Decorator[]) (g.getDecorators().toArray());
		int err1ctr = 0;  // no latlong data
		int err2ctr = 0;  // no aspect data
		for (Decorator decorator : decorators) {
	
			Object[] labels = decorator.getLabelsToUpdate().toArray();
			for (Object element: labels){
				
				if ( element instanceof NodeLabel) {
					NodeLabel nodeLabel = (NodeLabel)element;
					Node node = nodeLabel.getNode();
					
					String key = node.getDublinCore().getTitle();
					
					GEData data = stemMap.get(key);
					
					if (data == null) {	  // filtered previously	
						continue;
					}
					boolean keep = filter(node,key,data);
					if (!keep) 
						continue;
					//if (nodeLabel instanceof SEIRLabelImpl) {
						// TODO we need a way to get PopDensity
						//SEIRLabelImpl label = (SEIRLabelImpl)nodeLabel;
						//DiseaseModelState state = (DiseaseModelState)label.getDiseaseModelState();							
					//	popDensity =50*Math.random(); //state.getPopulationDensity();
					//	data.setPopDensity(popDensity);
					//}
					RelativeValueProviderAdapter rvp = (RelativeValueProviderAdapter) RelativeValueProviderAdapterFactory.INSTANCE
					.adapt(element, RelativeValueProvider.class);
					rvp.setTarget((Notifier)element);
					
					// Does the label have relative values?
					
					if (rvp != null) {	
						Map<String,Double> map = data.getValueMap();
						for (Iterator propertyIter = 
							rvp.getProperties().iterator(); propertyIter.hasNext();) {
							ItemPropertyDescriptor property = 
								(ItemPropertyDescriptor) propertyIter.next();

							String p = property.getDisplayName(property);
							double v = rvp.getRelativeValue(property);
							// TODO debug insert of Infectious value
//							if (key.startsWith("M") && p.equals("I")) {
//								v = Math.random();
//							}
							// if we are keeping track of this aspect
							if (Aspect.exists(p)) {
								map.put(p,v);
							}
						} // for each property
						//  remove debug code
						// To debug this then make the infectious value random
//						if (key.startsWith("Middlesex") && key.contains("MA")) {							
//							GELog.debug(this,key+" Aspects: "+data.getValuesAsString());
//							//GELog.debug(this,"BBox:"+data.getBBox());
//						}
//						if (key.contains("G220010") ) {							
//							GELog.debug(this,key+" Aspects: "+data.getValuesAsString());
//							//GELog.debug(this,"BBox:"+data.getBBox());
//						}
					} else {
						//if (err2ctr == 0) 
						//GELog.debug(this,"Node: "+key+" has no aspect data");
						err2ctr++;
					}

				}
			}  // for
		}
		
		if (err1ctr > 0) 
			GELog.debug(this,"Nodes with no LatLong data. count="+err1ctr);
		if (err2ctr > 0)
		    GELog.debug(this,"Nodes with no aspect values. count="+err2ctr);
	}
	
	/**
	 * Build a StemMap instance for the specified Simulation
	 * 
	 * The StemMap is a HashMap containing GEData objects 
	 * keyed by areaid.  The location object contains the 
	 * geographic borders for the areaid.
	 * 
	 * @param simulation that will be shown
	 * @return Map Key is node, element is GEData instance
	 * 
	 */
	
	private Map<String,GEData> buildMap(ISimulation simulation) {
		try {
			stemMap = new HashMap<String,GEData>();
			
			
			Scenario scenario = simulation.getScenario();
			//String title = scenario.produceTitle();
			//DublinCore dc = scenario.getDublinCore();
			//GELog.debug(this,"buildMap(): title="+title);
			//GELog.debug(this,"buildMap(): DublinCore="+dc);
			
			
			//		 We get the graph...
			final Graph canonicalGraph = scenario.getCanonicalGraph();
			//GELog.debug(this,"buildMap(): canonicalGraph="+canonicalGraph);
			if (canonicalGraph == null) {
				GELog.debug(this,"buildMap(): canonicalGraph is null");
				return null;
			}
			// ...and can now iterate through the nodes. Note that the method
			// "getNodes" returns a map indexed by the URI of each of the nodes,
			// thus we need to get the values of the map to have an actual list to
			// iterator over.				
			int errctr = 0;
			for (final Iterator nodeIter = canonicalGraph.getNodes().values()
					.iterator(); nodeIter.hasNext();) {
				final Node node = (Node) nodeIter.next();
			    String nodeTitle = node.getDublinCore().getTitle();
			    //GELog.debug(this, node+" : "+ nodeTitle);
			    boolean keep = filter(node,nodeTitle,null);
			    if (! keep) 
			    	continue;
			   
                // The node may or may not have lat/long data associated with
				// it, if it doesn't the LatLong that's returned will be empty.
				final LatLong latLongData = getLatLong(node);
				if (latLongData != null && latLongData.size() > 0) {

				    GEData data = new GEData(nodeTitle,latLongData);
				    stemMap.put(nodeTitle,data);
							  
				} else {					
//					if (errctr <= 2) {
//					  GELog.debug(this,"buildMap(): No spacial data\n"+
//							  "Name="+nodeTitle+" Node="+node);
//					}
					errctr++;
				}
				
			} // for each node
			
			if (errctr > 0)
				   GELog.debug(this,"Total buildmap errors = "+errctr);	
			
		} catch (Throwable e) {
			
			GELog.error("Failure building area map", e);
			stemMap = null;
		}
		
		
		return stemMap;	
	}
	/**
	 * Filter out nodes that we are not interested in 
	 * Note: The important filtering is done in the 
	 * filter method in StemKml.  This just affects gathering of 
	 * aspect data .
	 * 	
	 * @param node
	 * @param nodeTitle
	 * @paran data GEData instance for the node
	 * @return true if we should keep the node, false to ignore it
	 */
	boolean filter(Node node,String nodeTitle, GEData data) {
//		 if (GEPreferencePage.isTest()) {
//				if (nodeTitle.indexOf(" US-")< 0 ) {					
//					return false;
//				}
//		 }
//				// ignore alaska
//		if (nodeTitle.indexOf(" US-AK")> 0 ) {					
//					return false;
//		}
////				 ignore hawaii
//		if (nodeTitle.indexOf(" US-HI")> 0 ) {					
//					return false;
//		
		// filter out AdminArea 0 because they "may" be container entries
		int adminarea = getAreaType(node);
		if (adminarea <= 0) {
			GELog.debug(this,"Skip AdminArea 0: "+node);
			return false;
		}
		// debug stuff
		if (displayNode != null) {
			displayNode = displayNode.toLowerCase();			
			if (nodeTitle.toLowerCase().contains(displayNode) ) {
				GELog.debug(this,"Display: "+nodeTitle);
				return true;
			} else {
				//GELog.debug(this,"Do not Display: "+nodeTitle);
				return false;
			}
			
		}
		return true;
	}

	/**
	 * Get the id of the area from the DublinCore instance
	 * @param region Node representing an AdminArea
	 * @return 3 Char ISO id of Country
	 */

	private String getAreaID(Node region) {
		final DublinCore dc = region.getDublinCore();
		final String dcIdentifier = dc.getIdentifier();

		final String isoKey = dcIdentifier.substring(dcIdentifier
				.lastIndexOf("/")+1);
	    return isoKey;
	}
	/**
	 * Get the name of the area from the DublinCore instance
	 * @param region Node representing an AdminArea
	 * @return Name of the AdminArea
	 */

	private String getAreaName(Node region) {
		final DublinCore dc = region.getDublinCore();
		final String dcIdentifier = dc.getIdentifier();

		final String isoKey = dcIdentifier.substring(dcIdentifier
				.lastIndexOf("/")+1);
		// Did we get it?
		if (isoKey != null && isoKey != "") {
			// Yes
			final String geographicName = 
				GeographicNames.getName(isoKey);
			return geographicName;
//			final StringBuilder sb= new StringBuilder(geographicName);
//			sb.append(" (");
//			sb.append(isoKey);
//			sb.append(")");
//			return sb.toString();
		} else {
			return dc.getTitle();
		}
	}
	
	/**
	 * Get the type of the Admin area from the DublinCore instance
	 * @param region
	 * @return 0 1 or 2 (-1 if problem)
	 */

	private int getAreaType(Node node) {
		int areatype = -1;
		final DublinCore dc = node.getDublinCore();
		final String spatial = dc.getSpatial();
    
		if (spatial != null) {
			String mapid = spatial.substring(spatial.lastIndexOf("/") + 1);
			// Did we get it?
			if (mapid != null && mapid != "") {
				//   XXX_0_MAP.xml#XXX
				mapid = mapid.substring(0, mapid.indexOf("#"));
				mapid = mapid.substring(4, 5);
				areatype = Integer.parseInt(mapid);
			}
		}
		return areatype;
	}
	/**
	 * Build a StemMap instance for a specified Spatial location
	 * based on a Selection event from MapView
	 * 
	 * The StemMap is a HashMap containing GEData objects 
	 * keyed by areaid.  The location object contains the 
	 * geographic borders for the areaid.
	 * 
	 * @param region The Identifiable describing the admin area that 
	 *               was selected.
	 * @param gse  Instace of GeographicSelectionElements that was
	 *             passed from MapView when mouseup occurred.
	 * 
	 * @return Map Key is node, element is GEData instance
	 * 
	 */
	
	private Map<String, GEData> buildSelectionMap(RegionImpl region,
			                         GeographicSelectionElements gse) {
		
		try {
			
			DublinCore dc = region.getDublinCore();
			String spatial = dc.getSpatial();
			
            String uriString = spatial.replace("stemspatial:","");
            
			stemMap = new HashMap<String, GEData>();
			PlatformLatLongDataProvider provider = new PlatformLatLongDataProvider();

			URI uriNode = URI.createURI(uriString);                
		    LatLong latLong = provider.getLatLong(uriNode);
		 // get id of the area
			String id = getAreaID(region);
			String name = getAreaName(region);
	    	GEData data = new GEData(id,name, latLong);	    	// Use S just to get it to work
	    	data.setValue(Aspect.getAspect("S"), 01.0);
	    	String description = formatDescription(region,gse);
	    	data.setDescription(description);
	    	double longitude = gse.getLongitude();
	    	double latitude = gse.getLatitude();
	    	GELog.debug(longitude+":"+latitude);
	    	//double[] center = data.getBBoxCenter();
	    	//GELog.debug(center[0]+":"+center[1]);
	    	// set the thumbtack on the point clicked by user
	    	data.setPoint(longitude, latitude);
	    	
	    	stemMap.put(id, data);
			
		} catch (Throwable e) {
			GELog.error("Failure building area map", e);
			stemMap = null;
			errorMessage = "Exception while building Map";
		}

		return stemMap;
	}
	/**
	 * Build a StemMap instance for the specified Simulation
	 * 
	 * The StemMap is a HashMap containing GEData objects 
	 * keyed by areaid.  The location object contains the 
	 * geographic borders for the areaid.
	 * 
	 * @param adminFile file name to use in search
	 * @param search string to look for 
	 * @return Map Key is node, element is GEData instance
	 * 
	 */
	
	private Map<String, GEData> buildMap(String adminFile, String search) {
		
		String baseURI = 
			"platform:/plugin/org.eclipse.stem.geography/" + 
			"resources/data/geo/country/";
		
		try {
            String uriString = baseURI+adminFile;
			stemMap = new HashMap<String, GEData>();
			PlatformLatLongDataProvider provider = new PlatformLatLongDataProvider();

			final URI uri = URI.createURI(uriString);
			final Collection<String> ids = provider.getIds(uri);
			if (ids.size() == 0) {
				errorMessage = "Invalid Country code specified";
				return stemMap;
			}
			String match = search.toLowerCase();
			for (String id : ids) {
				if (id.toLowerCase().contains(match)) {
                    URI uriNode = URI.createURI(uriString + "#" + id);                
				    LatLong latLong = provider.getLatLong(uriNode);
				    if (latLong != null && latLong.size() > 0) {

				    	GEData data = new GEData(id, latLong);
				    	// Use S just to get it to work
				    	data.setValue(Aspect.getAspect("S"), 1.0);
				    	stemMap.put(id, data);
				    } else {
				    	GELog.debug(this, "No spacial data" + " Name=" + id);
				    }
				}

			} // for each id
			if (ids.size() == 0) {
				errorMessage = "No Matching internal Administration area found";
			}
		} catch (Throwable e) {

			GELog.error("Failure building area map", e);
			stemMap = null;
			errorMessage = "Exception while building Map";
		}

		return stemMap;
	}
	
	/**
	 * Create a formated display to use for description 
	 * <pre>
	 *   S:   25.3% 
	 *   I:   10.2%
	 *   ..
	 *   R:    0.0%
	 * </pre>
	 * @return formatted description
	 */
	private String formatDescription(RegionImpl region,
                             GeographicSelectionElements gse) {
		StringBuffer sb = new StringBuffer(128);
		Map<String,Double> relValues = getRelValues(region);
		Set<String> aspects = relValues.keySet();
		sb.append("&lt;pre&gt;");
		sb.append(getAreaID(region));
		sb.append(" &lt;br&gt;");
		for(String aspect:aspects) {			
			Double relValue = relValues.get(aspect)*100;
			// format as "     S: 15.1%"
			String result= String.format("%8s: %5.1f%%",aspect,relValue);
			sb.append(result);
			// add the html formatting 
			sb.append(" &lt;br&gt;");
		}
		sb.append("&lt;pre&gt;");
		return sb.toString();
	}
	
	/**
	 * Get relative values from the Graph.
	 * We are given the RegionImpl for the Admin Area.
	 * We will get the lable from it that contains 
	 * relative values and put then in a Map with 
	 * the value name as the key.
	 * 
	 * @param region
	 * @return Map containing <name:Value>
	 */
	private Map<String,Double> getRelValues(RegionImpl region) {
		Map<String,Double> map = new HashMap<String, Double>();
		
		List<NodeLabel> nodes = region.getLabels();
		for(NodeLabel node:nodes) {		 
			RelativeValueProvider rvp = 
				(RelativeValueProvider) RelativeValueProviderAdapterFactory.INSTANCE
					.adapt(node, RelativeValueProvider.class);
			// Does the label have relative values?
			if (rvp != null) {					
				for (Iterator propertyIter = 
					  rvp.getProperties().iterator(); propertyIter.hasNext();) {
					ItemPropertyDescriptor property = 
						(ItemPropertyDescriptor) propertyIter.next();			
					String name = property.getDisplayName(property);					
					Double value = rvp.getRelativeValue(property);
				    map.put(name, value);								
			    } // for				
			}			
		} // for
        return map;
	}
	/**
	 * Get geographical border of the node. We'd like to have access to lat/long
	 * data of the node if there is any, to do that we use a factory to create
	 * an adapter that knows about the inner details of nodes (it really knows
	 * about all Identifiables) and implements the LatLongProvider interface.
	 * 
	 * @param node
	 * @return border of the node espressed as an array of long/latitude points.
	 */
	LatLong getLatLong(final Node node) {		

		// The node may or may not have lat/long data associated with
		// it, if it doesn't the list that's returned will be empty.

		try {
			final LatLongProviderAdapter latLongProvider = 
				(LatLongProviderAdapter) LatLongProviderAdapterFactory.INSTANCE
			    .adapt(node, LatLongProvider.class);
			latLongProvider.setTarget(node);
			return latLongProvider.getLatLong();
		} catch (RuntimeException e) {
			GELog.debug(this,e.getMessage());
			return null;
		}
	}
	
	
    /**
	 * Check if the specified simulation is actively 
	 * being listened to. A simulation is active if
	 * it is listed in the map of active simulations
	 * and can therefore be manually displayed.
	 * 
	 * @param sim
	 * @return <code>true</code> if active, <code>false</code> in not active or non existent
	 */
    public boolean  isActive(ISimulation sim) {
    	
        String name = getSimulationId(sim);		
		GESimEntry existing = activeSimulations.get(name);
		return (existing == null) ? false : existing.active;
    }
    
    /**
	 * Check if the specified simulation is the simulation
	 * being viewed by GoogleEarth
	 * 
	 * @param sim
	 * @return true if activeView
	 */
    public boolean  isActiveView(ISimulation sim) {
    	
        String name = getSimulationId(sim);		
		return name.equals(activeView);
    }
	/**
	 * Set the logging for the specified simulation.
	 * This creates the GESimEntry which is used to collect 
	 * information about the ISimulation instance to used 
	 * to build KML files.
	 * 
	 * @param sim  Simulation instance being activated 
	 *             (or deactivated) 
	 * @param active  set true to write file, 
	 *                set false to bypass write
	 * @return true if ok, false in failed with
	 *           errorMessage
	 */
	public boolean setActive(ISimulation sim, boolean active) {
		
		String name = getSimulationId(sim);		
		GESimEntry existing = activeSimulations.get(name);
		GELog.debug(this.getClass(),"setActive: "+name+"  "+active);
		if (existing != null) {
			// if already known about
			if (existing.active == active) {
				// no change in state do nothing
				return true;
			} else 	{
				existing.active = active;
				if (!existing.active) {	
//					 do anything if deactivated????
					if (name.equals(activeView))
						activeView = null;				  
				}  
			}			
		} else {
			// new entry			
			existing = new GESimEntry(name,sim);
			existing.active = active;
			activeSimulations.put(name, existing);
			existing.setAspectToDisplay(GEPreferencePage.getAspect());
			
			//Handl this based on communication method
			if (active) {
				String entryFolder = existing.getLogFolder();
				int method = GEPreferencePage.getMethod();
				
				switch (method) {				
				case GEPreferencePage.M_LOG_ONLY:
					// log the file but no launch or netlink
					if (geView != null) {
						entryFolder = GEPreferencePage.getFolder();
						entryFolder = geView.verifyFolder(entryFolder);
						existing.setLogFolder(entryFolder);
						existing.setMethod(method);
					} 
					sim.addSimulationListener(this);
					break;
				case GEPreferencePage.M_LOG_SERVLET:
					// log file and launch a netlink to display				
					if (geView != null) {
						entryFolder = GEPreferencePage.getFolder();
						entryFolder = geView.verifyFolder(entryFolder);
						existing.setLogFolder(entryFolder);
					} 
					if (entryFolder != null) {					
						if (activeView == null) {
							StemKml.setWaitForKML(true);
							StemKml.launchNetworkLink(entryFolder,null);
							activeView = name;
							sim.addSimulationListener(this);
							existing.setMethod(method);
						} else {
							errorMessage ="Simulation "+
								activeView+
								" already active on GoogleEarth.";
							GELog.debug(this,errorMessage);
							existing.active = false;
							return false;
						}
					} 
					break;
				case GEPreferencePage.M_ASYNC_SERVLET:

					// write control.kml and 
					// launch netlink to display control.kml
					// every n seconds
					String kmlfn = StemKml.getControlFile();
					File f = new File(kmlfn);
					String parent = f.getParent()+File.separator;
					kmlfn = f.getName();
					kmlfn = parent+ kmlfn.replace(".","_Current.");
					if (activeView == null) {
						StemKml.setWaitForKML(true);
						StemKml.launchNetworkLink(entryFolder,kmlfn);
						activeView = name;
						sim.addSimulationListener(this);
						existing.setMethod(method);
					} else {
						errorMessage ="Simulation "+
							activeView+
							" already active on GoogleEarth.";
						GELog.debug(this,errorMessage);
						existing.active = false;
						return false;
					}

					break;
				case GEPreferencePage.M_AUTO_LAUNCH:
					if (activeView == null ) {					
						activeView = name;
						sim.addSimulationListener(this);
						existing.setMethod(method);
					} else {
						errorMessage ="Simulation "+
								activeView+
						" already active on GoogleEarth.";
						GELog.debug(this,errorMessage);
						existing.active = false;
						sim.addSimulationListener(this);
						return false;
					}
					
					break;	
				case GEPreferencePage.M_MANUAL_DISPLAY:
					sim.addSimulationListener(this);
					existing.setMethod(method);
					break;

				default:

				}// switch
			}
		}
		return true;		
	}
	/**
	 * Set the SEIR value that wwe want displayed.
	 * 
	 * @param sim  Simulation instance
	 * @param aspect the sEIRValue to set
	 */
	public void setAspectToDisplay(ISimulation sim, Aspect aspect) {
		if (sim == null) {
			setDefaultAspect(aspect);
		} else {
			String name = getSimulationId(sim);
			GESimEntry existing = activeSimulations.get(name);

			if (existing != null) {
				// if already known about
				existing.setAspectToDisplay(aspect);
			} else {
				setDefaultAspect(aspect);
			}
		}
	}
	/**
	 * Get the SEIR value to be displayed from user.
	 * 
	 * @param sim
	 *            Simulation instance
	 * @return the sEIRValue to display
	 */
	public Aspect getAspectToDisplay(ISimulation sim) {
        String name = getSimulationId(sim);		
		GESimEntry existing = activeSimulations.get(name);
		Aspect value = null;
		if (existing != null) {
			// if already known about
			value = existing.getAspectToDisplay();
			
		} else {
			value = getDefaultAspect();
		}
		return value;
	}
	/**
	 * display status.
	 * 
	 * This will display on the console a lot of 
	 * information about the environment. 
	 * Currently it displays the status on the console.
	 * At some point the important status may be 
	 * placed into a dialog box and displayed.
	 *The main purpose of this is to have a way to 
	 *display interesting stuff. 
	 * It can be used as a problem reporting aid 
	 * since one can take the output and use it in the 
	 * problem description.  So it is important that information
	 * that is needed in diagnosing problems with the 
	 * STEM-GE interface be displayed here.
	 *
	 *
	 *	 
	 */
	public void displayStatus() {
		boolean saveDebug = GELog.DEBUG;
		GELog.DEBUG = true;
		// display Preferences
		GELog.debug(this,GEPreferencePage.display());
		final Preferences preferences = 
			org.eclipse.stem.jobs.Activator.getDefault()
				.getPluginPreferences();
		boolean simulationSleep = preferences
				.getBoolean(PreferenceConstants.SIMULATION_SLEEP_BOOLEAN);
	    // display an important delay value.  GE needs it   
		int simulationSleepSeconds = preferences
				.getInt(PreferenceConstants.SIMULATION_SLEEP_MILLISECONDS_INTEGER) * 1000;
		GELog.debug(this,"SIMULATION_SLEEP: "
				            +simulationSleep);
		GELog.debug(this,"SIMULATION_SLEEP_SECONDS: "
				            +simulationSleepSeconds);
		GELog.debug(this,"activeView: "+activeView);
		if (activeSimulations.size() == 0) {
			GELog.debug(this,"No active Simulations");

		} else {
			GELog.debug(this,"Active Simulations: "+activeSimulations.size());
			for (Map.Entry entry : activeSimulations.entrySet()) {
				GESimEntry geSim = (GESimEntry)entry.getValue();
				String name = (String)entry.getKey();
				ISimulation sim = geSim.getSimulation();
				try {
					GELog.debug(this,"  Simulation: "+							
							" "+geSim.toString());
					
					GELog.debug(this,"  State: "+sim.getSimulationState());
							
					GESimEntry existing = activeSimulations.get(name);
					GELog.debug(this,"  GESimEntry: "+existing);		
					Scenario scenario = sim.getScenario();
					GELog.debug(this,"  Scenario: "+scenario);
					DublinCore dc = scenario.getDublinCore();
					GELog.debug(this,"  Scenario DublinCore: "+dc);
					Sequencer sequencer = scenario.getSequencer();
					GELog.debug(this,"  Sequencer: "+sequencer);
					Model model = scenario.getModel();
					GELog.debug(this,"  Model: "+model);
					//GELog.debug(this,"  LongLat: "+displayLatLong(sim));
					//GELog.debug(this,"  Aspect: "+displayAspect(sim));
					
				} catch (Throwable t) {
					GELog.error("Display Status failure", t);

				}
			}
		}
		GELog.DEBUG = saveDebug;
	}
	/**
	 * display the LatLong data.
	 * This is mostly for debug usage.
	 * 
	 * 
	 * @param simulation that will be shown
	 * @return display string of latlong data
	 * 
	 */
	
	@SuppressWarnings("unused")
	private String displayLatLong(ISimulation simulation) {
		final StringBuilder sb = new StringBuilder();
		int counter = 0;
		try {
			sb.append("LatLong data: ");			
			Scenario scenario = simulation.getScenario();
			
			//		 We get the graph...
			final Graph canonicalGraph = scenario.getCanonicalGraph();
			GELog.debug(this,"displayLatLong(): canonicalGraph="+canonicalGraph);
			if (canonicalGraph == null) {
				GELog.debug(this,"displayLatLong(): canonicalGraph is null");
				return null;
			}
			// ...and can now iterate through the nodes. Note that the method
			// "getNodes" returns a map indexed by the URI of each of the nodes,
			// thus we need to get the values of the map to have an actual list to
			// iterator over.				
			for (final Iterator nodeIter = canonicalGraph.getNodes().values()
					.iterator(); nodeIter.hasNext();) {
				counter++;
				if (counter>100) {
					sb.append("\n Limit of 100 reached");
					break;
				}
				final Node node = (Node) nodeIter.next();
			    String nodeTitle = node.getDublinCore().getTitle();
			    sb.append("\n"+"Node: "+nodeTitle);
			    final LatLongProviderAdapter latLongProvider = (LatLongProviderAdapter) LatLongProviderAdapterFactory.INSTANCE
				             .adapt(node, LatLongProvider.class);
			   latLongProvider.setTarget(node);
			   
                // The node may or may not have lat/long data associated with
				// it, if it doesn't the list that's returned will be empty.
				final LatLong latLongData = latLongProvider.getLatLong();
				if (latLongData != null && latLongData.size() > 0) {
					//GELog.debug(this,"displayLatLong(): Node="+nodeTitle);
                    //	Now we just go through each segment and create a string.
					for (Segment segment : latLongData.getSegments()) {
						String data = createStringOfLatLongData(segment);
						sb.append("LatLong: "+data);
					} // for
				    							  
				} else {
					GELog.debug(this,"buildMap()(): No spacial data for Node="+nodeTitle);
				}
				
			} // for each node
			
				
			
		} catch (Throwable e) {
			
			GELog.error("Failure building area map", e);
			
		}
		return sb.toString();	
	}
	
	/**
	 * display the Aspect data.
	 * This is mostly for debug
	 * 
	 * @param simulation that will be shown
	 * @return Display string containing info about SEIR valued
	 * 
	 */

	@SuppressWarnings("unused")
	private String displayAspect(ISimulation simulation) {
		final StringBuilder sb = new StringBuilder();
		try {
            int counter = 0;
			Scenario scenario = simulation.getScenario();		
					
			//		 We get the decorators from the scenario ...			

			Decorator[] decorators = (Decorator[]) (scenario.getCanonicalGraph()
					.getDecorators().toArray());
			for (Decorator decorator : decorators) {
				GELog.debug(this,"decorator: "+decorator.toString());
				
				Object[] labels = decorator.getLabelsToUpdate().toArray();
				for (Object element: labels){
					counter++;
					if (counter>100) {
						sb.append("\n Limit of 100 reached");
						break;
					}
					if ( element instanceof NodeLabel) {
						NodeLabel nodeLabel = (NodeLabel)element;
						Node node = nodeLabel.getNode();
						String title = node.getDublinCore().getTitle();
                        sb.append("\nNode: "+title+" ");
						RelativeValueProviderAdapter rvp = (RelativeValueProviderAdapter) RelativeValueProviderAdapterFactory.INSTANCE
						.adapt(element, RelativeValueProvider.class);
						rvp.setTarget((Notifier)element);
						
						// Does the label have relative values?
						if (rvp != null) {							
							for (Iterator propertyIter = rvp.getProperties().iterator(); propertyIter
							.hasNext();) {
								ItemPropertyDescriptor property = (ItemPropertyDescriptor) propertyIter
								.next();
								sb.append(property.getDisplayName(property));
								sb.append(": ");

								sb.append(String.format("%.2f", rvp.getRelativeValue(property)));

								if (propertyIter.hasNext()) {
									sb.append(", ");
								}
							} // for each property
                            
						} // if
						
					}
				}  // for
			}


		} catch (Throwable e) {
			GELog.error("Failure getting SEIR data", e);
		}
		return sb.toString();	

	}
	/** 
	 * Get the ID to use for getting the GESimEntry instance
	 * @param simulation
	 * @return "SIM[sequenceNumber"]"
	 */
	public static String getSimulationId(ISimulation simulation) {
		if (simulation != null)
		  return "SIM["+
		      Integer.toString(simulation.getSequenceNumber())+
		    		  "]";
		else 
		  return null;
	}
	
	/**
	 * Display the latlong data from a LatLong segment
	 * A segment is a line or polygon.
	 * 
	 * @param segment
	 * @return a string of the lat/long points
	 */
	private static String createStringOfLatLongData(final Segment segment) {
		final StringBuilder sb = new StringBuilder();
		final int size = segment.size();
		for (int i = 0; i < size; i++) {
			sb.append("(");
			sb.append(segment.latitude(i));
			sb.append(", ");
			sb.append(segment.longitude(i));
			sb.append(")");
		} // for each lat/long pair
		return sb.toString();
	} // createStringOfLatLongData




	/**
	 * @return the defaultAspect
	 */
	public Aspect getDefaultAspect() {
		if (defaultAspect == null) 
			defaultAspect = Aspect.getDefault();
		return defaultAspect;
	}




	/**
	 * @param defaultAspect the defaultAspect to set
	 */
	public void setDefaultAspect(Aspect defaultAspect) {
		this.defaultAspect = defaultAspect;
	}



	/**
	 * Set an error message to display
	 * @param msg 
	 * 
	 */
	public void setErrorMessage(String msg) {
		errorMessage = msg;
	}
	/**
	 * @return the errorMessage
	 */
	public String getErrorMessage() {
		if (errorMessage == null) 
			return "";
		else 
			return errorMessage;
	}

	/**
	 * @param sim Simulation that is being processed.
	 * @return the cycle
	 */
	public int getCycle(ISimulation sim) {
		Scenario scenario = sim.getScenario();		
		Sequencer seq = scenario.getSequencer();
		int cycle = seq.getCycle();
		return cycle;
	}
	
	
} // class GEInterface
	

