package org.eclipse.stem.ui.ge.servlet;
/*******************************************************************************
 * 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.io.PrintWriter;
import java.util.Date;
import java.util.Enumeration;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.eclipse.stem.ui.Activator;



/**
 * StartServlet sends back a valid KML file for a GET or POST
 * action that will give GoogleEarth the NetworkLink to 
 * start up the STEM SlideShow
 * <pre>
 * The way that it works is this:
 *    The invoking HTML will invoke this Servlet with the following
 *    parameters:
 *      folder <path>
 *      wait   <y/n>
 *       
 *    The servlet builds a KML file that is launched to GoogleEarth that 
 *    has a networklink with the following URL
 *    http://localhost:8080/STEM/slideshow?id=<id>&folder=<path>&wait=<wait>
 *    where <id> is a unique id
 *          <path> is the directory containing the 
 *            kml files generated by STEM.
 *          <wait> is "y" if it should wait for new files 
 *          to be generated    
 *     GoogleEarth will then issue http GET requests with 
 *     the specified URL 
 *     
 *             
 */
public class StartServlet extends HttpServlet {
    /**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	/**
     * Servlet context.  
     * 
     */
    public static final String CONTEXT = "/STEM";
	
    private static String debug = "n";
    /**
     * if set true, this will create readable output
     */
    private static boolean TEST = false;
    
    static final String STEM_FOLDER = "c:\\tmp\\ge";
    
    static final String VERSION = "1.0.1";
    /**
     *  Handle the initial setup 
     */
	public void init(ServletConfig config) throws ServletException {
		    super.init(config);
		    debug("init: "+VERSION+" invoked at startup or deploy");	
		    
	 }
    
	protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
		debug("doGet");
		doPost(request, response);
}

    protected void doPost(HttpServletRequest request,HttpServletResponse response) 
            throws ServletException, IOException {
    	debug("doPost");		
		
		String folderName = STEM_FOLDER;
		String waitForKML = "n";
		String interval = "2";  // every 2 seconds
		File folder = null;
		
		try {
			// get the folder from the URL parameters.
			// http://localhost:8080/slideshow?folder=path
			Enumeration e = request.getParameterNames();
			while (e.hasMoreElements()) {
				String name = (String)e.nextElement();
				String value = (String)request.getParameter(name);
				debug(name+"="+value);
				if (name.equals("folder")) {
					folderName = value;				
				} else if (name.equals("wait")) {
					waitForKML = value;					
				} else if (name.equals("interval")) {
					interval = value;					
				} else if (name.equals("debug")) {
					debug = value;					
				}
				
			}
			if (debug.toLowerCase().startsWith("y")) {
				SlideShowServlet.DEBUG = true;
			} else {
				SlideShowServlet.DEBUG = false;
			}
			folder = new File(folderName);
			debug("folder: "+folder.getAbsolutePath());
			
			
			long time = 0;
			String info = "IPaddr: " + request.getRemoteAddr() + 
	        " folder: "+folder.getAbsolutePath() +
	        " time: " + time;
	        debug(info);
			sendOutput(request,response, folderName, 
					waitForKML,interval);
		} catch (Throwable e) {
			
			e.printStackTrace();
		}
	}
   

	/**
	 * Send the KML file to the caller (GoogleEarth)
	 * 
	 * If TEST=true then it will be written to the browser 
	 * for testing. Note that becasuse it is XML the output 
	 * will be garbled and you need to use the browser to 
	 * look at the page source.
	 * 
	 * @param request
	 * @param response
	 * @param folderName
	 * @throws IOException
	 */
    synchronized 
    private void sendOutput(HttpServletRequest request,
			HttpServletResponse response, 
			String folderName, String waitForKML, String interval) 
	            throws IOException {
    	
    	
    	int port = request.getServerPort();
    	
    	String host = request.getServerName()+":"+port;
		
		long time = new Date().getTime();
		String id = Long.toHexString(time);
		PrintWriter os = new PrintWriter(response.getOutputStream());
    	// set TEST=true to get readable output instead of 
    	// launching a KML file
    	
    	if (TEST) {
    		String msg = " KML NetworkLink file: ";
    		response.setContentType("text/html");
    		
    		os.println("<html>");
    		os.println("<head><title>Start Slideshow</title></head>");
    		os.println("<body>");
    		os.println("<p>"+msg+"</p>");
    		    		    		
    	}  else {        
		    response.setContentType("application/keyhole");
    	}
				
		try {
			
			os.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
			os.println("<kml xmlns=\"http://earth.google.com/kml/2.0\">");
			os.println("<Folder>");
			os.println("   <description>SlideShow NetworkLink</description>");
			os.println("   <name>Network Links</name>");
			os.println("<NetworkLink>");
			os.println("<Url>");
			// The import info goes here
			String url = "<href>http://"+host+
					CONTEXT+"/slideshow?id="+id+
					"&amp;folder="+folderName+
					"&amp;wait="+waitForKML+
					"</href>";
			os.println(url);
			debug(url);
			
			os.println("<refreshInterval>"+interval+"</refreshInterval>");
			os.println("<refreshMode>onInterval</refreshMode>");
			os.println("</Url>");
			os.println("<flyToView>0</flyToView>");
			os.println("</NetworkLink>");
			os.println("</Folder>");
			os.println("</kml>");
		} catch (Exception e) {
			String msg = "SlideShow startup failure";
			debug(msg,e);
			errHtml(response,msg+e.getMessage());
		}
		if (TEST) {    		
    		 		
    		os.println("</body></html>");
    		   		    		
    	} 
		os.flush(); 
	}
    
    /**
     * print debug messages to the sever log.
     * @param msg
     */
	private void debug(String msg) {
		if (SlideShowServlet.DEBUG) {
		  //getServletContext().log(msg);
		  //log("log: "+msg);
		  Activator.logInformation("StartServlet: "+msg);
		}
	}
	
	private void debug(String msg,Throwable e) {
		System.err.println(msg);
		e.printStackTrace();
	}
	/**
	 * put out an error message as html
	 * 
	 * @param response
	 * @param msg
	 * @throws IOException
	 */
	private void errHtml(HttpServletResponse response,String msg) 
	                       throws IOException {
		response.setContentType("text/html");
		PrintWriter out = new PrintWriter(response.getOutputStream());
		out.println("<html>");
		out.println("<head><title>KML SlideShow Error</title></head>");
		out.println("<body>");
		out.println("<p>"+msg+"</p>");
		out.println("</body></html>");
		out.flush();
	}
}