/* BufferedImageGraphics.java
   Copyright (C) 2006 Free Software Foundation, Inc.

This file is part of GNU Classpath.

GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.

GNU Classpath 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
General Public License for more details.

You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version. */


package gnu.java.awt.peer.gtk;

import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Composite;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.Toolkit;
import java.awt.font.GlyphVector;
import java.awt.geom.AffineTransform;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.awt.image.DataBufferInt;
import java.awt.image.ImageObserver;
import java.awt.image.ImageProducer;
import java.awt.image.Raster;
import java.awt.image.RenderedImage;
import java.awt.image.SinglePixelPackedSampleModel;
import java.util.WeakHashMap;

/**
 * Implementation of Graphics2D on a Cairo surface.
 *
 * Simutanously maintains a CairoSurface and updates the
 * BufferedImage from that after each drawing operation.
 */
public class BufferedImageGraphics extends CairoGraphics2D
{
  /**
   * the buffered Image.
   */
  private BufferedImage image, buffer;

  /**
   * Image size.
   */
  private int imageWidth, imageHeight;

  /**
   * The cairo surface that we actually draw on.
   */
  CairoSurface surface;

  /**
   * Cache BufferedImageGraphics surfaces.
   */
  static WeakHashMap<BufferedImage, CairoSurface> bufferedImages
    = new WeakHashMap<BufferedImage, CairoSurface>();

  /**
   * Its corresponding cairo_t.
   */
  private long cairo_t;

  private boolean hasFastCM;
  private boolean hasAlpha;


  public BufferedImageGraphics(BufferedImage bi)
  {
    this.image = bi;
    imageWidth = bi.getWidth();
    imageHeight = bi.getHeight();

    if (!(image.getSampleModel() instanceof SinglePixelPackedSampleModel))
      hasFastCM = false;
    else if(bi.getColorModel().equals(CairoSurface.cairoCM_opaque))
      {
        hasFastCM = true;
        hasAlpha = false;
      }
    else if(bi.getColorModel().equals(CairoSurface.cairoColorModel)
        || bi.getColorModel().equals(CairoSurface.cairoCM_pre))
      {
        hasFastCM = true;
        hasAlpha = true;
      }
    else
      hasFastCM = false;

    // Cache surfaces.
    if( bufferedImages.get( bi ) != null )
      surface = bufferedImages.get( bi );
    else
      {
        surface = new CairoSurface( imageWidth, imageHeight );
        bufferedImages.put(bi, surface);
      }

    cairo_t = surface.newCairoContext();

    // Get pixels out of buffered image and set in cairo surface
    Raster raster = bi.getRaster();
    int[] pixels;

    if (hasFastCM)
      {
        SinglePixelPackedSampleModel sm = (SinglePixelPackedSampleModel)image.getSampleModel();
        int minX = image.getRaster().getSampleModelTranslateX();
        int minY = image.getRaster().getSampleModelTranslateY();

        // Pull pixels directly out of data buffer
        pixels = ((DataBufferInt)raster.getDataBuffer()).getData();

        // Discard pixels that fall outside of the image's bounds
        // (ie, this image is actually a subimage of a different image)
        if (!(sm.getScanlineStride() == imageWidth && minX == 0 && minY == 0))
          {
            int[] pixels2 = new int[imageWidth * imageHeight];
            int scanline = sm.getScanlineStride();

            for (int i = 0; i < imageHeight; i++)
              System.arraycopy(pixels, (i - minY) * scanline - minX, pixels2,
                               i * imageWidth, imageWidth);

            pixels = pixels2;
          }

        // Fill the alpha channel as opaque if image does not have alpha
        if( !hasAlpha )
          for(int i = 0; i < pixels.length; i++)
            pixels[i] &= 0xFFFFFFFF;
      }
    else
      {
        pixels = CairoGraphics2D.findSimpleIntegerArray(image.getColorModel(),
                                                        image.getData());
        if (pixels != null)
          System.arraycopy(pixels, 0, surface.getData(),
                           0, pixels.length);
      }

    setup( cairo_t );
    setClip(0, 0, imageWidth, imageHeight);
  }

  BufferedImageGraphics(BufferedImageGraphics copyFrom)
  {
    image = copyFrom.image;
    surface = copyFrom.surface;
    cairo_t = surface.newCairoContext();
    imageWidth = copyFrom.imageWidth;
    imageHeight = copyFrom.imageHeight;

    hasFastCM = copyFrom.hasFastCM;
    hasAlpha = copyFrom.hasAlpha;

    copy( copyFrom, cairo_t );
  }

  /**
   * Update a rectangle of the bufferedImage. This can be improved upon a lot.
   */
  private void updateBufferedImage(int x, int y, int width, int height)
  {
    Rectangle bounds = new Rectangle(x, y, width, height);
    bounds = getTransformedBounds(bounds, transform).getBounds();
    x = bounds.x;
    y = bounds.y;
    width = bounds.width;
    height = bounds.height;

    int[] pixels = surface.getData();

    if( x > imageWidth || y > imageHeight )
      return;

    // Deal with negative width/height.
    if (height < 0)
      {
        y += height;
        height = -height;
      }
    if (width < 0)
      {
        x += width;
        width = -width;
      }

    // Clip edges.
    if( x < 0 )
      x = 0;
    if( y < 0 )
      y = 0;

    if( x + width > imageWidth )
      width = imageWidth - x;
    if( y + height > imageHeight )
      height = imageHeight - y;

    if(!hasFastCM)
      {
        image.setRGB(x, y, width, height, pixels,
                     x + y * imageWidth, imageWidth);
        // The setRGB method assumes (or should assume) that pixels are NOT
        // alpha-premultiplied, but Cairo stores data with premultiplication
        // (thus the pixels returned in getPixels are premultiplied).
        // This is ignored for consistency, however, since in
        // CairoGrahpics2D.drawImage we also use non-premultiplied data

      }
    else
      {
        int[] db = ((DataBufferInt)image.getRaster().getDataBuffer()).
                  getData();

        // This should not fail, as we check the image sample model when we
        // set the hasFastCM flag
        SinglePixelPackedSampleModel sm = (SinglePixelPackedSampleModel)image.getSampleModel() ;

        int minX = image.getRaster().getSampleModelTranslateX();
        int minY = image.getRaster().getSampleModelTranslateY();

        if (sm.getScanlineStride() == imageWidth && minX == 0)
          {
            System.arraycopy(pixels, y * imageWidth,
                             db, (y - minY) * imageWidth,
                             height * imageWidth);
          }
        else
          {
            int scanline = sm.getScanlineStride();
            for (int i = y; i < (height + y); i++)
              System.arraycopy(pixels, i * imageWidth + x, db,
                               (i - minY) * scanline + x - minX, width);

          }
      }
  }

  /**
   * Abstract methods.
   */
  public Graphics create()
  {
    return new BufferedImageGraphics(this);
  }

  public GraphicsConfiguration getDeviceConfiguration()
  {
    return null;
  }

  protected Rectangle2D getRealBounds()
  {
    return new Rectangle2D.Double(0.0, 0.0, imageWidth, imageHeight);
  }

  public void copyAreaImpl(int x, int y, int width, int height, int dx, int dy)
  {
    surface.copyAreaNative(x, y, width, height, dx, dy, surface.width);
    updateBufferedImage(x + dx, y + dy, width, height);
  }

  /**
   * Overloaded methods that do actual drawing need to enter the gdk threads
   * and also do certain things before and after.
   */
  public void draw(Shape s)
  {
    // Find total bounds of shape
    Rectangle r = findStrokedBounds(s);
    if (shiftDrawCalls)
      {
        r.width++;
        r.height++;
      }

    // Do the drawing
    if (comp == null || comp instanceof AlphaComposite)
      {
        super.draw(s);
        updateBufferedImage(r.x, r.y, r.width, r.height);
      }
    else
      {
        createBuffer();

        Graphics2D g2d = (Graphics2D)buffer.getGraphics();
        g2d.setStroke(this.getStroke());
        g2d.setColor(this.getColor());
        g2d.setTransform(transform);
        g2d.draw(s);

        drawComposite(r.getBounds2D(), null);
      }
  }

  public void fill(Shape s)
  {
    if (comp == null || comp instanceof AlphaComposite)
      {
        super.fill(s);
        Rectangle r = s.getBounds();
        updateBufferedImage(r.x, r.y, r.width, r.height);
      }
    else
      {
        createBuffer();

        Graphics2D g2d = (Graphics2D)buffer.getGraphics();
        g2d.setPaint(this.getPaint());
        g2d.setColor(this.getColor());
        g2d.setTransform(transform);
        g2d.fill(s);

        drawComposite(s.getBounds2D(), null);
      }
  }

  public void drawRenderedImage(RenderedImage image, AffineTransform xform)
  {
    if (comp == null || comp instanceof AlphaComposite)
      {
        super.drawRenderedImage(image, xform);
        updateBufferedImage(0, 0, imageWidth, imageHeight);
      }
    else
      {
        createBuffer();

        Graphics2D g2d = (Graphics2D)buffer.getGraphics();
        g2d.setRenderingHints(this.getRenderingHints());
        g2d.setTransform(transform);
        g2d.drawRenderedImage(image, xform);

        drawComposite(buffer.getRaster().getBounds(), null);
      }

  }

  protected boolean drawImage(Image img, AffineTransform xform,
                              Color bgcolor, ImageObserver obs)
  {
    if (comp == null || comp instanceof AlphaComposite)
      {
        boolean rv = super.drawImage(img, xform, bgcolor, obs);
        updateBufferedImage(0, 0, imageWidth, imageHeight);
        return rv;
      }
    else
      {
        // Get buffered image of source
        if( !(img instanceof BufferedImage) )
          {
            ImageProducer source = img.getSource();
            if (source == null)
              return false;
            img = Toolkit.getDefaultToolkit().createImage(source);
          }
        BufferedImage bImg = (BufferedImage) img;

        // Find translated bounds
        Rectangle2D bounds = new Rectangle(bImg.getMinX(), bImg.getMinY(),
                                           bImg.getWidth(), bImg.getHeight());
        if (xform != null)
          bounds = getTransformedBounds(bounds, xform);

        // Create buffer and draw image
        createBuffer();

        Graphics2D g2d = (Graphics2D)buffer.getGraphics();
        g2d.setRenderingHints(this.getRenderingHints());
        g2d.drawImage(img, xform, obs);

        // Perform compositing
        return drawComposite(bounds, obs);
      }
  }

  public void drawGlyphVector(GlyphVector gv, float x, float y)
  {
    // Find absolute bounds, in user-space, of this glyph vector
    Rectangle2D bounds = gv.getLogicalBounds();
    bounds = new Rectangle2D.Double(x + bounds.getX(), y + bounds.getY(),
                                    bounds.getWidth(), bounds.getHeight());

    // Perform draw operation
    if (comp == null || comp instanceof AlphaComposite)
      {
        super.drawGlyphVector(gv, x, y);

        // this returns an integer-based Rectangle (rather than a
        // Rectangle2D), which takes care of any necessary rounding for us.
        bounds = bounds.getBounds();

        updateBufferedImage((int)bounds.getX(), (int)bounds.getY(),
                            (int)bounds.getWidth(), (int)bounds.getHeight());
      }
    else
      {
        createBuffer();

        Graphics2D g2d = (Graphics2D)buffer.getGraphics();
        g2d.setPaint(this.getPaint());
        g2d.setStroke(this.getStroke());
        g2d.setTransform(transform);
        g2d.drawGlyphVector(gv, x, y);

        drawComposite(bounds, null);
      }
  }

  /**
   * Perform composite drawing from the buffer onto the main image.
   *
   * The image to be composited should already be drawn into the buffer, in the
   * proper place, after all necessary transforms have been applied.
   *
   * @param bounds The bounds to draw, in user-space.
   * @param observer The image observer, if any (may be null).
   * @return True on success, false on failure.
   */
  private boolean drawComposite(Rectangle2D bounds, ImageObserver observer)
  {
    // Find bounds in device space
    bounds = getTransformedBounds(bounds, transform);

    // Clip bounds by the stored clip, and by the internal buffer
    Rectangle2D devClip = this.getClipInDevSpace();
    Rectangle2D.intersect(bounds, devClip, bounds);
    devClip = new Rectangle(buffer.getMinX(), buffer.getMinY(),
                            buffer.getWidth(), buffer.getHeight());
    Rectangle2D.intersect(bounds, devClip, bounds);

    // Round bounds as needed, but be careful in our rounding
    // (otherwise it may leave unpainted stripes)
    double x = bounds.getX();
    double y = bounds.getY();
    double maxX = x + bounds.getWidth();
    double maxY = y + bounds.getHeight();
    x = Math.round(x);
    y = Math.round(y);
    bounds.setRect(x, y, Math.round(maxX - x), Math.round(maxY - y));

    // Find subimage of internal buffer for updating
    BufferedImage buffer2 = buffer;
    if (!bounds.equals(buffer2.getRaster().getBounds()))
      buffer2 = buffer2.getSubimage((int)bounds.getX(), (int)bounds.getY(),
                                    (int)bounds.getWidth(),
                                    (int)bounds.getHeight());

    // Find subimage of main image for updating
    BufferedImage current = image;
    current = current.getSubimage((int)bounds.getX(), (int)bounds.getY(),
                                  (int)bounds.getWidth(),
                                  (int)bounds.getHeight());

    // Perform actual composite operation
    compCtx.compose(buffer2.getRaster(), current.getRaster(),
                    current.getRaster());

    // Set cairo's composite to direct SRC, since we've already done our own
    // compositing
    Composite oldcomp = comp;
    setComposite(AlphaComposite.Src);

    // This MUST call directly into the "action" method in CairoGraphics2D,
    // not one of the wrappers, to ensure that the composite isn't processed
    // more than once!
    boolean rv = super.drawImage(current,
                                 AffineTransform.getTranslateInstance(bounds.getX(),
                                                                      bounds.getY()),
                                 null, null);
    setComposite(oldcomp);
    updateColor();
    return rv;
  }

  private void createBuffer()
  {
    if (buffer == null)
      {
        buffer = new BufferedImage(image.getWidth(), image.getHeight(),
                                   BufferedImage.TYPE_INT_ARGB);
      }
    else
      {
        Graphics2D g2d = ((Graphics2D)buffer.getGraphics());

        g2d.setBackground(new Color(0,0,0,0));
        g2d.clearRect(0, 0, buffer.getWidth(), buffer.getHeight());
      }
  }

  protected ColorModel getNativeCM()
  {
    return image.getColorModel();
  }

  protected ColorModel getBufferCM()
  {
    return ColorModel.getRGBdefault();
  }
}
