/*
 * Copyright (C) 2005 metamesh (http://www.metamesh.de)
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * For further information about metamesh, please see the
 * company website: http://www.metamesh.de
 * 
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
package de.metamesh.opencms.imageops;

import java.awt.geom.AffineTransform;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.awt.image.RenderedImage;
import java.awt.image.WritableRaster;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.net.SocketException;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Locale;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.batik.ext.awt.image.codec.PNGImageDecoder;
import org.apache.batik.ext.awt.image.codec.PNGImageEncoder;
import org.apache.commons.collections.ExtendedProperties;
import org.opencms.configuration.CmsConfigurationManager;
import org.opencms.db.CmsPublishList;
import org.opencms.file.CmsFile;
import org.opencms.file.CmsObject;
import org.opencms.file.CmsResource;
import org.opencms.flex.CmsFlexCache;
import org.opencms.flex.CmsFlexController;
import org.opencms.flex.CmsFlexRequest;
import org.opencms.flex.CmsFlexResponse;
import org.opencms.loader.I_CmsFlexCacheEnabledLoader;
import org.opencms.loader.I_CmsResourceLoader;
import org.opencms.main.CmsEvent;
import org.opencms.main.CmsException;
import org.opencms.main.CmsLog;
import org.opencms.main.OpenCms;
import org.opencms.module.CmsModule;
import org.opencms.module.I_CmsModuleAction;
import org.opencms.report.I_CmsReport;
import org.opencms.util.CmsRequestUtil;
import org.opencms.util.CmsStringUtil;
import org.opencms.workplace.CmsWorkplaceManager;

import sun.awt.image.codec.JPEGImageEncoderImpl;
import Acme.JPM.Encoders.GifEncoder;

import com.sun.image.codec.jpeg.JPEGImageDecoder;
import com.sun.image.codec.jpeg.JPEGImageEncoder;

/**
 * 
 * @author Stephan Hartmann (hartmann@metamesh.de)
 */
public class ImageLoader implements I_CmsResourceLoader, I_CmsFlexCacheEnabledLoader,
   I_CmsModuleAction {

  public static final int FORMAT_PNG = 0;

  public static final int FORMAT_GIF = 1;

  public static final int FORMAT_JPEG = 2;

  public static final String C_PROPERTY_IMAGE_TYPE = "imagetype";

  public static final String PARAM_SCALE      = "scale";
  public static final String PARAM_SCALE_X    = "scalex";
  public static final String PARAM_SCALE_Y    = "scaley";
  public static final String PARAM_WIDTH      = "width";
  public static final String PARAM_HEIGHT     = "height";
  public static final String PARAM_MAX_WIDTH  = "maxwidth";
  public static final String PARAM_MAX_HEIGHT = "maxheight";
  public static final String PARAM_KEEP_RATIO = "keepratio";
  
  /** The id of this loader. */
  public static final int C_RESOURCE_LOADER_ID = 433;

  private CmsFlexCache flexCache;
  
  private ExtendedProperties props;
  /**
   * The constructor of the class is empty and does nothing.
   * <p>
   */
  public ImageLoader() {
    props = new ExtendedProperties();
  }

  /**
   * @see org.opencms.configuration.I_CmsConfigurationParameterHandler#addConfigurationParameter(java.lang.String,
   *      java.lang.String)
   */
  public void addConfigurationParameter(String paramName, String paramValue) {

    props.addProperty(paramName, paramValue);
  }

  /**
   * Destroy this ResourceLoder, this is a NOOP so far.
   * <p>
   */
  public void destroy() {
    // NOOP
  }

  /**
   * @see org.opencms.loader.I_CmsResourceLoader#dump(org.opencms.file.CmsObject,
   *      org.opencms.file.CmsResource, java.lang.String, java.util.Locale,
   *      javax.servlet.http.HttpServletRequest,
   *      javax.servlet.http.HttpServletResponse)
   */
  public byte[] dump(CmsObject cms, CmsResource resource, String element,
      Locale locale, HttpServletRequest req, HttpServletResponse res)
      throws CmsException {

    CmsFile file = CmsFile.upgrade(resource, cms);
    byte[] result = processImage(cms, req, file);
    return result;
  }

  /**
   * @throws CmsException
   * @throws IOException
   * @throws ServletException
   * @see org.opencms.loader.I_CmsResourceLoader#export(org.opencms.file.CmsObject,
   *      org.opencms.file.CmsResource, javax.servlet.http.HttpServletRequest,
   *      javax.servlet.http.HttpServletResponse)
   */
  public byte[] export(CmsObject cms, CmsResource resource,
      HttpServletRequest req, HttpServletResponse res) throws CmsException, ServletException, IOException {
    CmsFile file = CmsFile.upgrade(resource, cms);
    
    // if no request and response are given, the resource only must be
    // exported and no
    // output must be generated
    if ((req != null) && (res != null)) {
      // overwrite headers if set as default
      for (Iterator i = OpenCms.getStaticExportManager().getExportHeaders()
          .listIterator(); i.hasNext();) {
        String header = (String) i.next();

        // set header only if format is "key: value"
        String parts[] = CmsStringUtil.splitAsArray(header, ':');
        if (parts.length == 2) {
          res.setHeader(parts[0], parts[1]);
        }
      }

      return loadInternal(cms, file, req, res);
    }

    return new byte[0];
  }

  /**
   * Will always return <code>null</code> since this loader does not need to
   * be cnofigured.
   * <p>
   * 
   * @see org.opencms.configuration.I_CmsConfigurationParameterHandler#getConfiguration()
   */
  public Map getConfiguration() {
    return null;
  }

  /**
   * @see org.opencms.loader.I_CmsResourceLoader#getLoaderId()
   */
  public int getLoaderId() {
    return C_RESOURCE_LOADER_ID;
  }

  /**
   * Return a String describing the ResourceLoader, which is
   * <code>"resource loader for image files"</code>.
   * <p>
   * 
   * @return a describing String for the ResourceLoader
   */
  public String getResourceLoaderInfo() {
    return "resource loader for image files";
  }

  /**
   * @see org.opencms.configuration.I_CmsConfigurationParameterHandler#initConfiguration()
   */
  public void initConfiguration() {

    if (OpenCms.getLog(CmsLog.INIT).isInfoEnabled()) {
      OpenCms.getLog(CmsLog.INIT).info(
          ". Loader init          : " + this.getClass().getName()
              + " initialized");
    }
  }

  /**
   * @see org.opencms.loader.I_CmsResourceLoader#isStaticExportEnabled()
   */
  public boolean isStaticExportEnabled() {

    return true;
  }

  /**
   * @see org.opencms.loader.I_CmsResourceLoader#isStaticExportProcessable()
   */
  public boolean isStaticExportProcessable() {
    return true;
  }

  /**
   * @see org.opencms.loader.I_CmsResourceLoader#isUsableForTemplates()
   */
  public boolean isUsableForTemplates() {
    return false;
  }

  /**
   * @see org.opencms.loader.I_CmsResourceLoader#isUsingUriWhenLoadingTemplate()
   */
  public boolean isUsingUriWhenLoadingTemplate() {
    return false;
  }

  /**
   * @throws CmsException
   * @throws IOException
   * @throws ServletException
   * @see org.opencms.loader.I_CmsResourceLoader#load(org.opencms.file.CmsObject,
   *      org.opencms.file.CmsResource, javax.servlet.http.HttpServletRequest,
   *      javax.servlet.http.HttpServletResponse)
   */
  public void load(CmsObject cms, CmsResource resource, HttpServletRequest req,
      HttpServletResponse res) throws CmsException, ServletException, IOException {
    
    loadInternal(cms, resource, req, res);
  }

  /**
   * @throws IOException
   * @throws ServletException
   */
  private byte[] loadInternal(CmsObject cms, CmsResource resource, 
      HttpServletRequest req,
      HttpServletResponse res) throws CmsException, ServletException, IOException {
    
    // check if the current request was done by a workplace user
  	
    boolean isWorkplaceUser = CmsWorkplaceManager.isWorkplaceUser(req);

    if (!isWorkplaceUser) {
      // check if the request contains a last modified header
      long lastModifiedHeader = req
          .getDateHeader(CmsRequestUtil.HEADER_IF_MODIFIED_SINCE);
      if (lastModifiedHeader > -1) {
        // last modified header is set, compare it to the requested
        // resource
        if ((resource.getState() == CmsResource.STATE_UNCHANGED)
            && (resource.getDateLastModified() == lastModifiedHeader)) {
          long now = System.currentTimeMillis();
          if ((resource.getDateReleased() < now)
              && (resource.getDateExpired() > now)) {
            CmsFlexController.setDateExpiresHeader(res, resource
                .getDateExpired());
            res.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
            return new byte[0];
          }
        }
      }
    }

    // get the Flex controller
    CmsFlexController controller = getController(cms, resource, req, res, true);

    // get request / response wrappers
    CmsFlexRequest f_req = controller.getCurrentRequest();
    CmsFlexResponse f_res = controller.getCurrentResponse();

    try {
        f_req.getRequestDispatcher(controller.getCmsObject().getSitePath(controller.getCmsResource()))
            .include(f_req, f_res);
    } catch (SocketException e) {
        // uncritical, might happen if client (browser) does not wait until end of page delivery
        OpenCms.getLog(this).debug("Ignoring SocketException" + e);
    }
    
    byte[] result = f_res.getWriterBytes();

    // set response status to "200 - OK" (required for static export
    // "on-demand")
    res.setStatus(HttpServletResponse.SC_OK);

    if (isWorkplaceUser) {
      // prevent caching for Workplace users
      res.setDateHeader(CmsRequestUtil.HEADER_LAST_MODIFIED, System
          .currentTimeMillis());
      res.setHeader(CmsRequestUtil.HEADER_CACHE_CONTROL,
      		 CmsRequestUtil.HEADER_VALUE_MAX_AGE + "0");
      res.addHeader(CmsRequestUtil.HEADER_CACHE_CONTROL,
      		 CmsRequestUtil.HEADER_VALUE_MUST_REVALIDATE);
    } else {
      // set date last modified header
      res.setDateHeader(CmsRequestUtil.HEADER_LAST_MODIFIED, resource
          .getDateLastModified());

      // set "Expires" only if cache control is not already set
      if (!res.containsHeader(CmsRequestUtil.HEADER_CACHE_CONTROL)) {
        long expireTime = resource.getDateExpired();
        if (expireTime == CmsResource.DATE_EXPIRED_DEFAULT) {
          expireTime--;
          // flex controller will automatically reduce this to a
          // reasonable value
        }
        // now set "Expire" header
        CmsFlexController.setDateExpiresHeader(res, expireTime);
      }
    }

    // set content length header
    res.setContentLength(result.length);
    res.getOutputStream().write(result);
    return result;
  }
  
  private double[] getScale(ServletRequest req, int origWidth,
      int origHeight) {
    double[] result = new double[2];

    // read "scale" parameter
    String sScale = req.getParameter(PARAM_SCALE);
    double scale = -1;
    try {
      scale = Double.parseDouble(sScale);
    } catch (Exception e) {}
    
    // read "scalex" parameter
    String sScaleX = req.getParameter(PARAM_SCALE_X);
    double scaleX = -1;
    try {
      scaleX = Double.parseDouble(sScaleX);
    } catch (Exception e) {}

    // read "scaley" parameter
    String sScaleY = req.getParameter(PARAM_SCALE_Y);
    double scaleY = -1;
    try {
      scaleY = Double.parseDouble(sScaleY);
    } catch (Exception e) {}
    
    // read "width" parameter
    String sWidth = req.getParameter(PARAM_WIDTH);
    int width = -1;
    try {
      width = Integer.parseInt(sWidth);
    } catch (Exception e) {}
    
    // read "height" parameter
    String sHeight = req.getParameter(PARAM_HEIGHT);
    int height = -1;
    try {
      height = Integer.parseInt(sHeight);
    } catch (Exception e) {}
    
    // read "maxwidth" parameter
    String sMaxWidth = req.getParameter(PARAM_MAX_WIDTH);
    int maxWidth = -1;
    try {
      maxWidth = Integer.parseInt(sMaxWidth);
    } catch (Exception e) {}
    
    // read "maxheight" parameter
    String sMaxHeight = req.getParameter(PARAM_MAX_HEIGHT);
    int maxHeight = -1;
    try {
      maxHeight = Integer.parseInt(sMaxHeight);
    } catch (Exception e) {}
    
    // read "keepratio" parameter
    String sKeepRatio = req.getParameter(PARAM_KEEP_RATIO);
    Boolean keepRatio = null;
    if (sKeepRatio != null)
    try {
      keepRatio = new Boolean(sKeepRatio);
    } catch (Exception e) {}
    
    // width / height have highest priority
    // here keepRatio defaults to true
    if ((width > 0) || (height > 0)) {
      if (keepRatio == null) {
        if ((width > 0) && (height > 0))
          keepRatio = Boolean.FALSE;
        else
          keepRatio = Boolean.TRUE;
      }
      if (width <= 0) {
        scaleY = (double)height / origHeight;
        if (keepRatio.booleanValue())
          scaleX = scaleY;
        else scaleX = 1;
        width = (int)(origWidth * scaleX);
      }
      if (height <= 0) {
        scaleX = (double)width / origWidth;
        if (keepRatio.booleanValue())
          scaleY = scaleX;
        else scaleY = 1;
        height = (int)(origHeight * scaleY);
      }
      scaleX = (double)width / origWidth;
      scaleY = (double)height / origHeight;
    }
    // here keepRatio defaults to false
    else if ((scaleX > 0) || (scaleY > 0)) {
      if (keepRatio == null) keepRatio = Boolean.FALSE;
      if (scaleX <= 0) {
        if (keepRatio.booleanValue()) {
          scaleX = scaleY;
        }
      }
      if (scaleY <= 0) {
        if (keepRatio.booleanValue()) {
          scaleY = scaleX;
        }
      }
      width = (int)(origWidth * scaleX);
      height = (int)(origHeight * scaleY);
    }
    else if (scale > 0) {
      scaleX = scaleY = scale;
      keepRatio = Boolean.TRUE;
    }
    
    if ((maxWidth > 0) && (width > maxWidth)) {
      width  = maxWidth;
      scaleX = (double)width / origWidth;
      if (keepRatio.booleanValue()) {
        scaleY = scaleX;
      }
    }
    if ((maxHeight > 0) && (height > maxHeight)) {
      height = maxHeight;
      scaleY = (double)height / origHeight;
      if (keepRatio.booleanValue()) {
        scaleX = scaleY;
      }
    }
    
    if (scaleX > 2) {
      double factor = 2 / scaleX;
      scaleX = 2;
      if (keepRatio.booleanValue())
        scaleY = scaleY * factor;
    }
    if (scaleY > 2) {
      double factor = 2 / scaleY;
      scaleY = 2;
      if (keepRatio.booleanValue())
        scaleX = scaleX * factor;
    }
    
    if (scaleX <= 0) result[0] = 1;
    else result[0] = scaleX;
    if (scaleY <= 0) result[1] = 1;
    else result[1] = scaleY;
    
    return result;
  }
  private byte[] processImage(CmsObject cms, ServletRequest req, CmsFile file) {
    
    byte[] input = file.getContents();
    
    String sGifFrame = req.getParameter("gifframe");
    int gifFrame = 0;
    if (sGifFrame!=null) {
      try {
        gifFrame = Integer.parseInt(sGifFrame);
      } catch (Exception e) {}
    }
    BufferedImage bi = getBufferedImage(input, gifFrame);

    if (bi == null) return input;
    
    double[] scale = getScale(req, bi.getWidth(), bi.getHeight());
    
    if ((scale[0] == 1) && (scale[1] == 1)) return input;
    
    
    AffineTransformOp ato = new AffineTransformOp(AffineTransform
        .getScaleInstance(scale[0], scale[1]), null);
    BufferedImage si = ato.filter(bi, null);
    si.flush();

    byte[] result = null;
    
    int imageType = getFormat(cms, cms.getSitePath(file));
    
    switch (imageType) {
    case FORMAT_JPEG: 
      result = encodeAsJPEG(si, input);
      break;
    case FORMAT_PNG: 
      result = encodeAsPNG(si, input);
      break;
    default:
      result = encodeAsGIF(si, input);
    }
    return result;
  }
  public BufferedImage getBufferedImage(byte[] bytes, int gifFrame) {
    if (isJAI()) return JAICodecHelper.getInstance().getBufferedImageJAI(bytes);
    else return getBufferedImageAlt(bytes, gifFrame);
  }
  public BufferedImage getBufferedImageAlt(byte[] bytes, int gifFrame) {
    ByteArrayInputStream b = new ByteArrayInputStream(bytes);
    BufferedImage bimg = null;
    byte magic[] = new byte[8];
    char jpeg[] = {0xff, 0xd8};
    try {
      b.read(magic);
      String magicS = new String(magic);
      b.reset();
      // A_OpenCms.log(C_OPENCMS_DEBUG, magicS + " | " + magicS.substring(1,2));

      if (magicS.substring(0, 3).equalsIgnoreCase("gif")) {
        // We have a GIF
        GIFDecoder gd = new GIFDecoder();
        gd.read(b);
        return gd.getFrame(gifFrame);
      }
      else if ((bytes[0] == -1) && (bytes[1] == -40)) {
        // We have a JPEG
        JPEGImageDecoder jid = com.sun.image.codec.jpeg.JPEGCodec.createJPEGDecoder(b);
        return jid.decodeAsBufferedImage();
      }
      else if (magicS.toLowerCase().indexOf("png") >= 0) {
        PNGImageDecoder pid = new PNGImageDecoder(b, null);
        RenderedImage ri = pid.decodeAsRenderedImage();
        return convertRenderedImage(ri);
      }
      else {
        return null;
      }
    } catch (IOException ioe) {
      /// Error handling
      return null;
    }
  }
  public BufferedImage convertRenderedImage(RenderedImage img) {
    if (img instanceof BufferedImage) {
      return (BufferedImage)img;  
    } 
    ColorModel cm = img.getColorModel();
    int width = img.getWidth();
    int height = img.getHeight();
    WritableRaster raster = cm.createCompatibleWritableRaster(width, height);
    boolean isAlphaPremultiplied = cm.isAlphaPremultiplied();
    Hashtable properties = new Hashtable();
    String[] keys = img.getPropertyNames();
    if (keys!=null) {
      for (int i = 0; i < keys.length; i++) {
        properties.put(keys[i], img.getProperty(keys[i]));
      }
    }
    BufferedImage result = new BufferedImage(cm, raster, isAlphaPremultiplied, properties);
    img.copyData(raster);
    return result;
  }

  /**
   * @see org.opencms.loader.I_CmsResourceLoader#service(org.opencms.file.CmsObject,
   *      org.opencms.file.CmsResource, javax.servlet.ServletRequest,
   *      javax.servlet.ServletResponse)
   */
  public void service(CmsObject cms, CmsResource resource, ServletRequest req,
      ServletResponse res) throws CmsException, IOException {

    CmsFile file = CmsFile.upgrade(resource, cms);
    byte[] result = processImage(cms, req, file);
    
    res.getOutputStream().write(result);
  }

  /**
   * Delivers a Flex controller, either by creating a new one, or by re-using an existing one.<p> 
   * 
   * @param cms the initial CmsObject to wrap in the controller
   * @param resource the resource requested
   * @param req the current request
   * @param res the current response
   * @param streaming indicates if the response is streaming
   * @param top indicates if the response is the top response
   * 
   * @return a Flex controller
   */
  private CmsFlexController getController(
      CmsObject cms,
      CmsResource resource,
      HttpServletRequest req,
      HttpServletResponse res,
      boolean top
  ) {

      CmsFlexController controller = null;
      if (top) {
          // only check for existing contoller if this is the "top" request/response
          controller = (CmsFlexController)req.getAttribute(CmsFlexController.ATTRIBUTE_NAME);
      }
      if (controller == null) {
          // create new request / response wrappers
          controller = new CmsFlexController(cms, resource, flexCache, req, res, false, top);
          req.setAttribute(CmsFlexController.ATTRIBUTE_NAME, controller);
          CmsFlexRequest f_req = new CmsFlexRequest(req, controller);
          CmsFlexResponse f_res = new CmsFlexResponse(res, controller, false, true);
          controller.push(f_req, f_res);
      }
      return controller;
  }
  public byte[] encodeAsJPEG(BufferedImage simg, byte[] originalBytes) {

    if (simg == null) {
      return originalBytes;
    }
    ByteArrayOutputStream bout = new ByteArrayOutputStream();
    try {
      if (isJAI()) {
        JAICodecHelper.getInstance().encodeAsJPEG(simg, bout);
      }
      else {
        JPEGImageEncoder jie = new JPEGImageEncoderImpl(bout);
        jie.encode(simg);
      }
    } catch (Exception e) {
      return originalBytes;
    }
    try {
      bout.flush();
    } catch (IOException e) {

    }
    return bout.toByteArray();
  }

  public byte[] encodeAsGIF(BufferedImage simg, byte[] originalBytes) {

    if (simg == null) {
      return originalBytes;
    }
    ByteArrayOutputStream bout = new ByteArrayOutputStream();
    GifEncoder ge = null;
    try {
      ge = new GifEncoder(simg.getSource(), bout);
      ge.encode();
    } catch (Exception e) {
      // too many colors, try to quantize
      try {
        int[][] pixels = IMQuantizer.getPixels(simg);
        int[] palette = IMQuantizer.quantizeImage(pixels, 256);
        int w = pixels.length;
        int h = pixels[0].length;

        simg = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
        // convert to RGB
        for (int x = w; x-- > 0; ) {
            for (int y = h; y-- > 0; ) {
                simg.setRGB(x, y, palette[pixels[x][y]]);
            }
        }
        ge = new GifEncoder(simg.getSource(), bout);
        ge.encode();
      } catch (Exception e2) {
        return originalBytes;
      }
    }
    try {
      bout.flush();
    } catch (IOException e) {

    }
    return bout.toByteArray();

  }

  public byte[] encodeAsPNG(BufferedImage simg, byte[] originalBytes) {

    if (simg == null) {
      return originalBytes;
    }
    ByteArrayOutputStream bout = new ByteArrayOutputStream();
    try {
      if (isJAI()) {
        JAICodecHelper.getInstance().encodeAsPNG(simg, bout);
      }
      else {
        PNGImageEncoder pie = new PNGImageEncoder(bout, null);
        pie.encode(simg);
      }
    } catch (Exception e) {

      return originalBytes;
    }
    try {
      bout.flush();
    } catch (IOException e) {

    }
    return bout.toByteArray();

  }

  private int getFormat(CmsObject cms, String fileUri) {
    int format = -1;

    String pValue = getPropertyValue(cms, fileUri, C_PROPERTY_IMAGE_TYPE);
    if (pValue != null) {
      format = formatMapping(pValue);
    }
    if (format >= 0)
      return format;

    // then we look at the suffix
    int pos = fileUri.lastIndexOf('.');
    if (pos >= 0) {
      format = formatMapping(fileUri.substring(pos + 1));
    }
    if (format >= 0)
      return format;

    // default if nothing found
    return FORMAT_PNG;
  }

  private String getPropertyValue(CmsObject cms, String file, String property) {
    String pValue = null;
    try {
      // first look for imagetype property
      pValue = cms.readPropertyObject(file, property, true).getValue();
    } catch (CmsException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
    return pValue;
  }

  private int formatMapping(String format) {
    if (format == null)
      return -1;
    format = format.trim().toLowerCase();
    if (format.equals("png"))
      return FORMAT_PNG;
    if (format.equals("gif"))
      return FORMAT_GIF;
    if (format.equals("jpg") || format.equals("jpeg"))
      return FORMAT_JPEG;
    return -1;
  }
  
  public void setFlexCache(CmsFlexCache cache) {
    flexCache = cache;

  }
  public boolean isJAI() {
    try {
      return props.getBoolean("jai");
    } catch (Exception e) {}
    return false;
  }
  
  /* (non-Javadoc)
   * @see org.opencms.module.I_CmsModuleAction#initialize(org.opencms.file.CmsObject, org.opencms.configuration.CmsConfigurationManager, org.opencms.module.CmsModule)
   */
  public void initialize(CmsObject adminCms,
      CmsConfigurationManager configurationManager, CmsModule module) {


  }
  /* (non-Javadoc)
   * @see org.opencms.module.I_CmsModuleAction#moduleUninstall(org.opencms.module.CmsModule)
   */
  public void moduleUninstall(CmsModule module) {
    // TODO Auto-generated method stub

  }
  /* (non-Javadoc)
   * @see org.opencms.module.I_CmsModuleAction#moduleUpdate(org.opencms.module.CmsModule)
   */
  public void moduleUpdate(CmsModule module) {
    // TODO Auto-generated method stub

  }
  /* (non-Javadoc)
   * @see org.opencms.module.I_CmsModuleAction#publishProject(org.opencms.file.CmsObject, org.opencms.db.CmsPublishList, int, org.opencms.report.I_CmsReport)
   */
  public void publishProject(CmsObject cms, CmsPublishList publishList,
      int backupTagId, I_CmsReport report) {
    // TODO Auto-generated method stub

  }
  /* (non-Javadoc)
   * @see org.opencms.module.I_CmsModuleAction#shutDown(org.opencms.module.CmsModule)
   */
  public void shutDown(CmsModule module) {
    // TODO Auto-generated method stub

  }
  /* (non-Javadoc)
   * @see org.opencms.main.I_CmsEventListener#cmsEvent(org.opencms.main.CmsEvent)
   */
  public void cmsEvent(CmsEvent event) {
    // TODO Auto-generated method stub

  }
}