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

import org.eclipse.core.runtime.Preferences;
import org.eclipse.core.runtime.Preferences.IPropertyChangeListener;
import org.eclipse.core.runtime.Preferences.PropertyChangeEvent;
import org.eclipse.jface.preference.BooleanFieldEditor;
import org.eclipse.jface.preference.DirectoryFieldEditor;
import org.eclipse.jface.preference.FieldEditorPreferencePage;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.preference.IntegerFieldEditor;
import org.eclipse.jface.preference.RadioGroupFieldEditor;
import org.eclipse.jface.preference.StringFieldEditor;
import org.eclipse.stem.ui.ge.Activator;
import org.eclipse.stem.ui.ge.Aspect;
import org.eclipse.stem.ui.ge.GELog;
import org.eclipse.stem.ui.preferences.PreferenceConstants;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchPreferencePage;
import org.eclipse.ui.preferences.ScopedPreferenceStore;


/**
 * Handle Preferences for the STEM - GoogleEarth interface.
 * <pre>
 * This class contains the following:
 *   - code to present the setting of the preferences 
 *     by the user.  The gui for some preferences are 
 *     handled by GEAdvancedPreferencePage
 *     
 *   - getter/setter code for all of the preferences. 
 *     mostly getter.
 *   
 *   - code to pick up the aspect preference from the 
 *     visualization page.
 * 
 * This class was initialy generated by the PreferencePage wizard and 
 * then modified as described in 
 * "Building Comercial-Quality Plugins" 
 * 
 * This class represents a preference page that
 * is contributed to the Preferences dialog. By 
 * subclassing <samp>FieldEditorPreferencePage</samp>, we
 * can use the field support built into JFace that allows
 * us to create a page that is small and knows how to 
 * save, restore and apply itself.
 * <p>
 * This page is used to modify preferences only. They
 * are stored in the preference store that belongs to
 * the main plug-in class. That way, preferences can
 * be accessed directly via the preference store.
 * 
 * This uses the jface Preferences API rather than
 *  the new SWT Preferences API  because it is simpler 
 *  to implement. 
 *  </pre>
 */

public class GEPreferencePage
	extends FieldEditorPreferencePage
	implements IWorkbenchPreferencePage {
    
	/**
	 * Folder used to store KML files
	 */
	static final String P_FOLDER = "folderPreference";
	/**
	 * Server:port used for Web server that will feed the 
	 * KML files to GoogleEarth.
	 */
	static final String P_SERVER_HOST = "ServerHostPreference";
	/**
	 * Launch GoogleEarth at startup flag.
	 *   If true then automatically launch an empty file 
	 *   to GE at startup
	 *   
	 */
	
	static final String P_AUTO_LAUNCH = "AutoLaunchPreference";
	
	/**
	 * Use InternalServer flag
	 * if true then start the Eclpse built in web server
	 */
	static final String P_INTERNAL_SERVER = "InternalServer";
	/**
	 * Automatically launch NetworkLink.KML file
	 * 
	 */
	//static final String P_AUTO_NETLINK = "AutoNetLink";
	
	/**
	 * Write KML files every Nth cycle.
	 * 
	 * For example 1 would write every cycle and
	 * 3 would write every 3rd cycle. 
	 * This is useful when there is not much change 
	 * between cycles and saves the overhead of both
	 * writing the file and more importantly having 
	 * GoogleEarth read and process it.
	 * Note <- 0 would only write the first and last.
	 */
	static final String P_WHICH_CYCLE = "whichCycle";
	
	
	/**
	 * Debug display option
	 */
	static final String P_DEBUG = "DebugPreference";
	
	
	/**
	 * Use GoogleEarth BBox info to filter KML 
	 * Access via the isBBOX() method
	 */
	static final String P_BBOX = "BBOXPreference";
	/**
	 * Aspect (SEIR) to be displayed  (or Logged)
	 * 
	 */
	static final String P_ASPECT = "AspectPreference";
	
	/**
	 * if true then this will do autologging of every simulation 
	 * assuming that the GoogleEarth interface is active.
	 */
	static final String P_AUTO_LOGGING = "AutoLoggingPreference";
	
	/**
	 * Test option
	 * The Test option is used arbitrarily to 
	 * test newly implemented features or setup
	 * a temporary test environment.  It is a tool
	 * for the developer and would not normaly be
	 * specified by the user except on request of 
	 * a developer.  
	 * An example of use would be to turn on some 
	 * additional debug code to help find a bug.
	 */
	static final String P_TEST = "TestPreference";
	
	/**
	 * Option to control the display of borders on the map
	 */
	static final String P_SHOW_BORDER = "ShowBorderPreference";
	
	/**
	 * Method used to display STEM results on GoogleEarth
	 * <pre>
	 * 
	 * 1=LogOnly    - KML files will be logged for later display via Servlet
	 * 
	 * 2=Log+Servlet - KML files logged and Netlink file launched to cause 
	 *              GE to request logged files via Servlet.  
	 * 
	 * 3=ASynch-Servlet - KML written to Control.kml every Nth cycle
	 *              and Netlink file launched to cause GE to reread 
	 *              control.kml every N seconds             
	 * 4=AutoLaunch - At each Nth cycle, directly launch the file to GE             
	 */
	static final String P_METHOD = "MethodPreference";
	/** 
	 * Only Log KML for later display 
	 */
	public static final int M_LOG_ONLY = 1;
	/** 
	 * Log the KML files and 
	 * start the networkLink process 
	 */
	public static final int M_LOG_SERVLET = 2;
	/** 
	 * always write the control.kml file and 
	 * start a servlet to read the latest version.
	 * Advantage is that GoogleEarth is always reading
	 * the latest version and will not fall behind.  
	 */
	public static final int M_ASYNC_SERVLET = 3;
	
	/** 
	 * Build a KML file and launch it directly 
	 * to GoogleEarth
	 */
	public static final int M_AUTO_LAUNCH = 4;
	/** 
	 * Do not do anything automatically.
	 * Only generate a KML file at request of user.
	 * 
	 */
	public static final int M_MANUAL_DISPLAY = 5;
	/**
	 * 
	 */
	public static final IPreferenceStore preferences = 
		Activator.getDefault().getPreferenceStore();
	
	
	/**
	 * construct the Preference page for GoogleEarth interface.
	 * 
	 */
	public GEPreferencePage() {
		super(GRID);
		//super(FLAT);
		// To use GELog In preferences you have to manually
		// turn it on before the preference is used to set it.
		// obviously! :-)   Uncomment the following 
		//GELog.DEBUG = true;
		//preferences = Activator.getDefault().getPreferenceStore();
		setPreferenceStore(preferences);
		setDescription("Preferences for the STEM - GoogleEarth interface\n ");
		//getVisualizationPreferences();
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.ui.IWorkbenchPreferencePage#init(org.eclipse.ui.IWorkbench)
	 */
	public void init(IWorkbench workbench) {
	}
	
	
	/**
	 * Creates the field editors. Field editors are abstractions of
	 * the common GUI blocks needed to manipulate various types
	 * of preferences. Each field editor knows how to save and
	 * restore itself.
	 */
	public void createFieldEditors() {
		
		
		
		addField(new RadioGroupFieldEditor(
				P_METHOD,
			"&Choose the method used to display STEM results.",
			1,new String[][] { 
				{"LogOnly    - KML files will be logged for later display", "1" }, 
				{"Log+Servlet - KML files logged and displayed by GoogleEarth", "2" },
				{"AsyncServlet - KML written to Control.kml and Async read by Servlet ", "3" },
				{"DirectLaunch - At each Nth cycle, directly launch the file to GE ", "4" },
				{"ManualDisplay - Use DisplayMap command to display", "5"}
			 }, getFieldEditorParent()));
		
		addField(new DirectoryFieldEditor(P_FOLDER, 
				"&Folder for KML logging:", getFieldEditorParent()));
		
		addField(
				new BooleanFieldEditor(
					P_INTERNAL_SERVER,
					"&Use internal webserver",
					getFieldEditorParent()));
		
		addField(
				new StringFieldEditor(P_SERVER_HOST,
						"Hostname:port for external webserver:", getFieldEditorParent()));
			
		addField(
				new BooleanFieldEditor(
					P_AUTO_LAUNCH,
					"&Automatically startup GoogleEarth", 
					getFieldEditorParent()));
		addField(
				new BooleanFieldEditor(
					P_AUTO_LOGGING,
					"&Automatically process every simulation", 
					getFieldEditorParent()));
		
		addField(
				new IntegerFieldEditor(
					P_WHICH_CYCLE,
					"Write KML files only every N th cycle", 
					getFieldEditorParent(),2));
		// if aspect uninitialized, then get from Visualization page
		String a = preferences.getString(P_ASPECT); 
		if ("".equals(a)) {
			getVisualizationPreferences();
			//a = preferences.getString(P_ASPECT);
		}
		
		//GELog.debug(this,"Initial visualizationAspect="+a);
	    // if we have initialized the aspects - show selection
		String[][] aspectList = aspects();
		if (aspectList != null) {
			
			addField(
				new RadioGroupFieldEditor(
					P_ASPECT,
					"&Choose the STEM Aspect to be Logged.",
					2,aspects(),
					getFieldEditorParent()));
		}
				


	}
    
	/**
	 * Get the list of supported Aspects
	 * 
	 * @return Array of Aspects. Each entry in array 
	 *   consists of the Aspect Name and Code
	 */
	private String[][] aspects() {
		
		Map<String,Aspect> aspectMap = Aspect.getMap();
		if (aspectMap == null || aspectMap.size() == 0) {
			return null;
		}
		int n = aspectMap.size();
		String[][] result = new String[n][2];
		int i = 0;
		for(Map.Entry entry: aspectMap.entrySet()) {
			String code = (String)entry.getKey();
			Aspect aspect  = (Aspect)entry.getValue();
			result[i][0] = aspect.getName();
			result[i][1] = code;
			i++;
		}			
		
		return result;
	}
	
	
	public boolean performOk() {
		update();
		try {
			if (preferences instanceof ScopedPreferenceStore) {
			    ScopedPreferenceStore p = (ScopedPreferenceStore)preferences;
			    p.save();
			}
		} catch (IOException e) {			
		    GELog.error("Failure saving Preferences",e);	
		}
		GELog.debug(this,"saved preferences");
		return super.performOk();
	}
	
	/**
	 * Make any needed application updates
	 *
	 */
	private void update() {
		if (isDebug() != GELog.DEBUG) {
			GELog.DEBUG = isDebug();
			if (isDebug() ) {
				GELog.debug("Set DEBUG to "+isDebug());
			}
		}
	}
	

	/**
	 * Get the aspect to display from the Visualization 
	 * preference page. 
	 * We only use the visualization value if we don't 
	 * have any value specifified so that we can specify 
	 * a different value from the internal map if we want.
	 * 
	 *
	 */
	private void getVisualizationPreferences() {
		org.eclipse.stem.ui.Activator uiPlugin = null;
		try {
			
			// IPreferenceStore
			uiPlugin = org.eclipse.stem.ui.Activator.getDefault();
			final Preferences preferences = uiPlugin.getPluginPreferences();
			String visualizationAspect = preferences
					.getString(PreferenceConstants.INITIAL_ATTRIBUTE_NAME_STRING_PREFERENCE);
            if (preferences.getString(P_ASPECT) == "") {
            	// TODO temp fix for bad visualization default
            	GELog.debug(this,"Use visualizationAspect="+visualizationAspect);
            	if (visualizationAspect.equals("S"))
            		visualizationAspect = "I";
            	setAspect(visualizationAspect);
            } else {
			  GELog.debug(this,"Ignore visualizationAspect="+visualizationAspect);
            }
		} catch (Exception e) {
			GELog.error("Failure getting Visualization preferences",e);
		} 
		// listen for changes in the Visualization preferences
		try {
			// Listen for changes to the preferences and change the value we
			// use if the user changes the value on the preference page.
			uiPlugin.getPluginPreferences().addPropertyChangeListener(new IPropertyChangeListener() {
						public void propertyChange(PropertyChangeEvent event) {
							setVisulizationPreferences(event);
						} // propertyChange
					} // IPropertyChangeListener
					);
		} catch (Exception e) {
			// Ignore
		} // catch Exception
	}
	/**
	 * Check if the aspect was changed on the visualization preferences
	 * and if so then use it for us also.
	 * @param event
	 */
	private void setVisulizationPreferences(PropertyChangeEvent event) {
		
		String property = event.getProperty();
		if (PreferenceConstants.INITIAL_ATTRIBUTE_NAME_STRING_PREFERENCE == property) {
			String visualizationAspect = (String)event.getNewValue();
			GELog.debug(this,"Changed visualizationAspect="+visualizationAspect);
			setAspect(visualizationAspect);	
			performOk();
		}
	}
	
	/**
	 * @return the logFolder
	 */
	public static  String getFolder() {
		
		return preferences.getString(P_FOLDER);
	}
	/**
	 * @param logFolder the logFolder to set
	 */
	public static void setFolder(String logFolder) {
		preferences.setValue(P_FOLDER, logFolder);
	}
	/**
	 * @return the serverHost
	 */
	public static  String getServerHost() {
		
		return preferences.getString(P_SERVER_HOST);
	}

	/**
	 * This will return a code 1 to 5 indicating the 
	 * method used to display KML.  
	 * 
	 *  M_LOG_ONLY = 1;
	 *  M_LOG_SERVLET = 2;
	 *  M_ASYNC_SERVLET = 3;
	 *  M_AUTO_LAUNCH = 4;
	 *  M_MANUAL_DISPLAY = 5;
	 * 
	 * If there is no Servlet support, it will modify what
	 * is returned to avoid being dependent on a servlet.
	 * 
	 * @return the method code to be used to display KML 
	 *    
	 */
	public static int getMethod() {
		String s =  preferences.getString(P_METHOD);
		int type = Integer.parseInt(s);
// The test is now made in StemKML
//		if (StemKml.getServerUrl() == null) {
//			if (type == M_LOG_SERVLET) 
//				type = M_LOG_ONLY;
//			else if (type == M_ASYNC_SERVLET)
//				type = M_AUTO_LAUNCH;
//		}
		return type;
	}



	/**
	 * Set the Method that STEM coummicates with GE
	 *
	 * @param newMethod  New method to set
	 */
	public static void setMethod(int newMethod) {
		String m = ""+newMethod;
		preferences.setValue(P_METHOD, m);
	}

	/**
	 * @return the internalServer flag
	 * 
	 * If true then the info about the status of 
	 * the server is handled by the StemKML code.
	 */
	public static boolean isInternalServer() {
		return preferences.getBoolean(P_INTERNAL_SERVER);
	}



	/**
	 * @return the autoLaunch flag
	 */
	public static boolean isAutoLaunch() {
		return preferences.getBoolean(P_AUTO_LAUNCH);
	}

	/**
	 * @return the autoLogging
	 */
	public static boolean isAutoLogging() {
		return preferences.getBoolean(P_AUTO_LOGGING);
	}


	/**
	 * @return the whichCycle
	 */
	public static int getWhichCycle() {
		return preferences.getInt(P_WHICH_CYCLE);
	}
    
	/**
	 * get the specified Aspect that will be logged or displayed
	 * @return Aspect instance or null
	 */
	public static Aspect getAspect() {
		Aspect aspect = null;		
		String a = preferences.getString(P_ASPECT);
		if (a.length() == 0) 
			aspect = Aspect.getDefault();
		else
			aspect = Aspect.getAspect(a);
		if (aspect == null) {
		    GELog.debug("GEPreferencePage.getAspect: ",a+" returned null, use default aspect");
		    aspect = Aspect.getDefault();
		}
		return aspect;
	}
	/**
	 * set the Aspect that will be displayed
	 * @param aspectStr Name of the desired Aspect.
	 */
	public static void setAspect(String aspectStr) {
		Map<String,Aspect> aspectMap = Aspect.getMap();
		if (aspectMap != null && aspectMap.size() > 0) {
			
			Aspect aspect = null;	
			aspect = Aspect.getAspect(aspectStr);
			if (aspect == null ) {
				GELog.debug(GEPreferencePage.class,
					"Invalid aspect ignored: "+aspectStr);
				return;
			}
		}
		preferences.setValue(P_ASPECT,aspectStr);
		
		GELog.debug(GEPreferencePage.class,
				"Aspect set: "+aspectStr);
		return;
	}
	
	/**
	 * @return the BBox filter flag
	 */
	public static boolean isBBOX() {
		if (preferences != null)
			return preferences.getBoolean(P_BBOX);
		else 
			return false;
	}
	/**
	 * @return the Debug flag
	 */
	public static boolean isDebug() {
		if (preferences != null)
			return preferences.getBoolean(P_DEBUG);
		else 
			return true;
	}
	/**
	 * @return the Test flag
	 * <pre>
	 * Uses:
	 *  - Enhanced Debug output (time and thread)
	 *  - Filter out nodes
	 *    - KmlDisplay - if not BBox filter then not US or Mexico
	 *    - KmlDisplayCustom - not US
	 * To see where else this is used ask to see call hierarchy
	 */
	public static boolean isTest() {
		
		if (preferences != null)
			return preferences.getBoolean(P_TEST);
		else 
			return true;
	}
	
	/**
	 * @return the ShowBorder flag
	 * <pre>
	 * With KML you can either show the polygon borders or not.
	 * This flag will control whether they are shown or not.
	 * The default is to not show them
	 */
	public static boolean isShowBorder() {
		
		if (preferences != null)
			return preferences.getBoolean(P_SHOW_BORDER);
		else 
			return true;
	}
	// TODO keep this up to date
	/**
	 * To display all of the Preferences.
	 * 
	 * Please keep this up to date. 
	 * 
	 * @return string describing the current preferences.
	 */
	public static String display() {
		StringBuffer sb = new  StringBuffer(200);
		
		sb.append("STEM-GoogleEarth Preferences:\n");
		
		sb.append("P_METHOD: ");
		switch (getMethod()) {
		case M_LOG_ONLY:
			sb.append("M_LOG_ONLY ");
			break;
		case M_LOG_SERVLET:
			sb.append("M_LOG_SERVLET ");
			break;
		case M_ASYNC_SERVLET:
			sb.append("M_ASYNC_SERVLET ");
			break;
		case M_AUTO_LAUNCH:
			sb.append("M_AUTO_LAUNCH ");
			break;
		case M_MANUAL_DISPLAY:
			sb.append("M_MANUAL_DISPLAY ");
			break;
		default:
			sb.append("Unknown ");
		}
		sb.append("\n");
		
		
		sb.append("P_FOLDER: ");
		sb.append(getFolder()+"\n");

		sb.append("P_SERVER_HOST: ");
		sb.append(getServerHost()+"\n");		

		sb.append("P_INTERNAL_SERVER: ");
		sb.append(isInternalServer()+"\n");
		
		sb.append("P_AUTO_LAUNCH: ");
		sb.append(isAutoLaunch()+"\n");

		sb.append("P_AUTO_LOGGING: ");
		sb.append(isAutoLogging()+"\n");

		sb.append("P_WHICH_CYCLE: ");
		sb.append(getWhichCycle()+"\n");
		
		sb.append("P_ASPECT: ");
		sb.append(getAspect().toString()+"\n");
		
		sb.append("P_BBOX: ");
		sb.append(isBBOX()+"\n");

		sb.append("P_DEBUG: ");
		sb.append(isDebug()+"\n");
  // 
  //  The following are found in GEAdvancedPreferencePage
  //
		sb.append("P_TEST: ");
		sb.append(isTest()+"\n");
		
		sb.append("P_SHOW_BORDER: ");
		sb.append(isShowBorder()+"\n");
		return sb.toString();
	}
}