/*******************************************************************************
 * Copyright (c) 2002, 2005 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
 *     Jens Lukowski/Innoopract - initial renaming/restructuring
 *     
 *******************************************************************************/
package org.eclipse.wst.xml.ui.internal.catalog;

import java.util.Hashtable;

import org.eclipse.jface.resource.CompositeImageDescriptor;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.resource.ImageRegistry;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.ImageData;
import org.eclipse.swt.graphics.Point;
import org.eclipse.wst.xml.ui.internal.XMLUIPlugin;

public class ImageFactory
{                                
  public static final int TOP_LEFT = 1;
  public static final int TOP_RIGHT = 2;
  public static final int BOTTOM_LEFT = 3;
  public static final int BOTTOM_RIGHT = 4;     

  protected static final int[][] OVERLAY_COORDINATE = {{0,0},{0,2},{2,0},{2,2}};
  
  protected static ImageFactory INSTANCE = new ImageFactory();

  protected Hashtable compositeImageTable = new Hashtable();

  public ImageFactory()
  {
	  super();
  }
  
	public Image getImage(String iconName)
	{
	  ImageRegistry imageRegistry = XMLUIPlugin.getDefault().getImageRegistry();
    
	  if (imageRegistry.get(iconName) != null)
	  {
		return imageRegistry.get(iconName);
	  }
	  else
	  {
		imageRegistry.put(iconName, ImageDescriptor.createFromFile(getClass(), iconName));
		return imageRegistry.get(iconName);
	  }
	}

  public Image createCompositeImage(Image base, Image overlay, int overlayPosition)
  {                                                   
    String key = base + "*" + overlay + "*" + overlayPosition; //$NON-NLS-1$ //$NON-NLS-2$
    Image result = (Image)compositeImageTable.get(key);
    if (result == null)
    {
      ImageDescriptor overlays[][] = new ImageDescriptor[3][3]; 
      int[] coord = OVERLAY_COORDINATE[overlayPosition];
      overlays[coord[1]][coord[0]] = new ImageBasedImageDescriptor(overlay);
      OverlayIcon icon = new OverlayIcon(new ImageBasedImageDescriptor(base), overlays, new Point(16, 16));
      result = icon.createImage();
      compositeImageTable.put(key, result);
    }
    return result;
  }  


  public static ImageDescriptor createImageDescriptorWrapper(Image image)
  {
    return new ImageBasedImageDescriptor(image);
  }

  /**
   * An OverlayIcon consists of a main icon and several adornments.
   */
   class OverlayIcon extends CompositeImageDescriptor {

      static final int DEFAULT_WIDTH = 22;

      static final int DEFAULT_HEIGHT = 16;

      private Point fSize = null;

      private ImageDescriptor fBase;

      private ImageDescriptor fOverlays[][];

      public OverlayIcon(ImageDescriptor base, ImageDescriptor[][] overlays,
              Point size) {
          fBase = base;
          fOverlays = overlays;
          fSize = size;
      }

      protected void drawBottomLeft(ImageDescriptor[] overlays) {
          if (overlays == null)
              return;
          int length = overlays.length;
          int x = 0;
          for (int i = 0; i < 3; i++) {
              if (i < length && overlays[i] != null) {
                  ImageData id = overlays[i].getImageData();
                  drawImage(id, x, getSize().y - id.height);
                  x += id.width;
              }
          }
      }

      protected void drawBottomRight(ImageDescriptor[] overlays) {
          if (overlays == null)
              return;
          int length = overlays.length;
          int x = getSize().x;
          for (int i = 2; i >= 0; i--) {
              if (i < length && overlays[i] != null) {
                  ImageData id = overlays[i].getImageData();
                  x -= id.width;
                  drawImage(id, x, getSize().y - id.height);
              }
          }
      }

      /**
       * @see CompositeImageDescriptor#drawCompositeImage(int, int)
       */
      protected void drawCompositeImage(int width, int height) {
          ImageData bg;
          if (fBase == null || (bg = fBase.getImageData()) == null)
              bg = DEFAULT_IMAGE_DATA;
          drawImage(bg, 0, 0);

          if (fOverlays != null) {
              if (fOverlays.length > 0)
                  drawTopRight(fOverlays[0]);

              if (fOverlays.length > 1)
                  drawBottomRight(fOverlays[1]);

              if (fOverlays.length > 2)
                  drawBottomLeft(fOverlays[2]);

              if (fOverlays.length > 3)
                  drawTopLeft(fOverlays[3]);
          }
      }

      protected void drawTopLeft(ImageDescriptor[] overlays) {
          if (overlays == null)
              return;
          int length = overlays.length;
          int x = 0;
          for (int i = 0; i < 3; i++) {
              if (i < length && overlays[i] != null) {
                  ImageData id = overlays[i].getImageData();
                  drawImage(id, x, 0);
                  x += id.width;
              }
          }
      }

      protected void drawTopRight(ImageDescriptor[] overlays) {
          if (overlays == null)
              return;
          int length = overlays.length;
          int x = getSize().x;
          for (int i = 2; i >= 0; i--) {
              if (i < length && overlays[i] != null) {
                  ImageData id = overlays[i].getImageData();
                  x -= id.width;
                  drawImage(id, x, 0);
              }
          }
      }

      /**
       * @see CompositeImageDescriptor#getSize()
       */
      protected Point getSize() {
          return fSize;
      }
  }

   static class ImageBasedImageDescriptor extends ImageDescriptor
  {
    protected Image image;

    public ImageBasedImageDescriptor(Image image)
    {
      this.image = image;
    }                    

    public ImageData getImageData()
    {
      return image.getImageData();
    }
  }  
}

