//------------------------------------------------------------------------------
// Copyright (c) 2005, 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 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.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 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 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>();

	/**
	 * 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) {
		}

		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);
		
//		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 = Platform.resolve(entry);
//					filePath = I18nUtil.getLocalizedFile(url.getPath() + fileName, locale); //$NON-NLS-1$
//					if (filePath != null) {
//						break;
//					}
//				}
//			}
//		}
//
//		if (filePath == null) {
//			URL entry = bundle.getEntry(path);
//			if (entry != null) {
//				URL url = Platform.resolve(entry);
//				filePath = I18nUtil.getLocalizedFile(url.getPath(), locale);
//				if (filePath == null) {
//					filePath = url.getPath();
//				}
//			}
//		}

		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); //$NON-NLS-1$
					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;
	}
	
//	/**
//	 * get the localized files for the files in the specified folder. The folder is a relative path to the plugin.
//	 * returns a map of the files (in ralitive path to the plugin) to their localized files in absolute path.
//	 * @param folder String path relative to the current plugin
//	 * @param recursive boolean if true recurisely get all files in sub folders
//	 * @return Map a map of the files (in ralitive path to the plugin) to their localized files in absolute path.
//	 * @throws IOException
//	 */
//	public Map getLocalizedFiles(String folder, boolean recursive) throws IOException
//	{
//		Map fileMap = new HashMap();
//		
//		String pluginPath = getInstallPath();
//		
//		List files = new ArrayList();
//		File f = new File(pluginPath, folder);
//		FileUtil.getAllFiles(f, files, true);
//
//		// for each file found in the specified folder, get the localized file
//		// put an antry of the original file and the localized file
//		URI pluginUri = new File(pluginPath).toURI();
//		
//		for ( Iterator it = files.iterator(); it.hasNext(); )
//		{
//			File src = (File)it.next();
//			String relPath = pluginUri.relativize(src.toURI()).getPath();
//			
//			// only get the locale specific file, don't include the default one
//			String localizedFile = getLocalizedFile(relPath, false);
//			if ( localizedFile != null )
//			{
//				fileMap.put(relPath, localizedFile);
//			}
//		}
//		
//		return fileMap;
//	}
	
	/**
	 * 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 files = new ArrayList();
		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 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;		
	}


}
