package org.eclipse.stem.ui.ge.kml;
/*******************************************************************************
 * 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.io.IOException;
import java.util.Date;
import java.util.Map;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.Path;
import org.eclipse.help.internal.appserver.WebappManager;
import org.eclipse.stem.ui.ge.Activator;
import org.eclipse.stem.ui.ge.Aspect;
import org.eclipse.stem.ui.ge.GEData;
import org.eclipse.stem.ui.ge.GELog;
import org.eclipse.stem.ui.ge.servlet.VerifyClient;
import org.eclipse.stem.ui.ge.views.GEPreferencePage;
import org.eclipse.swt.program.Program;
import org.w3c.dom.DOMException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;




/**
 * StemKML works with GEInterface to handle the 
 * KML side of the interface between STEM and GoogleEarth.
 * Refer to GEInterface for more information.
 * <pre>
 *     
 *  
 *  - PolygonMap  Map<String,GEData> 
 *       Map of info to generate a set of Polygons
 *       The key is the area 
 *       
 *  - aspect   SEIR value
 *  - cycle    Nth time interval
 *  
 * 
 * During operation, when appropriate The "controlxxxx.kml" file 
 * will be rewriten with new instructions.
 * StemView will call generatePolygons() to generate a control file
 * that will display all of the county/areas of the map with the 
 * appropriate color fill to match the corresponding Stem map.
 * 
 * When the user selects a specific county/area on the map,
 * then StemView will call the generatePolygon method.
 * 
 *
 */
@SuppressWarnings("restriction")
public class StemKml {
	/**
     * Servlet context.  
     * 
     */
    public static final String CONTEXT = "STEM";
       
    /**
     * If internal web server started then this is set true
     */
    private static boolean _started = false;
    /** 
     * If internal server fails to start then this is set true
     */
    private static boolean _failed = false;
    
    /**
     * URL for either the embeded web server or 
     * an assigned web server.  
     * If this webserver was inoperative then this
     * is null.
     */
    private static String _baseurl = null;
    /**
     * System temp directory. 
     * calculated once and saved
     */
    private static String tmpFolder = null;
    /**
     * Number of intensities of color
     */
    static final int MAX = 5;
    static final int MIN = 0;
    
    /**
     *   unique id used for servlet communication
     */
    static String servletId = null;
    /**
     * FileName for KML control file.
     */
    static final String CONTROL_FN = "control.kml";
    /**
     * FileName for KML control file used to display
     * a named admin area.
     */
    static final String DISPLAYAREA_FN = "displayarea.kml";
    /**
     * if true then servlet will wait when 
     * sending files to GE and it has run 
     * out of files to send.  
     * 
     */
    private static boolean waitForKML = true;
    
    /**
     * Interval in seconds between requests
     * for refresh.  Filled into the 
     * NetworkLink request.
     */
	static int interval = 2;
    
	/**
	 * Indicate if KML is a valid filetype.
	 * If not then GoogleEarth has probably 
	 * not been installed and we cannot 
	 * simply launch a .kml file.
	 */
	static boolean validKML = true;
	/**
	 * implementation of IKmlDisplay that will create and write
	 * the KML file that is sent to GoogleEarth.
	 */
	private IKmlDisplay display = null;
	

    /**
     * Constructor  
     *
     */
    public StemKml() {
    	
    	
       try {
		   String kmlDisplayClass = Aspect.getKmlDisplayClass();

		   display = (IKmlDisplay)Class.forName(kmlDisplayClass).newInstance();
	   } catch (Throwable t) {		
		   GELog.error("Failed to create instance for KmlDisplay", t);
	   }
		  	
      
    }
        
    /**
     * initialization
     * 
     * currently we have nothing to do
     * 
     * 
     */
    public void init() {
    	        
    }

    /**
     * Verify that GoogleEarth is installed by 
     * checking that the KML filetype is known.
     * 
     * @return true if the KML file type is known.
     */
    public static boolean verifyGE() {
    	
    	String extension = ".kml";
    	Program p = Program.findProgram(extension);
    	if (p != null) {
    		GELog.debug("StemKml.verifyGE","KML handler: "+p.getName());
    		   			
    	} else {
    		validKML = false;
    	}
    	
    	return validKML;
    	
    }
	/**
	 * 
     * Create a GoogleEarth empty control files and launch it 
     * so that googleEarth starts up.
     *
	 * @throws DOMException
	 */
	public static void launchGE() throws DOMException {
		
		try {
			
			String fn = getControlFile();
			
		
			// write an empty control file so that 
			// to begin with, nothing happens but 
			// GoogleEarth gets a headstart on initialization
			
			KmlDoc kml = new KmlDoc();
			kml.setRoot(null);
			kml.getDocument();
			kml.writeFile(fn);
			GELog.debug("StemKml.launchGE",fn);
			// launch the file
			// 
			launch(fn);
			Thread.sleep(1*1000);
		} catch (Exception e) {
			String msg = "Error launching initial GoogleEarth control file.";
			GELog.error(msg,e);
		}
	}
	
	
	/**
	 * Generate the name used for KML Control.
	 * 
	 * @return Fully qualified filename (e.g. c:/tmp/control.kml)
	 */
	public static String getControlFile() {	
		String fn = null;
		if (tmpFolder == null) {
			tmpFolder = getTmpFolder();
		}
		if (tmpFolder == null) {
			GELog.error("Unable to generate KML Control file.",null);
		} else {
		
		    fn = tmpFolder+File.separator+CONTROL_FN;
		}
		
		return fn;
	}
	/**
	 * obtain the system temporary folder.
	 * 
	 * @return Fully qualified path (e.g. c:/tmp or /tmp)
	 */
	public static String getTmpFolder() {	
		String tmp = null;
		String slash = File.separator;		
		try {
			File tmpFile = File.createTempFile("control",".kml",null);
			tmp = tmpFile.getParent();
			tmpFile.delete();		
			
		} catch (IOException e) {			
			GELog.error("System Temporary Directory not defined: ",null);
			// if no system temp folder, use our log folder
			tmp = getLogFolder();
			tmp = tmp+slash+"tmp";
			File tmpFile = new File(tmp);
			tmpFile.mkdirs();
			
		} catch (Exception e) {			
			GELog.error("Failure getting TMP folder.",e);
			
		}
		return tmp;
	}
	/**
	 * obtain the users preference for the folder
	 * used to generate KML files.
	 * 
	 * @return Fully qualified path (e.g. c:/tmp or /tmp)
	 */
	public static String getLogFolder() {	
		String log = null;
				
		try {
			log = GEPreferencePage.getFolder();
			File logFolder = new File(log);
			if (logFolder.exists()) {
				if (logFolder.isDirectory()) {
					return log;
				} else {
					throw new RuntimeException("Log Folder "+
							log+ " is not valid");
				}
			}  else {
				boolean ok = logFolder.mkdirs();
				if (ok)
					return log; 
				else 
					throw new RuntimeException("Log Folder "+
							log+ " cannot be created ");
			}
			
			
		} catch (Exception e) {			
			GELog.error("Failed to get LOG folder: "+log,e);
			log = null;
		} 
		return log;
	}
	/**
	 * Generate the name used for KML when using
	 * the DisplayArea utility function
	 * 
	 * @return Fully qualified filename (e.g. c:/tmp/control.kml)
	 */
	public static String getDisplayAreaFile() {	
		String fn = null;
		try {
			if (tmpFolder == null) {
				File tmpFile = File.createTempFile("displayarea",".kml");
				tmpFolder = tmpFile.getParent();
				tmpFile.delete();
			}
			fn = tmpFolder+"/"+DISPLAYAREA_FN;
		} catch (IOException e) {			
			GELog.error("Unable to generate KML DisplayArea file.",e);
		}
		return fn;
	}
	/**
	 *  write an empty control file so that 
	 *  it clears the current display
	 */
	public static void clearDisplayArea() {
		String fn = tmpFolder+"/"+DISPLAYAREA_FN;	
		
		KmlDoc kml = new KmlDoc();
		kml.setRoot(null);
		kml.getDocument();
		kml.writeFile(fn);
		
		// launch the file
		// 
		launch(fn);
	}
    /**
	 * create and launch a network link file that will read the 
	 * kml files that we will be generating.
     *
     * @param folder Folder that contains KML files
     * @param file   If not null then pass this name to the servlet.  
     * @return URL used
	 *
	 */
	public static String launchNetworkLink(	String folder, String file) {
					
		String url = null;
		// clear if needed
		StemKml.launchGE();

		try {
			
			String fn = getControlFile();
			
			long time = new Date().getTime();
			servletId = Long.toHexString(time);
			String wait = "n";
			if (waitForKML) 
				wait = "y";
            
			url = _baseurl+
				"/"+CONTEXT+"/slideshow?id="+servletId+
				"&folder="+folder+
				"&wait="+wait;
			if (file != null) {
				url = url+"&file="+file;
			}
			GELog.debug(StemKml.class,"launchNetworkLink url="+url);
			
			StemKml.writeNetLink(fn, interval, url);
			
			String bboxurl = _baseurl+
			       "/"+CONTEXT+"/bbox?id="+servletId;
			
			// start Thread to access BBox info from GE
			if (GEPreferencePage.isBBOX()) {
				BBoxInfo bbox = new BBoxInfo(bboxurl,servletId);
				Thread t = (new Thread(bbox));
				t.start();
			}
			try {
				Program.launch(fn);
				GELog.debug(StemKml.class,"Launched networkLink file "+fn);
				Thread.sleep(5*1000);
			} catch (InterruptedException ie) {
			} catch (Throwable e) {
				GELog.error("Launch failure", e);
			}
		} catch (Exception e) {
			GELog.error("Failure launching NetworkLink.kml file",e);
			
		}
		return url;
    }
	/**
	 * 
	 * Write the network Link file that will tell GoogleEarth how 
	 * to make callbacks to the servlet.
	 * 
	 * @param fn  folder + fn to write  
	 * @param interval  How often to call back (seconds)
	 * @param url     Where to call back + parms
	 * @throws DOMException
	 */
	public static void writeNetLink(String fn, int interval, String url) 
	  throws DOMException {
		KmlDoc kml;
		// write a file using networklink that tells 
		// google earth to read the control file 
		// every N seconds and do whatever it says.
		kml = new KmlDoc();        
		Document doc = kml.getDocument();
		Element root = kml.setRoot(null);
		NetworkLink netLink = new NetworkLink(doc);        

		String mode = "onInterval";
		netLink.setUrl(url, interval,mode);
		// add <flyToView>1</flyToView> 
		kml.appendAttr(netLink.getElement(),"flyToView",false);
		root.appendChild(netLink.getElement());

		//kml.display();  // debug
		kml.writeFile(fn);
	}
	
	
  /**
  * Create the KML control file to display all of the 
  * polygon (county) areas
  *
  * Call the implementation of IKmlDisplay to create and 
  * write the kml file.
  * 
  * @param controlFileName File where KML will be written 
  * @param geData Map of GEData objects 
  * @param aspect  which type of map (population,susceptiple...
  * @param cycle current number of cycle being displayed
  */
    
	public void generatePolygons(String controlFileName, 
			Map<String,GEData> geData, Aspect aspect,long cycle) {
 	
	    
	    display.generatePolygons(controlFileName, geData, aspect);
	}
		
 

      

    /**
	 * get the Hex value corresponding to an int value. 
	 * This has leading zeros.
	 * 
	 * @param v      value to translate.
	 * @return Hex String
	 */
	public static String getHex(int v) {
		String hex = Integer.toHexString(v);
		if ((hex.length() % 2) != 0) {
			hex = "0" + hex;
		}
		return hex;
	}

/**
 * Launch the KML file to GoogleEarth
 * 
 * @param controlFileName
 *            absolute file path or a url
 * 
 */
public static void launch(String controlFileName) {
	try {
		if (!validKML) {
			GELog.debug("launch: KML is unknown filetype");
			return;
		}
		File controlFile = new File(controlFileName);
		
		
		Program.launch(controlFile.getAbsolutePath());
		GELog.debug("StemKml.launch","Launched file "+controlFileName);
	} catch (Throwable e) {
		GELog.error("StemKml: Launch failure", e);
	}
}

/** 
 * Startup and verify a web server to run the 
 * GEServlet servlets.
 * 
 * If specified it will try to start the embedded web server
 * If not or it failed then it will check if an 
 * external server was specified and try to access it.
 * 
 * @return url for host and port 
 *       example: http://127.0.0.1:54345/
 *       It will return null if unable to start server or 
 *       if server does not support our servlets
 */	 
public static String initWebServer() {
	
	if (GEPreferencePage.isInternalServer()){		
		_baseurl = startWebServer();		
	}
	
	if (_baseurl == null ) {
		String host =GEPreferencePage.getServerHost();
		if (host != null && host.length() > 0)
			_baseurl = "http://"+host;
	} 
	if (_baseurl != null) {
		GELog.debug(StemKml.class,"VerifyClient "+_baseurl);
		// verify that we have a working web server
		VerifyClient vc = new VerifyClient();
		boolean test = vc.verify(_baseurl+
			            	"/"+CONTEXT+"/verify");
		if (! test) {
			GELog.info(vc.getError());
			GELog.error("StemKml: Unable to communicate with web server @ "
					+_baseurl,null);
			if (GEPreferencePage.isInternalServer()){
				_failed = true;
			}
			_baseurl = null;
		} 
	}
	if (_baseurl == null) {
		GELog.error("GoogleEarth Servlet support disabled",null);
	}
	return _baseurl;
}

/** 
 * Startup an internal web server to run the 
 * GEServlet servlets.
 * @return url for host and port 
 *       example: http://127.0.0.1:54345/
 *       It will return null if unable to start server
 */	
@SuppressWarnings({ "deprecation" }) 
public static String startWebServer() {
	String url = null;
	if (!_started && !_failed)	  {
	    try {
	    	GELog.debug(StemKml.class,"Start webServer");
			WebappManager.start(CONTEXT, Activator.PLUGIN_ID, Path.EMPTY);
			
			String internalHost = WebappManager.getHost() + ":" + WebappManager.getPort();
			 url = "http://" +  internalHost;
			 GELog.debug(StemKml.class,"Started webServer "+url);
			 
		} catch (CoreException e) {
			GELog.error(e.getMessage(), e);
			_failed = true;
			url = null;
		}
	  } else if (!_failed ) {
		  String internalHost = WebappManager.getHost() + ":" + WebappManager.getPort();
			 url = "http://" +  internalHost; 
	  }
	GELog.debug(StemKml.class,"embedded web server at: "+url);
	if (! _failed) 
		_started = true;
	return url;
}

/**
 * obtain the URL used to access the GE Servlets.
 * 
 * @return The URL as a string, null if unable to 
 *   access a valid web server.
 */
static public String getServerUrl() {
	return _baseurl;
}

/**
 * Set the filename based on the Template and 
 * the current aspect and cycle number.
 * 
 * @param folder Folder where kml files are written
 * @param template 
 * @param aspect aspect to be displayed
 * @param cycle
 * 
 * @return resulting absolute filename
 */
	public static String getControlFN(String folder, String template,
			Aspect aspect, long cycle) {
        String controlFN = "";
		String seq = "0000" + cycle;
		if (cycle > 9)
			seq = "000" + cycle;
		if (cycle > 99)
			seq = "00" + cycle;
		if (cycle > 999)
			seq = "0" + cycle;
		if (cycle > 9999)
			seq = "" + cycle;
		// we won't worry about cycle > 99,999
		
		controlFN = folder + "/" + template;
		controlFN = controlFN.replaceAll("&T", aspect.toString());
		controlFN = controlFN.replaceAll("&N", seq);
		GELog.debug(StemKml.class,"Output file="+controlFN);
		return controlFN;

	}
/**
 * 
 * @return true if servlet should wait when it has
 *  sent all of the available kml files to GE
 */
public static boolean isWaitForKML() {
	return waitForKML;
}
/**
 * Set true if servlet should wait
 * @param waitForKML
 */
public static void setWaitForKML(boolean waitForKML) {
	StemKml.waitForKML = waitForKML;
}
 
}// class

