/*******************************************************************************
 * Copyright (c) 2000, 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 API and implementation
 *     Steven Ketcham (sketcham@dsicdi.com) - Bug 42451
 *     [Dialogs] ImageRegistry throws null pointer exception in
 *     application with multiple Display's
 *******************************************************************************/
package org.eclipse.jface.resource;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.core.runtime.Assert;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Device;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.ImageData;
import org.eclipse.swt.widgets.Display;

/**
 * An image registry maintains a mapping between symbolic image names 
 * and SWT image objects or special image descriptor objects which
 * defer the creation of SWT image objects until they are needed.
 * <p>
 * An image registry owns all of the image objects registered
 * with it, and automatically disposes of them when the SWT Display
 * that creates the images is disposed. Because of this, clients do not 
 * need to (indeed, must not attempt to) dispose of these images themselves.
 * </p>
 * <p>
 * Clients may instantiate this class (it was not designed to be subclassed).
 * </p>
 * <p>
 * Unlike the FontRegistry, it is an error to replace images. As a result
 * there are no events that fire when values are changed in the registry
 * </p>
 */
public class ImageRegistry {
    /**
     * display used when getting images
     */
    private Display display;

    private ResourceManager manager;

    private Map table;
    
    private Runnable disposeRunnable = new Runnable() {
        public void run() {
            dispose();
        }
    };
    
    /**
     * Contains the data for an entry in the registry. 
     */
    private static class Entry {
    	/** the image */
        protected Image image;

        /** the descriptor */
        protected ImageDescriptor descriptor;
    }
    
    private static class OriginalImageDescriptor extends ImageDescriptor {
        private Image original;
        private int refCount = 0;
        private Device originalDisplay;
        
        /**
         * @param original the original image
         * @param originalDisplay the device the image is part of
         */
        public OriginalImageDescriptor(Image original, Device originalDisplay) {
            this.original = original;
            this.originalDisplay = originalDisplay;
        }
        
        public Object createResource(Device device) throws DeviceResourceException {
            if (device == originalDisplay) {
                refCount++;
                return original;
            }
            return super.createResource(device);
        }
        
        public void destroyResource(Object toDispose) {
            if (original == toDispose) {
                refCount--;
                if (refCount == 0) {
                    original.dispose();
                    original = null;
                }
            } else {
                super.destroyResource(toDispose);
            }
        }

        /* (non-Javadoc)
         * @see org.eclipse.jface.resource.ImageDescriptor#getImageData()
         */
        public ImageData getImageData() {
            return original.getImageData();
        }
    }
        
    /**
     * Creates an empty image registry.
     * <p>
     * There must be an SWT Display created in the current 
     * thread before calling this method.
     * </p>
     */
    public ImageRegistry() {
        this(Display.getCurrent());
    }

    /**
     * Creates an empty image registry using the given resource manager to allocate images.
     * 
     * @param manager the resource manager used to allocate images
     * 
     * @since 3.1
     */
    public ImageRegistry(ResourceManager manager) {
        Assert.isNotNull(manager);
        Device dev = manager.getDevice();
        if (dev instanceof Display) {
            this.display = (Display)dev;
        }
        this.manager = manager;
        manager.disposeExec(disposeRunnable);
    }
    
    /**
     * Creates an empty image registry.
     * 
     * @param display this <code>Display</code> must not be 
     *        <code>null</code> and must not be disposed in order
     *        to use this registry
     */
    public ImageRegistry(Display display) {
        this(JFaceResources.getResources(display));
    }
    
    /**
     * Returns the image associated with the given key in this registry, 
     * or <code>null</code> if none.
     * 
     * @param key the key
     * @return the image, or <code>null</code> if none
     */
    public Image get(String key) {

        // can be null
        if (key == null) {
            return null;
        }
        
        if (display != null) {
            /**
             * NOTE, for backwards compatibility the following images are supported
             * here, they should never be disposed, hence we explicitly return them 
             * rather then registering images that SWT will dispose.  
             * 
             * Applications should go direclty to SWT for these icons.
             * 
             * @see Display.getSystemIcon(int ID)
             */
            int swtKey = -1;
            if (key.equals(Dialog.DLG_IMG_INFO)) {
                swtKey = SWT.ICON_INFORMATION;
            }
            if (key.equals(Dialog.DLG_IMG_QUESTION)) {
                swtKey = SWT.ICON_QUESTION;
            }
            if (key.equals(Dialog.DLG_IMG_WARNING)) {
                swtKey = SWT.ICON_WARNING;
            }
            if (key.equals(Dialog.DLG_IMG_ERROR)) {
                swtKey = SWT.ICON_ERROR;
            }
            // if we actually just want to return an SWT image do so without
            // looking in the registry
            if (swtKey != -1) {
                final Image[] image = new Image[1];
                final int id = swtKey;
                display.syncExec(new Runnable() {
                    public void run() {
                        image[0] = display.getSystemImage(id);
                    }
                });
                return image[0];
            }
        }

        Entry entry = getEntry(key);
        if (entry == null) {
            return null;
        }
        
        if (entry.image == null) {
            entry.image = manager.createImageWithDefault(entry.descriptor);
        }
        
        return entry.image;
    }

    /**
     * Returns the descriptor associated with the given key in this registry, 
     * or <code>null</code> if none.
     *
     * @param key the key
     * @return the descriptor, or <code>null</code> if none
     * @since 2.1
     */
    public ImageDescriptor getDescriptor(String key) {
        Entry entry = getEntry(key);
        if (entry == null) {
            return null;
        }
        
        return entry.descriptor;
    }

    /**
     * Adds (or replaces) an image descriptor to this registry. The first time
     * this new entry is retrieved, the image descriptor's image will be computed 
     * (via </code>ImageDescriptor.createImage</code>) and remembered. 
     * This method replaces an existing image descriptor associated with the 
     * given key, but fails if there is a real image associated with it.
     *
     * @param key the key
     * @param descriptor the ImageDescriptor
     * @exception IllegalArgumentException if the key already exists
     */
    public void put(String key, ImageDescriptor descriptor) {
        Entry entry = getEntry(key);
        if (entry == null) {
            entry = new Entry();
            getTable().put(key, entry);
        }
        
        if (entry.image != null) {
            throw new IllegalArgumentException(
                    "ImageRegistry key already in use: " + key); //$NON-NLS-1$            
        }
        
        entry.descriptor = descriptor;
    }

    /**
     * Adds an image to this registry.  This method fails if there
     * is already an image or descriptor for the given key.
     * <p>
     * Note that an image registry owns all of the image objects registered
     * with it, and automatically disposes of them when the SWT Display is disposed. 
     * Because of this, clients must not register an image object
     * that is managed by another object.
     * </p>
     *
     * @param key the key
     * @param image the image, should not be <code>null</code>
     * @exception IllegalArgumentException if the key already exists
     */
    public void put(String key, Image image) {
        Entry entry = getEntry(key);
        
        if (entry == null) {
            entry = new Entry();
            putEntry(key, entry);
        }
        
        if (entry.image != null || entry.descriptor != null) {
            throw new IllegalArgumentException(
                    "ImageRegistry key already in use: " + key); //$NON-NLS-1$            
        }
        
        // Check for a null image here, otherwise the problem won't appear
        // until dispose.
        // See https://bugs.eclipse.org/bugs/show_bug.cgi?id=130315
        Assert.isNotNull(image, "Cannot register a null image."); //$NON-NLS-1$
        entry.image = image;
        entry.descriptor = new OriginalImageDescriptor(image, manager.getDevice());
        
        try {
            manager.create(entry.descriptor);
        } catch (DeviceResourceException e) {            
        }
    }

    /**
     * Removes an image from this registry.  
     * If an SWT image was allocated, it is disposed.
     * This method has no effect if there is no image or descriptor for the given key.
     * @param key the key
     */
    public void remove(String key) {
        ImageDescriptor descriptor = getDescriptor(key);
        if (descriptor != null) {
            manager.destroy(descriptor);
            getTable().remove(key);
        }
    }

    private Entry getEntry(String key) {
        return (Entry) getTable().get(key);
    }

    private void putEntry(String key, Entry entry) {
        getTable().put(key, entry);
    }

    private Map getTable() {
        if (table == null) {
            table = new HashMap(10);
        }
        return table;
    }
    
    /**
     * Disposes this image registry, disposing any images
     * that were allocated for it, and clearing its entries.
     * 
     * @since 3.1
     */
    public void dispose() {
        manager.cancelDisposeExec(disposeRunnable);
        
        if (table != null) {
            for (Iterator i = table.values().iterator(); i.hasNext();) {
                Entry entry = (Entry) i.next();
                if (entry.image != null) {
                    manager.destroyImage(entry.descriptor);
                }
            }
            table = null;
        }
        display = null;
    }
}
