/**
 * File:    ImageFactory.java
 * Created: 25.02.2006
 *
 *
/*******************************************************************************
 * Copyright (c) 2005-2011
 * University of Augsburg, Germany <www.ds-lab.org>
 *
 * 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:
 *    Markus Bauer, Programming distributed Systems Lab, University of Augsburg 
 *    	- initial API and implementation
 *    Marc Blachon, Bull SAS, Grenoble, France
 *      - Make this class implementing IImageFactory.
 *******************************************************************************/

package org.eclipse.jwt.we.figures.internal;

import java.util.MissingResourceException;

import org.eclipse.draw2d.geometry.Dimension;
import org.eclipse.emf.common.ui.EclipseUIPlugin;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.resource.ImageRegistry;
import org.eclipse.jwt.we.PluginProperties;
import org.eclipse.jwt.we.figures.IImageFactory;
import org.eclipse.jwt.we.misc.logging.Logger;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.ImageData;
import org.eclipse.ui.plugin.AbstractUIPlugin;

/**
 * Creates images. It uses an {@link ImageRegistry} for disposing the images.
 * 
 * @version $Id: ImageFactory.java,v 1.8 2009-12-10 14:22:20 chsaad Exp $
 * @author Markus Bauer (markusbauer@users.sourceforge.net), Programming
 *         distributed Systems Lab, University of Augsburg, Germany,
 *         www.ds-lab.org
 */
public class ImageFactory implements IImageFactory
{

	/**
	 * A Logger.
	 */
	private static final Logger logger = Logger.getLogger(ImageFactory.class);

	/**
	 * Path where the icons are located
	 */
	private final String iconBasePath;

	/**
	 * plugin using JWT-WE
	 */
	private final EclipseUIPlugin plugin;

	/**
	 * The size for images representing a model type.
	 */
	public static final Dimension MODEL_TYPE_IMAGE_SIZE = new Dimension(16, 16);

	/**
	 * A ImageRegistry that handles images.
	 * 
	 * <p>
	 * Never <code>null</code>.
	 * </p>
	 */
	private final ImageRegistry imageRegistry;


	/**
	 * @param imageRegistry
	 *            The registry for disposing the images.
	 */
	public ImageFactory(final ImageRegistry imageRegistry, final EclipseUIPlugin plugin,
			final String iconBasePath)
	{
		assert imageRegistry != null;
		this.imageRegistry = imageRegistry;
		this.iconBasePath = iconBasePath;
		this.plugin = plugin;
	}


	/**
	 * Returns an image.
	 * 
	 * <p>
	 * The {@link ImageRegistry} handles dispose of the image.
	 * </p>
	 * 
	 * @param imageDescriptor
	 *            The {@link ImageDescriptor} that creates the image. Its String
	 *            representations is the key in the {@link ImageRegistry}.
	 * @return The image, or <code>null</code> if it could not be found.
	 */
	public Image getImage(final ImageDescriptor imageDescriptor)
	{
		return getImage(imageDescriptor, null);
	}


	/**
	 * Returns an image from the {@link ImageRegistry}.
	 * 
	 * <p>
	 * The image will be scaled to the given size.
	 * </p>
	 * 
	 * @param imageDescriptor
	 *            The {@link ImageDescriptor} that creates the image. Its String
	 *            representations is the key in the {@link ImageRegistry}.
	 * @param size
	 *            The size of the returned image. If <code>null</code> the image
	 *            is returned unscaled.
	 * @return The image, or <code>null</code> if it could not be found.
	 */
	public Image getImage(ImageDescriptor imageDescriptor, final Dimension size)
	{
		if (imageDescriptor == null)
		{
			return null;
		}

		// scale the image if necessary
		if (!(imageDescriptor instanceof ScalingImageDescriptor))
		{
			imageDescriptor = new ScalingImageDescriptor(imageDescriptor, size);
		}
		else
		{
			if (size != null)
			{
				((ScalingImageDescriptor) imageDescriptor).setSize(size);
			}
		}

		final String name = imageDescriptor.toString();

		Image image = imageRegistry.get(name);

		if (image != null)
		{
			logger.debug("Image found in registry as: " + name); //$NON-NLS-1$
		}
		else
		{
			try
			{
				// load new image into the registry
				imageRegistry.put(name, imageDescriptor);
				logger.debug("Registry miss. New entry: " + name); //$NON-NLS-1$
				image = imageRegistry.get(name);
			}
			catch (Exception e)
			{
				logger.warning("Error creating image " + name); //$NON-NLS-1$
			}
		}

		return image;
	}


	/**
	 * Returns an image descriptor for the image file at the given plug-in
	 * relative path.
	 * 
	 * @param path
	 *            the path
	 * @return the image descriptor
	 */
	public ImageDescriptor createImageDescriptor(final String path)
	{
		final String temppath = iconBasePath + path;

		ImageDescriptor result = AbstractUIPlugin.imageDescriptorFromPlugin(plugin
				.getBundle().getSymbolicName(), temppath);

		/**
		 * If the icon could not be found (for example because the user put it
		 * in a different folder than icons, load it a snd time but this time
		 * without the icons folder prefix
		 */
		// if (result == null)
		// result = AbstractUIPlugin.imageDescriptorFromPlugin(Plugin.getId(),
		// temppath);
		return result;
	}


	/**
	 * Creates an ImageDescriptor that represents the type of a model object.
	 * 
	 * @param model
	 *            The model object.
	 * @return The ImageDescriptor.
	 */
	public ImageDescriptor createModelTypeImageDescriptor(final Object model)
	{
		String path;
		try
		{
			path = PluginProperties.model_smallIcon(model);
		}
		catch (final MissingResourceException e)
		{
			return null;
		}

		final ImageDescriptor imageDescriptor = createImageDescriptor(path);

		// test if the image is available
		if (imageDescriptor == null)
			return null;
		final ImageData data = imageDescriptor.getImageData();

		ImageDescriptor result = data == null ? null : new ScalingImageDescriptor(
				imageDescriptor, MODEL_TYPE_IMAGE_SIZE);

		return result;
	}


	public String getIconBasePath()
	{
		return iconBasePath;
	}
}
