//------------------------------------------------------------------------------
// Copyright (c) 2005, 2007 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 implementation
//------------------------------------------------------------------------------
package org.eclipse.epf.common.ui;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URL;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.MissingResourceException;
import java.util.Properties;
import java.util.ResourceBundle;

import org.eclipse.core.internal.runtime.InternalPlatform;
import org.eclipse.core.runtime.FileLocator;
import org.eclipse.core.runtime.Platform;
import org.eclipse.epf.common.IActivator;
import org.eclipse.epf.common.serviceability.Logger;
import org.eclipse.epf.common.ui.util.MsgDialog;
import org.eclipse.epf.common.utils.FileUtil;
import org.eclipse.epf.common.utils.I18nUtil;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.plugin.AbstractUIPlugin;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;

/**
 * The abstract base class for all EPF plug-ins.
 * 
 * @author Kelvin Low
 * @author Jinhua Xi
 * @author Phong Nguyen Le
 * @since 1.0
 */
public abstract class AbstractPlugin extends AbstractUIPlugin implements IActivator {


	// The relative path to the icons.
	private static final String ICON_PATH = "icons/"; //$NON-NLS-1$;

	// The logger hash map.
	private static Map<String, Logger> loggers = new HashMap<String, Logger>();

	// The message dialog hash map.
	private static Map<String, MsgDialog> msgDialogs = new HashMap<String, MsgDialog>();

	// The shared image hash map.
	private static Map<String, Image> sharedImages = new HashMap<String, Image>();

	// The resource bundle for this plug-in.
	private ResourceBundle resourceBundle;

	// This plug-in ID.
	private String pluginId;

	// The plug-in install URL.
	private URL installURL;

	// The plug-in install path.
	private String installPath;

	// The plug-in icon URL.
	private URL iconURL;

	// The profiling flag.
	private boolean profiling;

	/**
	 * Default constructor.
	 */
	public AbstractPlugin() {
		super();
	}

	/**
	 * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(BundleContext)
	 */
	public void start(BundleContext context) throws Exception {
		super.start(context);

		init(context);

		// set the 
		if (isDebugging()) {
			getLogger().logInfo("Started " + pluginId); //$NON-NLS-1$			
		}
	}

	/**
	 * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(BundleContext)
	 */
	public void stop(BundleContext context) throws Exception {
		// Free the shared images.
		for (Iterator images = sharedImages.values().iterator(); images
				.hasNext();) {
			Image image = (Image) images.next();
			if (image != null && !image.isDisposed()) {
				image.dispose();
			}
		}

		super.stop(context);

		if (isDebugging()) {
			getLogger().logInfo("Stopped " + pluginId); //$NON-NLS-1$
		}
	}

	/**
	 * Initializes this plug-in.
	 * 
	 * @param context
	 *            The bundle context.
	 */
	protected void init(BundleContext context) throws Exception {
		// Get the bundle for this plug-in.
		Bundle bundle = getBundle();

		// Get the resouce bundle for this plug-in.
		resourceBundle = Platform.getResourceBundle(bundle);

		// Get the ID for this plug-in.
		pluginId = bundle.getSymbolicName();

		if (isDebugging()) {
			getLogger().logInfo("Initializing " + pluginId); //$NON-NLS-1$		
		}

		// Get the install path of this plug-in.
		installURL = bundle.getEntry("/"); //$NON-NLS-1$

		try {
			installPath = FileLocator.resolve(installURL).getPath();
		} catch (IOException e) {
			installPath = Platform.getInstallLocation().getURL().getPath();
		}

		try {
			iconURL = new URL(installURL, ICON_PATH);
		} catch (IOException e) {
		}

		String symbolicName = bundle.getSymbolicName();
		if (symbolicName != null) {
			String key = symbolicName + "/profiling"; //$NON-NLS-1$
			String value = InternalPlatform.getDefault().getOption(key);
			profiling = value == null ? false : value.equalsIgnoreCase("true"); //$NON-NLS-1$
		}

		if (isDebugging()) {
			getLogger().logInfo(
					"Initialized " + pluginId + ", installPath=" + installPath); //$NON-NLS-1$ //$NON-NLS-2$
		}
	}

	/**
	 * Returns the ID of this plug-in.
	 * 
	 * @return The ID of this plug-in.
	 */
	public String getId() {
		return pluginId;
	}

	/**
	 * Returns the install URL of this plug-in.
	 * 
	 * @param The
	 *            install URL of this plug-in.
	 */
	public URL getInstallURL() {
		return installURL;
	}

	/**
	 * Returns the install path of this plug-in.
	 * 
	 * @param The
	 *            install path of this plug-in.
	 */
	public String getInstallPath() {
		return installPath;
	}

	/**
	 * Loads and returns the localized properties of a Java properties file.
	 * <p>
	 * 
	 * @param path
	 *            The properties file path relative to the plug-in root.
	 * @return A <code>Properties</code> object.
	 */
	public Properties getProperties(String path) throws IOException {
		Properties props = new Properties();
		if (path == null) {
			return props;
		}

		String filePath = getLocalizedFile(path, true);
		if (filePath != null) {
			props.load(new FileInputStream(filePath));
		}

		return props;
	}

	/**
	 * get the locale specific absolute file path name of the given file in the
	 * plugin.
	 * 
	 * @param path
	 *            The properties file path relative to the plug-in root.
	 * @return String the locale specific absolute file path name of the given
	 *         file.
	 * @throws IOException
	 */
	public String getLocalizedFile(String path, boolean useDefault)
			throws IOException {
		String filePath = null;
		String fileName = FileUtil.getFileName(path);
		int index = path.lastIndexOf(fileName);
		String pathName = path.substring(0, index);

		Locale locale = Locale.getDefault();

		Bundle bundle = getBundle();
		Bundle[] bundles = Platform.getFragments(bundle);
		if (bundles != null) {
			for (int i = 0; i < bundles.length; i++) {
				URL entry = bundles[i].getEntry(pathName);
				if (entry != null) {
					URL url = FileLocator.resolve(entry);
					filePath = I18nUtil.getLocalizedFile(url.getPath()
							+ fileName, locale); 
					if (filePath != null) {
						break;
					}
				}
			}
		}

		if (filePath == null) {
			URL entry = bundle.getEntry(path);
			if (entry != null) {
				URL url = FileLocator.resolve(entry);
				filePath = I18nUtil.getLocalizedFile(url.getPath(), locale);
				if (filePath == null && useDefault) {
					filePath = url.getPath();
				}
			}
		}

		return filePath;
	}

	/**
	 * for the given path in the plugin, find the localized files form the nl
	 * fragemenets and copy the localized files to the destination folder
	 * 
	 * @param path
	 *            String a relative path to the plugin root. The files in this
	 *            folder will be iterated and their localized files will be
	 *            copied over
	 * @param toDir
	 *            FIle the destination folder
	 * @param recursive
	 *            boolean recurively looking for files int the specified folder
	 * @param useLocaleFileName
	 *            boolean if true the locale specific file names will be used in
	 *            the copied destination, otherwise, the locale specific file
	 *            name will be renamed to the default one in the destination
	 *            folder
	 * @throws IOException
	 */
	public void copyLocalizedFiles(String path, File toDir, boolean recursive,
			boolean useLocaleFileName) throws IOException {
		String pluginPath = getInstallPath();
		URI pluginUri = new File(pluginPath).toURI();
		URI pathUri = new File(pluginPath, path).toURI();

		List<File> files = new ArrayList<File>();
		File f = new File(pluginPath, path);
		FileUtil.getAllFiles(f, files, recursive);

		// for each file found in the specified folder, get the localized file
		for (Iterator it = files.iterator(); it.hasNext();) {
			URI srcUri = ((File) it.next()).toURI();

			// get the relative path of the file to the plugin root, then find
			// the localized file
			String relPath = pluginUri.relativize(srcUri).getPath();

			// only get the locale specific file, don't include the default one
			String localizedFile = getLocalizedFile(relPath, false);
			if (localizedFile == null) {
				continue;
			}

			// need to change the target file path to relative to the path
			// instead of the plugin root
			relPath = pathUri.relativize(srcUri).getPath();
			File srcFile = new File(localizedFile);
			File targetFile = new File(toDir, relPath);
			File targetParent = targetFile.getParentFile();

			// copy the file to the desitination
			// if useLocaleFileName is true, the destination file name should
			// also use the locale specific file name
			if (useLocaleFileName) {
				String fileName = srcFile.getName();
				targetFile = new File(targetParent, fileName);
			}

			if (isDebugging()) {
				System.out.println("Copying localized file: "); //$NON-NLS-1$
				System.out.println("Source: " + srcFile); //$NON-NLS-1$
				System.out.println("Target: " + targetFile); //$NON-NLS-1$
				System.out.println(""); //$NON-NLS-1$
			}

			try {
				if (!targetParent.exists()) {
					targetParent.mkdirs();
				}

				if (!targetFile.exists()) {
					targetFile.createNewFile();
				}

				FileUtil.copyFile(srcFile, targetFile);
			} catch (IOException e) {
				e.printStackTrace();
			}
		}

	}

	/**
	 * Returns the localized resource.
	 * 
	 * @param key
	 *            The resource key.
	 * @return The localized resource.
	 */
	public String getString(String key) {
		if (resourceBundle != null) {
			try {
				return resourceBundle.getString(key);
			} catch (MissingResourceException e) {
			}
		}
		return '[' + key + ']';
	}

	/**
	 * Returns the formatted localized message given the resource key and the
	 * message argument.
	 * 
	 * @param key
	 *            The resource key.
	 * @param argument
	 *            The message argument.
	 * @return The formatted localized message.
	 */
	public String formatMessage(String key, Object argument) {
		if (resourceBundle != null) {
			try {
				String msg = resourceBundle.getString(key);
				Object[] arguments = { argument };
				return MessageFormat.format(msg, arguments);
			} catch (MissingResourceException e) {
			}
		}
		return '[' + key + ']';
	}

	/**
	 * Returns the image URL given the relative path.
	 * 
	 * @param relativePath
	 *            The image's path relative to the plug-in's root.
	 * @return The image URL.
	 */
	public URL getImageURL(String relativePath) {
		try {
			URL url = new URL(iconURL, relativePath);
			return FileLocator.resolve(url);
		} catch (Exception e) {
			return null;
		}
	}

	/**
	 * Returns the image descriptor given the relative path.
	 * 
	 * @param relativePath
	 *            The image's path relative to the plug-in's root.
	 * @return The image descriptor.
	 */
	public ImageDescriptor getImageDescriptor(String relativePath) {
		try {
			URL url = new URL(iconURL, relativePath);
			return ImageDescriptor.createFromURL(url);
		} catch (MalformedURLException e) {
			return ImageDescriptor.getMissingImageDescriptor();
		}
	}

	/**
	 * Returns the image given the relative path.
	 * <p>
	 * Note: The returned image need to be freed by the caller.
	 * 
	 * @param relativePath
	 *            The image's path relative to the plug-in's root.
	 * @return The image.
	 */
	public Image getImage(String relativePath) {
		Image image = null;

		ImageDescriptor imageDescriptor = getImageDescriptor(relativePath);
		if (imageDescriptor != null) {
			image = imageDescriptor.createImage(false);
		}

		return image;
	}

	/**
	 * Returns the shared image given the relative path.
	 * <p>
	 * Note: The returned image will be automatically freed when the plug-in
	 * shuts down.
	 * 
	 * @param relativePath
	 *            The image's path relative to the plug-in's root.
	 * @return The image.
	 */
	public Image getSharedImage(String relativePath) {
		Image image = (Image) sharedImages.get(relativePath);
		if (image != null) {
			return image;
		}

		ImageDescriptor imageDescriptor = getImageDescriptor(relativePath);
		if (imageDescriptor != null) {
			image = imageDescriptor.createImage(false);
			if (image != null) {
				sharedImages.put(relativePath, image);
			}
		}

		return image;
	}

	/**
	 * Returns the profiling flag.
	 * 
	 * @return <code>true</code> if profiling is enabled for this plu-in
	 */
	public boolean isProfiling() {
		return profiling;
	}

	/**
	 * Returns the logger given the plug-in ID.
	 * 
	 * @return The new or cached logger.
	 */
	public Logger getLogger() {
		Logger logger = (Logger) loggers.get(pluginId);
		if (logger == null) {
			logger = new Logger(this);
			loggers.put(pluginId, logger);
		}
		return logger;
	}
	
	/**
	 * Returns the message dialog given the plug-in ID.
	 * 
	 * @return The new or cached message dialog.
	 */
	public static MsgDialog getMsgDialog(IActivator plugin) {
		MsgDialog msgDialog = (MsgDialog) msgDialogs.get(plugin.getId());
		if (msgDialog == null) {
			msgDialog = new MsgDialog(plugin);
			msgDialogs.put(plugin.getId(), msgDialog);
		}
		return msgDialog;
	}

	
	public MsgDialog getMsgDialog() {		
		return getMsgDialog(this);
	}
	
	/**
	 * Returns the standard display to be used. The method first checks, if the
	 * thread calling this method has an associated disaply. If so, this display
	 * is returned. Otherwise the method returns the default display.
	 */
	public static Display getStandardDisplay() {
		Display display;
		display = Display.getCurrent();
		if (display == null)
			display = Display.getDefault();
		return display;
	}

}
