package net.sf.jasperreports.engine.util;

import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.InputStream;
import java.net.URL;
import java.net.URLStreamHandlerFactory;
import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JRRuntimeException;

public class JRImageLoader {
  public static final String PROPERTY_IMAGE_READER = "net.sf.jasperreports.image.reader";
  
  public static final String PROPERTY_IMAGE_ENCODER = "net.sf.jasperreports.image.encoder";
  
  public static final byte NO_IMAGE = 1;
  
  public static final byte SUBREPORT_IMAGE = 2;
  
  public static final byte CHART_IMAGE = 3;
  
  public static final byte CROSSTAB_IMAGE = 4;
  
  private static final String str_NO_IMAGE = "net/sf/jasperreports/engine/images/noimage.GIF";
  
  private static final String str_SUBREPORT_IMAGE = "net/sf/jasperreports/engine/images/subreport.GIF";
  
  private static final String str_CHART_IMAGE = "net/sf/jasperreports/engine/images/chart.GIF";
  
  private static final String str_CROSSTAB_IMAGE = "net/sf/jasperreports/engine/images/crosstab.GIF";
  
  private static Image img_NO_IMAGE = null;
  
  private static Image img_SUBREPORT_IMAGE = null;
  
  private static Image img_CHART_IMAGE = null;
  
  private static Image img_CROSSTAB_IMAGE = null;
  
  private static JRImageReader imageReader = null;
  
  private static JRImageEncoder imageEncoder = null;
  
  static {
    String readerClassName = JRProperties.getProperty("net.sf.jasperreports.image.reader");
    if (readerClassName == null) {
      imageReader = new JRJdk14ImageReader();
    } else {
      try {
        Class clazz = JRClassLoader.loadClassForRealName(readerClassName);
        imageReader = clazz.newInstance();
      } catch (Exception e) {
        throw new JRRuntimeException(e);
      } 
    } 
    String encoderClassName = JRProperties.getProperty("net.sf.jasperreports.image.encoder");
    if (encoderClassName == null) {
      imageEncoder = new JRJdk14ImageEncoder();
    } else {
      try {
        Class clazz = JRClassLoader.loadClassForRealName(encoderClassName);
        imageEncoder = clazz.newInstance();
      } catch (Exception e) {
        throw new JRRuntimeException(e);
      } 
    } 
  }
  
  public static byte[] loadImageDataFromFile(File file) throws JRException {
    return JRLoader.loadBytes(file);
  }
  
  public static byte[] loadImageDataFromURL(URL url) throws JRException {
    return JRLoader.loadBytes(url);
  }
  
  public static byte[] loadImageDataFromInputStream(InputStream is) throws JRException {
    return JRLoader.loadBytes(is);
  }
  
  public static byte[] loadImageDataFromLocation(String location) throws JRException {
    return JRLoader.loadBytesFromLocation(location);
  }
  
  public static byte[] loadImageDataFromLocation(String location, ClassLoader classLoader) throws JRException {
    return JRLoader.loadBytesFromLocation(location, classLoader);
  }
  
  public static byte[] loadImageDataFromLocation(String location, ClassLoader classLoader, URLStreamHandlerFactory urlHandlerFactory) throws JRException {
    return JRLoader.loadBytesFromLocation(location, classLoader, urlHandlerFactory);
  }
  
  public static byte[] loadImageDataFromAWTImage(Image image, byte imageType) throws JRException {
    return imageEncoder.encode(image, imageType);
  }
  
  public static byte[] loadImageDataFromAWTImage(BufferedImage bi) throws JRException {
    return loadImageDataFromAWTImage(bi, (byte)2);
  }
  
  public static byte[] loadImageDataFromAWTImage(Image image) throws JRException {
    return loadImageDataFromAWTImage(image, (byte)2);
  }
  
  public static Image getImage(byte index) throws JRException {
    Image image = null;
    switch (index) {
      case 1:
        if (img_NO_IMAGE == null)
          img_NO_IMAGE = loadImage("net/sf/jasperreports/engine/images/noimage.GIF"); 
        image = img_NO_IMAGE;
        break;
      case 2:
        if (img_SUBREPORT_IMAGE == null)
          img_SUBREPORT_IMAGE = loadImage("net/sf/jasperreports/engine/images/subreport.GIF"); 
        image = img_SUBREPORT_IMAGE;
        break;
      case 3:
        if (img_CHART_IMAGE == null)
          img_CHART_IMAGE = loadImage("net/sf/jasperreports/engine/images/chart.GIF"); 
        image = img_CHART_IMAGE;
        break;
      case 4:
        if (img_CROSSTAB_IMAGE == null)
          img_CROSSTAB_IMAGE = loadImage("net/sf/jasperreports/engine/images/crosstab.GIF"); 
        image = img_CROSSTAB_IMAGE;
        break;
    } 
    return image;
  }
  
  public static Image loadImage(byte[] bytes) throws JRException {
    return imageReader.readImage(bytes);
  }
  
  protected static Image loadImage(String image) throws JRException {
    InputStream is;
    ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
    URL url = classLoader.getResource(image);
    if (url == null)
      classLoader = JRImageLoader.class.getClassLoader(); 
    if (classLoader == null) {
      is = JRImageLoader.class.getResourceAsStream("/" + image);
    } else {
      is = classLoader.getResourceAsStream(image);
    } 
    return imageReader.readImage(JRLoader.loadBytes(is));
  }
}
