// Utility.java
package org.eclipse.stem.core;

/*******************************************************************************
 * Copyright (c) 2008 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.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
import org.eclipse.emf.ecore.xmi.XMLResource;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.stem.core.common.Identifiable;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PlatformUI;

/**
 * This class contains common utility methods used in STEM.
 */
public class Utility {

	/**
	 * EMF Save Options, for properly serializing to UTF-8
	 */
	private static final Map<String,String> EMF_SAVE_OPTIONS 
		= new HashMap<String,String>();
	static {
		EMF_SAVE_OPTIONS.put(XMLResource.OPTION_ENCODING, "UTF-8");
	}
	
	public final static String NESTING_WARNING = "Warning, possible scenario initialization problem detected. Check the nesting of your models";
	public final static String URI_WARNING = "Warning, URI does not exist in Graph. Check the infector/innoculator URIs your models. ";
	
	
	/**
	 * Cached resource set
	 */

	public static ResourceSet resourceSet;
	
	static {
		resourceSet = new ResourceSetImpl();
		resourceSet.getResourceFactoryRegistry().getExtensionToFactoryMap().put("*", STEMXMIResourceFactoryImpl.INSTANCE);
		resourceSet.getResourceFactoryRegistry().getProtocolToFactoryMap().put("platform", STEMXMIResourceFactoryImpl.INSTANCE);
	}
	
	/**
	 * @param identifableURI
	 *            the {@link URI} of file with a serialized {@link Identifiable}
	 * @return the {@link Identifiable} de-serialized from the file, or
	 *         <code>null</code> if an error occurred.
	 */
	public static Identifiable getIdentifiable(final URI identifableURI) {
		Identifiable retValue = null;

		try {
			URI normalized = STEMURI.normalize(identifableURI);
			Resource resource = resourceSet.getResource(normalized,
					true);
			if(resource.isModified()) {				
				resource.unload();
				resource.load(null);
				if(resource.getErrors().size() > 0) {
					for(Resource.Diagnostic d: resource.getErrors()) 
						CorePlugin.logError(d.getMessage(), new Exception());
				}
			}
			EList<EObject>cont = resource.getContents();
			if(cont.size() == 0) {
				int maxretry = 10;
				while(cont.size() == 0)
					Thread.yield(); // allow other thread to load resource
				if(cont.size() == 0)
					CorePlugin.logError("Unable to load content for resource "+normalized, new Exception());
			}
			retValue = (Identifiable) cont.get(0);
		} catch (final Exception e) {
			CorePlugin.logError(
					"The serialized instance of an Identifiable at \""
							+ identifableURI.toString()
							+ "\" was not found or was of the wrong format", e);
			retValue = null;
		}
		return retValue;
	} // getIdentifiable

	/**
	 * Serialize an {@link Identifiable}
	 * <p>
	 * Note this code is copied from
	 * org.eclipse.stem.internal.data.records.Record. That method should be
	 * removed and this one used instead.
	 * 
	 * @param identifiable
	 *            the {@link Identifiable} to be serialized.
	 * @param serializationURI
	 *            the {@link URI} that specifies where the {@link Identifiable}
	 *            is to be serialized.
	 * @throws IOException
	 *             if there is a problem serializing the {@link Identifiable}
	 */
	public static void serializeIdentifiable(final Identifiable identifiable,
			final URI serializationURI) throws IOException {
		final List<Identifiable> set = new ArrayList<Identifiable>();
		set.add(identifiable);
		serializeIdentifiables(set, serializationURI);
	} // serializeIdentifiable

	/**
	 * Serialize an {@link Identifiable}
	 * 
	 * @param identifiable
	 *            the {@link Identifiable} to be serialized.
	 * @param serializationURI
	 *            the {@link URI} that specifies where the {@link Identifiable}
	 *            is to be serialized.
	 * @throws IOException
	 *             if there is a problem serializing the {@link Identifiable}
	 */
	public static void serializeIdentifiables(final List<Identifiable> identifiables,
			final URI serializationURI) throws IOException {

		// This code could be running "stand alone" (i.e., not within eclipse),
		// thus the default factories for the extensions are not registered as
		// they would from their extension of
		// "org.eclipse.emf.ecore.extension_parser". So we need to register them
		// here.

		Resource.Factory.Registry.INSTANCE.getExtensionToFactoryMap().put("*",
				STEMXMIResourceFactoryImpl.INSTANCE);
		Resource.Factory.Registry.INSTANCE.getProtocolToFactoryMap().put(
				"platform", STEMXMIResourceFactoryImpl.INSTANCE);

		final ResourceSet resourceSet = new ResourceSetImpl();

		resourceSet.getResourceFactoryRegistry().getExtensionToFactoryMap()
				.put("*", STEMXMIResourceFactoryImpl.INSTANCE);

		resourceSet.getResourceFactoryRegistry().getProtocolToFactoryMap().put(
				"platform", STEMXMIResourceFactoryImpl.INSTANCE);

		final Resource resource = resourceSet.createResource(serializationURI);
		
		for (Identifiable id : identifiables) {
			resource.getContents().add(id);
		}

		resource.save(EMF_SAVE_OPTIONS);
	} // serializeIdentifiable
	
	/**
	 * Common method for determining the geographic level of a geographic key (last segment of a URI)
	 * @param key
	 * @return the level of the key
	 */
	public  static int keyLevel(final String key) {
		// null means unspecified and truly global for population models.
		if(key == null || key.trim().equals("")) return -2;
		// ZZZ is special, it means the world
		if(key.equalsIgnoreCase("ZZZ")) return -1;
		
		int level = 0;
		int start = 0;
		for (int temp = key.indexOf("-"); temp > 0;) { //$NON-NLS-1$
			level++;
			start += temp + 1;
			temp = key.substring(start).indexOf("-"); //$NON-NLS-1$
		} // for
		return level;
	} // keyLevel
	
	/**
	 * Displays a warning that the scenario composition may be invalid.
	 * For example the graph nesting within a simulation may be invalid
	 * An infector or inoculator may point to a node that does not exist.
	 * @param message
	 */
	public static void displayScenarioCompositionWarning(final String message) {
		try {
			if(Display.getDefault() != null)
				Display.getDefault().syncExec(new Runnable() {
					public void run() {
						try {
							final IWorkbenchWindow window = PlatformUI
									.getWorkbench().getActiveWorkbenchWindow();
//							final IStatus warning = new Status(IStatus.WARNING,
//									CorePlugin.PLUGIN_ID, 1, message, null);
//							ErrorDialog.openError(window.getShell(), null, null,
//									warning);
							String [] labels = new String[2];
							labels[1]  = "Help";
							labels[0] = "Okay";
							MessageDialog dialog = new MessageDialog(window.getShell(), "Warning", null, message,
									MessageDialog.WARNING, labels, 0) {
								@Override
								protected void buttonPressed(int buttonId) {
									if(buttonId == 1)
										PlatformUI.getWorkbench().getHelpSystem().displayHelp("org.eclipse.stem.doc.invalidnesting_contextid");
									else
										super.buttonPressed(buttonId);
								}
							};
							dialog.open();
						} catch(Exception e) {
							// If we get this exception, it is because we're not running in
							// eclipse.
						}
					} // run
				});
			
			else CorePlugin.logError(message, null);
			
		} catch (final Error ncdfe) {
			// Empty
		} // catch
	}
	
} // Utility
