package org.eclipse.jwt.we.misc.providers;

import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.logging.Level;
import java.util.logging.Logger;

import org.eclipse.draw2d.geometry.Dimension;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jwt.meta.model.core.NamedElement;
import org.eclipse.jwt.meta.providers.interfaces.IImageProvider;
import org.eclipse.jwt.we.Plugin;
import org.eclipse.jwt.we.figures.internal.CombinedImageDescriptor;
import org.eclipse.jwt.we.figures.internal.ScalingImageDescriptor;
import org.eclipse.jwt.we.misc.views.Views;

public class MetaModelImageProvider implements IImageProvider
{

	private ImageDescriptor createScalingImageDescriptor(ImageDescriptor imageDescriptor)
	{
		if (imageDescriptor != null)
		{
			return new ScalingImageDescriptor((ImageDescriptor) imageDescriptor,
					new Dimension(16, 16));
		}
		else
		{
			return null;
		}
	}


	/**
	 * Returns an ImageDescriptor that creates an {@link ImageDescriptor} from
	 * the icon path stored in the model.
	 * 
	 * <p>
	 * The image is loaded from the path described by the
	 * {@link NamedElement#getIcon() icon path} in the model. Several methods
	 * are tried to retrieve the image. The image from first method that succeds
	 * is display. The following methods are used:
	 * </p>
	 * <ol>
	 * <li>Load icon as URL.<br>
	 * The icon path is interpreted an an URL. This is very flexible an allows
	 * different location for an icon.
	 * <ul>
	 * <li>The URL can describe a path on the local file system. For example:
	 * <code>file:///path/to/image.png</code></li>
	 * <li>The URL can describe a path in the internet. For example:
	 * <code>http://www.eclipse.org/jwt/pictures/uni_logo.gif</code></li>
	 * <li>The URL can describe a path to an icon in another plugin. For
	 * example:
	 * <code>platform:/plugin/org.eclipse.help.ui/icons/etool16/eclipse.gif</code>
	 * shows <code>eclipse.gif</code> form the
	 * <code>org.eclipse.help.ui plugin</code>.</li>
	 * <li>Any other URL which protocol is registered.</li>
	 * </ul>
	 * </li>
	 * <li>Load icon from Workflow plugin.<br>
	 * The icon path is interpreted as a relative path in the plugin's icon
	 * directory.</li>
	 * <li>Load icon from file system.<br>
	 * The icon path is interpreted as a path in the local file system. For
	 * example the icon <code>c:\path\to\image.png</code> load an icon from this
	 * path. Note that this is platform dependend.
	 * </ol>
	 * 
	 * @param object
	 *            The model element.
	 * @return The ImageDescriptor or <code>null</code> if the model does not
	 *         have an icon.
	 */
	public ImageDescriptor createImageDescriptor(Object object)
	{
		// if no icon is set, use standard model image
		String iconPath = "";

		if (object instanceof NamedElement && ((NamedElement) object).getIcon() != null)
		{
			iconPath = ((NamedElement) object).getIcon();
		}
		else
		{
			return createScalingImageDescriptor(Plugin.getInstance().getFactoryRegistry()
					.getImageFactory(Views.getInstance().getSelectedView())
					.createModelTypeImageDescriptor(object));
		}

		ImageDescriptor urlDescriptor = null;
		ImageDescriptor pluginDescriptor = null;
		ImageDescriptor fileDescriptor = null;

		if (!iconPath.equals(""))
		{
			// else: try to load icon from URL
			try
			{
				URL url = new URL(iconPath);
				urlDescriptor = ImageDescriptor.createFromURL(url);
			}
			catch (MalformedURLException e)
			{
			}

			// else: try to search for icon in plugin
			pluginDescriptor = Plugin.getInstance().getFactoryRegistry()
					.getImageFactory().createImageDescriptor(iconPath);

			// else: try to search for icon in file system (if it does not
			// exist,
			// add icon path prefix)
			if (new File(iconPath).exists())
			{
				fileDescriptor = ImageDescriptor.createFromFile(null, iconPath);
			}
			else if (new File(Plugin.ICONS_BASE_PATH + iconPath).exists())
			{
				fileDescriptor = ImageDescriptor.createFromFile(null,
						Plugin.ICONS_BASE_PATH + iconPath);
			}
		}

		// return result
		if (iconPath.equals("") && pluginDescriptor == null && urlDescriptor == null
				&& fileDescriptor == null)
		{
			// return standard
			return createScalingImageDescriptor(Plugin.getInstance().getFactoryRegistry()
					.getImageFactory().createModelTypeImageDescriptor(object));
		}
		else if (!iconPath.equals("") && pluginDescriptor == null
				&& urlDescriptor == null && fileDescriptor == null)
		{
//			Logger.getLogger(MetaModelImageProvider.class.toString()).log(Level.WARNING,
//					"error loading image " + iconPath + " (using standard image)");

			// return standard
			return createScalingImageDescriptor(Plugin.getInstance().getFactoryRegistry()
					.getImageFactory().createModelTypeImageDescriptor(object));
		}
		else
		{
			// return combined
			return createScalingImageDescriptor(new CombinedImageDescriptor(
					new ImageDescriptor[]
					{ urlDescriptor, pluginDescriptor, fileDescriptor }));
		}
	}
}
