//------------------------------------------------------------------------------
// 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.plugin;

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.serviceability.Logger;
import org.eclipse.epf.common.serviceability.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
 * @since 1.0
 */
public abstract class AbstractPlugin extends AbstractUIPlugin {

	// 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);

		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 MsgDialog getMsgDialog() {
		MsgDialog msgDialog = (MsgDialog) msgDialogs.get(pluginId);
		if (msgDialog == null) {
			msgDialog = new MsgDialog(this);
			msgDialogs.put(pluginId, msgDialog);
		}
		return msgDialog;
	}

	/**
	 * 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;
	}

}
